schannel: Implement new buffer size strategy
authorMarc Hoersken <info@marc-hoersken.de>
Wed, 20 Jun 2012 05:49:34 +0000 (07:49 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 20 Jun 2012 20:59:03 +0000 (22:59 +0200)
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
lib/curl_schannel.h

index c7d0468..dc8b21e 100644 (file)
@@ -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;
index 7cdd2d1..4f48f16 100644 (file)
 
 #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);