socket receive buffer size & window updates

Vijay Singh vijju.singh at gmail.com
Tue Mar 11 17:58:49 UTC 2014


The socket option handler currently doesn't prevent connecting or connected
sockets from changing their receive buffer sizes. In particular, I ran into
a an application that sets the receive buffer size lower than what it
originally was.

In tcp_output(), if no data is being sent, there is code that is trying to
decide if a window update is needed.

If the socket receive buffer size was reduced after a larger window was
already advertized, or perhaps even when there is data in the receive
buffer, it seems to me that the computation in 592 could go -ve, and be
interpreted as a large window update.

I was led to this issue after observing in packet traces that duplicate
FINs were being sent on close. I tracked it down to this check. Should this
be changed to a check like such?

if (adv >= oldwin)
    adv -= oldwin;
else
    adv = 0;

  586 <http://fxr.watson.org/fxr/source/netinet/tcp_output.c#L586>
            long adv <http://fxr.watson.org/fxr/ident?i=adv>;
  587 <http://fxr.watson.org/fxr/source/netinet/tcp_output.c#L587>
            int oldwin;
  588 <http://fxr.watson.org/fxr/source/netinet/tcp_output.c#L588>
  589 <http://fxr.watson.org/fxr/source/netinet/tcp_output.c#L589>
            adv <http://fxr.watson.org/fxr/ident?i=adv> = min
<http://fxr.watson.org/fxr/ident?i=min>(recwin, (long)TCP_MAXWIN
<http://fxr.watson.org/fxr/ident?i=TCP_MAXWIN> << tp
<http://fxr.watson.org/fxr/ident?i=tp>->rcv_scale);
  590 <http://fxr.watson.org/fxr/source/netinet/tcp_output.c#L590>
            if (SEQ_GT <http://fxr.watson.org/fxr/ident?i=SEQ_GT>(tp
<http://fxr.watson.org/fxr/ident?i=tp>->rcv_adv, tp
<http://fxr.watson.org/fxr/ident?i=tp>->rcv_nxt
<http://fxr.watson.org/fxr/ident?i=rcv_nxt>)) {
  591 <http://fxr.watson.org/fxr/source/netinet/tcp_output.c#L591>
                    oldwin = (tp
<http://fxr.watson.org/fxr/ident?i=tp>->rcv_adv - tp
<http://fxr.watson.org/fxr/ident?i=tp>->rcv_nxt
<http://fxr.watson.org/fxr/ident?i=rcv_nxt>);
  592 <http://fxr.watson.org/fxr/source/netinet/tcp_output.c#L592>
                    adv <http://fxr.watson.org/fxr/ident?i=adv> -=
oldwin;
  593 <http://fxr.watson.org/fxr/source/netinet/tcp_output.c#L593>
            } else
  594 <http://fxr.watson.org/fxr/source/netinet/tcp_output.c#L594>
                    oldwin = 0;

-vijay


More information about the freebsd-net mailing list