]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
gnutls_record_check_pending() accounts data not yet processed.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 8 Feb 2012 22:44:13 +0000 (23:44 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 8 Feb 2012 22:44:13 +0000 (23:44 +0100)
DTLS layer avoids multiple retransmissions in non-blocking mode.

lib/gnutls_buffers.c
lib/gnutls_buffers.h
lib/gnutls_dtls.c
lib/gnutls_handshake.c
lib/gnutls_int.h
lib/gnutls_record.c

index b896c1a2bae9e7918cede9dd40e8ee7d0e71b118..755bb4c11cfee3a75b3f0cbd5da84c95c8beed46 100644 (file)
@@ -93,7 +93,7 @@ _gnutls_record_buffer_put (gnutls_session_t session,
 size_t
 gnutls_record_check_pending (gnutls_session_t session)
 {
-  return _gnutls_record_buffer_get_size (GNUTLS_APPLICATION_DATA, session);
+  return _gnutls_record_buffer_get_size (session) + session->internals.record_recv_buffer.byte_length;
 }
 
 int
index 92b758a28c7a1dec234a951c6b8a6aae834e77bc..8a738b232c5a2232a86a88a2d7d9accdabf8acb0 100644 (file)
@@ -29,7 +29,7 @@ _gnutls_record_buffer_put (gnutls_session_t session,
   content_type_t type, uint64* seq, mbuffer_st* bufel);
 
 inline static int
-_gnutls_record_buffer_get_size (content_type_t type, gnutls_session_t session)
+_gnutls_record_buffer_get_size (gnutls_session_t session)
 {
   return session->internals.record_buffer.byte_length;
 }
index 7ff80e74327d3ff8ee39d4940270ce116f4ba4f4..f6dcfac9ac9f759ebc7092cda7cfd0c24032c66b 100644 (file)
@@ -144,11 +144,13 @@ static int drop_usage_count(gnutls_session_t session, mbuffer_head_st *const sen
 int _dtls_retransmit(gnutls_session_t session)
 {
 time_t now = gnutls_time (0);
+int ret;
 
   if (now - session->internals.dtls.last_retransmit > RETRANSMIT_WINDOW)
     {
+      ret = _dtls_transmit(session);
       session->internals.dtls.last_retransmit = now;
-      return _dtls_transmit(session);
+      return ret;
     }
   else
     return 0;
@@ -218,44 +220,50 @@ uint8_t* buf = NULL;
           ret = gnutls_assert_val(GNUTLS_E_TIMEDOUT);
           goto cleanup;
         }
-
-      _gnutls_dtls_log ("DTLS[%p]: %sStart of flight transmission.\n", session,  (session->internals.dtls.flight_init == 0)?"":"re-");
-
-      for (cur = send_buffer->head;
-           cur != NULL; cur = cur->next)
+        
+      if ((session->internals.dtls.flight_init == 0) ||
+          (now - session->internals.dtls.last_retransmit > RETRANSMIT_WINDOW))
         {
-          ret = transmit_message (session, cur, &buf);
-          if (ret < 0)
-            {
-              gnutls_assert();
-              goto cleanup;
-            }
+          session->internals.dtls.last_retransmit = now;
 
-          last_type = cur->htype;
-        }
+          _gnutls_dtls_log ("DTLS[%p]: %sStart of flight transmission.\n", session,  (session->internals.dtls.flight_init == 0)?"":"re-");
 
-      if (buf != NULL)
-        {
-          gnutls_free(buf);
-          buf = NULL;
-        }
+          for (cur = send_buffer->head;
+               cur != NULL; cur = cur->next)
+            {
+              ret = transmit_message (session, cur, &buf);
+              if (ret < 0)
+                {
+                  gnutls_assert();
+                  goto cleanup;
+                }
 
-      if (session->internals.dtls.flight_init == 0)
-        {
-          session->internals.dtls.flight_init = 1;
-          session->internals.dtls.handshake_last_call = now;
-          session->internals.dtls.actual_retrans_timeout_ms = session->internals.dtls.retrans_timeout_ms;
+              last_type = cur->htype;
+            }
 
-          if (last_type == GNUTLS_HANDSHAKE_FINISHED)
+          if (buf != NULL)
             {
-              /* On the last flight we cannot ensure retransmission
-               * from here. _dtls_wait_and_retransmit() is being called
-               * by handshake.
-               */
-              session->internals.dtls.last_flight = 1;
+              gnutls_free(buf);
+              buf = NULL;
             }
-          else
-            session->internals.dtls.last_flight = 0;
+
+          if (session->internals.dtls.flight_init == 0)
+            {
+              session->internals.dtls.flight_init = 1;
+              session->internals.dtls.handshake_last_call = now;
+              session->internals.dtls.actual_retrans_timeout_ms = session->internals.dtls.retrans_timeout_ms;
+
+              if (last_type == GNUTLS_HANDSHAKE_FINISHED)
+                {
+                  /* On the last flight we cannot ensure retransmission
+                   * from here. _dtls_wait_and_retransmit() is being called
+                   * by handshake.
+                   */
+                  session->internals.dtls.last_flight = 1;
+                }
+              else
+                session->internals.dtls.last_flight = 0;
+           }
         }
 
       ret = _gnutls_io_write_flush (session);
index f362be81e3fe308841d09810f593dfcdc2178c35..60434fa9506ee4d17e7cfd18cef4550b82c8f9da 100644 (file)
@@ -2680,7 +2680,8 @@ _gnutls_recv_handshake_final (gnutls_session_t session, int init)
       /* This is the last flight and peer cannot be sure
        * we have received it unless we notify him. So we
        * wait for a message and retransmit if needed. */
-      if (IS_DTLS(session) && !_dtls_is_async(session))
+      if (IS_DTLS(session) && !_dtls_is_async(session) && 
+          gnutls_record_check_pending (session) == 0)
         {
           ret = _dtls_wait_and_retransmit(session);
           if (ret < 0)
@@ -2716,7 +2717,8 @@ _gnutls_recv_handshake_final (gnutls_session_t session, int init)
     case STATE31:
       STATE = STATE31;
 
-       if (IS_DTLS(session) && !_dtls_is_async(session))
+       if (IS_DTLS(session) && !_dtls_is_async(session) && 
+           gnutls_record_check_pending( session) == 0)
          {
            ret = _dtls_wait_and_retransmit(session);
            if (ret < 0)
index 7f3c676ece4121baea0dd3b987e43804d873904a..d99354449abf96a95fe87dfa2a98e44309284f9b 100644 (file)
@@ -701,7 +701,8 @@ typedef struct
   /* this buffer holds a record packet -mostly used for
    * non blocking IO.
    */
-  mbuffer_head_st record_recv_buffer;   /* buffer holding the record that is currently being received */
+  mbuffer_head_st record_recv_buffer;   /* buffer holding the record that is currently 
+                                         * being received */
   mbuffer_head_st record_send_buffer;   /* holds cached data
                                          * for the gnutls_io_write_buffered()
                                          * function.
index 963966f9eb287c3198fce6b8fee7b8d0f96de100..460db362669be1c6f75e139d1a436165da25742a 100644 (file)
@@ -493,7 +493,7 @@ check_buffers (gnutls_session_t session, content_type_t type,
   if ((type == GNUTLS_APPLICATION_DATA ||
        type == GNUTLS_HANDSHAKE ||
        type == GNUTLS_CHANGE_CIPHER_SPEC)
-      && _gnutls_record_buffer_get_size (type, session) > 0)
+      && _gnutls_record_buffer_get_size (session) > 0)
     {
       int ret;
       ret = _gnutls_record_buffer_get (type, session, data, data_size, seq);
@@ -906,7 +906,7 @@ gnutls_datum_t raw; /* raw headers */
  */
 ssize_t
 _gnutls_recv_in_buffers (gnutls_session_t session, content_type_t type,
-                  gnutls_handshake_description_t htype)
+                         gnutls_handshake_description_t htype)
 {
   uint64 *packet_sequence;
   uint8_t *ciphertext;