WIP dns server
This commit is contained in:
parent
083df5755b
commit
fcaafbf8b9
117
bin/digd.js
117
bin/digd.js
|
@ -4,10 +4,10 @@ var cli = require('cli');
|
|||
var dig = require('../dns-request');
|
||||
var dgram = require('dgram');
|
||||
var dnsjs = require('dns-suite');
|
||||
var hexdump = require('hexdump.js').hexdump;
|
||||
var crypto = require('crypto');
|
||||
var common = require('../common');
|
||||
var defaultNameservers = require('dns').getServers();
|
||||
var hexdump;
|
||||
|
||||
cli.parse({
|
||||
// 'b': [ false, 'set source IP address (defaults to 0.0.0.0)', 'string' ]
|
||||
|
@ -81,18 +81,37 @@ cli.main(function (args, cli) {
|
|||
|
||||
handlers.onMessage = function (nb, rinfo) {
|
||||
var queryAb = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength);
|
||||
var query = dnsjs.DNSPacket.parse(queryAb);
|
||||
var newQuery;
|
||||
var query;
|
||||
var count;
|
||||
|
||||
try {
|
||||
query = dnsjs.DNSPacket.parse(queryAb);
|
||||
} catch(e) {
|
||||
// TODO log bad queries (?)
|
||||
console.error("Could not parse DNS query, ignoring.");
|
||||
try {
|
||||
hexdump = require('hexdump.js').hexdump;
|
||||
console.error(hexdump(queryAb));
|
||||
console.error('');
|
||||
} catch(e) {
|
||||
// ignore
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (cli.debug) {
|
||||
console.log('');
|
||||
console.log('DNS Question:');
|
||||
console.log('');
|
||||
console.log(query);
|
||||
console.log('');
|
||||
console.log(hexdump(queryAb));
|
||||
console.log('');
|
||||
try {
|
||||
hexdump = require('hexdump.js').hexdump;
|
||||
console.log(hexdump(queryAb));
|
||||
console.log('');
|
||||
} catch(e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
dig.logQuestion(query);
|
||||
|
@ -138,17 +157,18 @@ cli.main(function (args, cli) {
|
|||
//common.writeResponse(opts, query, nb, packet);
|
||||
}
|
||||
|
||||
function sendEmptyResponse(query) {
|
||||
var newQuery = {
|
||||
function sendEmptyResponse(query, nx) {
|
||||
var newAb;
|
||||
var emptyResp = {
|
||||
header: {
|
||||
id: query.header.id // require('crypto').randomBytes(2).readUInt16BE(0)
|
||||
, qr: 1
|
||||
, opcode: 0
|
||||
, aa: 0 // TODO maybe
|
||||
, aa: 0 // TODO it may be authoritative
|
||||
, tc: 0
|
||||
, rd: query.header.rd
|
||||
, ra: cli.norecurse ? 0 : 1
|
||||
, rcode: 0 // no error
|
||||
, ra: cli.norecurse ? 0 : 1 // TODO is this bit dependent on the rd bit?
|
||||
, rcode: nx ? 3 : 0 // no error
|
||||
}
|
||||
, question: []
|
||||
, answer: []
|
||||
|
@ -156,7 +176,7 @@ cli.main(function (args, cli) {
|
|||
, additional: []
|
||||
};
|
||||
query.question.forEach(function (q) {
|
||||
newQuery.question.push({
|
||||
emptyResp.question.push({
|
||||
name: q.name
|
||||
, type: q.type
|
||||
, typeName: q.typeName
|
||||
|
@ -164,26 +184,52 @@ cli.main(function (args, cli) {
|
|||
, className: q.className
|
||||
});
|
||||
});
|
||||
server.send(dnsjs.DNSPacket.write(newQuery), rinfo.port, rinfo.address, function () {
|
||||
console.log('[DEV] response sent');
|
||||
|
||||
try {
|
||||
newAb = dnsjs.DNSPacket.write(emptyResp);
|
||||
} catch(e) {
|
||||
console.error("Could not write DNS response");
|
||||
console.error(emptyResp);
|
||||
return;
|
||||
}
|
||||
|
||||
server.send(newAb, rinfo.port, rinfo.address, function () {
|
||||
console.log('[DEV] response sent (empty)');
|
||||
});
|
||||
}
|
||||
|
||||
function sendResponse(newPacket) {
|
||||
var newAb;
|
||||
|
||||
try {
|
||||
newAb = dnsjs.DNSPacket.write(newPacket);
|
||||
} catch(e) {
|
||||
console.error("Could not write DNS response");
|
||||
console.error(newPacket);
|
||||
return;
|
||||
}
|
||||
|
||||
server.send(newAb, rinfo.port, rinfo.address, function () {
|
||||
console.log('[DEV] response sent (local query)');
|
||||
});
|
||||
}
|
||||
|
||||
function recurse() {
|
||||
if (!query.header.rd) {
|
||||
console.log("[Could not answer. Sent empty response.]");
|
||||
sendEmptyResponse(query);
|
||||
sendEmptyResponse(query, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cli.norecurse) {
|
||||
console.log("[Could not answer. Sent empty response.]");
|
||||
sendEmptyResponse(query);
|
||||
sendEmptyResponse(query, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// ANY, A, AAAA, CNAME, MX, NAPTR, NS, PTR, SOA, SRV, TXT
|
||||
newQuery = {
|
||||
// TODO newQuery
|
||||
|
||||
var newResponse = {
|
||||
header: {
|
||||
id: query.header.id // require('crypto').randomBytes(2).readUInt16BE(0)
|
||||
, qr: 0
|
||||
|
@ -200,7 +246,7 @@ cli.main(function (args, cli) {
|
|||
, additional: []
|
||||
};
|
||||
query.question.forEach(function (q) {
|
||||
newQuery.question.push({
|
||||
newResponse.question.push({
|
||||
name: q.name
|
||||
, type: q.type
|
||||
, typeName: q.typeName
|
||||
|
@ -209,9 +255,19 @@ cli.main(function (args, cli) {
|
|||
});
|
||||
|
||||
function updateCount() {
|
||||
var newAb;
|
||||
count -= 1;
|
||||
|
||||
if (!count) {
|
||||
server.send(dnsjs.DNSPacket.write(newQuery), rinfo.port, rinfo.address, function () {
|
||||
try {
|
||||
newAb = dnsjs.DNSPacket.write(newResponse);
|
||||
} catch(e) {
|
||||
console.error("Could not write DNS response");
|
||||
console.error(newResponse);
|
||||
return;
|
||||
}
|
||||
|
||||
server.send(newAb, rinfo.port, rinfo.address, function () {
|
||||
console.log('[DEV] response sent');
|
||||
});
|
||||
}
|
||||
|
@ -225,29 +281,32 @@ cli.main(function (args, cli) {
|
|||
|
||||
(packet.answer||[]).forEach(function (a) {
|
||||
// TODO copy each relevant property
|
||||
console.log('ans', a);
|
||||
newQuery.answer.push(a);
|
||||
console.log('ans', JSON.stringify(a, null, 2));
|
||||
newResponse.answer.push(a);
|
||||
});
|
||||
(packet.authority||[]).forEach(function (a) {
|
||||
// TODO copy each relevant property
|
||||
console.log('auth', a);
|
||||
newQuery.authority.push(a);
|
||||
console.log('auth', JSON.stringify(a, null, 2));
|
||||
newResponse.authority.push(a);
|
||||
});
|
||||
(packet.additional||[]).forEach(function (a) {
|
||||
// TODO copy each relevant property
|
||||
console.log('add', a);
|
||||
newQuery.additional.push(a);
|
||||
console.log('add', JSON.stringify(a, null, 2));
|
||||
newResponse.additional.push(a);
|
||||
});
|
||||
|
||||
updateCount();
|
||||
|
||||
}
|
||||
, onListening: function () {}
|
||||
, onSent: function (res) {
|
||||
, onSent: function (/*res*/) {
|
||||
/*
|
||||
if (cli.debug) {
|
||||
console.log('');
|
||||
console.log('request sent to', res.nameserver);
|
||||
}
|
||||
*/
|
||||
console.log('[DEV] response sent (recurse)');
|
||||
}
|
||||
, onTimeout: function (res) {
|
||||
console.log(";; [" + q.name + "] connection timed out; no servers could be reached");
|
||||
|
@ -276,7 +335,11 @@ cli.main(function (args, cli) {
|
|||
}
|
||||
|
||||
// TODO get local answer first, if available
|
||||
recurse();
|
||||
require('../dns-store').query(query, function (err, resp) {
|
||||
if (err) { recurse(); return; }
|
||||
|
||||
sendResponse(resp);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -27,11 +27,10 @@ module.exports = {
|
|||
, 'PTR': function (q) {
|
||||
console.log(';' + q.name + '.', q.ttl, q.className, q.typeName, q.data);
|
||||
}
|
||||
/*
|
||||
, 'SOA': function (q) {
|
||||
console.log(';' + q.name + '.', q.ttl, q.className, q.typeName, q.data);
|
||||
// no ';' in authority section?
|
||||
console.log('' + q.name + '.', q.ttl, q.className, q.typeName, q.name_server, q.email_addr, q.sn, q.ref, q.ret, q.ex, q.nx);
|
||||
}
|
||||
*/
|
||||
, 'SRV': function (q) {
|
||||
console.log(';' + q.name + '.', q.ttl, q.className, q.typeName, q.priority + ' ' + q.weight + ' ' + q.port + ' ' + q.target);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
module.exports.query = function (query, cb) {
|
||||
process.nextTick(function () {
|
||||
cb(new Error('No local lookup method for DNS records defined.'));
|
||||
});
|
||||
};
|
||||
|
||||
}());
|
|
@ -40,7 +40,9 @@
|
|||
"homepage": "https://git.daplie.com/Daplie/dig.js",
|
||||
"dependencies": {
|
||||
"cli": "^1.0.1",
|
||||
"dns-suite": "git+https://git@git.daplie.com/Daplie/dns-suite#v1.1.0",
|
||||
"hexdump.js": "^1.0.2"
|
||||
"dns-suite": "git+https://git@git.daplie.com/Daplie/dns-suite#v1.1.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"hexdump.js": "git+https://git@git.daplie.com/Daplie/hexdump.js#master"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue