public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: Corinna Vinschen <corinna-cygwin@cygwin.com>
To: cygwin@cygwin.com
Subject: Re: RPC clnt_create() adress already in use
Date: Mon, 05 Feb 2018 11:26:00 -0000	[thread overview]
Message-ID: <20180205112617.GB2912@calimero.vinschen.de> (raw)
In-Reply-To: <5b897ca4-9a7d-df90-e7a0-dbdedbd1f179@maxrnd.com>

[-- Attachment #1: Type: text/plain, Size: 4217 bytes --]

On Feb  5 02:29, Mark Geisert wrote:
> PAULUS, Raimund, TI-ABN wrote:
> > Hello Mark,
> > 
> > unfortunately i must correct my statement from Friday.
> > The program works, but only if the connections to the server are established in a loop inside the program.
> > If the program ends and you start it anew, a connection is not possible for a long time. you have to wait before you can establish a new connection.
> 
> That isn't what I saw in my testing.  At one point I had three copies of
> your test_rpc.exe running simultaneously and they all were able to establish
> 20 connections and the allocated port numbers were interleaved.
> 
> Are you running your test programs directly from a Windows Command Prompt or
> from one of the Cygwin shells like bash?
> 
> > Actually only our approaches in the original bindresvport() seem to work for all cases.
> > You have proposed to use the static variable usecount in bindresvport(). But how is the value of the variable handled if the program starts anew. Is it possible to get an used portnumber
> > and run in EADDRINUSE?
> 
> You must understand that none of the libtirpc approaches is guaranteed to
> work 100% of the time.  The problem is that without a lot of extra work we
> can't get libtirpc to "know" which ports to avoid.  Our approaches are just
> different strategies for avoiding a port collision, with different chances
> of working.
> 
> Libtirpc's original approach is essentially to have a range of port numbers
> it will try, 600 thru 1023, start with one of them randomly (based on the
> pid of the calling process), increment by one on each use.  This won't work
> when you're calling bindresvport() multiple times within one program because
> it starts from the same port number each time.
> 
> My "usecount" modification changes things so we start with the same port
> number as before but increment each time we bindresvport().  Good for one
> program making multiple calls and sort of good for multiple programs at same
> time.. but there is a chance of port number collision between the programs.
> 
> Using Cygwin's bindresvport() is the best solution because Cygwin keeps
> track of the last port number it has allocated *to any Cygwin program*.
> This is the only approach that can deal with multiple programs and multiple
> calls in one program.  So we need to nail down why it doesn't seem to work
> for you.

Apart from all the above, there may still be a problem in the given scenario.

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.

- 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.


Corinna

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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2018-02-05 11:26 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-05  8:19 PAULUS, Raimund, TI-ABN
2018-02-05 10:29 ` Mark Geisert
2018-02-05 11:26   ` Corinna Vinschen [this message]
2018-02-05 13:34     ` Corinna Vinschen
2018-02-05 14:06       ` Corinna Vinschen
2018-02-05 20:15         ` Corinna Vinschen
  -- strict thread matches above, loose matches on Subject: below --
2018-03-08 11:44 PAULUS, Raimund, TI-ABN
2018-03-08 15:24 ` Corinna Vinschen
2018-03-08 23:00 ` Mark Geisert
2018-03-02 10:39 PAULUS, Raimund, TI-ABN
2018-02-27  9:54 PAULUS, Raimund, TI-ABN
2018-02-27 10:37 ` Corinna Vinschen
2018-02-28  6:00   ` Mark Geisert
2018-02-06 11:29 PAULUS, Raimund, TI-ABN
2018-02-06 14:20 ` Corinna Vinschen
2018-02-07  6:54   ` Mark Geisert
2018-02-05 14:58 PAULUS, Raimund, TI-ABN
2018-02-02 12:58 PAULUS, Raimund, TI-ABN
2018-01-30 10:07 PAULUS, Raimund, TI-ABN
2018-01-31  8:15 ` Mark Geisert
2018-01-31  9:11   ` Corinna Vinschen
2018-01-31  9:35     ` Mark Geisert
2018-02-02  8:11       ` Mark Geisert
2018-01-30  7:01 PAULUS, Raimund, TI-ABN
2018-01-30  9:05 ` Mark Geisert
2017-12-19 16:13 PAULUS, Raimund, TI-ABN
2017-12-28  0:03 ` Mark Geisert
2017-09-29  9:52 PAULUS, Raimund, TI-ABN
2017-09-29 17:36 ` Mark Geisert
2017-09-27 12:51 PAULUS, Raimund, TI-ABN
2017-09-25  6:44 PAULUS, Raimund, TI-ABN
2017-09-27  9:50 ` Mark Geisert
2017-09-22  7:22 PAULUS, Raimund, TI-ABN
2017-09-24  9:49 ` Mark Geisert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180205112617.GB2912@calimero.vinschen.de \
    --to=corinna-cygwin@cygwin.com \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).