Skip to content

net: add synchronous, role-neutral net.BoundHandle#63951

Open
guybedford wants to merge 2 commits into
nodejs:mainfrom
guybedford:tcp-bound-handle
Open

net: add synchronous, role-neutral net.BoundHandle#63951
guybedford wants to merge 2 commits into
nodejs:mainfrom
guybedford:tcp-bound-handle

Conversation

@guybedford

Copy link
Copy Markdown
Contributor

Add net.BoundHandle, a synchronous TCP bind primitive that mirrors POSIX bind(2): the socket is bound to a local address but stays role-agnostic until it is adopted as a server (server.listen()) or a client (new net.Socket({ handle }) followed by connect()).

Constructing a net.BoundHandle binds inline via the existing uv_tcp_bind() path, so the kernel-assigned address (including the ephemeral port when port is 0) is available immediately via boundHandle.address(), and bind errors throw synchronously.

Adoption transfers ownership of the underlying handle; afterwards address() and close() throw ERR_SOCKET_HANDLE_ADOPTED. An un-adopted handle is released with close() or via Symbol.dispose (using).

The handle is passed in-process rather than as a file descriptor, so it also works on Windows.

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/net

@nodejs-github-bot nodejs-github-bot added errors Issues and PRs related to JavaScript errors originated in Node.js core. needs-ci PRs that need a full CI run. net Issues and PRs related to the net subsystem. labels Jun 16, 2026
@guybedford guybedford force-pushed the tcp-bound-handle branch 2 times, most recently from 5db58e1 to 9da4d5f Compare June 17, 2026 00:07
Signed-off-by: Guy Bedford <guybedford@gmail.com>
@mcollina

Copy link
Copy Markdown
Member

I don't understand why this is needed

@Ethan-Arrowood Ethan-Arrowood 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.

I appreciate this change. net.BoundHandle lets you reserve a TCP port and actually hold onto it until you're ready to use it. This simplifies utility modules like [get-port](https://npmx.dev/package/get-port) that are susceptible to TOCTOU (Time-of-Check to Time-of-Use) race conditions. Of course, it doesn't solve the problem perfectly since this is in-process only, but I think it's a great improvement.

As a follow-up, it'd be great if BoundHandle could optionally expose its underlying file descriptor, so the reservation can be handed to another process (Unix-only, since this relies on POSIX fd passing). That would extend the same race-free guarantee across a process boundary.

@guybedford

guybedford commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for clarifying the use case here @Ethan-Arrowood. I've gone ahead and added a commit to expose the fd() as well here for the additional thread-passing use case.

@guybedford guybedford added request-ci Add this label to start a Jenkins CI on a PR. and removed request-ci Add this label to start a Jenkins CI on a PR. labels Jun 17, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

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

Labels

errors Issues and PRs related to JavaScript errors originated in Node.js core. needs-ci PRs that need a full CI run. net Issues and PRs related to the net subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants