PR: 2755
authorDr. Stephen Henson <steve@openssl.org>
Tue, 6 Mar 2012 13:45:47 +0000 (13:45 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 6 Mar 2012 13:45:47 +0000 (13:45 +0000)
Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de>

Reduce MTU after failed transmissions.

crypto/bio/bio.h
crypto/bio/bss_dgram.c
ssl/d1_both.c
ssl/d1_lib.c

index 6b2daa1f10ed75cc86874f477e82726d13286ed8..03bd3b28758fc5773b53f2b6c46d1ce83d70acf9 100644 (file)
@@ -145,6 +145,7 @@ extern "C" {
 /* #endif */
 
 #define BIO_CTRL_DGRAM_QUERY_MTU          40 /* as kernel for current MTU */
+#define BIO_CTRL_DGRAM_GET_FALLBACK_MTU   47
 #define BIO_CTRL_DGRAM_GET_MTU            41 /* get cached value for MTU */
 #define BIO_CTRL_DGRAM_SET_MTU            42 /* set cached value for
                                              * MTU. want to use this
index bfbcf9b5f89382e8df5144a061906d1f7c097683..437a050004d06486a20161f4b6144e98a3cc9f36 100644 (file)
@@ -494,6 +494,27 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
                ret = 0;
 #endif
                break;
+       case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
+               switch (data->peer.sa.sa_family)
+                       {
+                       case AF_INET:
+                               ret = 576 - 20 - 8;
+                               break;
+#if OPENSSL_USE_IPV6
+                       case AF_INET6:
+#ifdef IN6_IS_ADDR_V4MAPPED
+                               if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
+                                       ret = 576 - 20 - 8;
+                               else
+#endif
+                                       ret = 1280 - 40 - 8;
+                               break;
+#endif
+                       default:
+                               ret = 576 - 20 - 8;
+                               break;
+                       }
+               break;
        case BIO_CTRL_DGRAM_GET_MTU:
                return data->mtu;
                break;
index 85f4d83efeb4d3acb53f6e91f0b5cfbf414c3382..4481c550511237a3a1be1f345975c827fa1077b8 100644 (file)
@@ -227,14 +227,14 @@ int dtls1_do_write(SSL *s, int type)
        unsigned int len, frag_off, mac_size, blocksize;
 
        /* AHA!  Figure out the MTU, and stick to the right size */
-       if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
+       if (s->d1->mtu < dtls1_min_mtu() && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
                {
                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())
+               if (s->d1->mtu < dtls1_min_mtu())
                        {
                        s->d1->mtu = 0;
                        s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
index 2e57b63101267ac1b8bc8feb21b27d7da050fa39..bceba3c971bc1b8d8ac168a36b35ee339cd7174e 100644 (file)
@@ -454,6 +454,11 @@ int dtls1_handle_timeout(SSL *s)
                state->timeout.read_timeouts = 1;
                }
 
+       if (state->timeout_duration > 2)
+               {
+               s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);               
+               }
+
        dtls1_start_timer(s);
        return dtls1_retransmit_buffered_messages(s);
        }