net: support AF_UNIX paths in net.BoundSocket#64399
Conversation
|
Review requested:
|
1e91371 to
6a4fee8
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #64399 +/- ##
==========================================
- Coverage 92.01% 90.23% -1.78%
==========================================
Files 379 739 +360
Lines 170129 241738 +71609
Branches 26090 45560 +19470
==========================================
+ Hits 156544 218139 +61595
- Misses 13293 15153 +1860
- Partials 292 8446 +8154
🚀 New features to boost your workflow:
|
Ethan-Arrowood
left a comment
There was a problem hiding this comment.
LGTM with just some doc changes and one question about the implementation.
| // 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; |
There was a problem hiding this comment.
What happens here if this._handle is null from the if (this.destroyed) { line just before?
There was a problem hiding this comment.
Good catch! Yeah it would wrongly attempt a TCP connect - fixed to fall back to the path option if the handle is already gone.
31a96f5 to
9571737
Compare
Signed-off-by: Guy Bedford <guybedford@gmail.com>
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.
9571737 to
3429149
Compare
| synchronous port reservation, while for `new net.Socket()`, it allows control | ||
| over the local egress port/IP, via `bind(2)` semantics. | ||
|
|
||
| A `BoundSocket` binds either a TCP endpoint (`host`/`port`) or a |
There was a problem hiding this comment.
Nit: the `host`/`port` suggest `host` or `port` here.
| // selects the Linux abstract namespace. path is mutually exclusive with the | ||
| // TCP options; uv_pipe_bind is synchronous so conflicts throw here. | ||
| #bindPipe(options) { | ||
| const { path } = options; |
There was a problem hiding this comment.
Nit, you're destructing path here but not host, port, ipv6Only, and reusePort below. I'd destructure them all.
jasnell
left a comment
There was a problem hiding this comment.
Couple of nits but otherwise LGTM
Extends
net.BoundSocket(#63951) with apathoption 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 intoprocess.binding('pipe_wrap'), just as it replaces the need fortcp_wrapandudp_wrapsimilarly.pathis mutually exclusive withhost/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 throwsERR_INVALID_ARG_VALUE.address()returns the path string for a pipe (asServer.address()does), the address object for TCP.isPipegetter to tell the two apart.server.listen(bound)andnew net.Socket({ handle: bound }).connect()pick pipe vs TCP from the adopted handle's type.localAddress.Note two error codes match libuv rather than intuition: missing parent dir is
EACCES(libuv mapsENOENT), over-long path isEINVAL(UV_PIPE_NO_TRUNCATE).Tests cover sync bind +
address(), duplicate-bindEADDRINUSE, the listen/connect round-trip, bound-clientlocalAddress, the abstract namespace, and the error paths.