Unix Domain Socket bind, reuse address

unix-sockets

If I bind() an AF_INET socket (for a TCP connection), then later close() it, next time I run my program, I may have issues, since despite the close(), the kernel can still have the resources associated with the open socket.

I am not very clear on this issue with the Unix Domain Sockets, though.

So far I have seen

  1. I need a unique path to use it with bind(). The path must not
    exist at the time bind() is called, and the file will be created
    by bind(). (However, it may or may not be visible in the filesystem.
    The file will not appear in the filesystem, if the path starts with the
    special char \0.)

  2. If the file is not unlink()-ed, even after close, the kernel keeps
    the associated resources, and the socket is fully functional.

QUESTION:

Since neither close() nor unlink() alone can make a Unix Domain Socket disappear, will both of them do the trick reliably / trigger the kernel to give up all the resources associated with the socket?

Is it possible that I will ever run into a reuseaddr error, if both close() and unlink() were called?


EDIT (after the comments and answer):

So, a binded AF_LOCAL socket looks something like this:

unix_domain_socket_inode
-> binded to a socket
-> associated with a file (path)

The unix_domain_socket_inode will live as long as:

  1. something keeps it open (the socket is not closed), or
  2. it has the associated path

If only 1. is true, we have an open socket and an inode, and everything works.

If only 2. is true, since the inode has a path associated with it, the kernel cannot clean it up, but it does not work either, because it lacks the socket resources that handle incoming connections. It won't even be a normal file, just a dead husk of the past glory of a busy, working socket.

In case of the AF_INET connection, the address reuse issue was a design choice for better usability.

In case of the AF_LOCAL, the leftover file is an artifact from previous design choices, which prevent the kernel itself from automatically cleaning up the file it created in 1 go, when close() is called. There is no hidden mechanism associated, because of which the kernel would want to keep this resource after a close() is called.

Best Answer

In this context, it's important to understand the rationale for why the kernel has the TIME_WAIT state for TCP connections. This state is intended to allow any packets associated with the connection (that may have taken longer routes or otherwise been delayed) to drain from the network before a new connection on the same port can be established. That way, you ensure that a new connection doesn't receive any packets associated with the old connection. The reuseaddr option enables the developer to communicate "don't perform that wait".

Unix domain sockets don't have that concern; reuseaddr doesn't really make sense in that context.