indent has problems with comments that are on the right hand side of a line.
[openssl.git] / ssl / d1_both.c
index 9a981e82ae3d7b9a0dc27e3c03c6c5492e4fd302..b70192b4428e7ea313e58322849382ec42c7c034 100644 (file)
@@ -156,9 +156,8 @@ static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe
 static unsigned char bitmask_end_values[]   = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
 
 /* XDTLS:  figure out the right values */
-static const unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
+static const unsigned int g_probable_mtu[] = {1500, 512, 256};
 
-static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
 static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, 
        unsigned long frag_len);
 static unsigned char *dtls1_write_message_header(SSL *s,
@@ -224,58 +223,50 @@ void dtls1_hm_fragment_free(hm_fragment *frag)
        OPENSSL_free(frag);
        }
 
-static void dtls1_query_mtu(SSL *s)
+static int dtls1_query_mtu(SSL *s)
 {
-       /* AHA!  Figure out the MTU, and stick to the right size */
-       if (s->d1->mtu < dtls1_min_mtu() && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
+       if(s->d1->link_mtu)
                {
-               s->d1->mtu = 
-                       BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+               s->d1->mtu = s->d1->link_mtu-BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
+               s->d1->link_mtu = 0;
+               }
 
-               /* I've seen the kernel return bogus numbers when it doesn't know
-                * (initial write), so just make sure we have a reasonable number */
-               if (s->d1->mtu < dtls1_min_mtu())
+       /* AHA!  Figure out the MTU, and stick to the right size */
+       if (s->d1->mtu < dtls1_min_mtu(s))
+               {
+               if(!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
                        {
-                       s->d1->mtu = 0;
-                       s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
-                       BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, 
-                               s->d1->mtu, NULL);
+                       s->d1->mtu =
+                               BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+
+                       /* I've seen the kernel return bogus numbers when it doesn't know
+                        * (initial write), so just make sure we have a reasonable number */
+                       if (s->d1->mtu < dtls1_min_mtu(s))
+                               {
+                               /* Set to min mtu */
+                               s->d1->mtu = dtls1_min_mtu(s);
+                               BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
+                                       s->d1->mtu, NULL);
+                               }
                        }
+               else
+                       return 0;
                }
+       return 1;
 }
 
 /* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
 int dtls1_do_write(SSL *s, int type)
        {
        int ret;
-       int curr_mtu;
-       unsigned int len, frag_off, mac_size, blocksize;
-
-       dtls1_query_mtu(s);
-#if 0 
-       mtu = s->d1->mtu;
+       unsigned int curr_mtu;
+       int retry = 1;
+       unsigned int len, frag_off, mac_size, blocksize, used_len;
 
-       fprintf(stderr, "using MTU = %d\n", mtu);
-
-       mtu -= (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
-
-       curr_mtu = mtu - BIO_wpending(SSL_get_wbio(s));
-
-       if ( curr_mtu > 0)
-               mtu = curr_mtu;
-       else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0)
-               return ret;
-
-       if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu)
-               {
-               ret = BIO_flush(SSL_get_wbio(s));
-               if ( ret <= 0)
-                       return ret;
-               mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
-               }
-#endif
+       if(!dtls1_query_mtu(s))
+               return -1;
 
-       OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu());  /* should have something reasonable now */
+       OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu(s));  /* should have something reasonable now */
 
        if ( s->init_off == 0  && type == SSL3_RT_HANDSHAKE)
                OPENSSL_assert(s->init_num == 
@@ -298,10 +289,15 @@ int dtls1_do_write(SSL *s, int type)
                blocksize = 0;
 
        frag_off = 0;
-       while( s->init_num)
+       /* s->init_num shouldn't ever be < 0...but just in case */
+       while(s->init_num > 0)
                {
-               curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - 
-                       DTLS1_RT_HEADER_LENGTH - mac_size - blocksize;
+               used_len = BIO_wpending(SSL_get_wbio(s)) +  DTLS1_RT_HEADER_LENGTH
+                       + mac_size + blocksize;
+               if(s->d1->mtu > used_len)
+                       curr_mtu = s->d1->mtu - used_len;
+               else
+                       curr_mtu = 0;
 
                if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH)
                        {
@@ -309,15 +305,27 @@ int dtls1_do_write(SSL *s, int type)
                        ret = BIO_flush(SSL_get_wbio(s));
                        if ( ret <= 0)
                                return ret;
-                       curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH -
-                               mac_size - blocksize;
+                       used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize;
+                       if(s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH)
+                               {
+                               curr_mtu = s->d1->mtu - used_len;
+                               }
+                       else
+                               {
+                               /* Shouldn't happen */
+                               return -1;
+                               }
                        }
 
-               if ( s->init_num > curr_mtu)
+               /* We just checked that s->init_num > 0 so this cast should be safe */
+               if (((unsigned int)s->init_num) > curr_mtu)
                        len = curr_mtu;
                else
                        len = s->init_num;
 
+               /* Shouldn't ever happen */
+               if(len > INT_MAX)
+                       len = INT_MAX;
 
                /* XDTLS: this function is too long.  split out the CCS part */
                if ( type == SSL3_RT_HANDSHAKE)
@@ -328,12 +336,17 @@ int dtls1_do_write(SSL *s, int type)
                                s->init_off -= DTLS1_HM_HEADER_LENGTH;
                                s->init_num += DTLS1_HM_HEADER_LENGTH;
 
-                               if ( s->init_num > curr_mtu)
+                               /* We just checked that s->init_num > 0 so this cast should be safe */
+                               if (((unsigned int)s->init_num) > curr_mtu)
                                        len = curr_mtu;
                                else
                                        len = s->init_num;
                                }
 
+                       /* Shouldn't ever happen */
+                       if(len > INT_MAX)
+                               len = INT_MAX;
+
                        if ( len < DTLS1_HM_HEADER_LENGTH )
                                {
                                /*
@@ -358,11 +371,16 @@ int dtls1_do_write(SSL *s, int type)
                         * is fine and wait for an alert to handle the
                         * retransmit 
                         */
-                       if ( BIO_ctrl(SSL_get_wbio(s),
+                       if ( retry && BIO_ctrl(SSL_get_wbio(s),
                                BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0 )
                                {
                                if(!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
-                                       dtls1_query_mtu(s);
+                                       {
+                                       if(!dtls1_query_mtu(s))
+                                               return -1;
+                                       /* Have one more go */
+                                       retry = 0;
+                                       }
                                else
                                        return -1;
                                }
@@ -463,10 +481,15 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
 again:
        i = dtls1_get_message_fragment(s, st1, stn, max, ok);
        if ( i == DTLS1_HM_BAD_FRAGMENT ||
-               i == DTLS1_HM_FRAGMENT_RETRY)  /* bad fragment received */
+               i == DTLS1_HM_FRAGMENT_RETRY)
+               {
+               /* bad fragment received */
                goto again;
+               }
        else if ( i <= 0 && !*ok)
+               {
                return i;
+               }
 
        p = (unsigned char *)s->init_buf->data;
        msg_len = msg_hdr->msg_len;
@@ -556,7 +579,8 @@ static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max
 static int
 dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
        {
-       /* (0) check whether the desired fragment is available
+       /*-
+        * (0) check whether the desired fragment is available
         * if so:
         * (1) copy over the fragment to s->init_buf->data[]
         * (2) update s->init_num
@@ -946,7 +970,8 @@ f_err:
        return(-1);
        }
 
-/* for these 2 messages, we need to
+/*-
+ * for these 2 messages, we need to
  * ssl->enc_read_ctx                   re-init
  * ssl->s3->read_sequence              zero
  * ssl->s3->read_mac_secret            re-init
@@ -1002,9 +1027,11 @@ int dtls1_read_failed(SSL *s, int code)
                }
 
 #ifndef OPENSSL_NO_HEARTBEATS
-       if (!SSL_in_init(s) && !s->tlsext_hb_pending)  /* done, no need to send a retransmit */
+       /* done, no need to send a retransmit */
+       if (!SSL_in_init(s) && !s->tlsext_hb_pending)
 #else
-       if (!SSL_in_init(s))  /* done, no need to send a retransmit */
+       /* done, no need to send a retransmit */
+       if (!SSL_in_init(s))
 #endif
                {
                BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
@@ -1147,7 +1174,7 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
        struct dtls1_retransmit_state saved_state;
        unsigned char save_write_sequence[8];
 
-       /*
+       /*-
          OPENSSL_assert(s->init_num == 0);
          OPENSSL_assert(s->init_off == 0);
         */
@@ -1299,28 +1326,20 @@ dtls1_write_message_header(SSL *s, unsigned char *p)
        return p;
        }
 
-unsigned int 
-dtls1_min_mtu(void)
+unsigned int
+dtls1_link_min_mtu(void)
        {
        return (g_probable_mtu[(sizeof(g_probable_mtu) / 
                sizeof(g_probable_mtu[0])) - 1]);
        }
 
-static unsigned int 
-dtls1_guess_mtu(unsigned int curr_mtu)
+unsigned int
+dtls1_min_mtu(SSL *s)
        {
-       unsigned int i;
-
-       if ( curr_mtu == 0 )
-               return g_probable_mtu[0] ;
-
-       for ( i = 0; i < sizeof(g_probable_mtu)/sizeof(g_probable_mtu[0]); i++)
-               if ( curr_mtu > g_probable_mtu[i])
-                       return g_probable_mtu[i];
-
-       return curr_mtu;
+       return dtls1_link_min_mtu()-BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
        }
 
+
 void
 dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
        {
@@ -1404,6 +1423,8 @@ dtls1_process_heartbeat(SSL *s)
                 * payload, plus padding
                 */
                buffer = OPENSSL_malloc(write_length);
+               if (buffer == NULL)
+                       return -1;
                bp = buffer;
 
                /* Enter response type, length and copy payload */
@@ -1481,7 +1502,8 @@ dtls1_heartbeat(SSL *s)
         */
        OPENSSL_assert(payload + padding <= 16381);
 
-       /* Create HeartBeat message, we just use a sequence number
+       /*-
+        * Create HeartBeat message, we just use a sequence number
         * as payload to distuingish different messages and add
         * some random stuff.
         *  - Message Type, 1 byte
@@ -1491,6 +1513,11 @@ dtls1_heartbeat(SSL *s)
         *  - Padding
         */
        buf = OPENSSL_malloc(1 + 2 + payload + padding);
+       if (buf == NULL)
+               {
+               SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_MALLOC_FAILURE);
+               return -1;
+               }
        p = buf;
        /* Message Type */
        *p++ = TLS1_HB_REQUEST;