I don’t know Brian. And my previous message shouldn’t be taken as a slight against him or anyone.
I’ve known many really intelligent and capable software engineers who don’t grok deeper networking concepts. Reality is that there are many areas of software development and it’s impossible for even the best developers in the world to understand all the ins and outs of everything. I get networking, security, backend systems, DevOps and can do simple embedded systems, but I can’t do a GUI, web development (well I can sorta fake this but you’re not going to like the results), graphics or ML (among others).
That said, my problem with discovery isn’t so much as the design (I totally understand how they got here), but rather in the implementation. Simply put, if you want to send a UDP broadcast message like is used on UDP/9003 you’d do something like this:
bcast_sock = socket(AF_INET, SOCK_DGRAM, 0);
int broadcastEnable=1;
int ret=setsockopt(bcast_sock, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable));
if ret > 0 {
perror();
exit(errno);
}
For the record, I looked that up on stackoverflow because it’s been about a decade since I’ve written any C.
The key thing here is if you want to send a broadcast message over UDP you have to explicitly tell the computer you want to do so and it will return an error if you make a mistake.
Now let’s look at a two different network interfaces on my computer:
$ ifconfig en0
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
[SNIP]
$ ifconfig utun0
utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1380
[SNIP]
If you look at the first line of output from each ifconfig
command you see a set of FLAGS IN CAPITAL LETTERS. Things like “UP” and “RUNNING” and “BROADCAST”. Oh wait, BROADCAST only shows up on en0
(my wifi interface) and not tunnel interface utun0
. Instead we see POINTTOPOINT because this is not a network interface which supports broadcasts at all. (On a side note, notice both interfaces support Multicast messages!)
So the code sets the BROADCAST flag on the socket and we have a network interface which doesn’t support BROADCAST messages. What does the code do? Well my code above exits with an error because you can’t do that.
Roon does something different. I’m actually kinda curious what exactly… I have this feeling they hard coded the last octet to .255
in the IP address assuming everyone just uses a /24. I know at one point in time when I was testing my code I was using a /30 for my POINTTOPOINT VPN tunnel and was still seeing “broadcast” messages like they were being sent on a /24. I’d have to do more testing to understand what is up with that. It’s this rather non-standard/incompatible behavior that prevents udp-broadcast-relay-redux
from working on OpenVPN tunnel interfaces like this and is why I wrote udp-relay-2020
.
But Roon doesn’t try sending an Ethernet header on these “loopback” interfaces which is good. So Roon is doing something right.
The irony is that because Roon does this UDP broadcast incorrectly, it still sends a packet. This is really really good news! Because if it correctly determined that a OpenVPN tunnel interface did not support broadcast messages and just skipped that interface, then it would be MUCH MUCH more difficult to get this to work over a VPN tunnel (would require code to run on the remote device with the OpenVPN client).
Honestly, this totally could just be some weird .NET bug when it runs on a non-Windows platform and it’s Microsoft’s fault. I wouldn’t be shocked. Like I said, networking is one of those areas of programming that 99% of developers don’t really understand that well.