22 #define CARES_STATICLIB 39 #include <unordered_set> 41 #if defined(__ANDROID__) || \ 42 defined(__MINGW32__) || \ 43 defined(__OpenBSD__) || \ 48 # include <arpa/nameser.h> 51 #if defined(__OpenBSD__) 52 # define AI_V4MAPPED 0 56 namespace cares_wrap {
60 using v8::EscapableHandleScope;
61 using v8::FunctionCallbackInfo;
62 using v8::FunctionTemplate;
63 using v8::HandleScope;
73 inline uint16_t cares_get_16bit(
const unsigned char*
p) {
74 return static_cast<uint32_t
>(p[0] << 8U) | (static_cast<uint32_t>(p[1]));
77 inline uint32_t cares_get_32bit(
const unsigned char* p) {
78 return static_cast<uint32_t
>(p[0] << 24U) |
79 static_cast<uint32_t>(p[1] << 16U) |
80 static_cast<uint32_t
>(p[2] << 8U) |
81 static_cast<uint32_t>(p[3]);
84 const int ns_t_cname_or_a = -1;
86 inline const char* ToErrorCodeString(
int status) {
88 #define V(code) case ARES_##code: return #code; 89 V(EADDRGETNETWORKPARAMS)
116 return "UNKNOWN_ARES_ERROR";
121 struct node_ares_task {
128 size_t operator()(node_ares_task*
a)
const {
129 return std::hash<ares_socket_t>()(a->sock);
134 inline bool operator()(node_ares_task*
a, node_ares_task* b)
const {
135 return a->sock == b->sock;
139 using node_ares_task_list =
140 std::unordered_set<node_ares_task*, TaskHash, TaskEqual>;
142 class ChannelWrap :
public AsyncWrap {
144 ChannelWrap(Environment* env, Local<Object>
object);
147 static void New(
const FunctionCallbackInfo<Value>& args);
150 void EnsureServers();
153 inline uv_timer_t* timer_handle() {
return timer_handle_; }
154 inline ares_channel cares_channel() {
return channel_; }
155 inline bool query_last_ok()
const {
return query_last_ok_; }
156 inline void set_query_last_ok(
bool ok) { query_last_ok_ = ok; }
157 inline bool is_servers_default()
const {
return is_servers_default_; }
158 inline void set_is_servers_default(
bool is_default) {
159 is_servers_default_ = is_default;
161 inline node_ares_task_list* task_list() {
return &task_list_; }
163 size_t self_size()
const override {
return sizeof(
this); }
165 static void AresTimeout(uv_timer_t* handle);
168 uv_timer_t* timer_handle_;
169 ares_channel channel_;
171 bool is_servers_default_;
172 bool library_inited_;
173 node_ares_task_list task_list_;
176 ChannelWrap::ChannelWrap(Environment* env,
177 Local<Object>
object)
178 : AsyncWrap(env,
object, PROVIDER_DNSCHANNEL),
179 timer_handle_(
nullptr),
181 query_last_ok_(
true),
182 is_servers_default_(
true),
183 library_inited_(
false) {
184 MakeWeak<ChannelWrap>(
this);
190 CHECK(args.IsConstructCall());
191 CHECK_EQ(args.Length(), 0);
193 Environment* env = Environment::GetCurrent(args);
194 new ChannelWrap(env, args.This());
197 class GetAddrInfoReqWrap :
public ReqWrap<uv_getaddrinfo_t> {
199 GetAddrInfoReqWrap(Environment* env,
200 Local<Object> req_wrap_obj,
202 ~GetAddrInfoReqWrap();
204 size_t self_size()
const override {
return sizeof(*this); }
205 bool verbatim()
const {
return verbatim_; }
208 const bool verbatim_;
211 GetAddrInfoReqWrap::GetAddrInfoReqWrap(Environment* env,
212 Local<Object> req_wrap_obj,
214 : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETADDRINFOREQWRAP)
215 , verbatim_(verbatim) {
216 Wrap(req_wrap_obj,
this);
219 GetAddrInfoReqWrap::~GetAddrInfoReqWrap() {
224 class GetNameInfoReqWrap :
public ReqWrap<uv_getnameinfo_t> {
226 GetNameInfoReqWrap(Environment* env, Local<Object> req_wrap_obj);
227 ~GetNameInfoReqWrap();
229 size_t self_size()
const override {
return sizeof(*this); }
232 GetNameInfoReqWrap::GetNameInfoReqWrap(Environment* env,
233 Local<Object> req_wrap_obj)
234 : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETNAMEINFOREQWRAP) {
235 Wrap(req_wrap_obj,
this);
238 GetNameInfoReqWrap::~GetNameInfoReqWrap() {
245 void ChannelWrap::AresTimeout(uv_timer_t* handle) {
246 ChannelWrap*
channel =
static_cast<ChannelWrap*
>(handle->data);
247 CHECK_EQ(channel->timer_handle(), handle);
248 CHECK_EQ(
false, channel->task_list()->empty());
249 ares_process_fd(channel->cares_channel(), ARES_SOCKET_BAD, ARES_SOCKET_BAD);
253 void ares_poll_cb(uv_poll_t* watcher,
int status,
int events) {
255 ChannelWrap*
channel = task->channel;
258 uv_timer_again(channel->timer_handle());
263 ares_process_fd(channel->cares_channel(), task->sock, task->sock);
268 ares_process_fd(channel->cares_channel(),
269 events & UV_READABLE ? task->sock : ARES_SOCKET_BAD,
270 events & UV_WRITABLE ? task->sock : ARES_SOCKET_BAD);
274 void ares_poll_close_cb(uv_handle_t* watcher) {
276 reinterpret_cast<uv_poll_t*>(watcher));
282 node_ares_task* ares_task_create(ChannelWrap*
channel, ares_socket_t
sock) {
283 auto task = node::UncheckedMalloc<node_ares_task>(1);
285 if (task ==
nullptr) {
293 if (uv_poll_init_socket(channel->env()->event_loop(),
294 &task->poll_watcher,
sock) < 0) {
305 void ares_sockstate_cb(
void*
data,
309 ChannelWrap* channel =
static_cast<ChannelWrap*
>(
data);
310 node_ares_task* task;
312 node_ares_task lookup_task;
313 lookup_task.sock =
sock;
314 auto it = channel->task_list()->find(&lookup_task);
316 task = (it == channel->task_list()->end()) ?
nullptr : *it;
323 uv_timer_t* timer_handle = channel->timer_handle();
324 if (!uv_is_active(reinterpret_cast<uv_handle_t*>(timer_handle))) {
325 CHECK(channel->task_list()->empty());
326 uv_timer_start(timer_handle, ChannelWrap::AresTimeout, 1000, 1000);
329 task = ares_task_create(channel, sock);
330 if (task ==
nullptr) {
337 channel->task_list()->insert(task);
342 uv_poll_start(&task->poll_watcher,
343 (read ? UV_READABLE : 0) | (write ? UV_WRITABLE : 0),
351 "When an ares socket is closed we should have a handle for it");
353 channel->task_list()->erase(it);
354 uv_close(reinterpret_cast<uv_handle_t*>(&task->poll_watcher),
357 if (channel->task_list()->empty()) {
358 uv_timer_stop(channel->timer_handle());
364 Local<Array> HostentToAddresses(Environment* env,
365 struct hostent*
host,
366 Local<Array> append_to = Local<Array>()) {
367 EscapableHandleScope scope(env->isolate());
368 auto context = env->context();
369 bool append = !append_to.IsEmpty();
370 Local<Array> addresses = append ? append_to :
Array::New(env->isolate());
371 size_t offset = addresses->Length();
373 char ip[INET6_ADDRSTRLEN];
374 for (uint32_t i = 0; host->h_addr_list[i] !=
nullptr; ++i) {
375 uv_inet_ntop(host->h_addrtype, host->h_addr_list[i], ip,
sizeof(ip));
376 Local<String> address = OneByteString(env->isolate(), ip);
377 addresses->Set(context, i + offset, address).FromJust();
380 return append ? addresses : scope.Escape(addresses);
384 Local<Array> HostentToNames(Environment* env,
385 struct hostent* host,
386 Local<Array> append_to = Local<Array>()) {
387 EscapableHandleScope scope(env->isolate());
388 auto context = env->context();
389 bool append = !append_to.IsEmpty();
390 Local<Array> names = append ? append_to :
Array::New(env->isolate());
391 size_t offset = names->Length();
393 for (uint32_t i = 0; host->h_aliases[i] !=
nullptr; ++i) {
394 Local<String> address = OneByteString(env->isolate(), host->h_aliases[i]);
395 names->Set(context, i + offset, address).FromJust();
398 return append ? names : scope.Escape(names);
401 void safe_free_hostent(
struct hostent* host) {
404 if (host->h_addr_list !=
nullptr) {
406 while (host->h_addr_list[idx]) {
407 free(host->h_addr_list[idx++]);
409 free(host->h_addr_list);
410 host->h_addr_list = 0;
413 if (host->h_aliases !=
nullptr) {
415 while (host->h_aliases[idx]) {
416 free(host->h_aliases[idx++]);
418 free(host->h_aliases);
422 if (host->h_name !=
nullptr) {
426 host->h_addrtype = host->h_length = 0;
429 void cares_wrap_hostent_cpy(
struct hostent* dest,
struct hostent* src) {
430 dest->h_addr_list =
nullptr;
431 dest->h_addrtype = 0;
432 dest->h_aliases =
nullptr;
434 dest->h_name =
nullptr;
437 size_t name_size = strlen(src->h_name) + 1;
438 dest->h_name = node::Malloc<char>(name_size);
439 memcpy(dest->h_name, src->h_name, name_size);
443 size_t cur_alias_length;
444 for (alias_count = 0;
445 src->h_aliases[alias_count] !=
nullptr;
449 dest->h_aliases = node::Malloc<char*>(alias_count + 1);
450 for (
size_t i = 0; i < alias_count; i++) {
451 cur_alias_length = strlen(src->h_aliases[i]);
452 dest->h_aliases[i] = node::Malloc(cur_alias_length + 1);
453 memcpy(dest->h_aliases[i], src->h_aliases[i], cur_alias_length + 1);
455 dest->h_aliases[alias_count] =
nullptr;
460 src->h_addr_list[list_count] !=
nullptr;
464 dest->h_addr_list = node::Malloc<char*>(list_count + 1);
465 for (
size_t i = 0; i < list_count; i++) {
466 dest->h_addr_list[i] = node::Malloc(src->h_length);
467 memcpy(dest->h_addr_list[i], src->h_addr_list[i], src->h_length);
469 dest->h_addr_list[list_count] =
nullptr;
472 dest->h_length = src->h_length;
473 dest->h_addrtype = src->h_addrtype;
477 struct CaresAsyncData {
490 void ChannelWrap::Setup() {
491 struct ares_options options;
492 memset(&options, 0,
sizeof(options));
493 options.flags = ARES_FLAG_NOCHECKRESP;
494 options.sock_state_cb = ares_sockstate_cb;
495 options.sock_state_cb_data =
this;
498 if (!library_inited_) {
501 r = ares_library_init(ARES_LIB_INIT_ALL);
502 if (r != ARES_SUCCESS)
503 return env()->ThrowError(ToErrorCodeString(r));
507 r = ares_init_options(&channel_,
509 ARES_OPT_FLAGS | ARES_OPT_SOCK_STATE_CB);
511 if (r != ARES_SUCCESS) {
512 ares_library_cleanup();
513 return env()->ThrowError(ToErrorCodeString(r));
516 library_inited_ =
true;
521 timer_handle_ =
new uv_timer_t();
522 timer_handle_->data =
static_cast<void*
>(
this);
523 uv_timer_init(env()->event_loop(), timer_handle_);
527 ChannelWrap::~ChannelWrap() {
528 if (library_inited_) {
530 ares_library_cleanup();
533 ares_destroy(channel_);
538 void ChannelWrap::CleanupTimer() {
539 if (timer_handle_ ==
nullptr)
return;
541 uv_close(reinterpret_cast<uv_handle_t*>(timer_handle_),
542 [](uv_handle_t* handle) {
543 delete reinterpret_cast<uv_timer_t*
>(handle);
545 timer_handle_ =
nullptr;
556 void ChannelWrap::EnsureServers() {
558 if (query_last_ok_ || !is_servers_default_) {
562 ares_addr_port_node* servers =
nullptr;
564 ares_get_servers_ports(channel_, &servers);
567 if (servers ==
nullptr)
return;
568 if (servers->next !=
nullptr) {
569 ares_free_data(servers);
570 is_servers_default_ =
false;
575 if (servers[0].family != AF_INET ||
576 servers[0].addr.addr4.s_addr != htonl(INADDR_LOOPBACK) ||
577 servers[0].tcp_port != 0 ||
578 servers[0].udp_port != 0) {
579 ares_free_data(servers);
580 is_servers_default_ =
false;
584 ares_free_data(servers);
588 ares_destroy(channel_);
594 class QueryWrap :
public AsyncWrap {
596 QueryWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
597 : AsyncWrap(channel->env(), req_wrap_obj, AsyncWrap::PROVIDER_QUERYWRAP),
599 if (env()->in_domain()) {
600 req_wrap_obj->Set(env()->domain_string(),
601 env()->domain_array()->Get(env()->context(), 0)
605 Wrap(req_wrap_obj,
this);
608 req_wrap_obj->Set(env()->context(),
609 env()->channel_string(),
610 channel->object()).FromJust();
613 ~QueryWrap()
override {
614 CHECK_EQ(
false, persistent().IsEmpty());
616 persistent().Reset();
620 virtual int Send(
const char* name) {
625 virtual int Send(
const char* name,
int family) {
631 void AresQuery(
const char* name,
634 channel_->EnsureServers();
635 ares_query(channel_->cares_channel(), name, dnsclass, type, Callback,
636 static_cast<void*
>(
this));
639 static void CaresAsyncClose(uv_handle_t* handle) {
640 uv_async_t* async =
reinterpret_cast<uv_async_t*
>(handle);
641 auto data =
static_cast<struct CaresAsyncData*
>(async->data);
646 static void CaresAsyncCb(uv_async_t* handle) {
647 auto data =
static_cast<struct CaresAsyncData*
>(handle->data);
649 QueryWrap*
wrap = data->wrap;
650 int status = data->status;
652 if (status != ARES_SUCCESS) {
653 wrap->ParseError(status);
654 }
else if (!data->is_host) {
655 unsigned char*
buf = data->data.buf;
656 wrap->Parse(buf, data->len);
659 hostent* host = data->data.host;
661 safe_free_hostent(host);
665 uv_close(reinterpret_cast<uv_handle_t*>(handle), CaresAsyncClose);
668 static void Callback(
void *arg,
int status,
int timeouts,
669 unsigned char* answer_buf,
int answer_len) {
670 QueryWrap*
wrap =
static_cast<QueryWrap*
>(arg);
672 unsigned char* buf_copy =
nullptr;
673 if (status == ARES_SUCCESS) {
674 buf_copy = node::Malloc<unsigned char>(answer_len);
675 memcpy(buf_copy, answer_buf, answer_len);
678 CaresAsyncData* data =
new CaresAsyncData();
681 data->is_host =
false;
682 data->data.buf = buf_copy;
683 data->len = answer_len;
686 CHECK_EQ(0, uv_async_init(wrap->env()->event_loop(),
690 wrap->channel_->set_query_last_ok(status != ARES_ECONNREFUSED);
691 async_handle->data =
data;
692 uv_async_send(async_handle);
695 static void Callback(
void *arg,
int status,
int timeouts,
696 struct hostent* host) {
697 QueryWrap*
wrap =
static_cast<QueryWrap*
>(arg);
699 struct hostent* host_copy =
nullptr;
700 if (status == ARES_SUCCESS) {
701 host_copy = node::Malloc<hostent>(1);
702 cares_wrap_hostent_cpy(host_copy, host);
705 CaresAsyncData* data =
new CaresAsyncData();
707 data->data.host = host_copy;
709 data->is_host =
true;
712 CHECK_EQ(0, uv_async_init(wrap->env()->event_loop(),
716 wrap->channel_->set_query_last_ok(status != ARES_ECONNREFUSED);
717 async_handle->data =
data;
718 uv_async_send(async_handle);
721 void CallOnComplete(Local<Value> answer,
722 Local<Value> extra = Local<Value>()) {
723 HandleScope handle_scope(env()->isolate());
724 Context::Scope context_scope(env()->context());
725 Local<Value> argv[] = {
730 const int argc = arraysize(argv) - extra.IsEmpty();
734 void ParseError(
int status) {
735 CHECK_NE(status, ARES_SUCCESS);
736 HandleScope handle_scope(env()->isolate());
737 Context::Scope context_scope(env()->context());
738 const char* code = ToErrorCodeString(status);
739 Local<Value> arg = OneByteString(env()->isolate(), code);
744 virtual void Parse(
unsigned char*
buf,
int len) {
748 virtual void Parse(
struct hostent* host) {
752 ChannelWrap* channel_;
757 Local<Array> AddrTTLToArray(Environment* env,
760 auto isolate = env->isolate();
761 EscapableHandleScope escapable_handle_scope(isolate);
762 auto context = env->context();
764 Local<Array> ttls =
Array::New(isolate, naddrttls);
765 for (
size_t i = 0; i < naddrttls; i++) {
767 ttls->Set(context, i, value).FromJust();
770 return escapable_handle_scope.Escape(ttls);
774 int ParseGeneralReply(Environment* env,
775 const unsigned char*
buf,
779 void* addrttls =
nullptr,
780 int* naddrttls =
nullptr) {
781 HandleScope handle_scope(env->isolate());
782 auto context = env->context();
789 case ns_t_cname_or_a:
790 status = ares_parse_a_reply(buf,
793 static_cast<ares_addrttl*>(addrttls),
797 status = ares_parse_aaaa_reply(buf,
800 static_cast<ares_addr6ttl*>(addrttls),
804 status = ares_parse_ns_reply(buf, len, &host);
807 status = ares_parse_ptr_reply(buf, len, NULL, 0, AF_INET, &host);
810 CHECK(0 &&
"Bad NS type");
814 if (status != ARES_SUCCESS)
820 if ((*type == ns_t_cname_or_a && host->h_name && host->h_aliases[0]) ||
821 *type == ns_t_cname) {
827 OneByteString(env->isolate(), host->h_name)).FromJust();
828 ares_free_hostent(host);
832 if (*type == ns_t_cname_or_a)
835 if (*type == ns_t_ns) {
836 HostentToNames(env, host, ret);
837 }
else if (*type == ns_t_ptr) {
838 uint32_t offset = ret->Length();
839 for (uint32_t i = 0; host->h_aliases[i] != NULL; i++) {
842 OneByteString(env->isolate(), host->h_aliases[i])).FromJust();
845 HostentToAddresses(env, host, ret);
848 ares_free_hostent(host);
854 int ParseMxReply(Environment* env,
855 const unsigned char* buf,
858 bool need_type =
false) {
859 HandleScope handle_scope(env->isolate());
860 auto context = env->context();
862 struct ares_mx_reply* mx_start;
863 int status = ares_parse_mx_reply(buf, len, &mx_start);
864 if (status != ARES_SUCCESS) {
868 Local<String> exchange_symbol = env->exchange_string();
869 Local<String> priority_symbol = env->priority_string();
870 Local<String> type_symbol = env->type_string();
871 Local<String> mx_symbol = env->dns_mx_string();
873 uint32_t offset = ret->Length();
874 ares_mx_reply* current = mx_start;
875 for (uint32_t i = 0; current !=
nullptr; ++i, current = current->next) {
876 Local<Object> mx_record =
Object::New(env->isolate());
877 mx_record->Set(context,
879 OneByteString(env->isolate(), current->host)).FromJust();
880 mx_record->Set(context,
882 Integer::New(env->isolate(), current->priority)).FromJust();
884 mx_record->Set(context, type_symbol, mx_symbol).FromJust();
886 ret->Set(context, i + offset, mx_record).FromJust();
889 ares_free_data(mx_start);
893 int ParseTxtReply(Environment* env,
894 const unsigned char* buf,
897 bool need_type =
false) {
898 HandleScope handle_scope(env->isolate());
899 auto context = env->context();
901 struct ares_txt_ext* txt_out;
903 int status = ares_parse_txt_reply_ext(buf, len, &txt_out);
904 if (status != ARES_SUCCESS) {
908 Local<Array> txt_chunk;
910 struct ares_txt_ext* current = txt_out;
912 uint32_t offset = ret->Length();
913 for (j = 0; current !=
nullptr; current = current->next) {
914 Local<String> txt = OneByteString(env->isolate(), current->txt);
917 if (current->record_start) {
918 if (!txt_chunk.IsEmpty()) {
921 elem->Set(context, env->entries_string(), txt_chunk).FromJust();
924 env->dns_txt_string()).FromJust();
925 ret->Set(context, offset + i++, elem).FromJust();
927 ret->Set(context, offset + i++, txt_chunk).FromJust();
935 txt_chunk->Set(context, j++, txt).FromJust();
939 if (!txt_chunk.IsEmpty()) {
942 elem->Set(context, env->entries_string(), txt_chunk).FromJust();
945 env->dns_txt_string()).FromJust();
946 ret->Set(context, offset + i, elem).FromJust();
948 ret->Set(context, offset + i, txt_chunk).FromJust();
952 ares_free_data(txt_out);
957 int ParseSrvReply(Environment* env,
958 const unsigned char* buf,
961 bool need_type =
false) {
962 HandleScope handle_scope(env->isolate());
963 auto context = env->context();
965 struct ares_srv_reply* srv_start;
966 int status = ares_parse_srv_reply(buf, len, &srv_start);
967 if (status != ARES_SUCCESS) {
971 Local<String> name_symbol = env->name_string();
972 Local<String> port_symbol = env->port_string();
973 Local<String> priority_symbol = env->priority_string();
974 Local<String> weight_symbol = env->weight_string();
975 Local<String> type_symbol = env->type_string();
976 Local<String> srv_symbol = env->dns_srv_string();
978 ares_srv_reply* current = srv_start;
979 int offset = ret->Length();
980 for (uint32_t i = 0; current !=
nullptr; ++i, current = current->next) {
981 Local<Object> srv_record =
Object::New(env->isolate());
982 srv_record->Set(context,
984 OneByteString(env->isolate(), current->host)).FromJust();
985 srv_record->Set(context,
987 Integer::New(env->isolate(), current->port)).FromJust();
988 srv_record->Set(context,
990 Integer::New(env->isolate(), current->priority)).FromJust();
991 srv_record->Set(context,
993 Integer::New(env->isolate(), current->weight)).FromJust();
995 srv_record->Set(context, type_symbol, srv_symbol).FromJust();
997 ret->Set(context, i + offset, srv_record).FromJust();
1000 ares_free_data(srv_start);
1001 return ARES_SUCCESS;
1005 int ParseNaptrReply(Environment* env,
1006 const unsigned char* buf,
1009 bool need_type =
false) {
1010 HandleScope handle_scope(env->isolate());
1011 auto context = env->context();
1013 ares_naptr_reply* naptr_start;
1014 int status = ares_parse_naptr_reply(buf, len, &naptr_start);
1016 if (status != ARES_SUCCESS) {
1020 Local<String> flags_symbol = env->flags_string();
1021 Local<String> service_symbol = env->service_string();
1022 Local<String> regexp_symbol = env->regexp_string();
1023 Local<String> replacement_symbol = env->replacement_string();
1024 Local<String> order_symbol = env->order_string();
1025 Local<String> preference_symbol = env->preference_string();
1026 Local<String> type_symbol = env->type_string();
1027 Local<String> naptr_symbol = env->dns_naptr_string();
1029 ares_naptr_reply* current = naptr_start;
1030 int offset = ret->Length();
1031 for (uint32_t i = 0; current !=
nullptr; ++i, current = current->next) {
1032 Local<Object> naptr_record =
Object::New(env->isolate());
1033 naptr_record->Set(context,
1035 OneByteString(env->isolate(), current->flags)).FromJust();
1036 naptr_record->Set(context,
1038 OneByteString(env->isolate(),
1039 current->service)).FromJust();
1040 naptr_record->Set(context,
1042 OneByteString(env->isolate(),
1043 current->regexp)).FromJust();
1044 naptr_record->Set(context,
1046 OneByteString(env->isolate(),
1047 current->replacement)).FromJust();
1048 naptr_record->Set(context,
1050 Integer::New(env->isolate(), current->order)).FromJust();
1051 naptr_record->Set(context,
1054 current->preference)).FromJust();
1056 naptr_record->Set(context, type_symbol, naptr_symbol).FromJust();
1058 ret->Set(context, i + offset, naptr_record).FromJust();
1061 ares_free_data(naptr_start);
1062 return ARES_SUCCESS;
1066 int ParseSoaReply(Environment* env,
1069 Local<Object>* ret) {
1070 EscapableHandleScope handle_scope(env->isolate());
1071 auto context = env->context();
1074 unsigned int ancount = cares_get_16bit(buf + 6);
1075 unsigned char* ptr = buf + NS_HFIXEDSZ;
1076 int rr_type, rr_len;
1080 int status = ares_expand_name(ptr, buf, len, &name, &temp_len);
1081 if (status != ARES_SUCCESS) {
1083 return status == ARES_EBADNAME ? ARES_EBADRESP :
status;
1086 if (ptr + temp_len + NS_QFIXEDSZ > buf + len) {
1088 return ARES_EBADRESP;
1090 ptr += temp_len + NS_QFIXEDSZ;
1092 for (
unsigned int i = 0; i < ancount; i++) {
1093 status = ares_expand_name(ptr, buf, len, &rr_name, &temp_len);
1095 if (status != ARES_SUCCESS)
1099 if (ptr + NS_RRFIXEDSZ > buf + len) {
1101 status = ARES_EBADRESP;
1105 rr_type = cares_get_16bit(ptr);
1106 rr_len = cares_get_16bit(ptr + 8);
1107 ptr += NS_RRFIXEDSZ;
1110 if (rr_type == ns_t_soa) {
1113 status = ares_expand_name(ptr, buf, len, &soa.nsname, &temp_len);
1114 if (status != ARES_SUCCESS) {
1120 status = ares_expand_name(ptr, buf, len, &soa.hostmaster, &temp_len);
1121 if (status != ARES_SUCCESS) {
1128 if (ptr + 5 * 4 > buf + len) {
1131 free(soa.hostmaster);
1132 status = ARES_EBADRESP;
1136 soa.serial = cares_get_32bit(ptr + 0 * 4);
1137 soa.refresh = cares_get_32bit(ptr + 1 * 4);
1138 soa.retry = cares_get_32bit(ptr + 2 * 4);
1139 soa.expire = cares_get_32bit(ptr + 3 * 4);
1140 soa.minttl = cares_get_32bit(ptr + 4 * 4);
1142 Local<Object> soa_record =
Object::New(env->isolate());
1143 soa_record->Set(context,
1144 env->nsname_string(),
1145 OneByteString(env->isolate(), soa.nsname)).FromJust();
1146 soa_record->Set(context,
1147 env->hostmaster_string(),
1148 OneByteString(env->isolate(),
1149 soa.hostmaster)).FromJust();
1150 soa_record->Set(context,
1151 env->serial_string(),
1153 soa_record->Set(context,
1154 env->refresh_string(),
1156 soa_record->Set(context,
1157 env->retry_string(),
1159 soa_record->Set(context,
1160 env->expire_string(),
1162 soa_record->Set(context,
1163 env->minttl_string(),
1165 soa_record->Set(context,
1167 env->dns_soa_string()).FromJust();
1170 free(soa.hostmaster);
1172 *ret = handle_scope.Escape(soa_record);
1182 if (status != ARES_SUCCESS) {
1183 return status == ARES_EBADNAME ? ARES_EBADRESP :
status;
1186 return ARES_SUCCESS;
1190 class QueryAnyWrap:
public QueryWrap {
1192 QueryAnyWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
1193 : QueryWrap(channel, req_wrap_obj) {
1196 int Send(
const char* name)
override {
1197 AresQuery(name, ns_c_in, ns_t_any);
1201 size_t self_size()
const override {
return sizeof(*this); }
1204 void Parse(
unsigned char* buf,
int len)
override {
1205 HandleScope handle_scope(env()->isolate());
1206 auto context = env()->context();
1207 Context::Scope context_scope(context);
1209 Local<Array> ret =
Array::New(env()->isolate());
1210 int type,
status, old_count;
1213 ares_addrttl addrttls[256];
1214 int naddrttls = arraysize(addrttls);
1216 type = ns_t_cname_or_a;
1217 status = ParseGeneralReply(env(),
1224 int a_count = ret->Length();
1225 if (status != ARES_SUCCESS && status != ARES_ENODATA) {
1230 if (type == ns_t_a) {
1231 CHECK_EQ(naddrttls, a_count);
1232 for (
int i = 0; i < a_count; i++) {
1233 Local<Object> obj =
Object::New(env()->isolate());
1234 obj->Set(context, env()->address_string(), ret->Get(i)).FromJust();
1236 env()->ttl_string(),
1237 Integer::New(env()->isolate(), addrttls[i].ttl)).FromJust();
1239 env()->type_string(),
1240 env()->dns_a_string()).FromJust();
1241 ret->Set(context, i, obj).FromJust();
1244 for (
int i = 0; i < a_count; i++) {
1245 Local<Object> obj =
Object::New(env()->isolate());
1246 obj->Set(context, env()->value_string(), ret->Get(i)).FromJust();
1248 env()->type_string(),
1249 env()->dns_cname_string()).FromJust();
1250 ret->Set(context, i, obj).FromJust();
1255 ares_addr6ttl addr6ttls[256];
1256 int naddr6ttls = arraysize(addr6ttls);
1259 status = ParseGeneralReply(env(),
1266 int aaaa_count = ret->Length() - a_count;
1267 if (status != ARES_SUCCESS && status != ARES_ENODATA) {
1272 CHECK_EQ(aaaa_count, naddr6ttls);
1273 for (uint32_t i = a_count; i < ret->Length(); i++) {
1274 Local<Object> obj =
Object::New(env()->isolate());
1275 obj->Set(context, env()->address_string(), ret->Get(i)).FromJust();
1277 env()->ttl_string(),
1278 Integer::New(env()->isolate(), addr6ttls[i].ttl)).FromJust();
1280 env()->type_string(),
1281 env()->dns_aaaa_string()).FromJust();
1282 ret->Set(context, i, obj).FromJust();
1286 status = ParseMxReply(env(), buf, len, ret,
true);
1287 if (status != ARES_SUCCESS && status != ARES_ENODATA) {
1294 old_count = ret->Length();
1295 status = ParseGeneralReply(env(), buf, len, &type, ret);
1296 if (status != ARES_SUCCESS && status != ARES_ENODATA) {
1300 for (uint32_t i = old_count; i < ret->Length(); i++) {
1301 Local<Object> obj =
Object::New(env()->isolate());
1302 obj->Set(context, env()->value_string(), ret->Get(i)).FromJust();
1304 env()->type_string(),
1305 env()->dns_ns_string()).FromJust();
1306 ret->Set(context, i, obj).FromJust();
1310 status = ParseTxtReply(env(), buf, len, ret,
true);
1311 if (status != ARES_SUCCESS && status != ARES_ENODATA) {
1317 status = ParseSrvReply(env(), buf, len, ret,
true);
1318 if (status != ARES_SUCCESS && status != ARES_ENODATA) {
1324 old_count = ret->Length();
1325 status = ParseGeneralReply(env(), buf, len, &type, ret);
1326 for (uint32_t i = old_count; i < ret->Length(); i++) {
1327 Local<Object> obj =
Object::New(env()->isolate());
1328 obj->Set(context, env()->value_string(), ret->Get(i)).FromJust();
1330 env()->type_string(),
1331 env()->dns_ptr_string()).FromJust();
1332 ret->Set(context, i, obj).FromJust();
1336 status = ParseNaptrReply(env(), buf, len, ret,
true);
1337 if (status != ARES_SUCCESS && status != ARES_ENODATA) {
1343 Local<Object> soa_record = Local<Object>();
1344 status = ParseSoaReply(env(), buf, len, &soa_record);
1345 if (status != ARES_SUCCESS && status != ARES_ENODATA) {
1349 if (!soa_record.IsEmpty())
1350 ret->Set(context, ret->Length(), soa_record).FromJust();
1352 CallOnComplete(ret);
1357 class QueryAWrap:
public QueryWrap {
1359 QueryAWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
1360 : QueryWrap(channel, req_wrap_obj) {
1363 int Send(
const char* name)
override {
1364 AresQuery(name, ns_c_in, ns_t_a);
1368 size_t self_size()
const override {
return sizeof(*this); }
1371 void Parse(
unsigned char* buf,
int len)
override {
1372 HandleScope handle_scope(env()->isolate());
1373 Context::Scope context_scope(env()->context());
1375 ares_addrttl addrttls[256];
1376 int naddrttls = arraysize(addrttls),
status;
1377 Local<Array> ret =
Array::New(env()->isolate());
1380 status = ParseGeneralReply(env(),
1387 if (status != ARES_SUCCESS) {
1392 Local<Array> ttls = AddrTTLToArray<ares_addrttl>(env(),
1396 CallOnComplete(ret, ttls);
1401 class QueryAaaaWrap:
public QueryWrap {
1403 QueryAaaaWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
1404 : QueryWrap(channel, req_wrap_obj) {
1407 int Send(
const char* name)
override {
1408 AresQuery(name, ns_c_in, ns_t_aaaa);
1412 size_t self_size()
const override {
return sizeof(*this); }
1415 void Parse(
unsigned char* buf,
int len)
override {
1416 HandleScope handle_scope(env()->isolate());
1417 Context::Scope context_scope(env()->context());
1419 ares_addr6ttl addrttls[256];
1420 int naddrttls = arraysize(addrttls),
status;
1421 Local<Array> ret =
Array::New(env()->isolate());
1423 int type = ns_t_aaaa;
1424 status = ParseGeneralReply(env(),
1431 if (status != ARES_SUCCESS) {
1436 Local<Array> ttls = AddrTTLToArray<ares_addr6ttl>(env(),
1440 CallOnComplete(ret, ttls);
1445 class QueryCnameWrap:
public QueryWrap {
1447 QueryCnameWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
1448 : QueryWrap(channel, req_wrap_obj) {
1451 int Send(
const char* name)
override {
1452 AresQuery(name, ns_c_in, ns_t_cname);
1456 size_t self_size()
const override {
return sizeof(*this); }
1459 void Parse(
unsigned char* buf,
int len)
override {
1460 HandleScope handle_scope(env()->isolate());
1461 Context::Scope context_scope(env()->context());
1463 Local<Array> ret =
Array::New(env()->isolate());
1464 int type = ns_t_cname;
1465 int status = ParseGeneralReply(env(), buf, len, &type, ret);
1466 if (status != ARES_SUCCESS) {
1471 this->CallOnComplete(ret);
1476 class QueryMxWrap:
public QueryWrap {
1478 QueryMxWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
1479 : QueryWrap(channel, req_wrap_obj) {
1482 int Send(
const char* name)
override {
1483 AresQuery(name, ns_c_in, ns_t_mx);
1487 size_t self_size()
const override {
return sizeof(*this); }
1490 void Parse(
unsigned char* buf,
int len)
override {
1491 HandleScope handle_scope(env()->isolate());
1492 Context::Scope context_scope(env()->context());
1494 Local<Array> mx_records =
Array::New(env()->isolate());
1495 int status = ParseMxReply(env(), buf, len, mx_records);
1497 if (status != ARES_SUCCESS) {
1502 this->CallOnComplete(mx_records);
1507 class QueryNsWrap:
public QueryWrap {
1509 QueryNsWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
1510 : QueryWrap(channel, req_wrap_obj) {
1513 int Send(
const char* name)
override {
1514 AresQuery(name, ns_c_in, ns_t_ns);
1518 size_t self_size()
const override {
return sizeof(*this); }
1521 void Parse(
unsigned char* buf,
int len)
override {
1522 HandleScope handle_scope(env()->isolate());
1523 Context::Scope context_scope(env()->context());
1526 Local<Array> names =
Array::New(env()->isolate());
1527 int status = ParseGeneralReply(env(), buf, len, &type, names);
1528 if (status != ARES_SUCCESS) {
1533 this->CallOnComplete(names);
1538 class QueryTxtWrap:
public QueryWrap {
1540 QueryTxtWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
1541 : QueryWrap(channel, req_wrap_obj) {
1544 int Send(
const char* name)
override {
1545 AresQuery(name, ns_c_in, ns_t_txt);
1549 size_t self_size()
const override {
return sizeof(*this); }
1552 void Parse(
unsigned char* buf,
int len)
override {
1553 HandleScope handle_scope(env()->isolate());
1554 Context::Scope context_scope(env()->context());
1556 Local<Array> txt_records =
Array::New(env()->isolate());
1557 int status = ParseTxtReply(env(), buf, len, txt_records);
1558 if (status != ARES_SUCCESS) {
1563 this->CallOnComplete(txt_records);
1568 class QuerySrvWrap:
public QueryWrap {
1570 explicit QuerySrvWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
1571 : QueryWrap(channel, req_wrap_obj) {
1574 int Send(
const char* name)
override {
1575 AresQuery(name, ns_c_in, ns_t_srv);
1579 size_t self_size()
const override {
return sizeof(*this); }
1582 void Parse(
unsigned char* buf,
int len)
override {
1583 HandleScope handle_scope(env()->isolate());
1584 Context::Scope context_scope(env()->context());
1586 Local<Array> srv_records =
Array::New(env()->isolate());
1587 int status = ParseSrvReply(env(), buf, len, srv_records);
1588 if (status != ARES_SUCCESS) {
1593 this->CallOnComplete(srv_records);
1597 class QueryPtrWrap:
public QueryWrap {
1599 explicit QueryPtrWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
1600 : QueryWrap(channel, req_wrap_obj) {
1603 int Send(
const char* name)
override {
1604 AresQuery(name, ns_c_in, ns_t_ptr);
1608 size_t self_size()
const override {
return sizeof(*this); }
1611 void Parse(
unsigned char* buf,
int len)
override {
1612 HandleScope handle_scope(env()->isolate());
1613 Context::Scope context_scope(env()->context());
1615 int type = ns_t_ptr;
1616 Local<Array> aliases =
Array::New(env()->isolate());
1618 int status = ParseGeneralReply(env(), buf, len, &type, aliases);
1619 if (status != ARES_SUCCESS) {
1624 this->CallOnComplete(aliases);
1628 class QueryNaptrWrap:
public QueryWrap {
1630 explicit QueryNaptrWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
1631 : QueryWrap(channel, req_wrap_obj) {
1634 int Send(
const char* name)
override {
1635 AresQuery(name, ns_c_in, ns_t_naptr);
1639 size_t self_size()
const override {
return sizeof(*this); }
1642 void Parse(
unsigned char* buf,
int len)
override {
1643 HandleScope handle_scope(env()->isolate());
1644 Context::Scope context_scope(env()->context());
1646 Local<Array> naptr_records =
Array::New(env()->isolate());
1647 int status = ParseNaptrReply(env(), buf, len, naptr_records);
1648 if (status != ARES_SUCCESS) {
1653 this->CallOnComplete(naptr_records);
1658 class QuerySoaWrap:
public QueryWrap {
1660 QuerySoaWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
1661 : QueryWrap(channel, req_wrap_obj) {
1664 int Send(
const char* name)
override {
1665 AresQuery(name, ns_c_in, ns_t_soa);
1669 size_t self_size()
const override {
return sizeof(*this); }
1672 void Parse(
unsigned char* buf,
int len)
override {
1673 HandleScope handle_scope(env()->isolate());
1674 auto context = env()->context();
1675 Context::Scope context_scope(context);
1677 ares_soa_reply* soa_out;
1678 int status = ares_parse_soa_reply(buf, len, &soa_out);
1680 if (status != ARES_SUCCESS) {
1685 Local<Object> soa_record =
Object::New(env()->isolate());
1687 soa_record->Set(context,
1688 env()->nsname_string(),
1689 OneByteString(env()->isolate(),
1690 soa_out->nsname)).FromJust();
1691 soa_record->Set(context,
1692 env()->hostmaster_string(),
1693 OneByteString(env()->isolate(),
1694 soa_out->hostmaster)).FromJust();
1695 soa_record->Set(context,
1696 env()->serial_string(),
1697 Integer::New(env()->isolate(), soa_out->serial)).FromJust();
1698 soa_record->Set(context,
1699 env()->refresh_string(),
1701 soa_out->refresh)).FromJust();
1702 soa_record->Set(context,
1703 env()->retry_string(),
1704 Integer::New(env()->isolate(), soa_out->retry)).FromJust();
1705 soa_record->Set(context,
1706 env()->expire_string(),
1707 Integer::New(env()->isolate(), soa_out->expire)).FromJust();
1708 soa_record->Set(context,
1709 env()->minttl_string(),
1710 Integer::New(env()->isolate(), soa_out->minttl)).FromJust();
1712 ares_free_data(soa_out);
1714 this->CallOnComplete(soa_record);
1719 class GetHostByAddrWrap:
public QueryWrap {
1721 explicit GetHostByAddrWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
1722 : QueryWrap(channel, req_wrap_obj) {
1725 int Send(
const char* name)
override {
1727 char address_buffer[
sizeof(
struct in6_addr)];
1729 if (uv_inet_pton(AF_INET, name, &address_buffer) == 0) {
1730 length =
sizeof(
struct in_addr);
1732 }
else if (uv_inet_pton(AF_INET6, name, &address_buffer) == 0) {
1733 length =
sizeof(
struct in6_addr);
1739 ares_gethostbyaddr(channel_->cares_channel(),
1744 static_cast<void*
>(
static_cast<QueryWrap*
>(
this)));
1748 size_t self_size()
const override {
return sizeof(*this); }
1751 void Parse(
struct hostent* host)
override {
1752 HandleScope handle_scope(env()->isolate());
1753 Context::Scope context_scope(env()->context());
1754 this->CallOnComplete(HostentToNames(env(), host));
1759 class GetHostByNameWrap:
public QueryWrap {
1761 explicit GetHostByNameWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
1762 : QueryWrap(channel, req_wrap_obj) {
1765 int Send(
const char* name,
int family)
override {
1766 ares_gethostbyname(channel_->cares_channel(),
1770 static_cast<void*
>(
static_cast<QueryWrap*
>(
this)));
1775 void Parse(
struct hostent* host)
override {
1776 HandleScope scope(env()->isolate());
1778 Local<Array> addresses = HostentToAddresses(env(), host);
1779 Local<Integer> family =
Integer::New(env()->isolate(), host->h_addrtype);
1781 this->CallOnComplete(addresses, family);
1786 template <
class Wrap>
1787 static void Query(
const FunctionCallbackInfo<Value>& args) {
1788 Environment* env = Environment::GetCurrent(args);
1790 ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder());
1792 CHECK_EQ(
false, args.IsConstructCall());
1793 CHECK(args[0]->IsObject());
1794 CHECK(args[1]->IsString());
1796 Local<Object> req_wrap_obj = args[0].As<Object>();
1797 Local<String>
string = args[1].As<String>();
1798 Wrap*
wrap =
new Wrap(channel, req_wrap_obj);
1800 node::Utf8Value name(env->isolate(), string);
1801 int err = wrap->Send(*name);
1805 args.GetReturnValue().Set(err);
1809 void AfterGetAddrInfo(uv_getaddrinfo_t*
req,
int status,
struct addrinfo* res) {
1810 GetAddrInfoReqWrap* req_wrap =
static_cast<GetAddrInfoReqWrap*
>(req->data);
1811 Environment* env = req_wrap->env();
1813 HandleScope handle_scope(env->isolate());
1814 Context::Scope context_scope(env->context());
1816 Local<Value> argv[] = {
1818 Null(env->isolate())
1823 Local<Array> results =
Array::New(env->isolate());
1825 auto add = [&] (
bool want_ipv4,
bool want_ipv6) {
1826 for (
auto p = res; p !=
nullptr; p = p->ai_next) {
1827 CHECK_EQ(p->ai_socktype, SOCK_STREAM);
1830 if (want_ipv4 && p->ai_family == AF_INET) {
1831 addr =
reinterpret_cast<char*
>(
1832 &(
reinterpret_cast<struct sockaddr_in*
>(p->ai_addr)->sin_addr));
1833 }
else if (want_ipv6 && p->ai_family == AF_INET6) {
1834 addr =
reinterpret_cast<char*
>(
1835 &(
reinterpret_cast<struct sockaddr_in6*
>(p->ai_addr)->sin6_addr));
1840 char ip[INET6_ADDRSTRLEN];
1841 if (uv_inet_ntop(p->ai_family, addr, ip,
sizeof(ip)))
1844 Local<String>
s = OneByteString(env->isolate(), ip);
1850 const bool verbatim = req_wrap->verbatim();
1851 add(
true, verbatim);
1852 if (verbatim ==
false)
1863 uv_freeaddrinfo(res);
1866 req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv);
1872 void AfterGetNameInfo(uv_getnameinfo_t* req,
1874 const char* hostname,
1875 const char* service) {
1876 GetNameInfoReqWrap* req_wrap =
static_cast<GetNameInfoReqWrap*
>(req->data);
1877 Environment* env = req_wrap->env();
1879 HandleScope handle_scope(env->isolate());
1880 Context::Scope context_scope(env->context());
1882 Local<Value> argv[] = {
1884 Null(env->isolate()),
1885 Null(env->isolate())
1890 Local<String> js_hostname = OneByteString(env->isolate(), hostname);
1891 Local<String> js_service = OneByteString(env->isolate(), service);
1892 argv[1] = js_hostname;
1893 argv[2] = js_service;
1897 req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv);
1903 void IsIP(
const FunctionCallbackInfo<Value>& args) {
1904 node::Utf8Value ip(args.GetIsolate(), args[0]);
1905 char address_buffer[
sizeof(
struct in6_addr)];
1908 if (uv_inet_pton(AF_INET, *ip, &address_buffer) == 0)
1910 else if (uv_inet_pton(AF_INET6, *ip, &address_buffer) == 0)
1913 args.GetReturnValue().Set(rc);
1916 void IsIPv4(
const FunctionCallbackInfo<Value>& args) {
1917 node::Utf8Value ip(args.GetIsolate(), args[0]);
1918 char address_buffer[
sizeof(
struct in_addr)];
1920 if (uv_inet_pton(AF_INET, *ip, &address_buffer) == 0) {
1921 args.GetReturnValue().Set(
true);
1923 args.GetReturnValue().Set(
false);
1927 void IsIPv6(
const FunctionCallbackInfo<Value>& args) {
1928 node::Utf8Value ip(args.GetIsolate(), args[0]);
1929 char address_buffer[
sizeof(
struct in6_addr)];
1931 if (uv_inet_pton(AF_INET6, *ip, &address_buffer) == 0) {
1932 args.GetReturnValue().Set(
true);
1934 args.GetReturnValue().Set(
false);
1938 void GetAddrInfo(
const FunctionCallbackInfo<Value>& args) {
1939 Environment* env = Environment::GetCurrent(args);
1941 CHECK(args[0]->IsObject());
1942 CHECK(args[1]->IsString());
1943 CHECK(args[2]->IsInt32());
1944 CHECK(args[4]->IsBoolean());
1945 Local<Object> req_wrap_obj = args[0].As<Object>();
1946 node::Utf8Value hostname(env->isolate(), args[1]);
1948 int32_t flags = (args[3]->IsInt32()) ? args[3]->Int32Value() : 0;
1951 switch (args[2]->Int32Value()) {
1962 CHECK(0 &&
"bad address family");
1965 auto req_wrap =
new GetAddrInfoReqWrap(env, req_wrap_obj, args[4]->IsTrue());
1967 struct addrinfo hints;
1968 memset(&hints, 0,
sizeof(
struct addrinfo));
1969 hints.ai_family = family;
1970 hints.ai_socktype = SOCK_STREAM;
1971 hints.ai_flags = flags;
1973 int err = uv_getaddrinfo(env->event_loop(),
1979 req_wrap->Dispatched();
1983 args.GetReturnValue().Set(err);
1987 void GetNameInfo(
const FunctionCallbackInfo<Value>& args) {
1988 Environment* env = Environment::GetCurrent(args);
1990 CHECK(args[0]->IsObject());
1991 CHECK(args[1]->IsString());
1992 CHECK(args[2]->IsUint32());
1993 Local<Object> req_wrap_obj = args[0].As<Object>();
1994 node::Utf8Value ip(env->isolate(), args[1]);
1995 const unsigned port = args[2]->Uint32Value();
1996 struct sockaddr_storage addr;
1998 CHECK(uv_ip4_addr(*ip, port, reinterpret_cast<sockaddr_in*>(&addr)) == 0 ||
1999 uv_ip6_addr(*ip, port, reinterpret_cast<sockaddr_in6*>(&addr)) == 0);
2001 GetNameInfoReqWrap* req_wrap =
new GetNameInfoReqWrap(env, req_wrap_obj);
2003 int err = uv_getnameinfo(env->event_loop(),
2006 (
struct sockaddr*)&addr,
2008 req_wrap->Dispatched();
2012 args.GetReturnValue().Set(err);
2016 void GetServers(
const FunctionCallbackInfo<Value>& args) {
2017 Environment* env = Environment::GetCurrent(args);
2019 ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder());
2021 Local<Array> server_array =
Array::New(env->isolate());
2023 ares_addr_port_node* servers;
2025 int r = ares_get_servers_ports(channel->cares_channel(), &servers);
2026 CHECK_EQ(r, ARES_SUCCESS);
2028 ares_addr_port_node* cur = servers;
2030 for (uint32_t i = 0; cur !=
nullptr; ++i, cur = cur->next) {
2031 char ip[INET6_ADDRSTRLEN];
2033 const void* caddr =
static_cast<const void*
>(&cur->addr);
2034 int err = uv_inet_ntop(cur->family, caddr, ip,
sizeof(ip));
2037 Local<Array> ret =
Array::New(env->isolate(), 2);
2038 ret->Set(0, OneByteString(env->isolate(), ip));
2039 ret->Set(1,
Integer::New(env->isolate(), cur->udp_port));
2041 server_array->Set(i, ret);
2044 ares_free_data(servers);
2046 args.GetReturnValue().Set(server_array);
2050 void SetServers(
const FunctionCallbackInfo<Value>& args) {
2051 Environment* env = Environment::GetCurrent(args);
2053 ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder());
2055 CHECK(args[0]->IsArray());
2057 Local<Array> arr = Local<Array>::Cast(args[0]);
2059 uint32_t len = arr->Length();
2062 int rv = ares_set_servers(channel->cares_channel(),
nullptr);
2063 return args.GetReturnValue().Set(rv);
2066 std::vector<ares_addr_port_node> servers(len);
2067 ares_addr_port_node* last =
nullptr;
2071 for (uint32_t i = 0; i <
len; i++) {
2072 CHECK(arr->Get(i)->IsArray());
2074 Local<Array> elm = Local<Array>::Cast(arr->Get(i));
2076 CHECK(elm->Get(0)->Int32Value());
2077 CHECK(elm->Get(1)->IsString());
2078 CHECK(elm->Get(2)->Int32Value());
2080 int fam = elm->Get(0)->Int32Value();
2081 node::Utf8Value ip(env->isolate(), elm->Get(1));
2082 int port = elm->Get(2)->Int32Value();
2084 ares_addr_port_node* cur = &servers[i];
2086 cur->tcp_port = cur->udp_port = port;
2089 cur->family = AF_INET;
2090 err = uv_inet_pton(AF_INET, *ip, &cur->addr);
2093 cur->family = AF_INET6;
2094 err = uv_inet_pton(AF_INET6, *ip, &cur->addr);
2097 CHECK(0 &&
"Bad address family.");
2103 cur->next =
nullptr;
2105 if (last !=
nullptr)
2112 err = ares_set_servers_ports(channel->cares_channel(), &servers[0]);
2116 if (err == ARES_SUCCESS)
2117 channel->set_is_servers_default(
false);
2119 args.GetReturnValue().Set(err);
2122 void Cancel(
const FunctionCallbackInfo<Value>& args) {
2124 ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder());
2126 ares_cancel(channel->cares_channel());
2130 void StrError(
const FunctionCallbackInfo<Value>& args) {
2131 Environment* env = Environment::GetCurrent(args);
2132 const char* errmsg = ares_strerror(args[0]->Int32Value());
2133 args.GetReturnValue().Set(OneByteString(env->isolate(), errmsg));
2138 Local<Value> unused,
2139 Local<Context> context) {
2140 Environment* env = Environment::GetCurrent(context);
2142 env->SetMethod(target,
"getaddrinfo", GetAddrInfo);
2143 env->SetMethod(target,
"getnameinfo", GetNameInfo);
2144 env->SetMethod(target,
"isIP", IsIP);
2145 env->SetMethod(target,
"isIPv4", IsIPv4);
2146 env->SetMethod(target,
"isIPv6", IsIPv6);
2148 env->SetMethod(target,
"strerror", StrError);
2150 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"AF_INET"),
2152 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"AF_INET6"),
2154 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"AF_UNSPEC"),
2156 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"AI_ADDRCONFIG"),
2158 target->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
"AI_V4MAPPED"),
2161 auto is_construct_call_callback =
2162 [](
const FunctionCallbackInfo<Value>& args) {
2163 CHECK(args.IsConstructCall());
2164 ClearWrap(args.This());
2166 Local<FunctionTemplate> aiw =
2168 aiw->InstanceTemplate()->SetInternalFieldCount(1);
2169 AsyncWrap::AddWrapMethods(env, aiw);
2170 Local<String> addrInfoWrapString =
2171 FIXED_ONE_BYTE_STRING(env->isolate(),
"GetAddrInfoReqWrap");
2172 aiw->SetClassName(addrInfoWrapString);
2173 target->Set(addrInfoWrapString, aiw->GetFunction());
2175 Local<FunctionTemplate> niw =
2177 niw->InstanceTemplate()->SetInternalFieldCount(1);
2178 AsyncWrap::AddWrapMethods(env, niw);
2179 Local<String> nameInfoWrapString =
2180 FIXED_ONE_BYTE_STRING(env->isolate(),
"GetNameInfoReqWrap");
2181 niw->SetClassName(nameInfoWrapString);
2182 target->Set(nameInfoWrapString, niw->GetFunction());
2184 Local<FunctionTemplate> qrw =
2186 qrw->InstanceTemplate()->SetInternalFieldCount(1);
2187 AsyncWrap::AddWrapMethods(env, qrw);
2188 Local<String> queryWrapString =
2189 FIXED_ONE_BYTE_STRING(env->isolate(),
"QueryReqWrap");
2190 qrw->SetClassName(queryWrapString);
2191 target->Set(queryWrapString, qrw->GetFunction());
2193 Local<FunctionTemplate> channel_wrap =
2195 channel_wrap->InstanceTemplate()->SetInternalFieldCount(1);
2196 AsyncWrap::AddWrapMethods(env, channel_wrap);
2198 env->SetProtoMethod(channel_wrap,
"queryAny", Query<QueryAnyWrap>);
2199 env->SetProtoMethod(channel_wrap,
"queryA", Query<QueryAWrap>);
2200 env->SetProtoMethod(channel_wrap,
"queryAaaa", Query<QueryAaaaWrap>);
2201 env->SetProtoMethod(channel_wrap,
"queryCname", Query<QueryCnameWrap>);
2202 env->SetProtoMethod(channel_wrap,
"queryMx", Query<QueryMxWrap>);
2203 env->SetProtoMethod(channel_wrap,
"queryNs", Query<QueryNsWrap>);
2204 env->SetProtoMethod(channel_wrap,
"queryTxt", Query<QueryTxtWrap>);
2205 env->SetProtoMethod(channel_wrap,
"querySrv", Query<QuerySrvWrap>);
2206 env->SetProtoMethod(channel_wrap,
"queryPtr", Query<QueryPtrWrap>);
2207 env->SetProtoMethod(channel_wrap,
"queryNaptr", Query<QueryNaptrWrap>);
2208 env->SetProtoMethod(channel_wrap,
"querySoa", Query<QuerySoaWrap>);
2209 env->SetProtoMethod(channel_wrap,
"getHostByAddr", Query<GetHostByAddrWrap>);
2211 env->SetProtoMethod(channel_wrap,
"getServers", GetServers);
2212 env->SetProtoMethod(channel_wrap,
"setServers", SetServers);
2213 env->SetProtoMethod(channel_wrap,
"cancel", Cancel);
2215 Local<String> channelWrapString =
2216 FIXED_ONE_BYTE_STRING(env->isolate(),
"ChannelWrap");
2217 channel_wrap->SetClassName(channelWrapString);
2218 target->Set(channelWrapString, channel_wrap->GetFunction());
NODE_MODULE_CONTEXT_AWARE_BUILTIN(inspector, node::inspector::Agent::InitInspector)
union node::cares_wrap::@8::CaresAsyncData::@0 data
void Initialize(Local< Object > target, Local< Value > unused, Local< Context > context, void *priv)
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)
MaybeLocal< Value > MakeCallback(Isolate *isolate, Local< Object > recv, Local< Function > callback, int argc, Local< Value > *argv, async_id asyncId, async_id triggerAsyncId)