From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21062 invoked by alias); 30 Apr 2013 19:11:12 -0000 Mailing-List: contact ecos-discuss-help@ecos.sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: ecos-discuss-owner@ecos.sourceware.org Received: (qmail 21049 invoked by uid 89); 30 Apr 2013 19:11:12 -0000 X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.1 Received: from plane.gmane.org (HELO plane.gmane.org) (80.91.229.3) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Tue, 30 Apr 2013 19:11:11 +0000 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1UXFxB-0001B4-J8 for ecos-discuss@ecos.sourceware.org; Tue, 30 Apr 2013 21:11:05 +0200 Received: from dsl.comtrol.com ([64.122.56.22]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Tue, 30 Apr 2013 21:11:05 +0200 Received: from grant.b.edwards by dsl.comtrol.com with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Tue, 30 Apr 2013 21:11:05 +0200 To: ecos-discuss@ecos.sourceware.org From: Grant Edwards Date: Tue, 30 Apr 2013 19:11:00 -0000 Message-ID: User-Agent: slrn/1.0.1 (Linux) Subject: [ECOS] BSD TCP connect() ignores SO_REUSEADDR option X-SW-Source: 2013-04/txt/msg00036.txt.bz2 I've recently noticed that when using the FreeBSD TCP stack, the connect() system call ignores the SO_REUSEADDRESS setting and returns EADDRINUSE when attempting to connect a TCP socket if a connection with the same (SrcIP,SrcPort,DstIP,DstPort) tuple is still hanging around in the TIME_WAIT state. Here's an example sequence of events: * create a TCP socket * set SO_REUSEADDRESS and SO_REUSEPORT options * bind to port 12346 * connect to 1.2.3.4:54321 * send a little data * close connection * wait a few seconds * create a TCP socket * set SO_REUSEADDRESS and SO_REUSEPORT options * bind() to port 12346 * connect() to 1.2.3.4:54321 The bind() will succeed due to the SO_REUSEADDR, SO_REUSEPORT option. The connect() will fail with EADDRINUSE. If you wait a minute or two between connections it works fine. There appear to be a certain set of conditions when an existing TIME_WAIT connection will be discarded and reused -- see line 747 below: >From tcp_usrreq.c: 733 /* 734 * Cannot simply call in_pcbconnect, because there might be an 735 * earlier incarnation of this same connection still in 736 * TIME_WAIT state, creating an ADDRINUSE error. 737 */ 738 error = in_pcbladdr(inp, nam, &ifaddr); 739 if (error) 740 return error; 741 oinp = in_pcblookup_hash(inp->inp_pcbinfo, 742 sin->sin_addr, sin->sin_port, 743 inp->inp_laddr.s_addr != INADDR_ANY ? inp->inp_laddr 744 : ifaddr->sin_addr, 745 inp->inp_lport, 0, NULL); 746 if (oinp) { 747 if (oinp != inp && (otp = intotcpcb(oinp)) != NULL && 748 otp->t_state == TCPS_TIME_WAIT && 749 (ticks - otp->t_starttime) < tcp_msl && 750 (otp->t_flags & TF_RCVD_CC)) 751 otp = tcp_close(otp); 752 else 753 return EADDRINUSE; 754 } But setting SO_REUSEADDR doesn't affect the behavior of connect(). Should it? -- Grant Edwards grant.b.edwards Yow! VICARIOUSLY experience at some reason to LIVE!! gmail.com -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss