summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/bio/bio.h4
-rw-r--r--crypto/bio/bss_dgram.c46
2 files changed, 46 insertions, 4 deletions
diff --git a/crypto/bio/bio.h b/crypto/bio/bio.h
index 05699ab212..32eba71480 100644
--- a/crypto/bio/bio.h
+++ b/crypto/bio/bio.h
@@ -175,6 +175,8 @@ extern "C" {
#define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45 /* Next DTLS handshake timeout to
* adjust socket timeouts */
+#define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD 49
+
#ifndef OPENSSL_NO_SCTP
/* SCTP stuff */
#define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE 50
@@ -607,6 +609,8 @@ int BIO_ctrl_reset_read_request(BIO *b);
(int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer)
#define BIO_dgram_set_peer(b,peer) \
(int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer)
+#define BIO_dgram_get_mtu_overhead(b) \
+ (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL)
/* These two aren't currently implemented */
/* int BIO_get_ex_num(BIO *bio); */
diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c
index 8cad5b41db..7bed08e9b4 100644
--- a/crypto/bio/bss_dgram.c
+++ b/crypto/bio/bss_dgram.c
@@ -454,6 +454,36 @@ static int dgram_write(BIO *b, const char *in, int inl)
return(ret);
}
+static long dgram_get_mtu_overhead(bio_dgram_data *data)
+ {
+ long ret;
+
+ switch (data->peer.sa.sa_family)
+ {
+ case AF_INET:
+ /* Assume this is UDP - 20 bytes for IP, 8 bytes for UDP */
+ ret = 28;
+ break;
+#if OPENSSL_USE_IPV6
+ case AF_INET6:
+#ifdef IN6_IS_ADDR_V4MAPPED
+ if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
+ /* Assume this is UDP - 20 bytes for IP, 8 bytes for UDP */
+ ret = 28;
+ else
+#endif
+ /* Assume this is UDP - 40 bytes for IP, 8 bytes for UDP */
+ ret = 48;
+ break;
+#endif
+ default:
+ /* We don't know. Go with the historical default */
+ ret = 28;
+ break;
+ }
+ return ret;
+ }
+
static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret=1;
@@ -630,23 +660,24 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
#endif
break;
case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
+ ret = -dgram_get_mtu_overhead(data);
switch (data->peer.sa.sa_family)
{
case AF_INET:
- ret = 576 - 20 - 8;
+ ret += 576;
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;
+ ret += 576;
else
#endif
- ret = 1280 - 40 - 8;
+ ret += 1280;
break;
#endif
default:
- ret = 576 - 20 - 8;
+ ret += 576;
break;
}
break;
@@ -847,6 +878,9 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = 0;
break;
#endif
+ case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
+ ret = dgram_get_mtu_overhead(data);
+ break;
default:
ret=0;
break;
@@ -1367,6 +1401,10 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
* Returns always 1.
*/
break;
+ case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
+ /* We allow transport protocol fragmentation so this is irrelevant */
+ ret = 0;
+ break;
case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
if (num > 0)
data->in_handshake = 1;