Make loopback address search more accurate
#17901 (moved) and #11360 (moved) search local interfaces for loopback addresses.
We could make this more efficient by using the flags returned with each address:
- getifaddrs returns struct ifaddrs with ifa_flags which has IFF_LOOPBACK
- ioctl(.,SIOCGIFCONF,.) returns struct ifreq with ifr_flags which has IFF_LOOPBACK
- GetAdaptersAddresses (Win32) returns IP_ADAPTER_ADDRESSES with IfType which has IF_TYPE_SOFTWARE_LOOPBACK
- Also pass GAA_FLAG_SKIP_FRIENDLY_NAME as we never use it
- tor_getsockname/get_interface_address6_via_udp_socket_hack connects to a public address. When passed the localhost flag, it could connect to a loopback address, but this seems rather tautologous, and it's hard to know which loopback address to pick in 127/8. Alternately, we could lookup localhost using the resolver, and check the returned address is 127/8 or ::1 (otherwise, broken DNS configs could lead to security issues).
A design for this could be:
- pass a flag to get_interface_address* indicating whether we want loopback addresses
- pass that flag down to get_interface_addresses_raw
- pass that flag to the API-specific functions
- when converting the address to a smartlist, include/exclude addresses matching the specified types
- always exclude tor_addr_is_null()
- always exclude addresses matching tor_addr_is_multicast
- for extra points, create a flags argument for:
- loopback
- this will require disabling the checks for tor_addr_is_loopback() in get_interface_address6_list() and get_interface_address6_via_udp_socket_hack(), see #17901 (moved)
- listen any (0.0.0.0 and [::], needs
tor_addr_is_listen_any()
) - link-local (needs
tor_addr_is_link_local()
) - other internal/private
- public
- with #defines:
- _INTERNAL: everything except public
- _INTERNAL_FOR_LISTENING: everything except public and listen any
- loopback
After doing this, refactor the changes in #17901 (moved) and #11360 (moved), and all existing code, to use the new flags argument.
This will also resolve issues where systems have addresses other than 127.0.0.0/8 or ::1 as the loopback address (like some BSD jails and OpenVZ). But we're not too worried about this, they're non-standards-compliant, so the operator can configure the exact address correctly, as long as we fail with an informative message.
I need this to do #17835 (moved), I'll likely do it then if no-one gets to it first.