WIP dns server
Dieser Commit ist enthalten in:
		
							Ursprung
							
								
									083df5755b
								
							
						
					
					
						Commit
						fcaafbf8b9
					
				
							
								
								
									
										117
									
								
								bin/digd.js
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								bin/digd.js
									
									
									
									
									
								
							@ -4,10 +4,10 @@ var cli = require('cli');
 | 
				
			|||||||
var dig = require('../dns-request');
 | 
					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.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();
 | 
				
			||||||
 | 
					var hexdump;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cli.parse({
 | 
					cli.parse({
 | 
				
			||||||
//  'b': [ false, 'set source IP address (defaults to 0.0.0.0)', 'string' ]
 | 
					//  'b': [ false, 'set source IP address (defaults to 0.0.0.0)', 'string' ]
 | 
				
			||||||
@ -81,18 +81,37 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  handlers.onMessage = function (nb, rinfo) {
 | 
					  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;
 | 
				
			||||||
    var newQuery;
 | 
					 | 
				
			||||||
    var count;
 | 
					    var count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      query = dnsjs.DNSPacket.parse(queryAb);
 | 
				
			||||||
 | 
					    } catch(e) {
 | 
				
			||||||
 | 
					      // TODO log bad queries (?)
 | 
				
			||||||
 | 
					      console.error("Could not parse DNS query, ignoring.");
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        hexdump = require('hexdump.js').hexdump;
 | 
				
			||||||
 | 
					        console.error(hexdump(queryAb));
 | 
				
			||||||
 | 
					        console.error('');
 | 
				
			||||||
 | 
					      } catch(e) {
 | 
				
			||||||
 | 
					        // ignore
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (cli.debug) {
 | 
					    if (cli.debug) {
 | 
				
			||||||
      console.log('');
 | 
					      console.log('');
 | 
				
			||||||
      console.log('DNS Question:');
 | 
					      console.log('DNS Question:');
 | 
				
			||||||
      console.log('');
 | 
					      console.log('');
 | 
				
			||||||
      console.log(query);
 | 
					      console.log(query);
 | 
				
			||||||
      console.log('');
 | 
					      console.log('');
 | 
				
			||||||
      console.log(hexdump(queryAb));
 | 
					      try {
 | 
				
			||||||
      console.log('');
 | 
					        hexdump = require('hexdump.js').hexdump;
 | 
				
			||||||
 | 
					        console.log(hexdump(queryAb));
 | 
				
			||||||
 | 
					        console.log('');
 | 
				
			||||||
 | 
					      } catch(e) {
 | 
				
			||||||
 | 
					        // ignore
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dig.logQuestion(query);
 | 
					    dig.logQuestion(query);
 | 
				
			||||||
@ -138,17 +157,18 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
      //common.writeResponse(opts, query, nb, packet);
 | 
					      //common.writeResponse(opts, query, nb, packet);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function sendEmptyResponse(query) {
 | 
					    function sendEmptyResponse(query, nx) {
 | 
				
			||||||
      var newQuery = {
 | 
					      var newAb;
 | 
				
			||||||
 | 
					      var emptyResp = {
 | 
				
			||||||
        header: {
 | 
					        header: {
 | 
				
			||||||
          id: query.header.id // require('crypto').randomBytes(2).readUInt16BE(0)
 | 
					          id: query.header.id // require('crypto').randomBytes(2).readUInt16BE(0)
 | 
				
			||||||
        , qr: 1
 | 
					        , qr: 1
 | 
				
			||||||
        , opcode: 0
 | 
					        , opcode: 0
 | 
				
			||||||
        , aa: 0     // TODO maybe
 | 
					        , aa: 0     // TODO it may be authoritative
 | 
				
			||||||
        , tc: 0
 | 
					        , tc: 0
 | 
				
			||||||
        , rd: query.header.rd
 | 
					        , rd: query.header.rd
 | 
				
			||||||
        , ra: cli.norecurse ? 0 : 1
 | 
					        , ra: cli.norecurse ? 0 : 1 // TODO is this bit dependent on the rd bit?
 | 
				
			||||||
        , rcode: 0  // no error
 | 
					        , rcode: nx ? 3 : 0 // no error
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      , question: []
 | 
					      , question: []
 | 
				
			||||||
      , answer: []
 | 
					      , answer: []
 | 
				
			||||||
@ -156,7 +176,7 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
      , additional: []
 | 
					      , additional: []
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
      query.question.forEach(function (q) {
 | 
					      query.question.forEach(function (q) {
 | 
				
			||||||
        newQuery.question.push({
 | 
					        emptyResp.question.push({
 | 
				
			||||||
          name: q.name
 | 
					          name: q.name
 | 
				
			||||||
        , type: q.type
 | 
					        , type: q.type
 | 
				
			||||||
        , typeName: q.typeName
 | 
					        , typeName: q.typeName
 | 
				
			||||||
@ -164,26 +184,52 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
        , className: q.className
 | 
					        , className: q.className
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      server.send(dnsjs.DNSPacket.write(newQuery), rinfo.port, rinfo.address, function () {
 | 
					
 | 
				
			||||||
        console.log('[DEV] response sent');
 | 
					      try {
 | 
				
			||||||
 | 
					        newAb = dnsjs.DNSPacket.write(emptyResp);
 | 
				
			||||||
 | 
					      } catch(e) {
 | 
				
			||||||
 | 
					        console.error("Could not write DNS response");
 | 
				
			||||||
 | 
					        console.error(emptyResp);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      server.send(newAb, rinfo.port, rinfo.address, function () {
 | 
				
			||||||
 | 
					        console.log('[DEV] response sent (empty)');
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function sendResponse(newPacket) {
 | 
				
			||||||
 | 
					      var newAb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        newAb = dnsjs.DNSPacket.write(newPacket);
 | 
				
			||||||
 | 
					      } catch(e) {
 | 
				
			||||||
 | 
					        console.error("Could not write DNS response");
 | 
				
			||||||
 | 
					        console.error(newPacket);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      server.send(newAb, rinfo.port, rinfo.address, function () {
 | 
				
			||||||
 | 
					        console.log('[DEV] response sent (local query)');
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function recurse() {
 | 
					    function recurse() {
 | 
				
			||||||
      if (!query.header.rd) {
 | 
					      if (!query.header.rd) {
 | 
				
			||||||
        console.log("[Could not answer. Sent empty response.]");
 | 
					        console.log("[Could not answer. Sent empty response.]");
 | 
				
			||||||
        sendEmptyResponse(query);
 | 
					        sendEmptyResponse(query, true);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (cli.norecurse) {
 | 
					      if (cli.norecurse) {
 | 
				
			||||||
        console.log("[Could not answer. Sent empty response.]");
 | 
					        console.log("[Could not answer. Sent empty response.]");
 | 
				
			||||||
        sendEmptyResponse(query);
 | 
					        sendEmptyResponse(query, true);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // ANY, A, AAAA, CNAME, MX, NAPTR, NS, PTR, SOA, SRV, TXT
 | 
					      // TODO newQuery
 | 
				
			||||||
      newQuery = {
 | 
					
 | 
				
			||||||
 | 
					      var newResponse = {
 | 
				
			||||||
        header: {
 | 
					        header: {
 | 
				
			||||||
          id: query.header.id // require('crypto').randomBytes(2).readUInt16BE(0)
 | 
					          id: query.header.id // require('crypto').randomBytes(2).readUInt16BE(0)
 | 
				
			||||||
        , qr: 0
 | 
					        , qr: 0
 | 
				
			||||||
@ -200,7 +246,7 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
      , additional: []
 | 
					      , additional: []
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
      query.question.forEach(function (q) {
 | 
					      query.question.forEach(function (q) {
 | 
				
			||||||
        newQuery.question.push({
 | 
					        newResponse.question.push({
 | 
				
			||||||
          name: q.name
 | 
					          name: q.name
 | 
				
			||||||
        , type: q.type
 | 
					        , type: q.type
 | 
				
			||||||
        , typeName: q.typeName
 | 
					        , typeName: q.typeName
 | 
				
			||||||
@ -209,9 +255,19 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        function updateCount() {
 | 
					        function updateCount() {
 | 
				
			||||||
 | 
					          var newAb;
 | 
				
			||||||
          count -= 1;
 | 
					          count -= 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if (!count) {
 | 
					          if (!count) {
 | 
				
			||||||
            server.send(dnsjs.DNSPacket.write(newQuery), rinfo.port, rinfo.address, function () {
 | 
					            try {
 | 
				
			||||||
 | 
					              newAb = dnsjs.DNSPacket.write(newResponse);
 | 
				
			||||||
 | 
					            } catch(e) {
 | 
				
			||||||
 | 
					              console.error("Could not write DNS response");
 | 
				
			||||||
 | 
					              console.error(newResponse);
 | 
				
			||||||
 | 
					              return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            server.send(newAb, rinfo.port, rinfo.address, function () {
 | 
				
			||||||
              console.log('[DEV] response sent');
 | 
					              console.log('[DEV] response sent');
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
@ -225,29 +281,32 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            (packet.answer||[]).forEach(function (a) {
 | 
					            (packet.answer||[]).forEach(function (a) {
 | 
				
			||||||
              // TODO copy each relevant property
 | 
					              // TODO copy each relevant property
 | 
				
			||||||
              console.log('ans', a);
 | 
					              console.log('ans', JSON.stringify(a, null, 2));
 | 
				
			||||||
              newQuery.answer.push(a);
 | 
					              newResponse.answer.push(a);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            (packet.authority||[]).forEach(function (a) {
 | 
					            (packet.authority||[]).forEach(function (a) {
 | 
				
			||||||
              // TODO copy each relevant property
 | 
					              // TODO copy each relevant property
 | 
				
			||||||
              console.log('auth', a);
 | 
					              console.log('auth', JSON.stringify(a, null, 2));
 | 
				
			||||||
              newQuery.authority.push(a);
 | 
					              newResponse.authority.push(a);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            (packet.additional||[]).forEach(function (a) {
 | 
					            (packet.additional||[]).forEach(function (a) {
 | 
				
			||||||
              // TODO copy each relevant property
 | 
					              // TODO copy each relevant property
 | 
				
			||||||
              console.log('add', a);
 | 
					              console.log('add', JSON.stringify(a, null, 2));
 | 
				
			||||||
              newQuery.additional.push(a);
 | 
					              newResponse.additional.push(a);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            updateCount();
 | 
					            updateCount();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        , onListening: function () {}
 | 
					        , onListening: function () {}
 | 
				
			||||||
        , onSent: function (res) {
 | 
					        , onSent: function (/*res*/) {
 | 
				
			||||||
 | 
					            /*
 | 
				
			||||||
            if (cli.debug) {
 | 
					            if (cli.debug) {
 | 
				
			||||||
              console.log('');
 | 
					              console.log('');
 | 
				
			||||||
              console.log('request sent to', res.nameserver);
 | 
					              console.log('request sent to', res.nameserver);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            */
 | 
				
			||||||
 | 
					            console.log('[DEV] response sent (recurse)');
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        , onTimeout: function (res) {
 | 
					        , onTimeout: function (res) {
 | 
				
			||||||
            console.log(";; [" + q.name + "] connection timed out; no servers could be reached");
 | 
					            console.log(";; [" + q.name + "] connection timed out; no servers could be reached");
 | 
				
			||||||
@ -276,7 +335,11 @@ cli.main(function (args, cli) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO get local answer first, if available
 | 
					    // TODO get local answer first, if available
 | 
				
			||||||
    recurse();
 | 
					    require('../dns-store').query(query, function (err, resp) {
 | 
				
			||||||
 | 
					      if (err) { recurse(); return; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      sendResponse(resp);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -27,11 +27,10 @@ module.exports = {
 | 
				
			|||||||
  , 'PTR': function (q) {
 | 
					  , 'PTR': function (q) {
 | 
				
			||||||
      console.log(';' + q.name + '.', q.ttl, q.className, q.typeName, q.data);
 | 
					      console.log(';' + q.name + '.', q.ttl, q.className, q.typeName, q.data);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  /*
 | 
					 | 
				
			||||||
  , 'SOA': function (q) {
 | 
					  , 'SOA': function (q) {
 | 
				
			||||||
      console.log(';' + q.name + '.', q.ttl, q.className, q.typeName, q.data);
 | 
					      // no ';' in authority section?
 | 
				
			||||||
 | 
					      console.log('' + q.name + '.', q.ttl, q.className, q.typeName, q.name_server, q.email_addr, q.sn, q.ref, q.ret, q.ex, q.nx);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  */
 | 
					 | 
				
			||||||
  , 'SRV': function (q) {
 | 
					  , 'SRV': function (q) {
 | 
				
			||||||
      console.log(';' + q.name + '.', q.ttl, q.className, q.typeName, q.priority + ' ' + q.weight + ' ' + q.port + ' ' + q.target);
 | 
					      console.log(';' + q.name + '.', q.ttl, q.className, q.typeName, q.priority + ' ' + q.weight + ' ' + q.port + ' ' + q.target);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										10
									
								
								dns-store.js
									
									
									
									
									
										Normale Datei
									
								
							
							
						
						
									
										10
									
								
								dns-store.js
									
									
									
									
									
										Normale Datei
									
								
							@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					(function () {
 | 
				
			||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports.query = function (query, cb) {
 | 
				
			||||||
 | 
					  process.nextTick(function () {
 | 
				
			||||||
 | 
					    cb(new Error('No local lookup method for DNS records defined.'));
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}());
 | 
				
			||||||
@ -40,7 +40,9 @@
 | 
				
			|||||||
  "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"
 | 
					  },
 | 
				
			||||||
 | 
					  "optionalDependencies": {
 | 
				
			||||||
 | 
					    "hexdump.js": "git+https://git@git.daplie.com/Daplie/hexdump.js#master"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Laden…
	
	
			
			x
			
			
		
	
		In neuem Issue referenzieren
	
	Einen Benutzer sperren