From e44d75011f571cc6b4930b11e07cfa3a117cb9e0 Mon Sep 17 00:00:00 2001 From: XadillaX Date: Sun, 21 May 2017 18:02:33 +0800 Subject: [PATCH 1/5] dns: add resolveAny support `dns.resolveAny` and `dns.resolve` with `"ANY"` has the similar behavior like `$ dig any` and returns an array with several types of records. `dns.resolveAny` parses the result packet by several rules in turn. Supported types: * A * AAAA * CNAME * MX * NAPTR * NS * PTR * SOA * SRV * TXT Refs: https://github.com/nodejs/node/issues/2848 --- doc/api/dns.md | 47 ++ lib/dns.js | 2 + src/cares_wrap.cc | 795 +++++++++++++++++++++++++++------- src/env.h | 12 + test/internet/test-dns-any.js | 199 +++++++++ 5 files changed, 899 insertions(+), 156 deletions(-) create mode 100644 test/internet/test-dns-any.js diff --git a/doc/api/dns.md b/doc/api/dns.md index 42d93a14e7a020..d2cee6a6b3cd4e 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -197,6 +197,7 @@ records. The type and structure of individual results varies based on `rrtype`: | `'SOA'` | start of authority records | {Object} | [`dns.resolveSoa()`][] | | `'SRV'` | service records | {Object} | [`dns.resolveSrv()`][] | | `'TXT'` | text records | {string} | [`dns.resolveTxt()`][] | +| `'ANY'` | any records | {Object} | [`dns.resolveAny()`][] | On error, `err` is an [`Error`][] object, where `err.code` is one of the [DNS error codes](#dns_error_codes). @@ -417,6 +418,51 @@ is a two-dimensional array of the text records available for `hostname` (e.g., one record. Depending on the use case, these could be either joined together or treated separately. +## dns.resolveAny(hostname, callback) + +- `hostname` {string} +- `callback` {Function} + - `err` {Error} + - `ret` {Object[][]} + +Uses the DNS protocol to resolve any queries (`ANY` records) for the `hostname`. +The `ret` argument passed to the `callback` function will be an array of objects +with uncertain type of records. Each object has a property `type` that indicates +the type of current record. And for each type of record, the object structure +will be like: + +| Type | Properties | +|------|------------| +| `"A"` | `address` / `ttl` | +| `"AAAA"` | `address` / `ttl` | +| `"CNAME"` | `value` | +| `"MX"` | Refer to [`dns.resolveMx()`][] | +| `"NAPTR"` | Refer to [`dns.resolveNaptr()`][] | +| `"NS"` | `value` | +| `"PTR"` | `value` | +| `"SOA"` | Refer to [`dns.resolveSoa()`][] | +| `"SRV"` | Refer to [`dns.resolveSrv()`][] | +| `"TXT"` | This is an array-liked object with `length` and `indexes`, eg. `{'0':'sth','length':1}` | + +Following is a example of the `ret` object passed to the callback: + + +```js +[ { address: '127.0.0.1', ttl: 299, type: 'A' }, + { value: 'example.com', type: 'CNAME' }, // in fact, CNAME can't stay with A + { exchange: 'alt4.aspmx.l.example.com', priority: 50, type: 'MX' }, + { value: 'ns1.example.com', type: 'NS' }, + { '0': 'v=spf1 include:_spf.example.com ~all', type: 'TXT', length: 1 }, + { nsname: 'ns1.example.com', + hostmaster: 'admin.example.com', + serial: 156696742, + refresh: 900, + retry: 900, + expire: 1800, + minttl: 60, + type: 'SOA' } ] +``` + ## dns.reverse(ip, callback) ```js -[ { address: '127.0.0.1', ttl: 299, type: 'A' }, - { value: 'example.com', type: 'CNAME' }, // in fact, CNAME can't stay with A - { exchange: 'alt4.aspmx.l.example.com', priority: 50, type: 'MX' }, - { value: 'ns1.example.com', type: 'NS' }, - { '0': 'v=spf1 include:_spf.example.com ~all', type: 'TXT', length: 1 }, - { nsname: 'ns1.example.com', +[ { type: 'A', address: '127.0.0.1', ttl: 299 }, + { type: 'CNAME', value: 'example.com' }, + { type: 'MX', exchange: 'alt4.aspmx.l.example.com', priority: 50 }, + { type: 'NS', value: 'ns1.example.com', type: 'NS' }, + { type: 'TXT', '0': 'v=spf1 include:_spf.example.com ~all', length: 1 }, + { type: 'SOA', + nsname: 'ns1.example.com', hostmaster: 'admin.example.com', serial: 156696742, refresh: 900, retry: 900, expire: 1800, - minttl: 60, - type: 'SOA' } ] + minttl: 60 } ] ``` ## dns.reverse(ip, callback) diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index cb6a070cec0636..277cbdbb772c4a 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -69,14 +69,16 @@ using v8::Value; namespace { -#define CARES_16BIT(p) ((uint16_t)((unsigned int) 0xffff & \ - (((unsigned int)((unsigned char)(p)[0]) << 8U) | \ - ((unsigned int)((unsigned char)(p)[1]))))) -#define CARES_32BIT(p) ((unsigned int) \ - (((unsigned int)((unsigned char)(p)[0]) << 24U) | \ - ((unsigned int)((unsigned char)(p)[1]) << 16U) | \ - ((unsigned int)((unsigned char)(p)[2]) << 8U) | \ - ((unsigned int)((unsigned char)(p)[3])))) +inline uint16_t cares_get_16bit(const unsigned char* p) { + return static_cast(p[0] << 8U) | (static_cast(p[1])); +} + +inline uint32_t cares_get_32bit(const unsigned char* p) { + return static_cast(p[0] << 24U) | + static_cast(p[1] << 16U) | + static_cast(p[2] << 8U) | + static_cast(p[3]); +} const int ns_t_cname_or_a = -1; @@ -283,37 +285,41 @@ void ares_sockstate_cb(void* data, Local HostentToAddresses(Environment* env, struct hostent* host, - Local prev = Local()) { + Local append_to = Local()) { EscapableHandleScope scope(env->isolate()); - bool use_prev = !prev.IsEmpty(); - Local addresses = use_prev ? prev : Array::New(env->isolate()); + auto context = env->context(); + Context::Scope context_scope(context); + bool append = !append_to.IsEmpty(); + Local addresses = append ? append_to : Array::New(env->isolate()); size_t offset = addresses->Length(); char ip[INET6_ADDRSTRLEN]; for (uint32_t i = 0; host->h_addr_list[i] != nullptr; ++i) { uv_inet_ntop(host->h_addrtype, host->h_addr_list[i], ip, sizeof(ip)); Local address = OneByteString(env->isolate(), ip); - addresses->Set(i + offset, address); + addresses->Set(context, i + offset, address).FromJust(); } - return use_prev ? addresses : scope.Escape(addresses); + return append ? addresses : scope.Escape(addresses); } Local HostentToNames(Environment* env, struct hostent* host, - Local prev = Local()) { + Local append_to = Local()) { EscapableHandleScope scope(env->isolate()); - bool use_prev = !prev.IsEmpty(); - Local names = use_prev ? prev : Array::New(env->isolate()); + auto context = env->context(); + Context::Scope context_scope(context); + bool append = !append_to.IsEmpty(); + Local names = append ? append_to : Array::New(env->isolate()); size_t offset = names->Length(); for (uint32_t i = 0; host->h_aliases[i] != nullptr; ++i) { Local address = OneByteString(env->isolate(), host->h_aliases[i]); - names->Set(i + offset, address); + names->Set(context, i + offset, address).FromJust(); } - return scope.Escape(names); + return append ? names : scope.Escape(names); } void safe_free_hostent(struct hostent* host) { @@ -544,32 +550,18 @@ class QueryWrap : public AsyncWrap { } }; + +template Local AddrTTLToArray(Environment* env, - ares_addrttl* addrttls, - int naddrttls) { + const T* addrttls, + size_t naddrttls) { auto isolate = env->isolate(); EscapableHandleScope escapable_handle_scope(isolate); - - Local ttls = Array::New(isolate, naddrttls); auto context = env->context(); - for (int i = 0; i < naddrttls; i += 1) { - auto value = Integer::New(isolate, addrttls[i].ttl); - ttls->Set(context, i, value).FromJust(); - } - - return escapable_handle_scope.Escape(ttls); -} - - -Local AddrTTL6ToArray(Environment* env, - ares_addr6ttl* addrttls, - int naddrttls) { - auto isolate = env->isolate(); - EscapableHandleScope escapable_handle_scope(isolate); + Context::Scope context_scope(context); Local ttls = Array::New(isolate, naddrttls); - auto context = env->context(); - for (int i = 0; i < naddrttls; i += 1) { + for (size_t i = 0; i < naddrttls; i++) { auto value = Integer::New(isolate, addrttls[i].ttl); ttls->Set(context, i, value).FromJust(); } @@ -579,55 +571,60 @@ Local AddrTTL6ToArray(Environment* env, int ParseGeneralReply(Environment* env, - unsigned char* buf, + const unsigned char* buf, int len, int* type, Local ret, void* addrttls = nullptr, int* naddrttls = nullptr) { HandleScope handle_scope(env->isolate()); + auto context = env->context(); + Context::Scope context_scope(context); hostent* host; int status; switch (*type) { - case ns_t_a: - case ns_t_cname: - case ns_t_cname_or_a: - status = ares_parse_a_reply(buf, - len, - &host, - reinterpret_cast(addrttls), - naddrttls); - break; - case ns_t_aaaa: - status = ares_parse_aaaa_reply(buf, - len, - &host, - reinterpret_cast(addrttls), - naddrttls); - break; - case ns_t_ns: - status = ares_parse_ns_reply(buf, len, &host); - break; - case ns_t_ptr: - status = ares_parse_ptr_reply(buf, len, NULL, 0, AF_INET, &host); - break; - default: - CHECK(0 && "Bad NS type"); + case ns_t_a: + case ns_t_cname: + case ns_t_cname_or_a: + status = ares_parse_a_reply(buf, + len, + &host, + static_cast(addrttls), + naddrttls); + break; + case ns_t_aaaa: + status = ares_parse_aaaa_reply(buf, + len, + &host, + static_cast(addrttls), + naddrttls); + break; + case ns_t_ns: + status = ares_parse_ns_reply(buf, len, &host); + break; + case ns_t_ptr: + status = ares_parse_ptr_reply(buf, len, NULL, 0, AF_INET, &host); + break; + default: + CHECK(0 && "Bad NS type"); + break; } if (status != ARES_SUCCESS) return status; - /* If it's `CNAME`, return the CNAME value */ - /* And if it's `CNAME_OR_A` and it has value in `h_name` and `h_aliases[0]` */ - /* We consider it's a CNAME record, otherwise we consider it's an A record */ + /* If it's `CNAME`, return the CNAME value; + * And if it's `CNAME_OR_A` and it has value in `h_name` and `h_aliases[0]`, + * we consider it's a CNAME record, otherwise we consider it's an A record. */ if ((*type == ns_t_cname_or_a && host->h_name && host->h_aliases[0]) || *type == ns_t_cname) { // A cname lookup always returns a single record but we follow the // common API here. *type = ns_t_cname; - ret->Set(ret->Length(), OneByteString(env->isolate(), host->h_name)); + ret->Set(context, + ret->Length(), + OneByteString(env->isolate(), host->h_name)).FromJust(); ares_free_hostent(host); return ARES_SUCCESS; } @@ -640,7 +637,9 @@ int ParseGeneralReply(Environment* env, } else if (*type == ns_t_ptr) { uint32_t offset = ret->Length(); for (uint32_t i = 0; host->h_aliases[i] != NULL; i++) { - ret->Set(i + offset, OneByteString(env->isolate(), host->h_aliases[i])); + ret->Set(context, + i + offset, + OneByteString(env->isolate(), host->h_aliases[i])).FromJust(); } } else { HostentToAddresses(env, host, ret); @@ -653,11 +652,13 @@ int ParseGeneralReply(Environment* env, int ParseMxReply(Environment* env, - unsigned char* buf, + const unsigned char* buf, int len, Local ret, bool need_type = false) { HandleScope handle_scope(env->isolate()); + auto context = env->context(); + Context::Scope context_scope(context); struct ares_mx_reply* mx_start; int status = ares_parse_mx_reply(buf, len, &mx_start); @@ -674,13 +675,16 @@ int ParseMxReply(Environment* env, ares_mx_reply* current = mx_start; for (uint32_t i = 0; current != nullptr; ++i, current = current->next) { Local mx_record = Object::New(env->isolate()); - mx_record->Set(exchange_symbol, - OneByteString(env->isolate(), current->host)); - mx_record->Set(priority_symbol, - Integer::New(env->isolate(), current->priority)); + mx_record->Set(context, + exchange_symbol, + OneByteString(env->isolate(), current->host)).FromJust(); + mx_record->Set(context, + priority_symbol, + Integer::New(env->isolate(), current->priority)).FromJust(); if (need_type) - mx_record->Set(type_symbol, mx_symbol); - ret->Set(i + offset, mx_record); + mx_record->Set(context, type_symbol, mx_symbol).FromJust(); + + ret->Set(context, i + offset, mx_record).FromJust(); } ares_free_data(mx_start); @@ -688,11 +692,13 @@ int ParseMxReply(Environment* env, } int ParseTxtReply(Environment* env, - unsigned char* buf, + const unsigned char* buf, int len, Local ret, bool need_type = false) { HandleScope handle_scope(env->isolate()); + auto context = env->context(); + Context::Scope context_scope(context); struct ares_txt_ext* txt_out; @@ -714,14 +720,17 @@ int ParseTxtReply(Environment* env, if (current->record_start) { if (!need_type) { if (!txt_chunk.IsEmpty()) - ret->Set(offset + i++, txt_chunk); + ret->Set(context, offset + i++, txt_chunk).FromJust(); txt_chunk = Array::New(env->isolate()); } else { if (!txt_chunk_obj.IsEmpty()) { - txt_chunk_obj->Set(env->type_string(), env->dns_txt_string()); - txt_chunk_obj->Set(env->length_string(), - Integer::New(env->isolate(), j)); - ret->Set(offset + i++, txt_chunk_obj); + txt_chunk_obj->Set(context, + env->type_string(), + env->dns_txt_string()).FromJust(); + txt_chunk_obj->Set(context, + env->length_string(), + Integer::New(env->isolate(), j)).FromJust(); + ret->Set(context, offset + i++, txt_chunk_obj).FromJust(); } txt_chunk_obj = Object::New(env->isolate()); } @@ -729,16 +738,22 @@ int ParseTxtReply(Environment* env, j = 0; } - need_type ? txt_chunk_obj->Set(j++, txt) : txt_chunk->Set(j++, txt); + need_type ? + txt_chunk_obj->Set(context, j++, txt).FromJust() : + txt_chunk->Set(context, j++, txt).FromJust(); } // Push last chunk if it isn't empty if (!need_type && !txt_chunk.IsEmpty()) { - ret->Set(offset + i, txt_chunk); + ret->Set(context, offset + i, txt_chunk).FromJust(); } else if (need_type && !txt_chunk_obj.IsEmpty()) { - txt_chunk_obj->Set(env->type_string(), env->dns_txt_string()); - txt_chunk_obj->Set(env->length_string(), Integer::New(env->isolate(), j)); - ret->Set(offset + i, txt_chunk_obj); + txt_chunk_obj->Set(context, + env->type_string(), + env->dns_txt_string()).FromJust(); + txt_chunk_obj->Set(context, + env->length_string(), + Integer::New(env->isolate(), j)).FromJust(); + ret->Set(context, offset + i, txt_chunk_obj).FromJust(); } ares_free_data(txt_out); @@ -747,11 +762,14 @@ int ParseTxtReply(Environment* env, int ParseSrvReply(Environment* env, - unsigned char* buf, + const unsigned char* buf, int len, Local ret, bool need_type = false) { HandleScope handle_scope(env->isolate()); + auto context = env->context(); + Context::Scope context_scope(context); + struct ares_srv_reply* srv_start; int status = ares_parse_srv_reply(buf, len, &srv_start); if (status != ARES_SUCCESS) { @@ -769,17 +787,22 @@ int ParseSrvReply(Environment* env, int offset = ret->Length(); for (uint32_t i = 0; current != nullptr; ++i, current = current->next) { Local srv_record = Object::New(env->isolate()); - srv_record->Set(name_symbol, - OneByteString(env->isolate(), current->host)); - srv_record->Set(port_symbol, - Integer::New(env->isolate(), current->port)); - srv_record->Set(priority_symbol, - Integer::New(env->isolate(), current->priority)); - srv_record->Set(weight_symbol, - Integer::New(env->isolate(), current->weight)); + srv_record->Set(context, + name_symbol, + OneByteString(env->isolate(), current->host)).FromJust(); + srv_record->Set(context, + port_symbol, + Integer::New(env->isolate(), current->port)).FromJust(); + srv_record->Set(context, + priority_symbol, + Integer::New(env->isolate(), current->priority)).FromJust(); + srv_record->Set(context, + weight_symbol, + Integer::New(env->isolate(), current->weight)).FromJust(); if (need_type) - srv_record->Set(type_symbol, srv_symbol); - ret->Set(i + offset, srv_record); + srv_record->Set(context, type_symbol, srv_symbol).FromJust(); + + ret->Set(context, i + offset, srv_record).FromJust(); } ares_free_data(srv_start); @@ -788,11 +811,14 @@ int ParseSrvReply(Environment* env, int ParseNaptrReply(Environment* env, - unsigned char* buf, + const unsigned char* buf, int len, Local ret, bool need_type = false) { HandleScope handle_scope(env->isolate()); + auto context = env->context(); + Context::Scope context_scope(context); + ares_naptr_reply* naptr_start; int status = ares_parse_naptr_reply(buf, len, &naptr_start); @@ -813,21 +839,32 @@ int ParseNaptrReply(Environment* env, int offset = ret->Length(); for (uint32_t i = 0; current != nullptr; ++i, current = current->next) { Local naptr_record = Object::New(env->isolate()); - naptr_record->Set(flags_symbol, - OneByteString(env->isolate(), current->flags)); - naptr_record->Set(service_symbol, - OneByteString(env->isolate(), current->service)); - naptr_record->Set(regexp_symbol, - OneByteString(env->isolate(), current->regexp)); - naptr_record->Set(replacement_symbol, - OneByteString(env->isolate(), current->replacement)); - naptr_record->Set(order_symbol, - Integer::New(env->isolate(), current->order)); - naptr_record->Set(preference_symbol, - Integer::New(env->isolate(), current->preference)); + naptr_record->Set(context, + flags_symbol, + OneByteString(env->isolate(), current->flags)).FromJust(); + naptr_record->Set(context, + service_symbol, + OneByteString(env->isolate(), + current->service)).FromJust(); + naptr_record->Set(context, + regexp_symbol, + OneByteString(env->isolate(), + current->regexp)).FromJust(); + naptr_record->Set(context, + replacement_symbol, + OneByteString(env->isolate(), + current->replacement)).FromJust(); + naptr_record->Set(context, + order_symbol, + Integer::New(env->isolate(), current->order)).FromJust(); + naptr_record->Set(context, + preference_symbol, + Integer::New(env->isolate(), + current->preference)).FromJust(); if (need_type) - naptr_record->Set(type_symbol, naptr_symbol); - ret->Set(i + offset, naptr_record); + naptr_record->Set(context, type_symbol, naptr_symbol).FromJust(); + + ret->Set(context, i + offset, naptr_record).FromJust(); } ares_free_data(naptr_start); @@ -840,9 +877,11 @@ int ParseSoaReply(Environment* env, int len, Local* ret) { EscapableHandleScope handle_scope(env->isolate()); + auto context = env->context(); + Context::Scope context_scope(context); /* Can't use ares_parse_soa_reply() here which can only parse single record */ - unsigned int ancount = CARES_16BIT(buf + 6); + unsigned int ancount = cares_get_16bit(buf + 6); unsigned char* ptr = buf + NS_HFIXEDSZ; int rr_type, rr_len; char* name; @@ -873,8 +912,8 @@ int ParseSoaReply(Environment* env, break; } - rr_type = CARES_16BIT(ptr); - rr_len = CARES_16BIT(ptr + 8); + rr_type = cares_get_16bit(ptr); + rr_len = cares_get_16bit(ptr + 8); ptr += NS_RRFIXEDSZ; /* only need SOA */ @@ -907,28 +946,38 @@ int ParseSoaReply(Environment* env, break; } - soa->serial = CARES_32BIT(ptr + 0 * 4); - soa->refresh = CARES_32BIT(ptr + 1 * 4); - soa->retry = CARES_32BIT(ptr + 2 * 4); - soa->expire = CARES_32BIT(ptr + 3 * 4); - soa->minttl = CARES_32BIT(ptr + 4 * 4); + soa->serial = cares_get_32bit(ptr + 0 * 4); + soa->refresh = cares_get_32bit(ptr + 1 * 4); + soa->retry = cares_get_32bit(ptr + 2 * 4); + soa->expire = cares_get_32bit(ptr + 3 * 4); + soa->minttl = cares_get_32bit(ptr + 4 * 4); Local soa_record = Object::New(env->isolate()); - soa_record->Set(env->nsname_string(), - OneByteString(env->isolate(), soa->nsname)); - soa_record->Set(env->hostmaster_string(), - OneByteString(env->isolate(), soa->hostmaster)); - soa_record->Set(env->serial_string(), - Integer::New(env->isolate(), soa->serial)); - soa_record->Set(env->refresh_string(), - Integer::New(env->isolate(), soa->refresh)); - soa_record->Set(env->retry_string(), - Integer::New(env->isolate(), soa->retry)); - soa_record->Set(env->expire_string(), - Integer::New(env->isolate(), soa->expire)); - soa_record->Set(env->minttl_string(), - Integer::New(env->isolate(), soa->minttl)); - soa_record->Set(env->type_string(), env->dns_soa_string()); + soa_record->Set(context, + env->nsname_string(), + OneByteString(env->isolate(), soa->nsname)).FromJust(); + soa_record->Set(context, + env->hostmaster_string(), + OneByteString(env->isolate(), + soa->hostmaster)).FromJust(); + soa_record->Set(context, + env->serial_string(), + Integer::New(env->isolate(), soa->serial)).FromJust(); + soa_record->Set(context, + env->refresh_string(), + Integer::New(env->isolate(), soa->refresh)).FromJust(); + soa_record->Set(context, + env->retry_string(), + Integer::New(env->isolate(), soa->retry)).FromJust(); + soa_record->Set(context, + env->expire_string(), + Integer::New(env->isolate(), soa->expire)).FromJust(); + soa_record->Set(context, + env->minttl_string(), + Integer::New(env->isolate(), soa->minttl)).FromJust(); + soa_record->Set(context, + env->type_string(), + env->dns_soa_string()).FromJust(); free(soa->nsname); free(soa->hostmaster); @@ -974,7 +1023,8 @@ class QueryAnyWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); - Context::Scope context_scope(env()->context()); + auto context = env()->context(); + Context::Scope context_scope(context); Local ret = Array::New(env()->isolate()); int type, status, old_count; @@ -1001,18 +1051,23 @@ class QueryAnyWrap: public QueryWrap { CHECK_EQ(naddrttls, a_count); for (int i = 0; i < a_count; i++) { Local obj = Object::New(env()->isolate()); - obj->Set(env()->address_string(), ret->Get(i)); - obj->Set(env()->ttl_string(), - Integer::New(env()->isolate(), addrttls[i].ttl)); - obj->Set(env()->type_string(), env()->dns_a_string()); - ret->Set(i, obj); + obj->Set(context, env()->address_string(), ret->Get(i)).FromJust(); + obj->Set(context, + env()->ttl_string(), + Integer::New(env()->isolate(), addrttls[i].ttl)).FromJust(); + obj->Set(context, + env()->type_string(), + env()->dns_a_string()).FromJust(); + ret->Set(context, i, obj).FromJust(); } } else { for (int i = 0; i < a_count; i++) { Local obj = Object::New(env()->isolate()); - obj->Set(env()->value_string(), ret->Get(i)); - obj->Set(env()->type_string(), env()->dns_cname_string()); - ret->Set(i, obj); + obj->Set(context, env()->value_string(), ret->Get(i)).FromJust(); + obj->Set(context, + env()->type_string(), + env()->dns_cname_string()).FromJust(); + ret->Set(context, i, obj).FromJust(); } } @@ -1037,11 +1092,14 @@ class QueryAnyWrap: public QueryWrap { CHECK_EQ(aaaa_count, naddr6ttls); for (uint32_t i = a_count; i < ret->Length(); i++) { Local obj = Object::New(env()->isolate()); - obj->Set(env()->address_string(), ret->Get(i)); - obj->Set(env()->ttl_string(), Integer::New(env()->isolate(), - addr6ttls[i].ttl)); - obj->Set(env()->type_string(), env()->dns_aaaa_string()); - ret->Set(i, obj); + obj->Set(context, env()->address_string(), ret->Get(i)).FromJust(); + obj->Set(context, + env()->ttl_string(), + Integer::New(env()->isolate(), addr6ttls[i].ttl)).FromJust(); + obj->Set(context, + env()->type_string(), + env()->dns_aaaa_string()).FromJust(); + ret->Set(context, i, obj).FromJust(); } /* Parse MX records */ @@ -1061,9 +1119,11 @@ class QueryAnyWrap: public QueryWrap { } for (uint32_t i = old_count; i < ret->Length(); i++) { Local obj = Object::New(env()->isolate()); - obj->Set(env()->value_string(), ret->Get(i)); - obj->Set(env()->type_string(), env()->dns_ns_string()); - ret->Set(i, obj); + obj->Set(context, env()->value_string(), ret->Get(i)).FromJust(); + obj->Set(context, + env()->type_string(), + env()->dns_ns_string()).FromJust(); + ret->Set(context, i, obj).FromJust(); } /* Parse TXT records */ @@ -1085,9 +1145,11 @@ class QueryAnyWrap: public QueryWrap { status = ParseGeneralReply(env(), buf, len, &type, ret); for (uint32_t i = old_count; i < ret->Length(); i++) { Local obj = Object::New(env()->isolate()); - obj->Set(env()->value_string(), ret->Get(i)); - obj->Set(env()->type_string(), env()->dns_ptr_string()); - ret->Set(i, obj); + obj->Set(context, env()->value_string(), ret->Get(i)).FromJust(); + obj->Set(context, + env()->type_string(), + env()->dns_ptr_string()).FromJust(); + ret->Set(context, i, obj).FromJust(); } /* Parse NAPTR records */ @@ -1105,7 +1167,7 @@ class QueryAnyWrap: public QueryWrap { return; } if (!soa_record.IsEmpty()) - ret->Set(ret->Length(), soa_record); + ret->Set(context, ret->Length(), soa_record).FromJust(); CallOnComplete(ret); } @@ -1133,7 +1195,6 @@ class QueryAWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); - Context::Scope context_scope(env()->context()); ares_addrttl addrttls[256]; int naddrttls = arraysize(addrttls), status; @@ -1152,7 +1213,9 @@ class QueryAWrap: public QueryWrap { return; } - Local ttls = AddrTTLToArray(env(), addrttls, naddrttls); + Local ttls = AddrTTLToArray(env(), + addrttls, + naddrttls); CallOnComplete(ret, ttls); } @@ -1180,7 +1243,6 @@ class QueryAaaaWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); - Context::Scope context_scope(env()->context()); ares_addr6ttl addrttls[256]; int naddrttls = arraysize(addrttls), status; @@ -1199,7 +1261,9 @@ class QueryAaaaWrap: public QueryWrap { return; } - Local ttls = AddrTTL6ToArray(env(), addrttls, naddrttls); + Local ttls = AddrTTLToArray(env(), + addrttls, + naddrttls); CallOnComplete(ret, ttls); } @@ -1227,7 +1291,6 @@ class QueryCnameWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); - Context::Scope context_scope(env()->context()); Local ret = Array::New(env()->isolate()); int type = ns_t_cname; @@ -1263,7 +1326,6 @@ class QueryMxWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); - Context::Scope context_scope(env()->context()); Local mx_records = Array::New(env()->isolate()); int status = ParseMxReply(env(), buf, len, mx_records); @@ -1299,7 +1361,6 @@ class QueryNsWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); - Context::Scope context_scope(env()->context()); int type = ns_t_ns; Local names = Array::New(env()->isolate()); @@ -1335,7 +1396,6 @@ class QueryTxtWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); - Context::Scope context_scope(env()->context()); Local txt_records = Array::New(env()->isolate()); int status = ParseTxtReply(env(), buf, len, txt_records); @@ -1370,7 +1430,6 @@ class QuerySrvWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); - Context::Scope context_scope(env()->context()); Local srv_records = Array::New(env()->isolate()); int status = ParseSrvReply(env(), buf, len, srv_records); @@ -1404,7 +1463,6 @@ class QueryPtrWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); - Context::Scope context_scope(env()->context()); int type = ns_t_ptr; Local aliases = Array::New(env()->isolate()); @@ -1440,7 +1498,6 @@ class QueryNaptrWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); - Context::Scope context_scope(env()->context()); Local naptr_records = Array::New(env()->isolate()); int status = ParseNaptrReply(env(), buf, len, naptr_records); @@ -1475,7 +1532,8 @@ class QuerySoaWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); - Context::Scope context_scope(env()->context()); + auto context = env()->context(); + Context::Scope context_scope(context); ares_soa_reply* soa_out; int status = ares_parse_soa_reply(buf, len, &soa_out); @@ -1487,20 +1545,30 @@ class QuerySoaWrap: public QueryWrap { Local soa_record = Object::New(env()->isolate()); - soa_record->Set(env()->nsname_string(), - OneByteString(env()->isolate(), soa_out->nsname)); - soa_record->Set(env()->hostmaster_string(), - OneByteString(env()->isolate(), soa_out->hostmaster)); - soa_record->Set(env()->serial_string(), - Integer::New(env()->isolate(), soa_out->serial)); - soa_record->Set(env()->refresh_string(), - Integer::New(env()->isolate(), soa_out->refresh)); - soa_record->Set(env()->retry_string(), - Integer::New(env()->isolate(), soa_out->retry)); - soa_record->Set(env()->expire_string(), - Integer::New(env()->isolate(), soa_out->expire)); - soa_record->Set(env()->minttl_string(), - Integer::New(env()->isolate(), soa_out->minttl)); + soa_record->Set(context, + env()->nsname_string(), + OneByteString(env()->isolate(), + soa_out->nsname)).FromJust(); + soa_record->Set(context, + env()->hostmaster_string(), + OneByteString(env()->isolate(), + soa_out->hostmaster)).FromJust(); + soa_record->Set(context, + env()->serial_string(), + Integer::New(env()->isolate(), soa_out->serial)).FromJust(); + soa_record->Set(context, + env()->refresh_string(), + Integer::New(env()->isolate(), + soa_out->refresh)).FromJust(); + soa_record->Set(context, + env()->retry_string(), + Integer::New(env()->isolate(), soa_out->retry)).FromJust(); + soa_record->Set(context, + env()->expire_string(), + Integer::New(env()->isolate(), soa_out->expire)).FromJust(); + soa_record->Set(context, + env()->minttl_string(), + Integer::New(env()->isolate(), soa_out->minttl)).FromJust(); ares_free_data(soa_out); @@ -1946,8 +2014,8 @@ void CaresTimerCloseCb(uv_handle_t* handle) { void CaresTimerClose(Environment* env, - uv_handle_t* handle, - void* arg) { + uv_handle_t* handle, + void* arg) { uv_close(handle, CaresTimerCloseCb); } From 7fdffbdc1e1987d529c1815631e7db6029f25c4a Mon Sep 17 00:00:00 2001 From: XadillaX Date: Mon, 29 May 2017 00:29:42 +0800 Subject: [PATCH 3/5] update after reviewing --- doc/api/dns.md | 8 +++--- src/cares_wrap.cc | 69 +++++++++++++++++++++++------------------------ 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/doc/api/dns.md b/doc/api/dns.md index 50db981067f6dc..21425389c047e4 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -426,9 +426,9 @@ treated separately. - `ret` {Object[][]} Uses the DNS protocol to resolve all records (also known as `ANY` or `*` query). -The `ret` argument passed to the `callback` function will be an array of objects -with uncertain type of records. Each object has a property `type` that indicates -the type of current record. And depending on the `type`, additional properties +The `ret` argument passed to the `callback` function will be an array containing +various types of records. Each object has a property `type` that indicates the +type of the current record. And depending on the `type`, additional properties will be present on the object: | Type | Properties | @@ -442,7 +442,7 @@ will be present on the object: | `"PTR"` | `value` | | `"SOA"` | Refer to [`dns.resolveSoa()`][] | | `"SRV"` | Refer to [`dns.resolveSrv()`][] | -| `"TXT"` | This is an array-liked object with `length` and `indexes`, eg. `{'0':'sth','length':1}` | +| `"TXT"` | This is an array-like object with `length` and `indexes`, eg. `{'0':'sth','length':1}` | Here is a example of the `ret` object passed to the callback: diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 277cbdbb772c4a..25d65a74b902df 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -288,7 +288,6 @@ Local HostentToAddresses(Environment* env, Local append_to = Local()) { EscapableHandleScope scope(env->isolate()); auto context = env->context(); - Context::Scope context_scope(context); bool append = !append_to.IsEmpty(); Local addresses = append ? append_to : Array::New(env->isolate()); size_t offset = addresses->Length(); @@ -309,7 +308,6 @@ Local HostentToNames(Environment* env, Local append_to = Local()) { EscapableHandleScope scope(env->isolate()); auto context = env->context(); - Context::Scope context_scope(context); bool append = !append_to.IsEmpty(); Local names = append ? append_to : Array::New(env->isolate()); size_t offset = names->Length(); @@ -558,7 +556,6 @@ Local AddrTTLToArray(Environment* env, auto isolate = env->isolate(); EscapableHandleScope escapable_handle_scope(isolate); auto context = env->context(); - Context::Scope context_scope(context); Local ttls = Array::New(isolate, naddrttls); for (size_t i = 0; i < naddrttls; i++) { @@ -579,7 +576,6 @@ int ParseGeneralReply(Environment* env, int* naddrttls = nullptr) { HandleScope handle_scope(env->isolate()); auto context = env->context(); - Context::Scope context_scope(context); hostent* host; int status; @@ -658,7 +654,6 @@ int ParseMxReply(Environment* env, bool need_type = false) { HandleScope handle_scope(env->isolate()); auto context = env->context(); - Context::Scope context_scope(context); struct ares_mx_reply* mx_start; int status = ares_parse_mx_reply(buf, len, &mx_start); @@ -698,7 +693,6 @@ int ParseTxtReply(Environment* env, bool need_type = false) { HandleScope handle_scope(env->isolate()); auto context = env->context(); - Context::Scope context_scope(context); struct ares_txt_ext* txt_out; @@ -738,8 +732,9 @@ int ParseTxtReply(Environment* env, j = 0; } - need_type ? - txt_chunk_obj->Set(context, j++, txt).FromJust() : + if (need_type) + txt_chunk_obj->Set(context, j++, txt).FromJust(); + else txt_chunk->Set(context, j++, txt).FromJust(); } @@ -768,7 +763,6 @@ int ParseSrvReply(Environment* env, bool need_type = false) { HandleScope handle_scope(env->isolate()); auto context = env->context(); - Context::Scope context_scope(context); struct ares_srv_reply* srv_start; int status = ares_parse_srv_reply(buf, len, &srv_start); @@ -817,7 +811,6 @@ int ParseNaptrReply(Environment* env, bool need_type = false) { HandleScope handle_scope(env->isolate()); auto context = env->context(); - Context::Scope context_scope(context); ares_naptr_reply* naptr_start; int status = ares_parse_naptr_reply(buf, len, &naptr_start); @@ -878,7 +871,6 @@ int ParseSoaReply(Environment* env, Local* ret) { EscapableHandleScope handle_scope(env->isolate()); auto context = env->context(); - Context::Scope context_scope(context); /* Can't use ares_parse_soa_reply() here which can only parse single record */ unsigned int ancount = cares_get_16bit(buf + 6); @@ -918,71 +910,67 @@ int ParseSoaReply(Environment* env, /* only need SOA */ if (rr_type == ns_t_soa) { - ares_soa_reply* soa = node::Malloc(1); + ares_soa_reply soa; + // ares_soa_reply* soa = node::Malloc(1); - status = ares_expand_name(ptr, buf, len, &soa->nsname, &temp_len); + status = ares_expand_name(ptr, buf, len, &soa.nsname, &temp_len); if (status != ARES_SUCCESS) { free(rr_name); - free(soa); break; } ptr += temp_len; - status = ares_expand_name(ptr, buf, len, &soa->hostmaster, &temp_len); + status = ares_expand_name(ptr, buf, len, &soa.hostmaster, &temp_len); if (status != ARES_SUCCESS) { free(rr_name); - free(soa->nsname); - free(soa); + free(soa.nsname); break; } ptr += temp_len; if (ptr + 5 * 4 > buf + len) { free(rr_name); - free(soa->nsname); - free(soa->hostmaster); - free(soa); + free(soa.nsname); + free(soa.hostmaster); status = ARES_EBADRESP; break; } - soa->serial = cares_get_32bit(ptr + 0 * 4); - soa->refresh = cares_get_32bit(ptr + 1 * 4); - soa->retry = cares_get_32bit(ptr + 2 * 4); - soa->expire = cares_get_32bit(ptr + 3 * 4); - soa->minttl = cares_get_32bit(ptr + 4 * 4); + soa.serial = cares_get_32bit(ptr + 0 * 4); + soa.refresh = cares_get_32bit(ptr + 1 * 4); + soa.retry = cares_get_32bit(ptr + 2 * 4); + soa.expire = cares_get_32bit(ptr + 3 * 4); + soa.minttl = cares_get_32bit(ptr + 4 * 4); Local soa_record = Object::New(env->isolate()); soa_record->Set(context, env->nsname_string(), - OneByteString(env->isolate(), soa->nsname)).FromJust(); + OneByteString(env->isolate(), soa.nsname)).FromJust(); soa_record->Set(context, env->hostmaster_string(), OneByteString(env->isolate(), - soa->hostmaster)).FromJust(); + soa.hostmaster)).FromJust(); soa_record->Set(context, env->serial_string(), - Integer::New(env->isolate(), soa->serial)).FromJust(); + Integer::New(env->isolate(), soa.serial)).FromJust(); soa_record->Set(context, env->refresh_string(), - Integer::New(env->isolate(), soa->refresh)).FromJust(); + Integer::New(env->isolate(), soa.refresh)).FromJust(); soa_record->Set(context, env->retry_string(), - Integer::New(env->isolate(), soa->retry)).FromJust(); + Integer::New(env->isolate(), soa.retry)).FromJust(); soa_record->Set(context, env->expire_string(), - Integer::New(env->isolate(), soa->expire)).FromJust(); + Integer::New(env->isolate(), soa.expire)).FromJust(); soa_record->Set(context, env->minttl_string(), - Integer::New(env->isolate(), soa->minttl)).FromJust(); + Integer::New(env->isolate(), soa.minttl)).FromJust(); soa_record->Set(context, env->type_string(), env->dns_soa_string()).FromJust(); - free(soa->nsname); - free(soa->hostmaster); - free(soa); - free(rr_name); + free(soa.nsname); + free(soa.hostmaster); *ret = handle_scope.Escape(soa_record); break; @@ -1195,6 +1183,7 @@ class QueryAWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); + Context::Scope context_scope(env()->context()); ares_addrttl addrttls[256]; int naddrttls = arraysize(addrttls), status; @@ -1243,6 +1232,7 @@ class QueryAaaaWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); + Context::Scope context_scope(env()->context()); ares_addr6ttl addrttls[256]; int naddrttls = arraysize(addrttls), status; @@ -1291,6 +1281,7 @@ class QueryCnameWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); + Context::Scope context_scope(env()->context()); Local ret = Array::New(env()->isolate()); int type = ns_t_cname; @@ -1326,6 +1317,7 @@ class QueryMxWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); + Context::Scope context_scope(env()->context()); Local mx_records = Array::New(env()->isolate()); int status = ParseMxReply(env(), buf, len, mx_records); @@ -1361,6 +1353,7 @@ class QueryNsWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); + Context::Scope context_scope(env()->context()); int type = ns_t_ns; Local names = Array::New(env()->isolate()); @@ -1396,6 +1389,7 @@ class QueryTxtWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); + Context::Scope context_scope(env()->context()); Local txt_records = Array::New(env()->isolate()); int status = ParseTxtReply(env(), buf, len, txt_records); @@ -1430,6 +1424,7 @@ class QuerySrvWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); + Context::Scope context_scope(env()->context()); Local srv_records = Array::New(env()->isolate()); int status = ParseSrvReply(env(), buf, len, srv_records); @@ -1463,6 +1458,7 @@ class QueryPtrWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); + Context::Scope context_scope(env()->context()); int type = ns_t_ptr; Local aliases = Array::New(env()->isolate()); @@ -1498,6 +1494,7 @@ class QueryNaptrWrap: public QueryWrap { protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); + Context::Scope context_scope(env()->context()); Local naptr_records = Array::New(env()->isolate()); int status = ParseNaptrReply(env(), buf, len, naptr_records); From 7f9187d2590d5fc96a5f5f51554134c81779aed2 Mon Sep 17 00:00:00 2001 From: XadillaX Date: Tue, 30 May 2017 12:58:53 +0800 Subject: [PATCH 4/5] make `txt` as an property of result --- doc/api/dns.md | 4 +-- src/cares_wrap.cc | 51 +++++++++++++++-------------------- src/env.h | 1 + test/internet/test-dns-any.js | 7 ++--- 4 files changed, 29 insertions(+), 34 deletions(-) diff --git a/doc/api/dns.md b/doc/api/dns.md index 21425389c047e4..94e64864b64070 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -442,7 +442,7 @@ will be present on the object: | `"PTR"` | `value` | | `"SOA"` | Refer to [`dns.resolveSoa()`][] | | `"SRV"` | Refer to [`dns.resolveSrv()`][] | -| `"TXT"` | This is an array-like object with `length` and `indexes`, eg. `{'0':'sth','length':1}` | +| `"TXT"` | This type of record contains an array property called `entries` which refers to [`dns.resolveTxt()`][], eg. `{ entries: ['...'], type: 'TXT' }` | Here is a example of the `ret` object passed to the callback: @@ -452,7 +452,7 @@ Here is a example of the `ret` object passed to the callback: { type: 'CNAME', value: 'example.com' }, { type: 'MX', exchange: 'alt4.aspmx.l.example.com', priority: 50 }, { type: 'NS', value: 'ns1.example.com', type: 'NS' }, - { type: 'TXT', '0': 'v=spf1 include:_spf.example.com ~all', length: 1 }, + { type: 'TXT', entries: [ 'v=spf1 include:_spf.example.com ~all' ] }, { type: 'SOA', nsname: 'ns1.example.com', hostmaster: 'admin.example.com', diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 25d65a74b902df..fb60b53fcb9ee7 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -702,7 +702,6 @@ int ParseTxtReply(Environment* env, } Local txt_chunk; - Local txt_chunk_obj; struct ares_txt_ext* current = txt_out; uint32_t i = 0, j; @@ -712,43 +711,38 @@ int ParseTxtReply(Environment* env, // New record found - write out the current chunk if (current->record_start) { - if (!need_type) { - if (!txt_chunk.IsEmpty()) + if (!txt_chunk.IsEmpty()) { + if (need_type) { + Local elem = Object::New(env->isolate()); + elem->Set(context, env->entries_string(), txt_chunk).FromJust(); + elem->Set(context, + env->type_string(), + env->dns_txt_string()).FromJust(); + ret->Set(context, offset + i++, elem).FromJust(); + } else { ret->Set(context, offset + i++, txt_chunk).FromJust(); - txt_chunk = Array::New(env->isolate()); - } else { - if (!txt_chunk_obj.IsEmpty()) { - txt_chunk_obj->Set(context, - env->type_string(), - env->dns_txt_string()).FromJust(); - txt_chunk_obj->Set(context, - env->length_string(), - Integer::New(env->isolate(), j)).FromJust(); - ret->Set(context, offset + i++, txt_chunk_obj).FromJust(); } - txt_chunk_obj = Object::New(env->isolate()); } + txt_chunk = Array::New(env->isolate()); j = 0; } - if (need_type) - txt_chunk_obj->Set(context, j++, txt).FromJust(); - else - txt_chunk->Set(context, j++, txt).FromJust(); + txt_chunk->Set(context, j++, txt).FromJust(); } // Push last chunk if it isn't empty - if (!need_type && !txt_chunk.IsEmpty()) { - ret->Set(context, offset + i, txt_chunk).FromJust(); - } else if (need_type && !txt_chunk_obj.IsEmpty()) { - txt_chunk_obj->Set(context, - env->type_string(), - env->dns_txt_string()).FromJust(); - txt_chunk_obj->Set(context, - env->length_string(), - Integer::New(env->isolate(), j)).FromJust(); - ret->Set(context, offset + i, txt_chunk_obj).FromJust(); + if (!txt_chunk.IsEmpty()) { + if (need_type) { + Local elem = Object::New(env->isolate()); + elem->Set(context, env->entries_string(), txt_chunk).FromJust(); + elem->Set(context, + env->type_string(), + env->dns_txt_string()).FromJust(); + ret->Set(context, offset + i, elem).FromJust(); + } else { + ret->Set(context, offset + i, txt_chunk).FromJust(); + } } ares_free_data(txt_out); @@ -911,7 +905,6 @@ int ParseSoaReply(Environment* env, /* only need SOA */ if (rr_type == ns_t_soa) { ares_soa_reply soa; - // ares_soa_reply* soa = node::Malloc(1); status = ares_expand_name(ptr, buf, len, &soa.nsname, &temp_len); if (status != ARES_SUCCESS) { diff --git a/src/env.h b/src/env.h index fdf5ba4bc2fccf..844eb8fea8208e 100644 --- a/src/env.h +++ b/src/env.h @@ -123,6 +123,7 @@ namespace node { V(irq_string, "irq") \ V(encoding_string, "encoding") \ V(enter_string, "enter") \ + V(entries_string, "entries") \ V(env_pairs_string, "envPairs") \ V(errno_string, "errno") \ V(error_string, "error") \ diff --git a/test/internet/test-dns-any.js b/test/internet/test-dns-any.js index 07b25b50282dcf..e872340fffa769 100644 --- a/test/internet/test-dns-any.js +++ b/test/internet/test-dns-any.js @@ -12,7 +12,7 @@ const queue = []; const isIPv4 = net.isIPv4; const isIPv6 = net.isIPv6; -dns.setServers(['8.8.8.8', '8.8.4.4']); +dns.setServers([ '8.8.8.8', '8.8.4.4' ]); function checkWrap(req) { assert.ok(typeof req === 'object'); @@ -57,8 +57,9 @@ const checkers = { assert.strictEqual(r.type, 'PTR'); }, checkTXT(r) { - assert.ok(r.length > 0); - Array.prototype.forEach.call(r, (txt) => { + assert.ok(Array.isArray(r.entries)); + assert.ok(r.entries.length > 0); + r.entries.forEach((txt) => { assert.strictEqual(txt.indexOf('v=spf1'), 0); }); assert.strictEqual(r.type, 'TXT'); From 550dcf76a3d4be66bafa5385e90440bd14da364a Mon Sep 17 00:00:00 2001 From: XadillaX Date: Sun, 4 Jun 2017 00:04:05 +0800 Subject: [PATCH 5/5] update test for srv --- test/internet/test-dns-any.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/internet/test-dns-any.js b/test/internet/test-dns-any.js index e872340fffa769..7650c59a613de3 100644 --- a/test/internet/test-dns-any.js +++ b/test/internet/test-dns-any.js @@ -152,23 +152,21 @@ TEST(function test_sip2sip_for_naptr(done) { checkWrap(req); }); -TEST(function test_toshihikojs_for_cname_and_srv(done) { +TEST(function test_google_for_cname_and_srv(done) { const req = dns.resolve( - '_sipfederationtls._tcp.toshihikojs.com', + '_jabber._tcp.google.com', 'ANY', common.mustCall(function(err, ret) { assert.ifError(err); assert.ok(Array.isArray(ret)); assert.ok(ret.length > 0); - /* current _sipfederationtls._tcp.toshihikojs.com has SRV and */ - /* CNAME records */ const types = {}; ret.forEach((obj) => { types[obj.type] = true; checkers[`check${obj.type}`](obj); }); - assert.ok(types.SRV && types.CNAME); + assert.ok(types.SRV); done(); }));