]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Simplify handshake send buffer logic.
authorJonathan Bastien-Filiatrault <joe@x2a.org>
Sat, 15 Aug 2009 20:56:19 +0000 (16:56 -0400)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 3 Jun 2010 17:39:00 +0000 (19:39 +0200)
lib/gnutls_buffers.c
lib/gnutls_buffers.h
lib/gnutls_handshake.c
lib/gnutls_int.h
lib/gnutls_state.c

index fecbf85d496ffc722e1ae090af8c7b13019957b1..b1740aa74bc9d582ae649d18b7f938c453023f7b 100644 (file)
@@ -733,148 +733,88 @@ _gnutls_io_write_flush (gnutls_session_t session)
 /* This function writes the data that are left in the
  * Handshake write buffer (ie. because the previous write was
  * interrupted.
+ *
+ * FIXME: This is practically the same as _gnutls_io_write_flush.
  */
 ssize_t
 _gnutls_handshake_io_write_flush (gnutls_session_t session)
 {
-  ssize_t ret;
-  ret = _gnutls_handshake_io_send_int (session, 0, 0, NULL, 0);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      return ret;
-    }
+  mbuffer_head_st * const send_buffer = &session->internals.handshake_send_buffer;
+  gnutls_datum_t msg;
+  int ret;
+  ssize_t total = 0;
 
-  _gnutls_write_log ("HANDSHAKE_FLUSH: written[1] %d bytes\n", (int) ret);
+  _gnutls_write_log ("HWRITE FLUSH: %d bytes in buffer.\n",
+                    (int)send_buffer->byte_length);
 
-  if (session->internals.handshake_send_buffer.length == 0)
+  for (_gnutls_mbuffer_get_head (send_buffer, &msg);
+       msg.data != NULL && msg.size > 0;
+       _gnutls_mbuffer_get_head (send_buffer, &msg))
     {
-      ret = session->internals.handshake_send_buffer_prev_size;        /* done */
-      session->internals.handshake_send_buffer_prev_size = 0;
+      ret = _gnutls_send_int (session, GNUTLS_HANDSHAKE,
+                             session->internals.handshake_send_buffer_htype,
+                             msg.data, msg.size);
+
+      if (ret >= 0)
+       {
+         dump_bytes (msg.data, msg.size, 1);
+         _gnutls_mbuffer_remove_bytes (send_buffer, ret);
+
+         _gnutls_write_log ("HWRITE: wrote %d bytes, %d bytes left.\n",
+                            ret, (int)send_buffer->byte_length);
+
+         total += ret;
+       }
+      else if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN)
+       {
+         _gnutls_write_log ("HWRITE interrupted: %d bytes left.\n",
+                            (int)send_buffer->byte_length);
+         return ret;
+       }
+      else
+       {
+         _gnutls_write_log ("HWRITE error: code %d, %d bytes left.\n",
+                            ret, (int)send_buffer->byte_length);
+
+         gnutls_assert ();
+         return ret;
+       }
     }
 
-  return ret;
+  return total;
 }
 
 
 /* This is a send function for the gnutls handshake 
  * protocol. Just makes sure that all data have been sent.
+ *
+ * FIXME: This is practically the same as _gnutls_io_write_buffered.
  */
 ssize_t
 _gnutls_handshake_io_send_int (gnutls_session_t session,
-                              content_type_t type,
                               gnutls_handshake_description_t htype,
                               const void *iptr, size_t n)
 {
-  size_t left;
-  ssize_t ret = 0;
-  const opaque *ptr;
-  ssize_t retval = 0;
-
-  ptr = iptr;
-
-  if (session->internals.handshake_send_buffer.length > 0 && ptr == NULL
-      && n == 0)
-    {
-      gnutls_datum_t bdata;
-
-      /* resuming previously interrupted write
-       */
-      gnutls_assert ();
-
-      /* checking is handled above */
-      _gnutls_buffer_get_datum (&session->internals.handshake_send_buffer,
-                               &bdata,
-                               session->internals.handshake_send_buffer.
-                               length);
+  mbuffer_head_st * const send_buffer = &session->internals.handshake_send_buffer;
+  mbuffer_st *bufel = _gnutls_mbuffer_alloc(n);
 
-      ptr = bdata.data;
-      n = bdata.size;
-
-      type = session->internals.handshake_send_buffer_type;
-      htype = session->internals.handshake_send_buffer_htype;
-
-    }
-  else if (session->internals.handshake_send_buffer.length > 0)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INTERNAL_ERROR;
-    }
-#ifdef WRITE_DEBUG
-  else
-    {
-      _gnutls_write_log ("HWRITE: will write %d bytes to %d.\n", n,
-                        gnutls_transport_get_ptr (session));
-
-      dump_bytes(ptr, n, 1);
-    }
-#endif
-
-  if (n == 0)
-    {                          /* if we have no data to send */
-      gnutls_assert ();
-      return 0;
-    }
-  else if (ptr == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INTERNAL_ERROR;
-    }
-
-
-  left = n;
-  while (left > 0)
+  if(bufel == NULL)
     {
-      ret = _gnutls_send_int (session, type, htype, &ptr[n - left], left);
-
-      if (ret <= 0)
-       {
-         if (ret == 0)
-           {
-             gnutls_assert ();
-             ret = GNUTLS_E_INTERNAL_ERROR;
-           }
-
-         if (left > 0
-             && (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN))
-           {
-             gnutls_assert ();
-
-             retval =
-               _gnutls_buffer_append (&session->
-                                      internals.handshake_send_buffer,
-                                      &ptr[n - left], left);
-             if (retval < 0)
-               {
-                 gnutls_assert ();
-                 return retval;
-               }
-
-             session->internals.handshake_send_buffer_prev_size += n - left;
-
-             session->internals.handshake_send_buffer_type = type;
-             session->internals.handshake_send_buffer_htype = htype;
-
-           }
-         else
-           {
-             session->internals.handshake_send_buffer_prev_size = 0;
-             session->internals.handshake_send_buffer.length = 0;
-           }
-
-         gnutls_assert ();
-         return ret;
-       }
-      left -= ret;
+      gnutls_assert ()
+      return GNUTLS_E_MEMORY_ERROR;
     }
 
-  retval = n + session->internals.handshake_send_buffer_prev_size;
+  memcpy(bufel->msg.data, iptr, n);
 
-  session->internals.handshake_send_buffer.length = 0;
-  session->internals.handshake_send_buffer_prev_size = 0;
+  _gnutls_mbuffer_enqueue (send_buffer, bufel);
+  session->internals.handshake_send_buffer_htype = htype;
 
-  return retval;
+  _gnutls_write_log
+    ("HWRITE: enqueued %d. Total %d bytes.\n",
+     (int)bufel->msg.size,
+     (int)send_buffer->byte_length);
 
+  return _gnutls_handshake_io_write_flush(session);
 }
 
 /* This is a receive function for the gnutls handshake 
index 2e0b7de7677dbed06d4074b0b6790ed8b78aff88..c1d954e29ccd3e9ab52ace2bd013ce5a97c5c94c 100644 (file)
@@ -48,14 +48,13 @@ int _gnutls_handshake_buffer_get_ptr (gnutls_session_t session,
                                      opaque ** data_ptr, size_t * length);
 
 #define _gnutls_handshake_io_buffer_clear( session) \
-        _gnutls_buffer_clear( &session->internals.handshake_send_buffer); \
-        _gnutls_buffer_clear( &session->internals.handshake_recv_buffer); \
-        session->internals.handshake_send_buffer_prev_size = 0
+        _gnutls_mbuffer_clear( &session->internals.handshake_send_buffer); \
+        _gnutls_buffer_clear( &session->internals.handshake_recv_buffer);
 
 ssize_t _gnutls_handshake_io_recv_int (gnutls_session_t, content_type_t,
                                       gnutls_handshake_description_t, void *,
                                       size_t);
-ssize_t _gnutls_handshake_io_send_int (gnutls_session_t, content_type_t,
+ssize_t _gnutls_handshake_io_send_int (gnutls_session_t,
                                       gnutls_handshake_description_t,
                                       const void *, size_t);
 ssize_t _gnutls_io_write_flush (gnutls_session_t session);
index c83218579a795e240d556876b4a2f69b37d59e3f..21c63574b0adfe1ba59c2891be901c31b0425646 100644 (file)
@@ -1187,8 +1187,7 @@ _gnutls_send_handshake (gnutls_session_t session, void *i_data,
   session->internals.last_handshake_out = type;
 
   ret =
-    _gnutls_handshake_io_send_int (session, GNUTLS_HANDSHAKE, type,
-                                  data, datasize);
+    _gnutls_handshake_io_send_int (session, type, data, datasize);
 
   gnutls_free (data);
 
index d9a8d9245ca47b329de5e0f02c31a1caf77b8554..a89f13741fe7b4397f360569f4709a537bd24c5e 100644 (file)
@@ -589,9 +589,7 @@ typedef struct
   /* These buffers are used in the handshake
    * protocol only. freed using _gnutls_handshake_io_buffer_clear();
    */
-  gnutls_buffer handshake_send_buffer;
-  size_t handshake_send_buffer_prev_size;
-  content_type_t handshake_send_buffer_type;
+  mbuffer_head_st handshake_send_buffer;
   gnutls_handshake_description_t handshake_send_buffer_htype;
   content_type_t handshake_recv_buffer_type;
   gnutls_handshake_description_t handshake_recv_buffer_htype;
index d9e221fdd2104afdf8bc00de54f16f0625204436..c99150228bf715ad8b278f0e5193240c3a557b2f 100644 (file)
@@ -301,7 +301,7 @@ gnutls_init (gnutls_session_t * session, gnutls_connection_end_t con_end)
   _gnutls_mbuffer_init (&(*session)->internals.record_send_buffer);
   _gnutls_buffer_init (&(*session)->internals.record_recv_buffer);
 
-  _gnutls_buffer_init (&(*session)->internals.handshake_send_buffer);
+  _gnutls_mbuffer_init (&(*session)->internals.handshake_send_buffer);
   _gnutls_buffer_init (&(*session)->internals.handshake_recv_buffer);
 
   (*session)->key = gnutls_calloc (1, sizeof (struct gnutls_key_st));