summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsteve <steve>2012-03-06 13:47:42 +0000
committersteve <steve>2012-03-06 13:47:42 +0000
commita2a0033acfff9b015de60ee138a08dd6370d6b07 (patch)
tree6181e5040ca65d82817829a205c39bf9de664979
parentd16d2ddc146a207ed5b15d432cef9df82330a04f (diff)
downloadopenssl-a2a0033acfff9b015de60ee138a08dd6370d6b07.tar.gz
PR: 2755
Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de> Reduce MTU after failed transmissions.
-rw-r--r--crypto/bio/bio.h1
-rw-r--r--crypto/bio/bss_dgram.c21
-rw-r--r--ssl/d1_both.c4
-rw-r--r--ssl/d1_lib.c5
4 files changed, 29 insertions, 2 deletions
diff --git a/crypto/bio/bio.h b/crypto/bio/bio.h
index b440bdd6d..05699ab21 100644
--- a/crypto/bio/bio.h
+++ b/crypto/bio/bio.h
@@ -157,6 +157,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 4d1a64ea3..1b1e4bec8 100644
--- a/crypto/bio/bss_dgram.c
+++ b/crypto/bio/bss_dgram.c
@@ -616,6 +616,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 5c47c7c19..373285885 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 e205b5c6e..f4bfd29af 100644
--- a/ssl/d1_lib.c
+++ b/ssl/d1_lib.c
@@ -424,6 +424,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);
+ }
+
#ifndef OPENSSL_NO_HEARTBEATS
if (s->tlsext_hb_pending)
{