dns: add order option and support ipv6first

PR-URL: https://github.com/nodejs/node/pull/52492
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
This commit is contained in:
Paolo Insogna 2024-04-17 17:24:28 +02:00 committed by GitHub
parent b41347e496
commit 7e89369166
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 400 additions and 90 deletions

View File

@ -594,16 +594,20 @@ added:
- v16.4.0
- v14.18.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52492
description: The `ipv6first` is supported now.
- version: v17.0.0
pr-url: https://github.com/nodejs/node/pull/39987
description: Changed default value to `verbatim`.
-->
Set the default value of `verbatim` in [`dns.lookup()`][] and
Set the default value of `order` in [`dns.lookup()`][] and
[`dnsPromises.lookup()`][]. The value could be:
* `ipv4first`: sets default `verbatim` `false`.
* `verbatim`: sets default `verbatim` `true`.
* `ipv4first`: sets default `order` to `ipv4first`.
* `ipv6first`: sets default `order` to `ipv6first`.
* `verbatim`: sets default `order` to `verbatim`.
The default is `verbatim` and [`dns.setDefaultResultOrder()`][] have higher
priority than `--dns-result-order`.

View File

@ -179,6 +179,9 @@ section if a custom port is used.
<!-- YAML
added: v0.1.90
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52492
description: The `verbatim` option is now deprecated in favor of the new `order` option.
- version: v18.4.0
pr-url: https://github.com/nodejs/node/pull/43054
description: For compatibility with `node:net`, when passing an option
@ -211,9 +214,18 @@ changes:
flags may be passed by bitwise `OR`ing their values.
* `all` {boolean} When `true`, the callback returns all resolved addresses in
an array. Otherwise, returns a single address. **Default:** `false`.
* `order` {string} When `verbatim`, the resolved addresses are return
unsorted. When `ipv4first`, the resolved addresses are sorted by placing
IPv4 addresses before IPv6 addresses. When `ipv6first`, the resolved
addresses are sorted by placing IPv6 addresses before IPv4 addresses.
**Default:** `verbatim` (addresses are not reordered).
Default value is configurable using [`dns.setDefaultResultOrder()`][] or
[`--dns-result-order`][].
* `verbatim` {boolean} When `true`, the callback receives IPv4 and IPv6
addresses in the order the DNS resolver returned them. When `false`,
IPv4 addresses are placed before IPv6 addresses.
This option will be deprecated in favor of `order`. When both are specified,
`order` has higher precedence. New code should only use `order`.
**Default:** `true` (addresses are not reordered). Default value is
configurable using [`dns.setDefaultResultOrder()`][] or
[`--dns-result-order`][].
@ -775,18 +787,22 @@ added:
- v16.4.0
- v14.18.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52492
description: The `ipv6first` value is supported now.
- version: v17.0.0
pr-url: https://github.com/nodejs/node/pull/39987
description: Changed default value to `verbatim`.
-->
* `order` {string} must be `'ipv4first'` or `'verbatim'`.
* `order` {string} must be `'ipv4first'`, `'ipv6first'` or `'verbatim'`.
Set the default value of `verbatim` in [`dns.lookup()`][] and
Set the default value of `order` in [`dns.lookup()`][] and
[`dnsPromises.lookup()`][]. The value could be:
* `ipv4first`: sets default `verbatim` `false`.
* `verbatim`: sets default `verbatim` `true`.
* `ipv4first`: sets default `order` to `ipv4first`.
* `ipv6first`: sets default `order` to `ipv6first`.
* `verbatim`: sets default `order` to `verbatim`.
The default is `verbatim` and [`dns.setDefaultResultOrder()`][] have higher
priority than [`--dns-result-order`][]. When using [worker threads][],
@ -799,13 +815,18 @@ dns orders in workers.
added:
- v20.1.0
- v18.17.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52492
description: The `ipv6first` value is supported now.
-->
Get the default value for `verbatim` in [`dns.lookup()`][] and
Get the default value for `order` in [`dns.lookup()`][] and
[`dnsPromises.lookup()`][]. The value could be:
* `ipv4first`: for `verbatim` defaulting to `false`.
* `verbatim`: for `verbatim` defaulting to `true`.
* `ipv4first`: for `order` defaulting to `ipv4first`.
* `ipv6first`: for `order` defaulting to `ipv6first`.
* `verbatim`: for `order` defaulting to `verbatim`.
## `dns.setServers(servers)`
@ -949,6 +970,10 @@ section if a custom port is used.
<!-- YAML
added: v10.6.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52492
description: The `verbatim` option is now deprecated in favor of the new `order` option.
-->
* `hostname` {string}
@ -961,13 +986,22 @@ added: v10.6.0
flags may be passed by bitwise `OR`ing their values.
* `all` {boolean} When `true`, the `Promise` is resolved with all addresses in
an array. Otherwise, returns a single address. **Default:** `false`.
* `order` {string} When `verbatim`, the `Promise` is resolved with IPv4 and
IPv6 addresses in the order the DNS resolver returned them. When `ipv4first`,
IPv4 addresses are placed before IPv6 addresses. When `ipv6first`,
IPv6 addresses are placed before IPv4 addresses.
**Default:** `verbatim` (addresses are not reordered).
Default value is configurable using [`dns.setDefaultResultOrder()`][] or
[`--dns-result-order`][]. New code should use `{ order: 'verbatim' }`.
* `verbatim` {boolean} When `true`, the `Promise` is resolved with IPv4 and
IPv6 addresses in the order the DNS resolver returned them. When `false`,
IPv4 addresses are placed before IPv6 addresses.
This option will be deprecated in favor of `order`. When both are specified,
`order` has higher precedence. New code should only use `order`.
**Default:** currently `false` (addresses are reordered) but this is
expected to change in the not too distant future. Default value is
configurable using [`dns.setDefaultResultOrder()`][] or
[`--dns-result-order`][]. New code should use `{ verbatim: true }`.
[`--dns-result-order`][].
Resolves a host name (e.g. `'nodejs.org'`) into the first found A (IPv4) or
AAAA (IPv6) record. All `option` properties are optional. If `options` is an
@ -1349,18 +1383,22 @@ added:
- v16.4.0
- v14.18.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52492
description: The `ipv6first` value is supported now.
- version: v17.0.0
pr-url: https://github.com/nodejs/node/pull/39987
description: Changed default value to `verbatim`.
-->
* `order` {string} must be `'ipv4first'` or `'verbatim'`.
* `order` {string} must be `'ipv4first'`, `'ipv6first'` or `'verbatim'`.
Set the default value of `verbatim` in [`dns.lookup()`][] and
Set the default value of `order` in [`dns.lookup()`][] and
[`dnsPromises.lookup()`][]. The value could be:
* `ipv4first`: sets default `verbatim` `false`.
* `verbatim`: sets default `verbatim` `true`.
* `ipv4first`: sets default `order` to `ipv4first`.
* `ipv6first`: sets default `order` to `ipv6first`.
* `verbatim`: sets default `order` to `verbatim`.
The default is `verbatim` and [`dnsPromises.setDefaultResultOrder()`][] have
higher priority than [`--dns-result-order`][]. When using [worker threads][],

View File

@ -43,7 +43,6 @@ const {
setDefaultResolver,
validateHints,
emitInvalidHostnameWarning,
getDefaultVerbatim,
getDefaultResultOrder,
setDefaultResultOrder,
errorCodes: dnsErrorCodes,
@ -89,6 +88,9 @@ const {
const {
GetAddrInfoReqWrap,
GetNameInfoReqWrap,
DNS_ORDER_VERBATIM,
DNS_ORDER_IPV4_FIRST,
DNS_ORDER_IPV6_FIRST,
} = cares;
const kPerfHooksDnsLookupContext = Symbol('kPerfHooksDnsLookupContext');
@ -141,7 +143,7 @@ function lookup(hostname, options, callback) {
let hints = 0;
let family = 0;
let all = false;
let verbatim = getDefaultVerbatim();
let dnsOrder = getDefaultResultOrder();
// Parse arguments
if (hostname) {
@ -187,7 +189,11 @@ function lookup(hostname, options, callback) {
}
if (options?.verbatim != null) {
validateBoolean(options.verbatim, 'options.verbatim');
verbatim = options.verbatim;
dnsOrder = options.verbatim ? 'verbatim' : 'ipv4first';
}
if (options?.order != null) {
validateOneOf(options.order, 'options.order', ['ipv4first', 'ipv6first', 'verbatim']);
dnsOrder = options.dnsOrder;
}
}
@ -218,8 +224,16 @@ function lookup(hostname, options, callback) {
req.hostname = hostname;
req.oncomplete = all ? onlookupall : onlookup;
let order = DNS_ORDER_VERBATIM;
if (dnsOrder === 'ipv4first') {
order = DNS_ORDER_IPV4_FIRST;
} else if (dnsOrder === 'ipv6first') {
order = DNS_ORDER_IPV6_FIRST;
}
const err = cares.getaddrinfo(
req, hostname, family, hints, verbatim,
req, hostname, family, hints, order,
);
if (err) {
process.nextTick(callback, new DNSException(err, 'getaddrinfo', hostname));
@ -230,8 +244,10 @@ function lookup(hostname, options, callback) {
hostname,
family,
hints,
verbatim,
verbatim: order === DNS_ORDER_VERBATIM,
order: dnsOrder,
};
startPerf(req, kPerfHooksDnsLookupContext, { type: 'dns', name: 'lookup', detail });
}
return req;

View File

@ -12,7 +12,6 @@ const {
createResolverClass,
validateHints,
emitInvalidHostnameWarning,
getDefaultVerbatim,
errorCodes: dnsErrorCodes,
getDefaultResultOrder,
setDefaultResultOrder,
@ -53,6 +52,9 @@ const {
GetAddrInfoReqWrap,
GetNameInfoReqWrap,
QueryReqWrap,
DNS_ORDER_VERBATIM,
DNS_ORDER_IPV4_FIRST,
DNS_ORDER_IPV6_FIRST,
} = internalBinding('cares_wrap');
const {
ERR_INVALID_ARG_TYPE,
@ -120,13 +122,13 @@ function onlookupall(err, addresses) {
* @param {boolean} all - Whether to resolve with all IP addresses for the hostname.
* @param {number} hints - One or more supported getaddrinfo flags (supply multiple via
* bitwise OR).
* @param {boolean} verbatim - Whether to use the hostname verbatim.
* @param {number} dnsOrder - How to sort results. Must be `ipv4first`, `ipv6first` or `verbatim`.
* @returns {Promise<DNSLookupResult | DNSLookupResult[]>} The IP address(es) of the hostname.
* @typedef {object} DNSLookupResult
* @property {string} address - The IP address.
* @property {0 | 4 | 6} family - The IP address type. 4 for IPv4 or 6 for IPv6, or 0 (for both).
*/
function createLookupPromise(family, hostname, all, hints, verbatim) {
function createLookupPromise(family, hostname, all, hints, dnsOrder) {
return new Promise((resolve, reject) => {
if (!hostname) {
emitInvalidHostnameWarning(hostname);
@ -150,7 +152,15 @@ function createLookupPromise(family, hostname, all, hints, verbatim) {
req.resolve = resolve;
req.reject = reject;
const err = getaddrinfo(req, hostname, family, hints, verbatim);
let order = DNS_ORDER_VERBATIM;
if (dnsOrder === 'ipv4first') {
order = DNS_ORDER_IPV4_FIRST;
} else if (dnsOrder === 'ipv6first') {
order = DNS_ORDER_IPV6_FIRST;
}
const err = getaddrinfo(req, hostname, family, hints, order);
if (err) {
reject(new DNSException(err, 'getaddrinfo', hostname));
@ -159,7 +169,8 @@ function createLookupPromise(family, hostname, all, hints, verbatim) {
hostname,
family,
hints,
verbatim,
verbatim: order === DNS_ORDER_VERBATIM,
order: dnsOrder,
};
startPerf(req, kPerfHooksDnsLookupContext, { type: 'dns', name: 'lookup', detail });
}
@ -175,14 +186,15 @@ const validFamilies = [0, 4, 6];
* @param {0 | 4 | 6} [options.family=0] - The record family. Must be 4, 6, or 0 (for both).
* @param {number} [options.hints] - One or more supported getaddrinfo flags (supply multiple via
* bitwise OR).
* @param {boolean} [options.verbatim=false] - Return results in same order DNS resolved them;
* otherwise IPv4 then IPv6. New code should supply `true`.
* @param {string} [options.order='verbatim'] - Return results in same order DNS resolved them;
* Must be `ipv4first`, `ipv6first` or `verbatim`.
* New code should supply `verbatim`.
*/
function lookup(hostname, options) {
let hints = 0;
let family = 0;
let all = false;
let verbatim = getDefaultVerbatim();
let dnsOrder = getDefaultResultOrder();
// Parse arguments
if (hostname) {
@ -210,11 +222,15 @@ function lookup(hostname, options) {
}
if (options?.verbatim != null) {
validateBoolean(options.verbatim, 'options.verbatim');
verbatim = options.verbatim;
dnsOrder = options.verbatim ? 'verbatim' : 'ipv4first';
}
if (options?.order != null) {
validateOneOf(options.order, 'options.order', ['ipv4first', 'ipv6first', 'verbatim']);
dnsOrder = options.order;
}
}
return createLookupPromise(family, hostname, all, hints, verbatim);
return createLookupPromise(family, hostname, all, hints, dnsOrder);
}

View File

@ -207,6 +207,7 @@ function initializeDns() {
dnsOrder ??= 'verbatim';
} else {
// Allow the deserialized application to override order from CLI.
validateOneOf(orderFromCLI, '--dns-result-order', ['verbatim', 'ipv4first', 'ipv6first']);
dnsOrder = orderFromCLI;
}
@ -277,12 +278,8 @@ function emitInvalidHostnameWarning(hostname) {
}
}
function getDefaultVerbatim() {
return dnsOrder !== 'ipv4first';
}
function setDefaultResultOrder(value) {
validateOneOf(value, 'dnsOrder', ['verbatim', 'ipv4first']);
validateOneOf(value, 'dnsOrder', ['verbatim', 'ipv4first', 'ipv6first']);
dnsOrder = value;
}
@ -351,7 +348,6 @@ module.exports = {
validateTimeout,
validateTries,
emitInvalidHostnameWarning,
getDefaultVerbatim,
getDefaultResultOrder,
setDefaultResultOrder,
errorCodes,

View File

@ -253,7 +253,7 @@ async function isLocalAddress(hostname) {
) {
hostname = StringPrototypeSlice(hostname, 1, -1);
}
const addr = await dnsLookup(hostname, { verbatim: true });
const addr = await dnsLookup(hostname, { order: 'verbatim' });
const ipv = addr.family === 4 ? 'ipv4' : 'ipv6';
return allowList.check(addr.address, ipv);
} catch {

View File

@ -72,6 +72,7 @@ using v8::Nothing;
using v8::Null;
using v8::Object;
using v8::String;
using v8::Uint32;
using v8::Value;
namespace {
@ -665,12 +666,11 @@ void ChannelWrap::New(const FunctionCallbackInfo<Value>& args) {
new ChannelWrap(env, args.This(), timeout, tries);
}
GetAddrInfoReqWrap::GetAddrInfoReqWrap(
Environment* env,
GetAddrInfoReqWrap::GetAddrInfoReqWrap(Environment* env,
Local<Object> req_wrap_obj,
bool verbatim)
uint8_t order)
: ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETADDRINFOREQWRAP),
verbatim_(verbatim) {}
order_(order) {}
GetNameInfoReqWrap::GetNameInfoReqWrap(
Environment* env,
@ -1445,7 +1445,7 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
};
uint32_t n = 0;
const bool verbatim = req_wrap->verbatim();
const uint8_t order = req_wrap->order();
if (status == 0) {
Local<Array> results = Array::New(env->isolate());
@ -1477,11 +1477,21 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
return Just(true);
};
if (add(true, verbatim).IsNothing())
return;
if (verbatim == false) {
if (add(false, true).IsNothing())
return;
switch (order) {
case DNS_ORDER_IPV4_FIRST:
if (add(true, false).IsNothing()) return;
if (add(false, true).IsNothing()) return;
break;
case DNS_ORDER_IPV6_FIRST:
if (add(false, true).IsNothing()) return;
if (add(true, false).IsNothing()) return;
break;
default:
if (add(true, true).IsNothing()) return;
break;
}
// No responses were found to return
@ -1492,9 +1502,13 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
argv[1] = results;
}
TRACE_EVENT_NESTABLE_ASYNC_END2(
TRACING_CATEGORY_NODE2(dns, native), "lookup", req_wrap.get(),
"count", n, "verbatim", verbatim);
TRACE_EVENT_NESTABLE_ASYNC_END2(TRACING_CATEGORY_NODE2(dns, native),
"lookup",
req_wrap.get(),
"count",
n,
"order",
order);
// Make the callback into JavaScript
req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv);
@ -1558,7 +1572,7 @@ void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsObject());
CHECK(args[1]->IsString());
CHECK(args[2]->IsInt32());
CHECK(args[4]->IsBoolean());
CHECK(args[4]->IsUint32());
Local<Object> req_wrap_obj = args[0].As<Object>();
node::Utf8Value hostname(env->isolate(), args[1]);
std::string ascii_hostname = ada::idna::to_ascii(hostname.ToStringView());
@ -1584,9 +1598,10 @@ void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
UNREACHABLE("bad address family");
}
auto req_wrap = std::make_unique<GetAddrInfoReqWrap>(env,
req_wrap_obj,
args[4]->IsTrue());
Local<Uint32> order = args[4].As<Uint32>();
auto req_wrap =
std::make_unique<GetAddrInfoReqWrap>(env, req_wrap_obj, order->Value());
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
@ -1905,6 +1920,31 @@ void Initialize(Local<Object> target,
target->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(),
"AI_V4MAPPED"),
Integer::New(env->isolate(), AI_V4MAPPED)).Check();
target
->Set(env->context(),
FIXED_ONE_BYTE_STRING(env->isolate(), "DNS_ORDER_VERBATIM"),
Integer::New(env->isolate(), DNS_ORDER_VERBATIM))
.Check();
target
->Set(env->context(),
FIXED_ONE_BYTE_STRING(env->isolate(), "DNS_ORDER_IPV4_FIRST"),
Integer::New(env->isolate(), DNS_ORDER_IPV4_FIRST))
.Check();
target
->Set(env->context(),
FIXED_ONE_BYTE_STRING(env->isolate(), "DNS_ORDER_IPV6_FIRST"),
Integer::New(env->isolate(), DNS_ORDER_IPV6_FIRST))
.Check();
target
->Set(env->context(),
FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET"),
Integer::New(env->isolate(), AF_INET))
.Check();
target
->Set(env->context(),
FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET"),
Integer::New(env->isolate(), AF_INET))
.Check();
Local<FunctionTemplate> aiw =
BaseObject::MakeLazilyInitializedJSTemplate(env);

View File

@ -30,6 +30,9 @@ namespace cares_wrap {
constexpr int ns_t_cname_or_a = -1;
constexpr int DNS_ESETSRVPENDING = -1000;
constexpr uint8_t DNS_ORDER_VERBATIM = 0;
constexpr uint8_t DNS_ORDER_IPV4_FIRST = 1;
constexpr uint8_t DNS_ORDER_IPV6_FIRST = 2;
class ChannelWrap;
@ -195,16 +198,16 @@ class GetAddrInfoReqWrap final : public ReqWrap<uv_getaddrinfo_t> {
public:
GetAddrInfoReqWrap(Environment* env,
v8::Local<v8::Object> req_wrap_obj,
bool verbatim);
uint8_t order);
SET_NO_MEMORY_INFO()
SET_MEMORY_INFO_NAME(GetAddrInfoReqWrap)
SET_SELF_SIZE(GetAddrInfoReqWrap)
bool verbatim() const { return verbatim_; }
uint8_t order() const { return order_; }
private:
const bool verbatim_;
const uint8_t order_;
};
class GetNameInfoReqWrap final : public ReqWrap<uv_getnameinfo_t> {

View File

@ -374,6 +374,7 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
AddOption("--dns-result-order",
"set default value of verbatim in dns.lookup. Options are "
"'ipv4first' (IPv4 addresses are placed before IPv6 addresses) "
"'ipv6first' (IPv6 addresses are placed before IPv4 addresses) "
"'verbatim' (addresses are in the order the DNS resolver "
"returned)",
&EnvironmentOptions::dns_result_order,

View File

@ -8,6 +8,9 @@ const dns = require('dns');
dns.setDefaultResultOrder('ipv4first');
let dnsOrder = dns.getDefaultResultOrder();
assert.ok(dnsOrder === 'ipv4first');
dns.setDefaultResultOrder('ipv6first');
dnsOrder = dns.getDefaultResultOrder();
assert.ok(dnsOrder === 'ipv6first');
dns.setDefaultResultOrder('verbatim');
dnsOrder = dns.getDefaultResultOrder();
assert.ok(dnsOrder === 'verbatim');
@ -15,10 +18,26 @@ assert.ok(dnsOrder === 'verbatim');
{
(async function() {
const result = await dns.promises.lookup('localhost');
const result1 = await dns.promises.lookup('localhost', { verbatim: true });
const result1 = await dns.promises.lookup('localhost', { order: 'verbatim' });
assert.ok(result !== undefined);
assert.ok(result1 !== undefined);
assert.ok(result.address === result1.address);
assert.ok(result.family === result1.family);
})().then(common.mustCall());
}
{
(async function() {
const result = await dns.promises.lookup('localhost', { order: 'ipv4first' });
assert.ok(result !== undefined);
assert.ok(result.family === 4);
})().then(common.mustCall());
}
if (common.hasIPv6) {
(async function() {
const result = await dns.promises.lookup('localhost', { order: 'ipv6first' });
assert.ok(result !== undefined);
assert.ok(result.family === 6);
})().then(common.mustCall());
}

View File

@ -722,7 +722,7 @@ console.log(`looking up ${addresses.INET4_HOST}..`);
const cares = internalBinding('cares_wrap');
const req = new cares.GetAddrInfoReqWrap();
cares.getaddrinfo(req, addresses.INET4_HOST, 4,
/* hints */ 0, /* verbatim */ true);
/* hints */ 0, /* order */ cares.DNS_ORDER_VERBATIM);
req.oncomplete = function(err, domains) {
assert.strictEqual(err, 0);

View File

@ -0,0 +1,49 @@
// Flags: --expose-internals --dns-result-order=ipv4first
'use strict';
const common = require('../common');
const assert = require('assert');
const { internalBinding } = require('internal/test/binding');
const cares = internalBinding('cares_wrap');
const { promisify } = require('util');
// Test that --dns-result-order=ipv4first works as expected.
const originalGetaddrinfo = cares.getaddrinfo;
const calls = [];
cares.getaddrinfo = common.mustCallAtLeast((...args) => {
calls.push(args);
originalGetaddrinfo(...args);
}, 1);
const dns = require('dns');
const dnsPromises = dns.promises;
// We want to test the parameter of order only so that we
// ignore possible errors here.
function allowFailed(fn) {
return fn.catch((_err) => {
//
});
}
(async () => {
let callsLength = 0;
const checkParameter = (expected) => {
assert.strictEqual(calls.length, callsLength + 1);
const order = calls[callsLength][4];
assert.strictEqual(order, expected);
callsLength += 1;
};
await allowFailed(promisify(dns.lookup)('example.org'));
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
await allowFailed(dnsPromises.lookup('example.org'));
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
await allowFailed(promisify(dns.lookup)('example.org', {}));
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
await allowFailed(dnsPromises.lookup('example.org', {}));
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
})().then(common.mustCall());

View File

@ -0,0 +1,49 @@
// Flags: --expose-internals --dns-result-order=ipv6first
'use strict';
const common = require('../common');
const assert = require('assert');
const { internalBinding } = require('internal/test/binding');
const cares = internalBinding('cares_wrap');
const { promisify } = require('util');
// Test that --dns-result-order=verbatim works as expected.
const originalGetaddrinfo = cares.getaddrinfo;
const calls = [];
cares.getaddrinfo = common.mustCallAtLeast((...args) => {
calls.push(args);
originalGetaddrinfo(...args);
}, 1);
const dns = require('dns');
const dnsPromises = dns.promises;
// We want to test the parameter of verbatim only so that we
// ignore possible errors here.
function allowFailed(fn) {
return fn.catch((_err) => {
//
});
}
(async () => {
let callsLength = 0;
const checkParameter = (expected) => {
assert.strictEqual(calls.length, callsLength + 1);
const order = calls[callsLength][4];
assert.strictEqual(order, expected);
callsLength += 1;
};
await allowFailed(promisify(dns.lookup)('example.org'));
checkParameter(cares.DNS_ORDER_IPV6_FIRST);
await allowFailed(dnsPromises.lookup('example.org'));
checkParameter(cares.DNS_ORDER_IPV6_FIRST);
await allowFailed(promisify(dns.lookup)('example.org', {}));
checkParameter(cares.DNS_ORDER_IPV6_FIRST);
await allowFailed(dnsPromises.lookup('example.org', {}));
checkParameter(cares.DNS_ORDER_IPV6_FIRST);
})().then(common.mustCall());

View File

@ -0,0 +1,49 @@
// Flags: --expose-internals --dns-result-order=verbatim
'use strict';
const common = require('../common');
const assert = require('assert');
const { internalBinding } = require('internal/test/binding');
const cares = internalBinding('cares_wrap');
const { promisify } = require('util');
// Test that --dns-result-order=verbatim works as expected.
const originalGetaddrinfo = cares.getaddrinfo;
const calls = [];
cares.getaddrinfo = common.mustCallAtLeast((...args) => {
calls.push(args);
originalGetaddrinfo(...args);
}, 1);
const dns = require('dns');
const dnsPromises = dns.promises;
// We want to test the parameter of verbatim only so that we
// ignore possible errors here.
function allowFailed(fn) {
return fn.catch((_err) => {
//
});
}
(async () => {
let callsLength = 0;
const checkParameter = (expected) => {
assert.strictEqual(calls.length, callsLength + 1);
const order = calls[callsLength][4];
assert.strictEqual(order, expected);
callsLength += 1;
};
await allowFailed(promisify(dns.lookup)('example.org'));
checkParameter(cares.DNS_ORDER_VERBATIM);
await allowFailed(dnsPromises.lookup('example.org'));
checkParameter(cares.DNS_ORDER_VERBATIM);
await allowFailed(promisify(dns.lookup)('example.org', {}));
checkParameter(cares.DNS_ORDER_VERBATIM);
await allowFailed(dnsPromises.lookup('example.org', {}));
checkParameter(cares.DNS_ORDER_VERBATIM);
})().then(common.mustCall());

View File

@ -38,14 +38,14 @@ function allowFailed(fn) {
};
await allowFailed(promisify(dns.lookup)('example.org'));
checkParameter(false);
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
await allowFailed(dnsPromises.lookup('example.org'));
checkParameter(false);
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
await allowFailed(promisify(dns.lookup)('example.org', {}));
checkParameter(false);
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
await allowFailed(dnsPromises.lookup('example.org', {}));
checkParameter(false);
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
})().then(common.mustCall());

View File

@ -38,14 +38,14 @@ function allowFailed(fn) {
};
await allowFailed(promisify(dns.lookup)('example.org'));
checkParameter(true);
checkParameter(cares.DNS_ORDER_VERBATIM);
await allowFailed(dnsPromises.lookup('example.org'));
checkParameter(true);
checkParameter(cares.DNS_ORDER_VERBATIM);
await allowFailed(promisify(dns.lookup)('example.org', {}));
checkParameter(true);
checkParameter(cares.DNS_ORDER_VERBATIM);
await allowFailed(dnsPromises.lookup('example.org', {}));
checkParameter(true);
checkParameter(cares.DNS_ORDER_VERBATIM);
})().then(common.mustCall());

View File

@ -31,5 +31,7 @@ assert.throws(() => dnsPromises.lookup('127.0.0.1', { all: 'true' }),
{ code: 'ERR_INVALID_ARG_TYPE' });
assert.throws(() => dnsPromises.lookup('127.0.0.1', { verbatim: 'true' }),
{ code: 'ERR_INVALID_ARG_TYPE' });
assert.throws(() => dnsPromises.lookup('127.0.0.1', { order: 'true' }),
{ code: 'ERR_INVALID_ARG_VALUE' });
assert.throws(() => dnsPromises.lookup('127.0.0.1', '6'),
{ code: 'ERR_INVALID_ARG_TYPE' });

View File

@ -133,6 +133,15 @@ assert.throws(() => dnsPromises.lookup(false, () => {}),
}, err);
});
[0, 1, 0n, 1n, '', '0', Symbol(), {}, [], () => {}].forEach((order) => {
const err = { code: 'ERR_INVALID_ARG_VALUE' };
const options = { order };
assert.throws(() => { dnsPromises.lookup(false, options); }, err);
assert.throws(() => {
dns.lookup(false, options, common.mustNotCall());
}, err);
});
(async function() {
let res;

View File

@ -42,6 +42,7 @@ process.on('exit', () => {
assert.strictEqual(typeof entry.detail.family, 'number');
assert.strictEqual(typeof entry.detail.hints, 'number');
assert.strictEqual(typeof entry.detail.verbatim, 'boolean');
assert.strictEqual(typeof entry.detail.order, 'string');
assert.strictEqual(Array.isArray(entry.detail.addresses), true);
break;
case 'lookupService':

View File

@ -19,9 +19,7 @@ cares.getaddrinfo = common.mustCallAtLeast((...args) => {
const dns = require('dns');
const dnsPromises = dns.promises;
let verbatim;
// We want to test the parameter of verbatim only so that we
// We want to test the parameter of order only so that we
// ignore possible errors here.
function allowFailed(fn) {
return fn.catch((_err) => {
@ -46,48 +44,68 @@ assert.throws(() => dns.promises.setDefaultResultOrder(4), {
let callsLength = 0;
const checkParameter = (expected) => {
assert.strictEqual(calls.length, callsLength + 1);
verbatim = calls[callsLength][4];
assert.strictEqual(verbatim, expected);
const order = calls[callsLength][4];
assert.strictEqual(order, expected);
callsLength += 1;
};
dns.setDefaultResultOrder('verbatim');
await allowFailed(promisify(dns.lookup)('example.org'));
checkParameter(true);
checkParameter(cares.DNS_ORDER_VERBATIM);
await allowFailed(dnsPromises.lookup('example.org'));
checkParameter(true);
checkParameter(cares.DNS_ORDER_VERBATIM);
await allowFailed(promisify(dns.lookup)('example.org', {}));
checkParameter(true);
checkParameter(cares.DNS_ORDER_VERBATIM);
await allowFailed(dnsPromises.lookup('example.org', {}));
checkParameter(true);
checkParameter(cares.DNS_ORDER_VERBATIM);
dns.setDefaultResultOrder('ipv4first');
await allowFailed(promisify(dns.lookup)('example.org'));
checkParameter(false);
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
await allowFailed(dnsPromises.lookup('example.org'));
checkParameter(false);
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
await allowFailed(promisify(dns.lookup)('example.org', {}));
checkParameter(false);
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
await allowFailed(dnsPromises.lookup('example.org', {}));
checkParameter(false);
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
dns.setDefaultResultOrder('ipv6first');
await allowFailed(promisify(dns.lookup)('example.org'));
checkParameter(cares.DNS_ORDER_IPV6_FIRST);
await allowFailed(dnsPromises.lookup('example.org'));
checkParameter(cares.DNS_ORDER_IPV6_FIRST);
await allowFailed(promisify(dns.lookup)('example.org', {}));
checkParameter(cares.DNS_ORDER_IPV6_FIRST);
await allowFailed(dnsPromises.lookup('example.org', {}));
checkParameter(cares.DNS_ORDER_IPV6_FIRST);
dns.promises.setDefaultResultOrder('verbatim');
await allowFailed(promisify(dns.lookup)('example.org'));
checkParameter(true);
checkParameter(cares.DNS_ORDER_VERBATIM);
await allowFailed(dnsPromises.lookup('example.org'));
checkParameter(true);
checkParameter(cares.DNS_ORDER_VERBATIM);
await allowFailed(promisify(dns.lookup)('example.org', {}));
checkParameter(true);
checkParameter(cares.DNS_ORDER_VERBATIM);
await allowFailed(dnsPromises.lookup('example.org', {}));
checkParameter(true);
checkParameter(cares.DNS_ORDER_VERBATIM);
dns.promises.setDefaultResultOrder('ipv4first');
await allowFailed(promisify(dns.lookup)('example.org'));
checkParameter(false);
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
await allowFailed(dnsPromises.lookup('example.org'));
checkParameter(false);
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
await allowFailed(promisify(dns.lookup)('example.org', {}));
checkParameter(false);
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
await allowFailed(dnsPromises.lookup('example.org', {}));
checkParameter(false);
checkParameter(cares.DNS_ORDER_IPV4_FIRST);
dns.promises.setDefaultResultOrder('ipv6first');
await allowFailed(promisify(dns.lookup)('example.org'));
checkParameter(cares.DNS_ORDER_IPV6_FIRST);
await allowFailed(dnsPromises.lookup('example.org'));
checkParameter(cares.DNS_ORDER_IPV6_FIRST);
await allowFailed(promisify(dns.lookup)('example.org', {}));
checkParameter(cares.DNS_ORDER_IPV6_FIRST);
await allowFailed(dnsPromises.lookup('example.org', {}));
checkParameter(cares.DNS_ORDER_IPV6_FIRST);
})().then(common.mustCall());

View File

@ -292,7 +292,7 @@ dns.lookup('', {
await dnsPromises.lookup('', {
hints: dns.ADDRCONFIG | dns.V4MAPPED | dns.ALL
});
await dnsPromises.lookup('', { verbatim: true });
await dnsPromises.lookup('', { order: 'verbatim' });
})().then(common.mustCall());
{