Problem Description

This problem was origianl found when I tried to running AISDB on macOS. The default value of udp_listen_addr is an IPv6 address [::]:9921. However, the program will raise an error when it tries to bind the address:

No suitable network interfaces were found!

It is important to highlight that both my Ubuntu workstation and Raspberry Pi operate without any problems, as they do not encounter this issue. Alternatively, if I manually configure the udp_listen_addr as [::1]:9921 on macOS, no error is raised.

This error message is specifically associated with a Python wheel called mProxy, which is implemented using Rust. After downloading the source code and running the tests on macOS, the same error message will be raised. But the tests will pass on Ubuntu and Raspberry Pi.

Investigation

The IPv6 address ::, also known as the unspecified address, is a special address that signifies it is not assigned to any specific interface. Similar to the IPv4 address 0.0.0.0, this address operates in a similar manner.

During my experimentation on macOS, I attempted to ping both :: and 0.0.0.0. Both pings are failed. Conversely, on Ubuntu and Raspberry Pi, both pings were successful. This observation indicates that the issue is likely related to the operating system in use.

As per the defined standards, it is established that the unspecified address (0.0.0.0 in IPv4 and :: in IPv6) does not qualify as a valid destination address for ICMP and ICMPv6 echo requests (ping and ping6) or any other form of communication. Notably, while macOS fails to respond to pings sent to the unspecified address, both my Ubuntu and Raspberry Pi exhibit a different behavior by successfully responding to such requests. This divergence indicates that the unspecified address is handled as a special case in certain operating systems.

To confirm the hypothesis regarding the redirection of traffic directed to the unspecified address, I conducted a validation procedure by utilizing the traceroute and traceroute6 commands on macOS. The goal was to trace the route to both 0.0.0.0 (IPv4 unspecified address) and :: (IPv6 unspecified address). The output of this process is provided below:

# macOS
> traceroute 0.0.0.0

traceroute to 0.0.0.0 (0.0.0.0), 64 hops max, 52 byte packets
traceroute: sendto: Socket is not connected
 1 traceroute: wrote 0.0.0.0 52 chars, ret=-1

> traceroute6 ::
traceroute6 to :: (::) from ::1, 64 hops max, 12 byte packets
sendto: No route to host
 1 traceroute6: wrote :: 12 chars, ret=-1

On macOS, the traffic directed to unspecified address is not redirected to another address.

Then I tried to the same thing on Ubuntu and Raspberry Pi. The result is shown below:

# Raspberry Pi
> traceroute 0.0.0.0

traceroute to 0.0.0.0 (0.0.0.0), 30 hops max, 60 byte packets
 1  localhost (127.0.0.1)  0.182 ms  0.060 ms  0.054 ms

> traceroute6 ::

traceroute to :: (::), 30 hops max, 80 byte packets
 1  localhost (::1)  0.162 ms  0.050 ms  0.047 ms

On Ubuntu and Raspberry Pi, the traffic directed to unspecified address is redirected to the loopback address.

Surprisingly, unlike Ubuntu and Raspberry Pi, the traffic to the unspecified address on macOS is not redirected 0.0.0.0 or :: to the loopback address. This discrepancy provides a crucial insight into the underlying cause of the program’s inability to bind the address. Evidently, the divergent behavior of macOS in handling IPv6 traffic to the unspecified address is a key factor contributing to the issue at hand.

Solution

It is important to note that the unspecified address in IPv6 (represented as ::) or IPv4 (represented as 0.0.0.0) is not a valid destination address for ICMP or ICMPv6 echo requests (ping) or other forms of communication. Therefore, it is recommended to use the loopback address (represented as ::1 in IPv6 or 127.0.0.1 in IPv4) instead.

While some operating systems may exhibit a behavior where the traffic directed to the unspecified address is redirected to the loopback address, this should not be relied upon as a universal solution.