diff --git a/src/node_internals.h b/src/node_internals.h index ffb5ec7ad96242..aa198666b62c6c 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -79,6 +79,19 @@ v8::Local AddressToJS( const sockaddr* addr, v8::Local info = v8::Handle()); +template +void GetSockOrPeerName(const v8::FunctionCallbackInfo& args) { + T* const wrap = Unwrap(args.Holder()); + CHECK(args[0]->IsObject()); + sockaddr_storage storage; + int addrlen = sizeof(storage); + sockaddr* const addr = reinterpret_cast(&storage); + const int err = F(&wrap->handle_, addr, &addrlen); + if (err == 0) + AddressToJS(wrap->env(), addr, args[0].As()); + args.GetReturnValue().Set(err); +} + #ifdef _WIN32 // emulate snprintf() on windows, _snprintf() doesn't zero-terminate the buffer // on overflow... diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 6980f8b28ce028..d9a35886cbb376 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -98,8 +98,10 @@ void TCPWrap::Initialize(Handle target, env->SetProtoMethod(t, "connect", Connect); env->SetProtoMethod(t, "bind6", Bind6); env->SetProtoMethod(t, "connect6", Connect6); - env->SetProtoMethod(t, "getsockname", GetSockName); - env->SetProtoMethod(t, "getpeername", GetPeerName); + env->SetProtoMethod(t, "getsockname", + GetSockOrPeerName); + env->SetProtoMethod(t, "getpeername", + GetSockOrPeerName); env->SetProtoMethod(t, "setNoDelay", SetNoDelay); env->SetProtoMethod(t, "setKeepAlive", SetKeepAlive); @@ -162,50 +164,6 @@ TCPWrap::~TCPWrap() { } -void TCPWrap::GetSockName(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - struct sockaddr_storage address; - - TCPWrap* wrap = Unwrap(args.Holder()); - - CHECK(args[0]->IsObject()); - Local out = args[0].As(); - - int addrlen = sizeof(address); - int err = uv_tcp_getsockname(&wrap->handle_, - reinterpret_cast(&address), - &addrlen); - if (err == 0) { - const sockaddr* addr = reinterpret_cast(&address); - AddressToJS(env, addr, out); - } - - args.GetReturnValue().Set(err); -} - - -void TCPWrap::GetPeerName(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - struct sockaddr_storage address; - - TCPWrap* wrap = Unwrap(args.Holder()); - - CHECK(args[0]->IsObject()); - Local out = args[0].As(); - - int addrlen = sizeof(address); - int err = uv_tcp_getpeername(&wrap->handle_, - reinterpret_cast(&address), - &addrlen); - if (err == 0) { - const sockaddr* addr = reinterpret_cast(&address); - AddressToJS(env, addr, out); - } - - args.GetReturnValue().Set(err); -} - - void TCPWrap::SetNoDelay(const FunctionCallbackInfo& args) { TCPWrap* wrap = Unwrap(args.Holder()); int enable = static_cast(args[0]->BooleanValue()); diff --git a/src/tcp_wrap.h b/src/tcp_wrap.h index ee1e9817b231e9..79404a7e421963 100644 --- a/src/tcp_wrap.h +++ b/src/tcp_wrap.h @@ -19,12 +19,16 @@ class TCPWrap : public StreamWrap { size_t self_size() const override { return sizeof(*this); } private: + typedef uv_tcp_t HandleType; + + template + friend void GetSockOrPeerName(const v8::FunctionCallbackInfo&); + TCPWrap(Environment* env, v8::Handle object, AsyncWrap* parent); ~TCPWrap(); static void New(const v8::FunctionCallbackInfo& args); - static void GetSockName(const v8::FunctionCallbackInfo& args); - static void GetPeerName(const v8::FunctionCallbackInfo& args); static void SetNoDelay(const v8::FunctionCallbackInfo& args); static void SetKeepAlive(const v8::FunctionCallbackInfo& args); static void Bind(const v8::FunctionCallbackInfo& args); diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index dd3958ec0e37da..71cc547675ff3e 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -96,7 +96,8 @@ void UDPWrap::Initialize(Handle target, env->SetProtoMethod(t, "close", Close); env->SetProtoMethod(t, "recvStart", RecvStart); env->SetProtoMethod(t, "recvStop", RecvStop); - env->SetProtoMethod(t, "getsockname", GetSockName); + env->SetProtoMethod(t, "getsockname", + GetSockOrPeerName); env->SetProtoMethod(t, "addMembership", AddMembership); env->SetProtoMethod(t, "dropMembership", DropMembership); env->SetProtoMethod(t, "setMulticastTTL", SetMulticastTTL); @@ -325,29 +326,6 @@ void UDPWrap::RecvStop(const FunctionCallbackInfo& args) { } -void UDPWrap::GetSockName(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - - struct sockaddr_storage address; - UDPWrap* wrap = Unwrap(args.Holder()); - - CHECK(args[0]->IsObject()); - Local obj = args[0].As(); - - int addrlen = sizeof(address); - int err = uv_udp_getsockname(&wrap->handle_, - reinterpret_cast(&address), - &addrlen); - - if (err == 0) { - const sockaddr* addr = reinterpret_cast(&address); - AddressToJS(env, addr, obj); - } - - args.GetReturnValue().Set(err); -} - - // TODO(bnoordhuis) share with StreamWrap::AfterWrite() in stream_wrap.cc void UDPWrap::OnSend(uv_udp_send_t* req, int status) { SendWrap* req_wrap = static_cast(req->data); diff --git a/src/udp_wrap.h b/src/udp_wrap.h index 3373cb9a2dfddb..1582fb46cec0a4 100644 --- a/src/udp_wrap.h +++ b/src/udp_wrap.h @@ -40,6 +40,12 @@ class UDPWrap: public HandleWrap { size_t self_size() const override { return sizeof(*this); } private: + typedef uv_udp_t HandleType; + + template + friend void GetSockOrPeerName(const v8::FunctionCallbackInfo&); + UDPWrap(Environment* env, v8::Handle object, AsyncWrap* parent); static void DoBind(const v8::FunctionCallbackInfo& args,