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
-
I need a unique path to use it with
bind()
. The path must not
exist at the timebind()
is called, and the file will be created
bybind()
. (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
.) -
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:
- something keeps it open (the socket is not closed), or
- 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. Thereuseaddr
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.