WIP dns server, mov hexdump.js to own repo, add aaonly flag
This commit is contained in:
		
							parent
							
								
									cdd490ec42
								
							
						
					
					
						commit
						6d0f9b1588
					
				
							
								
								
									
										23
									
								
								bin/dig.js
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								bin/dig.js
									
									
									
									
									
								
							@ -38,6 +38,16 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (arg === '+aaonly' || arg === '+aaflag') {
 | 
				
			||||||
 | 
					      if (cli.aaonly) {
 | 
				
			||||||
 | 
					        console.error("'+aaonly' was specified more than once");
 | 
				
			||||||
 | 
					        process.exit(1);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      cli.aaonly = true;
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (arg === '+norecurse') {
 | 
					    if (arg === '+norecurse') {
 | 
				
			||||||
      if (cli.norecurse) {
 | 
					      if (cli.norecurse) {
 | 
				
			||||||
        console.error("'+norecurse' was specified more than once");
 | 
					        console.error("'+norecurse' was specified more than once");
 | 
				
			||||||
@ -69,7 +79,7 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (cli.query) {
 | 
					    if (cli.query) {
 | 
				
			||||||
      console.error("'query' was specified more than once");
 | 
					      console.error("'query' was specified more than once or unrecognized flag: " + cli.query + ", " + arg);
 | 
				
			||||||
      process.exit(1);
 | 
					      process.exit(1);
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -124,11 +134,11 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
      id: require('crypto').randomBytes(2).readUInt16BE(0)
 | 
					      id: require('crypto').randomBytes(2).readUInt16BE(0)
 | 
				
			||||||
    , qr: 0
 | 
					    , qr: 0
 | 
				
			||||||
    , opcode: 0
 | 
					    , opcode: 0
 | 
				
			||||||
    , aa: 0     // NA
 | 
					    , aa: cli.aaonly ? 1 : 0  // NA
 | 
				
			||||||
    , tc: 0     // NA
 | 
					    , tc: 0                   // NA
 | 
				
			||||||
    , rd: cli.norecurse ? 0 : 1
 | 
					    , rd: cli.norecurse ? 0 : 1
 | 
				
			||||||
    , ra: 0     // NA
 | 
					    , ra: 0                   // NA
 | 
				
			||||||
    , rcode: 0  // NA
 | 
					    , rcode: 0                // NA
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  , question: [
 | 
					  , question: [
 | 
				
			||||||
      { name: cli.query
 | 
					      { name: cli.query
 | 
				
			||||||
@ -140,7 +150,7 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  var dnsjs = require('dns-suite');
 | 
					  var dnsjs = require('dns-suite');
 | 
				
			||||||
  var queryAb = dnsjs.DNSPacket.write(query);
 | 
					  var queryAb = dnsjs.DNSPacket.write(query);
 | 
				
			||||||
  var hexdump = require('../hexdump');
 | 
					  var hexdump = require('hexdump.js').hexdump;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (cli.debug) {
 | 
					  if (cli.debug) {
 | 
				
			||||||
    console.log('');
 | 
					    console.log('');
 | 
				
			||||||
@ -254,5 +264,6 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
  , port: cli.port
 | 
					  , port: cli.port
 | 
				
			||||||
  , timeout: cli.timeout
 | 
					  , timeout: cli.timeout
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  dig.resolve(queryAb, opts);
 | 
					  dig.resolve(queryAb, opts);
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										156
									
								
								bin/digd.js
									
									
									
									
									
								
							
							
						
						
									
										156
									
								
								bin/digd.js
									
									
									
									
									
								
							@ -1,10 +1,10 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var cli = require('cli');
 | 
					var cli = require('cli');
 | 
				
			||||||
var dns = require('dns');
 | 
					var dig = require('../dns-request');
 | 
				
			||||||
var dgram = require('dgram');
 | 
					var dgram = require('dgram');
 | 
				
			||||||
var dnsjs = require('dns-suite');
 | 
					var dnsjs = require('dns-suite');
 | 
				
			||||||
var hexdump = require('../hexdump');
 | 
					var hexdump = require('hexdump.js').hexdump;
 | 
				
			||||||
var crypto = require('crypto');
 | 
					var crypto = require('crypto');
 | 
				
			||||||
var common = require('../common');
 | 
					var common = require('../common');
 | 
				
			||||||
var defaultNameservers = require('dns').getServers();
 | 
					var defaultNameservers = require('dns').getServers();
 | 
				
			||||||
@ -78,9 +78,12 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
    console.error("error:", err.stack);
 | 
					    console.error("error:", err.stack);
 | 
				
			||||||
    server.close();
 | 
					    server.close();
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  handlers.onMessage = function (nb) {
 | 
					
 | 
				
			||||||
 | 
					  handlers.onMessage = function (nb, rinfo) {
 | 
				
			||||||
    var queryAb = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength);
 | 
					    var queryAb = nb.buffer.slice(nb.byteOffset, nb.byteOffset + nb.byteLength);
 | 
				
			||||||
    var query = dnsjs.DNSPacket.parse(queryAb);
 | 
					    var query = dnsjs.DNSPacket.parse(queryAb);
 | 
				
			||||||
 | 
					    var newQuery;
 | 
				
			||||||
 | 
					    var count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (cli.debug) {
 | 
					    if (cli.debug) {
 | 
				
			||||||
      console.log('');
 | 
					      console.log('');
 | 
				
			||||||
@ -92,6 +95,8 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
      console.log('');
 | 
					      console.log('');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dig.logQuestion(query);
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
    console.log(';; Got question:');
 | 
					    console.log(';; Got question:');
 | 
				
			||||||
    console.log(';; ->>HEADER<<-');
 | 
					    console.log(';; ->>HEADER<<-');
 | 
				
			||||||
    console.log(JSON.stringify(query.header));
 | 
					    console.log(JSON.stringify(query.header));
 | 
				
			||||||
@ -100,6 +105,7 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
    query.question.forEach(function (q) {
 | 
					    query.question.forEach(function (q) {
 | 
				
			||||||
      console.log(';' + q.name + '.', ' ', q.className, q.typeName);
 | 
					      console.log(';' + q.name + '.', ' ', q.className, q.typeName);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function print(q) {
 | 
					    function print(q) {
 | 
				
			||||||
      var printer = common.printers[q.typeName] || common.printers.ANY;
 | 
					      var printer = common.printers[q.typeName] || common.printers.ANY;
 | 
				
			||||||
@ -132,19 +138,147 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
      //common.writeResponse(opts, query, nb, packet);
 | 
					      //common.writeResponse(opts, query, nb, packet);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!cli.norecurse) {
 | 
					    function sendEmptyResponse(query) {
 | 
				
			||||||
      // ANY, A, AAAA, CNAME, MX, NAPTR, NS, PTR, SOA, SRV, TXT
 | 
					      var newQuery = {
 | 
				
			||||||
      var count = query.question.length;
 | 
					        header: {
 | 
				
			||||||
 | 
					          id: query.header.id // require('crypto').randomBytes(2).readUInt16BE(0)
 | 
				
			||||||
 | 
					        , qr: 1
 | 
				
			||||||
 | 
					        , opcode: 0
 | 
				
			||||||
 | 
					        , aa: 0     // TODO maybe
 | 
				
			||||||
 | 
					        , tc: 0
 | 
				
			||||||
 | 
					        , rd: query.header.rd
 | 
				
			||||||
 | 
					        , ra: cli.norecurse ? 0 : 1
 | 
				
			||||||
 | 
					        , rcode: 0  // no error
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      , question: []
 | 
				
			||||||
 | 
					      , answer: []
 | 
				
			||||||
 | 
					      , authority: []
 | 
				
			||||||
 | 
					      , additional: []
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
      query.question.forEach(function (q) {
 | 
					      query.question.forEach(function (q) {
 | 
				
			||||||
        dns.resolve(q.name, q.typeName, function () {
 | 
					        newQuery.question.push({
 | 
				
			||||||
          count -= 1;
 | 
					          name: q.name
 | 
				
			||||||
          if (!count) {
 | 
					        , type: q.type
 | 
				
			||||||
          }
 | 
					        , typeName: q.typeName
 | 
				
			||||||
 | 
					        , class: q.class
 | 
				
			||||||
 | 
					        , className: q.className
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        console.log(';' + q.name + '.', ' ', q.className, q.typeName);
 | 
					      });
 | 
				
			||||||
 | 
					      server.send(dnsjs.DNSPacket.write(newQuery), rinfo.port, rinfo.address, function () {
 | 
				
			||||||
 | 
					        console.log('[DEV] response sent');
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    count = query.question.length;
 | 
				
			||||||
 | 
					    if (!count) {
 | 
				
			||||||
 | 
					      sendEmptyResponse(query);
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO get local answer first, if available
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (query.header.rd) {
 | 
				
			||||||
 | 
					      if (cli.norecurse) {
 | 
				
			||||||
 | 
					        console.log("[Could not answer. Sent empty response.]");
 | 
				
			||||||
 | 
					        sendEmptyResponse(query);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        // ANY, A, AAAA, CNAME, MX, NAPTR, NS, PTR, SOA, SRV, TXT
 | 
				
			||||||
 | 
					        newQuery = {
 | 
				
			||||||
 | 
					          header: {
 | 
				
			||||||
 | 
					            id: query.header.id // require('crypto').randomBytes(2).readUInt16BE(0)
 | 
				
			||||||
 | 
					          , qr: 0
 | 
				
			||||||
 | 
					          , opcode: 0
 | 
				
			||||||
 | 
					          , aa: query.header.aa ? 1 : 0 // NA? not sure what this would do
 | 
				
			||||||
 | 
					          , tc: 0     // NA
 | 
				
			||||||
 | 
					          , rd: 1
 | 
				
			||||||
 | 
					          , ra: 0     // NA
 | 
				
			||||||
 | 
					          , rcode: 0  // NA
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        , question: [
 | 
				
			||||||
 | 
					          /*
 | 
				
			||||||
 | 
					            { name: cli.query
 | 
				
			||||||
 | 
					            , typeName: cli.type
 | 
				
			||||||
 | 
					            , className: cli.class
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          */
 | 
				
			||||||
 | 
					          ]
 | 
				
			||||||
 | 
					        , answer: []
 | 
				
			||||||
 | 
					        , authority: []
 | 
				
			||||||
 | 
					        , additional: []
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        query.question.forEach(function (q) {
 | 
				
			||||||
 | 
					          newQuery.question.push({
 | 
				
			||||||
 | 
					            name: q.name
 | 
				
			||||||
 | 
					          , type: q.type
 | 
				
			||||||
 | 
					          , typeName: q.typeName
 | 
				
			||||||
 | 
					          , class: q.class
 | 
				
			||||||
 | 
					          , className: q.className
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          function updateCount() {
 | 
				
			||||||
 | 
					            count -= 1;
 | 
				
			||||||
 | 
					            if (!count) {
 | 
				
			||||||
 | 
					              server.send(dnsjs.DNSPacket.write(newQuery), rinfo.port, rinfo.address, function () {
 | 
				
			||||||
 | 
					                console.log('[DEV] response sent');
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          var opts = {
 | 
				
			||||||
 | 
					            onError: function () {
 | 
				
			||||||
 | 
					              updateCount();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          , onMessage: function (packet) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              (packet.answer||[]).forEach(function (a) {
 | 
				
			||||||
 | 
					                // TODO copy each relevant property
 | 
				
			||||||
 | 
					                console.log('ans', a);
 | 
				
			||||||
 | 
					                newQuery.answer.push(a);
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					              (packet.authority||[]).forEach(function (a) {
 | 
				
			||||||
 | 
					                // TODO copy each relevant property
 | 
				
			||||||
 | 
					                console.log('auth', a);
 | 
				
			||||||
 | 
					                newQuery.authority.push(a);
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					              (packet.additional||[]).forEach(function (a) {
 | 
				
			||||||
 | 
					                // TODO copy each relevant property
 | 
				
			||||||
 | 
					                console.log('add', a);
 | 
				
			||||||
 | 
					                newQuery.additional.push(a);
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              updateCount();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          , onListening: function () {}
 | 
				
			||||||
 | 
					          , onSent: function (res) {
 | 
				
			||||||
 | 
					              if (cli.debug) {
 | 
				
			||||||
 | 
					                console.log('');
 | 
				
			||||||
 | 
					                console.log('request sent to', res.nameserver);
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          , onTimeout: function (res) {
 | 
				
			||||||
 | 
					              console.log(";; [" + q.name + "] connection timed out; no servers could be reached");
 | 
				
			||||||
 | 
					              console.log(";; [timed out after " + res.timeout + "ms and 1 tries]");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          , onClose: function () {
 | 
				
			||||||
 | 
					              console.log('');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          , mdns: cli.mdns
 | 
				
			||||||
 | 
					          , nameserver: cli.nameserver
 | 
				
			||||||
 | 
					          , port: cli.port
 | 
				
			||||||
 | 
					          , timeout: cli.timeout
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          //dig.resolve(queryAb, opts);
 | 
				
			||||||
 | 
					          dig.resolveJson(query, opts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          console.log(';' + q.name + '.', ' ', q.className, q.typeName);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handlers.onListening = function () {
 | 
					  handlers.onListening = function () {
 | 
				
			||||||
    /*jshint validthis:true*/
 | 
					    /*jshint validthis:true*/
 | 
				
			||||||
    var server = this;
 | 
					    var server = this;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										27
									
								
								hexdump.js
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								hexdump.js
									
									
									
									
									
								
							@ -1,27 +0,0 @@
 | 
				
			|||||||
module.exports = function hexdump(ab) {
 | 
					 | 
				
			||||||
  var ui8 = new Uint8Array(ab);
 | 
					 | 
				
			||||||
  var bytecount = 0;
 | 
					 | 
				
			||||||
  var head = '        0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F';
 | 
					 | 
				
			||||||
  var trail;
 | 
					 | 
				
			||||||
  var str = [].slice.call(ui8).map(function (i) {
 | 
					 | 
				
			||||||
    var h = i.toString(16);
 | 
					 | 
				
			||||||
    if (h.length < 2) {
 | 
					 | 
				
			||||||
      h = '0' + h;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return h;
 | 
					 | 
				
			||||||
  }).join('').match(/.{1,2}/g).join(' ').match(/.{1,48}/g).map(function (str) {
 | 
					 | 
				
			||||||
    var lead = bytecount.toString(16);
 | 
					 | 
				
			||||||
    bytecount += 16;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while (lead.length < 7) {
 | 
					 | 
				
			||||||
      lead = '0' + lead;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return lead + ' ' + str;
 | 
					 | 
				
			||||||
  }).join('\n');
 | 
					 | 
				
			||||||
  trail = ab.byteLength.toString(16);
 | 
					 | 
				
			||||||
  while (trail.length < 7) {
 | 
					 | 
				
			||||||
    trail = '0' + trail;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return head + '\n' + str + '\n' + trail;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@ -40,6 +40,7 @@
 | 
				
			|||||||
  "homepage": "https://git.daplie.com/Daplie/dig.js",
 | 
					  "homepage": "https://git.daplie.com/Daplie/dig.js",
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "cli": "^1.0.1",
 | 
					    "cli": "^1.0.1",
 | 
				
			||||||
    "dns-suite": "git+https://git@git.daplie.com/Daplie/dns-suite#v1.1.0"
 | 
					    "dns-suite": "git+https://git@git.daplie.com/Daplie/dns-suite#v1.1.0",
 | 
				
			||||||
 | 
					    "hexdump.js": "^1.0.2"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user