From: Nikos Mavrogiannopoulos Date: Wed, 8 Feb 2012 22:44:13 +0000 (+0100) Subject: gnutls_record_check_pending() accounts data not yet processed. X-Git-Tag: gnutls_3_0_13~107 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8c19b028492148fcd27c2472a56cb46b88e5eea2;p=thirdparty%2Fgnutls.git gnutls_record_check_pending() accounts data not yet processed. DTLS layer avoids multiple retransmissions in non-blocking mode. --- diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index b896c1a2ba..755bb4c11c 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -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 diff --git a/lib/gnutls_buffers.h b/lib/gnutls_buffers.h index 92b758a28c..8a738b232c 100644 --- a/lib/gnutls_buffers.h +++ b/lib/gnutls_buffers.h @@ -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; } diff --git a/lib/gnutls_dtls.c b/lib/gnutls_dtls.c index 7ff80e7432..f6dcfac9ac 100644 --- a/lib/gnutls_dtls.c +++ b/lib/gnutls_dtls.c @@ -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); diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index f362be81e3..60434fa950 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -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) diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 7f3c676ece..d99354449a 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -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. diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index 963966f9eb..460db36266 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -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;