From: Nikos Mavrogiannopoulos Date: Sun, 26 Feb 2012 01:36:07 +0000 (+0100) Subject: fixes in DTLS rehandshake and epoch cleanup. X-Git-Tag: gnutls_3_0_15~43 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42116c1bc8a7579e5db33a8903c3eb93250e5584;p=thirdparty%2Fgnutls.git fixes in DTLS rehandshake and epoch cleanup. --- diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index eee4dc3af7..bdef97463d 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -722,7 +722,6 @@ _gnutls_handshake_io_cache_int (gnutls_session_t session, &session->internals.handshake_send_buffer; bufel->epoch = (uint16_t)_gnutls_epoch_refcount_inc(session, EPOCH_WRITE_CURRENT); - bufel->htype = htype; if (bufel->htype == GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC) bufel->type = GNUTLS_CHANGE_CIPHER_SPEC; diff --git a/lib/gnutls_constate.c b/lib/gnutls_constate.c index 730301081f..84e6fe3682 100644 --- a/lib/gnutls_constate.c +++ b/lib/gnutls_constate.c @@ -757,14 +757,10 @@ _gnutls_epoch_alloc (gnutls_session_t session, uint16_t epoch, } static inline int -epoch_alive (gnutls_session_t session, record_parameters_st * params) +epoch_is_active(gnutls_session_t session, record_parameters_st * params) { const security_parameters_st *sp = &session->security_parameters; - /* DTLS will, in addition, need to check the epoch timeout value. */ - if (params->usage_cnt > 0) - return 1; - if (params->epoch == sp->epoch_read) return 1; @@ -777,6 +773,15 @@ epoch_alive (gnutls_session_t session, record_parameters_st * params) return 0; } +static inline int +epoch_alive (gnutls_session_t session, record_parameters_st * params) +{ + if (params->usage_cnt > 0) + return 1; + + return epoch_is_active(session, params); +} + void _gnutls_epoch_gc (gnutls_session_t session) { @@ -787,12 +792,18 @@ _gnutls_epoch_gc (gnutls_session_t session) /* Free all dead cipher state */ for (i = 0; i < MAX_EPOCH_INDEX; i++) - if (session->record_parameters[i] != NULL - && !epoch_alive (session, session->record_parameters[i])) - { - _gnutls_epoch_free (session, session->record_parameters[i]); - session->record_parameters[i] = NULL; - } + { + if (session->record_parameters[i] != NULL) + { + if (!epoch_is_active(session, session->record_parameters[i]) && session->record_parameters[i]->usage_cnt) + _gnutls_record_log ("REC[%p]: Note inactive epoch %d has %d users\n", session, session->record_parameters[i]->epoch, session->record_parameters[i]->usage_cnt); + if (!epoch_alive (session, session->record_parameters[i])) + { + _gnutls_epoch_free (session, session->record_parameters[i]); + session->record_parameters[i] = NULL; + } + } + } /* Look for contiguous NULLs at the start of the array */ for (i = 0; i < MAX_EPOCH_INDEX && session->record_parameters[i] == NULL; diff --git a/lib/gnutls_dtls.c b/lib/gnutls_dtls.c index f61fea3f3b..93ba467a07 100644 --- a/lib/gnutls_dtls.c +++ b/lib/gnutls_dtls.c @@ -170,6 +170,14 @@ int ret; return gnutls_assert_val(GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET); } +void _dtls_reset_hsk_state(gnutls_session_t session) +{ + session->internals.dtls.flight_init = 0; + drop_usage_count(session, &session->internals.handshake_send_buffer); + _mbuffer_head_clear(&session->internals.handshake_send_buffer); +} + + #define UPDATE_TIMER { \ session->internals.dtls.actual_retrans_timeout_ms *= 2; \ session->internals.dtls.actual_retrans_timeout_ms %= MAX_DTLS_TIMEOUT; \ @@ -370,10 +378,7 @@ keep_up: end_flight: _gnutls_dtls_log ("DTLS[%p]: End of flight transmission.\n", session); - - session->internals.dtls.flight_init = 0; - drop_usage_count(session, send_buffer); - _mbuffer_head_clear(send_buffer); + _dtls_reset_hsk_state(session); cleanup: if (buf != NULL) diff --git a/lib/gnutls_dtls.h b/lib/gnutls_dtls.h index f8b1a721dc..3d40015220 100644 --- a/lib/gnutls_dtls.h +++ b/lib/gnutls_dtls.h @@ -24,14 +24,16 @@ # define DTLS_H #include -#include "gnutls_int.h" -#include "gnutls_buffers.h" -#include "gnutls_mbuffers.h" +#include +#include +#include +#include #include int _dtls_transmit(gnutls_session_t session); int _dtls_retransmit(gnutls_session_t session); int _dtls_record_check(struct record_parameters_st *rp, uint64 * _seq); +void _dtls_reset_hsk_state(gnutls_session_t session); #define MAX_DTLS_TIMEOUT 60000 @@ -87,7 +89,12 @@ inline static void _dtls_async_timer_init(gnutls_session_t session) session->internals.dtls.async_term = gnutls_time(0) + MAX_DTLS_TIMEOUT/1000; } else - session->internals.dtls.async_term = 0; + { + _dtls_reset_hsk_state(session); + _gnutls_handshake_io_buffer_clear (session); + _gnutls_epoch_gc(session); + session->internals.dtls.async_term = 0; + } } inline static void _dtls_async_timer_delete(gnutls_session_t session) @@ -95,8 +102,11 @@ inline static void _dtls_async_timer_delete(gnutls_session_t session) if (session->internals.dtls.async_term != 0) { _gnutls_dtls_log ("DTLS[%p]: Deinitializing handshake state.\n", session); - _gnutls_handshake_io_buffer_clear (session); session->internals.dtls.async_term = 0; /* turn off "timer" */ + + _dtls_reset_hsk_state(session); + _gnutls_handshake_io_buffer_clear (session); + _gnutls_epoch_gc(session); } } diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 573635a45d..648ed1cdbf 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -2945,7 +2945,11 @@ _gnutls_recv_hello_request (gnutls_session_t session, void *data, } type = ((uint8_t *) data)[0]; if (type == GNUTLS_HANDSHAKE_HELLO_REQUEST) - return GNUTLS_E_REHANDSHAKE; + { + if (IS_DTLS(session)) + session->internals.dtls.hsk_read_seq++; + return GNUTLS_E_REHANDSHAKE; + } else { gnutls_assert (); diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index 1df5be6106..8bf608bbaf 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -458,12 +458,14 @@ _gnutls_send_int (gnutls_session_t session, content_type_t type, session->internals.record_send_buffer_user_size = 0; - _gnutls_record_log ("REC[%p]: Sent Packet[%d] %s(%d) with length: %d\n", + _gnutls_record_log ("REC[%p]: Sent Packet[%d] %s(%d) in epoch %d and length: %d\n", session, (unsigned int) _gnutls_uint64touint32 (&record_state->sequence_number), - _gnutls_packet2str (type), type, (int) cipher_size); + _gnutls_packet2str (type), type, + (int) record_params->epoch, + (int) cipher_size); return retval; } @@ -831,10 +833,10 @@ record_read_headers (gnutls_session_t session, record->epoch = 0; } - _gnutls_record_log ("REC[%p]: SSL %d.%d %s packet received. Length: %d\n", + _gnutls_record_log ("REC[%p]: SSL %d.%d %s packet received. Epoch %d, length: %d\n", session, (int)record->version[0], (int)record->version[1], _gnutls_packet2str (record->type), - record->length); + (int)record->epoch, record->length); }