aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ssl/record/rec_layer_d1.c20
-rw-r--r--ssl/record/ssl3_record.c3
2 files changed, 21 insertions, 2 deletions
diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c
index f9bf10963c..0f7881ecd0 100644
--- a/ssl/record/rec_layer_d1.c
+++ b/ssl/record/rec_layer_d1.c
@@ -229,6 +229,7 @@ int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
int dtls1_process_buffered_records(SSL *s)
{
pitem *item;
+ SSL3_BUFFER *rb;
item = pqueue_peek(s->rlayer.d->unprocessed_rcds.q);
if (item) {
@@ -236,6 +237,18 @@ int dtls1_process_buffered_records(SSL *s)
if (s->rlayer.d->unprocessed_rcds.epoch != s->rlayer.d->r_epoch)
return (1); /* Nothing to do. */
+ rb = RECORD_LAYER_get_rbuf(&s->rlayer);
+
+ if (SSL3_BUFFER_get_left(rb) > 0) {
+ /*
+ * We've still got data from the current packet to read. There could
+ * be a record from the new epoch in it - so don't overwrite it
+ * with the unprocessed records yet (we'll do it when we've
+ * finished reading the current packet).
+ */
+ return 1;
+ }
+
/* Process all the records. */
while (pqueue_peek(s->rlayer.d->unprocessed_rcds.q)) {
dtls1_get_unprocessed_record(s);
@@ -1115,8 +1128,13 @@ DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
if (rr->epoch == s->rlayer.d->r_epoch)
return &s->rlayer.d->bitmap;
- /* Only HM and ALERT messages can be from the next epoch */
+ /*
+ * Only HM and ALERT messages can be from the next epoch and only if we
+ * have already processed all of the unprocessed records from the last
+ * epoch
+ */
else if (rr->epoch == (unsigned long)(s->rlayer.d->r_epoch + 1) &&
+ s->rlayer.d->unprocessed_rcds.epoch != s->rlayer.d->r_epoch &&
(rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) {
*is_next_epoch = 1;
return &s->rlayer.d->next_bitmap;
diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c
index 1782780db9..c99d5e4416 100644
--- a/ssl/record/ssl3_record.c
+++ b/ssl/record/ssl3_record.c
@@ -1467,6 +1467,7 @@ int dtls1_get_record(SSL *s)
rr = RECORD_LAYER_get_rrec(&s->rlayer);
+ again:
/*
* The epoch may have changed. If so, process all the pending records.
* This is a non-blocking operation.
@@ -1479,7 +1480,7 @@ int dtls1_get_record(SSL *s)
return 1;
/* get something from the wire */
- again:
+
/* check if we have the header */
if ((RECORD_LAYER_get_rstate(&s->rlayer) != SSL_ST_READ_BODY) ||
(RECORD_LAYER_get_packet_length(&s->rlayer) < DTLS1_RT_HEADER_LENGTH)) {