Subject: kern/34749: packets with zero-length payload in SACK fast recovery
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <yamt@mwd.biglobe.ne.jp>
List: netbsd-bugs
Date: 10/07/2006 22:20:05
>Number:         34749
>Category:       kern
>Synopsis:       packets with zero-length payload in SACK fast recovery
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Oct 07 22:20:05 +0000 2006
>Originator:     YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
>Release:        NetBSD 4.99.3
>Organization:
	
>Environment:
	
	
System: NetBSD 4.99.3
Architecture: i386
Machine: i386
>Description:
	a comment in tcp_sack_newack says "send one or 2 segments".

	    tp->snd_cwnd = sack_bytes_rxmt +
		(tp->snd_nxt - tp->sack_newdata) + num_segs * tp->t_segsz;
	    tp->t_flags |= TF_ACKNOW;
	    (void) tcp_output(tp);

	but the above tcp_output produces a packet with zero payload if
		- all sacks holes are already acked by a cumulative ack.
		  (ie. sack_bytes_rxmt == 0)
	and
		- sack_newdata > snd_una + num_segs * segsz.

>How-To-Repeat:
	do a bulk transfer with a large window size
	and observe some mysterious packets with zero length payload during
	fast recovery.
>Fix:

Index: tcp_output.c
===================================================================
--- tcp_output.c	(revision 1810)
+++ tcp_output.c	(revision 1811)
@@ -796,7 +796,7 @@ again:
 	}
 
 	if (sack_rxmit == 0) {
-		if (sack_bytes_rxmt != 0) {
+		if (TCP_SACK_ENABLED(tp) && tp->t_partialacks >= 0) {
 			long cwin;
 
 			/*

>Unformatted: