]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
use similar API when caching messages in DTLS or TLS.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 18 Feb 2011 10:41:11 +0000 (11:41 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 18 Feb 2011 10:41:11 +0000 (11:41 +0100)
lib/gnutls_buffers.c
lib/gnutls_buffers.h
lib/gnutls_dtls.c
lib/gnutls_dtls.h
lib/gnutls_handshake.c
lib/gnutls_int.h

index 692e61bc2ec9a549a0fa462d8f16fbdee4e896bf..9e078455c98599b86d3404e4e7b8f7c07f46434d 100644 (file)
@@ -55,6 +55,7 @@
 #include <gnutls_buffers.h>
 #include <gnutls_mbuffers.h>
 #include <gnutls_state.h>
+#include <gnutls_dtls.h>
 #include <system.h>
 
 #include <errno.h>
@@ -841,6 +842,10 @@ _gnutls_handshake_io_write_flush (gnutls_session_t session)
   _gnutls_write_log ("HWRITE FLUSH: %d bytes in buffer.\n",
                      (int) send_buffer->byte_length);
 
+  if (IS_DTLS)
+    return _gnutls_dtls_transmit(session);
+
+
   for (cur = _mbuffer_get_first (send_buffer, &msg);
        cur != NULL; cur = _mbuffer_get_first (send_buffer, &msg))
     {
@@ -877,12 +882,17 @@ _gnutls_handshake_io_write_flush (gnutls_session_t session)
  * protocol. Just makes sure that all data have been sent.
  *
  */
-void
+int
 _gnutls_handshake_io_cache_int (gnutls_session_t session,
                                 gnutls_handshake_description_t htype,
                                 mbuffer_st * bufel)
 {
-  mbuffer_head_st *const send_buffer =
+  mbuffer_head_st * send_buffer;
+  
+  if (IS_DTLS)
+    return _gnutls_dtls_handshake_enqueue(session, bufel, htype, session->internals.dtls.hsk_write_seq-1);
+  
+  send_buffer =
     &session->internals.handshake_send_buffer;
 
   _mbuffer_enqueue (send_buffer, bufel);
@@ -892,7 +902,7 @@ _gnutls_handshake_io_cache_int (gnutls_session_t session,
     ("HWRITE: enqueued %d. Total %d bytes.\n",
      (int) bufel->msg.size, (int) send_buffer->byte_length);
 
-  return;
+  return 0;
 }
 
 /* This is a receive function for the gnutls handshake 
index 3dfad550fe50c2d3296aa793a2b42dfe1060a89a..3546fc6e58ef5e2b052d6abb333e3eb4ec9358e1 100644 (file)
@@ -56,7 +56,7 @@ int _gnutls_handshake_buffer_get_ptr (gnutls_session_t session,
 ssize_t _gnutls_handshake_io_recv_int (gnutls_session_t, content_type_t,
                                        gnutls_handshake_description_t, void *,
                                        size_t);
-void _gnutls_handshake_io_cache_int (gnutls_session_t,
+int _gnutls_handshake_io_cache_int (gnutls_session_t,
                                      gnutls_handshake_description_t,
                                      mbuffer_st * bufel);
 ssize_t _gnutls_io_write_flush (gnutls_session_t session);
index 2cc67f7667210bc1ad91d8ed2946cdedb7ea65b8..20d238e4f2d9c909350cd4d314948bd53f887860 100644 (file)
@@ -30,6 +30,7 @@
 #include "debug.h"
 #include "gnutls_dtls.h"
 #include "gnutls_record.h"
+#include <gnutls_mbuffers.h>
 
 /* This function is called once a handshake message is ready to be
  * queued in the next outgoing flight. The actual transmission occurs
@@ -39,8 +40,7 @@
  */
 int
 _gnutls_dtls_handshake_enqueue (gnutls_session_t session,
-                               opaque *data,
-                               uint32_t datasize,
+                               mbuffer_st* bufel,
                                gnutls_handshake_description_t type,
                                uint16_t sequence)
 {
@@ -53,17 +53,7 @@ _gnutls_dtls_handshake_enqueue (gnutls_session_t session,
       return GNUTLS_E_MEMORY_ERROR;
     }
 
-  msg->msg.size = datasize - DTLS_HANDSHAKE_HEADER_SIZE;
-
-  msg->msg.data = gnutls_malloc (msg->msg.size);
-  if (msg->msg.data == NULL)
-    {
-      gnutls_free (msg);
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  memcpy (msg->msg.data, data + DTLS_HANDSHAKE_HEADER_SIZE, msg->msg.size);
+  msg->bufel = bufel;
 
   msg->next = NULL;
   /* FIXME: dummy epoch */
@@ -73,7 +63,7 @@ _gnutls_dtls_handshake_enqueue (gnutls_session_t session,
 
   _gnutls_dtls_log ("DTLS[%p]: Enqueued Packet[%u] %s(%d) with length: %u\n",
                    session, (uint)sequence, _gnutls_handshake2str (type),
-                   type, msg->msg.size);
+                   type, msg->bufel->msg.size);
 
   *(session->internals.dtls.retransmit_end) = msg;
   session->internals.dtls.retransmit_end = &msg->next;
@@ -87,61 +77,65 @@ static inline int
 transmit_message (gnutls_session_t session,
                  dtls_hsk_retransmit_buffer *msg)
 {
-  opaque *data;
-  uint offset, frag_len;
+  opaque *data, *mtu_data;
+  int ret = 0;
+  unsigned int offset, frag_len, data_size;
   const uint mtu = session->internals.dtls.hsk_mtu;
 
-  data = gnutls_malloc (DTLS_HANDSHAKE_HEADER_SIZE + mtu);
-  if (data == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
+  mtu_data = gnutls_malloc(mtu + DTLS_HANDSHAKE_HEADER_SIZE);
+  if (mtu_data == NULL)
+    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+  data = _mbuffer_get_udata_ptr( msg->bufel);
+  data_size = _mbuffer_get_udata_size(msg->bufel);
 
   /* Write fixed headers
    */
 
   /* Handshake type */
-  data[0] = (uint8_t) msg->type;
+  mtu_data[0] = (uint8_t) msg->type;
 
   /* Total length */
-  _gnutls_write_uint24 (msg->msg.size, &data[1]);
+  _gnutls_write_uint24 (data_size, &mtu_data[1]);
 
   /* Handshake sequence */
-  _gnutls_write_uint16 (msg->sequence, &data[4]);
+  _gnutls_write_uint16 (msg->sequence, &mtu_data[4]);
 
   /* Chop up and send handshake message into mtu-size pieces. */
-  for (offset=0; offset < msg->msg.size; offset += mtu)
+  for (offset=0; offset < data_size; offset += mtu)
     {
       /* Calculate fragment length */
-      if(offset + mtu > msg->msg.size)
-       frag_len = msg->msg.size - offset;
+      if(offset + mtu > data_size)
+       frag_len = data_size - offset;
       else
        frag_len = mtu;
 
       /* Fragment offset */
-      _gnutls_write_uint24 (offset, &data[6]);
+      _gnutls_write_uint24 (offset, &mtu_data[6]);
 
       /* Fragment length */
-      _gnutls_write_uint24 (frag_len, &data[9]);
+      _gnutls_write_uint24 (frag_len, &mtu_data[9]);
 
-      memcpy (&data[12], msg->msg.data + offset, frag_len);
+      
+      memcpy (&mtu_data[12], data+offset, frag_len);
 
       _gnutls_dtls_log ("DTLS[%p]: Sending Packet[%u] fragment %s(%d) with "
                        "length: %u, offset: %u, fragment length: %u\n",
                        session, msg->sequence,
                        _gnutls_handshake2str (msg->type),
-                       msg->type, msg->msg.size, offset, frag_len);
+                       msg->type, data_size, offset, frag_len);
 
       /* FIXME: We should collaborate with the record layer to pack as
         many records possible into a single datagram. We should also
         tell the record layer which epoch to use for encryption. */
-      _gnutls_send_int (session, GNUTLS_HANDSHAKE, msg->type, EPOCH_WRITE_CURRENT,
-                       data, DTLS_HANDSHAKE_HEADER_SIZE + frag_len, 0);
+      ret = _gnutls_send_int (session, GNUTLS_HANDSHAKE, msg->type, EPOCH_WRITE_CURRENT,
+                       mtu_data, DTLS_HANDSHAKE_HEADER_SIZE + frag_len, 0);
+      if (ret < 0)
+        break;
    }
 
-  gnutls_free (data);
-  return 0;
+  gnutls_free (mtu_data);
+  return ret;
 }
 
 /* This function transmits the flight that has been previously
@@ -183,7 +177,7 @@ _gnutls_dtls_clear_outgoing_buffer (gnutls_session_t session)
     {
       next = msg->next;
 
-      gnutls_free (msg->msg.data);
+      _mbuffer_xfree(&msg->bufel);
       gnutls_free (msg);
 
       msg = next;
index f870c1bc7bc4e767626581bbf1df1bb97f9d033d..4a9aa127ca4efc243f4b20c7dc11c950c0cae64b 100644 (file)
 
 #include "gnutls_int.h"
 
-int _gnutls_dtls_handshake_enqueue(gnutls_session_t session,
-                                  opaque *data,
-                                  uint32_t datasize,
-                                  gnutls_handshake_description_t type,
-                                  uint16_t sequence);
+int
+_gnutls_dtls_handshake_enqueue (gnutls_session_t session,
+                               mbuffer_st* bufel,
+                               gnutls_handshake_description_t type,
+                               uint16_t sequence);
 
 int _gnutls_dtls_transmit(gnutls_session_t session);
 void _gnutls_dtls_clear_outgoing_buffer(gnutls_session_t session);
index c6c699fd451cb32a7b82a70682fae0eb3f1282ef..34d30fbed867a658e1bc33caa753448f321d0f35 100644 (file)
@@ -33,7 +33,6 @@
 #include "gnutls_algorithms.h"
 #include "gnutls_compress.h"
 #include "gnutls_cipher.h"
-#include "gnutls_dtls.h"
 #include "gnutls_buffers.h"
 #include "gnutls_mbuffers.h"
 #include "gnutls_kx.h"
@@ -1241,17 +1240,19 @@ _gnutls_send_handshake (gnutls_session_t session, mbuffer_st * bufel,
          _gnutls_handshake_hash_add_sent (session, type, data, datasize)) < 0)
       {
         gnutls_assert ();
-        gnutls_free (bufel);
+      _mbuffer_xfree(&bufel);
         return ret;
       }
 
   session->internals.last_handshake_out = type;
 
-  if (_gnutls_is_dtls(session))
-    _gnutls_dtls_handshake_enqueue (session, data, datasize, type,
-                                   session->internals.dtls.hsk_write_seq-1);
-  else
-    _gnutls_handshake_io_cache_int (session, type, bufel);
+  ret = _gnutls_handshake_io_cache_int (session, type, bufel);
+  if (ret < 0)
+    {
+      _mbuffer_xfree(&bufel);
+      gnutls_assert();
+      return ret;
+    }
 
   switch (type)
     {
@@ -2867,8 +2868,6 @@ _gnutls_handshake_client (gnutls_session_t session)
       STATE = STATE1;
       IMED_RET ("send hello", ret, 1);
 
-      _gnutls_dtls_transmit(session);
-
     case STATE11:
       if (_gnutls_is_dtls (session))
        {
@@ -2964,7 +2963,6 @@ _gnutls_handshake_client (gnutls_session_t session)
           _gnutls_send_client_certificate_verify (session, AGAIN (STATE9));
       STATE = STATE9;
       IMED_RET ("send client certificate verify", ret, 1);
-      _gnutls_dtls_transmit(session);
 
       STATE = STATE0;
     default:
@@ -3038,7 +3036,6 @@ _gnutls_send_handshake_final (gnutls_session_t session, int init)
           return ret;
         }
 
-      _gnutls_dtls_transmit(session);
       STATE = STATE0;
     default:
       break;
index 90efdb5eaeffe0d56873e89f280bd3ad446c4a07..7cd9a326890e86be6cd1f1a2ce914daa1644d140 100644 (file)
@@ -284,6 +284,25 @@ typedef struct mbuffer_head_st
   size_t byte_length;
 } mbuffer_head_st;
 
+/* This is a linked list used to buffer the next flight of outgoing
+   handshake messages. Messages are queued whole; they are fragmented
+   dynamically on transmit. */
+typedef struct dtls_hsk_retransmit_buffer
+{
+  struct dtls_hsk_retransmit_buffer *next;
+
+  /* The actual handshake message */
+  mbuffer_st* bufel;
+
+  /* Record layer epoch of message */
+  uint16_t epoch;
+
+  /* Handshake layer type and sequence of message */
+  gnutls_handshake_description_t type;
+  uint16_t sequence;
+} dtls_hsk_retransmit_buffer;
+
+
 typedef enum
 {
   HANDSHAKE_MAC_TYPE_10 = 1,    /* TLS 1.0 style */
@@ -531,27 +550,6 @@ typedef struct
   int free_rsa_params;
 } internal_params_st;
 
-struct dtls_hsk_retransmit_buffer;
-typedef struct dtls_hsk_retransmit_buffer dtls_hsk_retransmit_buffer;
-
-/* This is a linked list used to buffer the next flight of outgoing
-   handshake messages. Messages are queued whole; they are fragmented
-   dynamically on transmit. */
-struct dtls_hsk_retransmit_buffer
-{
-  dtls_hsk_retransmit_buffer *next;
-
-  /* The actual handshake message */
-  gnutls_datum_t msg;
-
-  /* Record layer epoch of message */
-  uint16_t epoch;
-
-  /* Handshake layer type and sequence of message */
-  gnutls_handshake_description_t type;
-  uint16_t sequence;
-};
-
 /* DTLS session state
  */
 typedef struct