1
0

add ANAME resolution

这个提交包含在:
AJ ONeal 2017-10-12 12:48:09 -06:00
父节点 d32dba2a75
当前提交 a089bfc8e5
共有 5 个文件被更改,包括 78 次插入4 次删除

查看文件

@ -155,6 +155,7 @@ module.exports = {
// A, AAAA // A, AAAA
, address: '127.0.0.1' , address: '127.0.0.1'
, aname: 'some-device.example.com' // See "A Note on ANAMEs" below
// CAA // CAA
, flag: 0 , flag: 0
@ -194,6 +195,14 @@ Note: Because it's possible to that delegated subdomains could have delegated su
original nameserver, **NS** records will be replaced with an SOA record if any of the NS records match any of original nameserver, **NS** records will be replaced with an SOA record if any of the NS records match any of
the server's primary nameservers or if vanity nameservers are used. the server's primary nameservers or if vanity nameservers are used.
### A Note on ANAMES
ANAMEs serve two purposes in this system:
1. Traditional ANAME. Just a CNAME that is automatically resolved to an A record for the "bare domain" problem, and efficiency.
2. Dynamic DNS. When a record on the system is updated, any records that match it by ANAME are also updated
TODO: use dns0x20 for ANAME resolutions
Other Resources Other Resources
--------------- ---------------

查看文件

@ -23,8 +23,16 @@ Send malformed packets (both as queries and as answers):
- compression pointers to wrong bits (throw error on non-ascii / unsafe chars) - compression pointers to wrong bits (throw error on non-ascii / unsafe chars)
Test that ANY queries return records of all types matching the domain Test that ANY queries return records of all types matching the domain
Test that A queries only return A records, not others matching the domain Test that A queries only return A records, not others matching the domain
Test that A queries for ANAME-enabled records (but no address) recurse (regardless of general recursion settings).
* 0-anames.example.com
* 1-aname.example.com
* 2-anames.example.com
Generally speaking test the cases of 0, 1, and 2 records of any given type (null case, single case, multi case)
``` ```
# Sample Data: # Sample Data:

查看文件

@ -367,6 +367,12 @@ cli.main(function (args, cli) {
// TODO get local answer first, if available // TODO get local answer first, if available
var path = require('path'); var path = require('path');
if (!cli.input) {
console.warn('[WARN] no db path given, must recurse if enabled');
recurse();
return;
}
require('../lib/dns-store').query(path.resolve(cli.input), query, function (err, resp) { require('../lib/dns-store').query(path.resolve(cli.input), query, function (err, resp) {
if (err) { console.log('[DEV] answer not found in local db, recursing'); console.error(err); recurse(); return; } if (err) { console.log('[DEV] answer not found in local db, recursing'); console.error(err); recurse(); return; }

查看文件

@ -11,7 +11,12 @@ var NXDOMAIN = 3;
var REFUSED = 5; var REFUSED = 5;
function getRecords(db, qname, cb) { function getRecords(db, qname, cb) {
var myRecords = db.records.filter(function (r) { var delMe = {};
var dns = require('dns');
// SECURITY XXX TODO var dig = require('dig.js/dns-request');
var count;
var myRecords = db.records.slice(0).filter(function (r) {
if ('string' !== typeof r.name) { if ('string' !== typeof r.name) {
return false; return false;
} }
@ -23,9 +28,52 @@ function getRecords(db, qname, cb) {
} }
}); });
process.nextTick(function () { function checkCount() {
cb(null, myRecords); count -= 1;
if (count <= 0) {
myRecords = myRecords.filter(function (r) {
return !delMe[r.id];
}); });
cb(null, myRecords);
}
}
function getRecord(r) {
// TODO allow multiple records to be returned(?)
return function (err, addresses) {
if (err || !addresses.length) {
r.id = r.id || Math.random();
delMe[r.id] = true;
} else if (addresses.length > 1) {
r._address = addresses[Math.floor(Math.random() * addresses.length)];
} else {
r._address = addresses[0];
}
checkCount();
};
}
count = myRecords.length;
myRecords.forEach(function (r) {
if (r.aname && !r.address) {
if ('A' === r.type) {
// SECURITY XXX TODO dig.resolveJson(query, opts);
dns.resolve4(r.aname, getRecord(r));
return;
}
if ('AAAA' === r.type) {
// SECURITY XXX TODO dig.resolveJson(query, opts);
dns.resolve6(r.aname, getRecord(r));
return;
}
}
checkCount();
});
if (!myRecords.length) {
checkCount();
}
} }
function dbToResourceRecord(r) { function dbToResourceRecord(r) {
@ -47,7 +95,7 @@ function dbToResourceRecord(r) {
*/ */
// A, AAAA // A, AAAA
, address: -1 !== [ 'A', 'AAAA' ].indexOf(r.type) ? (r.address || r.value) : undefined , address: -1 !== [ 'A', 'AAAA' ].indexOf(r.type) ? (r._address || r.address || r.value) : undefined
// CNAME, NS, PTR || TXT // CNAME, NS, PTR || TXT
, data: -1 !== [ 'CNAME', 'NS', 'PTR', 'TXT' ].indexOf(r.type) ? (r.data || r.value || r.values) : undefined , data: -1 !== [ 'CNAME', 'NS', 'PTR', 'TXT' ].indexOf(r.type) ? (r.data || r.value || r.values) : undefined

查看文件

@ -15,6 +15,9 @@ module.exports = {
, { "zone": "daplie.me", "name": "www.daplie.me", "tld": "me", "sld": "daplie", "sub": "www" , { "zone": "daplie.me", "name": "www.daplie.me", "tld": "me", "sld": "daplie", "sub": "www"
, "type": "A", "address": "23.228.168.108", "aname": "tardigrade.devices.daplie.me" } , "type": "A", "address": "23.228.168.108", "aname": "tardigrade.devices.daplie.me" }
, { "zone": "daplie.me", "name": "aname.daplie.me", "tld": "me", "sld": "daplie", "sub": "aname"
, "type": "A", "aname": "google.com" }
, { "zone": "daplie.me", "name": "email.daplie.me", "tld": "me", "sld": "daplie", "sub": "email" , { "zone": "daplie.me", "name": "email.daplie.me", "tld": "me", "sld": "daplie", "sub": "email"
, "type": "CNAME", "data": "mailgun.org" } , "type": "CNAME", "data": "mailgun.org" }