If we look into current struct socket, we see that some functional fields
belong to normal data flow sockets, and other belong to listening socket.
They are never used simultaneously. Now, if we look at socket API, we see
that once a socket underwent transformation to a listening socket, only 3
regular syscalls now may be called: listen(2), accept(2) and close(2) and
a subset of ioctl() and setsockopt() parameters is accepted. A listening
socket cannot be closed from the protocol side, only from user side. So,
listening socket is so different from a dataflow socket, that separating
them looks architecturally right thing to do.
The benefits are:
- Nicer code (I hope).
- Smaller 'struct socket'.
- Having two different locks for socket and solisten, we can try to get rid of ACCEPT_LOCK global lock.
The patch is in a very pre-alpha state. It has been run only in my bhyve VM.
It passes regression tests from tools/regression/sockets and tests/sys,
including the race tests.
For TCP it passes basic functionality testing, but could be there are still
races remaining after ACCEPT_LOCK removal.
For SCTP the patch is unfinished yet. The tricky thing with SCTP is that it
can un-listen a listening socket back to normal socket, doing listen(fd, 0)
on it. My patch has API for that I started working on SCTP, but temporarily
put this problem aside. It looks solvable, but I don't know yet how to test
it. Better first see results with TCP.