kern/75122: [PATCH] Incorrect inflight bandwidth calculation on first packet

Uwe Doering gemini at geminix.org
Sat Dec 18 04:10:31 PST 2004


The following reply was made to PR kern/75122; it has been noted by GNATS.

From: Uwe Doering <gemini at geminix.org>
To: Dan Nelson <dnelson at allantgroup.com>
Cc: FreeBSD-gnats-submit at FreeBSD.org, freebsd-bugs at FreeBSD.org
Subject: Re: kern/75122: [PATCH] Incorrect inflight bandwidth calculation
 on	first packet
Date: Sat, 18 Dec 2004 13:09:14 +0100

 Dan Nelson wrote:
 > Updated patch including Matt's recommended fix:
 > 
 > [...]
 > diff -u -p -r1.201.2.4 tcp_subr.c
 > --- tcp_subr.c	1 Dec 2004 05:37:28 -0000	1.201.2.4
 > +++ tcp_subr.c	16 Dec 2004 06:38:48 -0000
 > [...]
 > @@ -1922,29 +1922,42 @@ tcp_xmit_bandwidth_limit(struct tcpcb *t
 >  	}
 >  
 >  	/*
 > +	  * Validate the delta time.  If a connection is new or has been idle
 > +	  * a long time we have to reset the bandwidth calculator.
 > +	  */
 > +	save_ticks = ticks;
 > +	delta_ticks = save_ticks - tp->t_bw_rtttime;
 > +	if (tp->t_bw_rtttime == 0 || delta_ticks < 0 || delta_ticks > hz * 10) {
 > +		tp->t_bw_rtttime = ticks;
 > +		tp->t_bw_rtseq = ack_seq;
 > +		if (tp->snd_bandwidth == 0)
 > +			tp->snd_bandwidth = tcp_inflight_min;
 > +		return;
 > +	}
 > +	if (delta_ticks == 0)
 > +		return;
 > +	
 > +	/*
 > +	 * Sanity check, plus ignore pure window update acks.
 > +	 */
 > +	if ((int)(ack_seq - tp->t_bw_rtseq) <= 0)
 > +		return;
 
 I wonder, isn't there a flaw in the logic with regard to the sequence 
 number handling?  If the sequence number wraps around 't_bw_rtseq' no 
 longer gets set and therefore the bandwidth calculation stops until 
 'ack_seq' either catches up with 't_bw_rtseq' again (which would take 
 quite a while), or 'ticks' wraps around as well, or there is inactivity 
 for more than 10 seconds.  This is probably not the intended behavior.
 
 I think the correct approach would be to separate the handling of the 
 two cases "sequence number wrap-around" and "window update acks".  I 
 suggest to define another variable 'delta_bytes' and initialize it like 
 this:
 
    int delta_bytes;
    [...]
    delta_bytes = ack_seq - tp->t_bw_rtseq;
 
 Then compare it with zero where you compare 'delta_ticks' with zero, and 
 check for less than zero (wrap-around) where you check 'delta_ticks' for 
 less than zero.  Combine the respective test results with '||'.  Of 
 course, you can then use 'delta_bytes' for the bandwidth calculation 
 further down in the code, too.
 
     Uwe
 -- 
 Uwe Doering         |  EscapeBox - Managed On-Demand UNIX Servers
 gemini at geminix.org  |  http://www.escapebox.net


More information about the freebsd-bugs mailing list