--- crypto/bio/bio.h	6 Mar 2012 13:47:26 -0000	1.76.2.5.2.5
+++ crypto/bio/bio.h	4 Jun 2012 09:36:27 -0000
@@ -174,6 +174,7 @@
 
 #define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT   45 /* Next DTLS handshake timeout to
                                               * adjust socket timeouts */
+#define BIO_CTRL_DGRAM_SET_DONT_FRAG      48
 
 #ifndef OPENSSL_NO_SCTP
 /* SCTP stuff */

--- crypto/bio/bss_dgram.c	6 Mar 2012 13:47:26 -0000	1.7.2.23.2.6
+++ crypto/bio/bss_dgram.c	4 Jun 2012 09:36:27 -0000
@@ -445,11 +445,9 @@
 	int *ip;
 	struct sockaddr *to = NULL;
 	bio_dgram_data *data = NULL;
-#if defined(IP_MTU_DISCOVER) || defined(IP_MTU)
-	long sockopt_val = 0;
-	unsigned int sockopt_len = 0;
-#endif
+	int sockopt_val = 0;
 #ifdef OPENSSL_SYS_LINUX
+	unsigned int sockopt_len = 0;
 	socklen_t addr_len;
 	union	{
 		struct sockaddr	sa;
@@ -812,6 +810,52 @@
 			ret = 0;
 		break;
 #endif
+	case BIO_CTRL_DGRAM_SET_DONT_FRAG:
+#ifdef OPENSSL_SYS_LINUX
+		sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT;
+#else
+		sockopt_val = num ? 1 : 0;
+#endif
+
+		switch (data->peer.sa.sa_family)
+			{
+			case AF_INET:
+#if defined(IP_DONTFRAG)
+				if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAG,
+					&sockopt_val, sizeof(sockopt_val))) < 0)
+					{ perror("setsockopt"); ret = -1; }
+#elif defined(OPENSSL_SYS_LINUX)
+				if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
+					&sockopt_val, sizeof(sockopt_val))) < 0)
+					{ perror("setsockopt"); ret = -1; }
+#elif defined(OPENSSL_SYS_WINDOWS)
+				if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAGMENT,
+					(const char *)&sockopt_val, sizeof(sockopt_val))) < 0)
+					{ perror("setsockopt"); ret = -1; }
+#else
+				ret = -1;
+#endif
+				break;
+#if OPENSSL_USE_IPV6 
+			case AF_INET6:
+#if defined(IPV6_DONTFRAG)
+				if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_DONTFRAG,
+					&sockopt_val, sizeof(sockopt_val))) < 0)
+					{ perror("setsockopt"); ret = -1; }
+#elif defined(OPENSSL_SYS_LINUX)
+				if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+					&sockopt_val, sizeof(sockopt_val))) < 0)
+					{ perror("setsockopt"); ret = -1; }
+#else
+				ret = -1;
+#endif
+				break;
+#endif
+			default:
+				ret = -1;
+				break;
+			}
+		break;
 	default:
 		ret=0;
 		break;
