diff --git a/index.html b/index.html
index d5a69c6..e0e4018 100644
--- a/index.html
+++ b/index.html
@@ -27,6 +27,13 @@
+
+
Device Discovery
+
+
+
+
+
diff --git a/index.js b/index.js
index eb097aa..c3c0dd9 100644
--- a/index.js
+++ b/index.js
@@ -36,6 +36,7 @@ function createWindow () {
require('./progress').init(win);
require('./drag-drop-main').init(win);
require('./startup-main').init(win);
+ require('./mdns-main').init(win);
// // Open the DevTools.
// win.webContents.openDevTools();
diff --git a/mdns-main.js b/mdns-main.js
new file mode 100644
index 0000000..efe222d
--- /dev/null
+++ b/mdns-main.js
@@ -0,0 +1,90 @@
+'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,
+};
diff --git a/mdns-render.js b/mdns-render.js
new file mode 100644
index 0000000..95c978e
--- /dev/null
+++ b/mdns-render.js
@@ -0,0 +1,14 @@
+'use strict';
+
+var electron = require('electron');
+var ipc = electron.ipcRenderer;
+
+ipc.on('deviceFound', function (e, packet) {
+ console.log(JSON.stringify(packet));
+});
+
+document.body.addEventListener('click', function (ev) {
+ if (ev.target.classList.contains('query-devices')) {
+ ipc.send('startDeviceScan');
+ }
+});
diff --git a/package.json b/package.json
index 53ae05d..ed1ab29 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"electron-packager": "^8.6.0"
},
"dependencies": {
- "auto-launch": "^5.0.1"
+ "auto-launch": "^5.0.1",
+ "dns-suite": "git+https://git@git.daplie.com:Daplie/dns-suite#v1"
}
}