fujiapple852 / trippy

A network diagnostic tool
https://trippy.cli.rs
Apache License 2.0
3.8k stars 82 forks source link

Do not conflate AddressInUse and AddrNotAvailable errors #1246

Closed fujiapple852 closed 4 months ago

fujiapple852 commented 4 months ago

The tracer has the ability to "skip" probes which fail with either AddressInUse or AddrNotAvailable errors.

This was added for TCP, where the the network layer performs a socket connect() after binding to the local socket address for each probe. By default for TCP tracing, the src port is set to be the sequence number and so if any of the src ports are in use (i.e. TIME_WAIT status) then the connect() operation will fail. The tracer can detect this situation and "skip" probes which cannot be bound.

Currently the tracer will do this if for both AddressInUse or AddrNotAvailable errors, however this is incorrect, it should only do this for the AddressInUse error.

macOS defines these errors as:

[EADDRINUSE]       The address is already in use.

[EADDRNOTAVAIL]    The specified address is not available on this machine.

Linux defines these errors as:

EADDRINUSE
      Local address is already in use.

EADDRNOTAVAIL
      (Internet  domain  sockets) The socket referred to by sockfd had not previously been bound 
to an address and, upon attempting to bind it to an ephemeral port, it was determined that all 
port numbers in the ephemeral port range are currently in use.

Testing on macOS confirms that only EADDRINUSE occurs in this scenario. Note that the stream socket sets SO_REUSEPORT which, on Linux, prevents this error from occurring. It does not appear to have any effect on macOS, the man page for setsockopt(2) says it should, but for UDP only:

SO_REUSEPORT allows completely duplicate bindings by multiple processes if they all set SO_REUSEPORT before binding the port. This option permits multiple instances of a program to each receive UDP/IP multicast or broadcast datagrams destined for the bound port.