Commit 006b8379 authored by Marc Hoersken's avatar Marc Hoersken Committed by Daniel Stenberg
Browse files

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.
parent 293c9288
Loading
Loading
Loading
Loading
+29 −9
Original line number Diff line number Diff line
@@ -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;
+5 −2
Original line number Diff line number Diff line
@@ -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);