194 |
|
#endif |
195 |
|
static int dtls1_buffer_record(SSL *s, record_pqueue *q, |
196 |
|
unsigned char *priority); |
197 |
< |
static int dtls1_process_record(SSL *s); |
197 |
> |
static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap); |
198 |
|
|
199 |
|
/* copy buffered record into SSL structure */ |
200 |
|
static int dtls1_copy_record(SSL *s, pitem *item) |
319 |
|
static int dtls1_process_buffered_records(SSL *s) |
320 |
|
{ |
321 |
|
pitem *item; |
322 |
+ |
SSL3_BUFFER *rb; |
323 |
+ |
SSL3_RECORD *rr; |
324 |
+ |
DTLS1_BITMAP *bitmap; |
325 |
+ |
unsigned int is_next_epoch; |
326 |
+ |
int replayok = 1; |
327 |
|
|
328 |
|
item = pqueue_peek(s->d1->unprocessed_rcds.q); |
329 |
|
if (item) { |
330 |
|
/* Check if epoch is current. */ |
331 |
|
if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) |
332 |
< |
return (1); /* Nothing to do. */ |
332 |
> |
return 1; /* Nothing to do. */ |
333 |
|
|
334 |
+ |
rr = &s->s3->rrec; |
335 |
+ |
rb = &s->s3->rbuf; |
336 |
+ |
|
337 |
+ |
if (rb->left > 0) { |
338 |
+ |
/* |
339 |
+ |
* We've still got data from the current packet to read. There could |
340 |
+ |
* be a record from the new epoch in it - so don't overwrite it |
341 |
+ |
* with the unprocessed records yet (we'll do it when we've |
342 |
+ |
* finished reading the current packet). |
343 |
+ |
*/ |
344 |
+ |
return 1; |
345 |
+ |
} |
346 |
+ |
|
347 |
+ |
|
348 |
|
/* Process all the records. */ |
349 |
|
while (pqueue_peek(s->d1->unprocessed_rcds.q)) { |
350 |
|
dtls1_get_unprocessed_record(s); |
351 |
< |
if (!dtls1_process_record(s)) |
352 |
< |
return (0); |
351 |
> |
bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); |
352 |
> |
if (bitmap == NULL) { |
353 |
> |
/* |
354 |
> |
* Should not happen. This will only ever be NULL when the |
355 |
> |
* current record is from a different epoch. But that cannot |
356 |
> |
* be the case because we already checked the epoch above |
357 |
> |
*/ |
358 |
> |
SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS, |
359 |
> |
ERR_R_INTERNAL_ERROR); |
360 |
> |
return 0; |
361 |
> |
} |
362 |
> |
#ifndef OPENSSL_NO_SCTP |
363 |
> |
/* Only do replay check if no SCTP bio */ |
364 |
> |
if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) |
365 |
> |
#endif |
366 |
> |
{ |
367 |
> |
/* |
368 |
> |
* Check whether this is a repeat, or aged record. We did this |
369 |
> |
* check once already when we first received the record - but |
370 |
> |
* we might have updated the window since then due to |
371 |
> |
* records we subsequently processed. |
372 |
> |
*/ |
373 |
> |
replayok = dtls1_record_replay_check(s, bitmap); |
374 |
> |
} |
375 |
> |
|
376 |
> |
if (!replayok || !dtls1_process_record(s, bitmap)) { |
377 |
> |
/* dump this record */ |
378 |
> |
rr->length = 0; |
379 |
> |
s->packet_length = 0; |
380 |
> |
continue; |
381 |
> |
} |
382 |
> |
|
383 |
|
if (dtls1_buffer_record(s, &(s->d1->processed_rcds), |
384 |
|
s->s3->rrec.seq_num) < 0) |
385 |
< |
return -1; |
385 |
> |
return 0; |
386 |
|
} |
387 |
|
} |
388 |
|
|
393 |
|
s->d1->processed_rcds.epoch = s->d1->r_epoch; |
394 |
|
s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; |
395 |
|
|
396 |
< |
return (1); |
396 |
> |
return 1; |
397 |
|
} |
398 |
|
|
399 |
|
#if 0 |
440 |
|
|
441 |
|
#endif |
442 |
|
|
443 |
< |
static int dtls1_process_record(SSL *s) |
443 |
> |
static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) |
444 |
|
{ |
445 |
|
int i, al; |
446 |
|
int enc_err; |
600 |
|
|
601 |
|
/* we have pulled in a full packet so zero things */ |
602 |
|
s->packet_length = 0; |
603 |
+ |
|
604 |
+ |
/* Mark receipt of record. */ |
605 |
+ |
dtls1_record_bitmap_update(s, bitmap); |
606 |
+ |
|
607 |
|
return (1); |
608 |
|
|
609 |
|
f_err: |
634 |
|
|
635 |
|
rr = &(s->s3->rrec); |
636 |
|
|
637 |
+ |
again: |
638 |
|
/* |
639 |
|
* The epoch may have changed. If so, process all the pending records. |
640 |
|
* This is a non-blocking operation. |
641 |
|
*/ |
642 |
< |
if (dtls1_process_buffered_records(s) < 0) |
642 |
> |
if (!dtls1_process_buffered_records(s)) |
643 |
|
return -1; |
644 |
|
|
645 |
|
/* if we're renegotiating, then there may be buffered records */ |
647 |
|
return 1; |
648 |
|
|
649 |
|
/* get something from the wire */ |
596 |
– |
again: |
650 |
|
/* check if we have the header */ |
651 |
|
if ((s->rstate != SSL_ST_READ_BODY) || |
652 |
|
(s->packet_length < DTLS1_RT_HEADER_LENGTH)) { |
770 |
|
if (dtls1_buffer_record |
771 |
|
(s, &(s->d1->unprocessed_rcds), rr->seq_num) < 0) |
772 |
|
return -1; |
720 |
– |
/* Mark receipt of record. */ |
721 |
– |
dtls1_record_bitmap_update(s, bitmap); |
773 |
|
} |
774 |
|
rr->length = 0; |
775 |
|
s->packet_length = 0; |
776 |
|
goto again; |
777 |
|
} |
778 |
|
|
779 |
< |
if (!dtls1_process_record(s)) { |
779 |
> |
if (!dtls1_process_record(s, bitmap)) { |
780 |
|
rr->length = 0; |
781 |
|
s->packet_length = 0; /* dump this record */ |
782 |
|
goto again; /* get another record */ |
783 |
|
} |
733 |
– |
dtls1_record_bitmap_update(s, bitmap); /* Mark receipt of record. */ |
784 |
|
|
785 |
|
return (1); |
786 |
|
|
1864 |
|
if (rr->epoch == s->d1->r_epoch) |
1865 |
|
return &s->d1->bitmap; |
1866 |
|
|
1867 |
< |
/* Only HM and ALERT messages can be from the next epoch */ |
1867 |
> |
/* |
1868 |
> |
* Only HM and ALERT messages can be from the next epoch and only if we |
1869 |
> |
* have already processed all of the unprocessed records from the last |
1870 |
> |
* epoch |
1871 |
> |
*/ |
1872 |
|
else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && |
1873 |
+ |
s->d1->unprocessed_rcds.epoch != s->d1->r_epoch && |
1874 |
|
(rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { |
1875 |
|
*is_next_epoch = 1; |
1876 |
|
return &s->d1->next_bitmap; |
1949 |
|
s->d1->r_epoch++; |
1950 |
|
memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); |
1951 |
|
memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); |
1952 |
+ |
|
1953 |
+ |
/* |
1954 |
+ |
* We must not use any buffered messages received from the previous |
1955 |
+ |
* epoch |
1956 |
+ |
*/ |
1957 |
+ |
dtls1_clear_received_buffer(s); |
1958 |
|
} else { |
1959 |
|
seq = s->s3->write_sequence; |
1960 |
|
memcpy(s->d1->last_write_sequence, seq, |