Move MTU setting to SSL context, not config
This setting belongs to the individual connection, not to a configuration
shared by many connections. (If a default value is desired, that can be handled
by the application code that calls mbedtls_ssl_set_mtu().)
There are at least two ways in which this matters:
- per-connection settings can be adjusted if MTU estimates become available
during the lifetime of the connection
- it is at least conceivable that a server might recognize restricted clients
based on range of IPs and immediately set a lower MTU for them. This is much
easier to do with a per-connection setting than by maintaining multiple
near-duplicated ssl_config objects that differ only by the MTU setting.
diff --git a/ChangeLog b/ChangeLog
index bab69f6..a95cc6c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,7 +3,10 @@
= mbed TLS x.x.x branch released xxxx-xx-xx
Features
- * Add support for fragmentation of outoing DTLS handshake messages.
+ * Add support for fragmentation of outgoing DTLS handshake messages. This
+ is controlled by the maximum fragment length as set locally or negotiated
+ with the peer, as well as new per-connection MTU option, set using
+ mbedtls_ssl_set_mtu().
Bugfix
* Fixes an issue with MBEDTLS_CHACHAPOLY_C which would not compile if
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index a3b514c..69a2e86 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -958,10 +958,6 @@
unsigned int dhm_min_bitlen; /*!< min. bit length of the DHM prime */
#endif
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- uint16_t mtu; /*!< path mtu, used to fragment outoing messages */
-#endif
-
unsigned char max_major_ver; /*!< max. major version used */
unsigned char max_minor_ver; /*!< max. minor version used */
unsigned char min_major_ver; /*!< min. major version used */
@@ -1116,6 +1112,10 @@
size_t out_msglen; /*!< record header: message length */
size_t out_left; /*!< amount of data not yet written */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ uint16_t mtu; /*!< path mtu, used to fragment outoing messages */
+#endif
+
#if defined(MBEDTLS_ZLIB_SUPPORT)
unsigned char *compress_buf; /*!< zlib data buffer */
#endif
@@ -1378,6 +1378,39 @@
mbedtls_ssl_recv_t *f_recv,
mbedtls_ssl_recv_timeout_t *f_recv_timeout );
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+/**
+ * \brief Set the Maximum Tranport Unit (MTU).
+ * Special value: 0 means unset (no limit).
+ * This represents the maximum size of a datagram payload
+ * handled by the transport layer (usually UDP) as determined
+ * by the network link and stack. In practice, this controls
+ * the maximum size datagram the DTLS layer will pass to the
+ * \c f_send() callback set using \c mbedtls_ssl_set_bio().
+ *
+ * \note This can be called at any point during the connection, for
+ * example when a PMTU estimate becomes available from other
+ * sources, such as lower (or higher) protocol layers.
+ *
+ * \note This only controls the size of the packet we send.
+ * Client-side, you can request the server to use smaller
+ * records with \c mbedtls_conf_max_frag_len().
+ *
+ * \note If both a MTU and a maximum fragment length have been
+ * configured (or negotiated with the peer), the lower limit
+ * is used.
+ *
+ * \note Values larger than \c MBEDTLS_SSL_OUT_CONTENT_LEN have no
+ * effect. This can only be used to decrease the maximum size
+ * of datagrams sent. Values lower than record layer expansion
+ * are ignored.
+ *
+ * \param ssl SSL context
+ * \param mtu Value of the path MTU in bytes
+ */
+void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu );
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
/**
* \brief Set the timeout period for mbedtls_ssl_read()
* (Default: no timeout.)
@@ -2427,35 +2460,6 @@
char cert_req_ca_list );
#endif /* MBEDTLS_SSL_SRV_C */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-/**
- * \brief Set the Maximum Tranport Unit (MTU).
- * Special value: 0 means unset (no limit).
- * This represents the maximum size of a datagram payload
- * handled by the transport layer (usually UDP) as determined
- * by the network link and stack. In practice, this controls
- * the maximum size datagram the DTLS layer will pass to the
- * \c f_send() callback set using \c mbedtls_ssl_set_bio().
- *
- * \note This only controls the size of the packet we send.
- * Client-side, you can request the server to use smaller
- * records with \c mbedtls_conf_max_frag_len().
- *
- * \note If both a MTU and a maximum fragment length have been
- * configured (or negotiated with the peer), the lower limit
- * is used.
- *
- * \note Values larger than \c MBEDTLS_SSL_OUT_CONTENT_LEN have no
- * effect. This can only be used to decrease the maximum size
- * of datagrams sent. Values lower than record layer expansion
- * are ignored.
- *
- * \param conf SSL configuration
- * \param mtu Value of the path MTU in bytes
- */
-void mbedtls_ssl_conf_mtu( mbedtls_ssl_config *conf, uint16_t mtu );
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
/**
* \brief Set the maximum fragment length to emit and/or negotiate
@@ -2476,7 +2480,7 @@
*
* \note For DTLS, it is also possible to set a limit for the total
* size of daragrams passed to the transport layer, including
- * record overhead, see \c mbedtls_ssl_conf_mtu().
+ * record overhead, see \c mbedtls_ssl_set_mtu().
*
* \param conf SSL configuration
* \param mfl_code Code for maximum fragment length (allowed values:
@@ -2784,7 +2788,7 @@
* \note This function is not available (always returns an error)
* when record compression is enabled.
*
- * \sa mbedtls_ssl_conf_mtu()
+ * \sa mbedtls_ssl_set_mtu()
* \sa mbedtls_ssl_get_max_frag_len()
* \sa mbedtls_ssl_get_record_expansion()
*
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 530f283..7f85ddf 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -6270,6 +6270,13 @@
ssl->f_recv_timeout = f_recv_timeout;
}
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu )
+{
+ ssl->mtu = mtu;
+}
+#endif
+
void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout )
{
conf->read_timeout = timeout;
@@ -6758,13 +6765,6 @@
}
#endif
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-void mbedtls_ssl_conf_mtu( mbedtls_ssl_config *conf, uint16_t mtu )
-{
- conf->mtu = mtu;
-}
-#endif
-
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code )
{
@@ -7101,9 +7101,9 @@
#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->mtu != 0 )
+ if( ssl->mtu != 0 )
{
- const size_t mtu = ssl->conf->mtu;
+ const size_t mtu = ssl->mtu;
const int ret = mbedtls_ssl_get_record_expansion( ssl );
const size_t overhead = (size_t) ret;
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 7cdc53a..e4a7412 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -1337,10 +1337,7 @@
if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX )
mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min,
opt.hs_to_max );
-
- if( opt.dtls_mtu != DFL_DTLS_MTU )
- mbedtls_ssl_conf_mtu( &conf, opt.dtls_mtu );
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#endif
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
if( ( ret = mbedtls_ssl_conf_max_frag_len( &conf, opt.mfl_code ) ) != 0 )
@@ -1498,6 +1495,11 @@
mbedtls_net_send, mbedtls_net_recv,
opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( opt.dtls_mtu != DFL_DTLS_MTU )
+ mbedtls_ssl_set_mtu( &ssl, opt.dtls_mtu );
+#endif
+
#if defined(MBEDTLS_TIMING_C)
mbedtls_ssl_set_timer_cb( &ssl, &timer, mbedtls_timing_set_delay,
mbedtls_timing_get_delay );
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 484f84f..71ec85b 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -2165,9 +2165,6 @@
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX )
mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min, opt.hs_to_max );
-
- if( opt.dtls_mtu != DFL_DTLS_MTU )
- mbedtls_ssl_conf_mtu( &conf, opt.dtls_mtu );
#endif /* MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
@@ -2486,6 +2483,11 @@
mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv,
opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( opt.dtls_mtu != DFL_DTLS_MTU )
+ mbedtls_ssl_set_mtu( &ssl, opt.dtls_mtu );
+#endif
+
#if defined(MBEDTLS_TIMING_C)
mbedtls_ssl_set_timer_cb( &ssl, &timer, mbedtls_timing_set_delay,
mbedtls_timing_get_delay );