91 lines
2.0 KiB
JavaScript
91 lines
2.0 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
var electron = require('electron');
|
||
|
var dns = require('dns-suite');
|
||
|
var ipc = electron.ipcMain;
|
||
|
var win;
|
||
|
var socket;
|
||
|
var mdnsPort = 5353;
|
||
|
var broadcastAddr = '224.0.0.251';
|
||
|
var queryname = '_cloud._tcp.local';
|
||
|
|
||
|
function sendDeviceQuery() {
|
||
|
var id = require('crypto').randomBytes(2).readUInt16LE();
|
||
|
var rpacket = {
|
||
|
header: {
|
||
|
id: id,
|
||
|
qr: 0,
|
||
|
opcode: 0,
|
||
|
aa: 0,
|
||
|
tc: 0,
|
||
|
rd: 0,
|
||
|
ra: 0,
|
||
|
res1: 0,
|
||
|
res2: 0,
|
||
|
res3: 0,
|
||
|
rcode: 0,
|
||
|
},
|
||
|
question: [
|
||
|
{
|
||
|
name: queryname,
|
||
|
typeName: 'PTR',
|
||
|
className: 'IN',
|
||
|
},
|
||
|
],
|
||
|
};
|
||
|
|
||
|
var buf = dns.DNSPacket.write(rpacket);
|
||
|
socket.send(buf, mdnsPort, broadcastAddr, function () {
|
||
|
console.log('sent mDNS query', buf.toString('hex'));
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function handleAnswer(message/*, rinfo*/) {
|
||
|
// console.log('received %d bytes from %s:%d', message.length, rinfo.address, rinfo.port);
|
||
|
|
||
|
var packet;
|
||
|
try {
|
||
|
packet = dns.DNSPacket.parse(message);
|
||
|
} catch (error) {
|
||
|
// The majority of the packets collected just listening to our local network seem to
|
||
|
// throw exceptions, so don't bother logging them.
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
// We are only interested in responses
|
||
|
if (packet.header.qr !== 1) {
|
||
|
return;
|
||
|
}
|
||
|
// And we only want the responses to the question we send (should be sent back in response)
|
||
|
if (packet.question.length !== 1 || packet.question[0].name !== queryname) {
|
||
|
return;
|
||
|
}
|
||
|
win.webContents.send('deviceFound', packet);
|
||
|
}
|
||
|
|
||
|
function init(window) {
|
||
|
if (win) {
|
||
|
console.error("can't initialize device discovery multiple times");
|
||
|
return;
|
||
|
}
|
||
|
win = window;
|
||
|
|
||
|
socket = require('dgram').createSocket({ type: 'udp4', reuseAddr: true });
|
||
|
socket.on('message', handleAnswer);
|
||
|
|
||
|
socket.bind(mdnsPort, function () {
|
||
|
var addr = this.address();
|
||
|
console.log('mDNS device discovery bound on %s:%d', addr.address, addr.port);
|
||
|
|
||
|
socket.setBroadcast(true);
|
||
|
socket.addMembership(broadcastAddr);
|
||
|
});
|
||
|
|
||
|
ipc.on('startDeviceScan', sendDeviceQuery);
|
||
|
}
|
||
|
|
||
|
module.exports = {
|
||
|
init: init,
|
||
|
};
|