tcp_output.c:560 - is this code correct?

Stefan `Sec` Zehl sec at 42.org
Sat Jan 15 01:45:53 UTC 2011


Hi,

I just found a bug in FreeBSD amd64 -- (see the PR#kern/154006)
a missing "(long)" cast in tcp_output.c.

I have a question about this code (around line 560) where adv is
calculated:

| 	if (recwin > 0 && !(tp->t_flags & TF_NEEDSYN) &&
| 	    !TCPS_HAVERCVDFIN(tp->t_state)) {
| 		/*
| 		 * "adv" is the amount we can increase the window,
| 		 * taking into account that we are limited by
| 		 * TCP_MAXWIN << tp->rcv_scale.
| 		 */
| 		long adv = min(recwin, (long)TCP_MAXWIN << tp->rcv_scale) -
| 			(tp->rcv_adv - tp->rcv_nxt);
| [...]

adv is getting negative in my case (receiver window size == 0) because
recwin == (tp->rcv_adv - tp->rcv_nxt), but 
recwin is bigger than (TCP_MAXWIN << tp->rcv_scale)

>From the comment above it seems that adv shouldn't be negative ever. So
I wonder if that code was meant to be:

long adv = min(recwin - (tp->rcv_adv - tp->rcv_nxt) ,
	       (long)TCP_MAXWIN << tp->rcv_scale);

instead? 

At least as far as I understand the code, that would make more sense.

Thanks,
    Sec
-- 
The problem with troubleshooting is that trouble shoots back.


More information about the freebsd-hackers mailing list