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:
kieranm 2002-10-24 13:14:52 +00:00
parent ef6b7099ba
commit 4933bfaaa0

View File

@ -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)) {