Web lists-archives.com

Re: RPC clnt_create() adress already in use




Hello Corinna,

with the snapshot of cygwin1.dll and using bindresvport() from Cygwin for libtirpc (instead of the original bindresvport() from libtirpc) all my testcases work without error.

Many thanks
Raimund



-----Ursprüngliche Nachricht-----
Von: cygwin-owner@xxxxxxxxxx [mailto:cygwin-owner@xxxxxxxxxx] Im Auftrag von Corinna Vinschen
Gesendet: Montag, 5. Februar 2018 21:15
An: cygwin@xxxxxxxxxx
Betreff: Re: RPC clnt_create() adress already in use

On Feb  5 15:06, Corinna Vinschen wrote:
> On Feb  5 14:34, Corinna Vinschen wrote:
> > On Feb  5 12:26, Corinna Vinschen wrote:
> > > To reiterate the problem we observe:
> > > 
> > > - socket()
> > > - setsockopt (SO_REUSEADDR)
> > > - bind() succeeds
> > > - connect() fails with EADDRINUSE while socket is still in 
> > > TIME_WAIT
> > > 
> > > using bindresvport in place of bind only marginally changes the 
> > > situation, in particular if the second parameter is set and 
> > > requests a port number != 0.  What happens in that case is that 
> > > bindresvport calls bind with this port number and checks if bind returns EADDRINUSE.
> > > 
> > > Only then it tries to bind other port numbers in the reserved range.
> > > But we now know that bind will never return EADDINUSE if the 
> > > SO_REUSEADDR socket option has been set.
> > > 
> > > Even assuming the process calls bindresvport(sock, NULL) we may 
> > > end up returning a port number already in use if the process is 
> > > the only Cygwin process on the system.  The reason is that Cygwin 
> > > uses a round robin approach which relies on having a globally 
> > > shared value called last_used_bindresvport.  If the process is the 
> > > only Cygwin process on the system, this information is lost after 
> > > exiting the process, so the next process will start with the same 
> > > start port number and bind will again fail to notice the client with EADDRINUSE.
> > > 
> > > What potential solutions to this problem do we have?
> > > 
> > > - bindresvport could enforce SO_EXCLUSIVEADDRUSE temporarily to make
> > >   sure bind fails.
> > 
> > Nope, no way.  Even enforcing SO_EXCLUSIVEADDRUSE results in the 
> > second bind succeeding and the subsequent connect failing.  The 
> > entire SO_REUSEADDR/SO_EXCLUSIVEADDRUSE semantics only works as 
> > desired on the server side apparently
> > 
> > > - bindresvport could check every local address for being free prior
> > >   to calling bind.  However, there's a potential race here.
> > > 
> > > - DisconnectEx?  Never tried this Winsock extension but it might be
> > >   worth a shot.
> 
> I think I have a very simple solution for the scenario which calls 
> bindresvport with port number.  Still looking for a solution for the 
> second problem...

I've pushed a few patches and uploaded new developer snapshots to https://cygwin.com/snapshots.  Please give them a try.


Thanks,
Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat