summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@crystal.(none)>2008-11-23 00:12:16 +0200
committerNikos Mavrogiannopoulos <nmav@crystal.(none)>2008-11-23 00:12:16 +0200
commit745436e29f339da41249db1b715e28081373b190 (patch)
tree9d9523a25165a25bdaa62b534af01cf271c800f3 /lib
parentf42d5b41fc63aab1d4c77128cbae9e8b25b24121 (diff)
downloadgnutls-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.c193
-rw-r--r--lib/gnutls_int.h2
-rw-r--r--lib/gnutls_str.c171
-rw-r--r--lib/gnutls_str.h17
-rw-r--r--lib/x509/dn.c7
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;