--- tcp_input.c.org Sat Oct 13 23:24:38 2001 +++ tcp_input.c Sun Oct 14 15:47:10 2001 @@ -126,24 +126,25 @@ * sends good full-sized frames. */ len = skb->len; + if (len >= tp->ack.rcv_mss) { tp->ack.rcv_mss = len; - /* Dubious? Rather, it is final cut. 8) */ - if (tcp_flag_word(skb->h.th)&TCP_REMNANT) - tp->ack.pending |= TCP_ACK_PUSHED; } else { - /* Otherwise, we make more careful check taking into account, - * that SACKs block is variable. + /* If PSH is not set, packet should be full sized, assuming + * that the peer implements Nagle correctly. + * This observation (if it is correct 8)) allows + * to handle super-low mtu links fairly. * - * "len" is invariant segment length, including TCP header. + * However, If sender sets TCP_NODELAY, this could effectively + * turn receiver side SWS algorithms off. TCP_MIN_MSS guards + * against a ridiculously small rcv_mss estimate. + * + * We also have to be careful checking the header size, since + * the SACK option is variable length. "len" is the invariant + * segment length, including TCP header. */ len += skb->data - skb->h.raw; if (len >= TCP_MIN_RCVMSS + sizeof(struct tcphdr) || - /* If PSH is not set, packet should be - * full sized, provided peer TCP is not badly broken. - * This observation (if it is correct 8)) allows - * to handle super-low mtu links fairly. - */ (len >= TCP_MIN_MSS + sizeof(struct tcphdr) && !(tcp_flag_word(skb->h.th)&TCP_REMNANT))) { /* Subtract also invariant (if peer is RFC compliant), @@ -152,12 +153,9 @@ */ len -= tp->tcp_header_len; tp->ack.last_seg_size = len; - if (len == lss) { + if (len == lss) tp->ack.rcv_mss = len; - return; - } } - tp->ack.pending |= TCP_ACK_PUSHED; } }