'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.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(); };