From b2a2c6af2a73ef99ef6d0033c5c43e968a3cb2e1 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 6 Mar 2012 13:45:47 +0000 Subject: [PATCH] PR: 2755 Submitted by: Robin Seggelmann Reduce MTU after failed transmissions. --- crypto/bio/bio.h | 1 + crypto/bio/bss_dgram.c | 21 +++++++++++++++++++++ ssl/d1_both.c | 4 ++-- ssl/d1_lib.c | 5 +++++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/crypto/bio/bio.h b/crypto/bio/bio.h index 6b2daa1f10..03bd3b2875 100644 --- a/crypto/bio/bio.h +++ b/crypto/bio/bio.h @@ -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 diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c index bfbcf9b5f8..437a050004 100644 --- a/crypto/bio/bss_dgram.c +++ b/crypto/bio/bss_dgram.c @@ -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; diff --git a/ssl/d1_both.c b/ssl/d1_both.c index 85f4d83efe..4481c55051 100644 --- a/ssl/d1_both.c +++ b/ssl/d1_both.c @@ -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); diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index 2e57b63101..bceba3c971 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -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); } -- 2.25.1