Subject: Nagle on send

From: Greg Minshall <[email-masked]>
Date: Thu, 11 Mar 1999 12:26:45 -0800

Hi.  Thanks for people's responses to my query of "what does Nagle on send 
mean?".

Here are what i think the variants are:

1.  FreeBSD 2.2.5, for example, says that if the send is bigger than an MTU 
but isn't too big (bigger than MCLBYTES), and there was no outstanding 
unacknowledged data, then all the data in the send, including any residual 
data making up only a small packet, will be transmitted.

2.  What i think most people would agree on:  If the send is bigger than an 
MTU, then even if there is unacknowledged data, then all the data in the send 
(no matter how large the send was, more or less), including any residual data 
making up only a small packet, will be transmitted.

3.  (I think this is what Vernon has in mind.)  If the send is not big enough 
and there is data in the pipe and NODELAY is not set, then don't call 
tcp_output().  And (if i understand correctly) don't do any Nagle in 
tcp_output().

OK, so forget #1 above (it doesn't meet most of our idea of "Nagle on send").

(I'm going to concentrate on #2, since i have a problem with #3, since i think 
it means that the next ACK received will cause a small packet to be generated, 
even if the next ACK doesn't acknowledge all outstanding data, and i'm not 
sure that is a good idea.  Also, the *intent* (and, i guess, mostly the 
*effect*) of #3 is the same as that of #2.)

Case #2 breaks into two categories, based on what happens if the current 
window/cwnd doesn't allow you to immediately transmit all the data from the 
send:

2a.  If because of window issues all the data can't be transmitted, then 
future transmissions will be constrained by things like "traditional Nagle".

2b.  If because of window issues all the data can't be transmitted, then 
future transmissions will *not* be constrained by things like "traditional 
Nagle".

I think one would prefer 2b.  I.e., the application makes a 64KB send() into a 
somewhat full pipe (i.e., data already transmitting), then you'd like to send 
the final 1296 (whatever) bytes as soon as the window allows, rather than 
waiting for all the data to drain from the pipe and the acknowledgment of the 
final 1460 byte segment.

Thoughts?

Greg

---

From: Vernon Schryver <[email-masked]>
Date: Thu, 11 Mar 1999 16:12:18 -0700 (MST)

> From: Greg Minshall <[email-masked]>

> ...

No, I think I said 
    put the data in the socket buffer;
    if (!NODELAY)
        tcp_output();

There's nothing there about sizes.

> *effect*) of #3 is the same as that of #2.)

    - silly window avoidance is not the Nagle algorithm, and vice versa.
    	If your tcp_output() is not broken, then it won't generate any
        bad small packets.

    - if you have 1 byte waiting to send, 10K waiting to be Acked, and
       you receive an Ack for 1 MSS and with no data, then (ignoring SWS
       prevention), it is ok to send even with Nagle on because you know
       you're not going to be able to piggyback.   If the Ack came with
       data, then you should definitely send your tiny data (modulo SWS).

    - most of us agree that the intention or purpose of the Nagle algorithm
       is <<NOT>> to prevent small packets, but to piggyback small data
       on Acks instead of in their own packets.   That distinction is
       significant, and allows you avoid being obssessd with the sizes of
       packets.  That obsession is a Bad Thing because it leads to
       additional TCB state, code, and debugging opportunties.

    - sending small packets is <<GOOD>> even with the Nagle algorithm on
       provided there is no opportunity for piggybacking, and provided
       you believe the algorithm sould be applied to application send
       requests instead the bowels of the TCP state machine.

> ...

> Thoughts?

I think I'm opposed, because it is still not applying the Nagle algorithm
to application send requests, and it is still obsessing on the sizes of
packets instead of trying to utilize opportunities for piggybacking.

vjs