Merge pull request #3050 from mpg/skip-close-notify-dev

Fix possible close_notify/ClientHello confusion
This commit is contained in:
Manuel Pégourié-Gonnard 2020-03-03 12:11:48 +01:00 committed by GitHub
commit f03c13c046
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 23 deletions

View file

@ -145,6 +145,7 @@ int main( void )
#define DFL_REPRODUCIBLE 0
#define DFL_NSS_KEYLOG 0
#define DFL_NSS_KEYLOG_FILE NULL
#define DFL_SKIP_CLOSE_NOTIFY 0
#define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
#define GET_REQUEST_END "\r\n\r\n"
@ -389,6 +390,7 @@ int main( void )
" options: 1 (level-triggered, implies nbio=1),\n" \
" read_timeout=%%d default: 0 ms (no timeout)\n" \
" max_resend=%%d default: 0 (no resend on timeout)\n" \
" skip_close_notify=%%d default: 0 (send close_notify)\n" \
"\n" \
USAGE_DTLS \
USAGE_CID \
@ -517,6 +519,7 @@ struct options
const char *cid_val_renego; /* the CID to use for incoming messages
* after renegotiation */
int reproducible; /* make communication reproducible */
int skip_close_notify; /* skip sending the close_notify alert */
} opt;
int query_config( const char *config );
@ -1311,6 +1314,7 @@ int main( int argc, char *argv[] )
opt.reproducible = DFL_REPRODUCIBLE;
opt.nss_keylog = DFL_NSS_KEYLOG;
opt.nss_keylog_file = DFL_NSS_KEYLOG_FILE;
opt.skip_close_notify = DFL_SKIP_CLOSE_NOTIFY;
for( i = 1; i < argc; i++ )
{
@ -1723,6 +1727,12 @@ int main( int argc, char *argv[] )
{
opt.nss_keylog_file = q;
}
else if( strcmp( p, "skip_close_notify" ) == 0 )
{
opt.skip_close_notify = atoi( q );
if( opt.skip_close_notify < 0 || opt.skip_close_notify > 1 )
goto usage;
}
else
goto usage;
}
@ -3160,10 +3170,25 @@ close_notify:
mbedtls_printf( " . Closing the connection..." );
fflush( stdout );
/* No error checking, the connection might be closed already */
do ret = mbedtls_ssl_close_notify( &ssl );
while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );
ret = 0;
/*
* Most of the time sending a close_notify before closing is the right
* thing to do. However, when the server already knows how many messages
* are expected and closes the connection by itself, this alert becomes
* redundant. Sometimes with DTLS this redundancy becomes a problem by
* leading to a race condition where the server might close the connection
* before seeing the alert, and since UDP is connection-less when the
* alert arrives it will be seen as a new connection, which will fail as
* the alert is clearly not a valid ClientHello. This may cause spurious
* failures in tests that use DTLS and resumption with ssl_server2 in
* ssl-opt.sh, avoided by enabling skip_close_notify client-side.
*/
if( opt.skip_close_notify == 0 )
{
/* No error checking, the connection might be closed already */
do ret = mbedtls_ssl_close_notify( &ssl );
while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );
ret = 0;
}
mbedtls_printf( " done\n" );