Skip to content

net: support AF_UNIX paths in net.BoundSocket#64399

Open
guybedford wants to merge 3 commits into
nodejs:mainfrom
guybedford:net-boundsocket-pipe
Open

net: support AF_UNIX paths in net.BoundSocket#64399
guybedford wants to merge 3 commits into
nodejs:mainfrom
guybedford:net-boundsocket-pipe

Conversation

@guybedford

Copy link
Copy Markdown
Contributor

Extends net.BoundSocket (#63951) with a path option so it can immediately bind a named unix-domain socket (or Windows pipe) synchronously, not just TCP. This gives a public synchronous UDS bind through the same role-neutral handle, instead of reaching into process.binding('pipe_wrap'), just as it replaces the need for tcp_wrap and udp_wrap similarly.

path is mutually exclusive with host/port/ipv6Only/reusePort, and binds in the constructor so conflicts throw there like TCP does. A leading '\0' uses the Linux abstract namespace; an abstract path elsewhere throws ERR_INVALID_ARG_VALUE.

  • address() returns the path string for a pipe (as Server.address() does), the address object for TCP.
  • New isPipe getter to tell the two apart.
  • server.listen(bound) and new net.Socket({ handle: bound }).connect() pick pipe vs TCP from the adopted handle's type.
  • A bound client pipe reports its source path as localAddress.

Note two error codes match libuv rather than intuition: missing parent dir is EACCES (libuv maps ENOENT), over-long path is EINVAL (UV_PIPE_NO_TRUNCATE).

Tests cover sync bind + address(), duplicate-bind EADDRINUSE, the listen/connect round-trip, bound-client localAddress, the abstract namespace, and the error paths.

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/net

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. net Issues and PRs related to the net subsystem. labels Jul 10, 2026
Signed-off-by: Guy Bedford <guybedford@gmail.com>
@guybedford guybedford force-pushed the net-boundsocket-pipe branch from 1e91371 to 6a4fee8 Compare July 10, 2026 00:24
Only trust the adopted handle's type when it came from a BoundSocket;
a TLSSocket's _handle is a TLSWrap, not a Pipe, so TLS/HTTPS over pipes
must still infer pipe-ness from the path option.
@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.93878% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.25%. Comparing base (8fec65d) to head (9571737).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
lib/net.js 96.93% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #64399      +/-   ##
==========================================
- Coverage   90.25%   90.25%   -0.01%     
==========================================
  Files         741      741              
  Lines      241207   241427     +220     
  Branches    45430    45495      +65     
==========================================
+ Hits       217698   217892     +194     
- Misses      15084    15090       +6     
- Partials     8425     8445      +20     
Files with missing lines Coverage Δ
lib/net.js 94.66% <96.93%> (+0.06%) ⬆️

... and 31 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

LGTM with just some doc changes and one question about the implementation.

Comment thread doc/api/net.md
Comment thread doc/api/net.md
Comment thread doc/api/net.md Outdated
Comment thread lib/net.js Outdated
// rather than inferring pipe-ness from a path option on the connect call.
// Other pre-existing handles (e.g. a TLSWrap) are not transport handles, so
// fall back to the path option in that case.
const pipe = this[kBoundSource] ? this._handle instanceof Pipe : !!path;

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.

What happens here if this._handle is null from the if (this.destroyed) { line just before?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch! Yeah it would wrongly attempt a TCP connect - fixed to fall back to the path option if the handle is already gone.

@guybedford guybedford force-pushed the net-boundsocket-pipe branch from 3716f9f to 31a96f5 Compare July 10, 2026 19:41
@guybedford guybedford force-pushed the net-boundsocket-pipe branch from 31a96f5 to 9571737 Compare July 10, 2026 19:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

3 participants