Bind fails in jail with assigned IP address
- Reply: Matthew Seaman : "Re: Bind fails in jail with assigned IP address"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 08 Jan 2023 18:52:12 UTC
Hi folks, (The whole discussion is for legacy IP (v4) only, IPv6 might be affected as well, but I haven't tested yet.) I've implemented a daemon in Python for the Web Services on Devices (WSD) discovery protocol [1]. The protocol requires the "host" side to receive multicast packets addressed to a specific port (i.e. 3702). On the other hand, unicast traffic must be sent from that very same port as well [2]. I realize this by using separate sockets for multicast reception (recv_socket), unicast transmission (uc_send_socket) and a third one for multicast transmission, but the third one is not of concern here. So, essentially I have a multicast-enabled socket and a "conventional" unicast socket that need to be bound to the same port. On Linux, I can bind the the multicast socket to the legacy IP multicast address, but for FreeBSD this does not work (EADDRNOTAVAIL) and I fall back to bind to the port only and a wildcard IP address [3]. Although I found a hint on this in Stevens' book and it actually works, I maybe doing it wrong. So if there is a better way to do so, I'd be happy to know about it. After the receiving multicast socket is bound, I bind the unicast sending socket to the IP address of the intended network interface and the required protocol-specific port. As said, this works fine under FreeBSD in general. But if the script/daemon is executed in a jail with an IP addresses assigned to the jail, binding the sending socket fails with EADDRINUSE. This appears to be caused by what is described in jail(8) for jails with provided IP addresses: > ip4.addr > A list of IPv4 addresses assigned to the jail. If this is set, the > jail is restricted to using only these addresses. [...] Attempts to > use wildcard addresses silently use the jailed address instead. For > IPv4 the first address given will be used as the source address when > source address selection on unbound sockets cannot find a better > match. The effect of the silently changed wildcard address in my case is that the changed address prevents the required binding of the second/sending socket. This is inconsistent with the behavior outside a jail. Is this actually intended? If so, what can be done to bind both sockets to their required ports? I also tried to set ip4.saddrsel = 1 in the jail config, but it appeared that nothing changed. If the IP address configuration is omitted for the jail, the service does not encounter the error of an address that is already in use. If there is a solution to have the daemon run in a jail, I would be happy to discuss this. If jails are not suitable for this use case, let me know as well. 😉 Looking forward to your replies. Regards, Steffen [1] https://github.com/christgau/wsdd [2] https://learn.microsoft.com/en-us/windows/win32/wsdapi/discovery-and-metadata-exchange-message-patterns [3] https://github.com/christgau/wsdd/blob/0aef2d7/src/wsdd.py#L281-L287