mirror of
https://github.com/nodejs/node.git
synced 2025-05-11 09:57:00 +00:00

The `validateString()` validator should cleanup the validation and keep consistency. PR-URL: https://github.com/nodejs/node/pull/40061 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
231 lines
5.5 KiB
JavaScript
231 lines
5.5 KiB
JavaScript
'use strict';
|
|
|
|
const {
|
|
ArrayPrototypeForEach,
|
|
ArrayPrototypeJoin,
|
|
ArrayPrototypeMap,
|
|
ArrayPrototypePush,
|
|
FunctionPrototypeBind,
|
|
NumberParseInt,
|
|
StringPrototypeMatch,
|
|
StringPrototypeReplace,
|
|
} = primordials;
|
|
|
|
const errors = require('internal/errors');
|
|
const { isIP } = require('internal/net');
|
|
const { getOptionValue } = require('internal/options');
|
|
const {
|
|
validateArray,
|
|
validateInt32,
|
|
validateOneOf,
|
|
validateString,
|
|
} = require('internal/validators');
|
|
const {
|
|
ChannelWrap,
|
|
strerror,
|
|
AI_ADDRCONFIG,
|
|
AI_ALL,
|
|
AI_V4MAPPED,
|
|
} = internalBinding('cares_wrap');
|
|
const IANA_DNS_PORT = 53;
|
|
const IPv6RE = /^\[([^[\]]*)\]/;
|
|
const addrSplitRE = /(^.+?)(?::(\d+))?$/;
|
|
const {
|
|
ERR_DNS_SET_SERVERS_FAILED,
|
|
ERR_INVALID_ARG_VALUE,
|
|
ERR_INVALID_IP_ADDRESS,
|
|
} = errors.codes;
|
|
|
|
function validateTimeout(options) {
|
|
const { timeout = -1 } = { ...options };
|
|
validateInt32(timeout, 'options.timeout', -1, 2 ** 31 - 1);
|
|
return timeout;
|
|
}
|
|
|
|
function validateTries(options) {
|
|
const { tries = 4 } = { ...options };
|
|
validateInt32(tries, 'options.tries', 1, 2 ** 31 - 1);
|
|
return tries;
|
|
}
|
|
|
|
// Resolver instances correspond 1:1 to c-ares channels.
|
|
class Resolver {
|
|
constructor(options = undefined) {
|
|
const timeout = validateTimeout(options);
|
|
const tries = validateTries(options);
|
|
this._handle = new ChannelWrap(timeout, tries);
|
|
}
|
|
|
|
cancel() {
|
|
this._handle.cancel();
|
|
}
|
|
|
|
getServers() {
|
|
return ArrayPrototypeMap(this._handle.getServers(), (val) => {
|
|
if (!val[1] || val[1] === IANA_DNS_PORT)
|
|
return val[0];
|
|
|
|
const host = isIP(val[0]) === 6 ? `[${val[0]}]` : val[0];
|
|
return `${host}:${val[1]}`;
|
|
});
|
|
}
|
|
|
|
setServers(servers) {
|
|
validateArray(servers, 'servers');
|
|
|
|
// Cache the original servers because in the event of an error while
|
|
// setting the servers, c-ares won't have any servers available for
|
|
// resolution.
|
|
const orig = this._handle.getServers();
|
|
const newSet = [];
|
|
|
|
ArrayPrototypeForEach(servers, (serv, index) => {
|
|
validateString(serv, `servers[${index}]`);
|
|
let ipVersion = isIP(serv);
|
|
|
|
if (ipVersion !== 0)
|
|
return ArrayPrototypePush(newSet, [ipVersion, serv, IANA_DNS_PORT]);
|
|
|
|
const match = StringPrototypeMatch(serv, IPv6RE);
|
|
|
|
// Check for an IPv6 in brackets.
|
|
if (match) {
|
|
ipVersion = isIP(match[1]);
|
|
|
|
if (ipVersion !== 0) {
|
|
const port = NumberParseInt(
|
|
StringPrototypeReplace(serv, addrSplitRE, '$2')) || IANA_DNS_PORT;
|
|
return ArrayPrototypePush(newSet, [ipVersion, match[1], port]);
|
|
}
|
|
}
|
|
|
|
// addr::port
|
|
const addrSplitMatch = StringPrototypeMatch(serv, addrSplitRE);
|
|
|
|
if (addrSplitMatch) {
|
|
const hostIP = addrSplitMatch[1];
|
|
const port = addrSplitMatch[2] || IANA_DNS_PORT;
|
|
|
|
ipVersion = isIP(hostIP);
|
|
|
|
if (ipVersion !== 0) {
|
|
return ArrayPrototypePush(
|
|
newSet, [ipVersion, hostIP, NumberParseInt(port)]);
|
|
}
|
|
}
|
|
|
|
throw new ERR_INVALID_IP_ADDRESS(serv);
|
|
});
|
|
|
|
const errorNumber = this._handle.setServers(newSet);
|
|
|
|
if (errorNumber !== 0) {
|
|
// Reset the servers to the old servers, because ares probably unset them.
|
|
this._handle.setServers(ArrayPrototypeJoin(orig, ','));
|
|
const err = strerror(errorNumber);
|
|
throw new ERR_DNS_SET_SERVERS_FAILED(err, servers);
|
|
}
|
|
}
|
|
|
|
setLocalAddress(ipv4, ipv6) {
|
|
validateString(ipv4, 'ipv4');
|
|
|
|
if (ipv6 !== undefined) {
|
|
validateString(ipv6, 'ipv6');
|
|
}
|
|
|
|
this._handle.setLocalAddress(ipv4, ipv6);
|
|
}
|
|
}
|
|
|
|
let defaultResolver = new Resolver();
|
|
const resolverKeys = [
|
|
'getServers',
|
|
'resolve',
|
|
'resolve4',
|
|
'resolve6',
|
|
'resolveAny',
|
|
'resolveCaa',
|
|
'resolveCname',
|
|
'resolveMx',
|
|
'resolveNaptr',
|
|
'resolveNs',
|
|
'resolvePtr',
|
|
'resolveSoa',
|
|
'resolveSrv',
|
|
'resolveTxt',
|
|
'reverse',
|
|
];
|
|
|
|
function getDefaultResolver() {
|
|
return defaultResolver;
|
|
}
|
|
|
|
function setDefaultResolver(resolver) {
|
|
defaultResolver = resolver;
|
|
}
|
|
|
|
function bindDefaultResolver(target, source) {
|
|
ArrayPrototypeForEach(resolverKeys, (key) => {
|
|
target[key] = FunctionPrototypeBind(source[key], defaultResolver);
|
|
});
|
|
}
|
|
|
|
function validateHints(hints) {
|
|
if ((hints & ~(AI_ADDRCONFIG | AI_ALL | AI_V4MAPPED)) !== 0) {
|
|
throw new ERR_INVALID_ARG_VALUE('hints', hints);
|
|
}
|
|
}
|
|
|
|
let invalidHostnameWarningEmitted = false;
|
|
|
|
function emitInvalidHostnameWarning(hostname) {
|
|
if (invalidHostnameWarningEmitted) {
|
|
return;
|
|
}
|
|
invalidHostnameWarningEmitted = true;
|
|
process.emitWarning(
|
|
`The provided hostname "${hostname}" is not a valid ` +
|
|
'hostname, and is supported in the dns module solely for compatibility.',
|
|
'DeprecationWarning',
|
|
'DEP0118'
|
|
);
|
|
}
|
|
|
|
let typeCoercionWarningEmitted = false;
|
|
function emitTypeCoercionDeprecationWarning() {
|
|
if (!typeCoercionWarningEmitted) {
|
|
process.emitWarning(
|
|
'Type coercion of dns.lookup options is deprecated',
|
|
'DeprecationWarning',
|
|
'DEP0153'
|
|
);
|
|
typeCoercionWarningEmitted = true;
|
|
}
|
|
}
|
|
|
|
let dnsOrder = getOptionValue('--dns-result-order') || 'verbatim';
|
|
|
|
function getDefaultVerbatim() {
|
|
return dnsOrder !== 'ipv4first';
|
|
}
|
|
|
|
function setDefaultResultOrder(value) {
|
|
validateOneOf(value, 'dnsOrder', ['verbatim', 'ipv4first']);
|
|
dnsOrder = value;
|
|
}
|
|
|
|
module.exports = {
|
|
bindDefaultResolver,
|
|
getDefaultResolver,
|
|
setDefaultResolver,
|
|
validateHints,
|
|
validateTimeout,
|
|
validateTries,
|
|
Resolver,
|
|
emitInvalidHostnameWarning,
|
|
emitTypeCoercionDeprecationWarning,
|
|
getDefaultVerbatim,
|
|
setDefaultResultOrder,
|
|
};
|