1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -05:00
denoland-deno/ext/node/polyfills/dns.ts
Nathan Whitaker a77b2987bc
fix(ext/node): Match punycode module behavior to node (#22847)
Fixes #19214.

We were using the `idna` crate to implement our polyfill for
`punycode.toASCII` and `punycode.toUnicode`. The `idna` crate is
correct, and adheres to the IDNA2003/2008 spec, but it turns out
`node`'s implementations don't really follow any spec! Instead, node
splits the domain by `'.'` and punycode encodes/decodes each part. This
means that node's implementations will happily work on codepoints that
are disallowed by the IDNA specs, causing the error in #19214.

While fixing this, I went ahead and matched the node behavior on all of
the punycode functions and enabled node's punycode test in our
`node_compat` suite.
2024-03-11 15:49:43 -07:00

1021 lines
27 KiB
TypeScript

// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// TODO(petamoriken): enable prefer-primordials for node polyfills
// deno-lint-ignore-file prefer-primordials
import { nextTick } from "ext:deno_node/_next_tick.ts";
import { customPromisifyArgs } from "ext:deno_node/internal/util.mjs";
import {
validateBoolean,
validateFunction,
validateNumber,
validateOneOf,
validateString,
} from "ext:deno_node/internal/validators.mjs";
import { isIP } from "ext:deno_node/internal/net.ts";
import {
emitInvalidHostnameWarning,
getDefaultResolver,
getDefaultVerbatim,
isFamily,
isLookupCallback,
isLookupOptions,
isResolveCallback,
Resolver as CallbackResolver,
setDefaultResolver,
setDefaultResultOrder,
validateHints,
} from "ext:deno_node/internal/dns/utils.ts";
import type {
AnyAaaaRecord,
AnyARecord,
AnyCnameRecord,
AnyMxRecord,
AnyNaptrRecord,
AnyNsRecord,
AnyPtrRecord,
AnyRecord,
AnySoaRecord,
AnySrvRecord,
AnyTxtRecord,
CaaRecord,
LookupAddress,
LookupAllOptions,
LookupOneOptions,
LookupOptions,
MxRecord,
NaptrRecord,
Records,
RecordWithTtl,
ResolveCallback,
ResolveOptions,
ResolverOptions,
ResolveWithTtlOptions,
SoaRecord,
SrvRecord,
} from "ext:deno_node/internal/dns/utils.ts";
import promisesBase from "ext:deno_node/internal/dns/promises.ts";
import type { ErrnoException } from "ext:deno_node/internal/errors.ts";
import {
dnsException,
ERR_INVALID_ARG_TYPE,
ERR_INVALID_ARG_VALUE,
} from "ext:deno_node/internal/errors.ts";
import {
AI_ADDRCONFIG as ADDRCONFIG,
AI_ALL as ALL,
AI_V4MAPPED as V4MAPPED,
} from "ext:deno_node/internal_binding/ares.ts";
import {
ChannelWrapQuery,
getaddrinfo,
GetAddrInfoReqWrap,
QueryReqWrap,
} from "ext:deno_node/internal_binding/cares_wrap.ts";
import { domainToASCII } from "ext:deno_node/internal/idna.ts";
import { notImplemented } from "ext:deno_node/_utils.ts";
function onlookup(
this: GetAddrInfoReqWrap,
err: number | null,
addresses: string[],
) {
if (err) {
return this.callback(dnsException(err, "getaddrinfo", this.hostname));
}
this.callback(null, addresses[0], this.family || isIP(addresses[0]));
}
function onlookupall(
this: GetAddrInfoReqWrap,
err: number | null,
addresses: string[],
) {
if (err) {
return this.callback(dnsException(err, "getaddrinfo", this.hostname));
}
const family = this.family;
const parsedAddresses = [];
for (let i = 0; i < addresses.length; i++) {
const addr = addresses[i];
parsedAddresses[i] = {
address: addr,
family: family || isIP(addr),
};
}
this.callback(null, parsedAddresses);
}
type LookupCallback = (
err: ErrnoException | null,
addressOrAddresses?: string | LookupAddress[] | null,
family?: number,
) => void;
const validFamilies = [0, 4, 6];
// Easy DNS A/AAAA look up
// lookup(hostname, [options,] callback)
export function lookup(
hostname: string,
family: number,
callback: (
err: ErrnoException | null,
address: string,
family: number,
) => void,
): GetAddrInfoReqWrap | Record<string, never>;
export function lookup(
hostname: string,
options: LookupOneOptions,
callback: (
err: ErrnoException | null,
address: string,
family: number,
) => void,
): GetAddrInfoReqWrap | Record<string, never>;
export function lookup(
hostname: string,
options: LookupAllOptions,
callback: (err: ErrnoException | null, addresses: LookupAddress[]) => void,
): GetAddrInfoReqWrap | Record<string, never>;
export function lookup(
hostname: string,
options: LookupOptions,
callback: (
err: ErrnoException | null,
address: string | LookupAddress[],
family: number,
) => void,
): GetAddrInfoReqWrap | Record<string, never>;
export function lookup(
hostname: string,
callback: (
err: ErrnoException | null,
address: string,
family: number,
) => void,
): GetAddrInfoReqWrap | Record<string, never>;
export function lookup(
hostname: string,
options: unknown,
callback?: unknown,
): GetAddrInfoReqWrap | Record<string, never> {
let hints = 0;
let family = 0;
let all = false;
let verbatim = getDefaultVerbatim();
// Parse arguments
if (hostname) {
validateString(hostname, "hostname");
}
if (isLookupCallback(options)) {
callback = options;
family = 0;
} else if (isFamily(options)) {
validateFunction(callback, "callback");
validateOneOf(options, "family", validFamilies);
family = options;
} else if (!isLookupOptions(options)) {
validateFunction(arguments.length === 2 ? options : callback, "callback");
throw new ERR_INVALID_ARG_TYPE("options", ["integer", "object"], options);
} else {
validateFunction(callback, "callback");
if (options?.hints != null) {
validateNumber(options.hints, "options.hints");
hints = options.hints >>> 0;
validateHints(hints);
}
if (options?.family != null) {
validateOneOf(options.family, "options.family", validFamilies);
family = options.family;
}
if (options?.all != null) {
validateBoolean(options.all, "options.all");
all = options.all;
}
if (options?.verbatim != null) {
validateBoolean(options.verbatim, "options.verbatim");
verbatim = options.verbatim;
}
}
if (!hostname) {
emitInvalidHostnameWarning(hostname);
if (all) {
nextTick(callback as LookupCallback, null, []);
} else {
nextTick(callback as LookupCallback, null, null, family === 6 ? 6 : 4);
}
return {};
}
const matchedFamily = isIP(hostname);
if (matchedFamily) {
if (all) {
nextTick(callback as LookupCallback, null, [
{ address: hostname, family: matchedFamily },
]);
} else {
nextTick(callback as LookupCallback, null, hostname, matchedFamily);
}
return {};
}
const req = new GetAddrInfoReqWrap();
req.callback = callback as LookupCallback;
req.family = family;
req.hostname = hostname;
req.oncomplete = all ? onlookupall : onlookup;
const err = getaddrinfo(
req,
domainToASCII(hostname),
family,
hints,
verbatim,
);
if (err) {
nextTick(
callback as LookupCallback,
dnsException(err, "getaddrinfo", hostname),
);
return {};
}
return req;
}
Object.defineProperty(lookup, customPromisifyArgs, {
value: ["address", "family"],
enumerable: false,
});
function onresolve(
this: QueryReqWrap,
err: number,
records: Records,
ttls?: number[],
) {
if (err) {
this.callback(dnsException(err, this.bindingName, this.hostname));
return;
}
const parsedRecords = ttls && this.ttl
? (records as string[]).map((address: string, index: number) => ({
address,
ttl: ttls[index],
}))
: records;
this.callback(null, parsedRecords);
}
function resolver(bindingName: keyof ChannelWrapQuery) {
function query(
this: Resolver,
name: string,
options: unknown,
callback?: unknown,
): QueryReqWrap {
if (isResolveCallback(options)) {
callback = options;
options = {};
}
validateString(name, "name");
validateFunction(callback, "callback");
const req = new QueryReqWrap();
req.bindingName = bindingName;
req.callback = callback as ResolveCallback;
req.hostname = name;
req.oncomplete = onresolve;
if (options && (options as ResolveOptions).ttl) {
notImplemented("dns.resolve* with ttl option");
}
req.ttl = !!(options && (options as ResolveOptions).ttl);
const err = this._handle[bindingName](req, domainToASCII(name));
if (err) {
throw dnsException(err, bindingName, name);
}
return req;
}
Object.defineProperty(query, "name", { value: bindingName });
return query;
}
const resolveMap = Object.create(null);
export class Resolver extends CallbackResolver {
constructor(options?: ResolverOptions) {
super(options);
}
// deno-lint-ignore no-explicit-any
[resolveMethod: string]: any;
}
Resolver.prototype.resolveAny = resolveMap.ANY = resolver("queryAny");
Resolver.prototype.resolve4 = resolveMap.A = resolver("queryA");
Resolver.prototype.resolve6 = resolveMap.AAAA = resolver("queryAaaa");
Resolver.prototype.resolveCaa = resolveMap.CAA = resolver("queryCaa");
Resolver.prototype.resolveCname = resolveMap.CNAME = resolver("queryCname");
Resolver.prototype.resolveMx = resolveMap.MX = resolver("queryMx");
Resolver.prototype.resolveNs = resolveMap.NS = resolver("queryNs");
Resolver.prototype.resolveTxt = resolveMap.TXT = resolver("queryTxt");
Resolver.prototype.resolveSrv = resolveMap.SRV = resolver("querySrv");
Resolver.prototype.resolvePtr = resolveMap.PTR = resolver("queryPtr");
Resolver.prototype.resolveNaptr = resolveMap.NAPTR = resolver("queryNaptr");
Resolver.prototype.resolveSoa = resolveMap.SOA = resolver("querySoa");
Resolver.prototype.reverse = resolver("getHostByAddr");
Resolver.prototype.resolve = _resolve;
function _resolve(
this: Resolver,
hostname: string,
rrtype: unknown,
callback?: unknown,
): QueryReqWrap {
let resolver: Resolver;
if (typeof hostname !== "string") {
throw new ERR_INVALID_ARG_TYPE("name", "string", hostname);
}
if (typeof rrtype === "string") {
resolver = resolveMap[rrtype];
} else if (typeof rrtype === "function") {
resolver = resolveMap.A;
callback = rrtype;
} else {
throw new ERR_INVALID_ARG_TYPE("rrtype", "string", rrtype);
}
if (typeof resolver === "function") {
return Reflect.apply(resolver, this, [hostname, callback]);
}
throw new ERR_INVALID_ARG_VALUE("rrtype", rrtype);
}
/**
* Sets the IP address and port of servers to be used when performing DNS
* resolution. The `servers` argument is an array of [RFC 5952](https://tools.ietf.org/html/rfc5952#section-6) formatted
* addresses. If the port is the IANA default DNS port (53) it can be omitted.
*
* ```js
* dns.setServers([
* '4.4.4.4',
* '[2001:4860:4860::8888]',
* '4.4.4.4:1053',
* '[2001:4860:4860::8888]:1053',
* ]);
* ```
*
* An error will be thrown if an invalid address is provided.
*
* The `dns.setServers()` method must not be called while a DNS query is in
* progress.
*
* The `setServers` method affects only `resolve`,`dns.resolve*()` and `reverse` (and specifically _not_ `lookup`).
*
* This method works much like [resolve.conf](https://man7.org/linux/man-pages/man5/resolv.conf.5.html).
* That is, if attempting to resolve with the first server provided results in a
* `NOTFOUND` error, the `resolve()` method will _not_ attempt to resolve with
* subsequent servers provided. Fallback DNS servers will only be used if the
* earlier ones time out or result in some other error.
*
* @param servers array of `RFC 5952` formatted addresses
*/
export function setServers(servers: ReadonlyArray<string>) {
const resolver = new Resolver();
resolver.setServers(servers);
setDefaultResolver(resolver);
}
// The Node implementation uses `bindDefaultResolver` to set the follow methods
// on `module.exports` bound to the current `defaultResolver`. We don't have
// the same ability in ESM but can simulate this (at some cost) by explicitly
// exporting these methods which dynamically bind to the default resolver when
// called.
/**
* Returns an array of IP address strings, formatted according to [RFC 5952](https://tools.ietf.org/html/rfc5952#section-6),
* that are currently configured for DNS resolution. A string will include a port
* section if a custom port is used.
*
* ```js
* [
* '4.4.4.4',
* '2001:4860:4860::8888',
* '4.4.4.4:1053',
* '[2001:4860:4860::8888]:1053',
* ]
* ```
*/
export function getServers(): string[] {
return Resolver.prototype.getServers.bind(getDefaultResolver())();
}
/**
* 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 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.
*
* Here is an example of the `ret` object passed to the callback:
*
* ```js
* [ { 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: 'TXT', entries: [ 'v=spf1 include:_spf.example.com ~all' ] },
* { type: 'SOA',
* nsname: 'ns1.example.com',
* hostmaster: 'admin.example.com',
* serial: 156696742,
* refresh: 900,
* retry: 900,
* expire: 1800,
* minttl: 60 } ]
* ```
*
* DNS server operators may choose not to respond to `ANY` queries. It may be
* better to call individual methods like `resolve4`, `resolveMx`, and so on.
* For more details, see [RFC 8482](https://tools.ietf.org/html/rfc8482).
*/
export function resolveAny(
hostname: string,
callback: (err: ErrnoException | null, addresses: AnyRecord[]) => void,
): QueryReqWrap;
export function resolveAny(...args: unknown[]): QueryReqWrap {
return Resolver.prototype.resolveAny.bind(getDefaultResolver() as Resolver)(
...args,
);
}
/**
* Uses the DNS protocol to resolve a IPv4 addresses (`A` records) for the
* `hostname`. The `addresses` argument passed to the `callback` function will
* contain an array of IPv4 addresses (e.g. `['74.125.79.104', '74.125.79.105','74.125.79.106']`).
*
* @param hostname Host name to resolve.
*/
export function resolve4(
hostname: string,
callback: (err: ErrnoException | null, addresses: string[]) => void,
): void;
export function resolve4(
hostname: string,
options: ResolveWithTtlOptions,
callback: (err: ErrnoException | null, addresses: RecordWithTtl[]) => void,
): void;
export function resolve4(
hostname: string,
options: ResolveOptions,
callback: (
err: ErrnoException | null,
addresses: string[] | RecordWithTtl[],
) => void,
): void;
export function resolve4(
hostname: string,
options: unknown,
callback?: unknown,
) {
return Resolver.prototype.resolve4.bind(getDefaultResolver() as Resolver)(
hostname,
options,
callback,
);
}
/**
* Uses the DNS protocol to resolve a IPv6 addresses (`AAAA` records) for the
* `hostname`. The `addresses` argument passed to the `callback` function
* will contain an array of IPv6 addresses.
*
* @param hostname Host name to resolve.
*/
export function resolve6(
hostname: string,
callback: (err: ErrnoException | null, addresses: string[]) => void,
): void;
export function resolve6(
hostname: string,
options: ResolveWithTtlOptions,
callback: (err: ErrnoException | null, addresses: RecordWithTtl[]) => void,
): void;
export function resolve6(
hostname: string,
options: ResolveOptions,
callback: (
err: ErrnoException | null,
addresses: string[] | RecordWithTtl[],
) => void,
): void;
export function resolve6(
hostname: string,
options: unknown,
callback?: unknown,
) {
return Resolver.prototype.resolve6.bind(getDefaultResolver() as Resolver)(
hostname,
options,
callback,
);
}
/**
* Uses the DNS protocol to resolve `CAA` records for the `hostname`. The
* `addresses` argument passed to the `callback` function will contain an array
* of certification authority authorization records available for the
* `hostname` (e.g. `[{critical: 0, iodef: 'mailto:pki@example.com'}, {critical: 128, issue: 'pki.example.com'}]`).
*/
export function resolveCaa(
hostname: string,
callback: (err: ErrnoException | null, records: CaaRecord[]) => void,
): QueryReqWrap;
export function resolveCaa(...args: unknown[]): QueryReqWrap {
return Resolver.prototype.resolveCaa.bind(getDefaultResolver() as Resolver)(
...args,
);
}
/**
* Uses the DNS protocol to resolve `CNAME` records for the `hostname`. The
* `addresses` argument passed to the `callback` function will contain an array
* of canonical name records available for the `hostname`(e.g. `['bar.example.com']`).
*/
export function resolveCname(
hostname: string,
callback: (err: ErrnoException | null, addresses: string[]) => void,
): QueryReqWrap;
export function resolveCname(...args: unknown[]): QueryReqWrap {
return Resolver.prototype.resolveCname.bind(getDefaultResolver() as Resolver)(
...args,
);
}
/**
* Uses the DNS protocol to resolve mail exchange records (`MX` records) for the
* `hostname`. The `addresses` argument passed to the `callback` function will
* contain an array of objects containing both a `priority` and `exchange`
* property (e.g. `[{priority: 10, exchange: 'mx.example.com'}, ...]`).
*/
export function resolveMx(
hostname: string,
callback: (err: ErrnoException | null, addresses: MxRecord[]) => void,
): QueryReqWrap;
export function resolveMx(...args: unknown[]): QueryReqWrap {
return Resolver.prototype.resolveMx.bind(getDefaultResolver() as Resolver)(
...args,
);
}
/**
* Uses the DNS protocol to resolve name server records (`NS` records) for the
* `hostname`. The `addresses` argument passed to the `callback` function will
* contain an array of name server records available for `hostname`
* (e.g. `['ns1.example.com', 'ns2.example.com']`).
*/
export function resolveNs(
hostname: string,
callback: (err: ErrnoException | null, addresses: string[]) => void,
): QueryReqWrap;
export function resolveNs(...args: unknown[]): QueryReqWrap {
return Resolver.prototype.resolveNs.bind(getDefaultResolver() as Resolver)(
...args,
);
}
/**
* Uses the DNS protocol to resolve text queries (`TXT` records) for the
* `hostname`. The `records` argument passed to the `callback` function is a
* two-dimensional array of the text records available for `hostname`
* (e.g.`[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]`). Each sub-array contains TXT
* chunks of one record. Depending on the use case, these could be either
* joined together or treated separately.
*/
export function resolveTxt(
hostname: string,
callback: (err: ErrnoException | null, addresses: string[][]) => void,
): QueryReqWrap;
export function resolveTxt(...args: unknown[]): QueryReqWrap {
return Resolver.prototype.resolveTxt.bind(getDefaultResolver() as Resolver)(
...args,
);
}
/**
* Uses the DNS protocol to resolve service records (`SRV` records) for the
* `hostname`. The `addresses` argument passed to the `callback` function will
* be an array of objects with the following properties:
*
* - `priority`
* - `weight`
* - `port`
* - `name`
*
* ```js
* {
* priority: 10,
* weight: 5,
* port: 21223,
* name: 'service.example.com'
* }
* ```
*/
export function resolveSrv(
hostname: string,
callback: (err: ErrnoException | null, addresses: SrvRecord[]) => void,
): QueryReqWrap;
export function resolveSrv(...args: unknown[]): QueryReqWrap {
return Resolver.prototype.resolveSrv.bind(getDefaultResolver() as Resolver)(
...args,
);
}
/**
* Uses the DNS protocol to resolve pointer records (`PTR` records) for the
* `hostname`. The `addresses` argument passed to the `callback` function will
* be an array of strings containing the reply records.
*/
export function resolvePtr(
hostname: string,
callback: (err: ErrnoException | null, addresses: string[]) => void,
): QueryReqWrap;
export function resolvePtr(...args: unknown[]): QueryReqWrap {
return Resolver.prototype.resolvePtr.bind(getDefaultResolver() as Resolver)(
...args,
);
}
/**
* Uses the DNS protocol to resolve regular expression based records (`NAPTR`
* records) for the `hostname`. The `addresses` argument passed to the
* `callback` function will contain an array of objects with the following
* properties:
*
* - `flags`
* - `service`
* - `regexp`
* - `replacement`
* - `order`
* - `preference`
*
* ```js
* {
* flags: 's',
* service: 'SIP+D2U',
* regexp: '',
* replacement: '_sip._udp.example.com',
* order: 30,
* preference: 100
* }
* ```
*/
export function resolveNaptr(
hostname: string,
callback: (err: ErrnoException | null, addresses: NaptrRecord[]) => void,
): QueryReqWrap;
export function resolveNaptr(...args: unknown[]): QueryReqWrap {
return Resolver.prototype.resolveNaptr.bind(getDefaultResolver() as Resolver)(
...args,
);
}
/**
* Uses the DNS protocol to resolve a start of authority record (`SOA` record) for
* the `hostname`. The `address` argument passed to the `callback` function will
* be an object with the following properties:
*
* - `nsname`
* - `hostmaster`
* - `serial`
* - `refresh`
* - `retry`
* - `expire`
* - `minttl`
*
* ```js
* {
* nsname: 'ns.example.com',
* hostmaster: 'root.example.com',
* serial: 2013101809,
* refresh: 10000,
* retry: 2400,
* expire: 604800,
* minttl: 3600
* }
* ```
*/
export function resolveSoa(
hostname: string,
callback: (err: ErrnoException | null, address: SoaRecord) => void,
): QueryReqWrap;
export function resolveSoa(...args: unknown[]): QueryReqWrap {
return Resolver.prototype.resolveSoa.bind(getDefaultResolver() as Resolver)(
...args,
);
}
/**
* Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an
* array of host names.
*
* On error, `err` is an `Error` object, where `err.code` is
* one of the `DNS error codes`.
*/
export function reverse(
ip: string,
callback: (err: ErrnoException | null, hostnames: string[]) => void,
): QueryReqWrap;
export function reverse(...args: unknown[]): QueryReqWrap {
return Resolver.prototype.reverse.bind(getDefaultResolver() as Resolver)(
...args,
);
}
/**
* Uses the DNS protocol to resolve a host name (e.g. `'nodejs.org'`) into an array
* of the resource records. The `callback` function has arguments`(err, records)`.]
* When successful, `records` will be an array of resource
* records. The type and structure of individual results varies based on `rrtype`.
*
* On error, `err` is an `Error` object, where `err.code` is one of the DNS error codes.
*
* @param hostname Host name to resolve.
* @param [rrtype='A'] Resource record type.
*/
export function resolve(
hostname: string,
callback: (err: ErrnoException | null, addresses: string[]) => void,
): QueryReqWrap;
export function resolve(
hostname: string,
rrtype: "A",
callback: (err: ErrnoException | null, addresses: string[]) => void,
): QueryReqWrap;
export function resolve(
hostname: string,
rrtype: "AAAA",
callback: (err: ErrnoException | null, addresses: string[]) => void,
): QueryReqWrap;
export function resolve(
hostname: string,
rrtype: "ANY",
callback: (err: ErrnoException | null, addresses: AnyRecord[]) => void,
): QueryReqWrap;
export function resolve(
hostname: string,
rrtype: "CNAME",
callback: (err: ErrnoException | null, addresses: string[]) => void,
): QueryReqWrap;
export function resolve(
hostname: string,
rrtype: "MX",
callback: (err: ErrnoException | null, addresses: MxRecord[]) => void,
): QueryReqWrap;
export function resolve(
hostname: string,
rrtype: "NAPTR",
callback: (err: ErrnoException | null, addresses: NaptrRecord[]) => void,
): QueryReqWrap;
export function resolve(
hostname: string,
rrtype: "NS",
callback: (err: ErrnoException | null, addresses: string[]) => void,
): QueryReqWrap;
export function resolve(
hostname: string,
rrtype: "PTR",
callback: (err: ErrnoException | null, addresses: string[]) => void,
): QueryReqWrap;
export function resolve(
hostname: string,
rrtype: "SOA",
callback: (err: ErrnoException | null, addresses: SoaRecord) => void,
): QueryReqWrap;
export function resolve(
hostname: string,
rrtype: "SRV",
callback: (err: ErrnoException | null, addresses: SrvRecord[]) => void,
): QueryReqWrap;
export function resolve(
hostname: string,
rrtype: "TXT",
callback: (err: ErrnoException | null, addresses: string[][]) => void,
): QueryReqWrap;
export function resolve(
hostname: string,
rrtype: string,
callback: (
err: ErrnoException | null,
addresses:
| string[]
| MxRecord[]
| NaptrRecord[]
| SoaRecord
| SrvRecord[]
| string[][]
| AnyRecord[],
) => void,
): QueryReqWrap;
export function resolve(hostname: string, rrtype: unknown, callback?: unknown) {
return Resolver.prototype.resolve.bind(getDefaultResolver() as Resolver)(
hostname,
rrtype,
callback,
);
}
// ERROR CODES
export const NODATA = "ENODATA";
export const FORMERR = "EFORMERR";
export const SERVFAIL = "ESERVFAIL";
export const NOTFOUND = "ENOTFOUND";
export const NOTIMP = "ENOTIMP";
export const REFUSED = "EREFUSED";
export const BADQUERY = "EBADQUERY";
export const BADNAME = "EBADNAME";
export const BADFAMILY = "EBADFAMILY";
export const BADRESP = "EBADRESP";
export const CONNREFUSED = "ECONNREFUSED";
export const TIMEOUT = "ETIMEOUT";
export const EOF = "EOF";
export const FILE = "EFILE";
export const NOMEM = "ENOMEM";
export const DESTRUCTION = "EDESTRUCTION";
export const BADSTR = "EBADSTR";
export const BADFLAGS = "EBADFLAGS";
export const NONAME = "ENONAME";
export const BADHINTS = "EBADHINTS";
export const NOTINITIALIZED = "ENOTINITIALIZED";
export const LOADIPHLPAPI = "ELOADIPHLPAPI";
export const ADDRGETNETWORKPARAMS = "EADDRGETNETWORKPARAMS";
export const CANCELLED = "ECANCELLED";
const promises = {
...promisesBase,
setDefaultResultOrder,
setServers,
// ERROR CODES
NODATA,
FORMERR,
SERVFAIL,
NOTFOUND,
NOTIMP,
REFUSED,
BADQUERY,
BADNAME,
BADFAMILY,
BADRESP,
CONNREFUSED,
TIMEOUT,
EOF,
FILE,
NOMEM,
DESTRUCTION,
BADSTR,
BADFLAGS,
NONAME,
BADHINTS,
NOTINITIALIZED,
LOADIPHLPAPI,
ADDRGETNETWORKPARAMS,
CANCELLED,
};
export { ADDRCONFIG, ALL, promises, setDefaultResultOrder, V4MAPPED };
export type {
AnyAaaaRecord,
AnyARecord,
AnyCnameRecord,
AnyMxRecord,
AnyNaptrRecord,
AnyNsRecord,
AnyPtrRecord,
AnyRecord,
AnySoaRecord,
AnySrvRecord,
AnyTxtRecord,
CaaRecord,
LookupAddress,
LookupAllOptions,
LookupOneOptions,
LookupOptions,
MxRecord,
NaptrRecord,
Records,
RecordWithTtl,
ResolveCallback,
ResolveOptions,
ResolverOptions,
ResolveWithTtlOptions,
SoaRecord,
SrvRecord,
};
export default {
ADDRCONFIG,
ALL,
V4MAPPED,
lookup,
getServers,
resolveAny,
resolve4,
resolve6,
resolveCaa,
resolveCname,
resolveMx,
resolveNs,
resolveTxt,
resolveSrv,
resolvePtr,
resolveNaptr,
resolveSoa,
resolve,
Resolver,
reverse,
setServers,
setDefaultResultOrder,
promises,
NODATA,
FORMERR,
SERVFAIL,
NOTFOUND,
NOTIMP,
REFUSED,
BADQUERY,
BADNAME,
BADFAMILY,
BADRESP,
CONNREFUSED,
TIMEOUT,
EOF,
FILE,
NOMEM,
DESTRUCTION,
BADSTR,
BADFLAGS,
NONAME,
BADHINTS,
NOTINITIALIZED,
LOADIPHLPAPI,
ADDRGETNETWORKPARAMS,
CANCELLED,
};