made the mDNS module able to adapt to changes in config
This commit is contained in:
parent
c132861cab
commit
c697008573
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
101
lib/mdns.js
101
lib/mdns.js
|
@ -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,18 +136,67 @@ module.exports.start = function (deps, config, mainPort) {
|
||||||
socket.send(resp, rinfo.port, rinfo.address);
|
socket.send(resp, rinfo.port, rinfo.address);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
socket.bind(config.mdns.port, function () {
|
function start() {
|
||||||
var addr = this.address();
|
socket = require('dgram').createSocket({ type: 'udp4', reuseAddr: true });
|
||||||
console.log('bound on UDP %s:%d for mDNS', addr.address, addr.port);
|
socket.on('message', handlePacket);
|
||||||
|
|
||||||
socket.setBroadcast(true);
|
return new Promise(function (resolve, reject) {
|
||||||
socket.addMembership(config.mdns.broadcast);
|
socket.once('error', reject);
|
||||||
// This is supposed to be a local device discovery mechanism, so we shouldn't
|
|
||||||
// need to hop through any gateways. This helps with security by making it
|
socket.bind(config.mdns.port, function () {
|
||||||
// much more difficult for someone to use us as part of a DDoS attack by
|
var addr = this.address();
|
||||||
// spoofing the UDP address a request came from.
|
console.log('bound on UDP %s:%d for mDNS', addr.address, addr.port);
|
||||||
socket.setTTL(1);
|
|
||||||
});
|
socket.setBroadcast(true);
|
||||||
|
socket.addMembership(config.mdns.broadcast);
|
||||||
|
// This is supposed to be a local device discovery mechanism, so we shouldn't
|
||||||
|
// need to hop through any gateways. This helps with security by making it
|
||||||
|
// much more difficult for someone to use us as part of a DDoS attack by
|
||||||
|
// spoofing the UDP address a request came from.
|
||||||
|
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
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
};
|
};
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in New Issue