Comparing version 0.0.10 to 0.0.11
@@ -8,2 +8,4 @@ #!/usr/bin/env node | ||
const dns = require('../lib/dns'); | ||
const Hosts = require('../lib/hosts'); | ||
const ResolvConf = require('../lib/resolvconf'); | ||
const util = require('../lib/util'); | ||
@@ -15,2 +17,4 @@ | ||
let port = 53; | ||
let conf = null; | ||
let hosts = null; | ||
let inet6 = null; | ||
@@ -54,2 +58,10 @@ let reverse = false; | ||
break; | ||
case '--conf': | ||
conf = ResolvConf.fromFile(process.argv[i + 1]); | ||
i += 1; | ||
break; | ||
case '--hosts': | ||
hosts = Hosts.fromFile(process.argv[i + 1]); | ||
i += 1; | ||
break; | ||
case '-h': | ||
@@ -175,2 +187,4 @@ case '--help': | ||
port, | ||
conf, | ||
hosts, | ||
inet6, | ||
@@ -200,7 +214,7 @@ reverse, | ||
if (json) { | ||
console.error(err.message); | ||
process.stdout.error(err.message + '\n'); | ||
process.exit(1); | ||
} else { | ||
if (short) { | ||
process.stdout.write(err.message + '\n'); | ||
process.stdout.error(err.message + '\n'); | ||
} else { | ||
@@ -207,0 +221,0 @@ printHeader(host); |
@@ -6,2 +6,4 @@ #!/usr/bin/env node | ||
const pkg = require('../package.json'); | ||
const dns = require('../lib/dns'); | ||
const Hints = require('../lib/hints'); | ||
const rdns = require('../lib/rdns'); | ||
@@ -14,2 +16,4 @@ const util = require('../lib/util'); | ||
let port = 53; | ||
let hints = null; | ||
let anchors = null; | ||
let inet6 = null; | ||
@@ -53,2 +57,14 @@ let reverse = false; | ||
break; | ||
case '--hints': | ||
hints = Hints.fromFile(process.argv[i + 1]); | ||
i += 1; | ||
break; | ||
case '--anchor': | ||
if (process.argv[i + 1]) { | ||
if (!anchors) | ||
anchors = []; | ||
anchors.push(process.argv[i + 1]); | ||
} | ||
i += 1; | ||
break; | ||
case '-h': | ||
@@ -124,2 +140,10 @@ case '--help': | ||
async function lookup(name) { | ||
const options = { all: true, hints: dns.ADDRCONFIG }; | ||
const addrs = await dns.lookup(host, options); | ||
const inet4 = addrs.filter(addr => addr.family === 4); | ||
const {address} = util.randomItem(inet4); | ||
return address; | ||
} | ||
async function resolve(name, type, options) { | ||
@@ -154,7 +178,25 @@ const resolver = new rdns.Resolver(options); | ||
(async () => { | ||
let ns = 'hints.local.'; | ||
if (host && !util.isIP(host)) { | ||
ns = host; | ||
host = await lookup(host); | ||
} | ||
if (host && !hints) { | ||
hints = new Hints(); | ||
hints.addServer(ns, host); | ||
if (anchors) { | ||
for (const ds of anchors) | ||
hints.addAnchor(ds); | ||
} | ||
} | ||
if (hints) | ||
hints.port = port; | ||
const now = Date.now(); | ||
const res = await resolve(name, type, { | ||
host, | ||
port, | ||
hints, | ||
inet6, | ||
@@ -184,7 +226,7 @@ reverse, | ||
if (json) { | ||
console.error(err.message); | ||
process.stdout.error(err.message + '\n'); | ||
process.exit(1); | ||
} else { | ||
if (short) { | ||
process.stdout.write(err.message + '\n'); | ||
process.stdout.error(err.message + '\n'); | ||
} else { | ||
@@ -191,0 +233,0 @@ printHeader(host); |
@@ -17,4 +17,2 @@ /*! | ||
const assert = require('assert'); | ||
/** | ||
@@ -797,3 +795,3 @@ * Message Opcodes | ||
const tsigHashes = { | ||
const tsigAlgs = { | ||
MD5: 'hmac-md5.sig-alg.reg.int.', | ||
@@ -811,7 +809,7 @@ SHA1: 'hmac-sha1.', | ||
const tsigHashesByVal = { | ||
[tsigHashes.MD5]: 'MD5', | ||
[tsigHashes.SHA1]: 'SHA1', | ||
[tsigHashes.SHA256]: 'SHA256', | ||
[tsigHashes.SHA512]: 'SHA512' | ||
const tsigAlgsByVal = { | ||
[tsigAlgs.MD5]: 'MD5', | ||
[tsigAlgs.SHA1]: 'SHA1', | ||
[tsigAlgs.SHA256]: 'SHA256', | ||
[tsigAlgs.SHA512]: 'SHA512' | ||
}; | ||
@@ -871,5 +869,9 @@ | ||
function toSymbol(value, map, prefix, size) { | ||
assert((value & size) === value); | ||
function toSymbol(value, name, map, prefix, max, size) { | ||
if (typeof value !== 'number') | ||
throw new Error(`'${name}' must be a number.`); | ||
if ((value & max) !== value) | ||
throw new Error(`Invalid ${name}: ${value}.`); | ||
const symbol = map[value]; | ||
@@ -883,4 +885,5 @@ | ||
function fromSymbol(symbol, name, map, prefix, size) { | ||
assert(typeof symbol === 'string'); | ||
function fromSymbol(symbol, name, map, prefix, max, size) { | ||
if (typeof symbol !== 'string') | ||
throw new Error(`'${name}' must be a string.`); | ||
@@ -902,3 +905,3 @@ if (symbol.length > 64) | ||
if (symbol.length > prefix.length + size) | ||
throw new Error(`Unknown ${name}.`); | ||
throw new Error(`Unknown ${name}: ${symbol}.`); | ||
@@ -915,2 +918,5 @@ let word = 0; | ||
word += ch; | ||
if (word > max) | ||
throw new Error(`Unknown ${name}: ${symbol}.`); | ||
} | ||
@@ -921,58 +927,98 @@ | ||
function isSymbol(symbol, name, map, prefix, max, size) { | ||
if (typeof symbol !== 'string') | ||
throw new Error(`'${name}' must be a string.`); | ||
try { | ||
fromSymbol(symbol, name, map, prefix, max, size); | ||
return true; | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
function opcodeToString(opcode) { | ||
return toSymbol(opcode, opcodesByVal, 'OPCODE', 0x0f); | ||
return toSymbol(opcode, 'opcode', opcodesByVal, 'OPCODE', 0x0f, 2); | ||
} | ||
function stringToOpcode(symbol) { | ||
return fromSymbol(symbol, 'opcode', opcodes, 'OPCODE', 2) & 0x0f; | ||
return fromSymbol(symbol, 'opcode', opcodes, 'OPCODE', 0x0f, 2); | ||
} | ||
function isOpcodeString(symbol) { | ||
return isSymbol(symbol, 'opcode', opcodes, 'OPCODE', 0x0f, 2); | ||
} | ||
function codeToString(code) { | ||
return toSymbol(code, codesByVal, 'RCODE', 0x0f); | ||
return toSymbol(code, 'code', codesByVal, 'RCODE', 0x0f, 2); | ||
} | ||
function stringToCode(symbol) { | ||
return fromSymbol(symbol, 'code', codes, 'RCODE', 2) & 0x0f; | ||
return fromSymbol(symbol, 'code', codes, 'RCODE', 0x0fff, 4); | ||
} | ||
function isCodeString(symbol) { | ||
return isSymbol(symbol, 'code', codes, 'RCODE', 0x0fff, 4); | ||
} | ||
function typeToString(type) { | ||
return toSymbol(type, typesByVal, 'TYPE', 0xffff); | ||
return toSymbol(type, 'type', typesByVal, 'TYPE', 0xffff, 5); | ||
} | ||
function stringToType(symbol) { | ||
return fromSymbol(symbol, 'type', types, 'TYPE', 5); | ||
return fromSymbol(symbol, 'type', types, 'TYPE', 0xffff, 5); | ||
} | ||
function isTypeString(symbol) { | ||
return isSymbol(symbol, 'type', types, 'TYPE', 0xffff, 5); | ||
} | ||
function classToString(class_) { | ||
return toSymbol(class_, classesByVal, 'CLASS', 0xffff); | ||
return toSymbol(class_, 'class', classesByVal, 'CLASS', 0xffff, 5); | ||
} | ||
function stringToClass(symbol) { | ||
return fromSymbol(symbol, 'class', classes, 'CLASS', 5); | ||
return fromSymbol(symbol, 'class', classes, 'CLASS', 0xffff, 5); | ||
} | ||
function isClassString(symbol) { | ||
return isSymbol(symbol, 'class', classes, 'CLASS', 0xffff, 5); | ||
} | ||
function optionToString(option) { | ||
return toSymbol(option, optionsByVal, 'OPTION', 0xffff); | ||
return toSymbol(option, 'option', optionsByVal, 'OPTION', 0xffff, 5); | ||
} | ||
function stringToOption(symbol) { | ||
return fromSymbol(symbol, 'option', options, 'OPTION', 5); | ||
return fromSymbol(symbol, 'option', options, 'OPTION', 0xffff, 5); | ||
} | ||
function isOptionString(symbol) { | ||
return isSymbol(symbol, 'option', options, 'OPTION', 0xffff, 5); | ||
} | ||
function algToString(alg) { | ||
return toSymbol(alg, algsByVal, 'ALG', 0xff); | ||
return toSymbol(alg, 'algorithm', algsByVal, 'ALG', 0xff, 3); | ||
} | ||
function stringToAlg(symbol) { | ||
return fromSymbol(symbol, 'algorithm', algs, 'ALG', 3) & 0xff; | ||
return fromSymbol(symbol, 'algorithm', algs, 'ALG', 0xff, 3); | ||
} | ||
function isAlgString(symbol) { | ||
return isSymbol(symbol, 'algorithm', algs, 'ALG', 0xff, 3); | ||
} | ||
function hashToString(hash) { | ||
return toSymbol(hash, hashesByVal, 'HASH', 0xff); | ||
return toSymbol(hash, 'hash', hashesByVal, 'HASH', 0xff, 3); | ||
} | ||
function stringToHash(symbol) { | ||
return fromSymbol(symbol, 'hash', hashes, 'HASH', 3) & 0xff; | ||
return fromSymbol(symbol, 'hash', hashes, 'HASH', 0xff, 3); | ||
} | ||
function isHashString(symbol) { | ||
return isSymbol(symbol, 'hash', hashes, 'HASH', 0xff, 3); | ||
} | ||
/* | ||
@@ -1016,4 +1062,4 @@ * Expose | ||
exports.sshHashesByVal = sshHashesByVal; | ||
exports.tsigHashes = tsigHashes; | ||
exports.tsigHashesByVal = tsigHashesByVal; | ||
exports.tsigAlgs = tsigAlgs; | ||
exports.tsigAlgsByVal = tsigAlgsByVal; | ||
@@ -1029,13 +1075,26 @@ exports.YEAR68 = YEAR68; | ||
exports.stringToOpcode = stringToOpcode; | ||
exports.isOpcodeString = isOpcodeString; | ||
exports.codeToString = codeToString; | ||
exports.stringToCode = stringToCode; | ||
exports.isCodeString = isCodeString; | ||
exports.typeToString = typeToString; | ||
exports.stringToType = stringToType; | ||
exports.isTypeString = isTypeString; | ||
exports.classToString = classToString; | ||
exports.stringToClass = stringToClass; | ||
exports.isClassString = isClassString; | ||
exports.optionToString = optionToString; | ||
exports.stringToOption = stringToOption; | ||
exports.isOptionString = isOptionString; | ||
exports.algToString = algToString; | ||
exports.stringToAlg = stringToAlg; | ||
exports.isAlgString = isAlgString; | ||
exports.hashToString = hashToString; | ||
exports.stringToHash = stringToHash; | ||
exports.isHashString = isHashString; |
170
lib/hints.js
@@ -13,5 +13,8 @@ /*! | ||
const assert = require('assert'); | ||
const fs = require('bfile'); | ||
const IP = require('binet'); | ||
const Authority = require('./authority'); | ||
const constants = require('./constants'); | ||
const dnssec = require('./dnssec'); | ||
const util = require('./util'); | ||
const wire = require('./wire'); | ||
@@ -22,2 +25,3 @@ const {DNS_PORT} = constants; | ||
types, | ||
classes, | ||
Record, | ||
@@ -83,2 +87,9 @@ NSRecord, | ||
getSystem() { | ||
if (process.platform === 'win32') | ||
return null; | ||
return '/var/named/root.hint'; | ||
} | ||
setDefault() { | ||
@@ -101,2 +112,99 @@ return this.setRoot(); | ||
addServer(name, addr) { | ||
if (!util.isName(name)) | ||
throw new Error('Invalid name.'); | ||
if (!util.isIP(addr)) | ||
throw new Error('Invalid IP.'); | ||
name = name.toLowerCase(); | ||
name = util.fqdn(name); | ||
if (this.ns.indexOf(name) === -1) | ||
this.ns.push(name); | ||
const ip = IP.toBuffer(addr); | ||
if (IP.isIPv4(ip)) | ||
this.inet4.set(name, IP.toString(ip)); | ||
else | ||
this.inet6.set(name, IP.toString(ip)); | ||
return this; | ||
} | ||
removeServer(name) { | ||
if (!util.isName(name)) | ||
throw new Error('Invalid name.'); | ||
name = name.toLowerCase(); | ||
name = util.fqdn(name); | ||
const i = this.ns.indexOf(name); | ||
if (i === -1) | ||
return this; | ||
this.ns.splice(i, 1); | ||
this.inet4.delete(name); | ||
this.inet6.delete(name); | ||
return this; | ||
} | ||
addAnchor(ds) { | ||
if (typeof ds === 'string') | ||
ds = Record.fromString(ds); | ||
assert(ds instanceof Record); | ||
if (ds.type === types.DNSKEY) | ||
ds = dnssec.createDS(ds, dnssec.hashes.SHA256); | ||
assert(ds.type === types.DS); | ||
if (ds.name !== '.') | ||
throw new Error('Invalid anchor name.'); | ||
if (ds.class !== classes.IN) | ||
throw new Error('Invalid anchor class.'); | ||
ds = ds.clone(); | ||
if (ds.ttl === 0) | ||
ds.ttl = 3600000; | ||
this.anchors.push(ds); | ||
return this; | ||
} | ||
removeAnchor(ds) { | ||
if (typeof ds === 'string') | ||
ds = Record.fromString(ds); | ||
assert(ds instanceof Record); | ||
if (ds.type === types.DNSKEY) | ||
ds = dnssec.createDS(ds, dnssec.hashes.SHA256); | ||
assert(ds.type === types.DS); | ||
const raw = ds.data.encode(); | ||
let i; | ||
for (i = 0; i < this.anchors.length; i++) { | ||
const ds = this.anchors[i]; | ||
if (ds.data.encode().equals(raw)) | ||
break; | ||
} | ||
if (i === this.anchors.length) | ||
return this; | ||
this.anchors.splice(i, 1); | ||
return this; | ||
} | ||
getAuthority(inet6) { | ||
@@ -244,3 +352,3 @@ if (this.ns.length === 0) | ||
case types.DS: { | ||
this.anchors.push(rr); | ||
this.anchors.push(rr.clone()); | ||
break; | ||
@@ -294,2 +402,62 @@ } | ||
} | ||
fromFile(file) { | ||
assert(typeof file === 'string'); | ||
const text = fs.readFileSync(file, 'utf8'); | ||
return this.fromString(text); | ||
} | ||
static fromFile(file) { | ||
return new this().fromFile(file); | ||
} | ||
fromSystem() { | ||
const file = this.getSystem(); | ||
if (file) { | ||
try { | ||
this.fromFile(file); | ||
} catch (e) { | ||
this.setDefault(); | ||
} | ||
} else { | ||
this.setDefault(); | ||
} | ||
return this; | ||
} | ||
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 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(); | ||
} | ||
return this; | ||
} | ||
static fromSystemAsync() { | ||
return new this().fromSystemAsync(); | ||
} | ||
} | ||
@@ -296,0 +464,0 @@ |
@@ -356,3 +356,3 @@ /*! | ||
const msg = req.encode(); | ||
const tcp = msg.length >= 4096; | ||
const tcp = msg.length >= MAX_EDNS_SIZE; | ||
const query = new Query(req, servers, tcp); | ||
@@ -383,3 +383,3 @@ const {port, host} = query.server; | ||
if (this.edns) | ||
req.setEDNS(4096, this.dnssec); | ||
req.setEDNS(MAX_EDNS_SIZE, this.dnssec); | ||
@@ -386,0 +386,0 @@ return this.exchange(req, servers); |
@@ -10,2 +10,3 @@ /*! | ||
const assert = require('assert'); | ||
const constants = require('../constants'); | ||
const DNSResolver = require('./dns'); | ||
@@ -17,3 +18,3 @@ const encoding = require('../encoding'); | ||
const wire = require('../wire'); | ||
const {id} = util; | ||
const {MAX_EDNS_SIZE} = constants; | ||
@@ -94,3 +95,3 @@ const { | ||
res.id = id(); | ||
res.id = util.id(); | ||
res.opcode = opcodes.QUERY; | ||
@@ -106,3 +107,3 @@ res.code = codes.NOERROR; | ||
if (this.edns) | ||
res.setEDNS(4096, this.dnssec); | ||
res.setEDNS(MAX_EDNS_SIZE, this.dnssec); | ||
@@ -109,0 +110,0 @@ return res; |
{ | ||
"name": "bns", | ||
"version": "0.0.10", | ||
"version": "0.0.11", | ||
"description": "DNS bike-shed", | ||
@@ -21,3 +21,5 @@ "keywords": [ | ||
"dig.js": "./bin/dig.js", | ||
"rdig.js": "./bin/rdig.js" | ||
"rdig.js": "./bin/rdig.js", | ||
"named.js": "./bin/named.js", | ||
"rnamed.js": "./bin/rnamed.js" | ||
}, | ||
@@ -24,0 +26,0 @@ "scripts": { |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
389084
15407