summaryrefslogtreecommitdiff
path: root/lib/gnutls_buffers.c
diff options
context:
space:
mode:
authorJonathan Bastien-Filiatrault <joe@x2a.org>2010-09-08 18:34:45 -0400
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2010-09-09 08:35:03 +0200
commite545991e0bbd011706626b8fddf05dd3e2612bf8 (patch)
tree169863511d503b1d0821c4a47eec43bbbf842307 /lib/gnutls_buffers.c
parent74f6fb83e2801986c83e461fa15ef8b3479af20d (diff)
downloadgnutls-e545991e0bbd011706626b8fddf05dd3e2612bf8.tar.gz
mbuffers: make _gnutls_io_read_buffered use mbuffers.
This will be needed by the DTLS code to make sure reads are stored in segments that correspond to datagram boundaries. Signed-off-by: Jonathan Bastien-Filiatrault <joe@x2a.org> Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
Diffstat (limited to 'lib/gnutls_buffers.c')
-rw-r--r--lib/gnutls_buffers.c85
1 files changed, 39 insertions, 46 deletions
diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c
index 34ef9df5ac..c44765f52d 100644
--- a/lib/gnutls_buffers.c
+++ b/lib/gnutls_buffers.c
@@ -445,36 +445,26 @@ _gnutls_io_clear_peeked_data (gnutls_session_t session)
return 0;
}
-
-void
-_gnutls_io_clear_read_buffer (gnutls_session_t session)
-{
- session->internals.record_recv_buffer.length = 0;
-}
-
/* This function is like recv(with MSG_PEEK). But it does not return -1 on error.
* It does return gnutls_errno instead.
* This function reads data from the socket and keeps them in a buffer, of up to
* MAX_RECV_SIZE.
*
* This is not a general purpose function. It returns EXACTLY the data requested,
- * which are stored in a local (in the session) buffer. A pointer (iptr) to this buffer is returned.
+ * which are stored in a local (in the session) buffer.
*
*/
ssize_t
-_gnutls_io_read_buffered (gnutls_session_t session, opaque ** iptr,
- size_t sizeOfPtr, content_type_t recv_type)
+_gnutls_io_read_buffered (gnutls_session_t session, size_t total,
+ content_type_t recv_type)
{
ssize_t ret = 0, ret2 = 0;
size_t min;
- int buf_pos;
- opaque *buf;
- int recvlowat;
- int recvdata;
+ opaque buf[MAX_RECV_SIZE];
+ mbuffer_st *bufel;
+ size_t recvlowat, recvdata, readsize;
- *iptr = session->internals.record_recv_buffer.data;
-
- if (sizeOfPtr > MAX_RECV_SIZE || sizeOfPtr == 0)
+ if (total > MAX_RECV_SIZE || total == 0)
{
gnutls_assert (); /* internal error */
return GNUTLS_E_INVALID_REQUEST;
@@ -505,13 +495,13 @@ _gnutls_io_read_buffered (gnutls_session_t session, opaque ** iptr,
/* calculate the actual size, ie. get the minimum of the
* buffered data and the requested data.
*/
- min = MIN (session->internals.record_recv_buffer.length, sizeOfPtr);
+ min = MIN (session->internals.record_recv_buffer.byte_length, total);
if (min > 0)
{
/* if we have enough buffered data
* then just return them.
*/
- if (min == sizeOfPtr)
+ if (min == total)
{
return min;
}
@@ -520,39 +510,30 @@ _gnutls_io_read_buffered (gnutls_session_t session, opaque ** iptr,
/* min is over zero. recvdata is the data we must
* receive in order to return the requested data.
*/
- recvdata = sizeOfPtr - min;
+ recvdata = total - min;
+ readsize = recvdata - recvlowat;
/* Check if the previously read data plus the new data to
* receive are longer than the maximum receive buffer size.
*/
- if ((session->internals.record_recv_buffer.length + recvdata) >
+ if ((session->internals.record_recv_buffer.byte_length + recvdata) >
MAX_RECV_SIZE)
{
gnutls_assert (); /* internal error */
return GNUTLS_E_INVALID_REQUEST;
}
- /* Allocate the data required to store the new packet.
- */
- ret = _gnutls_buffer_resize (&session->internals.record_recv_buffer,
- recvdata +
- session->internals.record_recv_buffer.length);
-
if (ret < 0)
{
gnutls_assert ();
return ret;
}
- buf_pos = session->internals.record_recv_buffer.length;
- buf = session->internals.record_recv_buffer.data;
- *iptr = buf;
-
/* READ DATA - but leave RCVLOWAT bytes in the kernel buffer.
*/
- if (recvdata - recvlowat > 0)
+ if (readsize > 0)
{
- ret = _gnutls_read (session, &buf[buf_pos], recvdata - recvlowat, session->internals.pull_func);
+ ret = _gnutls_read (session, buf, readsize, session->internals.pull_func);
/* return immediately if we got an interrupt or eagain
* error.
@@ -569,21 +550,27 @@ _gnutls_io_read_buffered (gnutls_session_t session, opaque ** iptr,
{
_gnutls_read_log
("RB: Have %d bytes into buffer. Adding %d bytes.\n",
- (int) session->internals.record_recv_buffer.length, (int) ret);
- _gnutls_read_log ("RB: Requested %d bytes\n", (int) sizeOfPtr);
- session->internals.record_recv_buffer.length += ret;
- }
+ (int) session->internals.record_recv_buffer.byte_length, (int) ret);
+ _gnutls_read_log ("RB: Requested %d bytes\n", (int) total);
- buf_pos = session->internals.record_recv_buffer.length;
+ bufel = _mbuffer_alloc (0, ret);
+ if (!bufel)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ _mbuffer_append_data (bufel, buf, ret);
+ _mbuffer_enqueue (&session->internals.record_recv_buffer, bufel);
+ }
/* This is hack in order for select to work. Just leave recvlowat data,
* into the kernel buffer (using a read with MSG_PEEK), thus making
* select think, that the socket is ready for reading.
* MSG_PEEK is only used with berkeley style sockets.
*/
- if (ret == (recvdata - recvlowat) && recvlowat > 0)
+ if (ret == readsize && recvlowat > 0)
{
- ret2 = _gnutls_read (session, &buf[buf_pos], recvlowat, system_read_peek);
+ ret2 = _gnutls_read (session, buf, recvlowat, system_read_peek);
if (ret2 < 0 && gnutls_error_is_fatal (ret2) == 0)
{
@@ -596,11 +583,17 @@ _gnutls_io_read_buffered (gnutls_session_t session, opaque ** iptr,
(int) ret2);
_gnutls_read_log
("RB-PEEK: Have %d bytes into buffer. Adding %d bytes.\nRB: Requested %d bytes\n",
- (int) session->internals.record_recv_buffer.length, (int) ret2,
- (int) sizeOfPtr);
+ (int) session->internals.record_recv_buffer.byte_length, (int) ret2,
+ (int) total);
session->internals.have_peeked_data = 1;
- session->internals.record_recv_buffer.length += ret2;
-
+ bufel = _mbuffer_alloc (0, ret2);
+ if (!bufel)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+ _mbuffer_append_data (bufel, buf, ret2);
+ _mbuffer_enqueue (&session->internals.record_recv_buffer, bufel);
}
}
@@ -625,9 +618,9 @@ _gnutls_io_read_buffered (gnutls_session_t session, opaque ** iptr,
return 0;
}
- ret = session->internals.record_recv_buffer.length;
+ ret = session->internals.record_recv_buffer.byte_length;
- if ((ret > 0) && ((size_t) ret < sizeOfPtr))
+ if ((ret > 0) && ((size_t) ret < total))
{
/* Short Read */
gnutls_assert ();