GCC Code Coverage Report
Directory: ../src/ Exec Total Coverage
File: /home/node-core-coverage/node-core-coverage/workdir/node/out/../src/cares_wrap.cc Lines: 385 671 57.4 %
Date: 2016-12-16 Branches: 124 497 24.9 %

Line Branch 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::FunctionCallbackInfo;
40
using v8::FunctionTemplate;
41
using v8::HandleScope;
42
using v8::Integer;
43
using v8::Local;
44
using v8::Null;
45
using v8::Object;
46
using v8::String;
47
using v8::Value;
48
49
50
inline const char* ToErrorCodeString(int status) {
51

1
  switch (status) {
52
#define V(code) case ARES_##code: return #code;
53
    V(EADDRGETNETWORKPARAMS)
54
    V(EBADFAMILY)
55
    V(EBADFLAGS)
56
    V(EBADHINTS)
57
    V(EBADNAME)
58
    V(EBADQUERY)
59
    V(EBADRESP)
60
    V(EBADSTR)
61
    V(ECANCELLED)
62
    V(ECONNREFUSED)
63
    V(EDESTRUCTION)
64
    V(EFILE)
65
    V(EFORMERR)
66
    V(ELOADIPHLPAPI)
67
    V(ENODATA)
68
    V(ENOMEM)
69
    V(ENONAME)
70
    V(ENOTFOUND)
71
    V(ENOTIMP)
72
    V(ENOTINITIALIZED)
73
    V(EOF)
74
    V(EREFUSED)
75
    V(ESERVFAIL)
76
    V(ETIMEOUT)
77
#undef V
78
  }
79
  return "UNKNOWN_ARES_ERROR";
80
}
81
82
1738
class GetAddrInfoReqWrap : public ReqWrap<uv_getaddrinfo_t> {
83
 public:
84
  GetAddrInfoReqWrap(Environment* env, Local<Object> req_wrap_obj);
85
86
  size_t self_size() const override { return sizeof(*this); }
87
};
88
89
1739
GetAddrInfoReqWrap::GetAddrInfoReqWrap(Environment* env,
90
                                       Local<Object> req_wrap_obj)
91
1739
    : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETADDRINFOREQWRAP) {
92
1739
  Wrap(req_wrap_obj, this);
93
1739
}
94
95
96
1740
static void NewGetAddrInfoReqWrap(const FunctionCallbackInfo<Value>& args) {
97
1740
  CHECK(args.IsConstructCall());
98
1740
}
99
100
101
3
class GetNameInfoReqWrap : public ReqWrap<uv_getnameinfo_t> {
102
 public:
103
  GetNameInfoReqWrap(Environment* env, Local<Object> req_wrap_obj);
104
105
  size_t self_size() const override { return sizeof(*this); }
106
};
107
108
3
GetNameInfoReqWrap::GetNameInfoReqWrap(Environment* env,
109
                                       Local<Object> req_wrap_obj)
110
3
    : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETNAMEINFOREQWRAP) {
111
3
  Wrap(req_wrap_obj, this);
112
3
}
113
114
115
3
static void NewGetNameInfoReqWrap(const FunctionCallbackInfo<Value>& args) {
116
3
  CHECK(args.IsConstructCall());
117
3
}
118
119
120
3
static void NewQueryReqWrap(const FunctionCallbackInfo<Value>& args) {
121
3
  CHECK(args.IsConstructCall());
122
3
}
123
124
125
static int cmp_ares_tasks(const node_ares_task* a, const node_ares_task* b) {
126

2
  if (a->sock < b->sock)
127
    return -1;
128

2
  if (a->sock > b->sock)
129
    return 1;
130
  return 0;
131
}
132
133
134











































14
RB_GENERATE_STATIC(node_ares_task_list, node_ares_task, node, cmp_ares_tasks)
135
136
137
138
/* This is called once per second by loop->timer. It is used to constantly */
139
/* call back into c-ares for possibly processing timeouts. */
140
static void ares_timeout(uv_timer_t* handle) {
141
  Environment* env = Environment::from_cares_timer_handle(handle);
142
  CHECK_EQ(false, RB_EMPTY(env->cares_task_list()));
143
  ares_process_fd(env->cares_channel(), ARES_SOCKET_BAD, ARES_SOCKET_BAD);
144
}
145
146
147
2
static void ares_poll_cb(uv_poll_t* watcher, int status, int events) {
148
2
  node_ares_task* task = ContainerOf(&node_ares_task::poll_watcher, watcher);
149
2
  Environment* env = task->env;
150
151
  /* Reset the idle timer */
152
2
  uv_timer_again(env->cares_timer_handle());
153
154
2
  if (status < 0) {
155
    /* An error happened. Just pretend that the socket is both readable and */
156
    /* writable. */
157
    ares_process_fd(env->cares_channel(), task->sock, task->sock);
158
    return;
159
  }
160
161
  /* Process DNS responses */
162

4
  ares_process_fd(env->cares_channel(),
163
2
                  events & UV_READABLE ? task->sock : ARES_SOCKET_BAD,
164
4
                  events & UV_WRITABLE ? task->sock : ARES_SOCKET_BAD);
165
}
166
167
168
2
static void ares_poll_close_cb(uv_handle_t* watcher) {
169
2
  node_ares_task* task = ContainerOf(&node_ares_task::poll_watcher,
170
2
                                  reinterpret_cast<uv_poll_t*>(watcher));
171
2
  free(task);
172
2
}
173
174
175
/* Allocates and returns a new node_ares_task */
176
2
static node_ares_task* ares_task_create(Environment* env, ares_socket_t sock) {
177
2
  auto task = node::UncheckedMalloc<node_ares_task>(1);
178
179
2
  if (task == nullptr) {
180
    /* Out of memory. */
181
    return nullptr;
182
  }
183
184
2
  task->env = env;
185
2
  task->sock = sock;
186
187
4
  if (uv_poll_init_socket(env->event_loop(), &task->poll_watcher, sock) < 0) {
188
    /* This should never happen. */
189
    free(task);
190
    return nullptr;
191
  }
192
193
  return task;
194
}
195
196
197
/* Callback from ares when socket operation is started */
198
4
static void ares_sockstate_cb(void* data,
199
                              ares_socket_t sock,
200
                              int read,
201
                              int write) {
202
4
  Environment* env = static_cast<Environment*>(data);
203
  node_ares_task* task;
204
205
  node_ares_task lookup_task;
206
4
  lookup_task.sock = sock;
207
8
  task = RB_FIND(node_ares_task_list, env->cares_task_list(), &lookup_task);
208
209
4
  if (read || write) {
210
2
    if (!task) {
211
      /* New socket */
212
213
      /* If this is the first socket then start the timer. */
214
2
      uv_timer_t* timer_handle = env->cares_timer_handle();
215
2
      if (!uv_is_active(reinterpret_cast<uv_handle_t*>(timer_handle))) {
216
2
        CHECK(RB_EMPTY(env->cares_task_list()));
217
2
        uv_timer_start(timer_handle, ares_timeout, 1000, 1000);
218
      }
219
220
2
      task = ares_task_create(env, sock);
221
2
      if (task == nullptr) {
222
        /* This should never happen unless we're out of memory or something */
223
        /* is seriously wrong. The socket won't be polled, but the the query */
224
        /* will eventually time out. */
225
        return;
226
      }
227
228
2
      RB_INSERT(node_ares_task_list, env->cares_task_list(), task);
229
    }
230
231
    /* This should never fail. If it fails anyway, the query will eventually */
232
    /* time out. */
233

2
    uv_poll_start(&task->poll_watcher,
234
                  (read ? UV_READABLE : 0) | (write ? UV_WRITABLE : 0),
235
2
                  ares_poll_cb);
236
237
  } else {
238
    /* read == 0 and write == 0 this is c-ares's way of notifying us that */
239
    /* the socket is now closed. We must free the data associated with */
240
    /* socket. */
241
2
    CHECK(task &&
242
          "When an ares socket is closed we should have a handle for it");
243
244
2
    RB_REMOVE(node_ares_task_list, env->cares_task_list(), task);
245
2
    uv_close(reinterpret_cast<uv_handle_t*>(&task->poll_watcher),
246
2
             ares_poll_close_cb);
247
248
2
    if (RB_EMPTY(env->cares_task_list())) {
249
2
      uv_timer_stop(env->cares_timer_handle());
250
    }
251
  }
252
}
253
254
255
1
static Local<Array> HostentToAddresses(Environment* env, struct hostent* host) {
256
2
  EscapableHandleScope scope(env->isolate());
257
1
  Local<Array> addresses = Array::New(env->isolate());
258
259
  char ip[INET6_ADDRSTRLEN];
260
2
  for (uint32_t i = 0; host->h_addr_list[i] != nullptr; ++i) {
261
1
    uv_inet_ntop(host->h_addrtype, host->h_addr_list[i], ip, sizeof(ip));
262
1
    Local<String> address = OneByteString(env->isolate(), ip);
263
2
    addresses->Set(i, address);
264
  }
265
266
2
  return scope.Escape(addresses);
267
}
268
269
270
1
static Local<Array> HostentToNames(Environment* env, struct hostent* host) {
271
2
  EscapableHandleScope scope(env->isolate());
272
1
  Local<Array> names = Array::New(env->isolate());
273
274
2
  for (uint32_t i = 0; host->h_aliases[i] != nullptr; ++i) {
275
1
    Local<String> address = OneByteString(env->isolate(), host->h_aliases[i]);
276
2
    names->Set(i, address);
277
  }
278
279
2
  return scope.Escape(names);
280
}
281
282
283
class QueryWrap : public AsyncWrap {
284
 public:
285
3
  QueryWrap(Environment* env, Local<Object> req_wrap_obj)
286
3
      : AsyncWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_QUERYWRAP) {
287
3
    if (env->in_domain())
288
      req_wrap_obj->Set(env->domain_string(), env->domain_array()->Get(0));
289
3
  }
290
291
6
  ~QueryWrap() override {
292
6
    CHECK_EQ(false, persistent().IsEmpty());
293
6
    ClearWrap(object());
294
6
    persistent().Reset();
295
3
  }
296
297
  // Subclasses should implement the appropriate Send method.
298
  virtual int Send(const char* name) {
299
    UNREACHABLE();
300
    return 0;
301
  }
302
303
  virtual int Send(const char* name, int family) {
304
    UNREACHABLE();
305
    return 0;
306
  }
307
308
 protected:
309
  void* GetQueryArg() {
310
    return static_cast<void*>(this);
311
  }
312
313
2
  static void Callback(void *arg, int status, int timeouts,
314
      unsigned char* answer_buf, int answer_len) {
315
2
    QueryWrap* wrap = static_cast<QueryWrap*>(arg);
316
317
2
    if (status != ARES_SUCCESS) {
318
1
      wrap->ParseError(status);
319
    } else {
320
1
      wrap->Parse(answer_buf, answer_len);
321
    }
322
323
2
    delete wrap;
324
2
  }
325
326
1
  static void Callback(void *arg, int status, int timeouts,
327
      struct hostent* host) {
328
1
    QueryWrap* wrap = static_cast<QueryWrap*>(arg);
329
330
1
    if (status != ARES_SUCCESS) {
331
      wrap->ParseError(status);
332
    } else {
333
1
      wrap->Parse(host);
334
    }
335
336
1
    delete wrap;
337
1
  }
338
339
2
  void CallOnComplete(Local<Value> answer,
340
                      Local<Value> extra = Local<Value>()) {
341
4
    HandleScope handle_scope(env()->isolate());
342
8
    Context::Scope context_scope(env()->context());
343
    Local<Value> argv[] = {
344
      Integer::New(env()->isolate(), 0),
345
      answer,
346
      extra
347
4
    };
348
4
    const int argc = arraysize(argv) - extra.IsEmpty();
349
4
    MakeCallback(env()->oncomplete_string(), argc, argv);
350
2
  }
351
352
1
  void ParseError(int status) {
353
1
    CHECK_NE(status, ARES_SUCCESS);
354
2
    HandleScope handle_scope(env()->isolate());
355
4
    Context::Scope context_scope(env()->context());
356
1
    const char* code = ToErrorCodeString(status);
357
2
    Local<Value> arg = OneByteString(env()->isolate(), code);
358
2
    MakeCallback(env()->oncomplete_string(), 1, &arg);
359
1
  }
360
361
  // Subclasses should implement the appropriate Parse method.
362
  virtual void Parse(unsigned char* buf, int len) {
363
    UNREACHABLE();
364
  }
365
366
  virtual void Parse(struct hostent* host) {
367
    UNREACHABLE();
368
  }
369
};
370
371
372
2
class QueryAWrap: public QueryWrap {
373
 public:
374
  QueryAWrap(Environment* env, Local<Object> req_wrap_obj)
375
2
      : QueryWrap(env, req_wrap_obj) {
376
  }
377
378
2
  int Send(const char* name) override {
379
2
    ares_query(env()->cares_channel(),
380
               name,
381
               ns_c_in,
382
               ns_t_a,
383
               Callback,
384
2
               GetQueryArg());
385
2
    return 0;
386
  }
387
388
  size_t self_size() const override { return sizeof(*this); }
389
390
 protected:
391
1
  void Parse(unsigned char* buf, int len) override {
392
2
    HandleScope handle_scope(env()->isolate());
393
4
    Context::Scope context_scope(env()->context());
394
395
    hostent* host;
396
    ares_addrttl addrttls[256];
397
1
    int naddrttls = arraysize(addrttls);
398
399
1
    int status = ares_parse_a_reply(buf, len, &host, addrttls, &naddrttls);
400
1
    if (status != ARES_SUCCESS) {
401
      ParseError(status);
402
      return;
403
    }
404
405
1
    Local<Array> addresses = HostentToAddresses(env(), host);
406
1
    Local<Array> ttls = Array::New(env()->isolate(), naddrttls);
407
408
2
    auto context = env()->context();
409
2
    for (int i = 0; i < naddrttls; i += 1) {
410
1
      auto value = Integer::New(env()->isolate(), addrttls[i].ttl);
411
3
      ttls->Set(context, i, value).FromJust();
412
    }
413
1
    ares_free_hostent(host);
414
415
2
    CallOnComplete(addresses, ttls);
416
  }
417
};
418
419
420
class QueryAaaaWrap: public QueryWrap {
421
 public:
422
  QueryAaaaWrap(Environment* env, Local<Object> req_wrap_obj)
423
      : QueryWrap(env, req_wrap_obj) {
424
  }
425
426
  int Send(const char* name) override {
427
    ares_query(env()->cares_channel(),
428
               name,
429
               ns_c_in,
430
               ns_t_aaaa,
431
               Callback,
432
               GetQueryArg());
433
    return 0;
434
  }
435
436
  size_t self_size() const override { return sizeof(*this); }
437
438
 protected:
439
  void Parse(unsigned char* buf, int len) override {
440
    HandleScope handle_scope(env()->isolate());
441
    Context::Scope context_scope(env()->context());
442
443
    hostent* host;
444
    ares_addr6ttl addrttls[256];
445
    int naddrttls = arraysize(addrttls);
446
447
    int status = ares_parse_aaaa_reply(buf, len, &host, addrttls, &naddrttls);
448
    if (status != ARES_SUCCESS) {
449
      ParseError(status);
450
      return;
451
    }
452
453
    Local<Array> addresses = HostentToAddresses(env(), host);
454
    Local<Array> ttls = Array::New(env()->isolate(), naddrttls);
455
456
    auto context = env()->context();
457
    for (int i = 0; i < naddrttls; i += 1) {
458
      auto value = Integer::New(env()->isolate(), addrttls[i].ttl);
459
      ttls->Set(context, i, value).FromJust();
460
    }
461
    ares_free_hostent(host);
462
463
    CallOnComplete(addresses, ttls);
464
  }
465
};
466
467
468
class QueryCnameWrap: public QueryWrap {
469
 public:
470
  QueryCnameWrap(Environment* env, Local<Object> req_wrap_obj)
471
      : QueryWrap(env, req_wrap_obj) {
472
  }
473
474
  int Send(const char* name) override {
475
    ares_query(env()->cares_channel(),
476
               name,
477
               ns_c_in,
478
               ns_t_cname,
479
               Callback,
480
               GetQueryArg());
481
    return 0;
482
  }
483
484
  size_t self_size() const override { return sizeof(*this); }
485
486
 protected:
487
  void Parse(unsigned char* buf, int len) override {
488
    HandleScope handle_scope(env()->isolate());
489
    Context::Scope context_scope(env()->context());
490
    struct hostent* host;
491
492
    int status = ares_parse_a_reply(buf, len, &host, nullptr, nullptr);
493
    if (status != ARES_SUCCESS) {
494
      ParseError(status);
495
      return;
496
    }
497
498
    // A cname lookup always returns a single record but we follow the
499
    // common API here.
500
    Local<Array> result = Array::New(env()->isolate(), 1);
501
    result->Set(0, OneByteString(env()->isolate(), host->h_name));
502
    ares_free_hostent(host);
503
504
    this->CallOnComplete(result);
505
  }
506
};
507
508
509
class QueryMxWrap: public QueryWrap {
510
 public:
511
  QueryMxWrap(Environment* env, Local<Object> req_wrap_obj)
512
      : QueryWrap(env, req_wrap_obj) {
513
  }
514
515
  int Send(const char* name) override {
516
    ares_query(env()->cares_channel(),
517
               name,
518
               ns_c_in,
519
               ns_t_mx,
520
               Callback,
521
               GetQueryArg());
522
    return 0;
523
  }
524
525
  size_t self_size() const override { return sizeof(*this); }
526
527
 protected:
528
  void Parse(unsigned char* buf, int len) override {
529
    HandleScope handle_scope(env()->isolate());
530
    Context::Scope context_scope(env()->context());
531
532
    struct ares_mx_reply* mx_start;
533
    int status = ares_parse_mx_reply(buf, len, &mx_start);
534
    if (status != ARES_SUCCESS) {
535
      ParseError(status);
536
      return;
537
    }
538
539
    Local<Array> mx_records = Array::New(env()->isolate());
540
    Local<String> exchange_symbol = env()->exchange_string();
541
    Local<String> priority_symbol = env()->priority_string();
542
543
    ares_mx_reply* current = mx_start;
544
    for (uint32_t i = 0; current != nullptr; ++i, current = current->next) {
545
      Local<Object> mx_record = Object::New(env()->isolate());
546
      mx_record->Set(exchange_symbol,
547
                     OneByteString(env()->isolate(), current->host));
548
      mx_record->Set(priority_symbol,
549
                     Integer::New(env()->isolate(), current->priority));
550
      mx_records->Set(i, mx_record);
551
    }
552
553
    ares_free_data(mx_start);
554
555
    this->CallOnComplete(mx_records);
556
  }
557
};
558
559
560
class QueryNsWrap: public QueryWrap {
561
 public:
562
  QueryNsWrap(Environment* env, Local<Object> req_wrap_obj)
563
      : QueryWrap(env, req_wrap_obj) {
564
  }
565
566
  int Send(const char* name) override {
567
    ares_query(env()->cares_channel(),
568
               name,
569
               ns_c_in,
570
               ns_t_ns,
571
               Callback,
572
               GetQueryArg());
573
    return 0;
574
  }
575
576
  size_t self_size() const override { return sizeof(*this); }
577
578
 protected:
579
  void Parse(unsigned char* buf, int len) override {
580
    HandleScope handle_scope(env()->isolate());
581
    Context::Scope context_scope(env()->context());
582
    struct hostent* host;
583
584
    int status = ares_parse_ns_reply(buf, len, &host);
585
    if (status != ARES_SUCCESS) {
586
      ParseError(status);
587
      return;
588
    }
589
590
    Local<Array> names = HostentToNames(env(), host);
591
    ares_free_hostent(host);
592
593
    this->CallOnComplete(names);
594
  }
595
};
596
597
598
class QueryTxtWrap: public QueryWrap {
599
 public:
600
  QueryTxtWrap(Environment* env, Local<Object> req_wrap_obj)
601
      : QueryWrap(env, req_wrap_obj) {
602
  }
603
604
  int Send(const char* name) override {
605
    ares_query(env()->cares_channel(),
606
               name,
607
               ns_c_in,
608
               ns_t_txt,
609
               Callback,
610
               GetQueryArg());
611
    return 0;
612
  }
613
614
  size_t self_size() const override { return sizeof(*this); }
615
616
 protected:
617
  void Parse(unsigned char* buf, int len) override {
618
    HandleScope handle_scope(env()->isolate());
619
    Context::Scope context_scope(env()->context());
620
    struct ares_txt_ext* txt_out;
621
622
    int status = ares_parse_txt_reply_ext(buf, len, &txt_out);
623
    if (status != ARES_SUCCESS) {
624
      ParseError(status);
625
      return;
626
    }
627
628
    Local<Array> txt_records = Array::New(env()->isolate());
629
    Local<Array> txt_chunk;
630
631
    struct ares_txt_ext* current = txt_out;
632
    uint32_t i = 0;
633
    for (uint32_t j = 0; current != nullptr; current = current->next) {
634
      Local<String> txt = OneByteString(env()->isolate(), current->txt);
635
      // New record found - write out the current chunk
636
      if (current->record_start) {
637
        if (!txt_chunk.IsEmpty())
638
          txt_records->Set(i++, txt_chunk);
639
        txt_chunk = Array::New(env()->isolate());
640
        j = 0;
641
      }
642
      txt_chunk->Set(j++, txt);
643
    }
644
    // Push last chunk if it isn't empty
645
    if (!txt_chunk.IsEmpty())
646
      txt_records->Set(i, txt_chunk);
647
648
    ares_free_data(txt_out);
649
650
    this->CallOnComplete(txt_records);
651
  }
652
};
653
654
655
class QuerySrvWrap: public QueryWrap {
656
 public:
657
  explicit QuerySrvWrap(Environment* env, Local<Object> req_wrap_obj)
658
      : QueryWrap(env, req_wrap_obj) {
659
  }
660
661
  int Send(const char* name) override {
662
    ares_query(env()->cares_channel(),
663
               name,
664
               ns_c_in,
665
               ns_t_srv,
666
               Callback,
667
               GetQueryArg());
668
    return 0;
669
  }
670
671
  size_t self_size() const override { return sizeof(*this); }
672
673
 protected:
674
  void Parse(unsigned char* buf, int len) override {
675
    HandleScope handle_scope(env()->isolate());
676
    Context::Scope context_scope(env()->context());
677
678
    struct ares_srv_reply* srv_start;
679
    int status = ares_parse_srv_reply(buf, len, &srv_start);
680
    if (status != ARES_SUCCESS) {
681
      ParseError(status);
682
      return;
683
    }
684
685
    Local<Array> srv_records = Array::New(env()->isolate());
686
    Local<String> name_symbol = env()->name_string();
687
    Local<String> port_symbol = env()->port_string();
688
    Local<String> priority_symbol = env()->priority_string();
689
    Local<String> weight_symbol = env()->weight_string();
690
691
    ares_srv_reply* current = srv_start;
692
    for (uint32_t i = 0; current != nullptr; ++i, current = current->next) {
693
      Local<Object> srv_record = Object::New(env()->isolate());
694
      srv_record->Set(name_symbol,
695
                      OneByteString(env()->isolate(), current->host));
696
      srv_record->Set(port_symbol,
697
                      Integer::New(env()->isolate(), current->port));
698
      srv_record->Set(priority_symbol,
699
                      Integer::New(env()->isolate(), current->priority));
700
      srv_record->Set(weight_symbol,
701
                      Integer::New(env()->isolate(), current->weight));
702
      srv_records->Set(i, srv_record);
703
    }
704
705
    ares_free_data(srv_start);
706
707
    this->CallOnComplete(srv_records);
708
  }
709
};
710
711
class QueryPtrWrap: public QueryWrap {
712
 public:
713
  explicit QueryPtrWrap(Environment* env, Local<Object> req_wrap_obj)
714
      : QueryWrap(env, req_wrap_obj) {
715
  }
716
717
  int Send(const char* name) override {
718
    ares_query(env()->cares_channel(),
719
               name,
720
               ns_c_in,
721
               ns_t_ptr,
722
               Callback,
723
               GetQueryArg());
724
    return 0;
725
  }
726
727
  size_t self_size() const override { return sizeof(*this); }
728
729
 protected:
730
  void Parse(unsigned char* buf, int len) override {
731
    HandleScope handle_scope(env()->isolate());
732
    Context::Scope context_scope(env()->context());
733
734
    struct hostent* host;
735
736
    int status = ares_parse_ptr_reply(buf, len, NULL, 0, AF_INET, &host);
737
    if (status != ARES_SUCCESS) {
738
      ParseError(status);
739
      return;
740
    }
741
742
    Local<Array> aliases = Array::New(env()->isolate());
743
744
    for (uint32_t i = 0; host->h_aliases[i] != NULL; i++) {
745
      aliases->Set(i, OneByteString(env()->isolate(), host->h_aliases[i]));
746
    }
747
748
    ares_free_hostent(host);
749
750
    this->CallOnComplete(aliases);
751
  }
752
};
753
754
class QueryNaptrWrap: public QueryWrap {
755
 public:
756
  explicit QueryNaptrWrap(Environment* env, Local<Object> req_wrap_obj)
757
      : QueryWrap(env, req_wrap_obj) {
758
  }
759
760
  int Send(const char* name) override {
761
    ares_query(env()->cares_channel(),
762
               name,
763
               ns_c_in,
764
               ns_t_naptr,
765
               Callback,
766
               GetQueryArg());
767
    return 0;
768
  }
769
770
  size_t self_size() const override { return sizeof(*this); }
771
772
 protected:
773
  void Parse(unsigned char* buf, int len) override {
774
    HandleScope handle_scope(env()->isolate());
775
    Context::Scope context_scope(env()->context());
776
777
    ares_naptr_reply* naptr_start;
778
    int status = ares_parse_naptr_reply(buf, len, &naptr_start);
779
780
    if (status != ARES_SUCCESS) {
781
      ParseError(status);
782
      return;
783
    }
784
785
    Local<Array> naptr_records = Array::New(env()->isolate());
786
    Local<String> flags_symbol = env()->flags_string();
787
    Local<String> service_symbol = env()->service_string();
788
    Local<String> regexp_symbol = env()->regexp_string();
789
    Local<String> replacement_symbol = env()->replacement_string();
790
    Local<String> order_symbol = env()->order_string();
791
    Local<String> preference_symbol = env()->preference_string();
792
793
    ares_naptr_reply* current = naptr_start;
794
    for (uint32_t i = 0; current != nullptr; ++i, current = current->next) {
795
      Local<Object> naptr_record = Object::New(env()->isolate());
796
      naptr_record->Set(flags_symbol,
797
                        OneByteString(env()->isolate(), current->flags));
798
      naptr_record->Set(service_symbol,
799
                        OneByteString(env()->isolate(), current->service));
800
      naptr_record->Set(regexp_symbol,
801
                        OneByteString(env()->isolate(), current->regexp));
802
      naptr_record->Set(replacement_symbol,
803
                        OneByteString(env()->isolate(), current->replacement));
804
      naptr_record->Set(order_symbol,
805
                        Integer::New(env()->isolate(), current->order));
806
      naptr_record->Set(preference_symbol,
807
                        Integer::New(env()->isolate(), current->preference));
808
      naptr_records->Set(i, naptr_record);
809
    }
810
811
    ares_free_data(naptr_start);
812
813
    this->CallOnComplete(naptr_records);
814
  }
815
};
816
817
818
class QuerySoaWrap: public QueryWrap {
819
 public:
820
  QuerySoaWrap(Environment* env, Local<Object> req_wrap_obj)
821
      : QueryWrap(env, req_wrap_obj) {
822
  }
823
824
  int Send(const char* name) override {
825
    ares_query(env()->cares_channel(),
826
               name,
827
               ns_c_in,
828
               ns_t_soa,
829
               Callback,
830
               GetQueryArg());
831
    return 0;
832
  }
833
834
  size_t self_size() const override { return sizeof(*this); }
835
836
 protected:
837
  void Parse(unsigned char* buf, int len) override {
838
    HandleScope handle_scope(env()->isolate());
839
    Context::Scope context_scope(env()->context());
840
841
    ares_soa_reply* soa_out;
842
    int status = ares_parse_soa_reply(buf, len, &soa_out);
843
844
    if (status != ARES_SUCCESS) {
845
      ParseError(status);
846
      return;
847
    }
848
849
    Local<Object> soa_record = Object::New(env()->isolate());
850
851
    soa_record->Set(env()->nsname_string(),
852
                    OneByteString(env()->isolate(), soa_out->nsname));
853
    soa_record->Set(env()->hostmaster_string(),
854
                    OneByteString(env()->isolate(), soa_out->hostmaster));
855
    soa_record->Set(env()->serial_string(),
856
                    Integer::New(env()->isolate(), soa_out->serial));
857
    soa_record->Set(env()->refresh_string(),
858
                    Integer::New(env()->isolate(), soa_out->refresh));
859
    soa_record->Set(env()->retry_string(),
860
                    Integer::New(env()->isolate(), soa_out->retry));
861
    soa_record->Set(env()->expire_string(),
862
                    Integer::New(env()->isolate(), soa_out->expire));
863
    soa_record->Set(env()->minttl_string(),
864
                    Integer::New(env()->isolate(), soa_out->minttl));
865
866
    ares_free_data(soa_out);
867
868
    this->CallOnComplete(soa_record);
869
  }
870
};
871
872
873
1
class GetHostByAddrWrap: public QueryWrap {
874
 public:
875
  explicit GetHostByAddrWrap(Environment* env, Local<Object> req_wrap_obj)
876
1
      : QueryWrap(env, req_wrap_obj) {
877
  }
878
879
1
  int Send(const char* name) override {
880
    int length, family;
881
    char address_buffer[sizeof(struct in6_addr)];
882
883
1
    if (uv_inet_pton(AF_INET, name, &address_buffer) == 0) {
884
      length = sizeof(struct in_addr);
885
      family = AF_INET;
886
    } else if (uv_inet_pton(AF_INET6, name, &address_buffer) == 0) {
887
      length = sizeof(struct in6_addr);
888
      family = AF_INET6;
889
    } else {
890
      return UV_EINVAL;  // So errnoException() reports a proper error.
891
    }
892
893
1
    ares_gethostbyaddr(env()->cares_channel(),
894
                       address_buffer,
895
                       length,
896
                       family,
897
                       Callback,
898
1
                       GetQueryArg());
899
1
    return 0;
900
  }
901
902
  size_t self_size() const override { return sizeof(*this); }
903
904
 protected:
905
1
  void Parse(struct hostent* host) override {
906
2
    HandleScope handle_scope(env()->isolate());
907
4
    Context::Scope context_scope(env()->context());
908
2
    this->CallOnComplete(HostentToNames(env(), host));
909
1
  }
910
};
911
912
913
class GetHostByNameWrap: public QueryWrap {
914
 public:
915
  explicit GetHostByNameWrap(Environment* env, Local<Object> req_wrap_obj)
916
      : QueryWrap(env, req_wrap_obj) {
917
  }
918
919
  int Send(const char* name, int family) override {
920
    ares_gethostbyname(env()->cares_channel(),
921
                       name,
922
                       family,
923
                       Callback,
924
                       GetQueryArg());
925
    return 0;
926
  }
927
928
 protected:
929
  void Parse(struct hostent* host) override {
930
    HandleScope scope(env()->isolate());
931
932
    Local<Array> addresses = HostentToAddresses(env(), host);
933
    Local<Integer> family = Integer::New(env()->isolate(), host->h_addrtype);
934
935
    this->CallOnComplete(addresses, family);
936
  }
937
};
938
939
940
template <class Wrap>
941
3
static void Query(const FunctionCallbackInfo<Value>& args) {
942
3
  Environment* env = Environment::GetCurrent(args);
943
944





3
  CHECK_EQ(false, args.IsConstructCall());
945





3
  CHECK(args[0]->IsObject());
946





6
  CHECK(args[1]->IsString());
947
948
6
  Local<Object> req_wrap_obj = args[0].As<Object>();
949
6
  Local<String> string = args[1].As<String>();
950
6
  Wrap* wrap = new Wrap(env, req_wrap_obj);
951
952
6
  node::Utf8Value name(env->isolate(), string);
953
3
  int err = wrap->Send(*name);
954





3
  if (err)
955
    delete wrap;
956
957
6
  args.GetReturnValue().Set(err);
958
3
}
959
960
961
1738
void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
962
1738
  GetAddrInfoReqWrap* req_wrap = static_cast<GetAddrInfoReqWrap*>(req->data);
963
1738
  Environment* env = req_wrap->env();
964
965
3476
  HandleScope handle_scope(env->isolate());
966
5214
  Context::Scope context_scope(env->context());
967
968
  Local<Value> argv[] = {
969
    Integer::New(env->isolate(), status),
970
    Null(env->isolate())
971
6952
  };
972
973
1738
  if (status == 0) {
974
    // Success
975
    struct addrinfo *address;
976
1731
    int n = 0;
977
978
    // Create the response array.
979
1731
    Local<Array> results = Array::New(env->isolate());
980
981
    char ip[INET6_ADDRSTRLEN];
982
    const char *addr;
983
984
    // Iterate over the IPv4 responses again this time creating javascript
985
    // strings for each IP and filling the results array.
986
1731
    address = res;
987
3479
    while (address) {
988
1748
      CHECK_EQ(address->ai_socktype, SOCK_STREAM);
989
990
      // Ignore random ai_family types.
991
1748
      if (address->ai_family == AF_INET) {
992
        // Juggle pointers
993
        addr = reinterpret_cast<char*>(&(reinterpret_cast<struct sockaddr_in*>(
994
1740
            address->ai_addr)->sin_addr));
995
        int err = uv_inet_ntop(address->ai_family,
996
                               addr,
997
                               ip,
998
1740
                               INET6_ADDRSTRLEN);
999
1740
        if (err)
1000
          continue;
1001
1002
        // Create JavaScript string
1003
1740
        Local<String> s = OneByteString(env->isolate(), ip);
1004
1740
        results->Set(n, s);
1005
1740
        n++;
1006
      }
1007
1008
      // Increment
1009
1748
      address = address->ai_next;
1010
    }
1011
1012
    // Iterate over the IPv6 responses putting them in the array.
1013
    address = res;
1014
3479
    while (address) {
1015
1748
      CHECK_EQ(address->ai_socktype, SOCK_STREAM);
1016
1017
      // Ignore random ai_family types.
1018
1748
      if (address->ai_family == AF_INET6) {
1019
        // Juggle pointers
1020
        addr = reinterpret_cast<char*>(&(reinterpret_cast<struct sockaddr_in6*>(
1021
8
            address->ai_addr)->sin6_addr));
1022
        int err = uv_inet_ntop(address->ai_family,
1023
                               addr,
1024
                               ip,
1025
8
                               INET6_ADDRSTRLEN);
1026
8
        if (err)
1027
          continue;
1028
1029
        // Create JavaScript string
1030
8
        Local<String> s = OneByteString(env->isolate(), ip);
1031
8
        results->Set(n, s);
1032
8
        n++;
1033
      }
1034
1035
      // Increment
1036
1748
      address = address->ai_next;
1037
    }
1038
1039
    // No responses were found to return
1040
1731
    if (n == 0) {
1041
      argv[0] = Integer::New(env->isolate(), UV_EAI_NODATA);
1042
    }
1043
1044
1731
    argv[1] = results;
1045
  }
1046
1047
1738
  uv_freeaddrinfo(res);
1048
1049
  // Make the callback into JavaScript
1050
3476
  req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv);
1051
1052
1738
  delete req_wrap;
1053
1738
}
1054
1055
1056
3
void AfterGetNameInfo(uv_getnameinfo_t* req,
1057
                      int status,
1058
                      const char* hostname,
1059
                      const char* service) {
1060
3
  GetNameInfoReqWrap* req_wrap = static_cast<GetNameInfoReqWrap*>(req->data);
1061
3
  Environment* env = req_wrap->env();
1062
1063
6
  HandleScope handle_scope(env->isolate());
1064
9
  Context::Scope context_scope(env->context());
1065
1066
  Local<Value> argv[] = {
1067
    Integer::New(env->isolate(), status),
1068
    Null(env->isolate()),
1069
    Null(env->isolate())
1070
18
  };
1071
1072
3
  if (status == 0) {
1073
    // Success
1074
    Local<String> js_hostname = OneByteString(env->isolate(), hostname);
1075
    Local<String> js_service = OneByteString(env->isolate(), service);
1076
    argv[1] = js_hostname;
1077
    argv[2] = js_service;
1078
  }
1079
1080
  // Make the callback into JavaScript
1081
6
  req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv);
1082
1083
3
  delete req_wrap;
1084
3
}
1085
1086
1087
4433
static void IsIP(const FunctionCallbackInfo<Value>& args) {
1088
13299
  node::Utf8Value ip(args.GetIsolate(), args[0]);
1089
  char address_buffer[sizeof(struct in6_addr)];
1090
1091
4433
  int rc = 0;
1092
4433
  if (uv_inet_pton(AF_INET, *ip, &address_buffer) == 0)
1093
    rc = 4;
1094
3607
  else if (uv_inet_pton(AF_INET6, *ip, &address_buffer) == 0)
1095
49
    rc = 6;
1096
1097
8866
  args.GetReturnValue().Set(rc);
1098
4433
}
1099
1100
12
static void IsIPv4(const FunctionCallbackInfo<Value>& args) {
1101
36
  node::Utf8Value ip(args.GetIsolate(), args[0]);
1102
  char address_buffer[sizeof(struct in_addr)];
1103
1104
12
  if (uv_inet_pton(AF_INET, *ip, &address_buffer) == 0) {
1105
4
    args.GetReturnValue().Set(true);
1106
  } else {
1107
20
    args.GetReturnValue().Set(false);
1108
  }
1109
12
}
1110
1111
19
static void IsIPv6(const FunctionCallbackInfo<Value>& args) {
1112
57
  node::Utf8Value ip(args.GetIsolate(), args[0]);
1113
  char address_buffer[sizeof(struct in6_addr)];
1114
1115
19
  if (uv_inet_pton(AF_INET6, *ip, &address_buffer) == 0) {
1116
8
    args.GetReturnValue().Set(true);
1117
  } else {
1118
30
    args.GetReturnValue().Set(false);
1119
  }
1120
19
}
1121
1122
1739
static void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
1123
1739
  Environment* env = Environment::GetCurrent(args);
1124
1125
1739
  CHECK(args[0]->IsObject());
1126
3478
  CHECK(args[1]->IsString());
1127
1739
  CHECK(args[2]->IsInt32());
1128
3478
  Local<Object> req_wrap_obj = args[0].As<Object>();
1129
3478
  node::Utf8Value hostname(env->isolate(), args[1]);
1130
1131
3478
  int32_t flags = (args[3]->IsInt32()) ? args[3]->Int32Value() : 0;
1132
  int family;
1133
1134

1739
  switch (args[2]->Int32Value()) {
1135
  case 0:
1136
    family = AF_UNSPEC;
1137
    break;
1138
  case 4:
1139
8
    family = AF_INET;
1140
8
    break;
1141
  case 6:
1142
6
    family = AF_INET6;
1143
6
    break;
1144
  default:
1145
    CHECK(0 && "bad address family");
1146
  }
1147
1148
1739
  GetAddrInfoReqWrap* req_wrap = new GetAddrInfoReqWrap(env, req_wrap_obj);
1149
1150
  struct addrinfo hints;
1151
1739
  memset(&hints, 0, sizeof(struct addrinfo));
1152
1739
  hints.ai_family = family;
1153
1739
  hints.ai_socktype = SOCK_STREAM;
1154
1739
  hints.ai_flags = flags;
1155
1156
5217
  int err = uv_getaddrinfo(env->event_loop(),
1157
                           req_wrap->req(),
1158
                           AfterGetAddrInfo,
1159
1739
                           *hostname,
1160
                           nullptr,
1161
1739
                           &hints);
1162
3478
  req_wrap->Dispatched();
1163
1739
  if (err)
1164
    delete req_wrap;
1165
1166
3478
  args.GetReturnValue().Set(err);
1167
1739
}
1168
1169
1170
3
static void GetNameInfo(const FunctionCallbackInfo<Value>& args) {
1171
3
  Environment* env = Environment::GetCurrent(args);
1172
1173
3
  CHECK(args[0]->IsObject());
1174
6
  CHECK(args[1]->IsString());
1175
3
  CHECK(args[2]->IsUint32());
1176
6
  Local<Object> req_wrap_obj = args[0].As<Object>();
1177
6
  node::Utf8Value ip(env->isolate(), args[1]);
1178
3
  const unsigned port = args[2]->Uint32Value();
1179
  struct sockaddr_storage addr;
1180
1181

3
  CHECK(uv_ip4_addr(*ip, port, reinterpret_cast<sockaddr_in*>(&addr)) == 0 ||
1182
        uv_ip6_addr(*ip, port, reinterpret_cast<sockaddr_in6*>(&addr)) == 0);
1183
1184
3
  GetNameInfoReqWrap* req_wrap = new GetNameInfoReqWrap(env, req_wrap_obj);
1185
1186
9
  int err = uv_getnameinfo(env->event_loop(),
1187
                           req_wrap->req(),
1188
                           AfterGetNameInfo,
1189
                           (struct sockaddr*)&addr,
1190
3
                           NI_NAMEREQD);
1191
6
  req_wrap->Dispatched();
1192
3
  if (err)
1193
    delete req_wrap;
1194
1195
6
  args.GetReturnValue().Set(err);
1196
3
}
1197
1198
1199
15
static void GetServers(const FunctionCallbackInfo<Value>& args) {
1200
15
  Environment* env = Environment::GetCurrent(args);
1201
1202
15
  Local<Array> server_array = Array::New(env->isolate());
1203
1204
  ares_addr_node* servers;
1205
1206
15
  int r = ares_get_servers(env->cares_channel(), &servers);
1207
15
  CHECK_EQ(r, ARES_SUCCESS);
1208
1209
15
  ares_addr_node* cur = servers;
1210
1211
46
  for (uint32_t i = 0; cur != nullptr; ++i, cur = cur->next) {
1212
    char ip[INET6_ADDRSTRLEN];
1213
1214
31
    const void* caddr = static_cast<const void*>(&cur->addr);
1215
31
    int err = uv_inet_ntop(cur->family, caddr, ip, sizeof(ip));
1216
31
    CHECK_EQ(err, 0);
1217
1218
31
    Local<String> addr = OneByteString(env->isolate(), ip);
1219
62
    server_array->Set(i, addr);
1220
  }
1221
1222
15
  ares_free_data(servers);
1223
1224
30
  args.GetReturnValue().Set(server_array);
1225
15
}
1226
1227
1228
7
static void SetServers(const FunctionCallbackInfo<Value>& args) {
1229
7
  Environment* env = Environment::GetCurrent(args);
1230
1231
7
  CHECK(args[0]->IsArray());
1232
1233
14
  Local<Array> arr = Local<Array>::Cast(args[0]);
1234
1235
7
  uint32_t len = arr->Length();
1236
1237
7
  if (len == 0) {
1238
1
    int rv = ares_set_servers(env->cares_channel(), nullptr);
1239
2
    return args.GetReturnValue().Set(rv);
1240
  }
1241
1242
6
  ares_addr_node* servers = new ares_addr_node[len];
1243
6
  ares_addr_node* last = nullptr;
1244
1245
  int err;
1246
1247
20
  for (uint32_t i = 0; i < len; i++) {
1248
28
    CHECK(arr->Get(i)->IsArray());
1249
1250
28
    Local<Array> elm = Local<Array>::Cast(arr->Get(i));
1251
1252
28
    CHECK(elm->Get(0)->Int32Value());
1253
42
    CHECK(elm->Get(1)->IsString());
1254
1255
28
    int fam = elm->Get(0)->Int32Value();
1256
28
    node::Utf8Value ip(env->isolate(), elm->Get(1));
1257
1258
14
    ares_addr_node* cur = &servers[i];
1259
1260
14
    switch (fam) {
1261
      case 4:
1262
9
        cur->family = AF_INET;
1263
9
        err = uv_inet_pton(AF_INET, *ip, &cur->addr);
1264
9
        break;
1265
      case 6:
1266
5
        cur->family = AF_INET6;
1267
5
        err = uv_inet_pton(AF_INET6, *ip, &cur->addr);
1268
5
        break;
1269
      default:
1270
        CHECK(0 && "Bad address family.");
1271
    }
1272
1273
14
    if (err)
1274
      break;
1275
1276
14
    cur->next = nullptr;
1277
1278
14
    if (last != nullptr)
1279
8
      last->next = cur;
1280
1281
14
    last = cur;
1282
  }
1283
1284
6
  if (err == 0)
1285
6
    err = ares_set_servers(env->cares_channel(), &servers[0]);
1286
  else
1287
    err = ARES_EBADSTR;
1288
1289
6
  delete[] servers;
1290
1291
12
  args.GetReturnValue().Set(err);
1292
}
1293
1294
1295
static void StrError(const FunctionCallbackInfo<Value>& args) {
1296
  Environment* env = Environment::GetCurrent(args);
1297
  const char* errmsg = ares_strerror(args[0]->Int32Value());
1298
  args.GetReturnValue().Set(OneByteString(env->isolate(), errmsg));
1299
}
1300
1301
1302
1502
static void CaresTimerCloseCb(uv_handle_t* handle) {
1303
  Environment* env = Environment::from_cares_timer_handle(
1304
1502
      reinterpret_cast<uv_timer_t*>(handle));
1305
1502
  env->FinishHandleCleanup(handle);
1306
1502
}
1307
1308
1309
1503
static void CaresTimerClose(Environment* env,
1310
                            uv_handle_t* handle,
1311
                            void* arg) {
1312
1503
  uv_close(handle, CaresTimerCloseCb);
1313
1503
}
1314
1315
1316
1671
static void Initialize(Local<Object> target,
1317
                       Local<Value> unused,
1318
                       Local<Context> context) {
1319
1671
  Environment* env = Environment::GetCurrent(context);
1320
1321
1671
  int r = ares_library_init(ARES_LIB_INIT_ALL);
1322
1671
  if (r != ARES_SUCCESS)
1323
    return env->ThrowError(ToErrorCodeString(r));
1324
1325
  struct ares_options options;
1326
1671
  memset(&options, 0, sizeof(options));
1327
1671
  options.flags = ARES_FLAG_NOCHECKRESP;
1328
1671
  options.sock_state_cb = ares_sockstate_cb;
1329
1671
  options.sock_state_cb_data = env;
1330
1331
  /* We do the call to ares_init_option for caller. */
1332
1671
  r = ares_init_options(env->cares_channel_ptr(),
1333
                        &options,
1334
1671
                        ARES_OPT_FLAGS | ARES_OPT_SOCK_STATE_CB);
1335
1671
  if (r != ARES_SUCCESS) {
1336
    ares_library_cleanup();
1337
    return env->ThrowError(ToErrorCodeString(r));
1338
  }
1339
1340
  /* Initialize the timeout timer. The timer won't be started until the */
1341
  /* first socket is opened. */
1342
3342
  uv_timer_init(env->event_loop(), env->cares_timer_handle());
1343
  env->RegisterHandleCleanup(
1344
1671
      reinterpret_cast<uv_handle_t*>(env->cares_timer_handle()),
1345
      CaresTimerClose,
1346
1671
      nullptr);
1347
1348
1671
  env->SetMethod(target, "queryA", Query<QueryAWrap>);
1349
1671
  env->SetMethod(target, "queryAaaa", Query<QueryAaaaWrap>);
1350
1671
  env->SetMethod(target, "queryCname", Query<QueryCnameWrap>);
1351
1671
  env->SetMethod(target, "queryMx", Query<QueryMxWrap>);
1352
1671
  env->SetMethod(target, "queryNs", Query<QueryNsWrap>);
1353
1671
  env->SetMethod(target, "queryTxt", Query<QueryTxtWrap>);
1354
1671
  env->SetMethod(target, "querySrv", Query<QuerySrvWrap>);
1355
1671
  env->SetMethod(target, "queryPtr", Query<QueryPtrWrap>);
1356
1671
  env->SetMethod(target, "queryNaptr", Query<QueryNaptrWrap>);
1357
1671
  env->SetMethod(target, "querySoa", Query<QuerySoaWrap>);
1358
1671
  env->SetMethod(target, "getHostByAddr", Query<GetHostByAddrWrap>);
1359
1360
1671
  env->SetMethod(target, "getaddrinfo", GetAddrInfo);
1361
1671
  env->SetMethod(target, "getnameinfo", GetNameInfo);
1362
1671
  env->SetMethod(target, "isIP", IsIP);
1363
1671
  env->SetMethod(target, "isIPv4", IsIPv4);
1364
1671
  env->SetMethod(target, "isIPv6", IsIPv6);
1365
1366
1671
  env->SetMethod(target, "strerror", StrError);
1367
1671
  env->SetMethod(target, "getServers", GetServers);
1368
1671
  env->SetMethod(target, "setServers", SetServers);
1369
1370
6684
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET"),
1371
1671
              Integer::New(env->isolate(), AF_INET));
1372
6684
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET6"),
1373
1671
              Integer::New(env->isolate(), AF_INET6));
1374
6684
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AF_UNSPEC"),
1375
1671
              Integer::New(env->isolate(), AF_UNSPEC));
1376
6684
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AI_ADDRCONFIG"),
1377
1671
              Integer::New(env->isolate(), AI_ADDRCONFIG));
1378
6684
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AI_V4MAPPED"),
1379
1671
              Integer::New(env->isolate(), AI_V4MAPPED));
1380
1381
  Local<FunctionTemplate> aiw =
1382
3342
      FunctionTemplate::New(env->isolate(), NewGetAddrInfoReqWrap);
1383
3342
  aiw->InstanceTemplate()->SetInternalFieldCount(1);
1384
1671
  aiw->SetClassName(
1385
1671
      FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap"));
1386
6684
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap"),
1387
1671
              aiw->GetFunction());
1388
1389
  Local<FunctionTemplate> niw =
1390
3342
      FunctionTemplate::New(env->isolate(), NewGetNameInfoReqWrap);
1391
3342
  niw->InstanceTemplate()->SetInternalFieldCount(1);
1392
1671
  niw->SetClassName(
1393
1671
      FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap"));
1394
6684
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap"),
1395
1671
              niw->GetFunction());
1396
1397
  Local<FunctionTemplate> qrw =
1398
3342
      FunctionTemplate::New(env->isolate(), NewQueryReqWrap);
1399
3342
  qrw->InstanceTemplate()->SetInternalFieldCount(1);
1400
1671
  qrw->SetClassName(
1401
1671
      FIXED_ONE_BYTE_STRING(env->isolate(), "QueryReqWrap"));
1402
6684
  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "QueryReqWrap"),
1403
1671
              qrw->GetFunction());
1404
}
1405
1406
}  // namespace cares_wrap
1407
}  // namespace node
1408
1409
1729
NODE_MODULE_CONTEXT_AWARE_BUILTIN(cares_wrap, node::cares_wrap::Initialize)