This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RPC clnt_create() adress already in use


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]