net/tcp: transformed NET_TCP_FAST_RETRANSMIT_WATERMARK option to boolean.
According to RFC 5681 (3.2) the TCP Fast Retransmit algorithm should start if the threshold of 3 duplicate ACKs is reached. Thus the threshold should be a constant, not an integer option.
This commit is contained in:
parent
ecccc614bd
commit
2a6de301ee
@ -79,9 +79,9 @@ config NET_MAX_LISTENPORTS
|
|||||||
---help---
|
---help---
|
||||||
Maximum number of listening TCP/IP ports (all tasks). Default: 20
|
Maximum number of listening TCP/IP ports (all tasks). Default: 20
|
||||||
|
|
||||||
config NET_TCP_FAST_RETRANSMIT_WATERMARK
|
config NET_TCP_FAST_RETRANSMIT
|
||||||
int "WaterMark to trigger Fast Retransmission"
|
bool "Enable the Fast Retransmit algorithm"
|
||||||
default 3
|
default y
|
||||||
---help---
|
---help---
|
||||||
RFC2001:
|
RFC2001:
|
||||||
3. Fast Retransmit
|
3. Fast Retransmit
|
||||||
|
@ -65,7 +65,9 @@
|
|||||||
# define TCP_WBPKTLEN(wrb) ((wrb)->wb_iob->io_pktlen)
|
# define TCP_WBPKTLEN(wrb) ((wrb)->wb_iob->io_pktlen)
|
||||||
# define TCP_WBSENT(wrb) ((wrb)->wb_sent)
|
# define TCP_WBSENT(wrb) ((wrb)->wb_sent)
|
||||||
# define TCP_WBNRTX(wrb) ((wrb)->wb_nrtx)
|
# define TCP_WBNRTX(wrb) ((wrb)->wb_nrtx)
|
||||||
|
#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
|
||||||
# define TCP_WBNACK(wrb) ((wrb)->wb_nack)
|
# define TCP_WBNACK(wrb) ((wrb)->wb_nack)
|
||||||
|
#endif
|
||||||
# define TCP_WBIOB(wrb) ((wrb)->wb_iob)
|
# define TCP_WBIOB(wrb) ((wrb)->wb_iob)
|
||||||
# define TCP_WBCOPYOUT(wrb,dest,n) (iob_copyout(dest,(wrb)->wb_iob,(n),0))
|
# define TCP_WBCOPYOUT(wrb,dest,n) (iob_copyout(dest,(wrb)->wb_iob,(n),0))
|
||||||
# define TCP_WBCOPYIN(wrb,src,n,off) \
|
# define TCP_WBCOPYIN(wrb,src,n,off) \
|
||||||
@ -101,6 +103,12 @@
|
|||||||
|
|
||||||
#define TCP_WSCALE 0x01U /* Window Scale option enabled */
|
#define TCP_WSCALE 0x01U /* Window Scale option enabled */
|
||||||
|
|
||||||
|
/* After receiving 3 duplicate ACKs, TCP performs a retransmission
|
||||||
|
* (RFC 5681 (3.2))
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TCP_FAST_RETRANSMISSION_THRESH 3
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Type Definitions
|
* Public Type Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -330,7 +338,9 @@ struct tcp_wrbuffer_s
|
|||||||
uint16_t wb_sent; /* Number of bytes sent from the I/O buffer chain */
|
uint16_t wb_sent; /* Number of bytes sent from the I/O buffer chain */
|
||||||
uint8_t wb_nrtx; /* The number of retransmissions for the last
|
uint8_t wb_nrtx; /* The number of retransmissions for the last
|
||||||
* segment sent */
|
* segment sent */
|
||||||
|
#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
|
||||||
uint8_t wb_nack; /* The number of ack count */
|
uint8_t wb_nack; /* The number of ack count */
|
||||||
|
#endif
|
||||||
struct iob_s *wb_iob; /* Head of the I/O buffer chain */
|
struct iob_s *wb_iob; /* Head of the I/O buffer chain */
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -543,6 +543,7 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
wrb, TCP_WBSEQNO(wrb), TCP_WBPKTLEN(wrb));
|
wrb, TCP_WBSEQNO(wrb), TCP_WBPKTLEN(wrb));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
|
||||||
else if (ackno == TCP_WBSEQNO(wrb))
|
else if (ackno == TCP_WBSEQNO(wrb))
|
||||||
{
|
{
|
||||||
/* Reset the duplicate ack counter */
|
/* Reset the duplicate ack counter */
|
||||||
@ -554,15 +555,13 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
/* Duplicate ACK? Retransmit data if need */
|
/* Duplicate ACK? Retransmit data if need */
|
||||||
|
|
||||||
if (++TCP_WBNACK(wrb) ==
|
if (++TCP_WBNACK(wrb) == TCP_FAST_RETRANSMISSION_THRESH)
|
||||||
CONFIG_NET_TCP_FAST_RETRANSMIT_WATERMARK)
|
|
||||||
{
|
{
|
||||||
/* Do fast retransmit */
|
/* Do fast retransmit */
|
||||||
|
|
||||||
rexmit = true;
|
rexmit = true;
|
||||||
}
|
}
|
||||||
else if ((TCP_WBNACK(wrb) >
|
else if ((TCP_WBNACK(wrb) > TCP_FAST_RETRANSMISSION_THRESH) &&
|
||||||
CONFIG_NET_TCP_FAST_RETRANSMIT_WATERMARK) &&
|
|
||||||
TCP_WBNACK(wrb) == sq_count(&conn->unacked_q) - 1)
|
TCP_WBNACK(wrb) == sq_count(&conn->unacked_q) - 1)
|
||||||
{
|
{
|
||||||
/* Reset the duplicate ack counter */
|
/* Reset the duplicate ack counter */
|
||||||
@ -570,6 +569,7 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
TCP_WBNACK(wrb) = 0;
|
TCP_WBNACK(wrb) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A special case is the head of the write_q which may be partially
|
/* A special case is the head of the write_q which may be partially
|
||||||
|
@ -88,6 +88,7 @@ struct send_s
|
|||||||
ssize_t snd_sent; /* The number of bytes sent */
|
ssize_t snd_sent; /* The number of bytes sent */
|
||||||
uint32_t snd_isn; /* Initial sequence number */
|
uint32_t snd_isn; /* Initial sequence number */
|
||||||
uint32_t snd_acked; /* The number of bytes acked */
|
uint32_t snd_acked; /* The number of bytes acked */
|
||||||
|
#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
|
||||||
uint32_t snd_prev_ack; /* The previous ACKed seq number */
|
uint32_t snd_prev_ack; /* The previous ACKed seq number */
|
||||||
#ifdef CONFIG_NET_TCP_WINDOW_SCALE
|
#ifdef CONFIG_NET_TCP_WINDOW_SCALE
|
||||||
uint32_t snd_prev_wnd; /* The advertised window in the last
|
uint32_t snd_prev_wnd; /* The advertised window in the last
|
||||||
@ -97,6 +98,7 @@ struct send_s
|
|||||||
uint16_t snd_prev_wnd;
|
uint16_t snd_prev_wnd;
|
||||||
#endif
|
#endif
|
||||||
int snd_dup_acks; /* Duplicate ACK counter */
|
int snd_dup_acks; /* Duplicate ACK counter */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -274,6 +276,7 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
goto end_wait;
|
goto end_wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
|
||||||
/* Fast Retransmit (RFC 5681): an acknowledgment is considered a
|
/* Fast Retransmit (RFC 5681): an acknowledgment is considered a
|
||||||
* "duplicate" when (a) the receiver of the ACK has outstanding data,
|
* "duplicate" when (a) the receiver of the ACK has outstanding data,
|
||||||
* (b) the incoming acknowledgment carries no data, (c) the SYN and
|
* (b) the incoming acknowledgment carries no data, (c) the SYN and
|
||||||
@ -289,8 +292,7 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
ackno == pstate->snd_prev_ack &&
|
ackno == pstate->snd_prev_ack &&
|
||||||
conn->snd_wnd == pstate->snd_prev_wnd)
|
conn->snd_wnd == pstate->snd_prev_wnd)
|
||||||
{
|
{
|
||||||
if (++pstate->snd_dup_acks >=
|
if (++pstate->snd_dup_acks >= TCP_FAST_RETRANSMISSION_THRESH)
|
||||||
CONFIG_NET_TCP_FAST_RETRANSMIT_WATERMARK)
|
|
||||||
{
|
{
|
||||||
flags |= TCP_REXMIT;
|
flags |= TCP_REXMIT;
|
||||||
pstate->snd_dup_acks = 0;
|
pstate->snd_dup_acks = 0;
|
||||||
@ -303,6 +305,7 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
pstate->snd_prev_ack = ackno;
|
pstate->snd_prev_ack = ackno;
|
||||||
pstate->snd_prev_wnd = conn->snd_wnd;
|
pstate->snd_prev_wnd = conn->snd_wnd;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we are being asked to retransmit data.
|
/* Check if we are being asked to retransmit data.
|
||||||
|
@ -84,6 +84,7 @@ struct sendfile_s
|
|||||||
ssize_t snd_sent; /* The number of bytes sent */
|
ssize_t snd_sent; /* The number of bytes sent */
|
||||||
uint32_t snd_isn; /* Initial sequence number */
|
uint32_t snd_isn; /* Initial sequence number */
|
||||||
uint32_t snd_acked; /* The number of bytes acked */
|
uint32_t snd_acked; /* The number of bytes acked */
|
||||||
|
#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
|
||||||
uint32_t snd_prev_ack; /* The previous ACKed seq number */
|
uint32_t snd_prev_ack; /* The previous ACKed seq number */
|
||||||
#ifdef CONFIG_NET_TCP_WINDOW_SCALE
|
#ifdef CONFIG_NET_TCP_WINDOW_SCALE
|
||||||
uint32_t snd_prev_wnd; /* The advertised window in the last
|
uint32_t snd_prev_wnd; /* The advertised window in the last
|
||||||
@ -93,6 +94,7 @@ struct sendfile_s
|
|||||||
uint16_t snd_prev_wnd;
|
uint16_t snd_prev_wnd;
|
||||||
#endif
|
#endif
|
||||||
int snd_dup_acks; /* Duplicate ACK counter */
|
int snd_dup_acks; /* Duplicate ACK counter */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -227,6 +229,7 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
goto end_wait;
|
goto end_wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
|
||||||
/* Fast Retransmit (RFC 5681): an acknowledgment is considered a
|
/* Fast Retransmit (RFC 5681): an acknowledgment is considered a
|
||||||
* "duplicate" when (a) the receiver of the ACK has outstanding data,
|
* "duplicate" when (a) the receiver of the ACK has outstanding data,
|
||||||
* (b) the incoming acknowledgment carries no data, (c) the SYN and
|
* (b) the incoming acknowledgment carries no data, (c) the SYN and
|
||||||
@ -242,8 +245,7 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
ackno == pstate->snd_prev_ack &&
|
ackno == pstate->snd_prev_ack &&
|
||||||
conn->snd_wnd == pstate->snd_prev_wnd)
|
conn->snd_wnd == pstate->snd_prev_wnd)
|
||||||
{
|
{
|
||||||
if (++pstate->snd_dup_acks >=
|
if (++pstate->snd_dup_acks >= TCP_FAST_RETRANSMISSION_THRESH)
|
||||||
CONFIG_NET_TCP_FAST_RETRANSMIT_WATERMARK)
|
|
||||||
{
|
{
|
||||||
flags |= TCP_REXMIT;
|
flags |= TCP_REXMIT;
|
||||||
pstate->snd_dup_acks = 0;
|
pstate->snd_dup_acks = 0;
|
||||||
@ -256,6 +258,7 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
pstate->snd_prev_ack = ackno;
|
pstate->snd_prev_ack = ackno;
|
||||||
pstate->snd_prev_wnd = conn->snd_wnd;
|
pstate->snd_prev_wnd = conn->snd_wnd;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we are being asked to retransmit data.
|
/* Check if we are being asked to retransmit data.
|
||||||
|
@ -243,9 +243,11 @@ void tcp_wrbuffer_release(FAR struct tcp_wrbuffer_s *wrb)
|
|||||||
iob_free_chain(wrb->wb_iob, IOBUSER_NET_TCP_WRITEBUFFER);
|
iob_free_chain(wrb->wb_iob, IOBUSER_NET_TCP_WRITEBUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
|
||||||
/* Reset the ack counter */
|
/* Reset the ack counter */
|
||||||
|
|
||||||
TCP_WBNACK(wrb) = 0;
|
TCP_WBNACK(wrb) = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Then free the write buffer structure */
|
/* Then free the write buffer structure */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user