Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet/tcp_input.c
Show First 20 Lines • Show All 432 Lines • ▼ Show 20 Lines | if (!IN_CONGRECOVERY(tp->t_flags)) { | ||||
tp->t_flags |= TF_ECN_SND_CWR; | tp->t_flags |= TF_ECN_SND_CWR; | ||||
} | } | ||||
break; | break; | ||||
case CC_RTO: | case CC_RTO: | ||||
maxseg = tcp_maxseg(tp); | maxseg = tcp_maxseg(tp); | ||||
tp->t_dupacks = 0; | tp->t_dupacks = 0; | ||||
tp->t_bytes_acked = 0; | tp->t_bytes_acked = 0; | ||||
EXIT_RECOVERY(tp->t_flags); | EXIT_RECOVERY(tp->t_flags); | ||||
tp->snd_ssthresh = max(2, min(tp->snd_wnd, tp->snd_cwnd) / 2 / | if (CC_ALGO(tp)->cong_signal == NULL) { | ||||
maxseg) * maxseg; | /* | ||||
* RFC5681 Section 3.1 | |||||
* ssthresh = max (FlightSize / 2, 2*SMSS) eq (4) | |||||
*/ | |||||
tp->snd_ssthresh = | |||||
max((tp->snd_max - tp->snd_una) / 2, 2 * maxseg); | |||||
tp->snd_cwnd = maxseg; | tp->snd_cwnd = maxseg; | ||||
} | |||||
break; | break; | ||||
case CC_RTO_ERR: | case CC_RTO_ERR: | ||||
TCPSTAT_INC(tcps_sndrexmitbad); | TCPSTAT_INC(tcps_sndrexmitbad); | ||||
/* RTO was unnecessary, so reset everything. */ | /* RTO was unnecessary, so reset everything. */ | ||||
tp->snd_cwnd = tp->snd_cwnd_prev; | tp->snd_cwnd = tp->snd_cwnd_prev; | ||||
tp->snd_ssthresh = tp->snd_ssthresh_prev; | tp->snd_ssthresh = tp->snd_ssthresh_prev; | ||||
tp->snd_recover = tp->snd_recover_prev; | tp->snd_recover = tp->snd_recover_prev; | ||||
if (tp->t_flags & TF_WASFRECOVERY) | if (tp->t_flags & TF_WASFRECOVERY) | ||||
▲ Show 20 Lines • Show All 2,156 Lines • ▼ Show 20 Lines | if (SEQ_LEQ(th->th_ack, tp->snd_una)) { | ||||
if (V_tcp_do_rfc6675_pipe) | if (V_tcp_do_rfc6675_pipe) | ||||
awnd = tcp_compute_pipe(tp); | awnd = tcp_compute_pipe(tp); | ||||
else | else | ||||
awnd = (tp->snd_nxt - tp->snd_fack) + | awnd = (tp->snd_nxt - tp->snd_fack) + | ||||
tp->sackhint.sack_bytes_rexmit; | tp->sackhint.sack_bytes_rexmit; | ||||
if (awnd < tp->snd_ssthresh) { | if (awnd < tp->snd_ssthresh) { | ||||
tp->snd_cwnd += maxseg; | tp->snd_cwnd += maxseg; | ||||
/* | |||||
* RFC5681 Section 3.2 talks about cwnd | |||||
* inflation on additional dupacks and | |||||
* deflation on recovering from loss. | |||||
* | |||||
* We keep cwnd into check so that | |||||
* we don't have to 'deflate' it when we | |||||
* get out of recovery. | |||||
*/ | |||||
if (tp->snd_cwnd > tp->snd_ssthresh) | if (tp->snd_cwnd > tp->snd_ssthresh) | ||||
tp->snd_cwnd = tp->snd_ssthresh; | tp->snd_cwnd = tp->snd_ssthresh; | ||||
} | } | ||||
} else | } else | ||||
tp->snd_cwnd += maxseg; | tp->snd_cwnd += maxseg; | ||||
(void) tp->t_fb->tfb_tcp_output(tp); | (void) tp->t_fb->tfb_tcp_output(tp); | ||||
goto drop; | goto drop; | ||||
} else if (tp->t_dupacks == tcprexmtthresh) { | } else if (tp->t_dupacks == tcprexmtthresh) { | ||||
Show All 23 Lines | if (SEQ_LEQ(th->th_ack, tp->snd_una)) { | ||||
cc_ack_received(tp, th, nsegs, | cc_ack_received(tp, th, nsegs, | ||||
CC_DUPACK); | CC_DUPACK); | ||||
tcp_timer_activate(tp, TT_REXMT, 0); | tcp_timer_activate(tp, TT_REXMT, 0); | ||||
tp->t_rtttime = 0; | tp->t_rtttime = 0; | ||||
if (tp->t_flags & TF_SACK_PERMIT) { | if (tp->t_flags & TF_SACK_PERMIT) { | ||||
TCPSTAT_INC( | TCPSTAT_INC( | ||||
tcps_sack_recovery_episode); | tcps_sack_recovery_episode); | ||||
tp->sack_newdata = tp->snd_nxt; | tp->sack_newdata = tp->snd_nxt; | ||||
if (CC_ALGO(tp)->cong_signal == NULL) | |||||
tp->snd_cwnd = maxseg; | tp->snd_cwnd = maxseg; | ||||
(void) tp->t_fb->tfb_tcp_output(tp); | (void) tp->t_fb->tfb_tcp_output(tp); | ||||
goto drop; | goto drop; | ||||
} | } | ||||
tp->snd_nxt = th->th_ack; | tp->snd_nxt = th->th_ack; | ||||
if (CC_ALGO(tp)->cong_signal == NULL) | |||||
tp->snd_cwnd = maxseg; | tp->snd_cwnd = maxseg; | ||||
(void) tp->t_fb->tfb_tcp_output(tp); | (void) tp->t_fb->tfb_tcp_output(tp); | ||||
KASSERT(tp->snd_limited <= 2, | KASSERT(tp->snd_limited <= 2, | ||||
("%s: tp->snd_limited too big", | ("%s: tp->snd_limited too big", | ||||
__func__)); | __func__)); | ||||
if (CC_ALGO(tp)->cong_signal == NULL) | |||||
tp->snd_cwnd = tp->snd_ssthresh + | tp->snd_cwnd = tp->snd_ssthresh + | ||||
maxseg * | maxseg * | ||||
(tp->t_dupacks - tp->snd_limited); | (tp->t_dupacks - tp->snd_limited); | ||||
if (SEQ_GT(onxt, tp->snd_nxt)) | if (SEQ_GT(onxt, tp->snd_nxt)) | ||||
tp->snd_nxt = onxt; | tp->snd_nxt = onxt; | ||||
goto drop; | goto drop; | ||||
} else if (V_tcp_do_rfc3042) { | } else if (V_tcp_do_rfc3042) { | ||||
/* | /* | ||||
* Process first and second duplicate | * Process first and second duplicate | ||||
* ACKs. Each indicates a segment | * ACKs. Each indicates a segment | ||||
* leaving the network, creating room | * leaving the network, creating room | ||||
▲ Show 20 Lines • Show All 1,225 Lines • Show Last 20 Lines |