Background. On a multi-homed host I'd like to run one Shairport Sync instance per network interface, with each instance only reachable on its own address. Today general.interface scopes the mDNS advertisement (mdns_avahi.c uses config.interface_index), but the RTSP listener in rtsp_listen_loop() still binds the wildcard address — getaddrinfo(NULL, portstr, &hints /* AI_PASSIVE */, …) — so the instance accepts connections on all interfaces regardless of that setting. (The per-connection RTP/data sockets already bind a specific local address via bind_socket_and_port().)
Proposal. Add an option to bind the listening socket(s) to a specific local IP address, so the daemon only listens where intended. I'd be happy to implement it and open a PR against development, tested on a multi-homed host.
A few design questions before I code:
- New option vs. existing
interface. I lean toward a new explicit address setting (config general.address + a matching command-line flag), leaving interface as the advertising knob, to avoid changing current behavior. Would you prefer instead that interface also restrict the listener? Or bind by interface name (resolving its addresses via getifaddrs())?
- Address vs. interface as the primitive. Binding an IP is portable across Linux and the BSDs (no
SO_BINDTODEVICE/privilege). Any objection to making the address the primary knob, with interface-name support as a possible follow-up?
- CLI + config. I'd expose it both ways (config value, overridden by the command line), matching
port/name. Sound right?
- Should an unset value keep today's behavior exactly (bind all interfaces, dual-stack v4/v6)? I'd preserve the existing
IPV6_V6ONLY handling.
Happy to adjust naming/semantics to your preference.
Background. On a multi-homed host I'd like to run one Shairport Sync instance per network interface, with each instance only reachable on its own address. Today
general.interfacescopes the mDNS advertisement (mdns_avahi.cusesconfig.interface_index), but the RTSP listener inrtsp_listen_loop()still binds the wildcard address —getaddrinfo(NULL, portstr, &hints /* AI_PASSIVE */, …)— so the instance accepts connections on all interfaces regardless of that setting. (The per-connection RTP/data sockets already bind a specific local address viabind_socket_and_port().)Proposal. Add an option to bind the listening socket(s) to a specific local IP address, so the daemon only listens where intended. I'd be happy to implement it and open a PR against
development, tested on a multi-homed host.A few design questions before I code:
interface. I lean toward a new explicitaddresssetting (configgeneral.address+ a matching command-line flag), leavinginterfaceas the advertising knob, to avoid changing current behavior. Would you prefer instead thatinterfacealso restrict the listener? Or bind by interface name (resolving its addresses viagetifaddrs())?SO_BINDTODEVICE/privilege). Any objection to making the address the primary knob, with interface-name support as a possible follow-up?port/name. Sound right?IPV6_V6ONLYhandling.Happy to adjust naming/semantics to your preference.