'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, };