diff options
Diffstat (limited to 'ext/node/polyfills/dns.ts')
-rw-r--r-- | ext/node/polyfills/dns.ts | 1012 |
1 files changed, 1012 insertions, 0 deletions
diff --git a/ext/node/polyfills/dns.ts b/ext/node/polyfills/dns.ts new file mode 100644 index 000000000..7b8752e13 --- /dev/null +++ b/ext/node/polyfills/dns.ts @@ -0,0 +1,1012 @@ +// Copyright 2018-2023 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. + +import { nextTick } from "internal:deno_node/polyfills/_next_tick.ts"; +import { customPromisifyArgs } from "internal:deno_node/polyfills/internal/util.mjs"; +import { + validateBoolean, + validateFunction, + validateNumber, + validateOneOf, + validateString, +} from "internal:deno_node/polyfills/internal/validators.mjs"; +import { isIP } from "internal:deno_node/polyfills/internal/net.ts"; +import { + emitInvalidHostnameWarning, + getDefaultResolver, + getDefaultVerbatim, + isFamily, + isLookupCallback, + isLookupOptions, + isResolveCallback, + Resolver as CallbackResolver, + setDefaultResolver, + setDefaultResultOrder, + validateHints, +} from "internal:deno_node/polyfills/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 "internal:deno_node/polyfills/internal/dns/utils.ts"; +import promisesBase from "internal:deno_node/polyfills/internal/dns/promises.ts"; +import type { ErrnoException } from "internal:deno_node/polyfills/internal/errors.ts"; +import { + dnsException, + ERR_INVALID_ARG_TYPE, + ERR_INVALID_ARG_VALUE, +} from "internal:deno_node/polyfills/internal/errors.ts"; +import { + AI_ADDRCONFIG as ADDRCONFIG, + AI_ALL as ALL, + AI_V4MAPPED as V4MAPPED, +} from "internal:deno_node/polyfills/internal_binding/ares.ts"; +import { + ChannelWrapQuery, + getaddrinfo, + GetAddrInfoReqWrap, + QueryReqWrap, +} from "internal:deno_node/polyfills/internal_binding/cares_wrap.ts"; +import { toASCII } from "internal:deno_node/polyfills/internal/idna.ts"; +import { notImplemented } from "internal:deno_node/polyfills/_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, toASCII(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, toASCII(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, +}; |