From owner-freebsd-bugs@FreeBSD.ORG Mon Oct 11 07:40:29 2004 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9B97016A4CF for ; Mon, 11 Oct 2004 07:40:29 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 796C443D2F for ; Mon, 11 Oct 2004 07:40:29 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.11/8.12.11) with ESMTP id i9B7eTRM055534 for ; Mon, 11 Oct 2004 07:40:29 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.11/8.12.11/Submit) id i9B7eTxU055533; Mon, 11 Oct 2004 07:40:29 GMT (envelope-from gnats) Resent-Date: Mon, 11 Oct 2004 07:40:29 GMT Resent-Message-Id: <200410110740.i9B7eTxU055533@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Michiel Boland Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id BBDD916A4CE for ; Mon, 11 Oct 2004 07:38:21 +0000 (GMT) Received: from smtp-vbr9.xs4all.nl (smtp-vbr9.xs4all.nl [194.109.24.29]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4182243D1D for ; Mon, 11 Oct 2004 07:38:21 +0000 (GMT) (envelope-from michiel@boland.org) Received: from xs6.xs4all.nl (xs6.xs4all.nl [194.109.21.6]) by smtp-vbr9.xs4all.nl (8.12.11/8.12.11) with ESMTP id i9B7cKIa026268 for ; Mon, 11 Oct 2004 09:38:20 +0200 (CEST) (envelope-from michiel@boland.org) Received: from xs6.xs4all.nl (boland37@localhost.xs4all.nl [127.0.0.1]) by xs6.xs4all.nl (8.12.10/8.12.10) with ESMTP id i9B7cKXC079710 for ; Mon, 11 Oct 2004 09:38:20 +0200 (CEST) (envelope-from michiel@boland.org) Received: (from boland37@localhost) by xs6.xs4all.nl (8.12.10/8.12.9/Submit) id i9B7cKIN079709 for FreeBSD-gnats-submit@freebsd.org; Mon, 11 Oct 2004 09:38:20 +0200 (CEST) (envelope-from michiel@boland.org) Message-Id: <200410110738.i9B7cKIN079709@xs6.xs4all.nl> Date: Mon, 11 Oct 2004 09:38:20 +0200 (CEST) From: Michiel Boland To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: kern/72502: TCP should honour incoming RSTs even if the receive window is closed X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Oct 2004 07:40:29 -0000 >Number: 72502 >Category: kern >Synopsis: TCP should honour incoming RSTs even if the receive window is closed >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Oct 11 07:40:28 GMT 2004 >Closed-Date: >Last-Modified: >Originator: Michiel Boland >Release: FreeBSD 6.0-CURRENT i386 >Organization: >Environment: System: FreeBSD leefnet.office.internl.net 6.0-CURRENT FreeBSD 6.0-CURRENT #0: Sat Oct 9 15:53:21 CEST 2004 root@leefnet.office.internl.net:/usr/obj/usr/src/sys/LEEFNET i386 >Description: TCP should honour incoming RST segments, even if the receive window is closed. (See RFC793, page 26.) Currently, FreeBSD drops RST packets on the floor, which may cause applications to hang indefinitely. >How-To-Repeat: The following code sets up two connected TCP sockets that send data to each other until the window is closed. Then one of the sockets is closed, which will generate a RST once the TCP at the other socket does a window probe. But the RST is ignored, therefore the application will never exit. After applying the patch below, the app will exit after a couple of seconds. (FWIW Linux 2.4 and Solaris 7-9 do this correctly.) #include #include #include #include #include #include #include int main(void) { int o, s, t, u, do_t, do_u; struct pollfd pfd[2]; struct sockaddr_in sa; char buf[4096]; s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) return 1; o = 1; setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &o, sizeof o); memset(&sa, 0, sizeof sa); sa.sin_family = AF_INET; sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); sa.sin_port = htons(3737); if (bind(s, (struct sockaddr *) &sa, sizeof sa) == -1) return 1; if (listen(s, 1) == -1) return 1; t = socket(AF_INET, SOCK_STREAM, 0); if (t == -1) return 1; if (connect(t, (struct sockaddr *) &sa, sizeof sa) == -1) return 1; u = accept(s, 0, 0); if (u == -1) return 1; close(s); fcntl(t, F_SETFL, fcntl(t, F_GETFL) | O_NONBLOCK); fcntl(u, F_SETFL, fcntl(t, F_GETFL) | O_NONBLOCK); do_t = 1; do_u = 1; pfd[0].fd = t; pfd[0].events = POLLOUT; pfd[1].fd = u; pfd[1].events = POLLOUT; while (do_t || do_u) { if (poll(pfd, 2, 1000) == 0) { close(t); pfd[0].fd = -1; do_t = 0; continue; } if (pfd[0].revents & POLLOUT) { if (write(t, buf, sizeof buf) == -1) { close(t); pfd[0].fd = -1; do_t = 0; } } if (pfd[1].revents & POLLOUT) { if (write(u, buf, sizeof buf) == -1) { close(u); pfd[1].fd = -1; do_u = 0; } } } return 0; } >Fix: Apply the following patch to src/sys/netinet/tcp_input.c --- tcp_input.c.orig Tue Oct 5 20:36:23 2004 +++ tcp_input.c Mon Oct 11 01:32:17 2004 @@ -1622,8 +1622,9 @@ * RFC 1337. */ if (thflags & TH_RST) { - if (SEQ_GEQ(th->th_seq, tp->last_ack_sent) && - SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) { + if ((SEQ_GEQ(th->th_seq, tp->last_ack_sent) && + SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) || + (tp->rcv_wnd == 0 && tp->last_ack_sent == th->th_seq)) { switch (tp->t_state) { case TCPS_SYN_RECEIVED: >Release-Note: >Audit-Trail: >Unformatted: