diff options
author | Nikos Mavrogiannopoulos <nmav@crystal.(none)> | 2008-11-23 00:12:16 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@crystal.(none)> | 2008-11-23 00:12:16 +0200 |
commit | 745436e29f339da41249db1b715e28081373b190 (patch) | |
tree | 9d9523a25165a25bdaa62b534af01cf271c800f3 /lib | |
parent | f42d5b41fc63aab1d4c77128cbae9e8b25b24121 (diff) | |
download | gnutls-745436e29f339da41249db1b715e28081373b190.tar.gz |
When reading data from a buffer (gnutls_string) avoid memmoving all remaining data.
This will speed up short byte reads.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gnutls_buffers.c | 193 | ||||
-rw-r--r-- | lib/gnutls_int.h | 2 | ||||
-rw-r--r-- | lib/gnutls_str.c | 171 | ||||
-rw-r--r-- | lib/gnutls_str.h | 17 | ||||
-rw-r--r-- | lib/x509/dn.c | 7 |
5 files changed, 153 insertions, 237 deletions
diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index b52eb83185..2aef31cc13 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -217,63 +217,22 @@ _gnutls_record_buffer_get (content_type_t type, switch (type) { case GNUTLS_APPLICATION_DATA: - - if (length > session->internals.application_data_buffer.length) - { - length = session->internals.application_data_buffer.length; - } - + _gnutls_buffer_get_data( &session->internals.application_data_buffer, data, &length); _gnutls_buffers_log ("BUFFER[REC][AD]: Read %d bytes of Data(%d)\n", length, type); - - session->internals.application_data_buffer.length -= length; - memcpy (data, session->internals.application_data_buffer.data, length); - - /* overwrite buffer */ - memmove (session->internals.application_data_buffer.data, - &session->internals.application_data_buffer.data[length], - session->internals.application_data_buffer.length); - - /* we do no longer realloc the application_data_buffer.data, - * since it serves no practical reason. It also decreases - * performance. - */ break; case GNUTLS_HANDSHAKE: - if (length > session->internals.handshake_data_buffer.length) - { - length = session->internals.handshake_data_buffer.length; - } - + _gnutls_buffer_get_data( &session->internals.handshake_data_buffer, data, &length); _gnutls_buffers_log ("BUF[REC][HD]: Read %d bytes of Data(%d)\n", length, type); - - session->internals.handshake_data_buffer.length -= length; - memcpy (data, session->internals.handshake_data_buffer.data, length); - - /* overwrite buffer */ - memmove (session->internals.handshake_data_buffer.data, - &session->internals.handshake_data_buffer.data[length], - session->internals.handshake_data_buffer.length); - break; case GNUTLS_INNER_APPLICATION: - if (length > session->internals.ia_data_buffer.length) - length = session->internals.ia_data_buffer.length; + _gnutls_buffer_get_data( &session->internals.ia_data_buffer, data, &length); _gnutls_buffers_log ("BUF[REC][IA]: Read %d bytes of Data(%d)\n", length, type); - - session->internals.ia_data_buffer.length -= length; - memcpy (data, session->internals.ia_data_buffer.data, length); - - /* overwrite buffer */ - memmove (session->internals.ia_data_buffer.data, - &session->internals.ia_data_buffer.data[length], - session->internals.ia_data_buffer.length); - break; default: @@ -487,7 +446,7 @@ _gnutls_io_read_buffered (gnutls_session_t session, opaque ** iptr, int buf_pos; opaque *buf; int recvlowat; - int recvdata, alloc_size; + int recvdata; *iptr = session->internals.record_recv_buffer.data; @@ -551,14 +510,13 @@ _gnutls_io_read_buffered (gnutls_session_t session, opaque ** iptr, /* Allocate the data required to store the new packet. */ - alloc_size = recvdata + session->internals.record_recv_buffer.length; - session->internals.record_recv_buffer.data = - gnutls_realloc_fast (session->internals.record_recv_buffer.data, - alloc_size); - if (session->internals.record_recv_buffer.data == NULL) + ret = _gnutls_buffer_resize( &session->internals.record_recv_buffer, + recvdata + session->internals.record_recv_buffer.length); + + if (ret < 0) { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; + gnutls_assert(); + return ret; } buf_pos = session->internals.record_recv_buffer.length; @@ -654,64 +612,6 @@ _gnutls_io_read_buffered (gnutls_session_t session, opaque ** iptr, } } - -/* These two functions are used to insert data to the send buffer of the handshake or - * record protocol. The send buffer is kept if a send is interrupted and we need to keep - * the data left to sent, in order to send them later. - */ - -#define MEMSUB(x,y) ((ssize_t)((ptrdiff_t)x-(ptrdiff_t)y)) - -inline static int -_gnutls_buffer_insert (gnutls_buffer * buffer, - const opaque * _data, size_t data_size) -{ - - if ((MEMSUB (_data, buffer->data) >= 0) - && (MEMSUB (_data, buffer->data) < (ssize_t) buffer->length)) - { - /* the given _data is part of the buffer. - */ - if (data_size > buffer->length) - { - gnutls_assert (); - /* this shouldn't have happened */ - return GNUTLS_E_INTERNAL_ERROR; - } - - if (_data == buffer->data) - { /* then don't even memmove */ - buffer->length = data_size; - return 0; - } - - memmove (buffer->data, _data, data_size); - buffer->length = data_size; - - return 0; - - } - - if (_gnutls_buffer_append (buffer, _data, data_size) < 0) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - return 0; -} - -inline static int -_gnutls_buffer_get (gnutls_buffer * buffer, - const opaque ** ptr, size_t * ptr_size) -{ - *ptr_size = buffer->length; - *ptr = buffer->data; - - return 0; -} - - /* This function is like write. But it does not return -1 on error. * It does return gnutls_errno instead. * @@ -754,14 +654,12 @@ _gnutls_io_write_buffered (gnutls_session_t session, */ if (iptr == NULL) { + gnutls_datum bdata; /* checking is handled above */ - ret = - _gnutls_buffer_get (&session->internals.record_send_buffer, &ptr, &n); - if (ret < 0) - { - gnutls_assert (); - return ret; - } + _gnutls_buffer_get_datum (&session->internals.record_send_buffer, &bdata, n); + + ptr = bdata.data; + n = bdata.size; _gnutls_write_log ("WRITE: Restoring old write. (%d bytes to send)\n", n); @@ -814,7 +712,7 @@ _gnutls_io_write_buffered (gnutls_session_t session, session->internals.record_send_buffer_prev_size += n - left; retval = - _gnutls_buffer_insert (&session->internals.record_send_buffer, + _gnutls_buffer_append (&session->internals.record_send_buffer, &ptr[n - left], left); if (retval < 0) { @@ -948,17 +846,17 @@ _gnutls_handshake_io_send_int (gnutls_session_t session, if (session->internals.handshake_send_buffer.length > 0 && ptr == NULL && n == 0) { + gnutls_datum bdata; + /* resuming previously interrupted write */ gnutls_assert (); - ret = - _gnutls_buffer_get (&session->internals.handshake_send_buffer, - &ptr, &n); - if (ret < 0) - { - gnutls_assert (); - return retval; - } + + /* checking is handled above */ + _gnutls_buffer_get_datum (&session->internals.handshake_send_buffer, &bdata, n); + + ptr = bdata.data; + n = bdata.size; type = session->internals.handshake_send_buffer_type; htype = session->internals.handshake_send_buffer_htype; @@ -1028,7 +926,7 @@ _gnutls_handshake_io_send_int (gnutls_session_t session, gnutls_assert (); retval = - _gnutls_buffer_insert (&session->internals. + _gnutls_buffer_append (&session->internals. handshake_send_buffer, &ptr[n - left], left); if (retval < 0) @@ -1089,33 +987,27 @@ _gnutls_handshake_io_recv_int (gnutls_session_t session, if (session->internals.handshake_recv_buffer.length > 0) { + size_t tmp; + /* if we have already received some data */ if (sizeOfPtr <= session->internals.handshake_recv_buffer.length) { /* if requested less data then return it. */ gnutls_assert (); - memcpy (iptr, session->internals.handshake_recv_buffer.data, - sizeOfPtr); - - session->internals.handshake_recv_buffer.length -= sizeOfPtr; - - memmove (session->internals.handshake_recv_buffer.data, - &session->internals.handshake_recv_buffer.data[sizeOfPtr], - session->internals.handshake_recv_buffer.length); - - return sizeOfPtr; + + tmp = sizeOfPtr; + _gnutls_string_get_data( &session->internals.handshake_recv_buffer, iptr, &tmp); + return tmp; } gnutls_assert (); - memcpy (iptr, session->internals.handshake_recv_buffer.data, - session->internals.handshake_recv_buffer.length); + + tmp = sizeOfPtr; + _gnutls_string_get_data( &session->internals.handshake_recv_buffer, iptr, &tmp); + left -= tmp; htype = session->internals.handshake_recv_buffer_htype; type = session->internals.handshake_recv_buffer_type; - - left -= session->internals.handshake_recv_buffer.length; - - session->internals.handshake_recv_buffer.length = 0; } while (left > 0) @@ -1129,25 +1021,12 @@ _gnutls_handshake_io_recv_int (gnutls_session_t session, { gnutls_assert (); - session->internals.handshake_recv_buffer.data = - gnutls_realloc_fast (session->internals. - handshake_recv_buffer.data, dsize); - if (session->internals.handshake_recv_buffer.data == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - memcpy (session->internals.handshake_recv_buffer.data, iptr, + _gnutls_buffer_append (&session->internals.handshake_recv_buffer, iptr, dsize); session->internals.handshake_recv_buffer_htype = htype; session->internals.handshake_recv_buffer_type = type; - - session->internals.handshake_recv_buffer.length = dsize; } - else - session->internals.handshake_recv_buffer.length = 0; gnutls_assert (); diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 489cf11e38..38c2e44d22 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -123,6 +123,8 @@ typedef struct #include <gnutls_mem.h> +#define MEMSUB(x,y) ((ssize_t)((ptrdiff_t)x-(ptrdiff_t)y)) + #define DECR_LEN(len, x) do { len-=x; if (len<0) {gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;} } while (0) #define DECR_LENGTH_RET(len, x, RET) do { len-=x; if (len<0) {gnutls_assert(); return RET;} } while (0) #define DECR_LENGTH_COM(len, x, COM) do { len-=x; if (len<0) {gnutls_assert(); COM;} } while (0) diff --git a/lib/gnutls_str.c b/lib/gnutls_str.c index 7e6a435080..f1bc46e001 100644 --- a/lib/gnutls_str.c +++ b/lib/gnutls_str.c @@ -97,7 +97,7 @@ _gnutls_string_init (gnutls_string * str, gnutls_realloc_function realloc_func, gnutls_free_function free_func) { - str->data = NULL; + str->data = str->allocd = NULL; str->max_length = 0; str->length = 0; @@ -109,123 +109,156 @@ _gnutls_string_init (gnutls_string * str, void _gnutls_string_clear (gnutls_string * str) { - if (str == NULL || str->data == NULL) + if (str == NULL || str->allocd == NULL) return; - str->free_func (str->data); + str->free_func (str->allocd); - str->data = NULL; + str->data = str->allocd = NULL; str->max_length = 0; str->length = 0; } -/* This one does not copy the string. - */ -gnutls_datum_t -_gnutls_string2datum (gnutls_string * str) -{ - gnutls_datum_t ret; - - ret.data = str->data; - ret.size = str->length; - - return ret; -} - #define MIN_CHUNK 256 int -_gnutls_string_copy_str (gnutls_string * dest, const char *src) +_gnutls_string_append_data (gnutls_string * dest, const void *data, + size_t data_size) { - size_t src_len = strlen (src); + size_t tot_len = data_size + dest->length; - if (dest->max_length >= src_len) + if (dest->max_length >= tot_len) { - memcpy (dest->data, src, src_len); - dest->length = src_len; + size_t unused = MEMSUB(dest->data, dest->allocd); + + if (dest->max_length - unused <= tot_len) + { + if (dest->length && dest->data) + memmove(dest->allocd, dest->data, dest->length); + + dest->data = dest->allocd; + } + memcpy (&dest->data[dest->length], data, data_size); + dest->length = tot_len; - return src_len; + return tot_len; } else { - dest->data = dest->realloc_func (dest->data, MAX (src_len, MIN_CHUNK)); - if (dest->data == NULL) + size_t unused = MEMSUB(dest->data, dest->allocd); + size_t new_len = + MAX (data_size, MIN_CHUNK) + MAX (dest->max_length, MIN_CHUNK); + + dest->allocd = dest->realloc_func (dest->allocd, new_len); + if (dest->allocd == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } - dest->max_length = MAX (MIN_CHUNK, src_len); + dest->max_length = new_len; + dest->data = dest->allocd + unused; + + if (dest->length && dest->data) + memmove(dest->allocd, dest->data, dest->length); + dest->data = dest->allocd; - memcpy (dest->data, src, src_len); - dest->length = src_len; + memcpy (&dest->data[dest->length], data, data_size); + dest->length = tot_len; - return src_len; + return tot_len; } } int -_gnutls_string_append_str (gnutls_string * dest, const char *src) +_gnutls_string_resize (gnutls_string * dest, size_t new_size) { - size_t src_len = strlen (src); - size_t tot_len = src_len + dest->length; - - if (dest->max_length >= tot_len) + if (dest->max_length >= new_size) { - memcpy (&dest->data[dest->length], src, src_len); - dest->length = tot_len; + size_t unused = MEMSUB(dest->data, dest->allocd); + if (dest->max_length - unused <= new_size) + { + if (dest->length && dest->data) + memmove(dest->allocd, dest->data, dest->length); + dest->data = dest->allocd; + } - return tot_len; + return 0; } else { - size_t new_len = - MAX (src_len, MIN_CHUNK) + MAX (dest->max_length, MIN_CHUNK); + size_t unused = MEMSUB(dest->data, dest->allocd); + size_t alloc_len = + MAX (new_size, MIN_CHUNK) + MAX (dest->max_length, MIN_CHUNK); - dest->data = dest->realloc_func (dest->data, new_len); - if (dest->data == NULL) + dest->allocd = dest->realloc_func (dest->allocd, alloc_len); + if (dest->allocd == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } - dest->max_length = new_len; + dest->max_length = alloc_len; + dest->data = dest->allocd + unused; - memcpy (&dest->data[dest->length], src, src_len); - dest->length = tot_len; + if (dest->length && dest->data) + memmove(dest->allocd, dest->data, dest->length); + dest->data = dest->allocd; - return tot_len; + return 0; } } int -_gnutls_string_append_data (gnutls_string * dest, const void *data, - size_t data_size) +_gnutls_string_append_str (gnutls_string * dest, const char *src) { - size_t tot_len = data_size + dest->length; + return _gnutls_string_append_data (dest, src, strlen(src)); +} - if (dest->max_length >= tot_len) - { - memcpy (&dest->data[dest->length], data, data_size); - dest->length = tot_len; +/* returns data from a string in a constant buffer. + * The data will NOT be valid if buffer is released or + * data are appended in the buffer. + */ +void +_gnutls_string_get_datum (gnutls_string * str, gnutls_datum *data, + size_t req_size) +{ - return tot_len; - } - else - { - size_t new_len = - MAX (data_size, MIN_CHUNK) + MAX (dest->max_length, MIN_CHUNK); + if (str->length == 0) { + data->data = NULL; + data->size = 0; + return; + } + + if (req_size > str->length) + req_size = str->length; + + data->data = str->data; + data->size = req_size; + + str->data += req_size; + str->length -= req_size; + + /* if string becomes empty start from begining */ + if (str->length == 0) { + str->data = str->allocd; + } + + return; + +} - dest->data = dest->realloc_func (dest->data, new_len); - if (dest->data == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - dest->max_length = new_len; +/* returns data from a string in a constant buffer. + */ +void +_gnutls_string_get_data (gnutls_string * str, void *data, + size_t *req_size) +{ +gnutls_datum tdata; - memcpy (&dest->data[dest->length], data, data_size); - dest->length = tot_len; + _gnutls_string_get_datum( str, &tdata, *req_size); - return tot_len; - } + *req_size = tdata.size; + memcpy( data, tdata.data, tdata.size); + + return; } int diff --git a/lib/gnutls_str.h b/lib/gnutls_str.h index 6b84fcae64..1a5dec6c9e 100644 --- a/lib/gnutls_str.h +++ b/lib/gnutls_str.h @@ -34,9 +34,10 @@ void _gnutls_str_cat (char *dest, size_t dest_tot_size, const char *src); typedef struct { - opaque *data; + opaque *allocd; /* pointer to allocated data */ + opaque *data; /* API: pointer to data to copy from */ size_t max_length; - size_t length; + size_t length; /* API: current length */ gnutls_realloc_function realloc_func; gnutls_alloc_function alloc_func; gnutls_free_function free_func; @@ -45,17 +46,14 @@ typedef struct void _gnutls_string_init (gnutls_string *, gnutls_alloc_function, gnutls_realloc_function, gnutls_free_function); void _gnutls_string_clear (gnutls_string *); +int _gnutls_string_resize (gnutls_string *, size_t new_size); -/* Beware, do not clear the string, after calling this - * function - */ -gnutls_datum_t _gnutls_string2datum (gnutls_string * str); - -int _gnutls_string_copy_str (gnutls_string * dest, const char *src); int _gnutls_string_append_str (gnutls_string *, const char *str); int _gnutls_string_append_data (gnutls_string *, const void *data, size_t data_size); +void _gnutls_string_get_data( gnutls_string *, void*, size_t *size); +void _gnutls_string_get_datum( gnutls_string *, gnutls_datum*, size_t max_size); #ifndef __attribute__ /* This feature is available in gcc versions 2.5 and later. */ @@ -72,6 +70,9 @@ typedef gnutls_string gnutls_buffer; #define _gnutls_buffer_init(buf) _gnutls_string_init(buf, gnutls_malloc, gnutls_realloc, gnutls_free); #define _gnutls_buffer_clear _gnutls_string_clear #define _gnutls_buffer_append _gnutls_string_append_data +#define _gnutls_buffer_get_datum _gnutls_string_get_datum +#define _gnutls_buffer_get_data _gnutls_string_get_data +#define _gnutls_buffer_resize _gnutls_string_resize char *_gnutls_bin2hex (const void *old, size_t oldlen, char *buffer, size_t buffer_size); diff --git a/lib/x509/dn.c b/lib/x509/dn.c index e714b3298e..79b803227b 100644 --- a/lib/x509/dn.c +++ b/lib/x509/dn.c @@ -307,10 +307,11 @@ _gnutls_x509_parse_dn (ASN1_TYPE asn1_struct, if (buf) { - memcpy (buf, out_str.data, out_str.length); - buf[out_str.length] = 0; + _gnutls_string_get_data( &out_str, buf, sizeof_buf); + buf[*sizeof_buf] = 0; } - *sizeof_buf = out_str.length; + else + *sizeof_buf = out_str.length; result = 0; |