&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;
}
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;
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)
{
/* 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;
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; \
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)
# define DTLS_H
#include <config.h>
-#include "gnutls_int.h"
-#include "gnutls_buffers.h"
-#include "gnutls_mbuffers.h"
+#include <gnutls_int.h>
+#include <gnutls_buffers.h>
+#include <gnutls_mbuffers.h>
+#include <gnutls_constate.h>
#include <timespec.h>
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
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)
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);
}
}
}
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 ();
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;
}
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);
}