Updating send window (snd_wnd)

Jonathan T. Looney jtl at freebsd.org
Wed Mar 16 16:55:11 UTC 2016


On 3/15/16, 6:46 PM, "hiren panchasara"
<owner-freebsd-transport at freebsd.org on behalf of
hiren at strugglingcoder.info> wrote:

>While discussing an issue we are seeing in field, Jonathan pointed out
>another issue where snd_wnd can underflow and he created a review for it
>with a possible fix: https://reviews.freebsd.org/D5625
>
>But he also raised a valid point of whether that specific logic is
>correct/needed or not. I.e. should we decrement snd_wnd by number of bytes
>acked when we are anyhow going to get window information from the
>client?

Hiren,

Thanks for starting this discussion! I wrote the review to add underflow
prevention with the idea that underflow prevention is "easy", while this
discussion will probably be "harder". Partly, that was because I had begun
to think further through my own question. :-)

I think a summary of the way things *should* work today is:
A. We should always trust the "current" window sent by the remote host.
B. When we don't know the "current" window send by the remote host, we
should decrement our local copy of the send window as we use window space.

The trick here is the word I set off in quotes in (A): "current".

If all packets are in order, this is easy: just always use the window in
the ACK from the client.

When packets arrive out-of-order, things become more tricky. Which window
advertisement do you believe? I think that is the point of the "step6"
logic Hiren quoted.

(However, I'm not sure that the "step6" logic works correctly. For
example, what if you have a retransmission from the remote side? In that
case, a newer packet could have an older sequence number. But, let's leave
that aside for the moment and assume it does work correctly.)

I *believe* it is correct to say that we should always be able to trust
the window advertised by any packet that ACKs new bytes. (In general, it
should be true that any packet that moves the ACK was sent later than any
other packet we've received so far.) And, we probably *should* trust any
larger window advertisement that doesn't change the ACK.

When we are between packets that authoritatively set the window, we can
just keep decrementing our local copy of the window as the remote side
ACKs more bytes.

But, think closely about that last sentence: do we really ever need to
worry about step (B)? When we get a packet which ACKs new bytes, isn't
that packet - almost by definition - the latest packet? It seems to me
that step (B) may have the greatest implications in a situation where we
have lots of SACKs, etc. going on and you MAY be able to open the window
slightly sooner if you can sift through that to discern which window
advertisement is the latest. But, even that shouldn't require
*decrementing* the window as the remote side ACKs new bytes. By
definition, isn't the window advertised in a packet that ACKs new bytes
the latest word on available space on the remote host?

In short, I just don't see a use case for step (B) above. It seems to me
that anytime we have a packet that ACKs new bytes, it - by definition -
contains the "current" window, and we should just use it.

Sorry for the long, convoluted email. But, like many things involving the
decades-old TCP code, the very topic is long and convoluted. :-)

Jonathan 




More information about the freebsd-transport mailing list