Skip to content

Commit bcbb544

Browse files
authored
Merge pull request #7881 from gasbytes/eagain-proper-shutdown
Properly handling the shutdown when multiple ones go on EAGAIN back to back
2 parents c454a42 + 8a6d7ff commit bcbb544

2 files changed

Lines changed: 99 additions & 2 deletions

File tree

src/internal.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
2020
*/
2121

22-
23-
2422
#ifdef HAVE_CONFIG_H
2523
#include <config.h>
2624
#endif
@@ -25063,6 +25061,20 @@ static int SendAlert_ex(WOLFSSL* ssl, int severity, int type)
2506325061
}
2506425062
#endif
2506525063

25064+
/*
25065+
* We check if we are trying to send a
25066+
* CLOSE_NOTIFY alert.
25067+
* */
25068+
if (type == close_notify) {
25069+
if (!ssl->options.sentNotify) {
25070+
ssl->options.sentNotify = 1;
25071+
}
25072+
else {
25073+
/* CLOSE_NOTIFY already sent */
25074+
return 0;
25075+
}
25076+
}
25077+
2506625078
ssl->buffers.outputBuffer.length += sendSz;
2506725079

2506825080
ret = SendBuffered(ssl);

tests/api.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81189,6 +81189,90 @@ static int test_extra_alerts_bad_psk(void)
8118981189
}
8119081190
#endif
8119181191

81192+
#if defined(OPENSSL_EXTRA) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12)
81193+
/*
81194+
* Emulates wolfSSL_shutdown that goes on EAGAIN,
81195+
* by returning on output WOLFSSL_ERROR_WANT_WRITE.*/
81196+
static int custom_wolfSSL_shutdown(WOLFSSL *ssl, char *buf,
81197+
int sz, void *ctx)
81198+
{
81199+
(void)ssl;
81200+
(void)buf;
81201+
(void)ctx;
81202+
(void)sz;
81203+
81204+
return WOLFSSL_CBIO_ERR_WANT_WRITE;
81205+
}
81206+
81207+
static int test_multiple_alerts_EAGAIN(void)
81208+
{
81209+
EXPECT_DECLS;
81210+
size_t size_of_last_packet = 0;
81211+
81212+
/* declare wolfSSL objects */
81213+
struct test_memio_ctx test_ctx;
81214+
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
81215+
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
81216+
81217+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
81218+
81219+
/* Create and initialize WOLFSSL_CTX and WOLFSSL objects */
81220+
#ifdef USE_TLSV13
81221+
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
81222+
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
81223+
#else
81224+
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
81225+
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
81226+
#endif
81227+
ExpectNotNull(ctx_c);
81228+
ExpectNotNull(ssl_c);
81229+
ExpectNotNull(ctx_s);
81230+
ExpectNotNull(ssl_s);
81231+
81232+
/* Load client certificates into WOLFSSL_CTX */
81233+
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx_c, "./certs/ca-cert.pem", NULL), WOLFSSL_SUCCESS);
81234+
81235+
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
81236+
81237+
/*
81238+
* We set the custom callback for the IO to emulate multiple EAGAINs
81239+
* on shutdown, so we can check that we don't send multiple packets.
81240+
* */
81241+
wolfSSL_SSLSetIOSend(ssl_c, custom_wolfSSL_shutdown);
81242+
81243+
/*
81244+
* We call wolfSSL_shutdown multiple times to reproduce the behaviour,
81245+
* to check that it doesn't add the CLOSE_NOTIFY packet multiple times
81246+
* on the output buffer.
81247+
* */
81248+
wolfSSL_shutdown(ssl_c);
81249+
wolfSSL_shutdown(ssl_c);
81250+
81251+
if (ssl_c != NULL) {
81252+
size_of_last_packet = ssl_c->buffers.outputBuffer.length;
81253+
}
81254+
wolfSSL_shutdown(ssl_c);
81255+
81256+
/*
81257+
* Finally we check the length of the output buffer.
81258+
* */
81259+
ExpectIntEQ((ssl_c->buffers.outputBuffer.length - size_of_last_packet), 0);
81260+
81261+
/* Cleanup and return */
81262+
wolfSSL_CTX_free(ctx_c);
81263+
wolfSSL_free(ssl_c);
81264+
wolfSSL_CTX_free(ctx_s);
81265+
wolfSSL_free(ssl_s);
81266+
81267+
return EXPECT_RESULT();
81268+
}
81269+
#else
81270+
static int test_multiple_alerts_EAGAIN(void)
81271+
{
81272+
return TEST_SKIPPED;
81273+
}
81274+
#endif
81275+
8119281276
#if defined(WOLFSSL_TLS13) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)\
8119381277
&& !defined(NO_PSK)
8119481278
static unsigned int test_tls13_bad_psk_binder_client_cb(WOLFSSL* ssl,
@@ -86705,6 +86789,7 @@ TEST_CASE testCases[] = {
8670586789
TEST_DECL(test_extra_alerts_wrong_cs),
8670686790
TEST_DECL(test_extra_alerts_skip_hs),
8670786791
TEST_DECL(test_extra_alerts_bad_psk),
86792+
TEST_DECL(test_multiple_alerts_EAGAIN),
8670886793
TEST_DECL(test_tls13_bad_psk_binder),
8670986794
/* Can't memory test as client/server Asserts. */
8671086795
TEST_DECL(test_harden_no_secure_renegotiation),

0 commit comments

Comments
 (0)