bss_dgram.c: add BIO_CTRL_DGRAM_SET_DONT_FRAG.
authorAndy Polyakov <appro@openssl.org>
Mon, 11 Jun 2012 14:56:25 +0000 (14:56 +0000)
committerAndy Polyakov <appro@openssl.org>
Mon, 11 Jun 2012 14:56:25 +0000 (14:56 +0000)
PR: 2830
Submitted by: Robin Seggelmann

crypto/bio/bio.h
crypto/bio/bss_dgram.c

index 05699ab21210edc4831cf7378a3fe6734edcdba8..d32bf7f7a2a98b9fdfb0d0f7e659d82ec1135b43 100644 (file)
@@ -174,6 +174,7 @@ extern "C" {
 
 #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 */
index a5a5cc125598af55d5e82640bb982a630e6de2e6..0d3c1cf3426beb304205cb9303eebb532b3ef247 100644 (file)
@@ -460,8 +460,8 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
        int *ip;
        struct sockaddr *to = NULL;
        bio_dgram_data *data = NULL;
-#if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
        int sockopt_val = 0;
+#if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
        socklen_t sockopt_len;  /* assume that system supporting IP_MTU is
                                 * modern enough to define socklen_t */
        socklen_t addr_len;
@@ -848,6 +848,50 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
                        ret = 0;
                break;
 #endif
+       case BIO_CTRL_DGRAM_SET_DONT_FRAG:
+               sockopt_val = num ? 1 : 0;
+
+               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) && defined(IP_MTUDISCOVER)
+                               if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
+                                   (ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
+                                       &sockopt_val, sizeof(sockopt_val))) < 0)
+                                       { perror("setsockopt"); ret = -1; }
+#elif defined(OPENSSL_SYS_WINDOWS) && defined(IP_DONTFRAGMENT)
+                               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) && defined(IPV6_MTUDISCOVER)
+                               if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
+                                   (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;