diff --git a/examples/client/client.c b/examples/client/client.c index 82cf47452..f0e839317 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -783,8 +783,16 @@ static int SMTP_Shutdown(WOLFSSL* ssl, int wc_shutdown) printf("%s\n", tmpBuf); ret = wolfSSL_shutdown(ssl); - if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) - wolfSSL_shutdown(ssl); /* bidirectional shutdown */ + if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) { + if (tcp_select(wolfSSL_get_fd(ssl), DEFAULT_TIMEOUT_SEC) == + TEST_RECV_READY) { + ret = wolfSSL_shutdown(ssl); /* bidirectional shutdown */ + if (ret == WOLFSSL_SUCCESS) + printf("Bidirectional shutdown complete\n"); + } + if (ret != WOLFSSL_SUCCESS) + printf("Bidirectional shutdown failed\n"); + } return WOLFSSL_SUCCESS; } @@ -3110,8 +3118,15 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (dtlsUDP == 0) { /* don't send alert after "break" command */ ret = wolfSSL_shutdown(ssl); - if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) - wolfSSL_shutdown(ssl); /* bidirectional shutdown */ + if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) { + if (tcp_select(sockfd, DEFAULT_TIMEOUT_SEC) == TEST_RECV_READY) { + ret = wolfSSL_shutdown(ssl); /* bidirectional shutdown */ + if (ret == WOLFSSL_SUCCESS) + printf("Bidirectional shutdown complete\n"); + } + if (ret != WOLFSSL_SUCCESS) + printf("Bidirectional shutdown failed\n"); + } } #if defined(ATOMIC_USER) && !defined(WOLFSSL_AEAD_ONLY) if (atomicUser) diff --git a/examples/server/server.c b/examples/server/server.c index 12d312cc1..c4fe52a5e 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -51,6 +51,8 @@ static int devId = INVALID_DEVID; #endif +#define DEFAULT_TIMEOUT_SEC 2 + /* Note on using port 0: if the server uses port 0 to bind an ephemeral port * number and is using the ready file for scripted testing, the code in * test.h will write the actual port number into the ready file for use @@ -2427,9 +2429,13 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) if (dtlsUDP == 0) { ret = SSL_shutdown(ssl); - if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) - SSL_shutdown(ssl); /* bidirectional shutdown */ + if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) { + ret = SSL_shutdown(ssl); /* bidirectional shutdown */ + if (ret == WOLFSSL_SUCCESS) + printf("Bidirectional shutdown complete\n"); + } } + /* display collected statistics */ #ifdef WOLFSSL_STATIC_MEMORY if (wolfSSL_is_static_memory(ssl, &ssl_stats) != 1) diff --git a/src/ssl.c b/src/ssl.c index 846e8bd20..d5a37bc6f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2973,7 +2973,6 @@ WOLFSSL_ABI int wolfSSL_shutdown(WOLFSSL* ssl) { int ret = WOLFSSL_FATAL_ERROR; - byte tmp; WOLFSSL_ENTER("SSL_shutdown()"); if (ssl == NULL) @@ -3012,16 +3011,16 @@ int wolfSSL_shutdown(WOLFSSL* ssl) /* call wolfSSL_shutdown again for bidirectional shutdown */ if (ssl->options.sentNotify && !ssl->options.closeNotify) { - ret = wolfSSL_read(ssl, &tmp, 0); - if (ret < 0) { + ret = ProcessReply(ssl); + if (ret == ZERO_RETURN) { + /* simulate OpenSSL behavior */ + ssl->error = WOLFSSL_ERROR_SYSCALL; + ret = WOLFSSL_SUCCESS; + } else if (ssl->error == WOLFSSL_ERROR_NONE) { + ret = WOLFSSL_SHUTDOWN_NOT_DONE; + } else { WOLFSSL_ERROR(ssl->error); ret = WOLFSSL_FATAL_ERROR; - } else if (ssl->options.closeNotify) { - ssl->error = WOLFSSL_ERROR_SYSCALL; /* simulate OpenSSL behavior */ - ret = WOLFSSL_SUCCESS; - } else if ((ssl->error == WOLFSSL_ERROR_NONE) && - (ret < WOLFSSL_SUCCESS)) { - ret = WOLFSSL_SHUTDOWN_NOT_DONE; } } } diff --git a/tests/test.conf b/tests/test.conf index 0fe6464a3..83c228bc3 100644 --- a/tests/test.conf +++ b/tests/test.conf @@ -2200,3 +2200,9 @@ -v 3 -l ECDHE-RSA-AES128-SHA256 -U + +# server with bidirectional shutdown +-w + +# client with bidirectional shutdown +-w