SO_REUSEADDR causing inconsistent behavior (on Windows)(?)


#1

I have a IPC network where the first started node becomes the server and the other nodes become clients. I determine the master node by testing the socket for its availability (flaky, know). On OSX this works very well, but on windows it fails als the socket simply gets stolen.

 this->isMaster =  this->beginWaitingForSocket(IPC::port);

So on Windows the line above always results in true, on OSX only for the first node (probably the same for LINUX).

http://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean-t

I hacked my woring copy, but you might want to address this :)

 

btw. I'm interseted in becoming a regular contributor to the repo. I there such a thing? 

I have great ideas for the Introjucer. I've build a quite complex toolset around it, might be nice to have the features insinde it, like building from it, template projects, interdepndent projcts, etc.

Cheers!

JM

 


#2

So what's the change you're suggesting? Changing it from SO_REUSEADDR to SO_REUSEPORT to produce the same behaviour as posix?


#3
#if JUCE_MAC    
    const int reuse = 1;
    setsockopt (handle, SOL_SOCKET, SO_REUSEADDR, (const char*) &reuse, sizeof (reuse));
#endif

On MAC all is behaving as I need it and also the behaviour I was infering from the JUCE docu.

Making the SO_REUSEADDR socket option "mac only" gives me the desired behaviour on windos too. 

 

The server is part of a VST plugin. I run it in reaper.

On OSX I noticed that the port is still open, with "reaper" as proccess, when I unload my plugins (the plugin & JUCE gets properly unloaded, all destructores get called etc., ).

I check the ports with:

sudo lsof -nP -iTCP -sTCP:LISTEN

The socket port only gets freed after I close REAPER, so one needs the SO_REUSEADDR on MAC to be able to reopen the port. Strangely enought I can not open the same port with a second plugin (the second node). although this is what i desire, i would no expect it from what i read in the c++ docs.

So theoreticly the option should be set to 0 on both systems but on MAC it is needed as the socket stays in some kind of bound state. 

On Windows on the other hand the default (eg no options set) bahaviour seems similar to the MAC behaviour WITH the SO_REUSEADDR option set. It seems on windows the option will enable other servers to "steal" the port (which is actually what i would expect when reading the docs, ass opposed to the MAC/LINUX behaviour), thus I can always bind to it and never will get a false in my very first code example. I tried SO_EXCLUSIVEADDRUSE, which is supposed to stop the port/adress stealing, thought it did not work. I did not try SO_REUSEPORT.

I suggest to just use it only on MAC (possibly LINUX builds, as its supposed to behave the same) and remove the option from Windows builds. The port is not supposed to be "stolen", at least this is how i read the juce doc for:


bool InterprocessConnectionServer::beginWaitingForSocket (int portNumber);

and also how I need it right new :P :)

Cheers!

 

JM


#4

Sorry.. having a bit of a TL;DR moment trying to read through your post! Can you summarize the changes you made that got it to work?


#5

sure:

juce_Socket.cpp::@line 421:

from:

    const int reuse = 1;
    setsockopt (handle, SOL_SOCKET, SO_REUSEADDR, (const char*) &reuse, sizeof (reuse));

to: =====>

#if JUCE_MAC    
    const int reuse = 1;
    setsockopt (handle, SOL_SOCKET, SO_REUSEADDR, (const char*) &reuse, sizeof (reuse));
#endif

Seems to normalize the Windows behaviour towards the MAC behaviour (in accordance to the infered behaviour in the JUCE doc).

Better?

Cheers!

JM


#6

Thanks, but presumably all posix systems are the same so it should be

#if ! JUCE_WINDOWS

and not

#if JUCE_MAC

right?


#7

Ppresumably yes, good catch! But i have no "linux" system ready to test it, sorry :(