net: tcp: Avoid SWS for the receiver
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 12 Jun 2017 18:13:37 +0000 (14:13 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 21 Jul 2017 15:56:27 +0000 (11:56 -0400)
commitd376475bbb172a09ce9230eb4cd2d96a642d935a
tree1ec61826d0bca4fc494db201dfe6c169012e99bc
parent682b414ddb840006ab670e3a128ef0695a9e256b
net: tcp: Avoid SWS for the receiver

See RFC 813 and 1122.  Basically, don't advertise very small increases in
the window.

The driver for this is actually qemu's user networking behavior.  If you
*almost* fill Akaros's receive window (qemu guest), but it is still not
fully closed, qemu will stop sending data.  It seems to happen once the
window is less than the MSS.  Qemu waits 5 seconds, then fills the window
completely.  That sounds like a possibly buggy implementation of the
recommended sender algorithm in RFC 813 (grep 'additional.*enhancement').
It wasn't a SWS issue, but this algorithm for fixing SWS forces an ACK when
becomes rcv.wnd >= MSS.  That additional enhancement *alone* seems to imply
window updates from the receiver that are not driven by anything sent by
the sender - not sure if that's legal or not.

Using the MSS as the cutoff for a small packet was recommended by RFC 1122.
Actually, they said min(BUF / 2, MSS), and for practical situations, the
MSS is always less than BUF / 2.

The important thing for us is to treat the window as closed and to update
the window when it opens back up.  Regardless of the SWS business, if we
happened to have closed the window fully on an ACK, we would never tell the
sender, since we were turning off the acktimer.  (Note from the future: if
this statement seems wrong from something you're seeing, reverify it.  We
definitely need to keep the acktimer going for Qemu to advertise rcv.wnd >=
tcb->mss).

Note that the TCP stack doens't get a callback or anything when the window
opens up - if we wanted to, we could set up qio callbacks to update the
window when the user drains the read queue.  It's a little trickier than
that, since we care about an edge at > MSS, not > 0.  That's independent of
this change, but figured I'd mention it.  Also, the whole tcptimer setup is
a bit hokey.  The acktimers are put in for 1 'count' (50 / 50, grep
MSPTICK), and the expected value for the first tick is 25ms.  Just from
looking at tcpdumps, I'll see Akaros waiting for about 25-50ms between the
window-closing ACK and the window update.  Presumably we could have opened
the window before that.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/src/net/tcp.c