mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-25 16:05:43 +01:00
Implement PMTU auto-reduction in handshake
This commit is contained in:
parent
68ae351dbe
commit
b8eec192f6
@ -7,6 +7,9 @@ Features
|
|||||||
is controlled by the maximum fragment length as set locally or negotiated
|
is controlled by the maximum fragment length as set locally or negotiated
|
||||||
with the peer, as well as by a new per-connection MTU option, set using
|
with the peer, as well as by a new per-connection MTU option, set using
|
||||||
mbedtls_ssl_set_mtu().
|
mbedtls_ssl_set_mtu().
|
||||||
|
* Add support for auto-adjustment of MTU to a safe value during the
|
||||||
|
handshake when flights do not get through (RFC 6347, section 4.1.1.1,
|
||||||
|
last paragraph).
|
||||||
|
|
||||||
Bugfix
|
Bugfix
|
||||||
* Fixes an issue with MBEDTLS_CHACHAPOLY_C which would not compile if
|
* Fixes an issue with MBEDTLS_CHACHAPOLY_C which would not compile if
|
||||||
|
@ -307,6 +307,7 @@ struct mbedtls_ssl_handshake_params
|
|||||||
resending messages */
|
resending messages */
|
||||||
unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter
|
unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter
|
||||||
for resending messages */
|
for resending messages */
|
||||||
|
uint16_t mtu; /*!< Handshake mtu, used to fragment outoing messages */
|
||||||
#endif /* MBEDTLS_SSL_PROTO_DTLS */
|
#endif /* MBEDTLS_SSL_PROTO_DTLS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -108,6 +108,15 @@ static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl )
|
|||||||
if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max )
|
if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
/* Implement the final paragraph of RFC 6347 section 4.1.1.1
|
||||||
|
* in the following way: after the initial transmission and a first
|
||||||
|
* retransmission, back off to a temporary estimated MTU of 508 bytes.
|
||||||
|
* This value is guaranteed to be deliverable (if not guaranteed to be
|
||||||
|
* delivered) of any compliant IPv4 (and IPv6) network, and should work
|
||||||
|
* on most non-IP stacks too. */
|
||||||
|
if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min )
|
||||||
|
ssl->handshake->mtu = 508;
|
||||||
|
|
||||||
new_timeout = 2 * ssl->handshake->retransmit_timeout;
|
new_timeout = 2 * ssl->handshake->retransmit_timeout;
|
||||||
|
|
||||||
/* Avoid arithmetic overflow and range overflow */
|
/* Avoid arithmetic overflow and range overflow */
|
||||||
@ -7088,6 +7097,20 @@ size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
|
|||||||
}
|
}
|
||||||
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
|
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
||||||
|
static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl )
|
||||||
|
{
|
||||||
|
if( ssl->handshake == NULL || ssl->handshake->mtu == 0 )
|
||||||
|
return( ssl->mtu );
|
||||||
|
|
||||||
|
if( ssl->mtu == 0 )
|
||||||
|
return( ssl->handshake->mtu );
|
||||||
|
|
||||||
|
return( ssl->mtu < ssl->handshake->mtu ?
|
||||||
|
ssl->mtu : ssl->handshake->mtu );
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_SSL_PROTO_DTLS */
|
||||||
|
|
||||||
int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl )
|
int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl )
|
||||||
{
|
{
|
||||||
size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
|
size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
|
||||||
@ -7105,9 +7128,9 @@ int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl )
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
||||||
if( ssl->mtu != 0 )
|
if( ssl_get_current_mtu( ssl ) != 0 )
|
||||||
{
|
{
|
||||||
const size_t mtu = ssl->mtu;
|
const size_t mtu = ssl_get_current_mtu( ssl );
|
||||||
const int ret = mbedtls_ssl_get_record_expansion( ssl );
|
const int ret = mbedtls_ssl_get_record_expansion( ssl );
|
||||||
const size_t overhead = (size_t) ret;
|
const size_t overhead = (size_t) ret;
|
||||||
|
|
||||||
@ -7123,7 +7146,7 @@ int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl )
|
|||||||
if( max_len > mtu - overhead )
|
if( max_len > mtu - overhead )
|
||||||
max_len = mtu - overhead;
|
max_len = mtu - overhead;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* MBEDTLS_SSL_PROTO_DTLS */
|
||||||
|
|
||||||
return( (int) max_len );
|
return( (int) max_len );
|
||||||
}
|
}
|
||||||
|
@ -5111,6 +5111,25 @@ run_test "DTLS fragmenting: both (MTU)" \
|
|||||||
-c "found fragmented DTLS handshake message" \
|
-c "found fragmented DTLS handshake message" \
|
||||||
-C "error"
|
-C "error"
|
||||||
|
|
||||||
|
# Test for automatic MTU reduction on repeated resend
|
||||||
|
requires_config_enabled MBEDTLS_SSL_PROTO_DTLS
|
||||||
|
requires_config_enabled MBEDTLS_RSA_C
|
||||||
|
requires_config_enabled MBEDTLS_ECDSA_C
|
||||||
|
run_test "DTLS fragmenting: proxy MTU: auto-reduction" \
|
||||||
|
-p "$P_PXY mtu=508" \
|
||||||
|
"$P_SRV dtls=1 debug_level=2 auth_mode=required \
|
||||||
|
crt_file=data_files/server7_int-ca.crt \
|
||||||
|
key_file=data_files/server7.key\
|
||||||
|
hs_timeout=100-400" \
|
||||||
|
"$P_CLI dtls=1 debug_level=2 \
|
||||||
|
crt_file=data_files/server8_int-ca2.crt \
|
||||||
|
key_file=data_files/server8.key \
|
||||||
|
hs_timeout=100-400" \
|
||||||
|
0 \
|
||||||
|
-s "found fragmented DTLS handshake message" \
|
||||||
|
-c "found fragmented DTLS handshake message" \
|
||||||
|
-C "error"
|
||||||
|
|
||||||
# the proxy shouldn't drop or mess up anything, so we shouldn't need to resend
|
# the proxy shouldn't drop or mess up anything, so we shouldn't need to resend
|
||||||
# OTOH the client might resend if the server is to slow to reset after sending
|
# OTOH the client might resend if the server is to slow to reset after sending
|
||||||
# a HelloVerifyRequest, so only check for no retransmission server-side
|
# a HelloVerifyRequest, so only check for no retransmission server-side
|
||||||
|
Loading…
Reference in New Issue
Block a user