forked from nuttx/nuttx-update
net/tcp(unbuffered): fast retransmit on duplicate acknowledgments
This commit is contained in:
parent
f345f3dc2e
commit
0afb1d8dbb
1 changed files with 49 additions and 11 deletions
|
@ -80,14 +80,23 @@
|
|||
|
||||
struct send_s
|
||||
{
|
||||
FAR struct socket *snd_sock; /* Points to the parent socket structure */
|
||||
FAR struct devif_callback_s *snd_cb; /* Reference to callback instance */
|
||||
sem_t snd_sem; /* Used to wake up the waiting thread */
|
||||
FAR const uint8_t *snd_buffer; /* Points to the buffer of data to send */
|
||||
size_t snd_buflen; /* Number of bytes in the buffer to send */
|
||||
ssize_t snd_sent; /* The number of bytes sent */
|
||||
uint32_t snd_isn; /* Initial sequence number */
|
||||
uint32_t snd_acked; /* The number of bytes acked */
|
||||
FAR struct socket *snd_sock; /* Points to the parent socket structure */
|
||||
FAR struct devif_callback_s *snd_cb; /* Reference to callback instance */
|
||||
sem_t snd_sem; /* Used to wake up the waiting thread */
|
||||
FAR const uint8_t *snd_buffer; /* Points to the buffer of data to send */
|
||||
size_t snd_buflen; /* Number of bytes in the buffer to send */
|
||||
ssize_t snd_sent; /* The number of bytes sent */
|
||||
uint32_t snd_isn; /* Initial sequence number */
|
||||
uint32_t snd_acked; /* The number of bytes acked */
|
||||
uint32_t snd_prev_ack; /* The previous ACKed seq number */
|
||||
#ifdef CONFIG_NET_TCP_WINDOW_SCALE
|
||||
uint32_t snd_prev_wnd; /* The advertised window in the last
|
||||
* incoming acknowledgment
|
||||
*/
|
||||
#else
|
||||
uint16_t snd_prev_wnd;
|
||||
#endif
|
||||
int snd_dup_acks; /* Duplicate ACK counter */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -183,6 +192,7 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
|
|||
|
||||
if ((flags & TCP_ACKDATA) != 0)
|
||||
{
|
||||
uint32_t ackno;
|
||||
FAR struct tcp_hdr_s *tcp;
|
||||
|
||||
/* Get the offset address of the TCP header */
|
||||
|
@ -213,7 +223,8 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
|
|||
* of bytes to be acknowledged.
|
||||
*/
|
||||
|
||||
pstate->snd_acked = TCP_SEQ_SUB(tcp_getsequence(tcp->ackno),
|
||||
ackno = tcp_getsequence(tcp->ackno);
|
||||
pstate->snd_acked = TCP_SEQ_SUB(ackno,
|
||||
pstate->snd_isn);
|
||||
ninfo("ACK: acked=%" PRId32 " sent=%zd buflen=%zd\n",
|
||||
pstate->snd_acked, pstate->snd_sent, pstate->snd_buflen);
|
||||
|
@ -229,12 +240,39 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
|
|||
goto end_wait;
|
||||
}
|
||||
|
||||
/* No.. fall through to send more data if necessary */
|
||||
/* Fast Retransmit (RFC 5681): an acknowledgment is considered a
|
||||
* "duplicate" when (a) the receiver of the ACK has outstanding data,
|
||||
* (b) the incoming acknowledgment carries no data, (c) the SYN and
|
||||
* FIN bits are both off, (d) the acknowledgment number is equal to
|
||||
* the greatest acknowledgment received on the given connection
|
||||
* and (e) the advertised window in the incoming acknowledgment equals
|
||||
* the advertised window in the last incoming acknowledgment.
|
||||
*/
|
||||
|
||||
if (pstate->snd_acked < pstate->snd_sent &&
|
||||
(flags & TCP_NEWDATA) == 0 &&
|
||||
(tcp->flags & (TCP_SYN | TCP_FIN)) == 0 &&
|
||||
ackno == pstate->snd_prev_ack &&
|
||||
conn->snd_wnd == pstate->snd_prev_wnd)
|
||||
{
|
||||
if (++pstate->snd_dup_acks >=
|
||||
CONFIG_NET_TCP_FAST_RETRANSMIT_WATERMARK)
|
||||
{
|
||||
flags |= TCP_REXMIT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pstate->snd_dup_acks = 0;
|
||||
}
|
||||
|
||||
pstate->snd_prev_ack = ackno;
|
||||
pstate->snd_prev_wnd = conn->snd_wnd;
|
||||
}
|
||||
|
||||
/* Check if we are being asked to retransmit data */
|
||||
|
||||
else if ((flags & TCP_REXMIT) != 0)
|
||||
if ((flags & TCP_REXMIT) != 0)
|
||||
{
|
||||
/* According to RFC 6298 (5.4), retransmit the earliest segment
|
||||
* that has not been acknowledged by the TCP receiver.
|
||||
|
|
Loading…
Reference in a new issue