There's indeed something wrong around the SRTO_REUSEADDR option. According to what I can see in the CUDTUnited::updateMux function that is responsible for associating the Multiplexer with the socket, the search through an existing multiplexer for the given address is being done only if the socket being bound has set SRTO_REUSEADDR option, and this option is also replicated inside the multiplexer, so only "reusable" multiplexers are allowed to be associated with such a socket.
In effect, if you have a socket that has SRTO_REUSEADDR set to false, or an existing multiplexer for that address is not reusable (that is, this address was earlier bound to a socket that has set SRTO_REUSEADDR to false), then it always tries to create a new multiplexer. There are two problems here, however:
-
Not handled explicitly a situation when an attempt to create this multiplexer, associated with creating a new socket and binding it to that address, would fail, and moreover, we know that this would fail from upside, if we already found a multiplexer that is bound to this address and it is not reusable. In such a situation, the attempt to create a new multiplexer should always fail and we know it at this very point. Simply, if we don't allow address reusage, then attempt to reuse the address should fail. This, however, relies on that the call to bind will fail due to that SO_REUSEADDR on a UDP socket is off by default.
-
The default value for SRTO_REUSEADDR is true, while SO_REUSEADDR for a UDP socket is false by default, which is actually a consequence of the need to share the multiplexer between the listener and the accepted sockets. Although it is required that accepted sockets share the multiplexer with the listener socket, it's unclear how this option should control the fact as to whether, for example, a potential caller socket can share the multiplexer with a listener socket and its accepted sockets.
What needs to be done:
- Made a unit test that embraces all these cases.
- Define correctly the consequences of having this flag set and clear in a various combinations of binding sockets to the address, including UDP socket acquisition (
srt_bind_acquire).
There's indeed something wrong around the
SRTO_REUSEADDRoption. According to what I can see in theCUDTUnited::updateMuxfunction that is responsible for associating the Multiplexer with the socket, the search through an existing multiplexer for the given address is being done only if the socket being bound has setSRTO_REUSEADDRoption, and this option is also replicated inside the multiplexer, so only "reusable" multiplexers are allowed to be associated with such a socket.In effect, if you have a socket that has
SRTO_REUSEADDRset to false, or an existing multiplexer for that address is not reusable (that is, this address was earlier bound to a socket that has setSRTO_REUSEADDRto false), then it always tries to create a new multiplexer. There are two problems here, however:Not handled explicitly a situation when an attempt to create this multiplexer, associated with creating a new socket and binding it to that address, would fail, and moreover, we know that this would fail from upside, if we already found a multiplexer that is bound to this address and it is not reusable. In such a situation, the attempt to create a new multiplexer should always fail and we know it at this very point. Simply, if we don't allow address reusage, then attempt to reuse the address should fail. This, however, relies on that the call to
bindwill fail due to thatSO_REUSEADDRon a UDP socket is off by default.The default value for
SRTO_REUSEADDRis true, whileSO_REUSEADDRfor a UDP socket is false by default, which is actually a consequence of the need to share the multiplexer between the listener and the accepted sockets. Although it is required that accepted sockets share the multiplexer with the listener socket, it's unclear how this option should control the fact as to whether, for example, a potential caller socket can share the multiplexer with a listener socket and its accepted sockets.What needs to be done:
srt_bind_acquire).