Updating send window (snd_wnd)

hiren panchasara hiren at strugglingcoder.info
Wed Mar 16 01:46:56 UTC 2016

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

Send window update happens at 2 places in our code right now inside
tcp_do_segment() in tcp_input.c

Block1 In "process_ACK:"
        if (acked > sbavail(&so->so_snd)) {
                tp->snd_wnd -= sbavail(&so->so_snd);
                mfree = sbcut_locked(&so->so_snd,
                ourfinisacked = 1;
        } else {
                mfree = sbcut_locked(&so->so_snd, acked);
                tp->snd_wnd -= acked;
                ourfinisacked = 0;

Block2 In "step6:"

        if ((thflags & TH_ACK) &&
            (SEQ_LT(tp->snd_wl1, th->th_seq) ||
            (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
             (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {

Logic in plain english:
snd_wl1;     last seg that updated window
snd_wl2;     last ack that updated window

snd_wl1 <= th_seq ||                            seq is newer
snd_wl1 == th_seq && snd_wl2 <= th_ack ||       seq is same but ack is newer
snd_wl2 == th_ack && tiwin > snd_wnd            ack is same but window is larger

So, in Block1, we more or less decrement snd_wnd by number of bytes
acked. Later in Block2, we use that (changed) value in making decision
of whether we'd accept window update from a certain ack or not.

What is the importance of that logic/code in Block1? I didn't find any
specific reference of that in RFCs though TCP/IP Illustrated Vol.2 has
that without specific explanation.

NetBSD is same as FreeBSD but I don't think Linux subtracts acked bytes
from snd_wnd based on my cursory look at their code.

(Differences of Block2 between different implementations is another can
of worms but I'll leave that to another day. :-))

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 603 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-transport/attachments/20160315/09ae4614/attachment.sig>

More information about the freebsd-transport mailing list