My issue is that once I call socket(); bind()(with some specific IP address, not INADDR_ANY); listen(), there seems to be no way of determining whether IP address that I bound socket to still exists in the system.
What I looked into using:
- checking error with
getsockopt(SO_ERROR); epoll()-ing on someEPOLLERR,EPOLL{,RD}HUPevents;- hoping that
accept()would return an error if the IP address is deleted when process is blocked on this syscall;
but facilities above do not seem to react on IP address vanishing and/or change of interface state at all.
- calling
bind()in some timer callback to periodically check whether the IP address still can be bound to, but apparently another socket has to be created each time sincebind()-ing socket twice is prohibited, so this approach looks ugly to me(leaving alone problems related to binding listening sockets to the same address:port).
What I did not test, but what looks wrong:
setting
SO_BINDTODEVICEin the hope that this will change behavior of the facilities from the first triple in case interface goes down/IP address is removedcalling some
ioctl()likeSIOCSPGRPorFIOASYNCsince they promise to signal process about asynchronous events that hopefully include disappearance of an IP address
Also
netlinkcan always be used to look directly into the routing table, but this is very Linux-specific and I'm not leaving the hope that there is a standard way to check that your socket is actually listening on anything
To make it clearer, what I actually want is some event similar to RDMA_CM_EVENT_DEVICE_REMOVAL, but with AF_INET sockets, that would notify me when I should abandon listening on a socket since there is no interface that it is bound to anymore, or (it would be perfect) that all such interfaces are down. But probably the latter wish is impossible to fulfill, because even bind() completes smoothly if the only interface with provided IP address is down.