fdinfo is a global table, indexed by the file descriptor, whose purpose
is just to remember if a port was allocated in a port range, so that
that port may be released when the file descriptor is closed. But that
would no longer work if we split file descriptors per thread-group, and
while we may just have one fdinfo table per thread group, this sounds
like wasted memory with little benefits.
So instead, abuse fdtab to store the relevant information. "state" now
has two more flags, FD_HAS_PORT and FD_OWNER_PR. FD_HAS_PORT means a
port has been explicitly allocated for that file descriptor.
FD_OWNER_PR means the owner field now points to the struct port_range
from which the port was allocated, and where it should be released.
The local port is now obtained from getsockname(), instead of storing it
anywhere.
For TCP, as fd_delete() is called from sock_conn_ctrl_close(), which
itself is called when the connection is about to be destroyed, we can
get the port range used as it is the one provided by the server, which
is available as conn->target.
For QUIC, unfortunately, the connection may be gone already, so instead,
we just store it in the quic_conn.
We have to wait until _fd_delete_orphan() is called in order to release
the port, as in some rare cases, fd_delete() will not call
_fd_delete_orphan(), and we want to make sure we only release the port
just as we're closing the file descriptor.