made the mDNS module able to adapt to changes in config

This commit is contained in:
tigerbot 2017-10-27 12:56:09 -06:00
parent c132861cab
commit c697008573
4 changed files with 88 additions and 34 deletions

View File

@ -301,13 +301,12 @@ module.exports.create = function (deps, config) {
mainPort = Object.keys(unforwarded).map(Number).sort((a, b) => a - b)[0]; mainPort = Object.keys(unforwarded).map(Number).sort((a, b) => a - b)[0];
} }
} }
updateConf(); updateConf();
if (!config.mdns.disabled) {
require('./mdns').start(deps, config, mainPort);
}
return { var result = {
updateConf updateConf
}; };
Object.defineProperty(result, 'mainPort', {enumerable: true, get: () => mainPort});
return result;
}; };

View File

@ -2,6 +2,7 @@
var PromiseA = require('bluebird'); var PromiseA = require('bluebird');
var queryName = '_cloud._tcp.local'; var queryName = '_cloud._tcp.local';
var dnsSuite = require('dns-suite');
function createResponse(name, ownerIds, packet, ttl, mainPort) { function createResponse(name, ownerIds, packet, ttl, mainPort) {
var rpacket = { var rpacket = {
@ -85,20 +86,19 @@ function createResponse(name, ownerIds, packet, ttl, mainPort) {
}); });
}); });
return require('dns-suite').DNSPacket.write(rpacket); return dnsSuite.DNSPacket.write(rpacket);
} }
module.exports.start = function (deps, config, mainPort) { module.exports.create = function (deps, config) {
var socket = require('dgram').createSocket({ type: 'udp4', reuseAddr: true }); var socket;
var dns = require('dns-suite');
var nextBroadcast = -1; var nextBroadcast = -1;
socket.on('message', function (message, rinfo) { function handlePacket(message, rinfo) {
// console.log('Received %d bytes from %s:%d', message.length, rinfo.address, rinfo.port); // console.log('Received %d bytes from %s:%d', message.length, rinfo.address, rinfo.port);
var packet; var packet;
try { try {
packet = dns.DNSPacket.parse(message); packet = dnsSuite.DNSPacket.parse(message);
} }
catch (er) { catch (er) {
// `dns-suite` actually errors on a lot of the packets floating around in our network, // `dns-suite` actually errors on a lot of the packets floating around in our network,
@ -108,16 +108,12 @@ module.exports.start = function (deps, config, mainPort) {
} }
// Only respond to queries. // Only respond to queries.
if (packet.header.qr !== 0) { if (packet.header.qr !== 0) { return; }
return;
}
// Only respond if they were asking for cloud devices. // Only respond if they were asking for cloud devices.
if (packet.question.length !== 1 || packet.question[0].name !== queryName) { if (packet.question.length !== 1) { return; }
return; if (packet.question[0].name !== queryName) { return; }
} if (packet.question[0].typeName !== 'PTR') { return; }
if (packet.question[0].typeName !== 'PTR' || packet.question[0].className !== 'IN' ) { if (packet.question[0].className !== 'IN' ) { return; }
return;
}
var proms = [ var proms = [
deps.storage.mdnsId.get() deps.storage.mdnsId.get()
@ -131,7 +127,7 @@ module.exports.start = function (deps, config, mainPort) {
]; ];
PromiseA.all(proms).then(function (results) { PromiseA.all(proms).then(function (results) {
var resp = createResponse(results[0], results[1], packet, config.mdns.ttl, mainPort); var resp = createResponse(results[0], results[1], packet, config.mdns.ttl, deps.tcp.mainPort);
var now = Date.now(); var now = Date.now();
if (now > nextBroadcast) { if (now > nextBroadcast) {
socket.send(resp, config.mdns.port, config.mdns.broadcast); socket.send(resp, config.mdns.port, config.mdns.broadcast);
@ -140,7 +136,14 @@ module.exports.start = function (deps, config, mainPort) {
socket.send(resp, rinfo.port, rinfo.address); socket.send(resp, rinfo.port, rinfo.address);
} }
}); });
}); }
function start() {
socket = require('dgram').createSocket({ type: 'udp4', reuseAddr: true });
socket.on('message', handlePacket);
return new Promise(function (resolve, reject) {
socket.once('error', reject);
socket.bind(config.mdns.port, function () { socket.bind(config.mdns.port, function () {
var addr = this.address(); var addr = this.address();
@ -153,5 +156,47 @@ module.exports.start = function (deps, config, mainPort) {
// much more difficult for someone to use us as part of a DDoS attack by // much more difficult for someone to use us as part of a DDoS attack by
// spoofing the UDP address a request came from. // spoofing the UDP address a request came from.
socket.setTTL(1); socket.setTTL(1);
socket.removeListener('error', reject);
resolve();
}); });
});
}
function stop() {
return new Promise(function (resolve, reject) {
socket.once('error', reject);
socket.close(function () {
socket.removeListener('error', reject);
socket = null;
resolve();
});
});
}
function updateConf() {
var promise;
if (config.mdns.disabled) {
if (socket) {
promise = stop();
}
} else {
if (!socket) {
promise = start();
} else if (socket.address().port !== config.mdns.port) {
promise = stop().then(start);
} else {
// Can't check membership, so just add the current broadcast address to make sure
// it's set. Hopefully nothing bad happens by adding multiple addresses or adding
// the same address multiple times.
socket.addMembership(config.mdns.broadcast);
promise = Promise.resolve();
}
}
}
updateConf();
return {
updateConf
};
}; };

View File

@ -51,6 +51,7 @@ function create(conf) {
, proxy: require('./proxy-conn').create(deps, conf) , proxy: require('./proxy-conn').create(deps, conf)
, socks5: require('./socks5-server').create(deps, conf) , socks5: require('./socks5-server').create(deps, conf)
, ddns: require('./ddns').create(deps, conf) , ddns: require('./ddns').create(deps, conf)
, mdns: require('./mdns').create(deps, conf)
, udp: require('./udp').create(deps, conf) , udp: require('./udp').create(deps, conf)
, tcp: require('./goldilocks').create(deps, conf) , tcp: require('./goldilocks').create(deps, conf)
}; };

11
package-lock.json generated
View File

@ -448,7 +448,11 @@
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
}, },
"dns-suite": { "dns-suite": {
"version": "git+https://git@git.daplie.com/Daplie/dns-suite#950867c452323da776c050363b22d8f06a8ed414" "version": "git+https://git@git.daplie.com/Daplie/dns-suite#6352cf4b516d94f0283c9c7cd024431bf974f049",
"requires": {
"bluebird": "3.5.0",
"hexdump.js": "1.0.5"
}
}, },
"duplexer2": { "duplexer2": {
"version": "0.1.4", "version": "0.1.4",
@ -820,6 +824,11 @@
"sntp": "1.0.9" "sntp": "1.0.9"
} }
}, },
"hexdump.js": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/hexdump.js/-/hexdump.js-1.0.5.tgz",
"integrity": "sha1-xbxlSoIvAzjzEX5fXzVgZd6HmDQ="
},
"hmac-drbg": { "hmac-drbg": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",