TCP之ACK/DUPACK

RFC中ACK/DUPACK的说明如下:
   The delayed ACK algorithm specified in [RFC1122] SHOULD be used by a
   TCP receiver.  When using delayed ACKs, a TCP receiver MUST NOT
   excessively delay acknowledgments.  Specifically, an ACK SHOULD be
   generated for at least every second full-sized segment, and MUST be
   generated within 500 ms of the arrival of the first unacknowledged
   packet.

   The requirement that an ACK "SHOULD" be generated for at least every
   second full-sized segment is listed in [RFC1122] in one place as a
   SHOULD and another as a MUST.  Here we unambiguously state it is a
   SHOULD.  We also emphasize that this is a SHOULD, meaning that an
   implementor should indeed only deviate from this requirement after
   careful consideration of the implications.  See the discussion of
   "Stretch ACK violation" in [RFC2525] and the references therein for a
   discussion of the possible performance problems with generating ACKs
   less frequently than every second full-sized segment.

   In some cases, the sender and receiver may not agree on what
   constitutes a full-sized segment.  An implementation is deemed to
   comply with this requirement if it sends at least one acknowledgment
   every time it receives 2*RMSS bytes of new data from the sender,
   where RMSS is the Maximum Segment Size specified by the receiver to
   the sender (or the default value of 536 bytes, per [RFC1122], if the
   receiver does not specify an MSS option during connection
establishment).  The sender may be forced to use a segment size less
   than RMSS due to the maximum transmission unit (MTU), the path MTU
   discovery algorithm or other factors.  For instance, consider the
   case when the receiver announces an RMSS of X bytes but the sender
   ends up using a segment size of Y bytes (Y < X) due to path MTU
   discovery (or the sender's MTU size).  The receiver will generate
   stretch ACKs if it waits for 2*X bytes to arrive before an ACK is
   sent.  Clearly this will take more than 2 segments of size Y bytes.
   Therefore, while a specific algorithm is not defined, it is desirable
   for receivers to attempt to prevent this situation, for example, by
   acknowledging at least every second segment, regardless of size.
   Finally, we repeat that an ACK MUST NOT be delayed for more than 500
   ms waiting on a second full-sized segment to arrive.

   Out-of-order data segments SHOULD be acknowledged immediately, in
   order to accelerate loss recovery.  To trigger the fast retransmit
   algorithm, the receiver SHOULD send an immediate duplicate ACK when
   it receives a data segment above a gap in the sequence space.  To
   provide feedback to senders recovering from losses, the receiver
   SHOULD send an immediate ACK when it receives a data segment that
   fills in all or part of a gap in the sequence space.

   A TCP receiver MUST NOT generate more than one ACK for every incoming
   segment, other than to update the offered window as the receiving
   application consumes new data (see [RFC813] and page 42 of [RFC793]).
TCP的接收端收到一个报文段时,向发送端发送一个ACK来对其进行确认(也就是所谓的下一个期望数据的序号)。
通常TCP在接收到数据时并不立即发送ACK;相反,它推迟发送,以便将ACK与需要沿该方向发送的数据一起发送
(有时候称这种现象为数据捎带ACK),这就是经受时延的确认。但是在收到一个失序的报文段时,TCP需要立即
产生一个ACK(一个重复的ACK),这个重复的ACK不应该被延迟,目的在于让对方知道收到一个失序的报文段。
内核中发送ACK的函数为tcp_send_ack():

内核中对dupack的定义是一个否定的定义:

即一个报文段带有数据(not pure ack)或者ack了新的数据或者或者通告了接收窗口扩大的不是dupack,反之是dupack。

References:

https://tools.ietf.org/html/rfc5681#page-11