71 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			71 lines
		
	
	
		
			2.0 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) { | ||
|  |           var lenbuf = Buffer.from([ newAb.length >> 8, newAb.length & 255 ]); | ||
|  |           // TODO XXX generate legit error packet
 | ||
|  |           if (err) { console.error("Error", err); c.end(); return; } | ||
|  |           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); | ||
|  |       tcpServer.close(function () { | ||
|  |         setTimeout(runTcp, 1000); | ||
|  |       }); | ||
|  |     }); | ||
|  | 
 | ||
|  |     tcpServer.listen(cli.port, function () { | ||
|  |       console.log('TCP Server bound'); | ||
|  |     }); | ||
|  | 
 | ||
|  |     return tcpServer; | ||
|  |   } | ||
|  | 
 | ||
|  |   return runTcp(); | ||
|  | }; |