Socket
Socket
Sign inDemoInstall

bns

Package Overview
Dependencies
16
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.5 to 0.0.6

lib/api.js

75

bin/dig.js

@@ -5,4 +5,5 @@ #!/usr/bin/env node

const IP = require('binet');
const pkg = require('../package.json');
const {StubResolver} = require('../lib/resolver');
const dns = require('../lib/dns');
const util = require('../lib/util');

@@ -13,4 +14,4 @@

let host = null;
let port = null;
let inet6 = false;
let port = 53;
let inet6 = null;
let reverse = false;

@@ -56,3 +57,3 @@ let json = false;

case '-v':
console.log(`bns ${pkg.version}`);
console.log(`dig.js ${pkg.version}`);
process.exit(0);

@@ -111,13 +112,18 @@ break;

async function lookup(name) {
const options = { all: true, hints: dns.ADDRCONFIG };
const addrs = await dns.lookup(host, options);
const {address} = util.randomItem(addrs);
return address;
}
async function resolve(name, type, options) {
const {host, port} = options;
const resolver = new StubResolver(options.inet6 ? 'udp6' : 'udp4');
const resolver = new dns.Resolver(options);
resolver.rd = options.rd == null ? true : options.rd;
resolver.edns = Boolean(options.edns);
resolver.dnssec = Boolean(options.dnssec);
if (options.debug) {
resolver.on('error', (err) => {
console.error(err.stack);
});
resolver.conf.fromSystem();
if (options.debug) {
resolver.on('log', (...args) => {

@@ -128,20 +134,26 @@ console.error(...args);

await resolver.open();
if (options.reverse) {
try {
return await resolver.reverse(name, port, host);
} finally {
await resolver.close();
}
if (host) {
const server = IP.toHost(host, port);
resolver.setServers([server]);
}
try {
return await resolver.lookup(name, type, port, host);
} finally {
await resolver.close();
}
if (options.reverse)
return resolver.reverseRaw(name);
return resolver.resolveRaw(name, type);
}
function printHeader(host) {
const argv = process.argv.slice(2).join(' ');
process.stdout.write('\n');
process.stdout.write(`; <<>> dig.js ${pkg.version} <<>> ${argv}\n`);
if (host)
process.stdout.write('; (1 server found)\n');
process.stdout.write(';; global options: +cmd\n');
}
(async () => {
if (host && !util.isIP(host))
host = await lookup(host);
const now = Date.now();

@@ -166,11 +178,14 @@

} else {
const argv = process.argv.slice(2).join(' ');
process.stdout.write('\n');
process.stdout.write(`; <<>> bns ${pkg.version} <<>> ${argv}\n`);
printHeader(host);
process.stdout.write(';; Got answer:\n');
process.stdout.write(res.toString(ms) + '\n');
process.stdout.write(res.toString(ms, host, port) + '\n');
}
})().catch((err) => {
console.error(err.message);
process.exit(1);
if (json) {
console.error(err.message);
process.exit(1);
} else {
printHeader(host);
process.stdout.write(`;; error; ${err.message}\n`);
}
});

55

bin/rdig.js

@@ -6,3 +6,3 @@ #!/usr/bin/env node

const pkg = require('../package.json');
const {RecursiveResolver} = require('../lib/resolver');
const rdns = require('../lib/rdns');
const util = require('../lib/util');

@@ -13,4 +13,4 @@

let host = null;
let port = null;
let inet6 = false;
let port = 53;
let inet6 = null;
let reverse = false;

@@ -56,3 +56,3 @@ let json = false;

case '-v':
console.log(`bns ${pkg.version}`);
console.log(`rdig.js ${pkg.version}`);
process.exit(0);

@@ -112,9 +112,9 @@ break;

async function resolve(name, type, options) {
const resolver = new RecursiveResolver(options.inet6 ? 'udp6' : 'udp4');
const resolver = new rdns.Resolver(options);
resolver.rd = Boolean(options.rd);
resolver.edns = Boolean(options.edns);
resolver.dnssec = Boolean(options.dnssec);
if (options.debug) {
resolver.on('error', (err) => {
console.error(err.stack);
});
if (options.debug) {
resolver.on('log', (...args) => {

@@ -125,17 +125,15 @@ console.error(...args);

await resolver.open();
if (options.reverse)
return resolver.reverseRaw(name);
if (options.reverse) {
try {
return await resolver.reverse(name);
} finally {
await resolver.close();
}
}
return resolver.resolveRaw(name, type);
}
try {
return await resolver.lookup(name, type);
} finally {
await resolver.close();
}
function printHeader(host) {
const argv = process.argv.slice(2).join(' ');
process.stdout.write('\n');
process.stdout.write(`; <<>> rdig.js ${pkg.version} <<>> ${argv}\n`);
if (host)
process.stdout.write('; (1 server found)\n');
process.stdout.write(';; global options: +cmd\n');
}

@@ -163,5 +161,3 @@

} else {
const argv = process.argv.slice(2).join(' ');
process.stdout.write('\n');
process.stdout.write(`; <<>> bns ${pkg.version} <<>> ${argv}\n`);
printHeader(host);
process.stdout.write(';; Got answer:\n');

@@ -171,4 +167,9 @@ process.stdout.write(res.toString(ms) + '\n');

})().catch((err) => {
console.error(err.message);
process.exit(1);
if (json) {
console.error(err.message);
process.exit(1);
} else {
printHeader(host);
process.stdout.write(`;; error; ${err.message}\n`);
}
});

@@ -5,5 +5,12 @@ #!/usr/bin/env node

const {RecursiveServer} = require('../lib/server');
const server = new RecursiveServer('udp4');
const RecursiveServer = require('../lib/server/recursive');
const server = new RecursiveServer({
inet6: null,
edns: true,
dnssec: true
});
server.hints.fromRoot();
server.on('error', (err) => {

@@ -38,5 +45,2 @@ console.error(err.stack);

// $ dig @127.0.0.1 google.com A -p 5300
// $ node bin/dig.js google.com A 127.0.0.1 5300
// $ dig @::1 -p 5300 mail.google.com AAAA +dnssec +crypto
server.open(53, '127.0.0.1');

@@ -5,3 +5,3 @@ #!/usr/bin/env node

const {DNSServer} = require('../lib/server');
const DNSServer = require('../lib/server/dns');
const wire = require('../lib/wire');

@@ -19,3 +19,7 @@ const util = require('../lib/util');

const server = new DNSServer('udp6');
const server = new DNSServer({
inet6: null,
edns: true,
dnssec: true
});

@@ -38,3 +42,3 @@ server.on('error', (err) => {

for (const qs of req.question) {
if (qs.class !== classes.INET
if (qs.class !== classes.IN
&& qs.class !== classes.ANY) {

@@ -46,3 +50,3 @@ continue;

answer.name = qs.name;
answer.class = classes.INET;
answer.class = classes.IN;

@@ -77,4 +81,2 @@ if (qs.type === types.A || qs.type === types.ANY) {

// $ dig @127.0.0.1 google.com A -p 5300
// $ node bin/dig.js google.com A 127.0.0.1 5300
server.open(5300, '::');
server.open(5300, '127.0.0.1');

@@ -5,3 +5,3 @@ [

"ttl": 172800,
"class": "INET",
"class": "IN",
"type": "DS",

@@ -18,3 +18,3 @@ "data": {

"ttl": 172800,
"class": "INET",
"class": "IN",
"type": "DS",

@@ -21,0 +21,0 @@ "data": {

@@ -5,3 +5,3 @@ [

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "NS",

@@ -15,3 +15,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "A",

@@ -25,3 +25,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "AAAA",

@@ -35,3 +35,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "NS",

@@ -45,3 +45,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "A",

@@ -55,3 +55,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "AAAA",

@@ -65,3 +65,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "NS",

@@ -75,3 +75,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "A",

@@ -85,3 +85,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "AAAA",

@@ -95,3 +95,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "NS",

@@ -105,3 +105,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "A",

@@ -115,3 +115,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "AAAA",

@@ -125,3 +125,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "NS",

@@ -135,3 +135,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "A",

@@ -145,3 +145,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "AAAA",

@@ -155,3 +155,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "NS",

@@ -165,3 +165,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "A",

@@ -175,3 +175,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "AAAA",

@@ -185,3 +185,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "NS",

@@ -195,3 +195,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "A",

@@ -205,3 +205,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "AAAA",

@@ -215,3 +215,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "NS",

@@ -225,3 +225,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "A",

@@ -235,3 +235,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "AAAA",

@@ -245,3 +245,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "NS",

@@ -255,3 +255,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "A",

@@ -265,3 +265,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "AAAA",

@@ -275,3 +275,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "NS",

@@ -285,3 +285,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "A",

@@ -295,3 +295,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "AAAA",

@@ -305,3 +305,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "NS",

@@ -315,3 +315,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "A",

@@ -325,3 +325,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "AAAA",

@@ -335,3 +335,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "NS",

@@ -345,3 +345,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "A",

@@ -355,3 +355,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "AAAA",

@@ -365,3 +365,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "NS",

@@ -375,3 +375,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "A",

@@ -385,3 +385,3 @@ "data": {

"ttl": 3600000,
"class": "INET",
"class": "IN",
"type": "AAAA",

@@ -395,3 +395,3 @@ "data": {

"ttl": 172800,
"class": "INET",
"class": "IN",
"type": "DS",

@@ -408,3 +408,3 @@ "data": {

"ttl": 172800,
"class": "INET",
"class": "IN",
"type": "DS",

@@ -411,0 +411,0 @@ "data": {

@@ -9,39 +9,56 @@ /*!

const API = require('./api');
const Authority = require('./authority');
const Cache = require('./cache');
const constants = require('./constants');
const dane = require('./dane');
const dns = require('./dns');
const DNSResolver = require('./resolver/dns');
const DNSServer = require('./server/dns');
const dnssec = require('./dnssec');
const encoding = require('./encoding');
const hints = require('./hints');
const Hints = require('./hints');
const Hosts = require('./hosts');
const hsig = require('./hsig');
const nsec3 = require('./nsec3');
const rdns = require('./rdns');
const RecursiveResolver = require('./resolver/recursive');
const RecursiveServer = require('./server/recursive');
const ResolvConf = require('./resolvconf');
const resolver = require('./resolver');
const server = require('./server');
const ROOT_HINTS = require('./roothints');
const sig0 = require('./sig0');
const smimea = require('./smimea');
const sshfp = require('./sshfp');
const StubResolver = require('./resolver/stub');
const StubServer = require('./server/stub');
const tlsa = require('./tlsa');
const util = require('./util');
const wire = require('./wire');
exports.API = API;
exports.Authority = Authority;
exports.Cache = Cache;
exports.constants = constants;
exports.dane = dane;
exports.dns = dns;
exports.DNSResolver = DNSResolver;
exports.DNSServer = DNSServer;
exports.dnssec = dnssec;
exports.encoding = encoding;
exports.hints = hints;
exports.Hints = Hints;
exports.Hosts = Hosts;
exports.hsig = hsig;
exports.nsec3 = nsec3;
exports.rdns = rdns;
exports.RecursiveResolver = RecursiveResolver;
exports.RecursiveServer = RecursiveServer;
exports.ResolvConf = ResolvConf;
exports.DNSResolver = resolver.DNSResolver;
exports.StubResolver = resolver.StubResolver;
exports.OSResolver = resolver.OSResolver;
exports.RecursiveResolver = resolver.RecursiveResolver;
exports.Cache = resolver.Cache;
exports.Hints = resolver.Hints;
exports.Authority = resolver.Authority;
exports.DNSServer = server.DNSServer;
exports.StubServer = server.StubServer;
exports.RecursiveServer = server.RecursiveServer;
exports.ROOT_HINTS = ROOT_HINTS;
exports.sig0 = sig0;
exports.smimea = smimea;
exports.sshfp = sshfp;
exports.StubResolver = StubResolver;
exports.StubServer = StubServer;
exports.tlsa = tlsa;
exports.util = util;
exports.wire = wire;

@@ -10,2 +10,5 @@ /*!

* https://github.com/golang/go/blob/master/src/net/dnsmsg.go
*
* Resources:
* https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
*/

@@ -27,5 +30,6 @@

STATUS: 2,
// 3 is unassigned
NOTIFY: 4,
UPDATE: 5,
UNKNOWN: 15
UPDATE: 5
// 6-15 are unassigned
};

@@ -44,4 +48,3 @@

[opcodes.NOTIFY]: 'NOTIFY',
[opcodes.UPDATE]: 'UPDATE',
[opcodes.UNKNOWN]: 'UNKNOWN'
[opcodes.UPDATE]: 'UPDATE'
};

@@ -93,6 +96,6 @@

SUCCESS: 0, // No Error
FORMATERROR: 1, // Format Error
SERVERFAILURE: 2, // Server Failure
FORMERR: 1, // Format Error
SERVFAIL: 2, // Server Failure
NXDOMAIN: 3, // Non-Existent Domain
NOTIMPLEMENTED: 4, // Not Implemented
NOTIMP: 4, // Not Implemented
REFUSED: 5, // Query Refused

@@ -104,3 +107,23 @@ YXDOMAIN: 6, // Name Exists when it should not

NOTZONE: 10, // Name not contained in zone
UNKNOWN: 15
// 11-15 are unassigned
// EDNS
BADSIG: 16, // TSIG Signature Failure
BADVERS: 16, // Bad OPT Version
BADKEY: 17, // Key not recognized
BADTIME: 18, // Signature out of time window
BADMODE: 19, // Bad TKEY Mode
BADNAME: 20, // Duplicate key name
BADALG: 21, // Algorithm not supported
BADTRUNC: 22, // Bad Truncation
BADCOOKIE: 23, // Bad/missing Server Cookie
// 24-3840 are unassigned
// 3841-4095 reserved for private use
// 4096-65534 unassigned
RESERVED: 65535
};

@@ -116,6 +139,6 @@

[codes.NOERROR]: 'NOERROR',
[codes.FORMATERROR]: 'FORMATERROR',
[codes.SERVERFAILURE]: 'SERVERFAILURE',
[codes.FORMERR]: 'FORMERR',
[codes.SERVFAIL]: 'SERVFAIL',
[codes.NXDOMAIN]: 'NXDOMAIN',
[codes.NOTIMPLEMENTED]: 'NOTIMPLEMENTED',
[codes.NOTIMP]: 'NOTIMP',
[codes.REFUSED]: 'REFUSED',

@@ -127,3 +150,12 @@ [codes.YXDOMAIN]: 'YXDOMAIN',

[codes.NOTZONE]: 'NOTZONE',
[codes.UNKNOWN]: 'UNKNOWN'
// edns
[codes.BADVERS]: 'BADVERS',
[codes.BADKEY]: 'BADKEY',
[codes.BADTIME]: 'BADTIME',
[codes.BADMODE]: 'BADMODE',
[codes.BADNAME]: 'BADNAME',
[codes.BADALG]: 'BADALG',
[codes.BADTRUNC]: 'BADTRUNC',
[codes.BADCOOKIE]: 'BADCOOKIE',
[codes.RESERVED]: 'RESERVED'
};

@@ -192,2 +224,5 @@

SMIMEA: 53,
// 54 is unassigned
HIP: 55,

@@ -201,2 +236,5 @@ NINFO: 56, // proposed

CSYNC: 62,
// 63-98 are unassigned
SPF: 99, // obsolete

@@ -213,5 +251,5 @@ UINFO: 100, // obsolete

EUI64: 109,
URI: 256,
CAA: 257,
AVC: 258, // proposed
// 110-248 are unassigned
TKEY: 249,

@@ -223,5 +261,18 @@ TSIG: 250,

MAILA: 254, // obsolete, unimpl (qtype)
ANY: 255, // impl (qtype)
URI: 256,
CAA: 257,
AVC: 258, // proposed
DOA: 259, // proposed
// OX: 260, // proposed successor to DOA?
// 260-32767 are unassigned
TA: 32768,
DLV: 32769,
// 32770-65279 are unassigned
// 65280-65534 reserved for private use
RESERVED: 65535 // unimpl

@@ -310,5 +361,2 @@ };

[types.EUI64]: 'EUI64',
[types.URI]: 'URI',
[types.CAA]: 'CAA',
[types.AVC]: 'AVC',
[types.TKEY]: 'TKEY',

@@ -320,2 +368,7 @@ [types.TSIG]: 'TSIG',

[types.MAILA]: 'MAILA',
[types.URI]: 'URI',
[types.CAA]: 'CAA',
[types.AVC]: 'AVC',
[types.DOA]: 'DOA',
// [types.OX]: 'OX',
[types.ANY]: 'ANY',

@@ -334,9 +387,19 @@ [types.TA]: 'TA',

const classes = {
UNKNOWN: 0, // RESERVED0
INET: 1,
CSNET: 2,
CHAOS: 3,
HESIOD: 4,
RESERVED0: 0,
IN: 1, // INET
// 2 is unassigned (used to be CSNET/CS)
CH: 3, // CHAOS
HS: 4, // HESIOD
// 5-253 are unassigned
NONE: 254,
ANY: 255
ANY: 255,
// 256-65279 are unassigned
// 65280-65534 are reserved for private use
RESERVED65535: 65535
};

@@ -351,44 +414,12 @@

const classesByVal = {
[classes.UNKNOWN]: 'UNKNOWN', // RESERVED0
[classes.INET]: 'INET',
[classes.CSNET]: 'CSNET',
[classes.CHAOS]: 'CHAOS',
[classes.HESIOD]: 'HESIOD',
[classes.RESERVED0]: 'RESERVED0',
[classes.IN]: 'IN',
[classes.CH]: 'CH',
[classes.HS]: 'HS',
[classes.NONE]: 'NONE',
[classes.ANY]: 'ANY'
[classes.ANY]: 'ANY',
[classes.RESERVED65535]: 'RESERVED65535'
};
/**
* Short Question and Record Classes (qclass/rclass)
* @enum {Number}
* @default
*/
const short = {
UNKNOWN: classes.UNKNOWN, // RESERVED0
IN: classes.INET,
CS: classes.CSNET, // CLASS2
CH: classes.CHAOS,
HS: classes.HESIOD,
NONE: classes.NONE,
ANY: classes.ANY
};
/**
* Short Question and Record Classes By Value
* @enum {String}
* @default
*/
const shortByVal = {
[short.UNKNOWN]: 'UNKNOWN', // RESERVED0
[short.IN]: 'IN',
[short.CS]: 'CS', // CLASS2
[short.CH]: 'CH',
[short.HS]: 'HS',
[short.NONE]: 'NONE',
[short.ANY]: 'ANY'
};
/**
* EDNS0 Flags

@@ -401,2 +432,3 @@ * @enum {Number}

DO: 1 << 15 // DNSSEC OK
// 1-15 are reserved
};

@@ -415,42 +447,2 @@

/**
* Extended Response Codes
* @enum {Number}
* @default
*/
const ecodes = {
NOERROR: 0, // No Error
SUCCESS: 0, // No Error
BADSIG: 1, // TSIG Signature Failure
BADVERS: 1, // Bad OPT Version
BADKEY: 2, // Key not recognized
BADTIME: 3, // Signature out of time window
BADMODE: 4, // Bad TKEY Mode
BADNAME: 5, // Duplicate key name
BADALG: 6, // Algorithm not supported
BADTRUNC: 7, // Bad Truncation
BADCOOKIE: 8, // Bad/missing Server Cookie
UNKNOWN: 255 // Unknown
};
/**
* Extended Response Codes By Value
* @enum {String}
* @default
*/
const ecodesByVal = {
[ecodes.NOERROR]: 'NOERROR',
[ecodes.BADVERS]: 'BADVERS',
[ecodes.BADKEY]: 'BADKEY',
[ecodes.BADTIME]: 'BADTIME',
[ecodes.BADMODE]: 'BADMODE',
[ecodes.BADNAME]: 'BADNAME',
[ecodes.BADALG]: 'BADALG',
[ecodes.BADTRUNC]: 'BADTRUNC',
[ecodes.BADCOOKIE]: 'BADCOOKIE',
[ecodes.UNKNOWN]: 'UNKNOWN'
};
/**
* EDNS0 Option Codes

@@ -462,3 +454,3 @@ * @enum {Number}

const options = {
UNKNOWN: 0, // None
RESERVED: 0, // None
LLQ: 1, // Long Lived Queries

@@ -475,5 +467,19 @@ UL: 2, // Update Lease Draft

PADDING: 12, // Padding
CHAIN: 13, // Chain
KEYTAG: 14, // EDNS Key Tag
// 15-26945 are unassigned
// DEVICEID: 26946,
// 26947-65000 are unassigned
LOCAL: 65001, // Beginning of range reserved for local/experimental use
LOCALSTART: 65001, // Beginning of range reserved for local/experimental use
// 65001-65534 are reserved for experimental use
LOCALEND: 65534 // End of range reserved for local/experimental use
// 65535 is reserved
};

@@ -488,3 +494,3 @@

const optionsByVal = {
[options.UNKNOWN]: 'UNKNOWN',
[options.RESERVED]: 'RESERVED',
[options.LLQ]: 'LLQ',

@@ -501,7 +507,332 @@ [options.UL]: 'UL',

[options.PADDING]: 'PADDING',
[options.LOCALSTART]: 'LOCALSTART',
[options.LOCALEND]: 'LOCALEND'
[options.CHAIN]: 'CHAIN',
[options.KEYTAG]: 'KEYTAG',
// [options.DEVICEID]: 'DEVICEID',
[options.LOCAL]: 'LOCAL'
};
/**
* DNSKEY flag values.
* @enum {Number}
* @default
*/
const keyFlags = {
SEP: 1,
REVOKE: 1 << 7,
ZONE: 1 << 8
};
/**
* DNSSEC encryption algorithm codes.
* @enum {Number}
* @default
*/
const algs = {
// _: 0,
RSAMD5: 1,
DH: 2,
DSA: 3,
// _: 4,
RSASHA1: 5,
DSANSEC3SHA1: 6,
RSASHA1NSEC3SHA1: 7,
RSASHA256: 8,
// _: 9,
RSASHA512: 10,
// _: 11,
ECCGOST: 12,
ECDSAP256SHA256: 13,
ECDSAP384SHA384: 14,
ED25519: 15,
ED448: 16,
INDIRECT: 252,
PRIVATEDNS: 253, // Private (experimental keys)
PRIVATEOID: 254
};
/**
* DNSSEC algorithm codes by value.
* @const {Object}
*/
const algsByVal = {
[algs.RSAMD5]: 'RSAMD5',
[algs.DH]: 'DH',
[algs.DSA]: 'DSA',
[algs.RSASHA1]: 'RSASHA1',
[algs.DSANSEC3SHA1]: 'DSA-NSEC3-SHA1',
[algs.RSASHA1NSEC3SHA1]: 'RSASHA1-NSEC3-SHA1',
[algs.RSASHA256]: 'RSASHA256',
[algs.RSASHA512]: 'RSASHA512',
[algs.ECCGOST]: 'ECC-GOST',
[algs.ECDSAP256SHA256]: 'ECDSAP256SHA256',
[algs.ECDSAP384SHA384]: 'ECDSAP384SHA384',
[algs.ED25519]: 'ED25519',
[algs.ED448]: 'ED448',
[algs.INDIRECT]: 'INDIRECT',
[algs.PRIVATEDNS]: 'PRIVATEDNS',
[algs.PRIVATEOID]: 'PRIVATEOID'
};
/**
* DNSSEC hashing algorithm codes.
* @enum {Number}
* @default
*/
const hashes = {
// _: 0,
SHA1: 1, // RFC 4034
SHA256: 2, // RFC 4509
GOST94: 3, // RFC 5933
SHA384: 4, // Experimental
SHA512: 5 // Experimental
};
/**
* DNSSEC hashing algorithm codes by value.
* @const {Object}
*/
const hashesByVal = {
[hashes.SHA1]: 'SHA1',
[hashes.SHA256]: 'SHA256',
[hashes.GOST94]: 'GOST94',
[hashes.SHA384]: 'SHA384',
[hashes.SHA512]: 'SHA512'
};
/**
* Corresponding hashes for algorithms.
* @const {Object}
*/
const algHashes = {
[algs.RSAMD5]: null, // Deprecated in RFC 6725 (introduced in rfc2537)
[algs.RSASHA1]: hashes.SHA1,
[algs.RSASHA1NSEC3SHA1]: hashes.SHA1,
[algs.RSASHA256]: hashes.SHA256,
[algs.ECDSAP256SHA256]: hashes.SHA256,
[algs.ECDSAP384SHA384]: hashes.SHA384,
[algs.RSASHA512]: hashes.SHA512,
[algs.ED25519]: hashes.SHA256
};
/**
* NSEC3 hashes.
* @enum {Number}
* @default
*/
const nsecHashes = {
SHA1: 1
};
/**
* NSEC3 hashes by value.
* @const {Object}
*/
const nsecHashesByVal = {
[nsecHashes.SHA1]: 'SHA1'
};
/**
* CERT types (rfc4398).
* @enum {Number}
* @default
*/
const certTypes = {
// 0 reserved
PKIX: 1,
SPKI: 2,
PGP: 3,
IPKIX: 4,
ISPKI: 5,
IPGP: 6,
ACPKIX: 7,
IACPKIX: 8,
// 9-252 unassigned
URI: 253,
OID: 254
// 255 reserved
// 256-65279 unassigned
// 65280-65534 experimental
// 65535 reserved
};
/**
* CERT types by value.
* @const {Object}
*/
const certTypesByVal = {
[certTypes.PKIX]: 'PKIX',
[certTypes.SPKI]: 'SPKI',
[certTypes.PGP]: 'PGP',
[certTypes.IPKIX]: 'IPKIX',
[certTypes.ISPKI]: 'ISPKI',
[certTypes.IPGP]: 'IPGP',
[certTypes.ACPKIX]: 'ACPKIX',
[certTypes.IACPKIX]: 'IACPKIX',
[certTypes.URI]: 'URI',
[certTypes.OID]: 'OID'
};
/**
* DANE usages.
* @enum {Number}
* @default
*/
const usages = {
CAC: 0, // CA constraint
SCC: 1, // Service certificate constraint
TAA: 2, // Trust anchor assertion
DIC: 3, // Domain-issued certificate
// 4-254 are unassigned
PRIVATE: 255 // Private Use
};
/**
* DANE usages by value.
* @const {Object}
*/
const usagesByVal = {
[usages.CAC]: 'CAC',
[usages.SCC]: 'SCC',
[usages.TAA]: 'TAA',
[usages.DIC]: 'DIC',
[usages.PRIVATE]: 'PRIVATE'
};
/**
* DANE selectors.
* @enum {Number}
* @default
*/
const selectors = {
FULL: 0, // Full Certificate
SPKI: 1, // SubjectPublicKeyInfo
// 2-254 are unassigned
PRIVATE: 255 // Private Use
};
/**
* DANE selectors by value.
* @const {Object}
*/
const selectorsByVal = {
[selectors.FULL]: 'FULL',
[selectors.SPKI]: 'SPKI',
[selectors.PRIVATE]: 'PRIVATE'
};
/**
* DANE matching types.
* @enum {Number}
* @default
*/
const matchingTypes = {
NONE: 0, // No hash used
SHA256: 1,
SHA512: 2,
// 3-254 are unassigned
PRIVATE: 255 // Private Use
};
/**
* DANE matching types by value.
* @const {Object}
*/
const matchingTypesByVal = {
[matchingTypes.NONE]: 'NONE',
[matchingTypes.SHA256]: 'SHA256',
[matchingTypes.SHA512]: 'SHA512',
[matchingTypes.PRIVATE]: 'PRIVATE'
};
/**
* SSHFP algorithms.
* @enum {Number}
* @default
*/
const sshAlgs = {
RSA: 1,
DSA: 2,
ECDSA: 3,
ED25519: 4
};
/**
* SSHFP algorithms by value.
* @const {Object}
* @default
*/
const sshAlgsByVal = {
[sshAlgs.RSA]: 'RSA',
[sshAlgs.DSA]: 'DSA',
[sshAlgs.ECDSA]: 'ECDSA',
[sshAlgs.ED25519]: 'ED25519'
};
/**
* SSHFP hashes.
* @enum {Number}
* @default
*/
const sshHashes = {
SHA1: 1,
SHA256: 2
};
/**
* SSHFP hashes by value.
* @const {Object}
* @default
*/
const sshHashesByVal = {
[sshHashes.SHA1]: 'SHA1',
[sshHashes.SHA256]: 'SHA256'
};
/**
* TSIG hash algorithms.
* @const {Object}
* @default
*/
const tsigHashes = {
MD5: 'hmac-md5.sig-alg.reg.int.',
SHA1: 'hmac-sha1.',
SHA256: 'hmac-sha256.',
SHA512: 'hmac-sha512.'
};
/**
* TSIG hash algorithms by value.
* @const {Object}
* @default
*/
const tsigHashesByVal = {
[tsigHashes.MD5]: 'MD5',
[tsigHashes.SHA1]: 'SHA1',
[tsigHashes.SHA256]: 'SHA256',
[tsigHashes.SHA512]: 'SHA512'
};
/**
* For RFC1982 (Serial Arithmetic) calculations in 32 bits.

@@ -520,4 +851,28 @@ * @const {Number}

const MAX_DOMAIN_LENGTH = 256;
const MAX_NAME_SIZE = 255;
/**
* Max label length.
* @const {Number}
* @default
*/
const MAX_LABEL_SIZE = 63;
/**
* Max udp size.
* @const {Number}
* @default
*/
const MAX_UDP_SIZE = 512;
/**
* Max udp+edns size.
* @const {Number}
* @default
*/
const MAX_EDNS_SIZE = 4096;
/*

@@ -605,24 +960,24 @@ * Helpers

function shortToString(class_) {
return toSymbol(class_, shortByVal, 'CLASS', 0xffff);
function optionToString(option) {
return toSymbol(option, optionsByVal, 'OPTION', 0xffff);
}
function stringToShort(symbol) {
return fromSymbol(symbol, 'short', short, 'CLASS', 5);
function stringToOption(symbol) {
return fromSymbol(symbol, 'option', options, 'OPTION', 5);
}
function ecodeToString(ecode) {
return toSymbol(ecode, ecodesByVal, 'RCODE', 0xff);
function algToString(alg) {
return toSymbol(alg, algsByVal, 'ALG', 0xff);
}
function stringToEcode(symbol) {
return fromSymbol(symbol, 'code', ecodes, 'RCODE', 3) & 0xff;
function stringToAlg(symbol) {
return fromSymbol(symbol, 'algorithm', algs, 'ALG', 3) & 0xff;
}
function optionToString(option) {
return toSymbol(option, optionsByVal, 'OPTION', 0xffff);
function hashToString(hash) {
return toSymbol(hash, hashesByVal, 'HASH', 0xff);
}
function stringToOption(symbol) {
return fromSymbol(symbol, 'option', options, 'OPTION', 5);
function stringToHash(symbol) {
return fromSymbol(symbol, 'hash', hashes, 'HASH', 3) & 0xff;
}

@@ -644,12 +999,34 @@

exports.classesByVal = classesByVal;
exports.short = short;
exports.shortByVal = shortByVal;
exports.eflags = eflags;
exports.eflagsByVal = eflagsByVal;
exports.ecodes = ecodes;
exports.ecodesByVal = ecodesByVal;
exports.options = options;
exports.optionsByVal = optionsByVal;
exports.keyFlags = keyFlags;
exports.algs = algs;
exports.algsByVal = algsByVal;
exports.hashes = hashes;
exports.hashesByVal = hashesByVal;
exports.algHashes = algHashes;
exports.nsecHashes = nsecHashes;
exports.nsecHashesByVal = nsecHashesByVal;
exports.certTypes = certTypes;
exports.certTypesByVal = certTypesByVal;
exports.usages = usages;
exports.usagesByVal = usagesByVal;
exports.selectors = selectors;
exports.selectorsByVal = selectorsByVal;
exports.matchingTypes = matchingTypes;
exports.matchingTypesByVal = matchingTypesByVal;
exports.sshAlgs = sshAlgs;
exports.sshAlgsByVal = sshAlgsByVal;
exports.sshHashes = sshHashes;
exports.sshHashesByVal = sshHashesByVal;
exports.tsigHashes = tsigHashes;
exports.tsigHashesByVal = tsigHashesByVal;
exports.YEAR68 = YEAR68;
exports.MAX_DOMAIN_LENGTH = MAX_DOMAIN_LENGTH;
exports.MAX_NAME_SIZE = MAX_NAME_SIZE;
exports.MAX_LABEL_SIZE = MAX_LABEL_SIZE;
exports.MAX_UDP_SIZE = MAX_UDP_SIZE;
exports.MAX_EDNS_SIZE = MAX_EDNS_SIZE;

@@ -664,7 +1041,7 @@ exports.opcodeToString = opcodeToString;

exports.stringToClass = stringToClass;
exports.shortToString = shortToString;
exports.stringToShort = stringToShort;
exports.ecodeToString = ecodeToString;
exports.stringToEcode = stringToEcode;
exports.optionToString = optionToString;
exports.stringToOption = stringToOption;
exports.algToString = algToString;
exports.stringToAlg = stringToAlg;
exports.hashToString = hashToString;
exports.stringToHash = stringToHash;

@@ -17,6 +17,7 @@ /*!

const bio = require('bufio');
const constants = require('./constants');
const crypto = require('./crypto');
const encoding = require('./encoding');
const util = require('./util');
const wire = require('./wire');
const crypto = require('./crypto');

@@ -37,2 +38,11 @@ const {

types,
keyFlags,
algs,
algsByVal,
hashes,
hashesByVal,
algHashes
} = constants;
const {
Message,

@@ -46,70 +56,2 @@ Record,

// DNSKEY flag values.
const flags = {
SEP: 1,
REVOKE: 1 << 7,
ZONE: 1 << 8
};
// DNSSEC encryption algorithm codes.
const algs = {
// _: 0,
RSAMD5: 1,
DH: 2,
DSA: 3,
// _: 4,
RSASHA1: 5,
DSANSEC3SHA1: 6,
RSASHA1NSEC3SHA1: 7,
RSASHA256: 8,
// _: 9,
RSASHA512: 10,
// _: 11,
ECCGOST: 12,
ECDSAP256SHA256: 13,
ECDSAP384SHA384: 14,
ED25519: 15,
ED448: 16,
INDIRECT: 252,
PRIVATEDNS: 253, // Private (experimental keys)
PRIVATEOID: 254
};
const algsByVal = {
[algs.RSAMD5]: 'RSAMD5',
[algs.DH]: 'DH',
[algs.DSA]: 'DSA',
[algs.RSASHA1]: 'RSASHA1',
[algs.DSANSEC3SHA1]: 'DSA-NSEC3-SHA1',
[algs.RSASHA1NSEC3SHA1]: 'RSASHA1-NSEC3-SHA1',
[algs.RSASHA256]: 'RSASHA256',
[algs.RSASHA512]: 'RSASHA512',
[algs.ECCGOST]: 'ECC-GOST',
[algs.ECDSAP256SHA256]: 'ECDSAP256SHA256',
[algs.ECDSAP384SHA384]: 'ECDSAP384SHA384',
[algs.ED25519]: 'ED25519',
[algs.ED448]: 'ED448',
[algs.INDIRECT]: 'INDIRECT',
[algs.PRIVATEDNS]: 'PRIVATEDNS',
[algs.PRIVATEOID]: 'PRIVATEOID'
};
// DNSSEC hashing algorithm codes.
const hashes = {
// _: 0,
SHA1: 1, // RFC 4034
SHA256: 2, // RFC 4509
GOST94: 3, // RFC 5933
SHA384: 4, // Experimental
SHA512: 5 // Experimental
};
const hashesByVal = {
[hashes.SHA1]: 'SHA1',
[hashes.SHA256]: 'SHA256',
[hashes.GOST94]: 'GOST94',
[hashes.SHA384]: 'SHA384',
[hashes.SHA512]: 'SHA512'
};
const algToHash = {

@@ -536,6 +478,6 @@ [algs.RSAMD5]: crypto.md5, // Deprecated in RFC 6725

if (rd.flags & flags.REVOKE)
if (rd.flags & keyFlags.REVOKE)
continue;
if (!(rd.flags & flags.ZONE))
if (!(rd.flags & keyFlags.ZONE))
continue;

@@ -546,3 +488,3 @@

if (rd.flags & dnssec.flags.SEP)
if (rd.flags & keyFlags.SEP)
kskMap.set(rd.keyTag(), rr);

@@ -741,33 +683,16 @@ }

if (type !== types.RRSIG) {
if (rr.type === types.RRSIG)
continue;
switch (rr.type) {
case types.RRSIG:
case types.DNSKEY:
case types.DS:
case types.NSEC3:
case types.NSEC3PARAM:
case types.NSEC:
if (type !== rr.type)
break;
// fall through
default:
filtered.push(rr);
break;
}
if (type !== types.DNSKEY) {
if (rr.type === types.DNSKEY)
continue;
}
if (type !== types.DS) {
if (rr.type === types.DS)
continue;
}
if (type !== types.NSEC3) {
if (rr.type === types.NSEC3)
continue;
}
if (type !== types.NSEC3PARAM) {
if (rr.type === types.NSEC3PARAM)
continue;
}
if (type !== types.NSEC) {
if (rr.type === types.NSEC)
continue;
}
filtered.push(rr);
}

@@ -794,3 +719,3 @@

dnssec.flags = flags;
dnssec.keyFlags = keyFlags;
dnssec.algs = algs;

@@ -800,3 +725,4 @@ dnssec.algsByVal = algsByVal;

dnssec.hashesByVal = hashesByVal;
dnssec.algHashes = algHashes;
dnssec.algToHash = algToHash;
dnssec.hashToHash = hashToHash;

@@ -19,2 +19,3 @@ /*!

const {EncodingError} = require('bufio');
const {MAX_NAME_SIZE, MAX_LABEL_SIZE} = require('./constants');

@@ -45,25 +46,31 @@ const ASCII = [

const NAME_BUFFER = Buffer.allocUnsafe(MAX_NAME_SIZE * 4);
const encoding = exports;
encoding.sizeName = function sizeName(name, map, cmp) {
const [off] = encoding.writeName(null, name, 0, map, cmp);
encoding.sizeName = function sizeName(name, map, insert, cmp) {
const [off] = encoding.writeName(null, name, 0, map, insert, cmp);
return off;
};
encoding.writeName = function writeName(data, name, off, map, cmp) {
encoding.writeName = function writeName(data, name, off, map, insert, cmp) {
if (data == null)
data = null;
if (map == null)
map = null;
if (insert == null)
insert = map != null;
if (cmp == null)
cmp = false;
cmp = map != null;
assert(data == null || Buffer.isBuffer(data));
assert(data === null || Buffer.isBuffer(data));
assert(typeof name === 'string');
assert((off >>> 0) === off);
assert(map == null || (map instanceof Map));
assert(map === null || (map instanceof Map));
assert(typeof insert === 'boolean');
assert(typeof cmp === 'boolean');
assert(name.length <= 254);
let len = 256;
if (data)
len = data.length;
let nl = name.length;

@@ -74,5 +81,8 @@

const n = Buffer.from(name, 'ascii');
if (nl > MAX_NAME_SIZE * 4)
throw new EncodingError(0, 'Name too large');
if (n.length !== nl)
const n = NAME_BUFFER;
if (n.write(name, 'ascii') !== nl)
throw new EncodingError(0, 'Bad ascii string');

@@ -83,4 +93,4 @@

let begin = 0;
let escaped = false;
let fresh = true;
let escaped = false;
let labels = 0;

@@ -95,5 +105,2 @@

if (off + 1 > len)
throw new EncodingError(off, 'EOF');
if (i + 2 < nl

@@ -109,3 +116,3 @@ && isDigit(n[i + 0])

escaped = true;
escaped = n[i] === 0x2e;
fresh = false;

@@ -120,23 +127,11 @@

if (i - begin >= (1 << 6))
throw new EncodingError(off, 'Bad top bits');
const size = i - begin;
if (off + 1 > len)
throw new EncodingError(off, 'EOF');
if (size > MAX_LABEL_SIZE)
throw new EncodingError(off, 'Max label size exceeded');
if (data)
data[off] = (i - begin) & 0xff;
const offset = off;
off += 1;
for (let j = begin; j < i; j++) {
if (off + 1 > len)
if (data) {
if (off + 1 > data.length)
throw new EncodingError(off, 'EOF');
if (data)
data[off] = n[j];
off += 1;
data[off] = size;
}

@@ -154,8 +149,8 @@

if (p == null) {
if (offset < (2 << 13))
map.set(s, offset);
if (insert && off < (2 << 13))
map.set(s, off);
} else {
if (cmp && ptr === -1) {
ptr = p;
pos = offset;
pos = off;
break;

@@ -167,2 +162,12 @@ }

off += 1;
if (data) {
if (off + size > data.length)
throw new EncodingError(off, 'EOF');
assert(n.copy(data, off, begin, i) === size);
}
off += size;
labels += 1;

@@ -175,14 +180,27 @@ begin = i + 1;

if (n.length === 1 && n[0] === 0x2e /*.*/)
if (nl > MAX_NAME_SIZE)
throw new EncodingError(off, 'Max name size exceeded');
if (nl === 1 && n[0] === 0x2e /*.*/)
return [off, labels];
if (ptr !== -1) {
if (data)
data.writeUInt16BE(pos, ptr ^ 0xc000, true);
off = pos + 2;
off = pos;
if (data) {
if (off + 2 > data.length)
throw new EncodingError(off, 'EOF');
data.writeUInt16BE(ptr ^ 0xc000, off, true);
}
off += 2;
return [off, labels];
}
if (data && off < len)
if (data) {
if (off + 1 > data.length)
throw new EncodingError(off, 'EOF');
data[off] = 0;
}

@@ -200,3 +218,3 @@ off += 1;

let res = 0;
let max = 255;
let max = MAX_NAME_SIZE;
let ptr = 0;

@@ -217,5 +235,11 @@

case 0x00: {
if (c > MAX_LABEL_SIZE)
throw new EncodingError(off, 'Max label size exceeded');
if (off + c > data.length)
throw new EncodingError(off, 'EOF');
if (name.length + c + 1 > max)
throw new EncodingError(off, 'Max name length exceeded');
for (let j = off; j < off + c; j++) {

@@ -247,5 +271,2 @@ const b = data[j];

}
if (name.length >= max)
throw new EncodingError(off, 'Max name length exceeded');
}

@@ -281,3 +302,3 @@

default: {
throw new EncodingError(off, 'Bad character');
throw new EncodingError(off, 'Invalid byte');
}

@@ -293,4 +314,3 @@ }

if (name.length >= max)
throw new EncodingError(off, 'Max name length exceeded');
assert(name.length <= max);

@@ -300,5 +320,6 @@ return [res, name];

encoding.writeNameBW = function writeNameBW(bw, name, map, cmp) {
encoding.writeNameBW = function writeNameBW(bw, name, map, insert, cmp) {
const {data, offset} = bw;
const [off, labels] = encoding.writeName(data, name, offset, map, cmp);
const [off, labels] =
encoding.writeName(data, name, offset, map, insert, cmp);
bw.offset = off;

@@ -315,5 +336,5 @@ return labels;

encoding.packName = function packName(name) {
const size = encoding.sizeName(name, null, false);
const size = encoding.sizeName(name, null, false, false);
const data = Buffer.allocUnsafe(size);
encoding.writeName(data, name, 0, null, false);
encoding.writeName(data, name, 0, null, false, false);
return data;

@@ -391,3 +412,2 @@ };

// WRONG
encoding.toBitmap = function toBitmap(types) {

@@ -394,0 +414,0 @@ assert(Array.isArray(types));

@@ -0,68 +1,202 @@

/*!
* hints.js - root hints object for bns
* Copyright (c) 2018, Christopher Jeffrey (MIT License).
* https://github.com/bcoin-org/bns
*
* Parts of this software are based on solvere:
* https://github.com/rolandshoemaker/solvere
*/
'use strict';
/* eslint max-len: 0 */
const assert = require('assert');
const Authority = require('./authority');
const dnssec = require('./dnssec');
const wire = require('./wire');
const {types, Record} = wire;
module.exports = `
;
; Root Zone
;
/*
* Constants
*/
. 3600000 IN NS A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET. 3600000 IN A 198.41.0.4
A.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:ba3e::2:30
const ROOT_HINTS = require('./roothints');
. 3600000 IN NS B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET. 3600000 IN A 199.9.14.201
B.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:200::b
/**
* Hints
*/
. 3600000 IN NS C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET. 3600000 IN A 192.33.4.12
C.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2::c
class Hints {
constructor() {
this.ns = [];
this.inet4 = new Map();
this.inet6 = new Map();
this.anchors = [];
this.port = 53;
}
. 3600000 IN NS D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET. 3600000 IN A 199.7.91.13
D.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2d::d
inject(hints) {
assert(hints instanceof this.constructor);
. 3600000 IN NS E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET. 3600000 IN A 192.203.230.10
E.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:a8::e
this.ns = hints.ns.slice();
. 3600000 IN NS F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET. 3600000 IN A 192.5.5.241
F.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2f::f
this.inet4.clear();
. 3600000 IN NS G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET. 3600000 IN A 192.112.36.4
G.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:12::d0d
for (const [key, ip] of hints.inet4)
this.inet4.set(key, ip);
. 3600000 IN NS H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET. 3600000 IN A 198.97.190.53
H.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:1::53
this.inet6.clear();
. 3600000 IN NS I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET. 3600000 IN A 192.36.148.17
I.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:7fe::53
for (const [key, ip] of hints.inet6)
this.inet6.set(key, ip);
. 3600000 IN NS J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET. 3600000 IN A 192.58.128.30
J.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:c27::2:30
this.anchors = hints.anchors.slice();
this.port = hints.port;
. 3600000 IN NS K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET. 3600000 IN A 193.0.14.129
K.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:7fd::1
return this;
}
. 3600000 IN NS L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET. 3600000 IN A 199.7.83.42
L.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:9f::42
clone() {
const copy = new this.constructor();
return copy.inject(this);
}
. 3600000 IN NS M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET. 3600000 IN A 202.12.27.33
M.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:dc3::35
clear() {
this.ns.length = 0;
this.inet4.clear();
this.inet6.clear();
this.anchors.length = 0;
this.port = 53;
return this;
}
;
; Trust Anchors
;
setDefault() {
return this.setRoot();
}
. 172800 IN DS 19036 8 2 49aac11d7b6f6446702e54a1607371607a1a41855200fd2ce1cdde32f24e8fb5
. 172800 IN DS 20326 8 2 e06d44b80b8f1d39a95c0b0d7c65d08458e880409bbc683457104237c7f8ec8d
`;
setLocal() {
this.clear();
this.ns.push('hints.local.');
this.inet4.set('hints.local.', '127.0.0.1');
this.inet6.set('hints.local.', '::1');
return this;
}
setRoot() {
this.clear();
return this.fromRoot();
}
getAuthority(inet6) {
if (this.ns.length === 0)
throw new Error('No nameservers available.');
const auth = new Authority('.', 'hints.local.');
for (const name of this.ns) {
let host;
if (inet6 && this.inet6.has(name))
host = this.inet6.get(name);
else
host = this.inet4.get(name);
auth.add(host, this.port);
}
return auth;
}
fromRecords(records) {
for (const rr of records) {
const name = rr.name.toLowerCase();
switch (rr.type) {
case types.A: {
this.inet4.set(name, rr.data.address);
break;
}
case types.AAAA: {
this.inet6.set(name, rr.data.address);
break;
}
}
}
for (const rr of records) {
const name = rr.name.toLowerCase();
if (name !== '.')
continue;
switch (rr.type) {
case types.NS: {
const ns = rr.data.ns.toLowerCase();
if (this.inet4.has(ns)
|| this.inet6.has(ns)) {
this.ns.push(ns);
}
break;
}
case types.DS: {
this.anchors.push(rr);
break;
}
case types.DNSKEY: {
const ds = dnssec.createDS(rr, dnssec.hashes.SHA256);
this.anchors.push(ds);
break;
}
}
}
assert(this.ns.length > 0);
assert(this.inet4.size > 0 || this.inet6.size > 0);
return this;
}
static fromRecords(records) {
return new this().fromRecords(records);
}
fromZone(text) {
const records = wire.fromZone(text);
return this.fromRecords(records);
}
static fromZone(text) {
return new this().fromZone(text);
}
fromJSON(json) {
assert(Array.isArray(json));
const records = [];
for (const item of json)
records.push(Record.fromJSON(item));
return this.fromRecords(records);
}
static fromJSON(json) {
return new this().fromJSON(json);
}
fromRoot() {
return this.fromZone(ROOT_HINTS);
}
static fromRoot() {
return new this().fromRoot();
}
}
/*
* Expose
*/
module.exports = Hints;

@@ -33,13 +33,86 @@ /*!

this.map = new Map();
this.init();
this.rev = new Map();
}
init() {
this.clear();
this.add('localhost', '127.0.0.1');
this.add('localhost', '::1');
inject(hosts) {
assert(hosts instanceof this.constructor);
this.map.clear();
for (const [key, value] of hosts.map)
this.map.set(key, value.clone());
this.rev.clear();
for (const [key, value] of hosts.rev)
this.rev.set(key, value);
return this;
}
add(name, host, hostname = null) {
clone() {
const copy = new this.constructor();
return copy.inject(this);
}
clear() {
this.clearHosts();
return this;
}
getSystem() {
if (process.platform === 'win32') {
const root = process.env.SystemRoot || 'C:\\Windows';
return Path.join(root, '\\System32\\Drivers\\etc\\hosts');
}
return '/etc/hosts';
}
getHosts() {
const out = [];
for (const [name, addr] of this.map) {
if (addr.inet4)
out.push([name, addr.inet4]);
if (addr.inet6)
out.push([name, addr.inet6]);
}
return out;
}
setHosts(hosts) {
assert(Array.isArray(hosts));
this.clearHosts();
for (const item of hosts) {
assert(Array.isArray(item) && item.length === 2);
const [name, addr] = item;
this.addHost(name, addr);
}
return this;
}
clearHosts() {
this.map.clear();
this.rev.clear();
return this;
}
setDefault() {
return this.setLocal();
}
setLocal() {
this.clearHosts();
this.addHost('localhost', '127.0.0.1');
this.addHost('localhost', '::1');
return this;
}
addHost(name, host, hostname = null) {
assert(typeof name === 'string');

@@ -85,3 +158,3 @@ assert(typeof host === 'string');

this.map.set(name, entry);
this.map.set(rev, entry);
this.rev.set(rev, name);

@@ -91,20 +164,12 @@ return this;

has(name) {
return this.map.has(name);
}
lookup(name) {
const key = name.toLowerCase();
const ptr = this.rev.get(key);
get(name) {
return this.map.get(name);
}
if (ptr)
return this.map.get(ptr);
remove(name) {
this.map.delete(name);
return this;
return this.map.get(key);
}
clear() {
this.map.clear();
return this;
}
query(name, type) {

@@ -114,3 +179,3 @@ assert(typeof name === 'string');

const entry = this.get(name.toLowerCase());
const entry = this.lookup(name);

@@ -126,4 +191,4 @@ if (!entry)

rr.name = name;
rr.class = classes.INET;
rr.ttl = 300;
rr.class = classes.IN;
rr.ttl = 10800;
rr.type = types.PTR;

@@ -141,4 +206,4 @@ rr.data = rd;

rr.name = name;
rr.class = classes.INET;
rr.ttl = 300;
rr.class = classes.IN;
rr.ttl = 10800;
rr.type = types.A;

@@ -156,4 +221,4 @@ rr.data = rd;

rr.name = name;
rr.class = classes.INET;
rr.ttl = 300;
rr.class = classes.IN;
rr.ttl = 10800;
rr.type = types.AAAA;

@@ -172,4 +237,2 @@ rr.data = rd;

this.clear();
if (text.charCodeAt(0) === 0xfeff)

@@ -205,3 +268,3 @@ text = text.substring(1);

try {
this.add(name, ip, hostname);
this.addHost(name, ip, hostname);
} catch (e) {

@@ -221,32 +284,45 @@ continue;

fromFile(file) {
let text;
assert(typeof file === 'string');
const text = fs.readFileSync(file, 'utf8');
return this.fromString(text);
}
this.init();
static fromFile(file) {
return new this().fromFile(file);
}
fromSystem() {
const file = this.getSystem();
try {
text = fs.readFileSync(file, 'utf8');
return this.fromFile(file);
} catch (e) {
return this;
return this.setLocal();
}
}
static fromSystem() {
return new this().fromSystem();
}
async fromFileAsync(file) {
assert(typeof file === 'string');
const text = await fs.readFile(file, 'utf8');
return this.fromString(text);
}
static fromFile(file) {
return new this().fromFile(file);
static fromFileAsync(file) {
return new this().fromFileAsync(file);
}
fromSystem() {
if (process.platform === 'win32') {
const root = process.env.SystemRoot || 'C:';
const file = Path.join(root, '\\System32\\drivers\\etc\\hosts');
this.fromFile(file);
} else {
this.fromFile('/etc/hosts');
async fromSystemAsync() {
const file = this.getSystem();
try {
return await this.fromFileAsync(file);
} catch (e) {
return this.setLocal();
}
return this;
}
static fromSystem() {
return new this().fromSystem();
static fromSystemAsync() {
return new this().fromSystemAsync();
}

@@ -266,2 +342,16 @@ }

}
inject(entry) {
assert(entry instanceof this.constructor);
this.name = entry.name;
this.inet4 = entry.inet4;
this.inet6 = entry.inet6;
this.hostname = entry.hostname;
return this;
}
clone() {
const copy = new this.constructor();
return copy.inject(this);
}
}

@@ -268,0 +358,0 @@

@@ -14,2 +14,4 @@ /*!

const udp = require('budp');
const util = require('./util');
const hasIPv6 = IP.getPublic('ipv6').length > 0;

@@ -31,7 +33,6 @@ /**

this.inet6 = false;
if (options === 'udp6' || (options && options.type === 'udp6'))
this.inet6 = true;
const opt = normalize(options);
this.socket = udp.createSocket(options);
this.inet6 = opt.type === 'udp6';
this.socket = udp.createSocket(opt);
this.sockets = new Map();

@@ -71,3 +72,4 @@

const {address, port} = this.socket.address();
const ip = IP.toBuffer(address);
const host = this.inet6 ? ensure6(address) : ensure4(address);
const ip = IP.toBuffer(host);
const v4 = IP.isIPv4(ip);

@@ -82,7 +84,7 @@ return {

async bind(...args) {
if (this.inet6 && args.length > 1) {
let [, host] = args;
if (args.length > 1) {
const [, host] = args;
if (typeof host === 'string') {
host = ensure6(host);
args[1] = host;
assert(util.isIP(host), 'Must bind to an IP address.');
args[1] = this.inet6 ? ensure6(host) : ensure4(host);
}

@@ -128,4 +130,3 @@ }

if (this.inet6)
host = ensure6(host);
host = this.inet6 ? ensure6(host) : ensure4(host);

@@ -190,2 +191,3 @@ return this.socket.send(msg, pos, len, port, host);

super(options);
this.socket.unref();
}

@@ -308,2 +310,3 @@

this.buffered = 0;
this.family = 'IPv4';
this.host = '0.0.0.0';

@@ -323,3 +326,3 @@ this.port = 0;

tcp: true,
family: IP.isIPv4String(this.host) ? 'IPv4' : 'IPv6',
family: this.family,
address: this.host,

@@ -379,2 +382,3 @@ port: this.port

this.connected = true;
this.family = socket.remoteFamily;
this.host = IP.normalize(socket.remoteAddress);

@@ -391,2 +395,3 @@ this.port = socket.remotePort;

this.socket.connect(...args);
this.socket.unref();

@@ -410,2 +415,3 @@ return new Promise((resolve, reject) => {

this.connected = true;
this.family = this.socket.remoteFamily;
this.host = IP.normalize(this.socket.remoteAddress);

@@ -550,9 +556,61 @@ this.port = this.socket.remotePort;

function ensure6(host) {
function ensure4(host) {
const ip = IP.toBuffer(host);
if (IP.isIPv4(ip))
return `::ffff:${IP.toString(ip)}`;
return host;
if (IP.isNull(ip))
return '0.0.0.0';
if (IP.isLocal(ip))
return '127.0.0.1';
return host;
}
function ensure6(host) {
const ip = IP.toBuffer(host);
if (!IP.isIPv4(ip))
return host;
return `::ffff:${IP.toString(ip)}`;
}
function normalize(options) {
let type = hasIPv6 ? 'udp6' : 'udp4';
if (options == null)
return { type };
if (typeof options === 'string') {
assert(options === 'udp4' || options === 'udp6');
return { type: options };
}
if (typeof options !== 'object')
throw new Error('Invalid options object.');
if (options.type != null) {
assert(options.type === 'udp4' || options.type === 'udp6');
type = options.type;
} else if (options.inet6) {
type = 'udp6';
}
const opt = { type };
if (options.reuseAddr != null)
opt.reuseAddr = options.reuseAddr;
if (options.recvBufferSize != null)
opt.recvBufferSize = options.recvBufferSize;
if (options.sendBufferSize != null)
opt.sendBufferSize = options.sendBufferSize;
return opt;
}
/*

@@ -559,0 +617,0 @@ * Expose

@@ -17,2 +17,3 @@ /*!

const base32 = require('bs32');
const constants = require('./constants');
const crypto = require('./crypto');

@@ -22,10 +23,7 @@ const encoding = require('./encoding');

const util = require('./util');
const {types, nsecHashes, nsecHashesByVal} = constants;
const {hasType, packName} = encoding;
const {types, Question, Record} = wire;
const {Question, Record} = wire;
const nsec3 = exports;
const hashes = {
SHA1: 1
};
nsec3.hashName = function hashName(name, ha, iter, salt) {

@@ -47,3 +45,3 @@ assert(typeof name === 'string');

switch (ha) {
case hashes.SHA1:
case nsecHashes.SHA1:
hash = crypto.sha1;

@@ -83,3 +81,3 @@ break;

const owner = rr.name.toUpperCase();
const owner = rr.name;
const label = util.split(owner);

@@ -92,9 +90,15 @@

const ownerZone = owner.substring(label[1]);
const ownerHash = base32.decodeHex(owner32.toLowerCase());
const ownerHash = base32.decodeHex(owner32);
if (!util.isSubdomain(ownerZone, name.toUpperCase()))
if (ownerHash.length !== nameHash.length)
return false;
if (!util.isSubdomain(ownerZone, name))
return false;
const nextHash = rd.nextDomain;
if (nextHash.length !== nameHash.length)
return false;
if (ownerHash.equals(nextHash))

@@ -125,3 +129,3 @@ return false;

const owner = rr.name.toUpperCase();
const owner = rr.name;
const label = util.split(owner);

@@ -134,7 +138,10 @@

const ownerZone = owner.substring(label[1]);
const ownerHash = base32.decodeHex(owner32.toLowerCase());
const ownerHash = base32.decodeHex(owner32);
if (!util.isSubdomain(ownerZone, name.toUpperCase()))
if (ownerHash.length !== nameHash.length)
return false;
if (!util.isSubdomain(ownerZone, name))
return false;
if (ownerHash.equals(nameHash))

@@ -280,2 +287,3 @@ return true;

nsec3.hashes = hashes;
nsec3.hashes = nsecHashes;
nsec3.hashesByVal = nsecHashesByVal;

@@ -18,9 +18,5 @@ /*!

const OPENDNS_NS = [
'208.67.222.222',
'208.67.220.220',
'208.67.222.220',
'208.67.220.222',
'2620:0:ccc::2',
'2620:0:ccd::2'
const LOCAL_NS = [
'127.0.0.1',
'::1'
];

@@ -35,4 +31,10 @@

// Make eslint happy.
OPENDNS_NS;
const OPENDNS_NS = [
'208.67.222.222',
'208.67.220.220',
'208.67.222.220',
'208.67.220.222',
'2620:0:ccc::2',
'2620:0:ccd::2'
];

@@ -47,2 +49,3 @@ /**

this.ns6 = [];
this.keys = new Map();
this.domain = null;

@@ -65,9 +68,93 @@ this.search = null;

this.forceTCP = false;
this.init();
}
init() {
return this.setServers(GOOGLE_NS);
inject(conf) {
assert(conf instanceof this.constructor);
this.ns4 = conf.ns4.slice();
this.ns6 = conf.ns6.slice();
this.keys.clear();
for (const [key, pub] of conf.keys)
this.keys.set(key, pub);
this.domain = conf.domain;
if (conf.search)
this.search = conf.search.slice();
else
this.search = null;
this.sortlist = conf.sortlist.slice();
this.debug = conf.debug;
this.dots = conf.dots;
this.timeout = conf.timeout;
this.attempts = conf.attempts;
this.rotate = conf.rotate;
this.checkNames = conf.checkNames;
this.inet6 = conf.inet6;
this.byteString = conf.byteString;
this.dotInt = conf.dotInt;
this.edns = conf.edns;
this.singleRequest = conf.singleRequest;
this.singleRequestReopen = conf.singleRequestReopen;
this.tldQuery = conf.tldQuery;
this.forceTCP = conf.forceTCP;
return this;
}
clone() {
const copy = new this.constructor();
return copy.inject(this);
}
clear() {
this.ns4.length = 0;
this.ns6.length = 0;
this.keys.clear();
this.domain = null;
this.search = null;
this.sortlist = [];
this.debug = false;
this.dots = 1;
this.timeout = 5;
this.attempts = 2;
this.rotate = false;
this.checkNames = true;
this.inet6 = false;
this.byteString = false;
this.dotInt = false;
this.edns = false;
this.singleRequest = false;
this.singleRequestReopen = false;
this.tldQuery = true;
this.forceTCP = false;
return this;
}
getSystem() {
if (process.platform === 'win32')
return null;
return '/etc/resolv.conf';
}
getRaw(inet6) {
assert(typeof inet6 === 'boolean');
const servers = [];
for (const addr of this.ns4)
servers.push(addr);
if (inet6) {
for (const addr of this.ns6)
servers.push(addr);
}
return servers;
}
getServers() {

@@ -99,6 +186,25 @@ const servers = [];

this.ns6.length = 0;
this.keys.clear();
return this;
}
setDefault() {
return this.setGoogle();
}
setLocal() {
return this.setServers(LOCAL_NS);
}
setGoogle() {
return this.setServers(GOOGLE_NS);
}
setOpenDNS() {
return this.setServers(OPENDNS_NS);
}
randomServer(inet6) {
assert(typeof inet6 === 'boolean');
if (inet6 && this.ns6.length > 0)

@@ -118,8 +224,15 @@ return util.randomItem(this.ns6);

if (addr.type === 4)
this.ns4.push(addr);
else if (addr.type === 6)
this.ns6.push(addr);
else
throw new Error('Invalid address.');
switch (addr.type) {
case 4:
this.ns4.push(addr);
break;
case 6:
this.ns6.push(addr);
break;
default:
throw new Error('Invalid address.');
}
if (addr.key)
this.keys.set(addr.hostname, addr.key);
}

@@ -402,13 +515,15 @@

fromFile(file) {
let text;
readEnv() {
if (process.env.LOCALDOMAIN)
this.parseDomain(process.env.LOCALDOMAIN);
this.init();
if (process.env.RES_OPTIONS)
this.parseOptions(process.env.RES_OPTIONS);
try {
text = fs.readFileSync(file, 'utf8');
} catch (e) {
return this;
}
return this;
}
fromFile(file) {
assert(typeof file === 'string');
const text = fs.readFileSync(file, 'utf8');
return this.fromString(text);

@@ -422,13 +537,16 @@ }

fromSystem() {
if (process.platform === 'win32')
return this.init();
const file = this.getSystem();
this.fromFile('/etc/resolv.conf');
if (file) {
try {
this.fromFile(file);
} catch (e) {
this.setDefault();
}
} else {
this.setDefault();
}
if (process.env.LOCALDOMAIN)
this.parseDomain(process.env.LOCALDOMAIN);
this.readEnv();
if (process.env.RES_OPTIONS)
this.parseOptions(process.env.RES_OPTIONS);
return this;

@@ -440,2 +558,34 @@ }

}
async fromFileAsync(file) {
assert(typeof file === 'string');
const text = await fs.readFile(file, 'utf8');
return this.fromString(text);
}
static fromFileAsync(file) {
return new this().fromFileAsync(file);
}
async fromSystemAsync() {
const file = this.getSystem();
if (file) {
try {
await this.fromFileAsync(file);
} catch (e) {
this.setDefault();
}
} else {
this.setDefault();
}
this.readEnv();
return this;
}
static fromSystemAsync() {
return new this().fromSystemAsync();
}
}

@@ -442,0 +592,0 @@

@@ -31,2 +31,8 @@ /*!

/*
* Constants
*/
const DUMMY = Buffer.alloc(0);
/*
* Schemas

@@ -258,3 +264,3 @@ */

['algorithm', 'u8'],
['keyType', 'u8'],
['digestType', 'u8'],
['fingerprint', 'hex-end']

@@ -323,3 +329,3 @@ ];

['publicKey', 'base64'],
['rendezvousServers', 'servers']
['servers', 'servers']
];

@@ -396,16 +402,2 @@

const URISchema = [
['priority', 'u16'],
['weight', 'u16'],
['target', 'octet']
];
const CAASchema = [
['flag', 'u8'],
['tag', 'string'],
['value', 'octet']
];
const AVCSchema = TXTSchema;
const TKEYSchema = [

@@ -431,2 +423,24 @@ ['algorithm', 'name'],

const URISchema = [
['priority', 'u16'],
['weight', 'u16'],
['target', 'octet']
];
const CAASchema = [
['flag', 'u8'],
['tag', 'string'],
['value', 'octet']
];
const AVCSchema = TXTSchema;
const DOASchema = [
['enterprise', 'u32'],
['type', 'u32'],
['location', 'u8'],
['mediaType', 'octet'],
['data', 'base64-end']
];
const ANYSchema = UNKNOWNSchema;

@@ -491,2 +505,10 @@

const CHAINSchema = [
['trustPoint', 'name']
];
const KEYTAGSchema = [
['tags', 'tags']
];
const LOCALSchema = [

@@ -576,7 +598,8 @@ ['data', 'hex-end']

[types.EUI64]: EUI64Schema,
[types.TKEY]: TKEYSchema,
[types.TSIG]: TSIGSchema,
[types.URI]: URISchema,
[types.CAA]: CAASchema,
[types.AVC]: AVCSchema,
[types.TKEY]: TKEYSchema,
[types.TSIG]: TSIGSchema,
[types.DOA]: DOASchema,
[types.IXFR]: null,

@@ -598,3 +621,3 @@ [types.AXFR]: null,

const opts = {
[options.UNKNOWN]: UNKNOWNSchema,
[options.RESERVED]: UNKNOWNSchema,
[options.LLQ]: LLQSchema,

@@ -611,2 +634,4 @@ [options.UL]: ULSchema,

[options.PADDING]: PADDINGSchema,
[options.CHAIN]: CHAINSchema,
[options.KEYTAG]: KEYTAGSchema,
[options.LOCAL]: LOCALSchema,

@@ -645,8 +670,58 @@ [options.LOCALSTART]: LOCALSchema,

case 'txt':
case 'octet': {
const left = parts.slice(i).join(' ');
case 'tags': {
let j = i;
for (; j < parts.length; j++) {
const part = parts[j];
if (part.length > 0 && part[0] === ';')
break;
}
const left = parts.slice(i, j).join(' ');
rd[name] = readType(type, left);
i = len - 1;
break;
}
case 'octet': {
const start = i;
let quote = false;
let str = null;
for (; i < parts.length; i++) {
const part = parts[i];
for (let j = 0; j < part.length; j++) {
const ch = part[j];
if (ch === '\\') {
j += 1;
continue;
}
if (ch === '"') {
if (!quote) {
assert(i === start);
assert(j === 0);
quote = true;
continue;
}
assert(j === part.length - 1);
str = parts.slice(start, i + 1).join(' ');
}
}
if (str)
break;
}
assert(str);
rd[name] = readType(type, str);
break;
}
default: {

@@ -704,2 +779,4 @@ rd[name] = readType(type, part);

case 'hex': {
if (part === '-')
return DUMMY;
const data = Buffer.from(part, 'hex');

@@ -710,2 +787,4 @@ assert(data.length === (part.length >>> 1));

case 'hex-end': {
if (part === '-')
return DUMMY;
const hex = part.replace(/\s+/g, '');

@@ -717,5 +796,9 @@ const data = Buffer.from(hex, 'hex');

case 'base32': {
if (part === '-')
return DUMMY;
return base32.decodeHex(part);
}
case 'base64': {
if (part === '-')
return DUMMY;
assert(/^[A-Za-z0-9+\/=]+$/.test(part));

@@ -725,2 +808,4 @@ return Buffer.from(part, 'base64');

case 'base64-end': {
if (part === '-')
return DUMMY;
const b64 = part.replace(/\s+/g, '');

@@ -773,2 +858,11 @@ assert(/^[A-Za-z0-9+\/=]+$/.test(b64));

}
case 'tags': {
const tags = part.split(' ');
const out = [];
for (const tag of tags)
out.push(util.parseU16(tag));
return out;
}
case 'time': {

@@ -825,2 +919,4 @@ return stringToTime(part);

assert(Buffer.isBuffer(value));
if (value.length === 0)
return '-';
return value.toString('hex').toUpperCase();

@@ -831,2 +927,5 @@ }

if (value.length === 0)
return '-';
const hex = value.toString('hex').toUpperCase();

@@ -842,2 +941,4 @@ const out = [];

assert(Buffer.isBuffer(value));
if (value.length === 0)
return '-';
return base32.encodeHex(value).toUpperCase();

@@ -847,2 +948,4 @@ }

assert(Buffer.isBuffer(value));
if (value.length === 0)
return '-';
return value.toString('base64');

@@ -853,2 +956,5 @@ }

if (value.length === 0)
return '-';
const b64 = value.toString('base64');

@@ -893,2 +999,6 @@ const out = [];

}
case 'tags': {
assert(Array.isArray(value));
return value.join(' ');
}
case 'time': {

@@ -1026,2 +1136,14 @@ return timeToString(value);

}
case 'tags': {
assert(Array.isArray(value));
const out = [];
for (const tag of value) {
assert((tag & 0xffff) === tag);
out.push(tag);
}
return out;
}
case 'time': {

@@ -1111,2 +1233,6 @@ return value;

}
case 'tags': {
assert(Array.isArray(value));
return value;
}
case 'time': {

@@ -1113,0 +1239,0 @@ assert(typeof value === 'number' && value >= 0);

@@ -36,2 +36,3 @@ /*!

sig0.hashesByVal = dnssec.hashesByVal;
sig0.algHashes = dnssec.algHashes;
sig0.algToHash = dnssec.algToHash;

@@ -38,0 +39,0 @@ sig0.hashToHash = dnssec.hashToHash;

@@ -14,2 +14,3 @@ /*!

const assert = require('assert');
const IP = require('binet');
const {sizeName} = require('./encoding');

@@ -209,6 +210,6 @@ const util = exports;

if (ai >= 0x41 && ai <= 0x5a)
ai |= 0x61 - 0x41;
ai |= 0x20;
if (bi >= 0x41 && bi <= 0x5a)
bi |= 0x61 - 0x41;
bi |= 0x20;

@@ -651,1 +652,25 @@ if (ai !== bi)

};
util.isIP = function isIP(host) {
try {
IP.toBuffer(host);
return true;
} catch (e) {
return false;
}
};
util.id = function id() {
return (Math.random() * 0x10000) >>> 0;
};
util.sortRandom = function sortRandom(items) {
assert(Array.isArray(items));
if (items.length <= 1)
return items;
return items.slice().sort((a, b) => {
return Math.random() > 0.5 ? 1 : -1;
});
};
{
"name": "bns",
"version": "0.0.5",
"version": "0.0.6",
"description": "DNS bike-shed",

@@ -5,0 +5,0 @@ "keywords": [

# bns
DNS library and recursive resolver for node.js, in pure javascript.
DNS library and validating recursive resolver for node.js, in pure javascript.

@@ -8,39 +8,76 @@ ## Example

``` bash
$ ./bin/rdig.js google.com
Querying google.com./255.
$ rdig.js www.ietf.org +dnssec +debug
Querying www.ietf.org./A.
Verifying zone change to [.]
Checking signatures...
Retrying over TCP (2001:503:ba3e::2:30): 19235.
Validated DNSSEC signatures.
Switching authority: [192.41.162.30] (c.gtld-servers.net.)
Switching zone: [.->com.]
Verifying zone change to [com.]
Switching authority: [2001:500:40::1] (d0.org.afilias-nst.org.)
Switching zone: [.->org.]
Verifying zone change to [org.]
Checking signatures...
Validated DNSSEC signatures.
Switching authority: [216.239.36.10] (ns3.google.com.)
Switching zone: [com.->google.com.]
Looking up NS: ns1.mia1.afilias-nst.info.
Looking up IPv6 nameserver for ns1.mia1.afilias-nst.info....
Querying ns1.mia1.afilias-nst.info./AAAA.
Verifying zone change to [.]
Checking signatures...
Cache hit for ./DNSKEY.
Validated DNSSEC signatures.
Switching authority: [199.254.48.1] (b0.info.afilias-nst.org.)
Switching zone: [.->info.]
Verifying zone change to [info.]
Checking signatures...
Validated DNSSEC signatures.
Validated NSEC3 delegation.
Switching authority: [2a01:8840:6::1] (d0.dig.afilias-nst.info.)
Switching zone: [info.->afilias-nst.info.]
Trust chain broken due to zone change.
Traversed zones: ., com., google.com. for google.com./255.
Finishing resolving google.com./255 (hops=2).
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 0
;; flags: qr ra, QUERY: 1, ANSWER: 15, AUTHORITY: 0, ADDITIONAL: 0
Traversed zones: ., info., afilias-nst.info. for ns1.mia1.afilias-nst.info./AAAA.
Picked nameserver: 2a01:8840:7::1.
Switching authority: [2a01:8840:7::1] (ns1.mia1.afilias-nst.info.)
Switching zone: [org.->ietf.org.]
Verifying zone change to [ietf.org.]
Checking signatures...
Validated DNSSEC signatures.
Found alias to: www.ietf.org.cdn.cloudflare.net.
Alias changing zone: [ietf.org.->.]
Verifying zone change to [.]
Checking signatures...
Cache hit for ./DNSKEY.
Validated DNSSEC signatures.
Switching authority: [192.54.112.30] (l.gtld-servers.net.)
Switching zone: [.->net.]
Verifying zone change to [net.]
Checking signatures...
Validated DNSSEC signatures.
Switching authority: [2400:cb00:2049:1::c629:de1f] (ns5.cloudflare.net.)
Switching zone: [net.->cloudflare.net.]
Verifying zone change to [cloudflare.net.]
Checking signatures...
Validated DNSSEC signatures.
Traversed zones: ., org., ietf.org., ., net., cloudflare.net. for www.ietf.org./A.
Finishing resolving www.ietf.org./A (hops=8).
; <<>> rdig.js 0.0.5 <<>> www.ietf.org +dnssec +debug
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28579
;; flags: qr ra ad, QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do, udp: 512
;; QUESTION SECTION:
; google.com. IN ANY
;www.ietf.org. IN A
;; ANSWER SECTION:
google.com. 300 IN A 172.217.0.46
google.com. 300 IN AAAA 2607:f8b0:4005:802::200e
google.com. 300 IN TXT "docusign=05958488-4752-4ef2-95eb-aa7ba8a3bd0e"
google.com. 600 IN MX 20 alt1.aspmx.l.google.com.
google.com. 345600 IN NS ns1.google.com.
google.com. 3600 IN TXT "v=spf1 include:_spf.google.com ~all"
google.com. 600 IN MX 40 alt3.aspmx.l.google.com.
google.com. 345600 IN NS ns3.google.com.
google.com. 600 IN MX 30 alt2.aspmx.l.google.com.
google.com. 86400 IN CAA 0 issue "pki.goog"
google.com. 600 IN MX 50 alt4.aspmx.l.google.com.
google.com. 60 IN SOA ns1.google.com. dns-admin.google.com. 188478103 900 900 1800 60
google.com. 600 IN MX 10 aspmx.l.google.com.
google.com. 345600 IN NS ns2.google.com.
google.com. 345600 IN NS ns4.google.com.
www.ietf.org. 1800 IN CNAME www.ietf.org.cdn.cloudflare.net.
www.ietf.org. 1800 IN RRSIG CNAME 5 3 1800 20190214160829 20180214150920 40452 ietf.org. OAS6hbpld1KpNJBpqg/T+0m0FpcVV933AbsDuVlgloHQfyVG4Ug5iOtK QLKGNYw+583Ba1yhFlFsYu4GNALZFpF8Tw5NcmxpmXJyzpeO0aj1rSCH oFQzYaIszrbw7TmE2pYQbh9QeklO9hILxi/Q1D7VxzrtHj0Ff8ncgFI7 6Ep+ud0Gysr0m/5MrwO69LGPV06LTuMRP3cXv7hqbjmyn2CmYR3h6+lQ +uiHSwkZYK20xhk+w1pOP9CD6fIqGYCJiKVaMY8K2lMQyi6Ppx0zOmtk MdaJjnxrzQ5TXbCcGQ48Rn4hzdug1MvkJzh1DGWZH6ZnPQTEf3+O1ehz +zSpbQ== ; alg = RSASHA1
www.ietf.org.cdn.cloudflare.net. 300 IN A 104.20.1.85
www.ietf.org.cdn.cloudflare.net. 300 IN A 104.20.0.85
www.ietf.org.cdn.cloudflare.net. 300 IN RRSIG A 13 6 300 20180329050317 20180327030317 35273 cloudflare.net. cp0elWqesQt1uNBhyhRd7Zpks7UzVc0xSqxTKBsKnpb7WWgdqZD/kq+s JWTE+POxzoJ2jSUhFSjWL4C+7o24KQ== ; alg = ECDSAP256SHA256
;; Query time: 766 msec
;; WHEN: Tue Mar 27 21:03:03 PDT 2018
;; MSG SIZE rcvd: 641
```

@@ -47,0 +84,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

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