- /* 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;
+ pitem *next;
+ hm_fragment *nextfrag;
+
+ if (!s->server
+ || frag->msg_header.seq != 0
+ || s->d1->handshake_read_seq != 1
+ || s->statem.hand_state != DTLS_ST_SW_HELLO_VERIFY_REQUEST) {
+ /*
+ * This is a stale message that has been buffered so clear it.
+ * It is safe to pop this message from the queue even though
+ * we have an active iterator
+ */
+ pqueue_pop(s->d1->buffered_messages);
+ dtls1_hm_fragment_free(frag);
+ pitem_free(item);
+ item = NULL;
+ frag = NULL;
+ } else {
+ /*
+ * We have fragments for a ClientHello without a cookie,
+ * even though we have sent a HelloVerifyRequest. It is possible
+ * that the HelloVerifyRequest got lost and this is a
+ * retransmission of the original ClientHello
+ */
+ next = pqueue_next(&iter);
+ if (next != NULL) {
+ nextfrag = (hm_fragment *)next->data;
+ if (nextfrag->msg_header.seq == s->d1->handshake_read_seq) {
+ /*
+ * We have fragments for both a ClientHello without
+ * cookie and one with. Ditch the one without.
+ */
+ pqueue_pop(s->d1->buffered_messages);
+ dtls1_hm_fragment_free(frag);
+ pitem_free(item);
+ item = next;
+ frag = nextfrag;
+ } else {
+ chretran = 1;
+ }
+ } else {
+ chretran = 1;
+ }
+ }