~yolanda.robla/ubuntu/trusty/nodejs/add_distribution

« back to all changes in this revision

Viewing changes to src/tcp_wrap.cc

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2013-08-14 00:16:46 UTC
  • mfrom: (7.1.40 sid)
  • Revision ID: package-import@ubuntu.com-20130814001646-bzlysfh8sd6mukbo
Tags: 0.10.15~dfsg1-4
* Update 2005 patch, adding a handful of tests that can fail on
  slow platforms.
* Add 1004 patch to fix test failures when writing NaN to buffer
  on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
20
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
 
#include <node.h>
23
 
#include <node_buffer.h>
24
 
#include <req_wrap.h>
25
 
#include <handle_wrap.h>
26
 
#include <stream_wrap.h>
27
 
#include <tcp_wrap.h>
 
22
#include "node.h"
 
23
#include "node_buffer.h"
 
24
#include "req_wrap.h"
 
25
#include "handle_wrap.h"
 
26
#include "stream_wrap.h"
 
27
#include "tcp_wrap.h"
28
28
 
29
29
#include <stdlib.h>
30
30
 
31
 
// Temporary hack: libuv should provide uv_inet_pton and uv_inet_ntop.
32
 
#if defined(__MINGW32__) || defined(_MSC_VER)
33
 
  extern "C" {
34
 
#   include <inet_net_pton.h>
35
 
#   include <inet_ntop.h>
36
 
  }
37
 
# define uv_inet_pton ares_inet_pton
38
 
# define uv_inet_ntop ares_inet_ntop
39
 
 
40
 
#else // __POSIX__
41
 
# include <arpa/inet.h>
42
 
# define uv_inet_pton inet_pton
43
 
# define uv_inet_ntop inet_ntop
44
 
#endif
45
 
 
46
 
#define UNWRAP \
47
 
  assert(!args.Holder().IsEmpty()); \
48
 
  assert(args.Holder()->InternalFieldCount() > 0); \
49
 
  TCPWrap* wrap =  \
50
 
      static_cast<TCPWrap*>(args.Holder()->GetPointerFromInternalField(0)); \
51
 
  if (!wrap) { \
52
 
    uv_err_t err; \
53
 
    err.code = UV_EBADF; \
54
 
    SetErrno(err); \
55
 
    return scope.Close(Integer::New(-1)); \
56
 
  }
57
31
 
58
32
namespace node {
59
33
 
60
 
using v8::Object;
 
34
using v8::Arguments;
 
35
using v8::Context;
 
36
using v8::Function;
 
37
using v8::FunctionTemplate;
61
38
using v8::Handle;
 
39
using v8::HandleScope;
 
40
using v8::Integer;
62
41
using v8::Local;
 
42
using v8::Null;
 
43
using v8::Object;
63
44
using v8::Persistent;
64
 
using v8::Value;
65
 
using v8::HandleScope;
66
 
using v8::FunctionTemplate;
 
45
using v8::PropertyAttribute;
67
46
using v8::String;
68
 
using v8::Function;
69
47
using v8::TryCatch;
70
 
using v8::Context;
71
 
using v8::Arguments;
72
 
using v8::Integer;
73
48
using v8::Undefined;
 
49
using v8::Value;
74
50
 
75
51
static Persistent<Function> tcpConstructor;
76
 
static Persistent<String> family_symbol;
77
 
static Persistent<String> address_symbol;
78
 
static Persistent<String> port_symbol;
 
52
static Persistent<String> oncomplete_sym;
 
53
static Persistent<String> onconnection_sym;
79
54
 
80
55
 
81
56
typedef class ReqWrap<uv_connect_t> ConnectWrap;
82
57
 
 
58
Local<Object> AddressToJS(const sockaddr* addr);
 
59
 
83
60
 
84
61
Local<Object> TCPWrap::Instantiate() {
85
62
  // If this assert fire then process.binding('tcp_wrap') hasn't been
104
81
 
105
82
  t->InstanceTemplate()->SetInternalFieldCount(1);
106
83
 
 
84
  enum PropertyAttribute attributes =
 
85
      static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
 
86
  t->InstanceTemplate()->SetAccessor(String::New("fd"),
 
87
                                     StreamWrap::GetFD,
 
88
                                     NULL,
 
89
                                     Handle<Value>(),
 
90
                                     v8::DEFAULT,
 
91
                                     attributes);
 
92
 
107
93
  NODE_SET_PROTOTYPE_METHOD(t, "close", HandleWrap::Close);
108
94
 
 
95
  NODE_SET_PROTOTYPE_METHOD(t, "ref", HandleWrap::Ref);
 
96
  NODE_SET_PROTOTYPE_METHOD(t, "unref", HandleWrap::Unref);
 
97
 
109
98
  NODE_SET_PROTOTYPE_METHOD(t, "readStart", StreamWrap::ReadStart);
110
99
  NODE_SET_PROTOTYPE_METHOD(t, "readStop", StreamWrap::ReadStop);
111
 
  NODE_SET_PROTOTYPE_METHOD(t, "write", StreamWrap::Write);
112
100
  NODE_SET_PROTOTYPE_METHOD(t, "shutdown", StreamWrap::Shutdown);
113
101
 
 
102
  NODE_SET_PROTOTYPE_METHOD(t, "writeBuffer", StreamWrap::WriteBuffer);
 
103
  NODE_SET_PROTOTYPE_METHOD(t, "writeAsciiString", StreamWrap::WriteAsciiString);
 
104
  NODE_SET_PROTOTYPE_METHOD(t, "writeUtf8String", StreamWrap::WriteUtf8String);
 
105
  NODE_SET_PROTOTYPE_METHOD(t, "writeUcs2String", StreamWrap::WriteUcs2String);
 
106
 
 
107
  NODE_SET_PROTOTYPE_METHOD(t, "open", Open);
114
108
  NODE_SET_PROTOTYPE_METHOD(t, "bind", Bind);
115
109
  NODE_SET_PROTOTYPE_METHOD(t, "listen", Listen);
116
110
  NODE_SET_PROTOTYPE_METHOD(t, "connect", Connect);
127
121
 
128
122
  tcpConstructor = Persistent<Function>::New(t->GetFunction());
129
123
 
130
 
  family_symbol = NODE_PSYMBOL("family");
131
 
  address_symbol = NODE_PSYMBOL("address");
132
 
  port_symbol = NODE_PSYMBOL("port");
 
124
  onconnection_sym = NODE_PSYMBOL("onconnection");
 
125
  oncomplete_sym = NODE_PSYMBOL("oncomplete");
133
126
 
134
127
  target->Set(String::NewSymbol("TCP"), tcpConstructor);
135
128
}
136
129
 
137
130
 
 
131
TCPWrap* TCPWrap::Unwrap(Local<Object> obj) {
 
132
  assert(!obj.IsEmpty());
 
133
  assert(obj->InternalFieldCount() > 0);
 
134
  return static_cast<TCPWrap*>(obj->GetPointerFromInternalField(0));
 
135
}
 
136
 
 
137
 
 
138
uv_tcp_t* TCPWrap::UVHandle() {
 
139
  return &handle_;
 
140
}
 
141
 
 
142
 
138
143
Handle<Value> TCPWrap::New(const Arguments& args) {
139
144
  // This constructor should not be exposed to public javascript.
140
145
  // Therefore we assert that we are not trying to call this as a
166
171
Handle<Value> TCPWrap::GetSockName(const Arguments& args) {
167
172
  HandleScope scope;
168
173
  struct sockaddr_storage address;
169
 
  int family;
170
 
  int port;
171
 
  char ip[INET6_ADDRSTRLEN];
172
174
 
173
 
  UNWRAP
 
175
  UNWRAP(TCPWrap)
174
176
 
175
177
  int addrlen = sizeof(address);
176
178
  int r = uv_tcp_getsockname(&wrap->handle_,
177
179
                             reinterpret_cast<sockaddr*>(&address),
178
180
                             &addrlen);
179
181
 
180
 
  Local<Object> sockname = Object::New();
181
 
  if (r != 0) {
 
182
  if (r) {
182
183
    SetErrno(uv_last_error(uv_default_loop()));
183
 
  } else {
184
 
    family = address.ss_family;
185
 
 
186
 
    if (family == AF_INET) {
187
 
      struct sockaddr_in* addrin = (struct sockaddr_in*)&address;
188
 
      uv_inet_ntop(AF_INET, &(addrin->sin_addr), ip, INET6_ADDRSTRLEN);
189
 
      port = ntohs(addrin->sin_port);
190
 
    } else if (family == AF_INET6) {
191
 
      struct sockaddr_in6* addrin6 = (struct sockaddr_in6*)&address;
192
 
      uv_inet_ntop(AF_INET6, &(addrin6->sin6_addr), ip, INET6_ADDRSTRLEN);
193
 
      port = ntohs(addrin6->sin6_port);
194
 
    } else {
195
 
      assert(0 && "bad address family");
196
 
      abort();
197
 
    }
198
 
 
199
 
    sockname->Set(port_symbol, Integer::New(port));
200
 
    sockname->Set(family_symbol, Integer::New(family));
201
 
    sockname->Set(address_symbol, String::New(ip));
 
184
    return Null();
202
185
  }
203
186
 
204
 
  return scope.Close(sockname);
 
187
  const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
 
188
  return scope.Close(AddressToJS(addr));
205
189
}
206
190
 
207
191
 
208
192
Handle<Value> TCPWrap::GetPeerName(const Arguments& args) {
209
193
  HandleScope scope;
210
194
  struct sockaddr_storage address;
211
 
  int family;
212
 
  int port;
213
 
  char ip[INET6_ADDRSTRLEN];
214
195
 
215
 
  UNWRAP
 
196
  UNWRAP(TCPWrap)
216
197
 
217
198
  int addrlen = sizeof(address);
218
199
  int r = uv_tcp_getpeername(&wrap->handle_,
219
200
                             reinterpret_cast<sockaddr*>(&address),
220
201
                             &addrlen);
221
202
 
222
 
  Local<Object> sockname = Object::New();
223
 
  if (r != 0) {
 
203
  if (r) {
224
204
    SetErrno(uv_last_error(uv_default_loop()));
225
 
  } else {
226
 
    family = address.ss_family;
227
 
 
228
 
    if (family == AF_INET) {
229
 
      struct sockaddr_in* addrin = (struct sockaddr_in*)&address;
230
 
      uv_inet_ntop(AF_INET, &(addrin->sin_addr), ip, INET6_ADDRSTRLEN);
231
 
      port = ntohs(addrin->sin_port);
232
 
    } else if (family == AF_INET6) {
233
 
      struct sockaddr_in6* addrin6 = (struct sockaddr_in6*)&address;
234
 
      uv_inet_ntop(AF_INET6, &(addrin6->sin6_addr), ip, INET6_ADDRSTRLEN);
235
 
      port = ntohs(addrin6->sin6_port);
236
 
    } else {
237
 
      assert(0 && "bad address family");
238
 
      abort();
239
 
    }
240
 
 
241
 
    sockname->Set(port_symbol, Integer::New(port));
242
 
    sockname->Set(family_symbol, Integer::New(family));
243
 
    sockname->Set(address_symbol, String::New(ip));
 
205
    return Null();
244
206
  }
245
207
 
246
 
  return scope.Close(sockname);
 
208
  const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
 
209
  return scope.Close(AddressToJS(addr));
247
210
}
248
211
 
249
212
 
250
213
Handle<Value> TCPWrap::SetNoDelay(const Arguments& args) {
251
214
  HandleScope scope;
252
215
 
253
 
  UNWRAP
 
216
  UNWRAP(TCPWrap)
254
217
 
255
 
  int r = uv_tcp_nodelay(&wrap->handle_, 1);
 
218
  int enable = static_cast<int>(args[0]->BooleanValue());
 
219
  int r = uv_tcp_nodelay(&wrap->handle_, enable);
256
220
  if (r)
257
221
    SetErrno(uv_last_error(uv_default_loop()));
258
222
 
263
227
Handle<Value> TCPWrap::SetKeepAlive(const Arguments& args) {
264
228
  HandleScope scope;
265
229
 
266
 
  UNWRAP
 
230
  UNWRAP(TCPWrap)
267
231
 
268
232
  int enable = args[0]->Int32Value();
269
233
  unsigned int delay = args[1]->Uint32Value();
280
244
Handle<Value> TCPWrap::SetSimultaneousAccepts(const Arguments& args) {
281
245
  HandleScope scope;
282
246
 
283
 
  UNWRAP
 
247
  UNWRAP(TCPWrap)
284
248
 
285
249
  bool enable = args[0]->BooleanValue();
286
250
 
293
257
#endif
294
258
 
295
259
 
 
260
Handle<Value> TCPWrap::Open(const Arguments& args) {
 
261
  HandleScope scope;
 
262
  UNWRAP(TCPWrap)
 
263
  int fd = args[0]->IntegerValue();
 
264
  uv_tcp_open(&wrap->handle_, fd);
 
265
  return Null();
 
266
}
 
267
 
 
268
 
296
269
Handle<Value> TCPWrap::Bind(const Arguments& args) {
297
270
  HandleScope scope;
298
271
 
299
 
  UNWRAP
 
272
  UNWRAP(TCPWrap)
300
273
 
301
 
  String::AsciiValue ip_address(args[0]->ToString());
 
274
  String::AsciiValue ip_address(args[0]);
302
275
  int port = args[1]->Int32Value();
303
276
 
304
277
  struct sockaddr_in address = uv_ip4_addr(*ip_address, port);
314
287
Handle<Value> TCPWrap::Bind6(const Arguments& args) {
315
288
  HandleScope scope;
316
289
 
317
 
  UNWRAP
 
290
  UNWRAP(TCPWrap)
318
291
 
319
 
  String::AsciiValue ip6_address(args[0]->ToString());
 
292
  String::AsciiValue ip6_address(args[0]);
320
293
  int port = args[1]->Int32Value();
321
294
 
322
295
  struct sockaddr_in6 address = uv_ip6_addr(*ip6_address, port);
332
305
Handle<Value> TCPWrap::Listen(const Arguments& args) {
333
306
  HandleScope scope;
334
307
 
335
 
  UNWRAP
 
308
  UNWRAP(TCPWrap)
336
309
 
337
310
  int backlog = args[0]->Int32Value();
338
311
 
355
328
  // uv_close() on the handle.
356
329
  assert(wrap->object_.IsEmpty() == false);
357
330
 
358
 
  Handle<Value> argv[1];
 
331
  Local<Value> argv[1];
359
332
 
360
333
  if (status == 0) {
361
334
    // Instantiate the client javascript object and handle.
363
336
 
364
337
    // Unwrap the client javascript object.
365
338
    assert(client_obj->InternalFieldCount() > 0);
366
 
    TCPWrap* client_wrap =
367
 
        static_cast<TCPWrap*>(client_obj->GetPointerFromInternalField(0));
 
339
    TCPWrap* client_wrap = static_cast<TCPWrap*>(
 
340
        client_obj->GetPointerFromInternalField(0));
368
341
 
369
342
    if (uv_accept(handle, (uv_stream_t*)&client_wrap->handle_)) return;
370
343
 
372
345
    argv[0] = client_obj;
373
346
  } else {
374
347
    SetErrno(uv_last_error(uv_default_loop()));
375
 
    argv[0] = v8::Null();
 
348
    argv[0] = Local<Value>::New(Null());
376
349
  }
377
350
 
378
 
  MakeCallback(wrap->object_, "onconnection", 1, argv);
 
351
  MakeCallback(wrap->object_, onconnection_sym, ARRAY_SIZE(argv), argv);
379
352
}
380
353
 
381
354
 
401
374
    Local<Value>::New(v8::True())
402
375
  };
403
376
 
404
 
  MakeCallback(req_wrap->object_, "oncomplete", 5, argv);
 
377
  MakeCallback(req_wrap->object_, oncomplete_sym, ARRAY_SIZE(argv), argv);
405
378
 
406
379
  delete req_wrap;
407
380
}
410
383
Handle<Value> TCPWrap::Connect(const Arguments& args) {
411
384
  HandleScope scope;
412
385
 
413
 
  UNWRAP
 
386
  UNWRAP(TCPWrap)
414
387
 
415
 
  String::AsciiValue ip_address(args[0]->ToString());
 
388
  String::AsciiValue ip_address(args[0]);
416
389
  int port = args[1]->Int32Value();
417
390
 
418
391
  struct sockaddr_in address = uv_ip4_addr(*ip_address, port);
440
413
Handle<Value> TCPWrap::Connect6(const Arguments& args) {
441
414
  HandleScope scope;
442
415
 
443
 
  UNWRAP
 
416
  UNWRAP(TCPWrap)
444
417
 
445
 
  String::AsciiValue ip_address(args[0]->ToString());
 
418
  String::AsciiValue ip_address(args[0]);
446
419
  int port = args[1]->Int32Value();
447
420
 
448
421
  struct sockaddr_in6 address = uv_ip6_addr(*ip_address, port);
464
437
}
465
438
 
466
439
 
 
440
// also used by udp_wrap.cc
 
441
Local<Object> AddressToJS(const sockaddr* addr) {
 
442
  static Persistent<String> address_sym;
 
443
  static Persistent<String> family_sym;
 
444
  static Persistent<String> port_sym;
 
445
  static Persistent<String> ipv4_sym;
 
446
  static Persistent<String> ipv6_sym;
 
447
 
 
448
  HandleScope scope;
 
449
  char ip[INET6_ADDRSTRLEN];
 
450
  const sockaddr_in *a4;
 
451
  const sockaddr_in6 *a6;
 
452
  int port;
 
453
 
 
454
  if (address_sym.IsEmpty()) {
 
455
    address_sym = NODE_PSYMBOL("address");
 
456
    family_sym = NODE_PSYMBOL("family");
 
457
    port_sym = NODE_PSYMBOL("port");
 
458
    ipv4_sym = NODE_PSYMBOL("IPv4");
 
459
    ipv6_sym = NODE_PSYMBOL("IPv6");
 
460
  }
 
461
 
 
462
  Local<Object> info = Object::New();
 
463
 
 
464
  switch (addr->sa_family) {
 
465
  case AF_INET6:
 
466
    a6 = reinterpret_cast<const sockaddr_in6*>(addr);
 
467
    uv_inet_ntop(AF_INET6, &a6->sin6_addr, ip, sizeof ip);
 
468
    port = ntohs(a6->sin6_port);
 
469
    info->Set(address_sym, String::New(ip));
 
470
    info->Set(family_sym, ipv6_sym);
 
471
    info->Set(port_sym, Integer::New(port));
 
472
    break;
 
473
 
 
474
  case AF_INET:
 
475
    a4 = reinterpret_cast<const sockaddr_in*>(addr);
 
476
    uv_inet_ntop(AF_INET, &a4->sin_addr, ip, sizeof ip);
 
477
    port = ntohs(a4->sin_port);
 
478
    info->Set(address_sym, String::New(ip));
 
479
    info->Set(family_sym, ipv4_sym);
 
480
    info->Set(port_sym, Integer::New(port));
 
481
    break;
 
482
 
 
483
  default:
 
484
    info->Set(address_sym, String::Empty());
 
485
  }
 
486
 
 
487
  return scope.Close(info);
 
488
}
 
489
 
 
490
 
467
491
}  // namespace node
468
492
 
469
493
NODE_MODULE(node_tcp_wrap, node::TCPWrap::Initialize)