WIP dns server

This commit is contained in:
AJ ONeal 2017-09-25 18:14:27 -06:00
parent 083df5755b
commit fcaafbf8b9
4 changed files with 106 additions and 32 deletions

View File

@ -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('');
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);
});
};

View File

@ -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);
}

10
dns-store.js Normal file
View File

@ -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.'));
});
};
}());

View File

@ -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"
}
}