Index: crypto/bio/bio.h
===================================================================
RCS file: /v/openssl/cvs/openssl/crypto/bio/bio.h,v
retrieving revision 1.76.2.5.2.4
diff -u -r1.76.2.5.2.4 bio.h
--- crypto/bio/bio.h	25 Feb 2012 17:58:03 -0000	1.76.2.5.2.4
+++ crypto/bio/bio.h	5 Mar 2012 11:35:09 -0000
@@ -157,6 +157,7 @@
 /* #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: crypto/bio/bss_dgram.c
===================================================================
RCS file: /v/openssl/cvs/openssl/crypto/bio/bss_dgram.c,v
retrieving revision 1.7.2.23.2.5
diff -u -r1.7.2.23.2.5 bss_dgram.c
--- crypto/bio/bss_dgram.c	27 Dec 2011 14:37:43 -0000	1.7.2.23.2.5
+++ crypto/bio/bss_dgram.c	5 Mar 2012 11:35:09 -0000
@@ -616,6 +614,27 @@
 		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: ssl/d1_both.c
===================================================================
RCS file: /v/openssl/cvs/openssl/ssl/d1_both.c,v
retrieving revision 1.14.2.21.2.8
diff -u -r1.14.2.21.2.8 d1_both.c
--- ssl/d1_both.c	27 Feb 2012 16:38:10 -0000	1.14.2.21.2.8
+++ ssl/d1_both.c	5 Mar 2012 11:35:09 -0000
@@ -227,14 +233,14 @@
 	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: ssl/d1_lib.c
===================================================================
RCS file: /v/openssl/cvs/openssl/ssl/d1_lib.c,v
retrieving revision 1.8.2.13.2.8
diff -u -r1.8.2.13.2.8 d1_lib.c
--- ssl/d1_lib.c	31 Dec 2011 23:00:35 -0000	1.8.2.13.2.8
+++ ssl/d1_lib.c	5 Mar 2012 11:35:09 -0000
@@ -424,6 +475,11 @@
 		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)
 		{
