add ANAME resolution
This commit is contained in:
		
							parent
							
								
									d32dba2a75
								
							
						
					
					
						commit
						a089bfc8e5
					
				@ -155,6 +155,7 @@ module.exports = {
 | 
			
		||||
 | 
			
		||||
      // A, AAAA
 | 
			
		||||
    , address: '127.0.0.1'
 | 
			
		||||
    , aname: 'some-device.example.com' // See "A Note on ANAMEs" below
 | 
			
		||||
 | 
			
		||||
      // CAA
 | 
			
		||||
    , 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
 | 
			
		||||
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
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								TESTS.md
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								TESTS.md
									
									
									
									
									
								
							@ -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)
 | 
			
		||||
 | 
			
		||||
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 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:
 | 
			
		||||
 | 
			
		||||
@ -367,6 +367,12 @@ cli.main(function (args, cli) {
 | 
			
		||||
 | 
			
		||||
    // TODO get local answer first, if available
 | 
			
		||||
    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) {
 | 
			
		||||
 | 
			
		||||
      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;
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
@ -23,9 +28,52 @@ function getRecords(db, qname, cb) {
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  process.nextTick(function () {
 | 
			
		||||
    cb(null, myRecords);
 | 
			
		||||
  function checkCount() {
 | 
			
		||||
    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) {
 | 
			
		||||
@ -47,7 +95,7 @@ function dbToResourceRecord(r) {
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    // 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
 | 
			
		||||
  , 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"
 | 
			
		||||
    , "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"
 | 
			
		||||
    , "type": "CNAME", "data": "mailgun.org" }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user