node-tradfri-client
node-tradfri-client copied to clipboard
discoverGateway returns null when used across vlans(using a mdns reflector)
Hi
After moving my program using node-tradfri-client to another vlan/subnet. It is not able to discover the ikea gateway anymore(it still works when program and gateway are on the same subnet)
I have done some tests with mdns-server used by node-tradfri-client and I think there is some race in that which are causing this issue:
When I just do the same thing as node-tradfri-client does for the discoverGateway function. I never see the answer to the query _coap._udp.local
If I let my test program run still listening for response packets and then do a avahi-browse _coap._udp -d local (after setting up avahi) I can see that mdns-server actually gets the response packet and print it out (with the conditions that you use in node-tradfri-client - that the name should match _coap._udp.local)
I then put in some console.logs in the response part and in the query part. I can then see that we are inside the query part before the response/listening part. So I think mdns-server in some circumstances doesn't listen when the query is sent
Also when using the same testprogram on the same subnet it seems that mdns-server doesn't see all the response packages(I am not quite sure of this, but I think I saw fewer responses than when doing the query via avahi-browse)
I am not a very experienced with development in javascript, but I tried moving the 'ready' event around in mdns-server, but not with great success
This is the small test program I used for mdns-server:
var mdns = require('mdns-server')({
reuseAddr: true, // in case other mdns service is running
loopback: false, // receive our own mdns messages
noInit: true // do not initialize on creation
})
domain = '_coap._udp.local'
mdns.on("response", (resp) => {
console.log("In response");
const allAnswers = [...resp.answers, ...resp.additionals];
const result = allAnswers.find(a => a.name === domain);
if (result != null)
console.log(result);
});
mdns.on("ready", () => {
console.log("In query");
mdns.query([
{ name: domain, type: "A" },
{ name: domain, type: "AAAA" },
{ name: domain, type: "PTR" },
{ name: domain, type: "SRV" },
{ name: domain, type: "TXT" },
]);
});
mdns.initServer();
I then tried to do a test with another mdns npm package bonjour-discovery. That finds the ikea gateway right away when it is run from another subnet. I noticed that it has a referer field in it (maybe mdns-server doesn't handle that this is present). This is the output running from another subnet:
> client = require('bonjour-service');
{
Bonjour: [class Bonjour],
Service: [class Service extends EventEmitter],
Browser: [class Browser extends EventEmitter],
default: [class Bonjour]
}
> bonjour = new client.Bonjour();
Bonjour {
server: Server {
registry: {},
mdns: EventEmitter {
_events: [Object: null prototype],
_eventsCount: 1,
_maxListeners: 0,
send: [Function],
respond: [Function],
response: [Function],
query: [Function],
destroy: [Function],
update: [Function],
[Symbol(kCapture)]: false
},
errorCallback: [Function]
},
registry: Registry {
services: [],
server: Server {
registry: {},
mdns: [EventEmitter],
errorCallback: [Function]
}
}
}
> bonjour.find({type:'coap',protocol:'udp'}, function (service) {
... console.log('Found an coap gateway:', service)
... })
Browser {
_events: [Object: null prototype] { up: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
onresponse: [Function],
serviceMap: {},
wildcard: false,
_services: [],
mdns: EventEmitter {
_events: [Object: null prototype] {
query: [Function: bound respondToQuery],
response: [Function]
},
_eventsCount: 2,
_maxListeners: 0,
send: [Function],
respond: [Function],
response: [Function],
query: [Function],
destroy: [Function],
update: [Function],
[Symbol(kCapture)]: false
},
txt: DnsTxt { binary: undefined },
name: '_coap._udp.local',
[Symbol(kCapture)]: false
}
> Found an coap gateway: {
addresses: [ '192.168.0.27' ],
subtypes: [],
rawTxt: [ <Buffer 76 65 72 73 69 6f 6e 3d 31 2e 32 31 2e 33 31> ],
txt: { version: '1.21.31' },
name: 'gw-4491602ba33d',
fqdn: 'gw-4491602ba33d._coap._udp.local',
host: 'TRADFRI-Gateway-4491602ba33d.local',
referer: { address: '192.168.8.1', family: 'IPv4', port: 5353, size: 151 },
port: 5684,
type: 'coap',
protocol: 'udp'
}
I am not sure how to proceed(probably a bug report at the mdns-server project), but it seems mdns-server doesn't handle the mdns between different subnets usecase
My current focus is trying to change the discoverGateway part og node-trafri-client to use bonjour-service instead - so I can get my program working (a plugin for the root music server to turn on/off an ikea switch when music plays/doesn't play)
I probably wasn't thinking straight. Of course the response will be later than the query as it reacts on received packets. Sorry for the confusion