summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/s_client.c10
-rw-r--r--apps/s_server.c13
-rw-r--r--crypto/bio/bss_dgram.c93
-rw-r--r--ssl/dtls1.h2
4 files changed, 89 insertions, 29 deletions
diff --git a/apps/s_client.c b/apps/s_client.c
index 4974f5fc93..e0a5de7fb4 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -226,7 +226,7 @@ static void sc_usage(void)
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");
@@ -338,7 +338,7 @@ int MAIN(int argc, char **argv)
struct sockaddr peer;
int peerlen = sizeof(peer);
int enable_timeouts = 0 ;
- long mtu = 0;
+ long socket_mtu = 0;
#ifndef OPENSSL_NO_JPAKE
char *jpake_secret = NULL;
#endif
@@ -489,7 +489,7 @@ int MAIN(int argc, char **argv)
else if (strcmp(*argv,"-mtu") == 0)
{
if (--argc < 1) goto bad;
- mtu = atol(*(++argv));
+ socket_mtu = atol(*(++argv));
}
#endif
else if (strcmp(*argv,"-bugs") == 0)
@@ -843,10 +843,10 @@ re_start:
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
}
- if ( mtu > 0)
+ if ( socket_mtu > 28)
{
SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
- SSL_set_mtu(con, mtu);
+ SSL_set_mtu(con, socket_mtu - 28);
}
else
/* want to do MTU discovery */
diff --git a/apps/s_server.c b/apps/s_server.c
index 84b1b28461..dd822de04d 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -283,10 +283,7 @@ static char *engine_id=NULL;
static const char *session_id_prefix=NULL;
static int enable_timeouts = 0;
-#ifdef mtu
-#undef mtu
-#endif
-static long mtu;
+static long socket_mtu;
static int cert_chain = 0;
@@ -375,7 +372,7 @@ static void sv_usage(void)
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");
@@ -1032,7 +1029,7 @@ int MAIN(int argc, char *argv[])
else if (strcmp(*argv,"-mtu") == 0)
{
if (--argc < 1) goto bad;
- mtu = atol(*(++argv));
+ socket_mtu = atol(*(++argv));
}
else if (strcmp(*argv, "-chain") == 0)
cert_chain = 1;
@@ -1660,10 +1657,10 @@ static int sv_body(char *hostname, int s, unsigned char *context)
}
- if ( mtu > 0)
+ if ( socket_mtu > 28)
{
SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
- SSL_set_mtu(con, mtu);
+ SSL_set_mtu(con, socket_mtu - 28);
}
else
/* want to do MTU discovery */
diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c
index 3d08102ea3..3f568da142 100644
--- a/crypto/bio/bss_dgram.c
+++ b/crypto/bio/bss_dgram.c
@@ -338,6 +338,10 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
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;
@@ -396,24 +400,83 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
#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:
-#ifdef IP_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 - 20 - 8; /* Subtract IP and UDP header */
- 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;
@@ -423,8 +486,8 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
return data->mtu;
break;
case BIO_CTRL_DGRAM_SET_MTU:
- data->mtu = num - 20 - 8; /* Subtract IP and UDP header */
- ret = data->mtu;
+ data->mtu = num;
+ ret = num;
break;
case BIO_CTRL_DGRAM_SET_CONNECTED:
to = (struct sockaddr *)ptr;
diff --git a/ssl/dtls1.h b/ssl/dtls1.h
index b9273c558f..189acedfab 100644
--- a/ssl/dtls1.h
+++ b/ssl/dtls1.h
@@ -202,7 +202,7 @@ typedef struct dtls1_state_st
*/
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;