Skip to content

Commit

Permalink
src: port Pipe to uv_pipe_bind2, uv_pipe_connect2
Browse files Browse the repository at this point in the history
The introduction of the uv_pipe_bind2 and uv_pipe_connect2 methods in
libuv v1.46.0 changed the behaviour of uv_pipe_bind and uv_pipe_connect.
This broke the ability to connect to abstract domain sockets on linux.
This change ports PipeWrap to use the new uv_pipe_bind2 and
uv_pipe_connect2 methods to restore abstract domain socket support.

Fixes: nodejs#49656
Refs: libuv/libuv#4030
PR-URL: nodejs#49667
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
ggoodman authored and alexfernandez committed Nov 1, 2023
1 parent 9b8ad5a commit bfe03a6
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 22 deletions.
29 changes: 7 additions & 22 deletions src/pipe_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ MaybeLocal<Object> PipeWrap::Instantiate(Environment* env,
constructor->NewInstance(env->context(), 1, &type_value));
}


void PipeWrap::Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
Expand All @@ -71,8 +70,7 @@ void PipeWrap::Initialize(Local<Object> target,
Isolate* isolate = env->isolate();

Local<FunctionTemplate> t = NewFunctionTemplate(isolate, New);
t->InstanceTemplate()
->SetInternalFieldCount(StreamBase::kInternalFieldCount);
t->InstanceTemplate()->SetInternalFieldCount(StreamBase::kInternalFieldCount);

t->Inherit(LibuvStreamWrap::GetConstructorTemplate(env));

Expand Down Expand Up @@ -102,9 +100,7 @@ void PipeWrap::Initialize(Local<Object> target,
NODE_DEFINE_CONSTANT(constants, IPC);
NODE_DEFINE_CONSTANT(constants, UV_READABLE);
NODE_DEFINE_CONSTANT(constants, UV_WRITABLE);
target->Set(context,
env->constants_string(),
constants).Check();
target->Set(context, env->constants_string(), constants).Check();
}

void PipeWrap::RegisterExternalReferences(ExternalReferenceRegistry* registry) {
Expand Down Expand Up @@ -152,7 +148,6 @@ void PipeWrap::New(const FunctionCallbackInfo<Value>& args) {
new PipeWrap(env, args.This(), provider, ipc);
}


PipeWrap::PipeWrap(Environment* env,
Local<Object> object,
ProviderType provider,
Expand All @@ -163,16 +158,14 @@ PipeWrap::PipeWrap(Environment* env,
// Suggestion: uv_pipe_init() returns void.
}


void PipeWrap::Bind(const FunctionCallbackInfo<Value>& args) {
PipeWrap* wrap;
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
node::Utf8Value name(args.GetIsolate(), args[0]);
int err = uv_pipe_bind(&wrap->handle_, *name);
int err = uv_pipe_bind2(&wrap->handle_, *name, name.length(), 0);
args.GetReturnValue().Set(err);
}


#ifdef _WIN32
void PipeWrap::SetPendingInstances(const FunctionCallbackInfo<Value>& args) {
PipeWrap* wrap;
Expand All @@ -183,7 +176,6 @@ void PipeWrap::SetPendingInstances(const FunctionCallbackInfo<Value>& args) {
}
#endif


void PipeWrap::Fchmod(const v8::FunctionCallbackInfo<v8::Value>& args) {
PipeWrap* wrap;
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
Expand All @@ -193,20 +185,17 @@ void PipeWrap::Fchmod(const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(err);
}


void PipeWrap::Listen(const FunctionCallbackInfo<Value>& args) {
PipeWrap* wrap;
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
Environment* env = wrap->env();
int backlog;
if (!args[0]->Int32Value(env->context()).To(&backlog)) return;
int err = uv_listen(reinterpret_cast<uv_stream_t*>(&wrap->handle_),
backlog,
OnConnection);
int err = uv_listen(
reinterpret_cast<uv_stream_t*>(&wrap->handle_), backlog, OnConnection);
args.GetReturnValue().Set(err);
}


void PipeWrap::Open(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);

Expand All @@ -222,7 +211,6 @@ void PipeWrap::Open(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(err);
}


void PipeWrap::Connect(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);

Expand All @@ -237,10 +225,8 @@ void PipeWrap::Connect(const FunctionCallbackInfo<Value>& args) {

ConnectWrap* req_wrap =
new ConnectWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_PIPECONNECTWRAP);
req_wrap->Dispatch(uv_pipe_connect,
&wrap->handle_,
*name,
AfterConnect);
req_wrap->Dispatch(
uv_pipe_connect2, &wrap->handle_, *name, name.length(), 0, AfterConnect);

TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(TRACING_CATEGORY_NODE2(net, native),
"connect",
Expand All @@ -251,7 +237,6 @@ void PipeWrap::Connect(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(0); // uv_pipe_connect() doesn't return errors.
}


} // namespace node

NODE_BINDING_CONTEXT_AWARE_INTERNAL(pipe_wrap, node::PipeWrap::Initialize)
Expand Down
27 changes: 27 additions & 0 deletions test/parallel/test-pipe-abstract-socket-http.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const http = require('http');

if (!common.isLinux) common.skip();

const server = http.createServer(
common.mustCall((req, res) => {
res.end('ok');
})
);

server.listen(
'\0abstract',
common.mustCall(() => {
http.get(
{
socketPath: server.address(),
},
common.mustCall((res) => {
assert.strictEqual(res.statusCode, 200);
server.close();
})
);
})
);

0 comments on commit bfe03a6

Please sign in to comment.