add ANAME resolution
This commit is contained in:
		
							parent
							
								
									d32dba2a75
								
							
						
					
					
						commit
						a089bfc8e5
					
				@ -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
 | 
				
			||||||
---------------
 | 
					---------------
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										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)
 | 
					  - 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" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user