Date: Thu, 22 Jan 2004 10:50:41 -0800 (PST) From: Roselyn Lee <rosel@verniernetworks.com> To: freebsd-gnats-submit@FreeBSD.org Subject: misc/61744: TCP hangs onto mbufs with no tcp data unnecessily under certain error conditions Message-ID: <200401221850.i0MIofn2006578@www.freebsd.org> Resent-Message-ID: <200401221900.i0MJ0aWd011114@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 61744 >Category: misc >Synopsis: TCP hangs onto mbufs with no tcp data unnecessily under certain error conditions >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Jan 22 11:00:35 PST 2004 >Closed-Date: >Last-Modified: >Originator: Roselyn Lee >Release: 4.8a1 >Organization: Vernier Networks >Environment: 4.8-RELEASE FreeBSD 4.8-RELEASE #0 >Description: In tcp_reass(), if we get a duplicate ACK with len = 0, we queue the mbuf. This is not necessary because there is no additional data in this mbuf that's useful for this tcp session. Under certain error conditions, we've seen VMware clients running freebsd send thousands of FIN/ACKs with duplicate sequence #'s and tcp len = 0. These result in mbufs being held on the system until the socket is closed. Sometimes this could result in mbuf exhaustion on the system. >How-To-Repeat: In our environment, we can reproduce the the problem as follows: 1. setup a freebsd pptp client (mpd) to connect to the freebsd server but have it use the wrong password so it will keep trying to talk. 2. Have the client 'disappear' for seconds to minutes and 'reappear' to the server. We do this by making the client roam away out of range. 3. Sometimes, this will result in thousands of FIN/ACKs with same seq#. Here is a partial tcpdump summary when the error condition is reached. Starting at froamd 2740, the FIN/ACK exchange continues until frame 20877 - looks like the client roams out of range at this point and returns a few seconds later. The tcpdump was filtered for this client only and so there a some gaps in the seq. But 90% of the packets captured from frames 2740 to 20877 were for this client. 2562 13:31:34.3043 42.0.0.1 42.171.25.102 PPP CHAP PPP CHAP Failure 127 2562 2563 13:31:34.3078 42.0.0.1 42.171.25.102 PPP LCP PPP LCP Termination Request 60 2563 2564 13:31:34.3113 42.171.25.102 42.0.0.1 PPTP CLEAR-CALL-REQUEST 70 2564 2565 13:31:34.3140 42.0.0.1 42.171.25.102 PPTP DISCONNECT-NOTIFY 202 2565 2566 13:31:34.3156 42.0.0.1 42.171.25.102 PPTP STOP-CONTROL-REQUEST 70 2566 2567 13:31:34.3174 42.171.25.102 42.0.0.1 TCP 1194 > pptp [ACK] Seq=3599677643 Ack=1998493514 Win=58236 Len=0 60 2567 2568 13:31:34.3231 42.171.25.102 42.0.0.1 PPTP STOP-CONTROL-REQUEST 70 2568 2569 13:31:34.3266 42.171.25.102 42.0.0.1 PPTP STOP-CONTROL-REPLY 70 2569 2570 13:31:34.3268 42.0.0.1 42.171.25.102 TCP pptp > 1194 [ACK] Seq=1998493514 Ack=3599677675 Win=65535 Len=0 60 2570 2571 13:31:34.3272 42.0.0.1 42.171.25.102 PPTP STOP-CONTROL-REPLY 70 2571 2572 13:31:34.3274 42.0.0.1 42.171.25.102 TCP pptp > 1194 [FIN, ACK] Seq=1998493530 Ack=3599677675 Win=65535 Len=0 60 2572 2573 13:31:34.3286 42.171.25.102 42.0.0.1 TCP 1194 > pptp [ACK] Seq=3599677675 Ack=1998493531 Win=58384 Len=0 60 2573 2574 13:31:34.3304 42.171.25.102 42.0.0.1 TCP 1194 > pptp [FIN, ACK] Seq=3599677675 Ack=1998493531 Win=58400 Len=0 60 2574 2575 13:31:34.3305 42.0.0.1 42.171.25.102 TCP pptp > 1194 [ACK] Seq=1998493531 Ack=3599677676 Win=65535 Len=0 60 2575 2739 13:31:40.3816 42.0.0.1 42.171.25.102 TCP pptp > 1193 [ACK] Seq=1565198537 Ack=2686410455 Win=32942 Len=0 60 2739 2740 13:31:40.3835 42.171.25.102 42.0.0.1 TCP 1193 > pptp [FIN, ACK] Seq=2686410655 Ack=1565198538 Win=57920 Len=0 66 2740 2741 13:31:40.3836 42.0.0.1 42.171.25.102 TCP pptp > 1193 [FIN, ACK] Seq=1565198702 Ack=2686410455 Win=32942 Len=0 66 2741 2742 13:31:40.3862 42.171.25.102 42.0.0.1 TCP 1193 > pptp [FIN, ACK] Seq=2686410655 Ack=1565198538 Win=57920 Len=0 66 2742 2743 13:31:40.3862 42.0.0.1 42.171.25.102 TCP pptp > 1193 [FIN, ACK] Seq=1565198702 Ack=2686410455 Win=32942 Len=0 66 2743 2744 13:31:40.3885 42.171.25.102 42.0.0.1 TCP 1193 > pptp [FIN, ACK] Seq=2686410655 Ack=1565198538 Win=57920 Len=0 66 2744 2745 13:31:40.3885 42.0.0.1 42.171.25.102 TCP pptp > 1193 [FIN, ACK] Seq=1565198702 Ack=2686410455 Win=32942 Len=0 66 2745 .... 20877 13:31:49.3741 42.171.25.102 42.0.0.1 TCP 1193 > pptp [FIN, ACK] Seq=2686410655 Ack=1565198538 Win=57920 Len=0 66 20877 20878 13:31:49.3741 42.0.0.1 42.171.25.102 TCP pptp > 1193 [FIN, ACK] Seq=1565198702 Ack=2686410455 Win=32942 Len=0 66 20878 21192 13:31:56.2532 42.171.25.102 42.0.0.1 TCP 1196 > pptp [SYN] Seq=926832057 Ack=0 Win=57344 Len=0 74 21192 21193 13:31:56.2534 42.0.0.1 42.171.25.102 TCP pptp > 1196 [SYN, ACK] Seq=1341705398 Ack=926832058 Win=65535 Len=0 74 21193 21194 13:31:56.2549 42.171.25.102 42.0.0.1 TCP 1196 > pptp [ACK] Seq=926832058 Ack=1341705399 Win=57920 Len=0 66 21194 21195 13:31:56.2550 42.0.0.1 42.171.25.102 TCP pptp > 1196 [ACK] Seq=1341705399 Ack=926832058 Win=32942 Len=0 66 21195 >Fix: The following patch to tcp_input.c's tcp_reass() routine seems to do the trick. --- freebsd/sys/netinet/tcp_input.c 5 Jun 2003 02:12:11 -0000 1.3 +++ freebsd/sys/netinet/tcp_input.c 22 Jan 2004 17:52:54 -0000 1.4 @@ -219,20 +219,29 @@ * Try to present any queued data * at the left window edge to the user. * This is needed after the 3-WHS * completes. */ goto present; /* ??? */ } m_adj(m, i); *tlenp -= i; th->th_seq += i; + } else if (i == 0 && p->tqe_len == 0 && *tlenp == 0) { + /* + * This means we're getting the same seq# and + * there is no new data. Just drop it. + */ + tcpstat.tcps_rcvduppack++; + m_freem(m); + free(te, M_TSEGQ); + return (0); } } tcpstat.tcps_rcvoopack++; tcpstat.tcps_rcvoobyte += *tlenp; /* * While we overlap succeeding segments trim them or, * if they are completely covered, dequeue them. */ while (q) { >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200401221850.i0MIofn2006578>