On Jan 15 21:02, Corinna Vinschen wrote: > On Jan 13 13:39, Mark Geisert wrote: > > Corinna Vinschen wrote: > > > On Jan 13 00:36, Mark Geisert wrote: > > > > ~ ./bindtest > > > > 1st socket is 3 > > > > 1st bind OK > > > > 1st connect OK > > > > 2nd socket is 3 > > > > 2nd bind OK > > > > 2nd connect: Address already in use > > > > > > > > ~ ./bindtest > > > > 1st socket is 3 > > > > 1st bind OK > > > > 1st connect: Address already in use > > > > > > > > On Fedora 27, running the same STC shows: > > > > > > > > [mark@lux ~]$ netstat -an|grep :111 > > > > tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN > > > > tcp6 0 0 :::111 :::* LISTEN > > > > udp 0 0 0.0.0.0:111 0.0.0.0:* > > > > udp6 0 0 :::111 :::* > > > > [mark@lux ~]$ ./bindtest > > > > 1st socket is 3 > > > > 1st bind OK > > > > 1st connect OK > > > > 2nd socket is 3 > > > > 2nd bind OK > > > > 2nd connect OK > > > > > > I can't reproduce this: > > > > > > $ uname -sr > > > Linux 4.14.13-300.fc27.x86_64 > > > $ netstat -an|grep :111 > > > tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN > > > tcp6 0 0 :::111 :::* LISTEN > > > udp 0 0 0.0.0.0:111 0.0.0.0:* > > > udp6 0 0 :::111 :::* > > > $ ./bindtest > > > 1st socket is 3 > > > 1st bind OK > > > 1st connect OK > > > 2nd socket is 3 > > > 2nd bind OK > > > 2nd connect: Cannot assign requested address > > > [...] > > Rats. I'll have to investigate a couple of directions, deeper. It makes > > sense that connect() returns EADDRINUSE rather than bind() [...] > > After some more digging it turns out that both of the above observations > on Linux are correct. I can reproduce the 2nd connect succeeding by > simply adding a `sleep(1)' after the first close. So it turns out that > Linux has a timing issue at socket cleanup which can be alleviated > by an extra sleep. I opened a case about this issue. EADDRNOTAVAIL > sounds a bit weird in this scenario, but it's kind of ok. > > In terms of Cygwin, the EADDRINUSE is a completely different matter. > > It turns out that the second connect fails because the first socket > connection is in TIME_WAIT state. This is not exactly correct in POSIX > terms. The TIME_WAIT connection should not disallow a new socket to > reuse the same local address. That's what we observe on Linux (apart from > the timing issue). > > But here's the problem: Regardless if we actually use SO_REUSEADDR or > not, Windows sockets apparently disallows a subsequent connect to > succeed while the first socket is still in TIME_WAIT. I tweaked Cygwin > to enforce SO_REUSEADDR before bind, but connect still fails with > EADDRINUSE as long as the first socket is in TIME_WAIT. > > It seems the code path for listen/accept is different here compared to > connect. Given that SO_REUSEADDR seems to cover mostly server side > scenarios, and given that I don't see this scenario discussed at all > in Steven's book, I wonder if bind/connect is a bit of a grey area. > > Either way, the bottom line is that this is a WinSock restriction, > apparently. As of today, I don't see any way around that.
For completeness sake I converted your testcase into a WinSock-only executable, built with Mingw-w64, and the problem persists, on Windows7 as well as on Windows 10. Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Maintainer cygwin AT cygwin DOT com Red Hat
signature.asc
Description: PGP signature