diff -u -r openssl-1.0.0-beta2-orig/apps/s_client.c openssl-1.0.0-beta2/apps/s_client.c
--- openssl-1.0.0-beta2-orig/apps/s_client.c	2009-02-15 16:29:59.000000000 +0100
+++ openssl-1.0.0-beta2/apps/s_client.c	2009-05-16 22:51:04.000000000 +0200
@@ -320,7 +320,7 @@
 	BIO_printf(bio_err," -ssl3         - just use SSLv3\n");
 	BIO_printf(bio_err," -tls1         - just use TLSv1\n");
 	BIO_printf(bio_err," -dtls1        - just use DTLSv1\n");    
-	BIO_printf(bio_err," -mtu          - set the MTU\n");
+	BIO_printf(bio_err," -mtu          - set the link layer MTU\n");
 	BIO_printf(bio_err," -no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
 	BIO_printf(bio_err," -bugs         - Switch on all SSL implementation bug workarounds\n");
 	BIO_printf(bio_err," -serverpref   - Use server's cipher preferences (only SSLv2)\n");
@@ -999,10 +999,10 @@
 			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
 			}
 
-		if (socket_mtu > 0)
+		if (socket_mtu > 28)
 			{
 			SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
-			SSL_set_mtu(con, socket_mtu);
+			SSL_set_mtu(con, socket_mtu - 28);
 			}
 		else
 			/* want to do MTU discovery */
diff -u -r openssl-1.0.0-beta2-orig/apps/s_server.c openssl-1.0.0-beta2/apps/s_server.c
--- openssl-1.0.0-beta2-orig/apps/s_server.c	2009-04-16 19:22:47.000000000 +0200
+++ openssl-1.0.0-beta2/apps/s_server.c	2009-05-16 22:52:16.000000000 +0200
@@ -459,7 +459,7 @@
 	BIO_printf(bio_err," -tls1         - Just talk TLSv1\n");
 	BIO_printf(bio_err," -dtls1        - Just talk DTLSv1\n");
 	BIO_printf(bio_err," -timeout      - Enable timeouts\n");
-	BIO_printf(bio_err," -mtu          - Set MTU\n");
+	BIO_printf(bio_err," -mtu          - Set link layer MTU\n");
 	BIO_printf(bio_err," -chain        - Read a certificate chain\n");
 	BIO_printf(bio_err," -no_ssl2      - Just disable SSLv2\n");
 	BIO_printf(bio_err," -no_ssl3      - Just disable SSLv3\n");
@@ -1823,10 +1823,10 @@
 			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
 			}
 
-		if (socket_mtu > 0)
+		if (socket_mtu > 28)
 			{
 			SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
-			SSL_set_mtu(con, socket_mtu);
+			SSL_set_mtu(con, socket_mtu - 28);
 			}
 		else
 			/* want to do MTU discovery */
diff -u -r openssl-1.0.0-beta2-orig/crypto/bio/bss_dgram.c openssl-1.0.0-beta2/crypto/bio/bss_dgram.c
--- openssl-1.0.0-beta2-orig/crypto/bio/bss_dgram.c	2009-04-14 17:13:35.000000000 +0200
+++ openssl-1.0.0-beta2/crypto/bio/bss_dgram.c	2009-05-16 23:10:11.000000000 +0200
@@ -70,7 +70,9 @@
 #include <sys/timeb.h>
 #endif
 
+#ifdef OPENSSL_SYS_LINUX
 #define IP_MTU      14 /* linux is lame */
+#endif
 
 #ifdef WATT32
 #define sock_write SockWrite  /* Watt-32 uses same names */
@@ -272,6 +274,10 @@
 	bio_dgram_data *data = NULL;
 	long sockopt_val = 0;
 	unsigned int sockopt_len = 0;
+#ifdef OPENSSL_SYS_LINUX
+	socklen_t addr_len;
+	struct sockaddr_storage addr;
+#endif
 
 	data = (bio_dgram_data *)b->ptr;
 
@@ -330,24 +336,87 @@
 #endif
 		break;
 		/* (Linux)kernel sets DF bit on outgoing IP packets */
-#ifdef IP_MTU_DISCOVER
 	case BIO_CTRL_DGRAM_MTU_DISCOVER:
-		sockopt_val = IP_PMTUDISC_DO;
-		if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
-			&sockopt_val, sizeof(sockopt_val))) < 0)
-			perror("setsockopt");
+#ifdef OPENSSL_SYS_LINUX
+		addr_len = (socklen_t)sizeof(struct sockaddr_storage);
+		memset((void *)&addr, 0, sizeof(struct sockaddr_storage));
+		if (getsockname(b->num, (void *)&addr, &addr_len) < 0)
+			{
+			ret = 0;
+			break;
+			}
+		sockopt_len = sizeof(sockopt_val);
+		switch (addr.ss_family)
+			{
+		case AF_INET:
+			sockopt_val = IP_PMTUDISC_DO;
+			if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
+				&sockopt_val, sizeof(sockopt_val))) < 0)
+				perror("setsockopt");
+			break;
+		case AF_INET6:
+			sockopt_val = IPV6_PMTUDISC_DO;
+			if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+				&sockopt_val, sizeof(sockopt_val))) < 0)
+				perror("setsockopt");
+			break;
+		default:
+			ret = -1;
+			break;
+			}
+		ret = -1;
+#else
 		break;
 #endif
 	case BIO_CTRL_DGRAM_QUERY_MTU:
-         sockopt_len = sizeof(sockopt_val);
-		if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
-			&sockopt_len)) < 0 || sockopt_val < 0)
-			{ ret = 0; }
-		else
+#ifdef OPENSSL_SYS_LINUX
+		addr_len = (socklen_t)sizeof(struct sockaddr_storage);
+		memset((void *)&addr, 0, sizeof(struct sockaddr_storage));
+		if (getsockname(b->num, (void *)&addr, &addr_len) < 0)
 			{
-			data->mtu = sockopt_val;
-			ret = data->mtu;
+			ret = 0;
+			break;
 			}
+		sockopt_len = sizeof(sockopt_val);
+		switch (addr.ss_family)
+			{
+		case AF_INET:
+			if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
+				&sockopt_len)) < 0 || sockopt_val < 0)
+				{
+				ret = 0;
+				}
+			else
+				{
+				/* we assume that the transport protocol is UDP and no
+				 * IP options are used.
+				 */
+				data->mtu = sockopt_val - 8 - 20;
+				ret = data->mtu;
+				}
+			break;
+		case AF_INET6:
+			if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (void *)&sockopt_val,
+				&sockopt_len)) < 0 || sockopt_val < 0)
+				{
+				ret = 0;
+				}
+			else
+				{
+				/* we assume that the transport protocol is UDP and no
+				 * IPV6 options are used.
+				 */
+				data->mtu = sockopt_val - 8 - 40;
+				ret = data->mtu;
+				}
+			break;
+		default:
+			ret = 0;
+			break;
+			}
+#else
+		ret = 0;
+#endif
 		break;
 	case BIO_CTRL_DGRAM_GET_MTU:
 		return data->mtu;
diff -u -r openssl-1.0.0-beta2-orig/include/openssl/dtls1.h openssl-1.0.0-beta2/include/openssl/dtls1.h
--- openssl-1.0.0-beta2-orig/include/openssl/dtls1.h	2009-04-19 20:03:12.000000000 +0200
+++ openssl-1.0.0-beta2/include/openssl/dtls1.h	2009-05-16 22:10:49.000000000 +0200
@@ -204,7 +204,7 @@
 	 */
 	record_pqueue buffered_app_data;
 
-	unsigned int mtu; /* max wire packet size */
+	unsigned int mtu; /* max DTLS packet size */
 
 	struct hm_header_st w_msg_hdr;
 	struct hm_header_st r_msg_hdr;
diff -u -r openssl-1.0.0-beta2-orig/ssl/dtls1.h openssl-1.0.0-beta2/ssl/dtls1.h
--- openssl-1.0.0-beta2-orig/ssl/dtls1.h	2009-04-19 20:03:12.000000000 +0200
+++ openssl-1.0.0-beta2/ssl/dtls1.h	2009-05-16 22:10:49.000000000 +0200
@@ -204,7 +204,7 @@
 	 */
 	record_pqueue buffered_app_data;
 
-	unsigned int mtu; /* max wire packet size */
+	unsigned int mtu; /* max DTLS packet size */
 
 	struct hm_header_st w_msg_hdr;
 	struct hm_header_st r_msg_hdr;
