This commit adds an initial implemented of TCP delayed ACKs as specified in RFC 1122.

Squashed commit of the following:

    net/tmp:  Rename the unacked field of the tcp connection structure to tx_unacked.  Too confusing with the implementation of delayed RX ACKs.

    net/tcp:  Initial implementation of TCP delayed ACKs.

    net/tcp:  Add delayed ACK configuration selection.  Rename tcp_ack() to tcp_synack().  It may or may not send a ACK.  It will always send SYN or SYN/ACK.
This commit is contained in:
Gregory Nutt
2019-12-08 13:13:51 -06:00
parent 594734e0ae
commit 66ef6d143a
12 changed files with 174 additions and 71 deletions
+51 -6
View File
@@ -60,6 +60,20 @@
#include "socket/socket.h"
#include "tcp/tcp.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Per RFC 1122: "... an ACK should not be excessively delayed; in
* particular, the delay MUST be less than 0.5 seconds ..."
*
* NOTE: We only have 0.5 timing resolution here so the delay will be
* between 0.5 and 1.0 seconds, and may be delayed further, depending on the
* polling rate of the the driver (often 1 second).
*/
#define ACK_DELAY (1)
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -187,7 +201,7 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
* retransmit.
*/
if (conn->unacked > 0)
if (conn->tx_unacked > 0)
{
/* The connection has outstanding data */
@@ -315,14 +329,14 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
* SYNACK.
*/
tcp_ack(dev, conn, TCP_ACK | TCP_SYN);
tcp_synack(dev, conn, TCP_ACK | TCP_SYN);
goto done;
case TCP_SYN_SENT:
/* In the SYN_SENT state, we retransmit out SYN. */
tcp_ack(dev, conn, TCP_SYN);
tcp_synack(dev, conn, TCP_SYN);
goto done;
case TCP_ESTABLISHED:
@@ -454,7 +468,7 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
* dummy byte that we just sent.
*/
conn->unacked++;
conn->tx_unacked++;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
/* Increment the un-ACKed sequence number */
@@ -472,9 +486,40 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
}
#endif
#ifdef CONFIG_NET_TCP_DELAYED_ACK
/* Handle delayed acknowledgments. Is there a segment with a
* delayed acknowledgment?
*/
if (conn->rx_unackseg > 0)
{
/* Increment the ACK delay. */
conn->rx_acktimer += hsec;
/* Per RFC 1122: "...an ACK should not be excessively
* delayed; in particular, the delay must be less than
* 0.5 seconds..."
*/
if (conn->rx_acktimer >= ACK_DELAY)
{
/* Reset the delayed ACK state and send the ACK
* packet.
*/
conn->rx_unackseg = 0;
conn->rx_acktimer = 0;
tcp_synack(dev, conn, TCP_ACK);
goto done;
}
}
#endif
/* There was no need for a retransmission and there was no
* need to probe the remote peer. We poll the application for
* new outgoing data.
* need to probe the remote peer and there was no need to
* send a delayed ACK. We poll the application for new
* outgoing data.
*/
result = tcp_callback(dev, conn, TCP_POLL);