mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-12-24 15:14:06 +00:00
Fixed bug in duplicate ack handling
(see http://www.sics.se/mailing-lists/lwip.html/msg01460.html) Solution adds check on right window edge when duplicate ack received, if it is different it is not a duplicate.
This commit is contained in:
parent
ef6b7099ba
commit
4933bfaaa0
@ -604,6 +604,8 @@ tcp_receive(struct tcp_pcb *pcb)
|
||||
|
||||
|
||||
if(flags & TCP_ACK) {
|
||||
unsigned long int right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;
|
||||
|
||||
/* Update window. */
|
||||
if(TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
|
||||
(pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
|
||||
@ -623,29 +625,33 @@ tcp_receive(struct tcp_pcb *pcb)
|
||||
|
||||
|
||||
if(pcb->lastack == ackno) {
|
||||
++pcb->dupacks;
|
||||
if(pcb->dupacks >= 3 && pcb->unacked != NULL) {
|
||||
if(!(pcb->flags & TF_INFR)) {
|
||||
/* This is fast retransmit. Retransmit the first unacked segment. */
|
||||
DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %d (%lu), fast retransmit %lu\n",
|
||||
pcb->dupacks, pcb->lastack,
|
||||
ntohl(pcb->unacked->tcphdr->seqno)));
|
||||
tcp_rexmit(pcb);
|
||||
/* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
|
||||
pcb->ssthresh = UMAX((pcb->snd_max -
|
||||
pcb->lastack) / 2,
|
||||
2 * pcb->mss);
|
||||
|
||||
pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
|
||||
pcb->flags |= TF_INFR;
|
||||
} else {
|
||||
/* Inflate the congestion window, but not if it means that
|
||||
the value overflows. */
|
||||
if((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
|
||||
pcb->cwnd += pcb->mss;
|
||||
if(pcb->snd_wl1+pcb->snd_wnd==right_wnd_edge){
|
||||
++pcb->dupacks;
|
||||
if(pcb->dupacks >= 3 && pcb->unacked != NULL) {
|
||||
if(!(pcb->flags & TF_INFR)) {
|
||||
/* This is fast retransmit. Retransmit the first unacked segment. */
|
||||
DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %d (%lu), fast retransmit %lu\n",
|
||||
pcb->dupacks, pcb->lastack,
|
||||
ntohl(pcb->unacked->tcphdr->seqno)));
|
||||
tcp_rexmit(pcb);
|
||||
/* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
|
||||
pcb->ssthresh = UMAX((pcb->snd_max -
|
||||
pcb->lastack) / 2,
|
||||
2 * pcb->mss);
|
||||
|
||||
pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
|
||||
pcb->flags |= TF_INFR;
|
||||
} else {
|
||||
/* Inflate the congestion window, but not if it means that
|
||||
the value overflows. */
|
||||
if((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
|
||||
pcb->cwnd += pcb->mss;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n", pcb->snd_wl1+pcb->snd_wnd, right_wnd_edge));
|
||||
}
|
||||
} else if(TCP_SEQ_LT(pcb->lastack, ackno) &&
|
||||
TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
|
||||
|
Loading…
Reference in New Issue
Block a user