This is the mail archive of the
cygwin
mailing list for the Cygwin project.
Re: RPC clnt_create() adress already in use
- From: Mark Geisert <mark at maxrnd dot com>
- To: cygwin at cygwin dot com
- Date: Wed, 31 Jan 2018 00:15:16 -0800
- Subject: Re: RPC clnt_create() adress already in use
- Authentication-results: sourceware.org; auth=none
- References: <59D90AF8D70E9740907BACDE2BCB520836E01220@RESW102.resdom01.local>
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