mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-19 05:10:40 +00:00
* tcp.c, tcp_in.c, tcp_out.c, tcp.h: Modify way the retransmission
timer is reset to fix bug#19434, with help from Oleg Tyshev.
This commit is contained in:
parent
58b3b0603d
commit
79be888b6f
@ -500,11 +500,13 @@ tcp_slowtmr(void)
|
|||||||
++pcb_remove;
|
++pcb_remove;
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
|
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
|
||||||
} else {
|
} else {
|
||||||
|
/* Increase the retransmission timer if it is running */
|
||||||
|
if(pcb->rtime >= 0)
|
||||||
++pcb->rtime;
|
++pcb->rtime;
|
||||||
if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
|
|
||||||
|
|
||||||
|
if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
|
||||||
/* Time for a retransmission. */
|
/* Time for a retransmission. */
|
||||||
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"U16_F" pcb->rto %"U16_F"\n",
|
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F" pcb->rto %"S16_F"\n",
|
||||||
pcb->rtime, pcb->rto));
|
pcb->rtime, pcb->rto));
|
||||||
|
|
||||||
/* Double retransmission time-out unless we are trying to
|
/* Double retransmission time-out unless we are trying to
|
||||||
@ -512,6 +514,10 @@ tcp_slowtmr(void)
|
|||||||
if (pcb->state != SYN_SENT) {
|
if (pcb->state != SYN_SENT) {
|
||||||
pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];
|
pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset the retransmission timer. */
|
||||||
|
pcb->rtime = 0;
|
||||||
|
|
||||||
/* Reduce congestion window and ssthresh. */
|
/* Reduce congestion window and ssthresh. */
|
||||||
eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
|
eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
|
||||||
pcb->ssthresh = eff_wnd >> 1;
|
pcb->ssthresh = eff_wnd >> 1;
|
||||||
@ -844,7 +850,7 @@ tcp_alloc(u8_t prio)
|
|||||||
pcb->rto = 3000 / TCP_SLOW_INTERVAL;
|
pcb->rto = 3000 / TCP_SLOW_INTERVAL;
|
||||||
pcb->sa = 0;
|
pcb->sa = 0;
|
||||||
pcb->sv = 3000 / TCP_SLOW_INTERVAL;
|
pcb->sv = 3000 / TCP_SLOW_INTERVAL;
|
||||||
pcb->rtime = 0;
|
pcb->rtime = -1;
|
||||||
pcb->cwnd = 1;
|
pcb->cwnd = 1;
|
||||||
iss = tcp_next_iss();
|
iss = tcp_next_iss();
|
||||||
pcb->snd_wl2 = iss;
|
pcb->snd_wl2 = iss;
|
||||||
@ -994,6 +1000,10 @@ tcp_pcb_purge(struct tcp_pcb *pcb)
|
|||||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
|
LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stop the retransmission timer as it will expect data on unacked
|
||||||
|
queue if it fires */
|
||||||
|
pcb->rtime = -1;
|
||||||
|
|
||||||
tcp_segs_free(pcb->ooseq);
|
tcp_segs_free(pcb->ooseq);
|
||||||
pcb->ooseq = NULL;
|
pcb->ooseq = NULL;
|
||||||
#endif /* TCP_QUEUE_OOSEQ */
|
#endif /* TCP_QUEUE_OOSEQ */
|
||||||
|
@ -504,6 +504,14 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));
|
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));
|
||||||
rseg = pcb->unacked;
|
rseg = pcb->unacked;
|
||||||
pcb->unacked = rseg->next;
|
pcb->unacked = rseg->next;
|
||||||
|
|
||||||
|
/* If there's nothing left to acknowledge, stop the retransmit
|
||||||
|
timer, otherwise reset it to start again */
|
||||||
|
if(pcb->unacked == NULL)
|
||||||
|
pcb->rtime = -1;
|
||||||
|
else
|
||||||
|
pcb->rtime = 0;
|
||||||
|
|
||||||
tcp_seg_free(rseg);
|
tcp_seg_free(rseg);
|
||||||
|
|
||||||
/* Parse any options in the SYNACK. */
|
/* Parse any options in the SYNACK. */
|
||||||
@ -700,10 +708,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
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",
|
||||||
pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
|
pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
|
||||||
}
|
}
|
||||||
} else
|
} else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_max)){
|
||||||
/*if (TCP_SEQ_LT(pcb->lastack, ackno) &&
|
|
||||||
TCP_SEQ_LEQ(ackno, pcb->snd_max)) { */
|
|
||||||
if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_max)){
|
|
||||||
/* We come here when the ACK acknowledges new data. */
|
/* We come here when the ACK acknowledges new data. */
|
||||||
|
|
||||||
/* Reset the "IN Fast Retransmit" flag, since we are no longer
|
/* Reset the "IN Fast Retransmit" flag, since we are no longer
|
||||||
@ -775,6 +780,14 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
pcb->unsent != NULL);
|
pcb->unsent != NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If there's nothing left to acknowledge, stop the retransmit
|
||||||
|
timer, otherwise reset it to start again */
|
||||||
|
if(pcb->unacked == NULL)
|
||||||
|
pcb->rtime = -1;
|
||||||
|
else
|
||||||
|
pcb->rtime = 0;
|
||||||
|
|
||||||
pcb->polltmr = 0;
|
pcb->polltmr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,6 +551,8 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
|||||||
ip_addr_set(&(pcb->local_ip), &(netif->ip_addr));
|
ip_addr_set(&(pcb->local_ip), &(netif->ip_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set retransmission timer running if it is not currently enabled */
|
||||||
|
if(pcb->rtime == -1)
|
||||||
pcb->rtime = 0;
|
pcb->rtime = 0;
|
||||||
|
|
||||||
if (pcb->rttest == 0) {
|
if (pcb->rttest == 0) {
|
||||||
@ -674,7 +676,6 @@ tcp_rexmit(struct tcp_pcb *pcb)
|
|||||||
/* Do the actual retransmission. */
|
/* Do the actual retransmission. */
|
||||||
snmp_inc_tcpretranssegs();
|
snmp_inc_tcpretranssegs();
|
||||||
tcp_output(pcb);
|
tcp_output(pcb);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ struct tcp_pcb {
|
|||||||
u8_t polltmr, pollinterval;
|
u8_t polltmr, pollinterval;
|
||||||
|
|
||||||
/* Retransmission timer. */
|
/* Retransmission timer. */
|
||||||
u16_t rtime;
|
s16_t rtime;
|
||||||
|
|
||||||
u16_t mss; /* maximum segment size */
|
u16_t mss; /* maximum segment size */
|
||||||
|
|
||||||
@ -262,7 +262,7 @@ struct tcp_pcb {
|
|||||||
u32_t rtseq; /* sequence number being timed */
|
u32_t rtseq; /* sequence number being timed */
|
||||||
s16_t sa, sv; /* @todo document this */
|
s16_t sa, sv; /* @todo document this */
|
||||||
|
|
||||||
u16_t rto; /* retransmission time-out */
|
s16_t rto; /* retransmission time-out */
|
||||||
u8_t nrtx; /* number of retransmissions */
|
u8_t nrtx; /* number of retransmissions */
|
||||||
|
|
||||||
/* fast retransmit/recovery */
|
/* fast retransmit/recovery */
|
||||||
|
Loading…
Reference in New Issue
Block a user