GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
// Copyright Joyent, Inc. and other Node contributors. |
||
2 |
// |
||
3 |
// Permission is hereby granted, free of charge, to any person obtaining a |
||
4 |
// copy of this software and associated documentation files (the |
||
5 |
// "Software"), to deal in the Software without restriction, including |
||
6 |
// without limitation the rights to use, copy, modify, merge, publish, |
||
7 |
// distribute, sublicense, and/or sell copies of the Software, and to permit |
||
8 |
// persons to whom the Software is furnished to do so, subject to the |
||
9 |
// following conditions: |
||
10 |
// |
||
11 |
// The above copyright notice and this permission notice shall be included |
||
12 |
// in all copies or substantial portions of the Software. |
||
13 |
// |
||
14 |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||
15 |
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||
16 |
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN |
||
17 |
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
||
18 |
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
||
19 |
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
||
20 |
// USE OR OTHER DEALINGS IN THE SOFTWARE. |
||
21 |
|||
22 |
#include "tcp_wrap.h" |
||
23 |
|||
24 |
#include "connect_wrap.h" |
||
25 |
#include "connection_wrap.h" |
||
26 |
#include "env-inl.h" |
||
27 |
#include "handle_wrap.h" |
||
28 |
#include "node_buffer.h" |
||
29 |
#include "node_external_reference.h" |
||
30 |
#include "node_internals.h" |
||
31 |
#include "stream_base-inl.h" |
||
32 |
#include "stream_wrap.h" |
||
33 |
#include "util-inl.h" |
||
34 |
|||
35 |
#include <cstdlib> |
||
36 |
|||
37 |
|||
38 |
namespace node { |
||
39 |
|||
40 |
using v8::Boolean; |
||
41 |
using v8::Context; |
||
42 |
using v8::EscapableHandleScope; |
||
43 |
using v8::Function; |
||
44 |
using v8::FunctionCallbackInfo; |
||
45 |
using v8::FunctionTemplate; |
||
46 |
using v8::Int32; |
||
47 |
using v8::Integer; |
||
48 |
using v8::Isolate; |
||
49 |
using v8::Local; |
||
50 |
using v8::MaybeLocal; |
||
51 |
using v8::Object; |
||
52 |
using v8::String; |
||
53 |
using v8::Uint32; |
||
54 |
using v8::Value; |
||
55 |
|||
56 |
5047 |
MaybeLocal<Object> TCPWrap::Instantiate(Environment* env, |
|
57 |
AsyncWrap* parent, |
||
58 |
TCPWrap::SocketType type) { |
||
59 |
5047 |
EscapableHandleScope handle_scope(env->isolate()); |
|
60 |
10094 |
AsyncHooks::DefaultTriggerAsyncIdScope trigger_scope(parent); |
|
61 |
✗✓ | 10094 |
CHECK_EQ(env->tcp_constructor_template().IsEmpty(), false); |
62 |
10094 |
Local<Function> constructor = env->tcp_constructor_template() |
|
63 |
10094 |
->GetFunction(env->context()) |
|
64 |
5047 |
.ToLocalChecked(); |
|
65 |
✗✓ | 5047 |
CHECK_EQ(constructor.IsEmpty(), false); |
66 |
5047 |
Local<Value> type_value = Int32::New(env->isolate(), type); |
|
67 |
return handle_scope.EscapeMaybe( |
||
68 |
10094 |
constructor->NewInstance(env->context(), 1, &type_value)); |
|
69 |
} |
||
70 |
|||
71 |
|||
72 |
6293 |
void TCPWrap::Initialize(Local<Object> target, |
|
73 |
Local<Value> unused, |
||
74 |
Local<Context> context, |
||
75 |
void* priv) { |
||
76 |
6293 |
Environment* env = Environment::GetCurrent(context); |
|
77 |
6293 |
Isolate* isolate = env->isolate(); |
|
78 |
|||
79 |
6293 |
Local<FunctionTemplate> t = NewFunctionTemplate(isolate, New); |
|
80 |
12586 |
t->InstanceTemplate()->SetInternalFieldCount(StreamBase::kInternalFieldCount); |
|
81 |
|||
82 |
// Init properties |
||
83 |
25172 |
t->InstanceTemplate()->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "reading"), |
|
84 |
Boolean::New(env->isolate(), false)); |
||
85 |
25172 |
t->InstanceTemplate()->Set(env->owner_symbol(), Null(env->isolate())); |
|
86 |
25172 |
t->InstanceTemplate()->Set(env->onconnection_string(), Null(env->isolate())); |
|
87 |
|||
88 |
6293 |
t->Inherit(LibuvStreamWrap::GetConstructorTemplate(env)); |
|
89 |
|||
90 |
6293 |
SetProtoMethod(isolate, t, "open", Open); |
|
91 |
6293 |
SetProtoMethod(isolate, t, "bind", Bind); |
|
92 |
6293 |
SetProtoMethod(isolate, t, "listen", Listen); |
|
93 |
6293 |
SetProtoMethod(isolate, t, "connect", Connect); |
|
94 |
6293 |
SetProtoMethod(isolate, t, "bind6", Bind6); |
|
95 |
6293 |
SetProtoMethod(isolate, t, "connect6", Connect6); |
|
96 |
6293 |
SetProtoMethod(isolate, |
|
97 |
t, |
||
98 |
"getsockname", |
||
99 |
GetSockOrPeerName<TCPWrap, uv_tcp_getsockname>); |
||
100 |
6293 |
SetProtoMethod(isolate, |
|
101 |
t, |
||
102 |
"getpeername", |
||
103 |
GetSockOrPeerName<TCPWrap, uv_tcp_getpeername>); |
||
104 |
6293 |
SetProtoMethod(isolate, t, "setNoDelay", SetNoDelay); |
|
105 |
6293 |
SetProtoMethod(isolate, t, "setKeepAlive", SetKeepAlive); |
|
106 |
6293 |
SetProtoMethod(isolate, t, "reset", Reset); |
|
107 |
|||
108 |
#ifdef _WIN32 |
||
109 |
SetProtoMethod(isolate, t, "setSimultaneousAccepts", SetSimultaneousAccepts); |
||
110 |
#endif |
||
111 |
|||
112 |
6293 |
SetConstructorFunction(context, target, "TCP", t); |
|
113 |
6293 |
env->set_tcp_constructor_template(t); |
|
114 |
|||
115 |
// Create FunctionTemplate for TCPConnectWrap. |
||
116 |
Local<FunctionTemplate> cwt = |
||
117 |
6293 |
BaseObject::MakeLazilyInitializedJSTemplate(env); |
|
118 |
6293 |
cwt->Inherit(AsyncWrap::GetConstructorTemplate(env)); |
|
119 |
6293 |
SetConstructorFunction(context, target, "TCPConnectWrap", cwt); |
|
120 |
|||
121 |
// Define constants |
||
122 |
6293 |
Local<Object> constants = Object::New(env->isolate()); |
|
123 |
31465 |
NODE_DEFINE_CONSTANT(constants, SOCKET); |
|
124 |
31465 |
NODE_DEFINE_CONSTANT(constants, SERVER); |
|
125 |
31465 |
NODE_DEFINE_CONSTANT(constants, UV_TCP_IPV6ONLY); |
|
126 |
12586 |
target->Set(context, |
|
127 |
env->constants_string(), |
||
128 |
18879 |
constants).Check(); |
|
129 |
6293 |
} |
|
130 |
|||
131 |
5552 |
void TCPWrap::RegisterExternalReferences(ExternalReferenceRegistry* registry) { |
|
132 |
5552 |
registry->Register(New); |
|
133 |
5552 |
registry->Register(Open); |
|
134 |
5552 |
registry->Register(Bind); |
|
135 |
5552 |
registry->Register(Listen); |
|
136 |
5552 |
registry->Register(Connect); |
|
137 |
5552 |
registry->Register(Bind6); |
|
138 |
5552 |
registry->Register(Connect6); |
|
139 |
|||
140 |
5552 |
registry->Register(GetSockOrPeerName<TCPWrap, uv_tcp_getsockname>); |
|
141 |
5552 |
registry->Register(GetSockOrPeerName<TCPWrap, uv_tcp_getpeername>); |
|
142 |
5552 |
registry->Register(SetNoDelay); |
|
143 |
5552 |
registry->Register(SetKeepAlive); |
|
144 |
5552 |
registry->Register(Reset); |
|
145 |
#ifdef _WIN32 |
||
146 |
registry->Register(SetSimultaneousAccepts); |
||
147 |
#endif |
||
148 |
5552 |
} |
|
149 |
|||
150 |
12848 |
void TCPWrap::New(const FunctionCallbackInfo<Value>& args) { |
|
151 |
// This constructor should not be exposed to public javascript. |
||
152 |
// Therefore we assert that we are not trying to call this as a |
||
153 |
// normal function. |
||
154 |
✗✓ | 12848 |
CHECK(args.IsConstructCall()); |
155 |
✗✓ | 25696 |
CHECK(args[0]->IsInt32()); |
156 |
12848 |
Environment* env = Environment::GetCurrent(args); |
|
157 |
|||
158 |
38544 |
int type_value = args[0].As<Int32>()->Value(); |
|
159 |
12848 |
TCPWrap::SocketType type = static_cast<TCPWrap::SocketType>(type_value); |
|
160 |
|||
161 |
ProviderType provider; |
||
162 |
✓✓✗ | 12848 |
switch (type) { |
163 |
11043 |
case SOCKET: |
|
164 |
11043 |
provider = PROVIDER_TCPWRAP; |
|
165 |
11043 |
break; |
|
166 |
1805 |
case SERVER: |
|
167 |
1805 |
provider = PROVIDER_TCPSERVERWRAP; |
|
168 |
1805 |
break; |
|
169 |
default: |
||
170 |
UNREACHABLE(); |
||
171 |
} |
||
172 |
|||
173 |
12848 |
new TCPWrap(env, args.This(), provider); |
|
174 |
12848 |
} |
|
175 |
|||
176 |
|||
177 |
12848 |
TCPWrap::TCPWrap(Environment* env, Local<Object> object, ProviderType provider) |
|
178 |
12848 |
: ConnectionWrap(env, object, provider) { |
|
179 |
12848 |
int r = uv_tcp_init(env->event_loop(), &handle_); |
|
180 |
✗✓ | 12848 |
CHECK_EQ(r, 0); // How do we proxy this error up to javascript? |
181 |
// Suggestion: uv_tcp_init() returns void. |
||
182 |
12848 |
} |
|
183 |
|||
184 |
|||
185 |
5772 |
void TCPWrap::SetNoDelay(const FunctionCallbackInfo<Value>& args) { |
|
186 |
TCPWrap* wrap; |
||
187 |
✗✓ | 5772 |
ASSIGN_OR_RETURN_UNWRAP(&wrap, |
188 |
args.Holder(), |
||
189 |
args.GetReturnValue().Set(UV_EBADF)); |
||
190 |
11544 |
int enable = static_cast<int>(args[0]->IsTrue()); |
|
191 |
5772 |
int err = uv_tcp_nodelay(&wrap->handle_, enable); |
|
192 |
11544 |
args.GetReturnValue().Set(err); |
|
193 |
} |
||
194 |
|||
195 |
|||
196 |
2398 |
void TCPWrap::SetKeepAlive(const FunctionCallbackInfo<Value>& args) { |
|
197 |
TCPWrap* wrap; |
||
198 |
✗✓ | 2398 |
ASSIGN_OR_RETURN_UNWRAP(&wrap, |
199 |
args.Holder(), |
||
200 |
args.GetReturnValue().Set(UV_EBADF)); |
||
201 |
2398 |
Environment* env = wrap->env(); |
|
202 |
int enable; |
||
203 |
✗✓ | 7194 |
if (!args[0]->Int32Value(env->context()).To(&enable)) return; |
204 |
7194 |
unsigned int delay = static_cast<unsigned int>(args[1].As<Uint32>()->Value()); |
|
205 |
2398 |
int err = uv_tcp_keepalive(&wrap->handle_, enable, delay); |
|
206 |
4796 |
args.GetReturnValue().Set(err); |
|
207 |
} |
||
208 |
|||
209 |
|||
210 |
#ifdef _WIN32 |
||
211 |
void TCPWrap::SetSimultaneousAccepts(const FunctionCallbackInfo<Value>& args) { |
||
212 |
TCPWrap* wrap; |
||
213 |
ASSIGN_OR_RETURN_UNWRAP(&wrap, |
||
214 |
args.Holder(), |
||
215 |
args.GetReturnValue().Set(UV_EBADF)); |
||
216 |
bool enable = args[0]->IsTrue(); |
||
217 |
int err = uv_tcp_simultaneous_accepts(&wrap->handle_, enable); |
||
218 |
args.GetReturnValue().Set(err); |
||
219 |
} |
||
220 |
#endif |
||
221 |
|||
222 |
|||
223 |
2 |
void TCPWrap::Open(const FunctionCallbackInfo<Value>& args) { |
|
224 |
TCPWrap* wrap; |
||
225 |
✗✓ | 2 |
ASSIGN_OR_RETURN_UNWRAP(&wrap, |
226 |
args.Holder(), |
||
227 |
args.GetReturnValue().Set(UV_EBADF)); |
||
228 |
int64_t val; |
||
229 |
✗✓ | 8 |
if (!args[0]->IntegerValue(args.GetIsolate()->GetCurrentContext()).To(&val)) |
230 |
return; |
||
231 |
2 |
int fd = static_cast<int>(val); |
|
232 |
2 |
int err = uv_tcp_open(&wrap->handle_, fd); |
|
233 |
|||
234 |
✓✗ | 2 |
if (err == 0) |
235 |
2 |
wrap->set_fd(fd); |
|
236 |
|||
237 |
4 |
args.GetReturnValue().Set(err); |
|
238 |
} |
||
239 |
|||
240 |
template <typename T> |
||
241 |
1828 |
void TCPWrap::Bind( |
|
242 |
const FunctionCallbackInfo<Value>& args, |
||
243 |
int family, |
||
244 |
std::function<int(const char* ip_address, int port, T* addr)> uv_ip_addr) { |
||
245 |
TCPWrap* wrap; |
||
246 |
✗✓✗✓ |
1828 |
ASSIGN_OR_RETURN_UNWRAP(&wrap, |
247 |
args.Holder(), |
||
248 |
args.GetReturnValue().Set(UV_EBADF)); |
||
249 |
1828 |
Environment* env = wrap->env(); |
|
250 |
3656 |
node::Utf8Value ip_address(env->isolate(), args[0]); |
|
251 |
int port; |
||
252 |
1828 |
unsigned int flags = 0; |
|
253 |
✗✓✗✓ |
5484 |
if (!args[1]->Int32Value(env->context()).To(&port)) return; |
254 |
✓✗✗✓ ✗✓✗✓ ✗✗✗✓ |
5352 |
if (family == AF_INET6 && |
255 |
6916 |
!args[2]->Uint32Value(env->context()).To(&flags)) { |
|
256 |
return; |
||
257 |
} |
||
258 |
|||
259 |
T addr; |
||
260 |
1828 |
int err = uv_ip_addr(*ip_address, port, &addr); |
|
261 |
|||
262 |
✓✓✓✗ |
1828 |
if (err == 0) { |
263 |
1826 |
err = uv_tcp_bind(&wrap->handle_, |
|
264 |
reinterpret_cast<const sockaddr*>(&addr), |
||
265 |
flags); |
||
266 |
} |
||
267 |
✓✗✓✗ |
3656 |
args.GetReturnValue().Set(err); |
268 |
} |
||
269 |
|||
270 |
132 |
void TCPWrap::Bind(const FunctionCallbackInfo<Value>& args) { |
|
271 |
132 |
Bind<sockaddr_in>(args, AF_INET, uv_ip4_addr); |
|
272 |
132 |
} |
|
273 |
|||
274 |
|||
275 |
1696 |
void TCPWrap::Bind6(const FunctionCallbackInfo<Value>& args) { |
|
276 |
1696 |
Bind<sockaddr_in6>(args, AF_INET6, uv_ip6_addr); |
|
277 |
1696 |
} |
|
278 |
|||
279 |
|||
280 |
1811 |
void TCPWrap::Listen(const FunctionCallbackInfo<Value>& args) { |
|
281 |
TCPWrap* wrap; |
||
282 |
✗✓ | 1811 |
ASSIGN_OR_RETURN_UNWRAP(&wrap, |
283 |
args.Holder(), |
||
284 |
args.GetReturnValue().Set(UV_EBADF)); |
||
285 |
1811 |
Environment* env = wrap->env(); |
|
286 |
int backlog; |
||
287 |
✗✓ | 5433 |
if (!args[0]->Int32Value(env->context()).To(&backlog)) return; |
288 |
1811 |
int err = uv_listen(reinterpret_cast<uv_stream_t*>(&wrap->handle_), |
|
289 |
backlog, |
||
290 |
1811 |
OnConnection); |
|
291 |
3622 |
args.GetReturnValue().Set(err); |
|
292 |
} |
||
293 |
|||
294 |
|||
295 |
644 |
void TCPWrap::Connect(const FunctionCallbackInfo<Value>& args) { |
|
296 |
✗✓ | 1288 |
CHECK(args[2]->IsUint32()); |
297 |
// explicit cast to fit to libuv's type expectation |
||
298 |
1932 |
int port = static_cast<int>(args[2].As<Uint32>()->Value()); |
|
299 |
644 |
Connect<sockaddr_in>(args, |
|
300 |
644 |
[port](const char* ip_address, sockaddr_in* addr) { |
|
301 |
return uv_ip4_addr(ip_address, port, addr); |
||
302 |
644 |
}); |
|
303 |
644 |
} |
|
304 |
|||
305 |
|||
306 |
4846 |
void TCPWrap::Connect6(const FunctionCallbackInfo<Value>& args) { |
|
307 |
4846 |
Environment* env = Environment::GetCurrent(args); |
|
308 |
✗✓ | 9692 |
CHECK(args[2]->IsUint32()); |
309 |
int port; |
||
310 |
✗✓ | 14538 |
if (!args[2]->Int32Value(env->context()).To(&port)) return; |
311 |
4846 |
Connect<sockaddr_in6>(args, |
|
312 |
4846 |
[port](const char* ip_address, sockaddr_in6* addr) { |
|
313 |
return uv_ip6_addr(ip_address, port, addr); |
||
314 |
4846 |
}); |
|
315 |
} |
||
316 |
|||
317 |
template <typename T> |
||
318 |
5490 |
void TCPWrap::Connect(const FunctionCallbackInfo<Value>& args, |
|
319 |
std::function<int(const char* ip_address, T* addr)> uv_ip_addr) { |
||
320 |
5490 |
Environment* env = Environment::GetCurrent(args); |
|
321 |
|||
322 |
TCPWrap* wrap; |
||
323 |
✗✓✗✓ |
5490 |
ASSIGN_OR_RETURN_UNWRAP(&wrap, |
324 |
args.Holder(), |
||
325 |
args.GetReturnValue().Set(UV_EBADF)); |
||
326 |
|||
327 |
✗✓✗✓ |
10980 |
CHECK(args[0]->IsObject()); |
328 |
✗✓✗✓ |
16470 |
CHECK(args[1]->IsString()); |
329 |
|||
330 |
10980 |
Local<Object> req_wrap_obj = args[0].As<Object>(); |
|
331 |
10980 |
node::Utf8Value ip_address(env->isolate(), args[1]); |
|
332 |
|||
333 |
T addr; |
||
334 |
5490 |
int err = uv_ip_addr(*ip_address, &addr); |
|
335 |
|||
336 |
✓✗✓✗ |
5490 |
if (err == 0) { |
337 |
10980 |
AsyncHooks::DefaultTriggerAsyncIdScope trigger_scope(wrap); |
|
338 |
10980 |
ConnectWrap* req_wrap = |
|
339 |
5490 |
new ConnectWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_TCPCONNECTWRAP); |
|
340 |
10980 |
err = req_wrap->Dispatch(uv_tcp_connect, |
|
341 |
5490 |
&wrap->handle_, |
|
342 |
reinterpret_cast<const sockaddr*>(&addr), |
||
343 |
AfterConnect); |
||
344 |
✗✓✗✓ |
5490 |
if (err) { |
345 |
delete req_wrap; |
||
346 |
} else { |
||
347 |
✗✓✗✓ |
16470 |
CHECK(args[2]->Uint32Value(env->context()).IsJust()); |
348 |
16470 |
int port = args[2]->Uint32Value(env->context()).FromJust(); |
|
349 |
✓✓✓✓ ✓✓✗✓ |
10980 |
TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(TRACING_CATEGORY_NODE2(net, native), |
350 |
"connect", |
||
351 |
req_wrap, |
||
352 |
"ip", |
||
353 |
TRACE_STR_COPY(*ip_address), |
||
354 |
"port", |
||
355 |
port); |
||
356 |
} |
||
357 |
} |
||
358 |
|||
359 |
10980 |
args.GetReturnValue().Set(err); |
|
360 |
} |
||
361 |
5 |
void TCPWrap::Reset(const FunctionCallbackInfo<Value>& args) { |
|
362 |
TCPWrap* wrap; |
||
363 |
✗✓ | 5 |
ASSIGN_OR_RETURN_UNWRAP( |
364 |
&wrap, args.Holder(), args.GetReturnValue().Set(UV_EBADF)); |
||
365 |
|||
366 |
10 |
int err = wrap->Reset(args[0]); |
|
367 |
|||
368 |
10 |
args.GetReturnValue().Set(err); |
|
369 |
} |
||
370 |
|||
371 |
5 |
int TCPWrap::Reset(Local<Value> close_callback) { |
|
372 |
✗✓ | 5 |
if (state_ != kInitialized) return 0; |
373 |
|||
374 |
5 |
int err = uv_tcp_close_reset(&handle_, OnClose); |
|
375 |
5 |
state_ = kClosing; |
|
376 |
✓✗✓✗ ✓✗✓✗ |
20 |
if (!err & !close_callback.IsEmpty() && close_callback->IsFunction() && |
377 |
10 |
!persistent().IsEmpty()) { |
|
378 |
10 |
object() |
|
379 |
15 |
->Set(env()->context(), env()->handle_onclose_symbol(), close_callback) |
|
380 |
.Check(); |
||
381 |
} |
||
382 |
5 |
return err; |
|
383 |
} |
||
384 |
|||
385 |
// also used by udp_wrap.cc |
||
386 |
4989 |
MaybeLocal<Object> AddressToJS(Environment* env, |
|
387 |
const sockaddr* addr, |
||
388 |
Local<Object> info) { |
||
389 |
4989 |
EscapableHandleScope scope(env->isolate()); |
|
390 |
char ip[INET6_ADDRSTRLEN + UV_IF_NAMESIZE]; |
||
391 |
const sockaddr_in* a4; |
||
392 |
const sockaddr_in6* a6; |
||
393 |
|||
394 |
int port; |
||
395 |
|||
396 |
✓✓ | 4989 |
if (info.IsEmpty()) |
397 |
440 |
info = Object::New(env->isolate()); |
|
398 |
|||
399 |
✓✓✗ | 4989 |
switch (addr->sa_family) { |
400 |
4284 |
case AF_INET6: |
|
401 |
4284 |
a6 = reinterpret_cast<const sockaddr_in6*>(addr); |
|
402 |
4284 |
uv_inet_ntop(AF_INET6, &a6->sin6_addr, ip, sizeof ip); |
|
403 |
// Add an interface identifier to a link local address. |
||
404 |
✓✓✓✗ ✓✓ |
4284 |
if (IN6_IS_ADDR_LINKLOCAL(&a6->sin6_addr) && a6->sin6_scope_id > 0) { |
405 |
2 |
const size_t addrlen = strlen(ip); |
|
406 |
✗✓ | 2 |
CHECK_LT(addrlen, sizeof(ip)); |
407 |
2 |
ip[addrlen] = '%'; |
|
408 |
2 |
size_t scopeidlen = sizeof(ip) - addrlen - 1; |
|
409 |
✗✓ | 2 |
CHECK_GE(scopeidlen, UV_IF_NAMESIZE); |
410 |
2 |
const int r = uv_if_indextoiid(a6->sin6_scope_id, |
|
411 |
2 |
ip + addrlen + 1, |
|
412 |
2 |
&scopeidlen); |
|
413 |
✗✓ | 2 |
if (r) { |
414 |
env->ThrowUVException(r, "uv_if_indextoiid"); |
||
415 |
return {}; |
||
416 |
} |
||
417 |
} |
||
418 |
4284 |
port = ntohs(a6->sin6_port); |
|
419 |
8568 |
info->Set(env->context(), |
|
420 |
env->address_string(), |
||
421 |
17136 |
OneByteString(env->isolate(), ip)).Check(); |
|
422 |
17136 |
info->Set(env->context(), env->family_string(), env->ipv6_string()).Check(); |
|
423 |
8568 |
info->Set(env->context(), |
|
424 |
env->port_string(), |
||
425 |
17136 |
Integer::New(env->isolate(), port)).Check(); |
|
426 |
4284 |
break; |
|
427 |
|||
428 |
705 |
case AF_INET: |
|
429 |
705 |
a4 = reinterpret_cast<const sockaddr_in*>(addr); |
|
430 |
705 |
uv_inet_ntop(AF_INET, &a4->sin_addr, ip, sizeof ip); |
|
431 |
705 |
port = ntohs(a4->sin_port); |
|
432 |
1410 |
info->Set(env->context(), |
|
433 |
env->address_string(), |
||
434 |
2820 |
OneByteString(env->isolate(), ip)).Check(); |
|
435 |
2820 |
info->Set(env->context(), env->family_string(), env->ipv4_string()).Check(); |
|
436 |
1410 |
info->Set(env->context(), |
|
437 |
env->port_string(), |
||
438 |
2820 |
Integer::New(env->isolate(), port)).Check(); |
|
439 |
705 |
break; |
|
440 |
|||
441 |
default: |
||
442 |
info->Set(env->context(), |
||
443 |
env->address_string(), |
||
444 |
String::Empty(env->isolate())).Check(); |
||
445 |
} |
||
446 |
|||
447 |
4989 |
return scope.Escape(info); |
|
448 |
} |
||
449 |
|||
450 |
|||
451 |
} // namespace node |
||
452 |
|||
453 |
5623 |
NODE_MODULE_CONTEXT_AWARE_INTERNAL(tcp_wrap, node::TCPWrap::Initialize) |
|
454 |
✓✗✓✗ |
22421 |
NODE_MODULE_EXTERNAL_REFERENCE(tcp_wrap, |
455 |
node::TCPWrap::RegisterExternalReferences) |
Generated by: GCOVR (Version 4.2) |