RPC clnt_create() adress already in use

Mark Geisert mark@maxrnd.com
Wed Jan 31 08:15:00 GMT 2018


PAULUS, Raimund, TI-ABN wrote:
> Hi Mark,
>
> in my email (https://sourceware.org/ml/cygwin/2017-12/msg00194.html) i described 2 approaches. I prefer  nr 1.
> Here the part of the source in bindresvport.c:
> ------------------------------------------------------------------------------------------------------------------
>         if (port == 0) {
>                 port = (getpid() % NPORTS) + STARTPORT;
>         }
>         res = -1;
>         errno = EADDRINUSE;
>
> /* fix for bind() */
> port = 0;
>                 again:
>         for (i = 0; i < nports; ++i) {
>                 *portp = htons(port++);
>                  if (port > endport)
>                         port = startport;
>                 res = bind(sd, sa, salen);
>                 if (res >= 0 || errno != EADDRINUSE)
>                         break;
>         }
>         if (i == nports && startport != LOWPORT) {
>             startport = LOWPORT;
>             endport = STARTPORT - 1;
>             nports = STARTPORT - LOWPORT;
>             port = LOWPORT + port % (STARTPORT - LOWPORT);
>             goto again;
>         }
>         mutex_unlock(&port_lock);
>
>         return (res);
> }
> -------------------------------------------------------------------------------------------------------
>
> This causes bind() to search an unused port. I use libtirpc with this fix since several weeks and it works for me. I don't know an other way (fixing Cygwin) to success.
> The RPC-client on my pc is started every few minutes and has to connect to the RPC-server.  Without the fix libtirpc is not usable and I have to use Cygwin 1.5.18 with the old librpc.
[...]

Hi Raimund,
Thanks for attaching the complete source for your modified bindresvport.c.  I 
had been treating your setting of port to 0 as a workaround rather than as a 
solution.  My misunderstanding.

We can't solve the issue that way because when bind() is called with a zeroed 
port number, it picks a random port number that's often outside the range of 
ports bindresvport() is supposed to return (i.e., a port between STARTPORT and 
ENDPORT).

I thought of something similar to your idea but obeying the bindresvport() 
semantics.  I add a static short value named 'usecount' to the function's local 
variables.  Mid-function, I have this code to choose a port number:
     if (port == 0) {
         port = ((getpid() + usecount++) % NPORTS) + STARTPORT;
     }

Can you try this with your testcase(s) and make sure it works for you?

..mark

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple



More information about the Cygwin mailing list