[PATCH 8/8] Fully mbufferize _gnutls_read and _gnutls_read_buffered.

Jonathan Bastien-Filiatrault joe at x2a.org
Thu Sep 9 00:34:47 CEST 2010


Signed-off-by: Jonathan Bastien-Filiatrault <joe at x2a.org>

diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c
index c44765f..be84e90 100644
--- a/lib/gnutls_buffers.c
+++ b/lib/gnutls_buffers.c
@@ -269,23 +269,36 @@ inline static int get_errno(gnutls_session_t session)
  * Flags are only used if the default recv() function is being used.
  */
 static ssize_t
-_gnutls_read (gnutls_session_t session, void *iptr,
-	      size_t sizeOfPtr, gnutls_pull_func pull_func)
+_gnutls_read (gnutls_session_t session, mbuffer_st **bufel,
+	      size_t size, gnutls_pull_func pull_func)
 {
   size_t left;
   ssize_t i = 0;
-  char *ptr = iptr;
+  char *ptr;
   gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;
 
+  if (!bufel)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INTERNAL_ERROR;
+    }
+
+  *bufel = _mbuffer_alloc (0, size);
+  if (!*bufel)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+  ptr = (*bufel)->msg.data;
+
   session->internals.direction = 0;
 
-  left = sizeOfPtr;
+  left = size;
   while (left > 0)
     {
-
       reset_errno(session);
 
-      i = pull_func (fd, &ptr[sizeOfPtr - left], left);
+      i = pull_func (fd, &ptr[size - left], left);
 
       if (i < 0)
 	{
@@ -296,11 +309,11 @@ _gnutls_read (gnutls_session_t session, void *iptr,
 
 	  if (err == EAGAIN || err == EINTR)
 	    {
-	      if (sizeOfPtr - left > 0)
+	      if (size - left > 0)
 		{
 
 		  _gnutls_read_log ("READ: returning %d bytes from %p\n",
-				    (int) (sizeOfPtr - left), fd);
+				    (int) (size - left), fd);
 
 		  goto finish;
 		}
@@ -325,7 +338,7 @@ _gnutls_read (gnutls_session_t session, void *iptr,
 	}
 
       left -= i;
-
+      (*bufel)->msg.size += i;
     }
 
 finish:
@@ -333,11 +346,11 @@ finish:
   if (_gnutls_log_level >= 7)
     {
       _gnutls_read_log ("READ: read %d bytes from %p\n",
-			(int) (sizeOfPtr - left), fd);
+			(int) (size - left), fd);
 
     }
 
-  return (sizeOfPtr - left);
+  return (size - left);
 }
 
 
@@ -408,32 +421,24 @@ _gnutls_debug_log("errno: %d\n", err);
 int
 _gnutls_io_clear_peeked_data (gnutls_session_t session)
 {
-  char *peekdata;
+  mbuffer_st *peekdata;
   int ret, sum;
 
   if (session->internals.have_peeked_data == 0 || RCVLOWAT == 0)
     return 0;
 
-  peekdata = gnutls_malloc (RCVLOWAT);
-  if (peekdata == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
   /* this was already read by using MSG_PEEK - so it shouldn't fail */
   sum = 0;
   do
     {				/* we need this to finish now */
-      ret = _gnutls_read (session, peekdata, RCVLOWAT - sum, session->internals.pull_func);
+      ret = _gnutls_read (session, &peekdata, RCVLOWAT - sum, session->internals.pull_func);
       if (ret > 0)
 	sum += ret;
+      _mbuffer_xfree (&peekdata);
     }
   while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN
 	 || sum < RCVLOWAT);
 
-  gnutls_free (peekdata);
-
   if (ret < 0)
     {
       gnutls_assert ();
@@ -460,8 +465,7 @@ _gnutls_io_read_buffered (gnutls_session_t session, size_t total,
 {
   ssize_t ret = 0, ret2 = 0;
   size_t min;
-  opaque buf[MAX_RECV_SIZE];
-  mbuffer_st *bufel;
+  mbuffer_st *bufel=NULL;
   size_t recvlowat, recvdata, readsize;
 
   if (total > MAX_RECV_SIZE || total == 0)
@@ -533,13 +537,14 @@ _gnutls_io_read_buffered (gnutls_session_t session, size_t total,
    */
   if (readsize > 0)
     {
-      ret = _gnutls_read (session, buf, readsize, session->internals.pull_func);
+      ret = _gnutls_read (session, &bufel, readsize, session->internals.pull_func);
 
       /* return immediately if we got an interrupt or eagain
        * error.
        */
       if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
 	{
+	  _mbuffer_xfree(&bufel);
 	  return ret;
 	}
     }
@@ -553,15 +558,11 @@ _gnutls_io_read_buffered (gnutls_session_t session, size_t total,
 	 (int) session->internals.record_recv_buffer.byte_length, (int) ret);
       _gnutls_read_log ("RB: Requested %d bytes\n", (int) total);
 
-      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);
     }
+  else
+    _mbuffer_xfree(&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
@@ -570,10 +571,11 @@ _gnutls_io_read_buffered (gnutls_session_t session, size_t total,
    */
   if (ret == readsize && recvlowat > 0)
     {
-      ret2 = _gnutls_read (session, buf, recvlowat, system_read_peek);
+      ret2 = _gnutls_read (session, &bufel, recvlowat, system_read_peek);
 
       if (ret2 < 0 && gnutls_error_is_fatal (ret2) == 0)
 	{
+	  _mbuffer_xfree(&bufel);
 	  return ret2;
 	}
 
@@ -586,15 +588,10 @@ _gnutls_io_read_buffered (gnutls_session_t session, size_t total,
 	     (int) session->internals.record_recv_buffer.byte_length, (int) ret2,
 	     (int) total);
 	  session->internals.have_peeked_data = 1;
-	  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);
 	}
+      else
+	_mbuffer_xfree(&bufel);
     }
 
   if (ret < 0 || ret2 < 0)
-- 
1.7.1





More information about the Gnutls-devel mailing list