To query the service, I recommend you tweak the order of configurations a little bit:
local ip, port = '*', 0
local data = '...'
local udp = socket.udp()
-- socket config
-- in addition to your current configurations
assert(udp:setsockname(ip, port))
assert(udp:setoption('broadcast', true))
-- broadcast
assert(udp:sendto(data, '224.0.0.251', 5353)
local res = assert(udp:receivefrom())
You should have a smooth execution if you update the multiaddr param of your socket’s config pointing to the multicast address you previously had, e.g.
local mc_addr = '224.0.0.251'
local addr, port = '*', 0
local udp = socket.udp()
...
...
udp:setoption("ip-add-membership", {multiaddr = '224.0.0.251', interface = "0.0.0.0"})
Also, it would be awesome if you could share with the community what are you developing, since, we’ve only covered implementations for Edge LAN Devices on top of SSDP + HTTP or JSON RPC.
Interesting… so, by tweaking just a bit the socket configuration and using the mdns_make_query function, I was able to track the mDNS query via wireshark.
And the code is this simple:
-- [[
-- Borrowed from the library you referred
-- ]]
local function mdns_make_query(service)
-- header: transaction id, flags, qdcount, ancount, nscount, nrcount
local data = '\000\000'..'\000\000'..'\000\001'..'\000\000'..'\000\000'..'\000\000'
-- question section: qname, qtype, qclass
for n in service:gmatch('([^%.]+)') do
data = data..string.char(#n)..n
end
return data..string.char(0)..'\000\012'..'\000\001'
end
-- [[
-- Opens the UDP socket to query the network
-- ]]
local function mdns_query()
local socket = require 'socket'
local udp = assert(socket.udp())
local service = 'erickv'
assert(udp:setsockname("*", 0))
assert(udp:settimeout(0.1))
assert(udp:setoption("ip-add-membership", {multiaddr = '224.0.0.251', interface = "0.0.0.0"}))
-- broadcast query
assert(udp:sendto(
mdns_make_query(service),
'224.0.0.251', 5353))
end
So, you should be able to use that library by updating the interface to "0.0.0.0" instead of just the wildcard char.
I can see the udp packet sent but no response received
while (os.time() - start < timeout) do
local data, peeraddr, peerport = udp:receivefrom()
print('data:', data, 'peeraddr:', peeraddr, 'peerport:', peerport)
if data and (peerport == port) then
log.info('mdns', 'received response from '..peeraddr)
end
end
This thread was useful to me when doing my first UDP edge driver. I did see what I think is a mistake in the code - the setsockname call is made BEFORE the setoption of “reusaddr” - in my testing you must set options that affect binding BEFORE you use setsockname (and I presume before setpeername). In addition there is a note in the “known issues” (at the time of this writing) of the following:
Calls to tcp.bind or udp.setsockname may only specify port 0 to be assigned a port randomly, unless you are binding to a multicast IP address and have already set the reuseaddr socket option to true .
In order for this to work you would have to set the option before calling setsockname. Just posting this because this thread was so useful and using this and the “known issue” got my udp multicast to work.