AJ ONeal
6 years ago
4 changed files with 175 additions and 58 deletions
@ -0,0 +1,70 @@ |
|||
'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(); |
|||
}; |
@ -0,0 +1,58 @@ |
|||
'use strict'; |
|||
|
|||
module.exports.create = function (cli, dnsd) { |
|||
var server = require('dgram').createSocket({ |
|||
type: cli.udp6 ? 'udp6' : 'udp4' |
|||
, reuseAddr: true |
|||
}); |
|||
server.bind({ |
|||
port: cli.port |
|||
, address: cli.address |
|||
}); |
|||
|
|||
var handlers = {}; |
|||
handlers.onError = function (err) { |
|||
if ('EACCES' === err.code) { |
|||
console.error(""); |
|||
console.error("EACCES: Couldn't bind to port. You probably need to use sudo, authbind, or setcap."); |
|||
console.error(""); |
|||
process.exit(123); |
|||
return; |
|||
} |
|||
console.error("error:", err.stack); |
|||
server.close(); |
|||
}; |
|||
|
|||
handlers.onMessage = function (nb, rinfo) { |
|||
//console.log('[DEBUG] got a UDP message', nb.length);
|
|||
//console.log(nb.toString('hex'));
|
|||
|
|||
dnsd.onMessage(nb, function (err, newAb, dbgmsg) { |
|||
// TODO send legit error message
|
|||
if (err) { server.send(Buffer.from([0x00])); return; } |
|||
server.send(newAb, rinfo.port, rinfo.address, function () { |
|||
console.log(dbgmsg, rinfo.port, rinfo.address); |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
handlers.onListening = function () { |
|||
/*jshint validthis:true*/ |
|||
var server = this; |
|||
|
|||
if (cli.mdns || '224.0.0.251' === cli.nameserver) { |
|||
server.setBroadcast(true); |
|||
server.addMembership(cli.nameserver); |
|||
} |
|||
|
|||
console.log(''); |
|||
console.log('Bound and Listening:'); |
|||
console.log(server.address().address + '#' + server.address().port + ' (' + server.type + ')'); |
|||
}; |
|||
|
|||
server.on('error', handlers.onError); |
|||
server.on('message', handlers.onMessage); |
|||
server.on('listening', handlers.onListening); |
|||
|
|||
return server; |
|||
}; |
Loading…
Reference in new issue