From d9501ae8e35871c78990d2066dec2b3dced38f8c Mon Sep 17 00:00:00 2001 From: "shoney.arickathil" Date: Wed, 9 Sep 2026 16:08:57 +0200 Subject: [PATCH] fix(tls): send close_notify on TLS close (rv2 9 follow-up) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit net.close on a TLS connection now seals a close_notify alert (warning, close_notify; RFC 8446 §6.1) with the application write keys and sends it best-effort/non-blocking before the inbound drain + close(). Peers see a clean end of stream instead of truncation — openssl's "unexpected eof while reading" is gone (verified), browsers stop treating the reply as aborted. Covers both directions (one code path). just tls 5/0, just tls-server 4/0. Co-Authored-By: Claude Opus 4.8 (cherry picked from commit 54020a45fdb1efab792212170b8f36c2d38d95be) --- runtime/src/sysio.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/runtime/src/sysio.c b/runtime/src/sysio.c index 669430e..527b005 100644 --- a/runtime/src/sysio.c +++ b/runtime/src/sysio.c @@ -1029,7 +1029,17 @@ int wo_builtin_sys(wo_vm *vm, uint64_t *R, uint32_t ins, const char **msg) { } case WO_B_NET_CLOSE: { int cfd = (int)R[B]; - if (tls_find(vm, cfd)) { + wo_tls_conn *tc = tls_find(vm, cfd); + if (tc) { + /* Graceful TLS shutdown (RFC 8446 §6.1): send a close_notify alert + * — level warning(1), description close_notify(0) — sealed with the + * application write keys, best-effort and non-blocking. A peer that + * gets it treats the end of stream as clean rather than truncated + * (openssl's "unexpected eof", browsers' aborted-response heuristics). */ + uint8_t alert[2] = { 0x01, 0x00 }, arec[64]; + int an = wo_tls_record_seal(tc->suite, tc->wr_key, tc->keylen, tc->wr_iv, + tc->wr_seq, WO_TLS_CT_ALERT, alert, 2, arec); + if (an > 0) { tc->wr_seq++; (void)send(cfd, arec, (size_t)an, MSG_NOSIGNAL | MSG_DONTWAIT); } /* Drain any unread inbound (typically the peer's close_notify) so * close() sends FIN, not RST — otherwise the RST discards the * response we just wrote (openssl and browsers send close_notify). */