PR: 1828
[openssl.git] / ssl / d1_pkt.c
index b1248770b59c56409ba50fcb48130f7f2f22a435..b0ab1e850cafe00b717690767b25c57863d5b8c7 100644 (file)
@@ -597,6 +597,7 @@ again:
        /* check whether this is a repeat, or aged record */
        if ( ! dtls1_record_replay_check(s, bitmap, &(rr->seq_num)))
                {
+               rr->length = 0;
                s->packet_length=0; /* dump this record */
                goto again;     /* get another record */
                }
@@ -811,6 +812,14 @@ start:
              *  may be fragmented--don't always expect dest_maxlen bytes */
                        if ( rr->length < dest_maxlen)
                                {
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+                               /*
+                                * for normal alerts rr->length is 2, while
+                                * dest_maxlen is 7 if we were to handle this
+                                * non-existing alert...
+                                */
+                               FIX ME
+#endif
                                s->rstate=SSL_ST_READ_HEADER;
                                rr->length = 0;
                                goto start;
@@ -933,7 +942,9 @@ start:
                                n2s(p, seq);
                                n2l3(p, frag_off);
 
-                               dtls1_retransmit_message(s, seq, frag_off, &found);
+                               dtls1_retransmit_message(s,
+                                                                                dtls1_get_queue_priority(frag->msg_header.seq, 0),
+                                                                                frag_off, &found);
                                if ( ! found  && SSL_in_init(s))
                                        {
                                        /* fprintf( stderr,"in init = %d\n", SSL_in_init(s)); */
@@ -1006,8 +1017,8 @@ start:
                /* do this whenever CCS is processed */
                dtls1_reset_seq_numbers(s, SSL3_CC_READ);
 
-               /* handshake read seq is reset upon handshake completion */
-               s->d1->handshake_read_seq++;
+               if (s->client_version == DTLS1_BAD_VER)
+                       s->d1->handshake_read_seq++;
 
                goto start;
                }
@@ -1026,6 +1037,16 @@ start:
                        goto start;
                        }
 
+               /* If we are server, we may have a repeated FINISHED of the
+                * client here, then retransmit our CCS and FINISHED.
+                */
+               if (msg_hdr.type == SSL3_MT_FINISHED)
+                       {
+                       dtls1_retransmit_buffered_messages(s);
+                       rr->length = 0;
+                       goto start;
+                       }
+
                if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&
                        !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))
                        {
@@ -1251,7 +1272,7 @@ int dtls1_write_bytes(SSL *s, int type, const void *buf_, int len)
        else 
                s->s3->wnum += i;
 
-       return tot + i;
+       return i;
        }
 
 int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment)
@@ -1576,7 +1597,7 @@ int dtls1_dispatch_alert(SSL *s)
        {
        int i,j;
        void (*cb)(const SSL *ssl,int type,int val)=NULL;
-       unsigned char buf[2 + 2 + 3]; /* alert level + alert desc + message seq +frag_off */
+       unsigned char buf[DTLS1_AL_HEADER_LENGTH];
        unsigned char *ptr = &buf[0];
 
        s->s3->alert_dispatch=0;
@@ -1585,6 +1606,7 @@ int dtls1_dispatch_alert(SSL *s)
        *ptr++ = s->s3->send_alert[0];
        *ptr++ = s->s3->send_alert[1];
 
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
        if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
                {       
                s2n(s->d1->handshake_read_seq, ptr);
@@ -1600,6 +1622,7 @@ int dtls1_dispatch_alert(SSL *s)
 #endif
                l2n3(s->d1->r_msg_hdr.frag_off, ptr);
                }
+#endif
 
        i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0);
        if (i <= 0)
@@ -1609,8 +1632,11 @@ int dtls1_dispatch_alert(SSL *s)
                }
        else
                {
-               if ( s->s3->send_alert[0] == SSL3_AL_FATAL ||
-                       s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
+               if (s->s3->send_alert[0] == SSL3_AL_FATAL
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+                   || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+#endif
+                  )
                        (void)BIO_flush(s->wbio);
 
                if (s->msg_callback)
@@ -1744,6 +1770,7 @@ dtls1_reset_seq_numbers(SSL *s, int rw)
        else
                {
                seq = s->s3->write_sequence;
+               memcpy(s->d1->last_write_sequence, seq, sizeof(s->s3->write_sequence));
                s->d1->w_epoch++;
                }