digd.js/lib/tcpd.js

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