aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2012-06-11 14:56:25 +0000
committerAndy Polyakov <appro@openssl.org>2012-06-11 14:56:25 +0000
commit447e1319b12d613e697a379bcd585179549ba3d7 (patch)
tree146bb0f7b68d7752bb8b6d06d245b720a9101d05
parente77ec2ba6f385e4b9d63a6dc5eadc1dbb336a174 (diff)
downloadopenssl-447e1319b12d613e697a379bcd585179549ba3d7.tar.gz
bss_dgram.c: add BIO_CTRL_DGRAM_SET_DONT_FRAG.
PR: 2830 Submitted by: Robin Seggelmann
-rw-r--r--crypto/bio/bio.h1
-rw-r--r--crypto/bio/bss_dgram.c46
2 files changed, 46 insertions, 1 deletions
diff --git a/crypto/bio/bio.h b/crypto/bio/bio.h
index 05699ab212..d32bf7f7a2 100644
--- a/crypto/bio/bio.h
+++ b/crypto/bio/bio.h
@@ -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 */
diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c
index a5a5cc1255..0d3c1cf342 100644
--- a/crypto/bio/bss_dgram.c
+++ b/crypto/bio/bss_dgram.c
@@ -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;