From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30680 invoked by alias); 15 Jan 2018 20:03:28 -0000 Mailing-List: contact cygwin-help@cygwin.com; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner@cygwin.com Mail-Followup-To: cygwin@cygwin.com Received: (qmail 30549 invoked by uid 89); 15 Jan 2018 20:03:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-101.6 required=5.0 tests=AWL,BAYES_00,GOOD_FROM_CORINNA_CYGWIN,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=digging, observe, H*R:D*cygwin.com, H*R:U*cygwin X-HELO: drew.franken.de Received: from mail-n.franken.de (HELO drew.franken.de) (193.175.24.27) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 15 Jan 2018 20:03:00 +0000 Received: from aqua.hirmke.de (aquarius.franken.de [193.175.24.89]) (Authenticated sender: aquarius) by mail-n.franken.de (Postfix) with ESMTPSA id BE2B0721E2822 for ; Mon, 15 Jan 2018 21:02:49 +0100 (CET) Received: from calimero.vinschen.de (calimero.vinschen.de [192.168.129.6]) by aqua.hirmke.de (Postfix) with ESMTP id 325105E0362 for ; Mon, 15 Jan 2018 21:02:49 +0100 (CET) Received: by calimero.vinschen.de (Postfix, from userid 500) id 1C4A2A803C5; Mon, 15 Jan 2018 21:02:49 +0100 (CET) Date: Mon, 15 Jan 2018 20:03:00 -0000 From: Corinna Vinschen To: cygwin@cygwin.com Subject: Re: Cygwin socket option SO_REUSEADDR operates unlike Linux Message-ID: <20180115200249.GA3009@calimero.vinschen.de> Reply-To: cygwin@cygwin.com Mail-Followup-To: cygwin@cygwin.com References: <20180113135127.GA22225@calimero.vinschen.de> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="LQksG6bCIzRHxTLp" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.9.1 (2017-09-22) X-SW-Source: 2018-01/txt/msg00146.txt.bz2 --LQksG6bCIzRHxTLp Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-length: 3263 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 > > >=20 > > > ~ ./bindtest > > > 1st socket is 3 > > > 1st bind OK > > > 1st connect: Address already in use > > >=20 > > > On Fedora 27, running the same STC shows: > > >=20 > > > [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 > >=20 > > I can't reproduce this: > >=20 > > $ 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:* LIS= TEN > > tcp6 0 0 :::111 :::* LIS= TEN > > 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. Corinna --=20 Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Maintainer cygwin AT cygwin DOT com Red Hat --LQksG6bCIzRHxTLp Content-Type: application/pgp-signature; name="signature.asc" Content-length: 833 -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEoVYPmneWZnwT6kwF9TYGna5ET6AFAlpdCOgACgkQ9TYGna5E T6AtHg//fPm7RJzE+S9biURJiP3uVVSDyqULwjDYVZqMYjxg07cZ7cze7a9wDjOP tJeazTfyeKrljfqCLeRB0xKmq3FpJ8s3fRXv9d/6WlyqvoQ/uRbv6pw0hdNNj3YF NZuqnEeOm5ek3Sau7tydyeQ+oa4k9RT7Yp++h4hOPCZHOh5qma6YnxP4P+GKyqtk y0SwOsSNyT8muXcjuagSd5SGlNtqmkwnYPfNlE3JTgPbFIVj7RyhCLvhYjrEOLlB Nfl/YrGfysHH/RP7rAdEbbETmMmKY5bgogCluNfCpigFjUvZ8uK5zx1BpF1T5/VG r0tk3ttIDHyLpYoUTqLYk+r55ZarMLEWfqq/nIJUCV0A9ukmAzb8GW3W7pVoIdTq mGGIbi56rC7HviXXTsZ9vGrUcLpBduFLhNwN6dCrQ3xHczw5aD/ejzpk2z4E7wkB /4uUtextjd7ZTm9qPYLEPQOf4p3ikexWjcJLEqmZTfCy0v5F88hglaSq4b1Z3KWZ YpC27vj6yU1erTzmLfmZiVwrqW+y/iy36xCCZiMd7uwLn9q9W44RtajbJjQrzxFn CvJeVAWMqoXfKpazau4nUPmG28NQth+wk0EzO+mnDIIKDSSZCAf3grWj+13NE/R6 UdY8+lD/UlH1vNblgc+bLcpAvCtdkscNV4RZrWt+mBNppYidYls= =Plmc -----END PGP SIGNATURE----- --LQksG6bCIzRHxTLp--