summaryrefslogtreecommitdiff
path: root/lib/dtls.c
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-03-30 11:37:49 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2016-03-31 13:28:42 +0200
commitcd24f9ec69d714853b5f04a600e7670dd463dc9a (patch)
tree54c7f26402eb59bd4529d60135f97e7b86158a1e /lib/dtls.c
parente2c9f4b7d9f09861b913d048b3253e60e0f204a8 (diff)
downloadgnutls-cd24f9ec69d714853b5f04a600e7670dd463dc9a.tar.gz
dtls: reset the record number sliding window on gnutls_record_set_state()
This addresses issue where gnutls_record_set_state() was called with a new state but the sliding window information was not updated, thus blocking any incoming packets. Resolves #82
Diffstat (limited to 'lib/dtls.c')
-rw-r--r--lib/dtls.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/lib/dtls.c b/lib/dtls.c
index 06a0ba61bc..6ae3056910 100644
--- a/lib/dtls.c
+++ b/lib/dtls.c
@@ -448,6 +448,37 @@ int _dtls_wait_and_retransmit(gnutls_session_t session)
#define window_size rp->record_sw_size
#define window_head_idx rp->record_sw_head_idx
+#define LOAD_UINT48(out, ubytes) \
+ for (i = 2; i < 8; i++) { \
+ out <<= 8; \
+ out |= ubytes[i] & 0xff; \
+ }
+
+void _dtls_reset_window(gnutls_session_t session, uint8_t _seq[8])
+{
+ record_parameters_st *rp;
+ int ret;
+ unsigned i;
+ uint64_t seq = 0;
+
+ ret =
+ _gnutls_epoch_get(session, EPOCH_READ_CURRENT, &rp);
+ if (ret < 0)
+ return;
+
+ LOAD_UINT48(seq, _seq);
+
+ if (seq == 0) {
+ window_size = 0;
+ window_head_idx = 0;
+ return;
+ }
+
+ window_size = 1;
+ window_head_idx = 0;
+ window_table[window_head_idx] = seq - 1;
+}
+
static void slide_window(struct record_parameters_st *rp,
unsigned int places)
{
@@ -475,10 +506,7 @@ int _dtls_record_check(struct record_parameters_st *rp, uint64 * _seq)
unsigned int i, offset = 0;
unsigned int last_idx;
- for (i = 2; i < 8; i++) {
- seq <<= 8;
- seq |= _seq->i[i] & 0xff;
- }
+ LOAD_UINT48(seq, _seq->i);
/* only two values allowed in window_size */
if (window_size == 0) {