GCC Code Coverage Report
Directory: ../src/ Exec Total Coverage
File: /home/node-core-coverage/node-core-coverage/workdir/node/src/cares_wrap.cc Lines: 379 690 54.9 %
Date: 2016-07-12 Branches: 122 512 23.8 %

Line Exec Source
1
#define CARES_STATICLIB
2
#include "ares.h"
3
#include "async-wrap.h"
4
#include "async-wrap-inl.h"
5
#include "env.h"
6
#include "env-inl.h"
7
#include "node.h"
8
#include "req-wrap.h"
9
#include "req-wrap-inl.h"
10
#include "tree.h"
11
#include "util.h"
12
#include "util-inl.h"
13
#include "uv.h"
14
15
#include <errno.h>
16
#include <stdlib.h>
17
#include <string.h>
18
19
#if defined(__ANDROID__) || \
20
    defined(__MINGW32__) || \
21
    defined(__OpenBSD__) || \
22
    defined(_MSC_VER)
23
24
# include <nameser.h>
25
#else
26
# include <arpa/nameser.h>
27
#endif
28
29
#if defined(__OpenBSD__)
30
# define AI_V4MAPPED 0
31
#endif
32
33
namespace node {
34
namespace cares_wrap {
35
36
using v8::Array;
37
using v8::Context;
38
using v8::EscapableHandleScope;
39
using v8::Function;
40
using v8::FunctionCallbackInfo;
41
using v8::FunctionTemplate;
42
using v8::HandleScope;
43
using v8::Integer;
44
using v8::Local;
45
using v8::Null;
46
using v8::Object;
47
using v8::String;
48
using v8::Value;
49
50
51
1914
class GetAddrInfoReqWrap : public ReqWrap<uv_getaddrinfo_t> {
52
 public:
53
  GetAddrInfoReqWrap(Environment* env, Local<Object> req_wrap_obj);
54
55
  size_t self_size() const override { return sizeof(*this); }
56
};
57
58
1915
GetAddrInfoReqWrap::GetAddrInfoReqWrap(Environment* env,
59
                                       Local<Object> req_wrap_obj)
60
1915
    : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETADDRINFOREQWRAP) {
61
1915
  Wrap(req_wrap_obj, this);
62
1915
}
63
64
65
1916
static void NewGetAddrInfoReqWrap(const FunctionCallbackInfo<Value>& args) {
66
1916
  CHECK(args.IsConstructCall());
67
1916
}
68
69
70
3
class GetNameInfoReqWrap : public ReqWrap<uv_getnameinfo_t> {
71
 public:
72
  GetNameInfoReqWrap(Environment* env, Local<Object> req_wrap_obj);
73
74
  size_t self_size() const override { return sizeof(*this); }
75
};
76
77
3
GetNameInfoReqWrap::GetNameInfoReqWrap(Environment* env,
78
                                       Local<Object> req_wrap_obj)
79
3
    : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETNAMEINFOREQWRAP) {
80
3
  Wrap(req_wrap_obj, this);
81
3
}
82
83
84
3
static void NewGetNameInfoReqWrap(const FunctionCallbackInfo<Value>& args) {
85
3
  CHECK(args.IsConstructCall());
86
3
}
87
88
89
3
static void NewQueryReqWrap(const FunctionCallbackInfo<Value>& args) {
90
3
  CHECK(args.IsConstructCall());
91
3
}
92
93
94
static int cmp_ares_tasks(const node_ares_task* a, const node_ares_task* b) {
95
2
  if (a->sock < b->sock)
96
    return -1;
97
2
  if (a->sock > b->sock)
98
    return 1;
99
  return 0;
100
}
101
102
103
14
RB_GENERATE_STATIC(node_ares_task_list, node_ares_task, node, cmp_ares_tasks)
104
105
106
107
/* This is called once per second by loop->timer. It is used to constantly */
108
/* call back into c-ares for possibly processing timeouts. */
109
static void ares_timeout(uv_timer_t* handle) {
110
  Environment* env = Environment::from_cares_timer_handle(handle);
111
  CHECK_EQ(false, RB_EMPTY(env->cares_task_list()));
112
  ares_process_fd(env->cares_channel(), ARES_SOCKET_BAD, ARES_SOCKET_BAD);
113
}
114
115
116
2
static void ares_poll_cb(uv_poll_t* watcher, int status, int events) {
117
2
  node_ares_task* task = ContainerOf(&node_ares_task::poll_watcher, watcher);
118
2
  Environment* env = task->env;
119
120
  /* Reset the idle timer */
121
2
  uv_timer_again(env->cares_timer_handle());
122
123
2
  if (status < 0) {
124
    /* An error happened. Just pretend that the socket is both readable and */
125
    /* writable. */
126
    ares_process_fd(env->cares_channel(), task->sock, task->sock);
127
    return;
128
  }
129
130
  /* Process DNS responses */
131
4
  ares_process_fd(env->cares_channel(),
132
2
                  events & UV_READABLE ? task->sock : ARES_SOCKET_BAD,
133
4
                  events & UV_WRITABLE ? task->sock : ARES_SOCKET_BAD);
134
}
135
136
137
2
static void ares_poll_close_cb(uv_handle_t* watcher) {
138
2
  node_ares_task* task = ContainerOf(&node_ares_task::poll_watcher,
139
2
                                  reinterpret_cast<uv_poll_t*>(watcher));
140
2
  free(task);
141
2
}
142
143
144
/* Allocates and returns a new node_ares_task */
145
2
static node_ares_task* ares_task_create(Environment* env, ares_socket_t sock) {
146
2
  node_ares_task* task = static_cast<node_ares_task*>(malloc(sizeof(*task)));
147
148
2
  if (task == nullptr) {
149
    /* Out of memory. */
150
    return nullptr;
151
  }
152
153
2
  task->env = env;
154
2
  task->sock = sock;
155
156
4
  if (uv_poll_init_socket(env->event_loop(), &task->poll_watcher, sock) < 0) {
157
    /* This should never happen. */
158
    free(task);
159
    return nullptr;
160
  }
161
162
  return task;
163
}
164
165
166
/* Callback from ares when socket operation is started */
167
4
static void ares_sockstate_cb(void* data,
168
                              ares_socket_t sock,
169
                              int read,
170
                              int write) {
171
4
  Environment* env = static_cast<Environment*>(data);
172
  node_ares_task* task;
173
174
  node_ares_task lookup_task;
175
4
  lookup_task.sock = sock;
176
8
  task = RB_FIND(node_ares_task_list, env->cares_task_list(), &lookup_task);
177
178
4
  if (read || write) {
179
2
    if (!task) {
180
      /* New socket */
181
182
      /* If this is the first socket then start the timer. */
183
2
      uv_timer_t* timer_handle = env->cares_timer_handle();
184
2
      if (!uv_is_active(reinterpret_cast<uv_handle_t*>(timer_handle))) {
185
2
        CHECK(RB_EMPTY(env->cares_task_list()));
186
2
        uv_timer_start(timer_handle, ares_timeout, 1000, 1000);
187
      }
188
189
2
      task = ares_task_create(env, sock);
190
2
      if (task == nullptr) {
191
        /* This should never happen unless we're out of memory or something */
192
        /* is seriously wrong. The socket won't be polled, but the the query */
193
        /* will eventually time out. */
194
        return;
195
      }
196
197
2
      RB_INSERT(node_ares_task_list, env->cares_task_list(), task);
198
    }
199
200
    /* This should never fail. If it fails anyway, the query will eventually */
201
    /* time out. */
202
2
    uv_poll_start(&task->poll_watcher,
203
                  (read ? UV_READABLE : 0) | (write ? UV_WRITABLE : 0),
204
2
                  ares_poll_cb);
205
206
  } else {
207
    /* read == 0 and write == 0 this is c-ares's way of notifying us that */
208
    /* the socket is now closed. We must free the data associated with */
209
    /* socket. */
210
2
    CHECK(task &&
211
          "When an ares socket is closed we should have a handle for it");
212
213
2
    RB_REMOVE(node_ares_task_list, env->cares_task_list(), task);
214
2
    uv_close(reinterpret_cast<uv_handle_t*>(&task->poll_watcher),
215
2
             ares_poll_close_cb);
216
217
2
    if (RB_EMPTY(env->cares_task_list())) {
218
2
      uv_timer_stop(env->cares_timer_handle());
219
    }
220
  }
221
}
222
223
224
1
static Local<Array> HostentToAddresses(Environment* env, struct hostent* host) {
225
2
  EscapableHandleScope scope(env->isolate());
226
1
  Local<Array> addresses = Array::New(env->isolate());
227
228
  char ip[INET6_ADDRSTRLEN];
229
2
  for (uint32_t i = 0; host->h_addr_list[i] != nullptr; ++i) {
230
1
    uv_inet_ntop(host->h_addrtype, host->h_addr_list[i], ip, sizeof(ip));
231
1
    Local<String> address = OneByteString(env->isolate(), ip);
232
2
    addresses->Set(i, address);
233
  }
234
235
2
  return scope.Escape(addresses);
236
}
237
238
239
1
static Local<Array> HostentToNames(Environment* env, struct hostent* host) {
240
2
  EscapableHandleScope scope(env->isolate());
241
1
  Local<Array> names = Array::New(env->isolate());
242
243
2
  for (uint32_t i = 0; host->h_aliases[i] != nullptr; ++i) {
244
1
    Local<String> address = OneByteString(env->isolate(), host->h_aliases[i]);
245
2
    names->Set(i, address);
246
  }
247
248
2
  return scope.Escape(names);
249
}
250
251
252
class QueryWrap : public AsyncWrap {
253
 public:
254
3
  QueryWrap(Environment* env, Local<Object> req_wrap_obj)
255
3
      : AsyncWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_QUERYWRAP) {
256
3
    if (env->in_domain())
257
      req_wrap_obj->Set(env->domain_string(), env->domain_array()->Get(0));
258
3
  }
259
260
6
  ~QueryWrap() override {
261
6
    CHECK_EQ(false, persistent().IsEmpty());
262
6
    ClearWrap(object());
263
6
    persistent().Reset();
264
3
  }
265
266
  // Subclasses should implement the appropriate Send method.
267
  virtual int Send(const char* name) {
268
    UNREACHABLE();
269
    return 0;
270
  }
271
272
  virtual int Send(const char* name, int family) {
273
    UNREACHABLE();
274
    return 0;
275
  }
276
277
 protected:
278
  void* GetQueryArg() {
279
    return static_cast<void*>(this);
280
  }
281
282
2
  static void Callback(void *arg, int status, int timeouts,
283
      unsigned char* answer_buf, int answer_len) {
284
2
    QueryWrap* wrap = static_cast<QueryWrap*>(arg);
285
286
2
    if (status != ARES_SUCCESS) {
287
1
      wrap->ParseError(status);
288
    } else {
289
1
      wrap->Parse(answer_buf, answer_len);
290
    }
291
292
2
    delete wrap;
293
2
  }
294
295
1
  static void Callback(void *arg, int status, int timeouts,
296
      struct hostent* host) {
297
1
    QueryWrap* wrap = static_cast<QueryWrap*>(arg);
298
299
1
    if (status != ARES_SUCCESS) {
300
      wrap->ParseError(status);
301
    } else {
302
1
      wrap->Parse(host);
303
    }
304
305
1
    delete wrap;
306
1
  }
307
308
2
  void CallOnComplete(Local<Value> answer) {
309
4
    HandleScope handle_scope(env()->isolate());
310
8
    Context::Scope context_scope(env()->context());
311
    Local<Value> argv[] = {
312
      Integer::New(env()->isolate(), 0),
313
      answer
314
4
    };
315
4
    MakeCallback(env()->oncomplete_string(), arraysize(argv), argv);
316
2
  }
317
318
  void CallOnComplete(Local<Value> answer, Local<Value> family) {
319
    HandleScope handle_scope(env()->isolate());
320
    Context::Scope context_scope(env()->context());
321
    Local<Value> argv[] = {
322
      Integer::New(env()->isolate(), 0),
323
      answer,
324
      family
325
    };
326
    MakeCallback(env()->oncomplete_string(), arraysize(argv), argv);
327
  }
328
329
1
  void ParseError(int status) {
330
1
    CHECK_NE(status, ARES_SUCCESS);
331
2
    HandleScope handle_scope(env()->isolate());
332
4
    Context::Scope context_scope(env()->context());
333
1
    Local<Value> arg;
334
1
    switch (status) {
335
#define V(code)                                                               \
336
      case ARES_ ## code:                                                     \
337
        arg = FIXED_ONE_BYTE_STRING(env()->isolate(), #code);                 \
338
        break;
339
      V(ENODATA)
340
      V(EFORMERR)
341
      V(ESERVFAIL)
342
2
      V(ENOTFOUND)
343
      V(ENOTIMP)
344
      V(EREFUSED)
345
      V(EBADQUERY)
346
      V(EBADNAME)
347
      V(EBADFAMILY)
348
      V(EBADRESP)
349
      V(ECONNREFUSED)
350
      V(ETIMEOUT)
351
      V(EOF)
352
      V(EFILE)
353
      V(ENOMEM)
354
      V(EDESTRUCTION)
355
      V(EBADSTR)
356
      V(EBADFLAGS)
357
      V(ENONAME)
358
      V(EBADHINTS)
359
      V(ENOTINITIALIZED)
360
      V(ELOADIPHLPAPI)
361
      V(EADDRGETNETWORKPARAMS)
362
      V(ECANCELLED)
363
#undef V
364
      default:
365
        arg = FIXED_ONE_BYTE_STRING(env()->isolate(), "UNKNOWN_ARES_ERROR");
366
        break;
367
    }
368
2
    MakeCallback(env()->oncomplete_string(), 1, &arg);
369
1
  }
370
371
  // Subclasses should implement the appropriate Parse method.
372
  virtual void Parse(unsigned char* buf, int len) {
373
    UNREACHABLE();
374
  }
375
376
  virtual void Parse(struct hostent* host) {
377
    UNREACHABLE();
378
  }
379
};
380
381
382
2
class QueryAWrap: public QueryWrap {
383
 public:
384
  QueryAWrap(Environment* env, Local<Object> req_wrap_obj)
385
2
      : QueryWrap(env, req_wrap_obj) {
386
  }
387
388
2
  int Send(const char* name) override {
389
2
    ares_query(env()->cares_channel(),
390
               name,
391
               ns_c_in,
392
               ns_t_a,
393
               Callback,
394
2
               GetQueryArg());
395
2
    return 0;
396
  }
397
398
  size_t self_size() const override { return sizeof(*this); }
399
400
 protected:
401
1
  void Parse(unsigned char* buf, int len) override {
402
2
    HandleScope handle_scope(env()->isolate());
403
4
    Context::Scope context_scope(env()->context());
404
405
    struct hostent* host;
406
407
1
    int status = ares_parse_a_reply(buf, len, &host, nullptr, nullptr);
408
1
    if (status != ARES_SUCCESS) {
409
      ParseError(status);
410
      return;
411
    }
412
413
1
    Local<Array> addresses = HostentToAddresses(env(), host);
414
1
    ares_free_hostent(host);
415
416
1
    this->CallOnComplete(addresses);
417
  }
418
};
419
420
421
class QueryAaaaWrap: public QueryWrap {
422
 public:
423
  QueryAaaaWrap(Environment* env, Local<Object> req_wrap_obj)
424
      : QueryWrap(env, req_wrap_obj) {
425
  }
426
427
  int Send(const char* name) override {
428
    ares_query(env()->cares_channel(),
429
               name,
430
               ns_c_in,
431
               ns_t_aaaa,
432
               Callback,
433
               GetQueryArg());
434
    return 0;
435
  }
436
437
  size_t self_size() const override { return sizeof(*this); }
438
439
 protected:
440
  void Parse(unsigned char* buf, int len) override {
441
    HandleScope handle_scope(env()->isolate());
442
    Context::Scope context_scope(env()->context());
443
444
    struct hostent* host;
445
446
    int status = ares_parse_aaaa_reply(buf, len, &host, nullptr, nullptr);
447
    if (status != ARES_SUCCESS) {
448
      ParseError(status);
449
      return;
450
    }
451
452
    Local<Array> addresses = HostentToAddresses(env(), host);
453
    ares_free_hostent(host);
454
455
    this->CallOnComplete(addresses);
456
  }
457
};
458
459
460
class QueryCnameWrap: public QueryWrap {
461
 public:
462
  QueryCnameWrap(Environment* env, Local<Object> req_wrap_obj)
463
      : QueryWrap(env, req_wrap_obj) {
464
  }
465
466
  int Send(const char* name) override {
467
    ares_query(env()->cares_channel(),
468
               name,
469
               ns_c_in,
470
               ns_t_cname,
471
               Callback,
472
               GetQueryArg());
473
    return 0;
474
  }
475
476
  size_t self_size() const override { return sizeof(*this); }
477
478
 protected:
479
  void Parse(unsigned char* buf, int len) override {
480
    HandleScope handle_scope(env()->isolate());
481
    Context::Scope context_scope(env()->context());
482
    struct hostent* host;
483
484
    int status = ares_parse_a_reply(buf, len, &host, nullptr, nullptr);
485
    if (status != ARES_SUCCESS) {
486
      ParseError(status);
487
      return;
488
    }
489
490
    // A cname lookup always returns a single record but we follow the
491
    // common API here.
492
    Local<Array> result = Array::New(env()->isolate(), 1);
493
    result->Set(0, OneByteString(env()->isolate(), host->h_name));
494
    ares_free_hostent(host);
495
496
    this->CallOnComplete(result);
497
  }
498
};
499
500
501
class QueryMxWrap: public QueryWrap {
502
 public:
503
  QueryMxWrap(Environment* env, Local<Object> req_wrap_obj)
504
      : QueryWrap(env, req_wrap_obj) {
505
  }
506
507
  int Send(const char* name) override {
508
    ares_query(env()->cares_channel(),
509
               name,
510
               ns_c_in,
511
               ns_t_mx,
512
               Callback,
513
               GetQueryArg());
514
    return 0;
515
  }
516
517
  size_t self_size() const override { return sizeof(*this); }
518
519
 protected:
520
  void Parse(unsigned char* buf, int len) override {
521
    HandleScope handle_scope(env()->isolate());
522
    Context::Scope context_scope(env()->context());
523
524
    struct ares_mx_reply* mx_start;
525
    int status = ares_parse_mx_reply(buf, len, &mx_start);
526
    if (status != ARES_SUCCESS) {
527
      ParseError(status);
528
      return;
529
    }
530
531
    Local<Array> mx_records = Array::New(env()->isolate());
532
    Local<String> exchange_symbol = env()->exchange_string();
533
    Local<String> priority_symbol = env()->priority_string();
534
535
    ares_mx_reply* current = mx_start;
536
    for (uint32_t i = 0; current != nullptr; ++i, current = current->next) {
537
      Local<Object> mx_record = Object::New(env()->isolate());
538
      mx_record->Set(exchange_symbol,
539
                     OneByteString(env()->isolate(), current->host));
540
      mx_record->Set(priority_symbol,
541
                     Integer::New(env()->isolate(), current->priority));
542
      mx_records->Set(i, mx_record);
543
    }
544
545
    ares_free_data(mx_start);
546
547
    this->CallOnComplete(mx_records);
548
  }
549
};
550
551
552
class QueryNsWrap: public QueryWrap {
553
 public:
554
  QueryNsWrap(Environment* env, Local<Object> req_wrap_obj)
555
      : QueryWrap(env, req_wrap_obj) {
556
  }
557
558
  int Send(const char* name) override {
559
    ares_query(env()->cares_channel(),
560
               name,
561
               ns_c_in,
562
               ns_t_ns,
563
               Callback,
564
               GetQueryArg());
565
    return 0;
566
  }
567
568
  size_t self_size() const override { return sizeof(*this); }
569
570
 protected:
571
  void Parse(unsigned char* buf, int len) override {
572
    HandleScope handle_scope(env()->isolate());
573
    Context::Scope context_scope(env()->context());
574
    struct hostent* host;
575
576
    int status = ares_parse_ns_reply(buf, len, &host);
577
    if (status != ARES_SUCCESS) {
578
      ParseError(status);
579
      return;
580
    }
581
582
    Local<Array> names = HostentToNames(env(), host);
583
    ares_free_hostent(host);
584
585
    this->CallOnComplete(names);
586
  }
587
};
588
589
590
class QueryTxtWrap: public QueryWrap {
591
 public:
592
  QueryTxtWrap(Environment* env, Local<Object> req_wrap_obj)
593
      : QueryWrap(env, req_wrap_obj) {
594
  }
595
596
  int Send(const char* name) override {
597
    ares_query(env()->cares_channel(),
598
               name,
599
               ns_c_in,
600
               ns_t_txt,
601
               Callback,
602
               GetQueryArg());
603
    return 0;
604
  }
605
606
  size_t self_size() const override { return sizeof(*this); }
607
608
 protected:
609
  void Parse(unsigned char* buf, int len) override {
610
    HandleScope handle_scope(env()->isolate());
611
    Context::Scope context_scope(env()->context());
612
    struct ares_txt_ext* txt_out;
613
614
    int status = ares_parse_txt_reply_ext(buf, len, &txt_out);
615
    if (status != ARES_SUCCESS) {
616
      ParseError(status);
617
      return;
618
    }
619
620
    Local<Array> txt_records = Array::New(env()->isolate());
621
    Local<Array> txt_chunk;
622
623
    struct ares_txt_ext* current = txt_out;
624
    uint32_t i = 0;
625
    for (uint32_t j = 0; current != nullptr; current = current->next) {
626
      Local<String> txt = OneByteString(env()->isolate(), current->txt);
627
      // New record found - write out the current chunk
628
      if (current->record_start) {
629
        if (!txt_chunk.IsEmpty())
630
          txt_records->Set(i++, txt_chunk);
631
        txt_chunk = Array::New(env()->isolate());
632
        j = 0;
633
      }
634
      txt_chunk->Set(j++, txt);
635
    }
636
    // Push last chunk if it isn't empty
637
    if (!txt_chunk.IsEmpty())
638
      txt_records->Set(i, txt_chunk);
639
640
    ares_free_data(txt_out);
641
642
    this->CallOnComplete(txt_records);
643
  }
644
};
645
646
647
class QuerySrvWrap: public QueryWrap {
648
 public:
649
  explicit QuerySrvWrap(Environment* env, Local<Object> req_wrap_obj)
650
      : QueryWrap(env, req_wrap_obj) {
651
  }
652
653
  int Send(const char* name) override {
654
    ares_query(env()->cares_channel(),
655
               name,
656
               ns_c_in,
657
               ns_t_srv,
658
               Callback,
659
               GetQueryArg());
660
    return 0;
661
  }
662
663
  size_t self_size() const override { return sizeof(*this); }
664
665
 protected:
666
  void Parse(unsigned char* buf, int len) override {
667
    HandleScope handle_scope(env()->isolate());
668
    Context::Scope context_scope(env()->context());
669
670
    struct ares_srv_reply* srv_start;
671
    int status = ares_parse_srv_reply(buf, len, &srv_start);
672
    if (status != ARES_SUCCESS) {
673
      ParseError(status);
674
      return;
675
    }
676
677
    Local<Array> srv_records = Array::New(env()->isolate());
678
    Local<String> name_symbol = env()->name_string();
679
    Local<String> port_symbol = env()->port_string();
680
    Local<String> priority_symbol = env()->priority_string();
681
    Local<String> weight_symbol = env()->weight_string();
682
683
    ares_srv_reply* current = srv_start;
684
    for (uint32_t i = 0; current != nullptr; ++i, current = current->next) {
685
      Local<Object> srv_record = Object::New(env()->isolate());
686
      srv_record->Set(name_symbol,
687
                      OneByteString(env()->isolate(), current->host));
688
      srv_record->Set(port_symbol,
689
                      Integer::New(env()->isolate(), current->port));
690
      srv_record->Set(priority_symbol,
691
                      Integer::New(env()->isolate(), current->priority));
692
      srv_record->Set(weight_symbol,
693
                      Integer::New(env()->isolate(), current->weight));
694
      srv_records->Set(i, srv_record);
695
    }
696
697
    ares_free_data(srv_start);
698
699
    this->CallOnComplete(srv_records);
700
  }
701
};
702
703
class QueryPtrWrap: public QueryWrap {
704
 public:
705
  explicit QueryPtrWrap(Environment* env, Local<Object> req_wrap_obj)
706
      : QueryWrap(env, req_wrap_obj) {
707
  }
708
709
  int Send(const char* name) override {
710
    ares_query(env()->cares_channel(),
711
               name,
712
               ns_c_in,
713
               ns_t_ptr,
714
               Callback,
715
               GetQueryArg());
716
    return 0;
717
  }
718
719
  size_t self_size() const override { return sizeof(*this); }
720
721
 protected:
722
  void Parse(unsigned char* buf, int len) override {
723
    HandleScope handle_scope(env()->isolate());
724
    Context::Scope context_scope(env()->context());
725
726
    struct hostent* host;
727
728
    int status = ares_parse_ptr_reply(buf, len, NULL, 0, AF_INET, &host);
729
    if (status != ARES_SUCCESS) {
730
      ParseError(status);
731
      return;
732
    }
733
734
    Local<Array> aliases = Array::New(env()->isolate());
735
736
    for (uint32_t i = 0; host->h_aliases[i] != NULL; i++) {
737
      aliases->Set(i, OneByteString(env()->isolate(), host->h_aliases[i]));
738
    }
739
740
    ares_free_hostent(host);
741
742
    this->CallOnComplete(aliases);
743
  }
744
};
745
746
class QueryNaptrWrap: public QueryWrap {
747
 public:
748
  explicit QueryNaptrWrap(Environment* env, Local<Object> req_wrap_obj)
749
      : QueryWrap(env, req_wrap_obj) {
750
  }
751
752
  int Send(const char* name) override {
753
    ares_query(env()->cares_channel(),
754
               name,
755
               ns_c_in,
756
               ns_t_naptr,
757
               Callback,
758
               GetQueryArg());
759
    return 0;
760
  }
761
762
  size_t self_size() const override { return sizeof(*this); }
763
764
 protected:
765
  void Parse(unsigned char* buf, int len) override {
766
    HandleScope handle_scope(env()->isolate());
767
    Context::Scope context_scope(env()->context());
768
769
    ares_naptr_reply* naptr_start;
770
    int status = ares_parse_naptr_reply(buf, len, &naptr_start);
771
772
    if (status != ARES_SUCCESS) {
773
      ParseError(status);
774
      return;
775
    }
776
777
    Local<Array> naptr_records = Array::New(env()->isolate());
778
    Local<String> flags_symbol = env()->flags_string();
779
    Local<String> service_symbol = env()->service_string();
780
    Local<String> regexp_symbol = env()->regexp_string();
781
    Local<String> replacement_symbol = env()->replacement_string();
782
    Local<String> order_symbol = env()->order_string();
783
    Local<String> preference_symbol = env()->preference_string();
784
785
    ares_naptr_reply* current = naptr_start;
786
    for (uint32_t i = 0; current != nullptr; ++i, current = current->next) {
787
      Local<Object> naptr_record = Object::New(env()->isolate());
788
      naptr_record->Set(flags_symbol,
789
                        OneByteString(env()->isolate(), current->flags));
790
      naptr_record->Set(service_symbol,
791
                        OneByteString(env()->isolate(), current->service));
792
      naptr_record->Set(regexp_symbol,
793
                        OneByteString(env()->isolate(), current->regexp));
794
      naptr_record->Set(replacement_symbol,
795
                        OneByteString(env()->isolate(), current->replacement));
796
      naptr_record->Set(order_symbol,
797
                        Integer::New(env()->isolate(), current->order));
798
      naptr_record->Set(preference_symbol,
799
                        Integer::New(env()->isolate(), current->preference));
800
      naptr_records->Set(i, naptr_record);
801
    }
802
803
    ares_free_data(naptr_start);
804
805
    this->CallOnComplete(naptr_records);
806
  }
807
};
808
809
810
class QuerySoaWrap: public QueryWrap {
811
 public:
812
  QuerySoaWrap(Environment* env, Local<Object> req_wrap_obj)
813
      : QueryWrap(env, req_wrap_obj) {
814
  }
815
816
  int Send(const char* name) override {
817
    ares_query(env()->cares_channel(),
818
               name,
819
               ns_c_in,
820
               ns_t_soa,
821
               Callback,
822
               GetQueryArg());
823
    return 0;
824
  }
825
826
  size_t self_size() const override { return sizeof(*this); }
827
828
 protected:
829
  void Parse(unsigned char* buf, int len) override {
830
    HandleScope handle_scope(env()->isolate());
831
    Context::Scope context_scope(env()->context());
832
833
    ares_soa_reply* soa_out;
834
    int status = ares_parse_soa_reply(buf, len, &soa_out);
835
836
    if (status != ARES_SUCCESS) {
837
      ParseError(status);
838
      return;
839
    }
840
841
    Local<Object> soa_record = Object::New(env()->isolate());
842
843
    soa_record->Set(env()->nsname_string(),
844
                    OneByteString(env()->isolate(), soa_out->nsname));
845
    soa_record->Set(env()->hostmaster_string(),
846
                    OneByteString(env()->isolate(), soa_out->hostmaster));
847
    soa_record->Set(env()->serial_string(),
848
                    Integer::New(env()->isolate(), soa_out->serial));
849
    soa_record->Set(env()->refresh_string(),
850
                    Integer::New(env()->isolate(), soa_out->refresh));
851
    soa_record->Set(env()->retry_string(),
852
                    Integer::New(env()->isolate(), soa_out->retry));
853
    soa_record->Set(env()->expire_string(),
854
                    Integer::New(env()->isolate(), soa_out->expire));
855
    soa_record->Set(env()->minttl_string(),
856
                    Integer::New(env()->isolate(), soa_out->minttl));
857
858
    ares_free_data(soa_out);
859
860
    this->CallOnComplete(soa_record);
861
  }
862
};
863
864
865
1
class GetHostByAddrWrap: public QueryWrap {
866
 public:
867
  explicit GetHostByAddrWrap(Environment* env, Local<Object> req_wrap_obj)
868
1
      : QueryWrap(env, req_wrap_obj) {
869
  }
870
871
1
  int Send(const char* name) override {
872
    int length, family;
873
    char address_buffer[sizeof(struct in6_addr)];
874
875
1
    if (uv_inet_pton(AF_INET, name, &address_buffer) == 0) {
876
      length = sizeof(struct in_addr);
877
      family = AF_INET;
878
    } else if (uv_inet_pton(AF_INET6, name, &address_buffer) == 0) {
879
      length = sizeof(struct in6_addr);
880
      family = AF_INET6;
881
    } else {
882
      return UV_EINVAL;  // So errnoException() reports a proper error.
883
    }
884
885
1
    ares_gethostbyaddr(env()->cares_channel(),
886
                       address_buffer,
887
                       length,
888
                       family,
889
                       Callback,
890
1
                       GetQueryArg());
891
1
    return 0;
892
  }
893
894
  size_t self_size() const override { return sizeof(*this); }
895
896
 protected:
897
1
  void Parse(struct hostent* host) override {
898
2
    HandleScope handle_scope(env()->isolate());
899
4
    Context::Scope context_scope(env()->context());
900
2
    this->CallOnComplete(HostentToNames(env(), host));
901
1
  }
902
};
903
904
905
class GetHostByNameWrap: public QueryWrap {
906
 public:
907
  explicit GetHostByNameWrap(Environment* env, Local<Object> req_wrap_obj)
908
      : QueryWrap(env, req_wrap_obj) {
909
  }
910
911
  int Send(const char* name, int family) override {
912
    ares_gethostbyname(env()->cares_channel(),
913
                       name,
914
                       family,
915
                       Callback,
916
                       GetQueryArg());
917
    return 0;
918
  }
919
920
 protected:
921
  void Parse(struct hostent* host) override {
922
    HandleScope scope(env()->isolate());
923
924
    Local<Array> addresses = HostentToAddresses(env(), host);
925
    Local<Integer> family = Integer::New(env()->isolate(), host->h_addrtype);
926
927
    this->CallOnComplete(addresses, family);
928
  }
929
};
930
931
932
template <class Wrap>
933
3
static void Query(const FunctionCallbackInfo<Value>& args) {
934
3
  Environment* env = Environment::GetCurrent(args);
935
936
3
  CHECK_EQ(false, args.IsConstructCall());
937
3
  CHECK(args[0]->IsObject());
938
6
  CHECK(args[1]->IsString());
939
940
6
  Local<Object> req_wrap_obj = args[0].As<Object>();
941
6
  Local<String> string = args[1].As<String>();
942
6
  Wrap* wrap = new Wrap(env, req_wrap_obj);
943
944
6
  node::Utf8Value name(env->isolate(), string);
945
3
  int err = wrap->Send(*name);
946
3
  if (err)
947
    delete wrap;
948
949
6
  args.GetReturnValue().Set(err);
950
3
}
951
952
953
1914
void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
954
1914
  GetAddrInfoReqWrap* req_wrap = static_cast<GetAddrInfoReqWrap*>(req->data);
955
1914
  Environment* env = req_wrap->env();
956
957
3828
  HandleScope handle_scope(env->isolate());
958
5742
  Context::Scope context_scope(env->context());
959
960
  Local<Value> argv[] = {
961
    Integer::New(env->isolate(), status),
962
    Null(env->isolate())
963
7656
  };
964
965
1914
  if (status == 0) {
966
    // Success
967
    struct addrinfo *address;
968
1907
    int n = 0;
969
970
    // Create the response array.
971
1907
    Local<Array> results = Array::New(env->isolate());
972
973
    char ip[INET6_ADDRSTRLEN];
974
    const char *addr;
975
976
    // Iterate over the IPv4 responses again this time creating javascript
977
    // strings for each IP and filling the results array.
978
1907
    address = res;
979
3821
    while (address) {
980
1914
      CHECK_EQ(address->ai_socktype, SOCK_STREAM);
981
982
      // Ignore random ai_family types.
983
1914
      if (address->ai_family == AF_INET) {
984
        // Juggle pointers
985
        addr = reinterpret_cast<char*>(&(reinterpret_cast<struct sockaddr_in*>(
986
1906
            address->ai_addr)->sin_addr));
987
        int err = uv_inet_ntop(address->ai_family,
988
                               addr,
989
                               ip,
990
1906
                               INET6_ADDRSTRLEN);
991
1906
        if (err)
992
          continue;
993
994
        // Create JavaScript string
995
1906
        Local<String> s = OneByteString(env->isolate(), ip);
996
1906
        results->Set(n, s);
997
1906
        n++;
998
      }
999
1000
      // Increment
1001
1914
      address = address->ai_next;
1002
    }
1003
1004
    // Iterate over the IPv6 responses putting them in the array.
1005
    address = res;
1006
3821
    while (address) {
1007
1914
      CHECK_EQ(address->ai_socktype, SOCK_STREAM);
1008
1009
      // Ignore random ai_family types.
1010
1914
      if (address->ai_family == AF_INET6) {
1011
        // Juggle pointers
1012
        addr = reinterpret_cast<char*>(&(reinterpret_cast<struct sockaddr_in6*>(
1013
8
            address->ai_addr)->sin6_addr));
1014
        int err = uv_inet_ntop(address->ai_family,
1015
                               addr,
1016
                               ip,
1017
8
                               INET6_ADDRSTRLEN);
1018
8
        if (err)
1019
          continue;
1020
1021
        // Create JavaScript string
1022
8
        Local<String> s = OneByteString(env->isolate(), ip);
1023
8
        results->Set(n, s);
1024
8
        n++;
1025
      }
1026
1027
      // Increment
1028
1914
      address = address->ai_next;
1029
    }
1030
1031
    // No responses were found to return
1032
1907
    if (n == 0) {
1033
      argv[0] = Integer::New(env->isolate(), UV_EAI_NODATA);
1034
    }
1035
1036
1907
    argv[1] = results;
1037
  }
1038
1039
1914
  uv_freeaddrinfo(res);
1040
1041
  // Make the callback into JavaScript
1042
3828
  req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv);
1043
1044
1914
  delete req_wrap;
1045
1914
}
1046
1047
1048
3
void AfterGetNameInfo(uv_getnameinfo_t* req,
1049
                      int status,
1050
                      const char* hostname,
1051
                      const char* service) {
1052
3
  GetNameInfoReqWrap* req_wrap = static_cast<GetNameInfoReqWrap*>(req->data);
1053
3
  Environment* env = req_wrap->env();
1054
1055
6
  HandleScope handle_scope(env->isolate());
1056
9
  Context::Scope context_scope(env->context());
1057
1058
  Local<Value> argv[] = {
1059
    Integer::New(env->isolate(), status),
1060
    Null(env->isolate()),
1061
    Null(env->isolate())
1062
18
  };
1063
1064
3
  if (status == 0) {
1065
    // Success
1066
    Local<String> js_hostname = OneByteString(env->isolate(), hostname);
1067
    Local<String> js_service = OneByteString(env->isolate(), service);
1068
    argv[1] = js_hostname;
1069
    argv[2] = js_service;
1070
  }
1071
1072
  // Make the callback into JavaScript
1073
6
  req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv);
1074
1075
3
  delete req_wrap;
1076
3
}
1077
1078
1079
4824
static void IsIP(const FunctionCallbackInfo<Value>& args) {
1080
14472
  node::Utf8Value ip(args.GetIsolate(), args[0]);
1081
  char address_buffer[sizeof(struct in6_addr)];
1082
1083
4824
  int rc = 0;
1084
4824
  if (uv_inet_pton(AF_INET, *ip, &address_buffer) == 0)
1085
    rc = 4;
1086
3947
  else if (uv_inet_pton(AF_INET6, *ip, &address_buffer) == 0)
1087
45
    rc = 6;
1088
1089
9648
  args.GetReturnValue().Set(rc);
1090
4824
}
1091
1092
12
static void IsIPv4(const FunctionCallbackInfo<Value>& args) {
1093
36
  node::Utf8Value ip(args.GetIsolate(), args[0]);
1094
  char address_buffer[sizeof(struct in_addr)];
1095
1096
12
  if (uv_inet_pton(AF_INET, *ip, &address_buffer) == 0) {
1097
4
    args.GetReturnValue().Set(true);
1098
  } else {
1099
20
    args.GetReturnValue().Set(false);
1100
  }
1101
12
}
1102
1103
18
static void IsIPv6(const FunctionCallbackInfo<Value>& args) {
1104
54
  node::Utf8Value ip(args.GetIsolate(), args[0]);
1105
  char address_buffer[sizeof(struct in6_addr)];
1106
1107
18
  if (uv_inet_pton(AF_INET6, *ip, &address_buffer) == 0) {
1108
16
    args.GetReturnValue().Set(true);
1109
  } else {
1110
20
    args.GetReturnValue().Set(false);
1111
  }
1112
18
}
1113
1114
1915
static void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
1115
1915
  Environment* env = Environment::GetCurrent(args);
1116
1117
1915
  CHECK(args[0]->IsObject());
1118
3830
  CHECK(args[1]->IsString());
1119
1915
  CHECK(args[2]->IsInt32());
1120
3830
  Local<Object> req_wrap_obj = args[0].As<Object>();
1121
3830
  node::Utf8Value hostname(env->isolate(), args[1]);
1122
1123
3830
  int32_t flags = (args[3]->IsInt32()) ? args[3]->Int32Value() : 0;
1124
  int family;
1125
1126
1915
  switch (args[2]->Int32Value()) {
1127
  case 0:
1128
    family = AF_UNSPEC;
1129
    break;
1130
  case 4:
1131
5
    family = AF_INET;
1132
5
    break;
1133
  case 6:
1134
6
    family = AF_INET6;
1135
6
    break;
1136
  default:
1137
    CHECK(0 && "bad address family");
1138
    ABORT();
1139
  }
1140
1141
1915
  GetAddrInfoReqWrap* req_wrap = new GetAddrInfoReqWrap(env, req_wrap_obj);
1142
1143
  struct addrinfo hints;
1144
1915
  memset(&hints, 0, sizeof(struct addrinfo));
1145
1915
  hints.ai_family = family;
1146
1915
  hints.ai_socktype = SOCK_STREAM;
1147
1915
  hints.ai_flags = flags;
1148
1149
3830
  int err = uv_getaddrinfo(env->event_loop(),
1150
                           &req_wrap->req_,
1151
                           AfterGetAddrInfo,
1152
1915
                           *hostname,
1153
                           nullptr,
1154
1915
                           &hints);
1155
3830
  req_wrap->Dispatched();
1156
1915
  if (err)
1157
    delete req_wrap;
1158
1159
3830
  args.GetReturnValue().Set(err);
1160
1915
}
1161
1162
1163
3
static void GetNameInfo(const FunctionCallbackInfo<Value>& args) {
1164
3
  Environment* env = Environment::GetCurrent(args);
1165
1166
3
  CHECK(args[0]->IsObject());
1167
6
  CHECK(args[1]->IsString());
1168
3
  CHECK(args[2]->IsUint32());
1169
6
  Local<Object> req_wrap_obj = args[0].As<Object>();
1170
6
  node::Utf8Value ip(env->isolate(), args[1]);
1171
3
  const unsigned port = args[2]->Uint32Value();
1172
  struct sockaddr_storage addr;
1173
1174
3
  CHECK(uv_ip4_addr(*ip, port, reinterpret_cast<sockaddr_in*>(&addr)) == 0 ||
1175
        uv_ip6_addr(*ip, port, reinterpret_cast<sockaddr_in6*>(&addr)) == 0);
1176
1177
3
  GetNameInfoReqWrap* req_wrap = new GetNameInfoReqWrap(env, req_wrap_obj);
1178
1179
6
  int err = uv_getnameinfo(env->event_loop(),
1180
                           &req_wrap->req_,
1181
                           AfterGetNameInfo,
1182
                           (struct sockaddr*)&addr,
1183
3
                           NI_NAMEREQD);
1184
6
  req_wrap->Dispatched();
1185
3
  if (err)
1186
    delete req_wrap;
1187
1188
6
  args.GetReturnValue().Set(err);
1189
3
}
1190
1191
1192
13
static void GetServers(const FunctionCallbackInfo<Value>& args) {
1193
13
  Environment* env = Environment::GetCurrent(args);
1194
1195
13
  Local<Array> server_array = Array::New(env->isolate());
1196
1197
  ares_addr_node* servers;
1198
1199
13
  int r = ares_get_servers(env->cares_channel(), &servers);
1200
13
  CHECK_EQ(r, ARES_SUCCESS);
1201
1202
13
  ares_addr_node* cur = servers;
1203
1204
39
  for (uint32_t i = 0; cur != nullptr; ++i, cur = cur->next) {
1205
    char ip[INET6_ADDRSTRLEN];
1206
1207
26
    const void* caddr = static_cast<const void*>(&cur->addr);
1208
26
    int err = uv_inet_ntop(cur->family, caddr, ip, sizeof(ip));
1209
26
    CHECK_EQ(err, 0);
1210
1211
26
    Local<String> addr = OneByteString(env->isolate(), ip);
1212
52
    server_array->Set(i, addr);
1213
  }
1214
1215
13
  ares_free_data(servers);
1216
1217
26
  args.GetReturnValue().Set(server_array);
1218
13
}
1219
1220
1221
5
static void SetServers(const FunctionCallbackInfo<Value>& args) {
1222
5
  Environment* env = Environment::GetCurrent(args);
1223
1224
5
  CHECK(args[0]->IsArray());
1225
1226
10
  Local<Array> arr = Local<Array>::Cast(args[0]);
1227
1228
5
  uint32_t len = arr->Length();
1229
1230
5
  if (len == 0) {
1231
1
    int rv = ares_set_servers(env->cares_channel(), nullptr);
1232
2
    return args.GetReturnValue().Set(rv);
1233
  }
1234
1235
4
  ares_addr_node* servers = new ares_addr_node[len];
1236
4
  ares_addr_node* last = nullptr;
1237
1238
  int err;
1239
1240
13
  for (uint32_t i = 0; i < len; i++) {
1241
18
    CHECK(arr->Get(i)->IsArray());
1242
1243
18
    Local<Array> elm = Local<Array>::Cast(arr->Get(i));
1244
1245
18
    CHECK(elm->Get(0)->Int32Value());
1246
27
    CHECK(elm->Get(1)->IsString());
1247
1248
18
    int fam = elm->Get(0)->Int32Value();
1249
18
    node::Utf8Value ip(env->isolate(), elm->Get(1));
1250
1251
9
    ares_addr_node* cur = &servers[i];
1252
1253
9
    switch (fam) {
1254
      case 4:
1255
4
        cur->family = AF_INET;
1256
4
        err = uv_inet_pton(AF_INET, *ip, &cur->addr);
1257
4
        break;
1258
      case 6:
1259
5
        cur->family = AF_INET6;
1260
5
        err = uv_inet_pton(AF_INET6, *ip, &cur->addr);
1261
5
        break;
1262
      default:
1263
        CHECK(0 && "Bad address family.");
1264
        ABORT();
1265
    }
1266
1267
9
    if (err)
1268
      break;
1269
1270
9
    cur->next = nullptr;
1271
1272
9
    if (last != nullptr)
1273
5
      last->next = cur;
1274
1275
9
    last = cur;
1276
  }
1277
1278
4
  if (err == 0)
1279
4
    err = ares_set_servers(env->cares_channel(), &servers[0]);
1280
  else
1281
    err = ARES_EBADSTR;
1282
1283
4
  delete[] servers;
1284
1285
8
  args.GetReturnValue().Set(err);
1286
}
1287
1288
1289
static void StrError(const FunctionCallbackInfo<Value>& args) {
1290
  Environment* env = Environment::GetCurrent(args);
1291
  const char* errmsg = ares_strerror(args[0]->Int32Value());
1292
  args.GetReturnValue().Set(OneByteString(env->isolate(), errmsg));
1293
}
1294
1295
1296
1345
static void CaresTimerCloseCb(uv_handle_t* handle) {
1297
  Environment* env = Environment::from_cares_timer_handle(
1298
1345
      reinterpret_cast<uv_timer_t*>(handle));
1299
1345
  env->FinishHandleCleanup(handle);
1300
1345
}
1301
1302
1303
1345
static void CaresTimerClose(Environment* env,
1304
                            uv_handle_t* handle,
1305
                            void* arg) {
1306
1345
  uv_close(handle, CaresTimerCloseCb);
1307
1345
}
1308
1309
1310
1501
static void Initialize(Local<Object> target,
1311
                       Local<Value> unused,
1312
                       Local<Context> context) {
1313
1501
  Environment* env = Environment::GetCurrent(context);
1314
1315
1501
  int r = ares_library_init(ARES_LIB_INIT_ALL);
1316
1501
  CHECK_EQ(r, ARES_SUCCESS);
1317
1318
  struct ares_options options;
1319
1501
  memset(&options, 0, sizeof(options));
1320
1501
  options.flags = ARES_FLAG_NOCHECKRESP;
1321
1501
  options.sock_state_cb = ares_sockstate_cb;
1322
1501
  options.sock_state_cb_data = env;
1323
1324
  /* We do the call to ares_init_option for caller. */
1325
1501
  r = ares_init_options(env->cares_channel_ptr(),
1326
                        &options,
1327
1501
                        ARES_OPT_FLAGS | ARES_OPT_SOCK_STATE_CB);
1328
1501
  CHECK_EQ(r, ARES_SUCCESS);
1329
1330
  /* Initialize the timeout timer. The timer won't be started until the */
1331
  /* first socket is opened. */
1332
3002
  uv_timer_init(env->event_loop(), env->cares_timer_handle());
1333
  env->RegisterHandleCleanup(
1334
1501
      reinterpret_cast<uv_handle_t*>(env->cares_timer_handle()),
1335
      CaresTimerClose,
1336
1501
      nullptr);
1337
1338
1501
  env->SetMethod(target, "queryA", Query<QueryAWrap>);
1339
1501
  env->SetMethod(target, "queryAaaa", Query<QueryAaaaWrap>);
1340
1501
  env->SetMethod(target, "queryCname", Query<QueryCnameWrap>);
1341
1501
  env->SetMethod(target, "queryMx", Query<QueryMxWrap>);
1342
1501
  env->SetMethod(target, "queryNs", Query<QueryNsWrap>);
1343
1501
  env->SetMethod(target, "queryTxt", Query<QueryTxtWrap>);
1344
1501
  env->SetMethod(target, "querySrv", Query<QuerySrvWrap>);
1345
1501
  env->SetMethod(target, "queryPtr", Query<QueryPtrWrap>);
1346
1501
  env->SetMethod(target, "queryNaptr", Query<QueryNaptrWrap>);
1347
1501
  env->SetMethod(target, "querySoa", Query<QuerySoaWrap>);
1348
1501
  env->SetMethod(target, "getHostByAddr", Query<GetHostByAddrWrap>);
1349
1350
1501
  env->SetMethod(target, "getaddrinfo", GetAddrInfo);
1351
1501
  env->SetMethod(target, "getnameinfo", GetNameInfo);
1352
1501
  env->SetMethod(target, "isIP", IsIP);
1353
1501
  env->SetMethod(target, "isIPv4", IsIPv4);
1354
1501
  env->SetMethod(target, "isIPv6", IsIPv6);
1355
1356
1501
  env->SetMethod(target, "strerror", StrError);
1357
1501
  env->SetMethod(target, "getServers", GetServers);
1358
1501
  env->SetMethod(target, "setServers", SetServers);
1359
1360
6004
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET"),
1361
1501
              Integer::New(env->isolate(), AF_INET));
1362
6004
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET6"),
1363
1501
              Integer::New(env->isolate(), AF_INET6));
1364
6004
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AF_UNSPEC"),
1365
1501
              Integer::New(env->isolate(), AF_UNSPEC));
1366
6004
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AI_ADDRCONFIG"),
1367
1501
              Integer::New(env->isolate(), AI_ADDRCONFIG));
1368
6004
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AI_V4MAPPED"),
1369
1501
              Integer::New(env->isolate(), AI_V4MAPPED));
1370
1371
  Local<FunctionTemplate> aiw =
1372
3002
      FunctionTemplate::New(env->isolate(), NewGetAddrInfoReqWrap);
1373
3002
  aiw->InstanceTemplate()->SetInternalFieldCount(1);
1374
1501
  aiw->SetClassName(
1375
1501
      FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap"));
1376
6004
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap"),
1377
1501
              aiw->GetFunction());
1378
1379
  Local<FunctionTemplate> niw =
1380
3002
      FunctionTemplate::New(env->isolate(), NewGetNameInfoReqWrap);
1381
3002
  niw->InstanceTemplate()->SetInternalFieldCount(1);
1382
1501
  niw->SetClassName(
1383
1501
      FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap"));
1384
6004
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap"),
1385
1501
              niw->GetFunction());
1386
1387
  Local<FunctionTemplate> qrw =
1388
3002
      FunctionTemplate::New(env->isolate(), NewQueryReqWrap);
1389
3002
  qrw->InstanceTemplate()->SetInternalFieldCount(1);
1390
1501
  qrw->SetClassName(
1391
1501
      FIXED_ONE_BYTE_STRING(env->isolate(), "QueryReqWrap"));
1392
6004
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "QueryReqWrap"),
1393
1501
              qrw->GetFunction());
1394
1501
}
1395
1396
}  // namespace cares_wrap
1397
}  // namespace node
1398
1399
1559
NODE_MODULE_CONTEXT_AWARE_BUILTIN(cares_wrap, node::cares_wrap::Initialize)