Date: Tue, 1 Mar 2005 05:49:13 GMT From: Noritoshi Demizu <demizu@dd.iij4u.or.jp> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/78226: rcv_lastsack in struct tcpcb is not updated when the right most SACK block expands. Message-ID: <200503010549.j215nDjk068343@www.freebsd.org> Resent-Message-ID: <200503010550.j215oHW9067729@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 78226 >Category: kern >Synopsis: rcv_lastsack in struct tcpcb is not updated when the right most SACK block expands. >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: Tue Mar 01 05:50:16 GMT 2005 >Closed-Date: >Last-Modified: >Originator: Noritoshi Demizu >Release: FreeBSD 6.0 current (as of Mar 1, 2005) >Organization: NICT >Environment: FreeBSD xxx 6.0-CURRENT FreeBSD 6.0-CURRENT #7: Tue Mar 1 10:50:54 JST 2005 noritosi@xxx:/home/FreeBSD-current/src/sys/i386/compile/GENERIC i386 >Description: rcv_lastsack in struct tcpcb is "last seq number(+1) sack'd by rcv'r" according to the comment in tcp_var.h. In tcp_sack.c Rev 1.9, it is updated only when the first SACK block or a new right most SACK block is reported. In other words, it is not updated when the right most SACK block expands to the right. Hence, tcp_sack_adjust() may choose inappropriate snd_nxt at the last line. >How-To-Repeat: In my experimental environment, there are three machines: a sender, a router and a receiver. Dummynet runs on the router configured as RTT=40ms, bandwidth=10Mbps, queue=8pkts and plr=0.03. The sender's buffer size and the receiver's buffer size are 192k bytes. In the environment, when a fast retransmitted packet is lost, the sender has to wait for a timeout. But the sender keeps sending data segments until the timeout is triggered because buffer is big enough. In such case, just after the timeout, the sender keeps receiving ACK segments containing SACK information of segments sent before the timeout. Such SACK information can be used to avoid unnecessary retransmission. However, since rcv_lastsack is not updated when fack advances, sack'd data are sent unnecessarily. >Fix: The following patch fixes this problem in my environment. Since rcv_lastsack is referred only when snd_holes != NULL, this patch does not touch tcp_del_sackholes() and tcp_free_sackholes(). --- tcp_sack.c-ORG Mon Feb 28 10:43:29 2005 +++ tcp_sack.c Tue Mar 1 14:46:16 2005 @@ -431,6 +431,8 @@ tp->rcv_lastsack = sack.end; tp->snd_numholes++; } + if (SEQ_LT(tp->rcv_lastsack, sack.end)) + tp->rcv_lastsack = sack.end; } return (0); } >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200503010549.j215nDjk068343>