From 2ab424feb69e468bf477d7e025e7f6453ed8b153 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Fri, 20 Oct 2017 11:37:04 -0600 Subject: [PATCH] NS records returned for sub and sub sub domains --- TESTS.md | 76 ++++++++++++++++++++++++++++++------------------ lib/dns-store.js | 39 ++++++++++++++++++------- 2 files changed, 76 insertions(+), 39 deletions(-) diff --git a/TESTS.md b/TESTS.md index b5ff288..6637e6c 100644 --- a/TESTS.md +++ b/TESTS.md @@ -33,18 +33,28 @@ Test that A queries for ANAME-enabled records (but no address) recurse (regardle Generally speaking test the cases of 0, 1, and 2 records of any given type (null case, single case, multi case) +### Variables + ``` port=65053 ns=localhost -digcmd="node bin/dig.js" -#digcmd="dig" + +# For the sake of accuracy, it's most important to test with the standard unix dig tool +digcmd="dig" + +# For the sake of completeness, it's important to test with our very own dig tool +#digcmd="node bin/dig.js" ``` +### Run the server + ``` # Serve: node bin/digd.js +norecurse -p $port --input sample/db.json ``` +### Manual Tests + ``` # Sample Data: # no A records for out-delegated.example.com @@ -54,15 +64,15 @@ node bin/digd.js +norecurse -p $port --input sample/db.json # Test: # should return NS records in AUTHORITY section, nothing else $digcmd @$ns -p $port A out-delegated.example.com -node bin/dig.js @$ns -p $port ANY out-delegated.example.com +$digcmd @$ns -p $port ANY out-delegated.example.com # should return SOA records in AUTHORITY section, nothing else -node bin/dig.js @$ns -p $port A in-delegated.example.com -node bin/dig.js @$ns -p $port ANY in-delegated.example.com +$digcmd @$ns -p $port A in-delegated.example.com +$digcmd @$ns -p $port ANY in-delegated.example.com # should return NS records in ANSWER section, nothing else -node bin/dig.js @$ns -p $port NS out-delegated.example.com -node bin/dig.js @$ns -p $port NS in-delegated.example.com +$digcmd @$ns -p $port NS out-delegated.example.com +$digcmd @$ns -p $port NS in-delegated.example.com # Sample Data: @@ -71,16 +81,16 @@ node bin/dig.js @$ns -p $port NS in-delegated.example.com # Test: # should return records in ANSWER section, nothing else -node bin/dig.js @$ns -p $port A example.com -node bin/dig.js @$ns -p $port AAAA example.com -node bin/dig.js @$ns -p $port MX example.com -node bin/dig.js @$ns -p $port SRV example.com -node bin/dig.js @$ns -p $port TXT example.com -node bin/dig.js @$ns -p $port ANY example.com +$digcmd @$ns -p $port A example.com +$digcmd @$ns -p $port AAAA example.com +$digcmd @$ns -p $port MX example.com +$digcmd @$ns -p $port SRV example.com +$digcmd @$ns -p $port TXT example.com +$digcmd @$ns -p $port ANY example.com # should return SOA records in AUTHORITY section, nothing else -node bin/dig.js @$ns -p $port A doesntexist.example.com -node bin/dig.js @$ns -p $port NS doesntexist.example.com +$digcmd @$ns -p $port A doesntexist.example.com +$digcmd @$ns -p $port NS doesntexist.example.com # Sample Data: @@ -89,23 +99,31 @@ node bin/dig.js @$ns -p $port NS doesntexist.example.com # Test: # should return record of correct type in ANSWER section, nothing else -node bin/dig.js @$ns -p $port A a.example.com -node bin/dig.js @$ns -p $port ANY a.example.com -node bin/dig.js @$ns -p $port AAAA aaaa.example.com -node bin/dig.js @$ns -p $port ANY aaaa.example.com -node bin/dig.js @$ns -p $port MX mx.example.com -node bin/dig.js @$ns -p $port ANY mx.example.com -node bin/dig.js @$ns -p $port SRV srv.example.com -node bin/dig.js @$ns -p $port ANY srv.example.com -node bin/dig.js @$ns -p $port TXT txt.example.com -node bin/dig.js @$ns -p $port ANY txt.example.com -node bin/dig.js @$ns -p $port TXT mtxt.example.com -node bin/dig.js @$ns -p $port ANY mtxt.example.com +$digcmd @$ns -p $port A a.example.com +$digcmd @$ns -p $port AAAA aaaa.example.com +$digcmd @$ns -p $port MX mx.example.com +$digcmd @$ns -p $port SRV srv.example.com +$digcmd @$ns -p $port TXT txt.example.com +$digcmd @$ns -p $port TXT mtxt.example.com + +# should return record of correct type in ANSWER section, and SOA / NS +$digcmd @$ns -p $port ANY a.example.com +$digcmd @$ns -p $port ANY aaaa.example.com +$digcmd @$ns -p $port ANY mx.example.com +$digcmd @$ns -p $port ANY srv.example.com +$digcmd @$ns -p $port ANY txt.example.com +$digcmd @$ns -p $port ANY mtxt.example.com + +# Test: +# all subdomains of a delegated domain should return NS for that domain +$digcmd @$ns -p 65053 ANY ns.example.com +$digcmd @$ns -p 65053 ANY foo.ns.example.com +$digcmd @$ns -p 65053 ANY bar.foo.ns.example.com # should return SOA record in AUTHORITY section, nothing else -node bin/dig.js @$ns -p $port A doesntexist.a.example.com +$digcmd @$ns -p $port A doesntexist.a.example.com # should return NS records in ANSWER section, nothing else -node bin/dig.js @$ns -p $port NS a.example.com +$digcmd @$ns -p $port NS a.example.com ``` diff --git a/lib/dns-store.js b/lib/dns-store.js index b60b8f4..952ebf1 100644 --- a/lib/dns-store.js +++ b/lib/dns-store.js @@ -114,9 +114,10 @@ function dbToResourceRecord(r) { } function getNs(db, ds, results, cb) { - console.log('[DEV] getNs entered'); + console.log('[DEV] getNs entered with domains', ds); var d = ds.shift(); + console.log('[DEV] trying another one', d); if (!d) { results.header.rcode = NXDOMAIN; @@ -298,6 +299,10 @@ module.exports.query = function (input, query, cb) { qarr.shift(); // first } + console.log('[DEV] getNsAlso?', getNsAlso); + console.log('[DEV] answerSoa?', answerSoa); + console.log('[DEV] qnames'); + console.log(qnames); var myDomains = db.domains.filter(function (d) { return -1 !== qnames.indexOf(d.id.toLowerCase()); }); @@ -325,7 +330,7 @@ module.exports.query = function (input, query, cb) { return getSoa(db, myDomains[0], results, cb, answerSoa); } - return getNs(db, myDomains.slice(0), results, function (err, results) { + return getNs(db, /*myDomains.slice(0)*/qnames.map(function (qn) { return { id: qn }; }), results, function (err, results) { //console.log('[DEV] getNs complete'); if (err) { cb(err, results); return; } @@ -352,6 +357,12 @@ module.exports.query = function (input, query, cb) { if (err) { cb(err); return; } + // There are two special cases + // NS records are returned as ANSWER for NS and ANY, and as AUTHORITY when an externally-delegated domain would return an SOA (no records) + // SOA records are returned as ANSWER for SOA and ANY, and as AUTHORITY when no records are found, but the domain is controlled here + + console.log("[DEV] has records"); + // filter out NS (delegation) records, unless that is what is intended someRecords = someRecords.filter(function (r) { // If it's not an NS record, it's a potential result @@ -359,21 +370,23 @@ module.exports.query = function (input, query, cb) { return true; } - // If the query was for NS, it's a potential result - if ('NS' === query.question[0].typeName) { - return true; - } + console.log("It's NS"); // If it's a vanity NS, it's not a valid NS for lookup if (-1 !== db.primaryNameservers.indexOf(r.data.toLowerCase())) { + console.log("It's a vanity NS"); return false; } + // If the query was for NS, it's a potential result + if ('ANY' === query.question[0].typeName || 'NS' === query.question[0].typeName) { + return true; + } + nsRecords.push(r); return false; }); - // TODO should NS be returned as ANSWER or AUTHORITY in ANY? myRecords = someRecords; if (255 !== query.question[0].type && 'ANY' !== query.question[0].typeName) { myRecords = myRecords.filter(function (r) { @@ -391,6 +404,11 @@ module.exports.query = function (input, query, cb) { }); results.header.rcode = NOERROR; //console.log('[DEV] ANSWER results', results); + + if (255 === query.question[0].type && 'ANY' === query.question[0].typeName) { + getNsAndSoa(false, true); + return; + } cb(null, results); return; } @@ -404,9 +422,10 @@ module.exports.query = function (input, query, cb) { return; } - if (!myRecords.length) { - getNsAndSoa(true); - } + console.log("[DEV] Gonna get NS and SOA"); + + // !myRecords.length + getNsAndSoa(true); }); };