Socket
Socket
Sign inDemoInstall

dns-query

Package Overview
Dependencies
9
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.8.0 to 0.9.0

.cache/resolvers.json

343

common.js

@@ -1,84 +0,303 @@

'use strict'
"use strict";
function inherit (ctor, superCtor) {
Object.defineProperty(ctor, 'super_', {
value: superCtor,
writable: true,
configurable: true
})
Object.setPrototypeOf(ctor.prototype, superCtor.prototype)
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.URL = exports.UDPEndpoint = exports.UDP6Endpoint = exports.UDP4Endpoint = exports.TimeoutError = exports.ResponseError = exports.HTTPStatusError = exports.HTTPEndpoint = exports.BaseEndpoint = exports.AbortError = void 0;
exports.parseEndpoint = parseEndpoint;
exports.reduceError = reduceError;
exports.supportedProtocols = void 0;
exports.toEndpoint = toEndpoint;
let AbortError = typeof global !== 'undefined' ? global.AbortError : typeof window !== 'undefined' ? window.AbortError : null;
exports.AbortError = AbortError;
if (!AbortError) {
exports.AbortError = AbortError = class AbortError extends Error {
constructor(message = 'Request aborted.') {
super(message);
}
};
}
let AbortError = typeof global !== 'undefined' ? global.AbortError : typeof window !== 'undefined' ? window.AbortError : null
if (!AbortError) {
AbortError = function () {
Error.captureStackTrace(this, AbortError)
this.message = 'Request aborted.'
AbortError.prototype.name = 'AbortError';
AbortError.prototype.code = 'ABORT_ERR';
const URL = typeof globalThis !== 'undefined' && globalThis.URL || require('url').URL;
exports.URL = URL;
class HTTPStatusError extends Error {
constructor(uri, code, method) {
super('status=' + code + ' while requesting ' + uri + ' [' + method + ']');
this.uri = uri;
this.status = code;
this.method = method;
}
inherit(AbortError, Error)
AbortError.prototype.code = 'ABORT_ERR'
AbortError.prototype.name = 'AbortError'
toJSON() {
return {
code: this.code,
uri: this.uri,
status: this.status,
method: this.method
};
}
}
function HTTPStatusError (uri, code, method) {
Error.captureStackTrace(this, HTTPStatusError)
this.message = 'status=' + code + ' while requesting ' + uri + ' [' + method + ']'
this.uri = uri
this.status = code
this.method = method
exports.HTTPStatusError = HTTPStatusError;
HTTPStatusError.prototype.name = 'HTTPStatusError';
HTTPStatusError.prototype.code = 'HTTP_STATUS';
class ResponseError extends Error {
constructor(message, cause) {
super(message);
this.cause = cause;
}
toJSON() {
return {
message: this.message,
code: this.code,
cause: reduceError(this.cause)
};
}
}
inherit(HTTPStatusError, Error)
HTTPStatusError.prototype.code = 'HTTP_STATUS'
HTTPStatusError.prototype.name = 'StatusError'
function ResponseError (message, cause) {
Error.captureStackTrace(this, ResponseError)
this.message = message
this.cause = cause
exports.ResponseError = ResponseError;
ResponseError.prototype.name = 'ResponseError';
ResponseError.prototype.code = 'RESPONSE_ERR';
class TimeoutError extends Error {
constructor(timeout) {
super('Timeout (t=' + timeout + ').');
this.timeout = timeout;
}
toJSON() {
return {
code: this.code,
timeout: this.timeout
};
}
}
inherit(ResponseError, Error)
ResponseError.prototype.code = 'RESPONSE_ERR'
ResponseError.prototype.name = 'ResponseError'
function TimeoutError (timeout) {
Error.captureStackTrace(this, TimeoutError)
this.message = 'Timeout (t=' + timeout + ').'
this.timeout = timeout
exports.TimeoutError = TimeoutError;
TimeoutError.prototype.name = 'TimeoutError';
TimeoutError.prototype.code = 'ETIMEOUT';
const v4Regex = /^((\d{1,3}\.){3,3}\d{1,3})(:(\d{2,5}))?$/;
const v6Regex = /^((::)?(((\d{1,3}\.){3}(\d{1,3}){1})?([0-9a-f]){0,4}:{0,2}){1,8}(::)?)(:(\d{2,5}))?$/i;
function reduceError(err) {
if (typeof err === 'string') {
return {
message: err
};
}
try {
const json = JSON.stringify(err);
if (json !== '{}') {
return JSON.parse(json);
}
} catch (e) {}
const error = {
message: String(err.message || err)
};
if (err.code !== undefined) {
error.code = String(err.code);
}
return error;
}
inherit(TimeoutError, Error)
TimeoutError.prototype.code = 'ETIMEOUT'
TimeoutError.prototype.name = 'TimeoutError'
function Endpoint (opts) {
if (!opts.protocol) {
opts.protocol = 'https:'
} else if (!['http:', 'https:', 'udp4:', 'udp6:'].includes(opts.protocol)) {
throw new Error(`Invalid Endpoint: unsupported protocol "${opts.protocol}" for endpoint: ${JSON.stringify(opts)}`)
function parseEndpoint(endpoint) {
const parts = /^(([^:]+?:)\/\/)?([^/]*?)(\/.*?)?(\s\[(post|get)\])?(\s\[pk=(.*)\])?(\s\[cors\])?(\s\[name=(.*)\])?$/i.exec(endpoint);
const protocol = parts[2] || 'https:';
let family = 1;
let host;
let port;
const ipv6Parts = v6Regex.exec(parts[3]);
if (ipv6Parts) {
const ipv4Parts = v4Regex.exec(parts[3]);
if (ipv4Parts) {
host = ipv4Parts[1];
if (ipv4Parts[4]) {
port = parseInt(ipv4Parts[4]);
}
} else {
family = 2;
host = ipv6Parts[1];
if (ipv6Parts[9]) {
port = parseInt(ipv6Parts[10]);
}
}
} else {
const portParts = /^([^:]*)(:(.*))?$/.exec(parts[3]);
host = portParts[1];
if (portParts[3]) {
port = parseInt(portParts[3]);
}
}
if (typeof opts.host !== 'string') {
throw new Error(`Invalid Endpoint: host "${opts.host}" needs to be a string: ${JSON.stringify(opts)}`)
if (protocol === 'udp:' && family === 2 || protocol === 'udp6:') {
return toEndpoint({
name: parts[11],
protocol: 'udp6:',
ipv6: host,
pk: parts[8],
port
});
}
if (typeof opts.port !== 'number' && !isNaN(opts.port)) {
throw new Error(`Invalid Endpoint: port "${opts.port}" needs to be a number: ${JSON.stringify(opts)}`)
if (protocol === 'udp:' && family === 1 || protocol === 'udp4:') {
return toEndpoint({
name: parts[11],
protocol: 'udp4:',
ipv4: host,
pk: parts[8],
port
});
}
for (const key in opts) {
if (opts[key] !== undefined) {
this[key] = opts[key]
return toEndpoint({
name: parts[11],
protocol,
host,
port,
path: parts[4],
method: parts[6],
cors: !!parts[9]
});
}
const supportedProtocols = ['http:', 'https:', 'udp4:', 'udp6:'];
exports.supportedProtocols = supportedProtocols;
class BaseEndpoint {
constructor(opts, isHTTP) {
this.name = opts.name || null;
this.protocol = opts.protocol;
const port = typeof opts.port === 'string' ? opts.port = parseInt(opts.port, 10) : opts.port;
if (port === undefined || port === null) {
this.port = isHTTP ? this.protocol === 'https:' ? 443 : 80 : opts.pk ? 443 : 53;
} else if (typeof port !== 'number' && !isNaN(port)) {
throw new Error(`Invalid Endpoint: port "${opts.port}" needs to be a number: ${JSON.stringify(opts)}`);
} else {
this.port = port;
}
}
}
const rawEndpoints = require('./endpoints.json')
const endpoints = {}
for (const name in rawEndpoints) {
endpoints[name] = new Endpoint(rawEndpoints[name])
exports.BaseEndpoint = BaseEndpoint;
class UDPEndpoint extends BaseEndpoint {
constructor(opts) {
super(opts, false);
this.pk = opts.pk || null;
}
toString() {
const port = this.port !== (this.pk ? 443 : 53) ? `:${this.port}` : '';
const pk = this.pk ? ` [pk=${this.pk}]` : '';
const name = this.name ? ` [name=${this.name}]` : '';
return `udp://${this.ipv4 || this.ipv6}${port}${pk}${name}`;
}
}
module.exports = {
endpoints,
AbortError: AbortError,
HTTPStatusError: HTTPStatusError,
ResponseError: ResponseError,
TimeoutError: TimeoutError,
Endpoint: Endpoint
exports.UDPEndpoint = UDPEndpoint;
class UDP4Endpoint extends UDPEndpoint {
constructor(opts) {
super(opts);
if (!opts.ipv4 || typeof opts.ipv4 !== 'string') {
throw new Error(`Invalid Endpoint: .ipv4 "${opts.ipv4}" needs to be set: ${JSON.stringify(opts)}`);
}
this.ipv4 = opts.ipv4;
}
}
exports.UDP4Endpoint = UDP4Endpoint;
class UDP6Endpoint extends UDPEndpoint {
constructor(opts) {
super(opts);
if (!opts.ipv6 || typeof opts.ipv6 !== 'string') {
throw new Error(`Invalid Endpoint: .ipv6 "${opts.ipv6}" needs to be set: ${JSON.stringify(opts)}`);
}
}
}
exports.UDP6Endpoint = UDP6Endpoint;
class HTTPEndpoint extends BaseEndpoint {
constructor(opts) {
super(opts, true);
if (!opts.host || typeof opts.host !== 'string') {
throw new Error(`Invalid Endpoint: host "${opts.path}" needs to be set: ${JSON.stringify(opts)}`);
}
this.host = opts.host;
this.cors = !!opts.cors;
this.path = opts.path || '/dns-query';
this.method = /^post$/i.test(opts.method) ? 'POST' : 'GET';
this.ipv4 = opts.ipv4;
this.ipv6 = opts.ipv6;
const urlHost = v6Regex.test(this.host) && !v4Regex.test(this.host) ? `[${this.host}]` : this.host;
this.url = new URL(`${this.protocol}//${urlHost}:${this.port}${this.path}`);
}
toString() {
const port = this.port !== (this.protocol === 'https:' ? 443 : 80) ? `:${this.port}` : '';
const method = this.method !== 'GET' ? ' [post]' : '';
const cors = this.cors ? ' [cors]' : '';
const path = this.path === '/dns-query' ? '' : this.path;
const name = this.name ? ` [name=${this.name}]` : '';
return `${this.protocol}//${this.host}${port}${path}${method}${cors}${name}`;
}
}
exports.HTTPEndpoint = HTTPEndpoint;
function toEndpoint(opts) {
if (opts.protocol === null || opts.protocol === undefined) {
opts.protocol = 'https:';
}
const protocol = opts.protocol;
if (protocol === 'udp4:') {
return new UDP4Endpoint(opts);
}
if (protocol === 'udp6:') {
return new UDP6Endpoint(opts);
}
if (protocol === 'https:' || protocol === 'http:') {
return new HTTPEndpoint(opts);
}
throw new Error(`Invalid Endpoint: unsupported protocol "${opts.protocol}" for endpoint: ${JSON.stringify(opts)}, supported protocols: ${supportedProtocols.join(', ')}`);
}

481

index.js

@@ -1,178 +0,359 @@

'use strict'
const packet = require('dns-packet')
const lib = require('./lib.node.js')
const common = require('./common.js')
const AbortError = common.AbortError
const ResponseError = common.ResponseError
const Endpoint = common.Endpoint
const endpoints = common.endpoints
const v4Regex = /^((\d{1,3}\.){3,3}\d{1,3})(:(\d{2,5}))?$/
const v6Regex = /^((::)?(((\d{1,3}\.){3}(\d{1,3}){1})?([0-9a-f]){0,4}:{0,2}){1,8}(::)?)(:(\d{2,5}))?$/i
"use strict";
function queryOne (endpoint, query, timeout, abortSignal) {
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "AbortError", {
enumerable: true,
get: function () {
return _common.AbortError;
}
});
Object.defineProperty(exports, "BaseEndpoint", {
enumerable: true,
get: function () {
return _common.BaseEndpoint;
}
});
Object.defineProperty(exports, "HTTPEndpoint", {
enumerable: true,
get: function () {
return _common.HTTPEndpoint;
}
});
Object.defineProperty(exports, "HTTPStatusError", {
enumerable: true,
get: function () {
return _common.HTTPStatusError;
}
});
Object.defineProperty(exports, "ResponseError", {
enumerable: true,
get: function () {
return _common.ResponseError;
}
});
exports.Session = void 0;
Object.defineProperty(exports, "TimeoutError", {
enumerable: true,
get: function () {
return _common.TimeoutError;
}
});
Object.defineProperty(exports, "UDP4Endpoint", {
enumerable: true,
get: function () {
return _common.UDP4Endpoint;
}
});
Object.defineProperty(exports, "UDP6Endpoint", {
enumerable: true,
get: function () {
return _common.UDP6Endpoint;
}
});
exports.backup = void 0;
exports.endpoints = endpoints;
exports.loadEndpoints = loadEndpoints;
Object.defineProperty(exports, "parseEndpoint", {
enumerable: true,
get: function () {
return _common.parseEndpoint;
}
});
exports.query = query;
Object.defineProperty(exports, "toEndpoint", {
enumerable: true,
get: function () {
return _common.toEndpoint;
}
});
exports.wellknown = wellknown;
var packet = _interopRequireWildcard(require("@leichtgewicht/dns-packet"), true);
var lib = _interopRequireWildcard(require("./lib.js"), true);
var _resolvers = require("./resolvers.js");
var _common = require("./common.js");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function resolversToWellknown(res) {
const resolvers = res.data.map(resolver => {
resolver.endpoint = (0, _common.toEndpoint)(Object.assign({
name: resolver.name
}, resolver.endpoint));
return resolver;
});
const endpoints = resolvers.map(resolver => resolver.endpoint);
return lib.processWellknown({
data: {
resolvers,
resolverByName: resolvers.reduce((byName, resolver) => {
byName[resolver.name] = resolver;
return byName;
}, {}),
endpoints,
endpointByName: endpoints.reduce((byName, endpoint) => {
byName[endpoint.name] = endpoint;
return byName;
}, {})
},
time: res.time === null || res.time === undefined ? Date.now() : res.time
});
}
const backup = resolversToWellknown(_resolvers.resolvers);
exports.backup = backup;
function toMultiQuery(singleQuery) {
const query = Object.assign({
type: 'query'
}, singleQuery);
delete query.question;
query.questions = [];
if (singleQuery.question) {
query.questions.push(singleQuery.question);
}
return query;
}
function queryOne(endpoint, query, timeout, abortSignal) {
if (abortSignal && abortSignal.aborted) {
return Promise.reject(new AbortError())
return Promise.reject(new _common.AbortError());
}
if (endpoint.protocol === 'udp4:' || endpoint.protocol === 'udp6:') {
return lib.queryDns(endpoint, query, timeout, abortSignal)
return lib.queryDns(endpoint, toMultiQuery(query), timeout, abortSignal).then(result => {
result.question = result.questions[0];
delete result.questions;
return result;
});
}
return queryDoh(endpoint, query, timeout, abortSignal)
return queryDoh(endpoint, query, timeout, abortSignal);
}
function queryDoh (endpoint, query, timeout, abortSignal) {
const protocol = endpoint.protocol || 'https:'
return new Promise(function (resolve, reject) {
lib.request(
protocol,
endpoint.host,
endpoint.port ? parseInt(endpoint.port, 10) : (protocol === 'https:' ? 443 : 80),
endpoint.path || '/dns-query',
/^post$/i.test(endpoint.method) ? 'POST' : 'GET',
packet.encode(Object.assign({
flags: packet.RECURSION_DESIRED,
type: 'query'
}, query)),
timeout,
abortSignal,
function (error, data, response) {
let decoded
if (error === null) {
if (data.length === 0) {
error = new ResponseError('Empty.')
} else {
try {
decoded = packet.decode(data)
} catch (err) {
error = new ResponseError('Invalid packet (cause=' + err.message + ')', err)
}
}
function queryDoh(endpoint, query, timeout, abortSignal) {
return lib.request(endpoint.url, endpoint.method, packet.query.encode(Object.assign({
flags: packet.RECURSION_DESIRED
}, query)), timeout, abortSignal).then(function (res) {
const data = res.data;
const response = res.response;
let error = res.error;
if (error === undefined) {
if (data.length === 0) {
error = new _common.ResponseError('Empty.');
} else {
try {
const decoded = packet.response.decode(data);
decoded.endpoint = endpoint;
decoded.response = response;
return decoded;
} catch (err) {
error = new _common.ResponseError('Invalid packet (cause=' + err.message + ')', err);
}
if (error !== null) {
reject(Object.assign(error, { response, endpoint }))
} else {
decoded.endpoint = endpoint
decoded.response = response
resolve(decoded)
}
}
)
})
}
throw Object.assign(error, {
response,
endpoint
});
}, error => {
throw Object.assign(error, {
endpoint
});
});
}
function query (q, opts) {
opts = Object.assign({
retries: 5,
timeout: 30000
}, opts)
let endpoints
try {
if (opts.endpoints === 'doh') {
endpoints = lib.endpoints({ doh: true, dns: false })
} else if (opts.endpoints === 'dns') {
endpoints = lib.endpoints({ doh: false, dns: true })
} else {
endpoints = parseEndpoints(opts.endpoints) || lib.endpoints({ doh: true, dns: true })
const UPDATE_URL = new _common.URL('https://martinheidegger.github.io/dns-query/resolvers.json');
class Session {
constructor(opts) {
this.opts = Object.assign({
retries: 5,
timeout: 30000,
// 30 seconds
update: true,
updateURL: UPDATE_URL,
persist: false,
localStoragePrefix: 'dnsquery_',
maxAge: 300000 // 5 minutes
}, opts);
this._wellknownP = null;
}
_wellknown(force, outdated) {
if (!force && this._wellknownP !== null) {
return this._wellknownP.then(res => {
if (res.time < Date.now() - this.opts.maxAge) {
return this._wellknown(true, res);
}
return res;
});
}
if (!endpoints || endpoints.length === 0) {
throw new Error('No endpoints defined.')
}
} catch (error) {
return Promise.reject(error)
this._wellknownP = !this.opts.update ? Promise.resolve(backup) : lib.loadJSON(this.opts.updateURL, this.opts.persist ? {
name: 'resolvers.json',
localStoragePrefix: this.opts.localStoragePrefix,
maxTime: Date.now() - this.opts.maxAge
} : null, this.opts.timeout).then(res => resolversToWellknown({
data: res.data.resolvers,
time: res.time
})).catch(() => outdated || backup);
return this._wellknownP;
}
return queryN(endpoints, q, opts)
wellknown() {
return this._wellknown(false).then(data => data.data);
}
endpoints() {
return this.wellknown().then(data => data.endpoints);
}
query(q, opts) {
opts = Object.assign({}, this.opts, opts);
if (!q.question) return Promise.reject(new Error('To request data you need to specify a .question!'));
return loadEndpoints(this, opts.endpoints).then(endpoints => queryN(endpoints, q, opts));
}
}
function queryN (endpoints, q, opts) {
const endpoint = endpoints.length === 1
? endpoints[0]
: endpoints[Math.floor(Math.random() * endpoints.length) % endpoints.length]
return queryOne(endpoint, q, opts.timeout, opts.signal)
.then(
data => {
// Add the endpoint to give a chance to identify which endpoint returned the result
data.endpoint = endpoint
return data
},
err => {
if (err.name === 'AbortError' || opts.retries === 0) {
throw err
}
if (opts.retries > 0) {
opts.retries -= 1
}
return query(q, opts)
}
)
exports.Session = Session;
const defautSession = new Session();
function query(q, opts) {
return defautSession.query(q, opts);
}
function parseEndpoints (input) {
if (!input) {
return
function endpoints() {
return defautSession.endpoints();
}
function wellknown() {
return defautSession.wellknown();
}
function queryN(endpoints, q, opts) {
if (endpoints.length === 0) {
throw new Error('No endpoints defined.');
}
if (typeof input[Symbol.iterator] !== 'function' || typeof input === 'string') {
throw new Error('Endpoints needs to be iterable.')
}
const result = []
for (let endpoint of input) {
if (typeof endpoint === 'object') {
if (!(endpoint instanceof Endpoint)) {
endpoint = new Endpoint(endpoint)
}
result.push(endpoint)
} else if (typeof endpoint === 'string') {
result.push(endpoints[endpoint] || parseEndpoint(endpoint))
const endpoint = endpoints.length === 1 ? endpoints[0] : endpoints[Math.floor(Math.random() * endpoints.length) % endpoints.length];
return queryOne(endpoint, q, opts.timeout, opts.signal).then(data => {
// Add the endpoint to give a chance to identify which endpoint returned the result
data.endpoint = endpoint;
return data;
}, err => {
if (err.name === 'AbortError' || opts.retries === 0) {
throw err;
}
}
return result
if (opts.retries > 0) {
opts.retries -= 1;
}
return query(q, opts);
});
}
function parseEndpoint (endpoint) {
const parts = /^(([^:]+?:)\/\/)?([^/]*?)(\/.*?)?(\s\[(post|get)\])?$/i.exec(endpoint)
let protocol = parts[2] || 'https:'
let family = 1
let host
let port
const ipv6Parts = v6Regex.exec(parts[3])
if (ipv6Parts) {
const ipv4Parts = v4Regex.exec(parts[3])
if (ipv4Parts) {
host = ipv4Parts[1]
if (ipv4Parts[4]) {
port = parseInt(ipv4Parts[4])
function filterEndpoints(filter) {
return function (endpoints) {
const result = [];
for (const name in endpoints) {
const endpoint = endpoints[name];
if (filter(endpoint)) {
result.push(endpoint);
}
} else {
family = 2
host = ipv6Parts[1]
if (ipv6Parts[9]) {
port = parseInt(ipv6Parts[10])
}
}
} else {
const portParts = /^([^:]*)(:(.*))?$/.exec(parts[3])
host = portParts[1]
if (portParts[3]) {
port = parseInt(portParts[3])
}
return result;
};
}
const filterDoh = filterEndpoints(function filterDoh(endpoint) {
return endpoint.protocol === 'https:' || endpoint.protocol === 'http:';
});
const filterDns = filterEndpoints(function filterDns(endpoint) {
return endpoint.protocol === 'udp4:' || endpoint.protocol === 'udp6:';
});
function isPromise(input) {
if (input === null) {
return false;
}
if (protocol === 'udp:') {
protocol = family === 2 ? 'udp6:' : 'udp4:'
if (typeof input !== 'object') {
return false;
}
return new Endpoint({
protocol: protocol,
host,
port,
path: parts[4],
method: parts[6]
})
return typeof input.then === 'function';
}
module.exports = {
query: query,
endpoints: endpoints,
parseEndpoints: parseEndpoints,
AbortError: AbortError,
ResponseError: ResponseError,
TimeoutError: common.TimeoutError,
HTTPStatusError: common.HTTPStatusError,
Endpoint: Endpoint
function isString(entry) {
return typeof entry === 'string';
}
function loadEndpoints(session, input) {
const p = isPromise(input) ? input : Promise.resolve(input);
return p.then(function (endpoints) {
if (endpoints === 'doh') {
return session.endpoints().then(filterDoh);
}
if (endpoints === 'dns') {
return session.endpoints().then(filterDns);
}
const type = typeof endpoints;
if (type === 'function') {
return session.endpoints().then(filterEndpoints(endpoints));
}
if (endpoints === null || endpoints === undefined) {
return session.endpoints();
}
if (type === 'string' || typeof endpoints[Symbol.iterator] !== 'function') {
throw new Error(`Endpoints (${endpoints}) needs to be iterable.`);
}
endpoints = Array.from(endpoints).filter(Boolean);
if (endpoints.findIndex(isString) === -1) {
return endpoints.map(endpoint => {
if (endpoint instanceof _common.BaseEndpoint) {
return endpoint;
}
return (0, _common.toEndpoint)(endpoint);
});
}
return session.wellknown().then(wellknown => endpoints.map(endpoint => {
if (endpoint instanceof _common.BaseEndpoint) {
return endpoint;
}
if (typeof endpoint === 'string') {
return wellknown.endpointByName[endpoint] || (0, _common.parseEndpoint)(endpoint);
}
return (0, _common.toEndpoint)(endpoint);
}));
});
}

@@ -1,104 +0,179 @@

'use strict'
/* global XMLHttpRequest */
const Buffer = require('buffer').Buffer
const common = require('./common.js')
const AbortError = common.AbortError
const HTTPStatusError = common.HTTPStatusError
const TimeoutError = common.TimeoutError
const contentType = 'application/dns-message'
const endpoints = Object.values(common.endpoints).filter(function (endpoint) {
return !endpoint.filter && !endpoint.logging && endpoint.cors
})
"use strict";
// https://tools.ietf.org/html/rfc8484
function toRFC8484 (buffer) {
return buffer.toString('base64')
.replace(/=/g, '')
.replace(/\+/g, '-')
.replace(/\//g, '_')
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.loadJSON = loadJSON;
exports.processWellknown = processWellknown;
exports.queryDns = queryDns;
exports.request = request;
var utf8Codec = _interopRequireWildcard(require("utf8-codec"), true);
var _base64Codec = require("@leichtgewicht/base64-codec");
var _common = require("./common.js");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/* global XMLHttpRequest, localStorage */
const contentType = 'application/dns-message';
function noop() {}
function queryDns() {
throw new Error('Only "doh" endpoints are supported in the browser');
}
function noop () {}
async function loadJSON(url, cache, timeout, abortSignal) {
const cacheKey = cache ? cache.localStoragePrefix + cache.name : null;
function request (protocol, host, port, path, method, packet, timeout, abortSignal, cb) {
const uri = protocol + '//' + host + ':' + port + path + (method === 'GET' ? '?dns=' + toRFC8484(packet) : '')
const xhr = new XMLHttpRequest()
xhr.open(method, uri, true)
xhr.setRequestHeader('Accept', contentType)
if (method === 'POST') {
xhr.setRequestHeader('Content-Type', contentType)
}
xhr.responseType = 'arraybuffer'
xhr.timeout = timeout
xhr.ontimeout = ontimeout
xhr.onreadystatechange = onreadystatechange
xhr.onerror = onerror
xhr.onload = onload
if (method === 'GET') {
xhr.send()
} else {
xhr.send(packet)
}
if (cacheKey) {
try {
const cached = JSON.parse(localStorage.getItem(cacheKey));
if (abortSignal) {
abortSignal.addEventListener('abort', onabort)
if (cached && cached.time > cache.maxTime) {
return cached;
}
} catch (err) {}
}
function ontimeout () {
finish(new TimeoutError(timeout))
const {
data
} = await requestRaw(url, 'GET', null, timeout, abortSignal);
const result = {
time: Date.now(),
data: JSON.parse(utf8Codec.decode(data))
};
if (cacheKey) {
try {
xhr.abort()
} catch (e) {}
localStorage.setItem(cacheKey, JSON.stringify(result));
} catch (err) {
result.time = null;
}
}
function onload () {
if (xhr.status !== 200) {
finish(new HTTPStatusError(uri, xhr.status, method))
return result;
}
function requestRaw(url, method, data, timeout, abortSignal) {
return new Promise((resolve, reject) => {
const target = new _common.URL(url);
if (method === 'GET' && data) {
target.search = '?dns=' + _base64Codec.base64URL.decode(data);
}
const uri = target.toString();
const xhr = new XMLHttpRequest();
xhr.open(method, uri, true);
xhr.setRequestHeader('Accept', contentType);
if (method === 'POST') {
xhr.setRequestHeader('Content-Type', contentType);
}
xhr.responseType = 'arraybuffer';
xhr.timeout = timeout;
xhr.ontimeout = ontimeout;
xhr.onreadystatechange = onreadystatechange;
xhr.onerror = onerror;
xhr.onload = onload;
if (method === 'POST') {
xhr.send(data);
} else {
finish(null, Buffer.from(xhr.response))
xhr.send();
}
}
function onreadystatechange () {
if (xhr.readyState > 1 && xhr.status !== 200 && xhr.status !== 0) {
finish(new HTTPStatusError(uri, xhr.status, method))
if (abortSignal) {
abortSignal.addEventListener('abort', onabort);
}
function ontimeout() {
finish(new _common.TimeoutError(timeout));
try {
xhr.abort()
xhr.abort();
} catch (e) {}
}
}
let finish = function (error, data) {
finish = noop
if (abortSignal) {
abortSignal.removeEventListener('abort', onabort)
function onload() {
if (xhr.status !== 200) {
finish(new _common.HTTPStatusError(uri, xhr.status, method));
} else {
let buf;
if (typeof xhr.response === 'string') {
buf = utf8Codec.encode(xhr.response);
} else if (xhr.response instanceof Uint8Array) {
buf = xhr.response;
} else if (Array.isArray(xhr.response) || xhr.response instanceof ArrayBuffer) {
buf = new Uint8Array(xhr.response);
} else {
throw new Error('Unprocessable response ' + xhr.response);
}
finish(null, buf);
}
}
cb(error, data, xhr)
}
function onerror () {
finish(xhr.status === 200 ? new Error('Inexplicable XHR Error') : new HTTPStatusError(uri, xhr.status, method))
}
function onreadystatechange() {
if (xhr.readyState > 1 && xhr.status !== 200 && xhr.status !== 0) {
finish(new _common.HTTPStatusError(uri, xhr.status, method));
function onabort () {
finish(new AbortError())
try {
xhr.abort()
} catch (e) {}
}
}
try {
xhr.abort();
} catch (e) {}
}
}
module.exports = {
request: request,
queryDns: function () {
throw new Error('Only "doh" endpoints are supported in the browser')
},
endpoints: opts => {
if (opts.doh) {
return endpoints
let finish = function (error, data) {
finish = noop;
if (abortSignal) {
abortSignal.removeEventListener('abort', onabort);
}
if (error) {
resolve({
error,
response: xhr
});
} else {
resolve({
data,
response: xhr
});
}
};
function onerror() {
finish(xhr.status === 200 ? new Error('Inexplicable XHR Error') : new _common.HTTPStatusError(uri, xhr.status, method));
}
if (opts.dns) {
throw new Error('Only "doh" is supported in the browser')
function onabort() {
finish(new _common.AbortError());
try {
xhr.abort();
} catch (e) {}
}
}
});
}
function request(url, method, packet, timeout, abortSignal) {
return requestRaw(url, method, packet, timeout, abortSignal);
}
function processWellknown(wellknown) {
return {
time: wellknown.time,
data: Object.assign({}, wellknown.data, {
endpoints: wellknown.data.endpoints.filter(ep => ep.cors)
})
};
}
{
"name": "dns-query",
"version": "0.8.0",
"version": "0.9.0",
"description": "Node & Browser tested, Non-JSON DNS over HTTPS fetching with minimal dependencies.",
"main": "index.js",
"types": "types",
"module": "index.mjs",
"types": "types/index.d.ts",
"bin": {

@@ -11,16 +12,43 @@ "dns-query": "./bin/dns-query"

"scripts": {
"lint": "npm run endpoints && standard *.js bin/* && dtslint --localTs node_modules/typescript/lib types",
"endpoints": "node endpoints-json.js",
"prepack": "npm run endpoints",
"lint": "standard '**/*.mjs' bin/* test/env && dtslint types --localTs node_modules/typescript/lib",
"update-resolvers": "node bin/update-resolvers && standard --fix resolvers.mjs && esm2umd",
"prepare": "esm2umd",
"test": "node test/env npm run test-impl",
"test-impl": "fresh-tape test/all.js",
"test-cov": "node test/env c8 -r lcov -r html npm run test-impl",
"test-cjs": "node test/env fresh-tape test/all.js",
"test-impl": "fresh-tape test/all.mjs",
"test-cov": "node test/env c8 -r lcov -r html -r text npm run test-impl",
"browser-test": "env TEST_ENV=browser node test/env npm run browser-test-impl -s",
"browser-test-impl": "browserify -t envify --debug test/all.js | tape-run",
"browser-test-cov": "env TEST_ENV=browser node test/env npm run browser-test-cov-impl -s",
"browser-test-cov-impl": "browserify -t envify -t coverify --debug test/all.js | tape-run | coverify"
"browser-test-impl": "browserify -t envify --debug test/all.js | tape-run"
},
"browser": {
"./lib.node.js": "./lib.browser.js"
"./lib.js": "./lib.browser.js",
"./lib.mjs": "./lib.browser.mjs"
},
"exports": {
".": {
"import": "./index.mjs",
"types": "./types/index.d.ts",
"require": "./index.js"
},
"./common.js": {
"import": "./common.mjs",
"types": "./common.d.ts",
"require": "./common.js"
},
"./resolvers.js": {
"import": "./resolvers.mjs",
"types": "./resolvers.d.ts",
"require": "./resolvers.js"
},
"./lib.js": {
"import": "./lib.mjs",
"types": "./lib.d.ts",
"require": "./lib.js",
"browser": {
"import": "./lib.browser.mjs",
"types": "./lib.d.ts",
"require": "./lib.browser.js"
}
}
},
"keywords": [

@@ -43,21 +71,23 @@ "dns",

"dependencies": {
"@leichtgewicht/ip-codec": "^2.0.2",
"@types/dns-packet": "^5.2.0",
"dns-packet": "^5.3.0",
"dns-socket": "^4.2.2"
"@leichtgewicht/base64-codec": "^1.0.0",
"@leichtgewicht/dns-packet": "^6.0.1",
"@leichtgewicht/dns-socket": "^5.0.0",
"@leichtgewicht/ip-codec": "^2.0.4",
"utf8-codec": "^1.0.0"
},
"devDependencies": {
"@definitelytyped/dtslint": "0.0.112",
"@leichtgewicht/dnsstamp": "^1.1.4",
"@leichtgewicht/esm2umd": "^0.4.0",
"abort-controller": "^3.0.0",
"browserify": "^17.0.0",
"c8": "^7.7.3",
"coverify": "^1.5.1",
"dtslint": "^4.1.1",
"c8": "^7.11.3",
"envify": "^4.1.0",
"fresh-tape": "^5.2.4",
"markdown-it": "^12.1.0",
"ngrok": "^4.0.1",
"p-map": "^4.0.0",
"standard": "^16.0.3",
"tape-run": "^9.0.0",
"typescript": "^4.3.5",
"fresh-tape": "^5.5.3",
"markdown-it": "^13.0.1",
"ngrok": "^4.3.1",
"p-filter": "^3.0.0",
"standard": "^17.0.0",
"tape-run": "^10.0.0",
"typescript": "^4.6.4",
"xhr2": "^0.2.1"

@@ -64,0 +94,0 @@ },

@@ -15,5 +15,26 @@ # dns-query

By default `dns-query` uses well-known public dns-over-https servers to execute
queries! These servers come with caveats, please look at [`./endpoints.md`](./endpoints.md)
for more information.
queries [automatically compiled][] by the data from the [DNSCrypt][] project.
[automatically compiled]: https://github.com/martinheidegger/dns-query/actions/workflows/update.yml
[DNSCrypt]: https://dnscrypt.info/
The npm package comes with the list that was/is current on the time of the publication.
It will will try to automatically download the list from [the dns-query website][] unless
you set the `.update` property on a `Session` object.
[the dns-query website]: https://martinheidegger.github.io/dns-query/resolvers.json
These servers come with caveats that you should be aware of:
- A server may filter, log or limit the requests it receives!
- Filtering can be useful in case you want to avoid malware/ads/adult-content.
- Logging may be required in some countries and limiting may be part of a business model.
- Furthermore the different endpoints may or may not be distributed around the globe,
making requests slower/faster depending on the client's location.
- Not all endpoints supply CORS headers which means that the list is severly reduced if you use this
library in the browser.
If you are presenting this library to an end-user, you may want to allow them to decide what endpoint
they want to use as it has privacy and usage implications!
## DNS support

@@ -37,11 +58,10 @@

endpoints = [{ host: 'cloudflare-dns.com' }] // Specify using properties
endpoints = (endpoint) => endpoint.protocol === 'https:' // Use a filter against the well-known endpoints
endpoints = Promise.resolve('doh') // The endpoints can also be a promise
try {
const { answers } = await query({
questions: [
{type: 'A', name: 'google.com'},
{type: 'A', name: 'twitter.com'}
]
question: {type: 'A', name: 'google.com'}
}, {
/* Options (optional) */
endpoints,
endpoints: endpoints,
retry: 3, // (optional) retries if a given endpoint fails; -1 = infinite retries; 0 = no retry

@@ -69,26 +89,45 @@ timeout: 4000, // (optional, default=30000) timeout for single requests

Execute a dns query over https.
dns-query - Execute a dns query over https.
Examples:
USAGE:
dns-query <Options> <Input>
EXAMPLES:
# Fetch from the google dns-over-https endpoint the A-name of google.com
$ dns-query --json -e google \
'{ "questions": [{ "type": "A", "name": "google.com" }] }'
'{ "question": { "type": "A", "name": "google.com" } }'
$ echo '{ "questions": [{ "type": "A", "name": "google.com" }] }' \
# Fetch TXT entries for ipfs.io through regular dns
$ dns-query --json --dns \
'{ "question": { "type": "TXT", "name": "ipfs.io" } }'
# Pass the query through stdin
$ echo '{ "question": { "type": "A", "name": "google.com" } }' \
| dns-query --stdin --endpoint cloudflare
--help, -h ....... Show this help
--version, -v .... Show the version
--json ........... --type=json
--base64 ......... --type=base64
--binary ......... --type=binary
--type ........... Input type. Options: json, base64, binary; Default: json
--out ............ Output type. Defaults to the input --type.
--stdin .......... Get <input> from stdin instead of cli arguments
--endpoint, -e ... Use a specific endpoint. Can be either the name of a known
endpoint, a json object or an url. By default uses one of the known endpoints.
If multiple are provided, one at random will be used.
--endpoints ...... Lists all known endpoints as json.
--retry .......... Number of retries to do in case a request fails, default: 3
--timeout ........ Timeout for the request in milliseconds, default: 30000
OPTIONS:
--help, -h ....... Show this help
--version, -v .... Show the version
--json ........... --type=json
--base64 ......... --type=base64
--binary ......... --type=binary
--type ........... Input type. Options: json, base64, binary; Default: json
--out ............ Output type. Defaults to the input --type.
--stdin .......... Get <input> from stdin instead of cli arguments
--dns ............ Use dns endpoints
--doh ............ Use doh endpoints
--endpoint, -e ... Use a specific endpoint. Can be either the name of a known
endpoint, a json object or an url. By default uses one of the known endpoints.
If multiple are provided, one at random will be used.
--endpoints ...... Lists all known endpoints as json.
--resolvers ...... List all known resolvers as json.
--response ....... Show the http response in the result.
--retries ........ Number of retries to do in case requests fails, default: 5
--timeout ........ Timeout for the request in milliseconds, default: 30000 (5 sec)
--max-age ........ Max age of the persisted data, default: 300000 (5 min)
--no-persist ..... Dont persist the the latest resolvers
--offline ........ Do not update the resolver list
```

@@ -101,23 +140,35 @@

```typescript
interface EndpointProps {
/* https is the default for DoH endpoints, udp4:/upd6: for regular dns endpoints and http for debug only! defaults to https: */
protocol?: 'http:' | 'https:' | 'udp4:' | 'udp6:';
type EndpointProps = {
/* https is the default for DoH endpoints and http for debug only! If you don't specify a protocol, https is assumed */
protocol: 'https:' | 'http:'
/* https port, defaults to 443 for https, 80 for http */
port?: number | string | null
/* Host to look up */
host: string;
/* Path, prefixed with /, defaults to /dns-query for the http/https protocol, ignored for udp */
path?: string;
/* https port, defaults to 443 for https, 80 for http and 53 for udp*/
port?: number;
/* true, if endpoint is known to log requests, defaults to false */
log?: boolean;
host: string
/* Known IPV4 address that can be used for the lookup */
ipv4?: string
/* Known IPV6 address that can be used for the lookup */
ipv6?: string
/* true, if endpoint supports http/https CORS headers, defaults to false */
cors?: boolean;
/* true, if endpoint is known to filters/redirects DNS packets, defaults to false */
filter?: boolean;
/* link to documentation, if available */
docs?: string;
/* Known geographical location */
location?: string;
cors?: boolean
/* Path, prefixed with /, defaults to /dns-query for the http/https protocol */
path?: string
/* Method to request in case of http/https, defaults to GET */
method?: 'post' | 'Post' | 'POST' | 'get' | 'Get' | 'GET';
method?: 'POST' | 'GET'
} | {
protocol: 'udp4:'
/* ipv4 endpoint to connect-to */
ipv4: string
/* https port, defaults to 53; 443 if pk is present */
port?: number | string | null
/* dnscrypt public key */
pk?: string | null
} | {
protocol: 'udp6:'
/* ipv4 endpoint to connect-to */
ipv6: string
/* https port, defaults to 53; 443 if pk is present */
port?: number | string | null
/* dnscrypt public key */
pk?: string | null
}

@@ -129,4 +180,5 @@ ```

Instead of passing an object you can also pass a string. If the string matches the name
of one of the [endpoints](./endpoints.md), that endpoint will be used, else it needs
to be a url, with a possible `[post]` or `[get]` suffix to indicate the method.
of one of the endpoints, that endpoint will be used. If it doesnt match any endpoint,
then it will be parsed using the `parseEndpoint` method understands an URL like structure
with additional properties defined like flags (`[<name>]`).

@@ -148,2 +200,32 @@ _Examples:_

### Persisting Resolvers
Loading the latest list of resolvers from the servers will increase both the load
on the server hosting the list and your application's responsiveness. `dns-query` comes
with support for persisting the resolvers in order to ease the load.
While the CLI does that by default, you need to enable it when using the JavaScript
API.
```js
query(..., {
persist: true
})
```
In node.js this will try to persist the list of resolvers to the `node_modules`
directory.
In the browser it will use `localStorage` to store the copy of resolvers. By default
it will use the `localStoragePrefix = 'dnsquery_'` option. You will be able to find
the persisted resolvers under `localStorage.getItem('dnsquery_resolvers.json')`.
You can change the prefix in the options.
```js
query(..., {
localStoragePrefix: 'my_custom_prefix'
})
```
## See Also

@@ -150,0 +232,0 @@

@@ -1,7 +0,52 @@

import { Packet } from 'dns-packet';
import { IncomingMessage } from 'http';
import { SingleQuestionPacket } from '@leichtgewicht/dns-packet';
import {
Endpoint, EndpointOpts
} from '../common.js';
export interface Options {
import {
RawResolver
} from '../resolvers.js';
export {
TimeoutError,
HTTPStatusError,
AbortError,
ResponseError,
BaseEndpoint,
BaseEndpointOpts,
Endpoint,
EndpointOpts,
HTTPEndpoint,
HTTPEndpointOpts,
UDP4Endpoint,
UDP4EndpointOpts,
UDP6Endpoint,
UDP6EndpointOpts,
parseEndpoint,
toEndpoint
} from '../common.js';
export {
RawResolver
} from '../resolvers.js';
export type Resolver = RawResolver<Endpoint>;
export const backup: {
data: Resolver
time: number
};
export interface Wellknown {
resolvers: Resolver[];
resolverByName: { [name: string]: Resolver };
endpoints: Endpoint[];
endpointByName: { [name: string]: Endpoint };
}
export type OrPromise <T> = Promise<T> | T;
export type EndpointInput = OrPromise<'doh' | 'dns' | ((endpoint: Endpoint) => boolean) | Iterable<Endpoint | EndpointOpts | string>>;
export interface QueryOpts {
/* Set of endpoints to lookup doh queries. */
endpoints?: 'doh' | 'dns' | Iterable<Endpoint | EndpointProps | string>;
endpoints?: EndpointInput;
/* Amount of retry's if a request fails, defaults to 5 */

@@ -15,139 +60,24 @@ retries?: number;

export class Endpoint {
/* https is the default for DoH endpoints, udp4:/upd6: for regular dns endpoints and http for debug only! defaults to https: */
protocol?: 'http:' | 'https:' | 'udp4:' | 'udp6:';
/* Host to look up */
host: string;
/* Path, prefixed with /, defaults to /dns-query for the http/https protocol, ignored for udp */
path?: string;
/* https port, defaults to 443 for https, 80 for http and 53 for udp*/
port?: number;
/* true, if endpoint is known to log requests, defaults to false */
log?: boolean;
/* true, if endpoint supports http/https CORS headers, defaults to false */
cors?: boolean;
/* true, if endpoint is known to filters/redirects DNS packets, defaults to false */
filter?: boolean;
/* link to documentation, if available */
docs?: string;
/* Known geographical location */
location?: string;
/* Method to request in case of http/https, defaults to GET */
method?: 'post' | 'Post' | 'POST' | 'get' | 'Get' | 'GET';
constructor(data: EndpointProps);
}
export type SessionOpts = Partial<{
retries: number
timeout: number
update: boolean
updateURL: URL
persist: boolean
localStoragePrefix: string
maxAge: number
}>;
export type EndpointProps = Omit<Endpoint, ''>;
export type Response = undefined | XMLHttpRequest | IncomingMessage;
export class Session {
opts: SessionOpts;
constructor(opts: SessionOpts);
export function query(packet: Packet, options?: Options): Promise<Packet & {
endpoint: Endpoint;
response: Response;
}>;
wellknown(): Promise<Wellknown>;
endpoints(): Promise<Endpoint[]>;
query(query: SingleQuestionPacket, opts: QueryOpts): Promise<SingleQuestionPacket>;
}
export class AbortError extends Error {
constructor();
code: 'ABORT_ERR';
name: 'AbortError';
}
export class HTTPStatusError extends Error {
constructor(uri: string, status: number, method: string);
uri: string;
status: number;
method: 'POST' | 'GET';
code: 'HTTP_STATUS';
name: 'StatusError';
response: Response;
endpoint: Endpoint;
}
export class ResponseError extends Error {
constructor(message: string)
code: 'RESPONSE_ERR';
name: 'ResponseError';
response: Response;
endpoint: Endpoint;
}
export class TimeoutError extends Error {
constructor(timeout: number)
timeout: number;
code: 'ETIMEOUT';
name: 'TimeoutError';
}
export function parseEndpoints(endpoints?: Iterable<Endpoint | EndpointProps | string>): Endpoint[];
export const endpoints: {
cloudflare: Endpoint;
cloudflareFamily: Endpoint;
cloudflareSecurity: Endpoint;
cloudflareEth: Endpoint;
aAndA: Endpoint;
usablePrivacy: Endpoint;
adguard: Endpoint;
adguardFamily: Endpoint;
adguardUnfiltered: Endpoint;
ahadnsIn: Endpoint;
ahadnsIt: Endpoint;
ahadnsEs: Endpoint;
ahadnsNo: Endpoint;
ahadnsNl: Endpoint;
ahadnsPl: Endpoint;
ahadnsNy: Endpoint;
ahadnsChi: Endpoint;
ahadnsAu: Endpoint;
ahadnsLa: Endpoint;
alidns: Endpoint;
amsNl: Endpoint;
amsSe: Endpoint;
amsEs: Endpoint;
arapurayil: Endpoint;
digitaleGesellschaft: Endpoint;
dnsForFamily: Endpoint;
dnsHome: Endpoint;
blahDnsCh: Endpoint;
blahDnsJp: Endpoint;
blahDnsDe: Endpoint;
blahDnsFi: Endpoint;
cleanBrowsingSecurity: Endpoint;
cleanBrowsingFamily: Endpoint;
cleanBrowsingAdult: Endpoint;
appliedPrivacy: Endpoint;
ffmuc: Endpoint;
tiarap: Endpoint;
tiarapJp: Endpoint;
google: Endpoint;
he: Endpoint;
iij: Endpoint;
libredns: Endpoint;
librednsAds: Endpoint;
njalla: Endpoint;
opendns: Endpoint;
opendnsFamily: Endpoint;
sebyVultr: Endpoint;
sebyOVH: Endpoint;
quad9: Endpoint;
quad9Ads: Endpoint;
switchCh: Endpoint;
yepdns: Endpoint;
lavaDnsEU1: Endpoint;
controlId: Endpoint;
controlIdMw: Endpoint;
controlIdAds: Endpoint;
controlIdSoc: Endpoint;
uncensoredAny: Endpoint;
uncensoredUni: Endpoint;
dnssbGlobal: Endpoint;
dbssbDeDus: Endpoint;
dnssbDeFra: Endpoint;
dnssbNlAms: Endpoint;
dnssbNlAms2: Endpoint;
dnssbEeTll: Endpoint;
dnssbJpKix: Endpoint;
dnssbHkHkg: Endpoint;
dnssbAuSyd: Endpoint;
dnssbUsChi: Endpoint;
dnssbInBlr: Endpoint;
dnssbSgSin: Endpoint;
dnssbKrSel: Endpoint;
dnssbRuMow: Endpoint;
ethlink: Endpoint;
handshake: Endpoint;
};
export function query(query: SingleQuestionPacket, opts: QueryOpts): Promise<SingleQuestionPacket>;
export function wellknown(): Promise<Wellknown>;
export function endpoints(): Promise<Endpoint[]>;
export function loadEndpoints(session: Session, input: EndpointInput): Promise<Endpoint[]>;

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc