From 006b83798ea416200991e5075f3cbb30fd16759e Mon Sep 17 00:00:00 2001 From: Marc Hoersken Date: Wed, 20 Jun 2012 07:49:34 +0200 Subject: [PATCH] schannel: Implement new buffer size strategy Increase decrypted and encrypted cache buffers using limitted doubling strategy. More information on the mailinglist: http://curl.haxx.se/mail/lib-2012-06/0255.html It updates the two remaining reallocations that have already been there and fixes the other one to use the same "do we need to increase the buffer"-condition as the other two. CURL_SCHANNEL_BUFFER_STEP_SIZE was renamed to CURL_SCHANNEL_BUFFER_FREE_SIZE since that is actually what it is now. Since we don't know how much more data we are going to read during the handshake, CURL_SCHANNEL_BUFFER_FREE_SIZE is used as the minimum free space required in the buffer for the next operation. CURL_SCHANNEL_BUFFER_STEP_SIZE was used for that before, too, but since we don't have a step size now, the define was renamed. --- lib/curl_schannel.c | 38 +++++++++++++++++++++++++++++--------- lib/curl_schannel.h | 7 +++++-- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/lib/curl_schannel.c b/lib/curl_schannel.c index c7d0468fd..dc8b21ebd 100644 --- a/lib/curl_schannel.c +++ b/lib/curl_schannel.c @@ -309,13 +309,18 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) } /* if we need a bigger buffer to read a full message, increase buffer now */ - if(connssl->encdata_offset == connssl->encdata_length) { - if(connssl->encdata_length >= CURL_SCHANNEL_BUFFER_INIT_SIZE * 16) + if(connssl->encdata_length - connssl->encdata_offset < + CURL_SCHANNEL_BUFFER_FREE_SIZE) { + if(connssl->encdata_length >= CURL_SCHANNEL_BUFFER_MAX_SIZE) { + failf(data, "schannel: memory buffer size limit reached"); return CURLE_OUT_OF_MEMORY; + } + /* increase internal encrypted data buffer */ - connssl->encdata_length *= 2; + connssl->encdata_length *= CURL_SCHANNEL_BUFFER_STEP_FACTOR; connssl->encdata_buffer = realloc(connssl->encdata_buffer, connssl->encdata_length); + if(connssl->encdata_buffer == NULL) { failf(data, "schannel: unable to re-allocate memory"); return CURLE_OUT_OF_MEMORY; @@ -826,17 +831,25 @@ schannel_recv(struct connectdata *conn, int sockindex, connssl->decdata_buffer = malloc(connssl->decdata_length); if(connssl->decdata_buffer == NULL) { failf(data, "schannel: unable to allocate memory"); - return CURLE_OUT_OF_MEMORY; + *err = CURLE_OUT_OF_MEMORY; + return -1; } } /* increase buffer in order to fit the requested amount of data */ while(connssl->encdata_length - connssl->encdata_offset < - CURL_SCHANNEL_BUFFER_STEP_SIZE || connssl->encdata_length < len) { + CURL_SCHANNEL_BUFFER_FREE_SIZE || connssl->encdata_length < len) { + if(connssl->encdata_length >= CURL_SCHANNEL_BUFFER_MAX_SIZE) { + failf(data, "schannel: memory buffer size limit reached"); + *err = CURLE_OUT_OF_MEMORY; + return -1; + } + /* increase internal encrypted data buffer */ - connssl->encdata_length += CURL_SCHANNEL_BUFFER_STEP_SIZE; + connssl->encdata_length *= CURL_SCHANNEL_BUFFER_STEP_FACTOR; connssl->encdata_buffer = realloc(connssl->encdata_buffer, connssl->encdata_length); + if(connssl->encdata_buffer == NULL) { failf(data, "schannel: unable to re-allocate memory"); *err = CURLE_OUT_OF_MEMORY; @@ -901,14 +914,21 @@ schannel_recv(struct connectdata *conn, int sockindex, inbuf[1].cbBuffer); /* increase buffer in order to fit the received amount of data */ - size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_STEP_SIZE ? - inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_STEP_SIZE; + size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ? + inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE; while(connssl->decdata_length - connssl->decdata_offset < size || connssl->decdata_length < len) { + if(connssl->decdata_length >= CURL_SCHANNEL_BUFFER_MAX_SIZE) { + failf(data, "schannel: memory buffer size limit reached"); + *err = CURLE_OUT_OF_MEMORY; + return -1; + } + /* increase internal decrypted data buffer */ - connssl->decdata_length += size; + connssl->decdata_length *= CURL_SCHANNEL_BUFFER_STEP_FACTOR; connssl->decdata_buffer = realloc(connssl->decdata_buffer, connssl->decdata_length); + if(connssl->decdata_buffer == NULL) { failf(data, "schannel: unable to re-allocate memory"); *err = CURLE_OUT_OF_MEMORY; diff --git a/lib/curl_schannel.h b/lib/curl_schannel.h index 7cdd2d142..4f48f16e6 100644 --- a/lib/curl_schannel.h +++ b/lib/curl_schannel.h @@ -95,12 +95,15 @@ #ifdef BUFSIZE #define CURL_SCHANNEL_BUFFER_INIT_SIZE BUFSIZE -#define CURL_SCHANNEL_BUFFER_STEP_SIZE BUFSIZE/2 +#define CURL_SCHANNEL_BUFFER_FREE_SIZE BUFSIZE/2 #else #define CURL_SCHANNEL_BUFFER_INIT_SIZE 4096 -#define CURL_SCHANNEL_BUFFER_STEP_SIZE 2048 +#define CURL_SCHANNEL_BUFFER_FREE_SIZE 2048 #endif +#define CURL_SCHANNEL_BUFFER_MAX_SIZE CURL_SCHANNEL_BUFFER_INIT_SIZE*16 +#define CURL_SCHANNEL_BUFFER_STEP_FACTOR 2 + CURLcode Curl_schannel_connect(struct connectdata *conn, int sockindex); -- 2.50.1