Fixed bug #27329: dupacks by unidirectional data transmit

This commit is contained in:
goldsimon 2009-10-15 20:09:13 +00:00
parent a9740c6a44
commit d9a5094068
2 changed files with 36 additions and 29 deletions

View File

@ -43,6 +43,9 @@ HISTORY
++ Bugfixes: ++ Bugfixes:
2009-10-15: Simon Goldschmidt (Oleg Tyshev)
* tcp_in.c: Fixed bug #27329: dupacks by unidirectional data transmit
2009-10-15: Simon Goldschmidt 2009-10-15: Simon Goldschmidt
* api_msg.c: Fixed bug #27709: conn->err race condition on netconn_recv() * api_msg.c: Fixed bug #27709: conn->err race condition on netconn_recv()
timeout timeout

View File

@ -766,39 +766,43 @@ tcp_receive(struct tcp_pcb *pcb)
pcb->acked = 0; pcb->acked = 0;
if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){ if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){
++pcb->dupacks; if (pcb->unacked != NULL) {
if (pcb->dupacks >= 3 && pcb->unacked != NULL) { ++pcb->dupacks;
if (!(pcb->flags & TF_INFR)) { if (pcb->dupacks >= 3) {
/* This is fast retransmit. Retransmit the first unacked segment. */ if (!(pcb->flags & TF_INFR)) {
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %"U16_F" (%"U32_F"), fast retransmit %"U32_F"\n", /* This is fast retransmit. Retransmit the first unacked segment. */
(u16_t)pcb->dupacks, pcb->lastack, LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %"U16_F" (%"U32_F"), fast retransmit %"U32_F"\n",
ntohl(pcb->unacked->tcphdr->seqno))); (u16_t)pcb->dupacks, pcb->lastack,
tcp_rexmit(pcb); ntohl(pcb->unacked->tcphdr->seqno)));
/* Set ssthresh to max (FlightSize / 2, 2*SMSS) */ tcp_rexmit(pcb);
/*pcb->ssthresh = LWIP_MAX((pcb->snd_max - /* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
pcb->lastack) / 2, /*pcb->ssthresh = LWIP_MAX((pcb->snd_max -
2 * pcb->mss);*/ pcb->lastack) / 2,
/* Set ssthresh to half of the minimum of the current cwnd and the advertised window */ 2 * pcb->mss);*/
if (pcb->cwnd > pcb->snd_wnd) /* Set ssthresh to half of the minimum of the current cwnd and the advertised window */
pcb->ssthresh = pcb->snd_wnd / 2; if (pcb->cwnd > pcb->snd_wnd)
else pcb->ssthresh = pcb->snd_wnd / 2;
pcb->ssthresh = pcb->cwnd / 2; else
pcb->ssthresh = pcb->cwnd / 2;
/* The minimum value for ssthresh should be 2 MSS */ /* The minimum value for ssthresh should be 2 MSS */
if (pcb->ssthresh < 2*pcb->mss) { if (pcb->ssthresh < 2*pcb->mss) {
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: The minimum value for ssthresh %"U16_F" should be min 2 mss %"U16_F"...\n", pcb->ssthresh, 2*pcb->mss)); LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: The minimum value for ssthresh %"U16_F" should be min 2 mss %"U16_F"...\n", pcb->ssthresh, 2*pcb->mss));
pcb->ssthresh = 2*pcb->mss; pcb->ssthresh = 2*pcb->mss;
} }
pcb->cwnd = pcb->ssthresh + 3 * pcb->mss; pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
pcb->flags |= TF_INFR; pcb->flags |= TF_INFR;
} else { } else {
/* Inflate the congestion window, but not if it means that /* Inflate the congestion window, but not if it means that
the value overflows. */ the value overflows. */
if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
pcb->cwnd += pcb->mss; pcb->cwnd += pcb->mss;
}
} }
} }
} else {
pcb->dupacks = 0;
} }
} else { } else {
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %"U32_F" %"U32_F"\n", LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %"U32_F" %"U32_F"\n",