From: Nikos Mavrogiannopoulos Date: Mon, 14 Jun 2010 17:08:41 +0000 (+0200) Subject: Appending data in mbuffers is now cheaper by avoiding realloc, at the cost X-Git-Tag: gnutls_2_11_3~181 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e044aabe9f67af9781e512d597315e79ca13f4fe;p=thirdparty%2Fgnutls.git Appending data in mbuffers is now cheaper by avoiding realloc, at the cost of requiring to specify a maximum mbuffer size at creation. --- diff --git a/lib/ext_session_ticket.c b/lib/ext_session_ticket.c index fafb1747b2..69e4ee9221 100644 --- a/lib/ext_session_ticket.c +++ b/lib/ext_session_ticket.c @@ -663,7 +663,7 @@ _gnutls_send_new_session_ticket (gnutls_session_t session, int again) ticket_len = KEY_NAME_SIZE + IV_SIZE + 2 + ticket.encrypted_state_len + MAC_SIZE; - bufel = _gnutls_handshake_alloc (4 + 2 + ticket_len); + bufel = _gnutls_handshake_alloc (4 + 2 + ticket_len, 4+2+ticket_len); if (!bufel) { gnutls_assert (); diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index a84dd42aaf..8a8a3f1355 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -655,7 +655,7 @@ _gnutls_send_finished (gnutls_session_t session, int again) if (again == 0) { - bufel = _gnutls_handshake_alloc (MAX_VERIFY_DATA_SIZE); + bufel = _gnutls_handshake_alloc (MAX_VERIFY_DATA_SIZE, MAX_VERIFY_DATA_SIZE); if (bufel == NULL) { gnutls_assert (); @@ -1046,7 +1046,7 @@ _gnutls_send_empty_handshake (gnutls_session_t session, if (again == 0) { - bufel = _gnutls_handshake_alloc (0); + bufel = _gnutls_handshake_alloc (0, 0); if (bufel == NULL) { gnutls_assert (); @@ -1913,7 +1913,7 @@ _gnutls_copy_comp_methods (gnutls_session_t session, /* This should be sufficient by now. It should hold all the extensions * plus the headers in a hello message. */ -#define MAX_EXT_DATA_LENGTH 65535 +#define MAX_EXT_DATA_LENGTH 32*1024 /* This function sends the client hello handshake message. */ @@ -1944,7 +1944,7 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) /* 2 for version, (4 for unix time + 28 for random bytes==GNUTLS_RANDOM_SIZE) */ - bufel = _gnutls_handshake_alloc (datalen); + bufel = _gnutls_handshake_alloc (datalen, datalen+MAX_EXT_DATA_LENGTH); if (bufel == NULL) { gnutls_assert (); @@ -2051,12 +2051,12 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) if (ret > 0) { - bufel = _mbuffer_push_data (bufel, extdata, ret); - if (bufel == NULL) + ret = _mbuffer_append_data (bufel, extdata, ret); + if (ret < 0) { gnutls_assert (); gnutls_free (extdata); - return GNUTLS_E_MEMORY_ERROR; + return ret; } } else @@ -2075,12 +2075,12 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) ret = _gnutls_copy_comp_methods (session, extdata, extdatalen); if (ret > 0) { - bufel = _mbuffer_push_data (bufel, extdata, ret); - if (bufel == NULL) + ret = _mbuffer_append_data (bufel, extdata, ret); + if (ret < 0) { gnutls_assert (); gnutls_free (extdata); - return GNUTLS_E_MEMORY_ERROR; + return ret; } } else @@ -2109,12 +2109,12 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) if (ret > 0) { - bufel = _mbuffer_push_data (bufel, extdata, ret); - if (bufel == NULL) + ret = _mbuffer_append_data (bufel, extdata, ret); + if (ret < 0) { gnutls_assert (); gnutls_free (extdata); - return GNUTLS_E_MEMORY_ERROR; + return ret; } } else if (ret < 0) @@ -2170,7 +2170,7 @@ _gnutls_send_server_hello (gnutls_session_t session, int again) } extdatalen = ret; - bufel = _gnutls_handshake_alloc (datalen + extdatalen); + bufel = _gnutls_handshake_alloc (datalen + extdatalen, datalen + extdatalen); if (bufel == NULL) { gnutls_assert (); @@ -2472,7 +2472,7 @@ _gnutls_send_supplemental (gnutls_session_t session, int again) return ret; } - bufel = _gnutls_handshake_alloc(buf.length); + bufel = _gnutls_handshake_alloc(buf.length, buf.length); if (bufel == NULL) { gnutls_assert (); diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 47bd385074..36b40a9864 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -207,6 +207,7 @@ typedef struct mbuffer_st head of the queue. */ size_t mark; unsigned int user_mark; /* only used during fill in */ + size_t maximum_size; } mbuffer_st; typedef struct mbuffer_head_st diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c index 9f1f5a7927..0eb6f3c150 100644 --- a/lib/gnutls_kx.c +++ b/lib/gnutls_kx.c @@ -59,7 +59,7 @@ send_handshake (gnutls_session_t session, opaque *data, size_t size, return GNUTLS_E_INVALID_REQUEST; } - bufel = _gnutls_handshake_alloc(size); + bufel = _gnutls_handshake_alloc(size, size); if (bufel == NULL) { gnutls_assert (); diff --git a/lib/gnutls_mbuffers.c b/lib/gnutls_mbuffers.c index db9763bc4b..cb360e38d6 100644 --- a/lib/gnutls_mbuffers.c +++ b/lib/gnutls_mbuffers.c @@ -130,11 +130,11 @@ _mbuffer_remove_bytes (mbuffer_head_st *buf, size_t bytes) } mbuffer_st * -_mbuffer_alloc (size_t payload_size) +_mbuffer_alloc (size_t payload_size, size_t maximum_size) { mbuffer_st * st; - st = gnutls_malloc (payload_size+sizeof (mbuffer_st)); + st = gnutls_malloc (maximum_size+sizeof (mbuffer_st)); if (st == NULL) { gnutls_assert (); @@ -147,22 +147,24 @@ _mbuffer_alloc (size_t payload_size) st->mark = 0; st->user_mark = 0; st->next = NULL; + st->maximum_size = maximum_size; return st; } -mbuffer_st* -_mbuffer_push_data (mbuffer_st *bufel, void* newdata, size_t newdata_size) +int +_mbuffer_append_data (mbuffer_st *bufel, void* newdata, size_t newdata_size) { - bufel = gnutls_realloc_fast (bufel, bufel->msg.size+newdata_size+sizeof (mbuffer_st)); - if (bufel == NULL) + if (sizeof(mbuffer_st)+bufel->msg.size+newdata_size < bufel->maximum_size) { - gnutls_assert (); - return NULL; + memcpy(&bufel->msg.data[bufel->msg.size], newdata, newdata_size); + bufel->msg.size+=newdata_size; + } + else + { + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; } - bufel->msg.data = (opaque*)bufel + sizeof (mbuffer_st); - memcpy(&bufel->msg.data[bufel->msg.size], newdata, newdata_size); - bufel->msg.size += newdata_size; - return bufel; + return 0; } diff --git a/lib/gnutls_mbuffers.h b/lib/gnutls_mbuffers.h index 3580a420e2..1ea67184fc 100644 --- a/lib/gnutls_mbuffers.h +++ b/lib/gnutls_mbuffers.h @@ -32,12 +32,12 @@ void _mbuffer_clear (mbuffer_head_st *buf); void _mbuffer_enqueue (mbuffer_head_st *buf, mbuffer_st *bufel); void _mbuffer_get_head (mbuffer_head_st *buf, gnutls_datum_t *msg); int _mbuffer_remove_bytes (mbuffer_head_st *buf, size_t bytes); -mbuffer_st* _mbuffer_alloc (size_t payload_size); +mbuffer_st* _mbuffer_alloc (size_t payload_size, size_t maximum_size); /* This is dangerous since it will replace bufel with a new * one. */ -mbuffer_st* _mbuffer_push_data (mbuffer_st *bufel, void* newdata, size_t newdata_size); +int _mbuffer_append_data (mbuffer_st *bufel, void* newdata, size_t newdata_size); /* For "user" use. One can have buffer data and header. @@ -80,9 +80,9 @@ inline static void _mbuffer_set_uhead_size(mbuffer_st *bufel, size_t size) -inline static mbuffer_st* _gnutls_handshake_alloc(size_t size) +inline static mbuffer_st* _gnutls_handshake_alloc(size_t size, size_t maximum) { - mbuffer_st *ret = _mbuffer_alloc (HANDSHAKE_HEADER_SIZE + size); + mbuffer_st *ret = _mbuffer_alloc (HANDSHAKE_HEADER_SIZE + size, HANDSHAKE_HEADER_SIZE+maximum); if (!ret) return NULL; diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index c2c3a9b30a..9ea214e257 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -400,7 +400,7 @@ _gnutls_send_int (gnutls_session_t session, content_type_t type, /* now proceed to packet encryption */ cipher_size = data2send_size + MAX_RECORD_OVERHEAD; - bufel = _mbuffer_alloc (cipher_size); + bufel = _mbuffer_alloc (cipher_size, cipher_size); if (bufel == NULL) { gnutls_assert ();