netflector available as plugin (mDNS, SSDP, DIAL, WSD, WoL reflector)

Started by UnicronHD, August 13, 2026, 02:44:16 PM

Previous topic - Next topic
@UnicronHD Good progress with this build!

With target_peers = ["10.10.10.2"] the Roon server is consistently discovered, bidirectional UDP/9003 communication works, and the previous Network is unreachable / ICMP issues for multicast and broadcast are gone.

There is still one issue: the iPhone does not reliably appear as a Roon audio endpoint.

I also captured:

10.10.10.2 > 192.168.1.60: ICMP udp port 9003 unreachable

for a peer-unicast packet from the Roon server to 10.10.10.2:9003.

In addition, I repeatedly see 350-byte UDP/9003 packets on wg0 from the iPhone to its own WG address, but these do not appear on the LAN capture. The LAN side only shows the normal 98-byte discovery packets and 491-byte replies.

This may be worth comparing with udp-proxy-2020: since v0.0.11 it opens a UDP listening socket specifically to prevent ICMP Port Unreachable messages, as these were found to make Roon on iOS close its listening port and prevent the phone from appearing as an audio output. The ICMP direction here is different, so it may not be the exact same issue, but the symptom is very similar.

So the new peer handling clearly fixes the original WireGuard multicast/broadcast problem, but there still seems to be something missing for reliable iPhone endpoint discovery. Happy to test further.
Deciso DEC850v2

@RamSense Thanks, that confirms the peers change does what it should: the copy carries the server's own source, and the multicast and broadcast errors are gone.

On the endpoint problem. The ICMP you captured goes from the phone to the server, so it tells us the Roon app had no socket open on 9003 at that moment: the phone cannot answer the server's query while its port is closed, which is exactly "not an endpoint". The open question is why the port was closed. Two candidates: the app was in the background (iOS suspends it, and Roon holds its listener only in the foreground), or something made the app drop the socket while it was up. udp-proxy-2020's finding was the second kind, but that needs an ICMP port unreachable arriving at the phone, and there is none in what you sent. netflector's host does not hold port 9003 open, so if the phone ever sends unicast 9003 traffic to one of the OPNsense addresses, OPNsense would answer with exactly that ICMP. Whether that happens depends on where the 350-byte packets go.

Could you check:

  • The exact destination address of the 350-byte packets on wg0, and whether their payload is a SOOD query or a reply.
  • Any ICMP toward the phone on wg0: tcpdump -ni wg0 icmp and dst host 10.10.10.2.
  • The wg0 address and prefix on OPNsense, and the phone's tunnel address and prefix (/24 or /32).
  • Whether the Roon app was in the foreground when you captured the port-unreachable from the phone.
  • Which OS the Roon Core runs on.

@UnicronHD thanks for the follow-up. I checked your remaining details.

The iPhone WireGuard interface is configured as 10.10.10.2/32. OPNsense has wg0 = 10.10.10.1/24, with 10.10.10.2/32 as the peer AllowedIP.

The ~350-byte packets are actually 348-byte SOOD packets. Their exact destination is the iPhone's own tunnel address:

10.10.10.2:<ephemeral> -> 10.10.10.2:9003

The payload starts with SOOD, message type Q, and includes the iPhone endpoint data (iOS 26.7, raat_version 1.1.48, tcp_port 9200).

During the dedicated capture I saw no ICMP packets toward 10.10.10.2.

Roon Server runs on Linux, Debian 12 (bookworm), x86_64.

Roon was in the foreground during the endpoint test.

One thing that may be relevant is the /32 on the iPhone together with the destination above: the phone's SOOD packet is sourced from 10.10.10.2 and is also addressed to 10.10.10.2:9003, and it does not appear on the LAN capture.

This may also be an interesting difference compared with udp-proxy-2020. Its VPN handling learns the client from UDP/9003 traffic seen on the tunnel interface and forwards that traffic onto the other configured interfaces; its debug examples show WG client traffic being reinjected toward the LAN.

So perhaps the relevant question here is whether UDP/9003 sourced from a configured WG peer should also be treated as discovery input for the opposite interface even when its destination is the peer's own tunnel address (?)

Happy to run any further captures or test another build.
Deciso DEC850v2