73 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
module.exports.create = function (cli, dnsd) {
 | 
						|
  function runTcp() {
 | 
						|
    var tcpServer = require('net').createServer({ }, function (c) {
 | 
						|
      c.on('error', function (err) {
 | 
						|
        console.warn("TCP Connection Error:");
 | 
						|
        console.warn(err);
 | 
						|
      });
 | 
						|
      c.on('data', function (nb) {
 | 
						|
        //console.log('TCP data.length:', nb.length);
 | 
						|
        //console.log(nb.toString('hex'));
 | 
						|
 | 
						|
        // DNS packets include a 2-byte length header
 | 
						|
        var count = nb.length;
 | 
						|
        var length = nb[0] << 8;
 | 
						|
        length = length | nb[1];
 | 
						|
        count -= 2;
 | 
						|
        // TODO slice?
 | 
						|
        nb._dnsByteOffset = nb.byteOffset + 2;
 | 
						|
 | 
						|
        if (length !== count) {
 | 
						|
          console.error("Handling TCP packets > 512 bytes not implemented.");
 | 
						|
          c.end();
 | 
						|
          return;
 | 
						|
        }
 | 
						|
 | 
						|
        // TODO pad two bytes for lengths
 | 
						|
        dnsd.onMessage(nb, function (err, newAb, dbgmsg) {
 | 
						|
          // TODO XXX generate legit error packet
 | 
						|
          if (err) { console.error("Error", err); c.end(); return; }
 | 
						|
 | 
						|
          var lenbuf = Buffer.from([ newAb.length >> 8, newAb.length & 255 ]);
 | 
						|
          console.log('TCP ' + dbgmsg);
 | 
						|
 | 
						|
          c.write(lenbuf);
 | 
						|
          c.end(newAb);
 | 
						|
        });
 | 
						|
      });
 | 
						|
      c.on('end', function () {
 | 
						|
        console.log('TCP client disconnected from server');
 | 
						|
      });
 | 
						|
    });
 | 
						|
 | 
						|
    tcpServer.on('error', function (err) {
 | 
						|
      if ('EADDRINUSE' === err.code) {
 | 
						|
        console.error("Port '" + cli.port + "' is already in use.");
 | 
						|
        tcpServer.close();
 | 
						|
        process.exit(0);
 | 
						|
      }
 | 
						|
      if ('EACCES' === err.code) {
 | 
						|
        console.error("Could not bind on port '" + cli.port + "': EACCESS (you probably need root permissions)");
 | 
						|
        tcpServer.close();
 | 
						|
        process.exit(0);
 | 
						|
      }
 | 
						|
      console.error("TCP Server Error:");
 | 
						|
      console.error(err.stack);
 | 
						|
      tcpServer.close(function () {
 | 
						|
        setTimeout(runTcp, 1000);
 | 
						|
      });
 | 
						|
      //throw new Error(err);
 | 
						|
    });
 | 
						|
 | 
						|
    tcpServer.listen(cli.port, function () {
 | 
						|
      console.log(tcpServer.address().address + '#' + tcpServer.address().port + ' (tcp)');
 | 
						|
    });
 | 
						|
 | 
						|
    return tcpServer;
 | 
						|
  }
 | 
						|
 | 
						|
  return runTcp();
 | 
						|
};
 |