Skip to content

Commit 4b7a2b6

Browse files
committed
wolfSSL_shutdown: fix non-blocking retry after WANT_WRITE.
1. Send buffered message in case SendAlert_ex returned WANT_WRITE. 2. If pending messages are sent successfully return SHUTDOWN_NOT_DONE as current API behavior. 3. Propagate WANT_READ error for ProcessReply if waiting for other peer shutdown (when invoking wolfSSL_shutdown for the second time)
1 parent 6b0e24e commit 4b7a2b6

2 files changed

Lines changed: 50 additions & 19 deletions

File tree

src/internal.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26502,20 +26502,6 @@ static int SendAlert_ex(WOLFSSL* ssl, int severity, int type)
2650226502
}
2650326503
#endif
2650426504

26505-
/*
26506-
* We check if we are trying to send a
26507-
* CLOSE_NOTIFY alert.
26508-
* */
26509-
if (type == close_notify) {
26510-
if (!ssl->options.sentNotify) {
26511-
ssl->options.sentNotify = 1;
26512-
}
26513-
else {
26514-
/* CLOSE_NOTIFY already sent */
26515-
return 0;
26516-
}
26517-
}
26518-
2651926505
ssl->buffers.outputBuffer.length += (word32)sendSz;
2652026506

2652126507
ret = SendBuffered(ssl);

src/ssl.c

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4478,15 +4478,53 @@ int wolfSSL_shutdown(WOLFSSL* ssl)
44784478
ret = WOLFSSL_SUCCESS;
44794479
}
44804480
else {
4481+
4482+
/* Try to flush the buffer first, it might contain the alert */
4483+
if (ssl->error == WC_NO_ERR_TRACE(WANT_WRITE) &&
4484+
ssl->buffers.outputBuffer.length > 0) {
4485+
ret = SendBuffered(ssl);
4486+
if (ret != 0) {
4487+
ssl->error = ret;
4488+
/* for error tracing */
4489+
if (ret != WC_NO_ERR_TRACE(WANT_WRITE))
4490+
WOLFSSL_ERROR(ret);
4491+
ret = WOLFSSL_FATAL_ERROR;
4492+
WOLFSSL_LEAVE("wolfSSL_shutdown", ret);
4493+
return ret;
4494+
}
4495+
4496+
ssl->error = WOLFSSL_ERROR_NONE;
4497+
/* we succeeded in sending the alert now */
4498+
if (ssl->options.sentNotify) {
4499+
/* just after we send the alert, if we didn't receive the alert
4500+
* from the other peer yet, return WOLFSSL_STHUDOWN_NOT_DONE */
4501+
if (!ssl->options.closeNotify) {
4502+
ret = WOLFSSL_SHUTDOWN_NOT_DONE;
4503+
WOLFSSL_LEAVE("wolfSSL_shutdown", ret);
4504+
return ret;
4505+
}
4506+
else {
4507+
ssl->options.shutdownDone = 1;
4508+
ret = WOLFSSL_SUCCESS;
4509+
}
4510+
}
4511+
}
4512+
44814513
/* try to send close notify, not an error if can't */
44824514
if (!ssl->options.isClosed && !ssl->options.connReset &&
44834515
!ssl->options.sentNotify) {
44844516
ssl->error = SendAlert(ssl, alert_warning, close_notify);
4517+
4518+
/* the alert is now sent or sitting in the buffer,
4519+
* where will be sent eventually */
4520+
if (ssl->error == 0 || ssl->error == WC_NO_ERR_TRACE(WANT_WRITE))
4521+
ssl->options.sentNotify = 1;
4522+
44854523
if (ssl->error < 0) {
44864524
WOLFSSL_ERROR(ssl->error);
44874525
return WOLFSSL_FATAL_ERROR;
44884526
}
4489-
ssl->options.sentNotify = 1; /* don't send close_notify twice */
4527+
44904528
if (ssl->options.closeNotify) {
44914529
ret = WOLFSSL_SUCCESS;
44924530
ssl->options.shutdownDone = 1;
@@ -4506,7 +4544,7 @@ int wolfSSL_shutdown(WOLFSSL* ssl)
45064544
}
45074545
#endif
45084546

4509-
/* call wolfSSL_shutdown again for bidirectional shutdown */
4547+
/* wolfSSL_shutdown called again for bidirectional shutdown */
45104548
if (ssl->options.sentNotify && !ssl->options.closeNotify) {
45114549
ret = ProcessReply(ssl);
45124550
if ((ret == WC_NO_ERR_TRACE(ZERO_RETURN)) ||
@@ -4516,11 +4554,18 @@ int wolfSSL_shutdown(WOLFSSL* ssl)
45164554
/* Clear error */
45174555
ssl->error = WOLFSSL_ERROR_NONE;
45184556
ret = WOLFSSL_SUCCESS;
4519-
} else if (ret == WC_NO_ERR_TRACE(MEMORY_E)) {
4557+
}
4558+
else if (ret == WC_NO_ERR_TRACE(MEMORY_E)) {
45204559
ret = WOLFSSL_FATAL_ERROR;
4521-
} else if (ssl->error == WOLFSSL_ERROR_NONE) {
4560+
}
4561+
else if (ret == WC_NO_ERR_TRACE(WANT_READ)) {
4562+
ssl->error = ret;
4563+
ret = WOLFSSL_FATAL_ERROR;
4564+
}
4565+
else if (ssl->error == WOLFSSL_ERROR_NONE) {
45224566
ret = WOLFSSL_SHUTDOWN_NOT_DONE;
4523-
} else {
4567+
}
4568+
else {
45244569
WOLFSSL_ERROR(ssl->error);
45254570
ret = WOLFSSL_FATAL_ERROR;
45264571
}

0 commit comments

Comments
 (0)