Skip to main content

 none
sockets, multicast/broadcast, UDP, TCP, SO_REUSEADDR, SO_REUSEPORT and SO_EXCLUSIVEADDRUSE RRS feed

  • Question

  • Hello,

    in the project Dao (https://github.com/daokoder/dao) we got stuck upon a problem with a wrapper interface for bind(), which should be multiplatform (work on all Windows versions from XP higher and also on BSDs and also other POSIX systems) and offer the following two options:

    1) A safe bind of one socket, one address (specific or wildcard) and one port such that no other process (disregarding the user the process runs under and disregarding user privileges) could be successful with a call to bind() on the same socket with the same address and the same port.

    2) A bind with allowing multicast/broadcast, reuse of address, port and all these disregarding the state of the socket (e.g. TIME_WAIT) and disregarding the type of connection (UDP, TCP). In other words, the behavior should be the same a the behavior of BSD sockets in all cases and under all conditions.

    The main differences between BSD and Windows are conveniently described on http://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean-t . According to that, one would say that a solution:

    1) For BSD "0" and for Windows "SO_EXCLUSIVEADDRUSE"

    2) For BSD "SO_REUSEPORT | SO_REUSEADDR" and for Windows "SO_REUSEADDR"

    is enough. But it's not true. For example due to Enhanced Socket Security and their behavior described in the table http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx (after first call to bind() with wildcard address and SO_REUSEADDR set, a second call to bind() with non-wildcard address and SO_REUSEADDR set will fail with error WSAEACCES).

    A solution might be to gather all the needed information (like user id, if there are any processes using that particular socket and if a call to connect() was already issued in case of TCP) and according to this information use the right mix of options SO_REUSEADDR, SO_EXCLUSIVEADDRUSE and others if needed. We didn't find though enough documentation about where to get all the needed information. Note that this solution would need an atomic query on socket (for all the information) in conjunction with a call to bind().

    Another solution could be to call bind() with different flags and decide upon the return error codes. This is though a nasty hack we would like to avoid.

    The question for you is, if you happen to know about any better solution than the ones mentioned above. There is a public discussion about this problem starting with comment https://github.com/daokoder/dao/issues/243#issuecomment-60434078 .

    Thank you in advance!
    Friday, January 16, 2015 4:33 PM

All replies

  • Anybody? This is a serious issue and there is no other issue tracker, so I had to ask here :(

    It would be sufficient if somebody with an access to the Microsoft socket API implementation took a short look at the code, answered my questions and added the newly found information to the official MSDN documentation.

    Tuesday, June 16, 2015 3:09 PM
  • Bump.
    Friday, July 3, 2015 3:31 PM