Blob Blame History Raw
diff -up openssl-1.0.1e/ssl/d1_both.c.dtls1-dos2 openssl-1.0.1e/ssl/d1_both.c
--- openssl-1.0.1e/ssl/d1_both.c.dtls1-dos2	2016-09-20 15:53:03.748445806 +0200
+++ openssl-1.0.1e/ssl/d1_both.c	2016-09-20 16:12:01.422861505 +0200
@@ -211,7 +211,7 @@ dtls1_hm_fragment_new(unsigned long frag
 	return frag;
 	}
 
-static void
+void
 dtls1_hm_fragment_free(hm_fragment *frag)
 	{
 
@@ -544,11 +544,26 @@ dtls1_retrieve_buffered_fragment(SSL *s,
 	int al;
 
 	*ok = 0;
-	item = pqueue_peek(s->d1->buffered_messages);
-	if ( item == NULL)
-		return 0;
+	do
+		{
+		item = pqueue_peek(s->d1->buffered_messages);
+		if (item == NULL)
+			return 0;
+
+		frag = (hm_fragment *)item->data;
+
+		if (frag->msg_header.seq < s->d1->handshake_read_seq)
+			{
+			/* This is a stale message that has been buffered so clear it */
+			pqueue_pop(s->d1->buffered_messages);
+			dtls1_hm_fragment_free(frag);
+			pitem_free(item);
+			item = NULL;
+			frag = NULL;
+			}
+		}
+	while (item == NULL);
 
-	frag = (hm_fragment *)item->data;
 	
 	/* Don't return if reassembly still in progress */
 	if (frag->reassembly != NULL)
@@ -1339,21 +1354,6 @@ dtls1_retransmit_message(SSL *s, unsigne
 	return ret;
 	}
 
-/* call this function when the buffered messages are no longer needed */
-void
-dtls1_clear_record_buffer(SSL *s)
-	{
-	pitem *item;
-
-	for(item = pqueue_pop(s->d1->sent_messages);
-		item != NULL; item = pqueue_pop(s->d1->sent_messages))
-		{
-		dtls1_hm_fragment_free((hm_fragment *)item->data);
-		pitem_free(item);
-		}
-	}
-
-
 unsigned char *
 dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt,
 			unsigned long len, unsigned long frag_off, unsigned long frag_len)
diff -up openssl-1.0.1e/ssl/d1_clnt.c.dtls1-dos2 openssl-1.0.1e/ssl/d1_clnt.c
--- openssl-1.0.1e/ssl/d1_clnt.c.dtls1-dos2	2016-09-20 15:53:03.748445806 +0200
+++ openssl-1.0.1e/ssl/d1_clnt.c	2016-09-20 15:58:38.292200957 +0200
@@ -739,6 +739,7 @@ int dtls1_connect(SSL *s)
 			/* done with handshaking */
 			s->d1->handshake_read_seq  = 0;
 			s->d1->next_handshake_write_seq = 0;
+			dtls1_clear_received_buffer(s);
 			goto end;
 			/* break; */
 			
diff -up openssl-1.0.1e/ssl/d1_lib.c.dtls1-dos2 openssl-1.0.1e/ssl/d1_lib.c
--- openssl-1.0.1e/ssl/d1_lib.c.dtls1-dos2	2016-09-20 15:53:03.749445830 +0200
+++ openssl-1.0.1e/ssl/d1_lib.c	2016-09-20 16:18:10.046443374 +0200
@@ -133,7 +133,6 @@ int dtls1_new(SSL *s)
 static void dtls1_clear_queues(SSL *s)
 	{
     pitem *item = NULL;
-    hm_fragment *frag = NULL;
 	DTLS1_RECORD_DATA *rdata;
 
     while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL)
@@ -158,32 +157,45 @@ static void dtls1_clear_queues(SSL *s)
         pitem_free(item);
         }
 
-    while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL)
-        {
+    while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
+	{
+        rdata = (DTLS1_RECORD_DATA *)item->data;
+        if (rdata->rbuf.buf)
+		{
+		OPENSSL_free(rdata->rbuf.buf);
+		}
+        OPENSSL_free(item->data);
+        pitem_free(item);
+	}
+
+    dtls1_clear_received_buffer(s);
+    dtls1_clear_sent_buffer(s);
+	}
+
+void dtls1_clear_received_buffer(SSL *s)
+	{
+    pitem *item = NULL;
+    hm_fragment *frag = NULL;
+
+    while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL)
+	{
         frag = (hm_fragment *)item->data;
-        OPENSSL_free(frag->fragment);
-        OPENSSL_free(frag);
+        dtls1_hm_fragment_free(frag);
         pitem_free(item);
         }
+	}
 
-    while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL)
-        {
+void dtls1_clear_sent_buffer(SSL *s)
+	{
+    pitem *item = NULL;
+    hm_fragment *frag = NULL;
+
+    while ((item = pqueue_pop(s->d1->sent_messages)) != NULL)
+	{
         frag = (hm_fragment *)item->data;
-        OPENSSL_free(frag->fragment);
-        OPENSSL_free(frag);
+        dtls1_hm_fragment_free(frag);
         pitem_free(item);
         }
-
-	while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
-		{
-		rdata = (DTLS1_RECORD_DATA *) item->data;
-		if (rdata->rbuf.buf)
-			{
-			OPENSSL_free(rdata->rbuf.buf);
-			}
-		OPENSSL_free(item->data);
-		pitem_free(item);
-		}
 	}
 
 void dtls1_free(SSL *s)
@@ -410,7 +422,7 @@ void dtls1_stop_timer(SSL *s)
 	s->d1->timeout_duration = 1;
 	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
 	/* Clear retransmission buffer */
-	dtls1_clear_record_buffer(s);
+	dtls1_clear_sent_buffer(s);
 	}
 
 int dtls1_check_timeout_num(SSL *s)
diff -up openssl-1.0.1e/ssl/d1_pkt.c.dtls1-dos2 openssl-1.0.1e/ssl/d1_pkt.c
--- openssl-1.0.1e/ssl/d1_pkt.c.dtls1-dos2	2016-09-20 15:53:17.246758715 +0200
+++ openssl-1.0.1e/ssl/d1_pkt.c	2016-09-20 16:14:33.020390824 +0200
@@ -1900,6 +1900,12 @@ dtls1_reset_seq_numbers(SSL *s, int rw)
 		s->d1->r_epoch++;
 		memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP));
 		memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
+
+		/*
+		 * We must not use any buffered messages received from the previous
+		 * epoch
+		 */
+		dtls1_clear_received_buffer(s);
 		}
 	else
 		{
diff -up openssl-1.0.1e/ssl/d1_srvr.c.dtls1-dos2 openssl-1.0.1e/ssl/d1_srvr.c
--- openssl-1.0.1e/ssl/d1_srvr.c.dtls1-dos2	2016-09-20 15:53:03.750445853 +0200
+++ openssl-1.0.1e/ssl/d1_srvr.c	2016-09-20 16:15:39.699943181 +0200
@@ -276,7 +276,7 @@ int dtls1_accept(SSL *s)
 		case SSL3_ST_SW_HELLO_REQ_B:
 
 			s->shutdown=0;
-			dtls1_clear_record_buffer(s);
+			dtls1_clear_sent_buffer(s);
 			dtls1_start_timer(s);
 			ret=dtls1_send_hello_request(s);
 			if (ret <= 0) goto end;
@@ -811,6 +811,7 @@ int dtls1_accept(SSL *s)
 			/* next message is server hello */
 			s->d1->handshake_write_seq = 0;
 			s->d1->next_handshake_write_seq = 0;
+			dtls1_clear_received_buffer(s);
 			goto end;
 			/* break; */
 
diff -up openssl-1.0.1e/ssl/ssl_locl.h.dtls1-dos2 openssl-1.0.1e/ssl/ssl_locl.h
--- openssl-1.0.1e/ssl/ssl_locl.h.dtls1-dos2	2016-09-20 15:53:03.751445876 +0200
+++ openssl-1.0.1e/ssl/ssl_locl.h	2016-09-20 16:11:36.288276350 +0200
@@ -974,7 +974,8 @@ int dtls1_retransmit_message(SSL *s, uns
 	unsigned long frag_off, int *found);
 int dtls1_get_queue_priority(unsigned short seq, int is_ccs);
 int dtls1_retransmit_buffered_messages(SSL *s);
-void dtls1_clear_record_buffer(SSL *s);
+void dtls1_clear_received_buffer(SSL *s);
+void dtls1_clear_sent_buffer(SSL *s);
 void dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr);
 void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr);
 void dtls1_reset_seq_numbers(SSL *s, int rw);
@@ -989,6 +990,7 @@ int dtls1_is_timer_expired(SSL *s);
 void dtls1_double_timeout(SSL *s);
 int dtls1_send_newsession_ticket(SSL *s);
 unsigned int dtls1_min_mtu(void);
+void dtls1_hm_fragment_free(hm_fragment *frag);
 
 /* some client-only functions */
 int ssl3_client_hello(SSL *s);