Skip to content

test: cover terminate() on a TLS socket sending a bare RST - #40040

Open
robobun wants to merge 1 commit into
mainfrom
farm/e7dcd7cc/tls-terminate-reset-test
Open

test: cover terminate() on a TLS socket sending a bare RST#40040
robobun wants to merge 1 commit into
mainfrom
farm/e7dcd7cc/tls-terminate-reset-test

Conversation

@robobun

@robobun robobun commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

Problem

Fix

  • test/js/bun/net/socket.test.ts: the in-process terminate() case in "close() error after the peer resets the connection" now runs for tls as well as tcp. The accepted TLS socket calls terminate(), and the connected peer must get close(socket, error) with read ECONNRESET.
  • Before tls: send a bare RST from terminate(), no close_notify #39632 the peer got a clean close: the close_notify queued ahead of the RST was consumed as an end of stream. The comment that said an in-process TLS terminate() is not usable here was stale and is removed.
  • Verified: a debug build of main with only the LIBUS_SOCKET_CLOSE_CODE_CONNECTION_RESET check at packages/bun-usockets/src/crypto/openssl.c:1960 reverted fails the tls case (reported: false, no code). The same build with the line restored passes 5 of 5 runs. Also bun test with bun 1.3.13 fails 20 of 20, and the 1.4.0 canary passes 20 of 20.

Background

  • terminate() closes with code 1 (CloseCode::failure): SO_LINGER{1,0} so the kernel sends an RST. For TLS, us_internal_ssl_close used to run SSL_shutdown first for every non-zero code, which wrote a close_notify alert before the RST.
  • A peer that reads a close_notify gets SSL_ERROR_ZERO_RETURN and closes cleanly. Only a bare RST reaches it as a read error, which is what node's resetAndDestroy() produces.
Notes

no test proof · iteration 0 · platform-specific test(s) that do not run on this machine, deferring to CI, which covers all platforms: test/js/bun/net/socket.test.ts

Run the in-process terminate() case of "close() error after the peer
resets the connection" for tls as well as tcp. A TLS terminate() sends
no close_notify since #39632, so the reading peer gets read ECONNRESET
and not a clean close. Before that change the tls case fails: the peer
consumes the close_notify queued ahead of the RST as a clean end.
@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Your included review limit has been reached.

You’re in a promotional period — use the checkbox below to run this review for free:

  • Run review for free

On-demand reviews are free for the next 30 days. After that, they cost $0.25 per reviewed file.

How can I continue?

Run this review now using the option above, or comment @coderabbitai review --use-credits.

You can also wait for the limit to reset (next review available in 9 minutes), then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ade1491c-b2ba-43d1-9352-6e9a004c90e5

📥 Commits

Reviewing files that changed from the base of the PR and between 85ed30a and 8971d7c.

📒 Files selected for processing (1)
  • test/js/bun/net/socket.test.ts

Comment @coderabbitai help to get the list of available commands.

@robobun

robobun commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator Author

Adopted from #40006 at the request of @Jarred-Sumner. Test-only PR: the fix it proves is already on main (#39632).

Reproduced: with packages/bun-usockets/src/crypto/openssl.c:1960 reverted on a debug build of main, the new tls case fails with { reported: false, code: undefined } (clean close) instead of read ECONNRESET. With the line restored it passes 5 of 5 runs. Bun 1.3.13 fails it 20 of 20, the 1.4.0 canary passes 20 of 20.

CI (build 103178): socket.test.ts passed on every lane. The one red test, bun-audit.test.ts, fails on main too (its snapshot contains the version range <1.4.1, which the normalizer now rewrites as the bun version). The other four failures passed on retry. Ready for a maintainer.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — test-only change that extends the existing in-process terminate() reset test to run under TLS as well as TCP.

What was reviewed:

  • The test now sits inside the describe.each(["tcp", "tls"]) block and mirrors the sibling child-process test's tls setup (open vs handshake gating, { ca: tls.cert } on connect) — patterns match line for line.
  • Failure paths are wired to reject: connectError, the new error handler, and handshake failure all reject the awaited promises, so a regression fails rather than hangs.
  • No sleeps, port: 0, using listener, and the assertion (closeErrorShapereadReset) is unchanged from the tcp-only version.
Extended reasoning...

Overview

This PR moves the "a connected socket reports the reset the same way" test from outside the describe.each(["tcp", "tls"]) block into it, so the in-process terminate() case now runs for TLS in addition to plain TCP. The only additions beyond the move are the tls-conditional tls: options on both listen and connect, a handshake handler that mirrors the sibling test's, and an error handler on the client that rejects the greeted resolver. The stale comment claiming an in-process TLS terminate() was unusable is replaced. There are no src/ or packages/ changes — the fix (#39632) is already on main; this PR supplies the missing regression test for it.

Security risks

None. Test-only change touching a socket test file. No new fixtures, no external network, no credentials, no changes to TLS validation logic — the test uses the harness tls cert already in use by the neighboring test.

Level of scrutiny

Low. This is a coverage addition for behavior already shipped. The new TLS branch is a copy of the pattern used ~40 lines above in the same describe.each (open→greet for tcp, handshake→greet for tls, reject on handshake failure). The PR description documents fail-before (reverting the openssl.c guard fails the tls case; bun 1.3.13 fails 20/20) and pass-after (5/5 on debug main; canary 20/20), which satisfies the "prove the test fails for the right reason" bar.

Other factors

The test follows the repo's conventions: port: 0, using for the listener, awaits observable conditions (accepted, greeted, closedWith) with every failure event wired to reject rather than hang, and asserts the same readReset shape via toEqual. The added error handler on the client is a small hardening over the original tcp-only version. The handshake callback is not invoked for plain tcp sockets, so the tcp path is unchanged in behavior. The PR notes a trivial one-hunk conflict with #39653 on the comment lines, which is expected and not a blocker.

@robobun

robobun commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator Author

The review above asks for no changes. CI for 8971d7c is build 103178 and is still running. The claude-find-issues action failed in its own setup step, as it did on #40006, and is not about this diff.

@robobun

robobun commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 9:19 PM PT - Aug 21st, 2026

@robobun, your commit 8971d7c has 1 failures in Build #103178 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 40040

That installs a local version of the PR into your bun-40040 executable, so you can run:

bun-40040 --bun

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants