Changeset View
Standalone View
sys/netinet/tcp_input.c
Show First 20 Lines • Show All 405 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
u_int maxseg; | u_int maxseg; | ||||
INP_WLOCK_ASSERT(tp->t_inpcb); | INP_WLOCK_ASSERT(tp->t_inpcb); | ||||
switch(type) { | switch(type) { | ||||
case CC_NDUPACK: | case CC_NDUPACK: | ||||
if (!IN_FASTRECOVERY(tp->t_flags)) { | if (!IN_FASTRECOVERY(tp->t_flags)) { | ||||
tp->snd_recover = tp->snd_max; | tp->snd_recover = tp->snd_max; | ||||
rscheff: Recovery Point (RFC) is set in this wrapper irrespective if the session supports SACK or not. | |||||
if (tp->t_flags & TF_ECN_PERMIT) | if (tp->t_flags & TF_ECN_PERMIT) | ||||
tp->t_flags |= TF_ECN_SND_CWR; | tp->t_flags |= TF_ECN_SND_CWR; | ||||
} | } | ||||
break; | break; | ||||
case CC_ECN: | case CC_ECN: | ||||
if (!IN_CONGRECOVERY(tp->t_flags)) { | if (!IN_CONGRECOVERY(tp->t_flags)) { | ||||
TCPSTAT_INC(tcps_ecn_rcwnd); | TCPSTAT_INC(tcps_ecn_rcwnd); | ||||
tp->snd_recover = tp->snd_max; | tp->snd_recover = tp->snd_max; | ||||
▲ Show 20 Lines • Show All 1,382 Lines • ▼ Show 20 Lines | #ifdef TCP_HHOOK | ||||
hhook_run_tcp_est_in(tp, th, &to); | hhook_run_tcp_est_in(tp, th, &to); | ||||
#endif | #endif | ||||
TCPSTAT_ADD(tcps_rcvackpack, nsegs); | TCPSTAT_ADD(tcps_rcvackpack, nsegs); | ||||
TCPSTAT_ADD(tcps_rcvackbyte, acked); | TCPSTAT_ADD(tcps_rcvackbyte, acked); | ||||
sbdrop(&so->so_snd, acked); | sbdrop(&so->so_snd, acked); | ||||
if (SEQ_GT(tp->snd_una, tp->snd_recover) && | if (SEQ_GT(tp->snd_una, tp->snd_recover) && | ||||
SEQ_LEQ(th->th_ack, tp->snd_recover)) | SEQ_LEQ(th->th_ack, tp->snd_recover)) | ||||
tp->snd_recover = th->th_ack - 1; | tp->snd_recover = th->th_ack - 1; | ||||
rscheffAuthorUnsubmitted Done Inline ActionsMove recovery point forward on full ACKs. Just in case? rscheff: Move recovery point forward on full ACKs. Just in case? | |||||
/* | /* | ||||
* Let the congestion control algorithm update | * Let the congestion control algorithm update | ||||
* congestion control related information. This | * congestion control related information. This | ||||
* typically means increasing the congestion | * typically means increasing the congestion | ||||
* window. | * window. | ||||
*/ | */ | ||||
cc_ack_received(tp, th, nsegs, CC_ACK); | cc_ack_received(tp, th, nsegs, CC_ACK); | ||||
▲ Show 20 Lines • Show All 769 Lines • ▼ Show 20 Lines | if (SEQ_LEQ(th->th_ack, tp->snd_una)) { | ||||
} else { | } else { | ||||
if (SEQ_LEQ(th->th_ack, | if (SEQ_LEQ(th->th_ack, | ||||
tp->snd_recover)) { | tp->snd_recover)) { | ||||
tp->t_dupacks = 0; | tp->t_dupacks = 0; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
/* Congestion signal before ack. */ | /* Congestion signal before ack. */ | ||||
cc_cong_signal(tp, th, CC_NDUPACK); | cc_cong_signal(tp, th, CC_NDUPACK); | ||||
rscheffAuthorUnsubmitted Done Inline Actionscc_cong_signal wrapper already sets snd_recover to snd_nxt. The special handling for SACK sessions below could omit setting snd_recover (which used to be sack_newdata) anew. rscheff: cc_cong_signal wrapper already sets snd_recover to snd_nxt. The special handling for SACK… | |||||
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->snd_recover = tp->snd_nxt; | ||||
rscheffAuthorUnsubmitted Not Done Inline Actionsredundant with cc_cong_signal rscheff: redundant with cc_cong_signal | |||||
tp->snd_cwnd = maxseg; | tp->snd_cwnd = maxseg; | ||||
rscheffAuthorUnsubmitted Not Done Inline Actionscould move up before the if clause (same on both branches) rscheff: could move up before the if clause (same on both branches) | |||||
(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; | ||||
tp->snd_cwnd = maxseg; | tp->snd_cwnd = maxseg; | ||||
rscheffAuthorUnsubmitted Not Done Inline ActionsCould move this assignment up just before the SACK check, and save a small bit of code. rscheff: Could move this assignment up just before the SACK check, and save a small bit of code. | |||||
(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__)); | ||||
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)) | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | #endif | ||||
KASSERT(SEQ_GT(th->th_ack, tp->snd_una), | KASSERT(SEQ_GT(th->th_ack, tp->snd_una), | ||||
("%s: th_ack <= snd_una", __func__)); | ("%s: th_ack <= snd_una", __func__)); | ||||
/* | /* | ||||
* If the congestion window was inflated to account | * If the congestion window was inflated to account | ||||
* for the other side's cached packets, retract it. | * for the other side's cached packets, retract it. | ||||
*/ | */ | ||||
if (IN_FASTRECOVERY(tp->t_flags)) { | if (IN_FASTRECOVERY(tp->t_flags)) { | ||||
if (SEQ_LT(th->th_ack, tp->snd_recover)) { | if (SEQ_LT(th->th_ack, tp->snd_recover)) { | ||||
rscheffAuthorUnsubmitted Done Inline ActionsHere is the point, where the split tracking of sack_newdata and snd_recover got mingled already. Fortunately, snd_recover gets set by the cc_cong_signal wrapper anyway (thus tracks sack_newdata for SACK-enabled sessions). If Reno and SACK had truly independent tracking of the RecoveryPoint variable, this would have failed a long time ago. rscheff: Here is the point, where the split tracking of sack_newdata and snd_recover got mingled already. | |||||
if (tp->t_flags & TF_SACK_PERMIT) | if (tp->t_flags & TF_SACK_PERMIT) | ||||
tcp_sack_partialack(tp, th); | tcp_sack_partialack(tp, th); | ||||
else | else | ||||
tcp_newreno_partial_ack(tp, th); | tcp_newreno_partial_ack(tp, th); | ||||
} else | } else | ||||
cc_post_recovery(tp, th); | cc_post_recovery(tp, th); | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 116 Lines • ▼ Show 20 Lines | process_ACK: | ||||
m_freem(mfree); | m_freem(mfree); | ||||
/* Detect una wraparound. */ | /* Detect una wraparound. */ | ||||
if (!IN_RECOVERY(tp->t_flags) && | if (!IN_RECOVERY(tp->t_flags) && | ||||
SEQ_GT(tp->snd_una, tp->snd_recover) && | SEQ_GT(tp->snd_una, tp->snd_recover) && | ||||
SEQ_LEQ(th->th_ack, tp->snd_recover)) | SEQ_LEQ(th->th_ack, tp->snd_recover)) | ||||
tp->snd_recover = th->th_ack - 1; | tp->snd_recover = th->th_ack - 1; | ||||
/* XXXLAS: Can this be moved up into cc_post_recovery? */ | /* XXXLAS: Can this be moved up into cc_post_recovery? */ | ||||
if (IN_RECOVERY(tp->t_flags) && | if (IN_RECOVERY(tp->t_flags) && | ||||
SEQ_GEQ(th->th_ack, tp->snd_recover)) { | SEQ_GEQ(th->th_ack, tp->snd_recover)) { | ||||
rscheffAuthorUnsubmitted Done Inline Actionsanother instance, where sack_newdata was already missed for SACK-enabled sessions rscheff: another instance, where sack_newdata was already missed for SACK-enabled sessions | |||||
EXIT_RECOVERY(tp->t_flags); | EXIT_RECOVERY(tp->t_flags); | ||||
} | } | ||||
tp->snd_una = th->th_ack; | tp->snd_una = th->th_ack; | ||||
if (tp->t_flags & TF_SACK_PERMIT) { | if (tp->t_flags & TF_SACK_PERMIT) { | ||||
if (SEQ_GT(tp->snd_una, tp->snd_recover)) | if (SEQ_GT(tp->snd_una, tp->snd_recover)) | ||||
tp->snd_recover = tp->snd_una; | tp->snd_recover = tp->snd_una; | ||||
rscheffAuthorUnsubmitted Done Inline ActionsA prior example, where the sack_newdata was missed as the "proper" variable for RecoveryPoint, and snd_recover used instead. rscheff: A prior example, where the sack_newdata was missed as the "proper" variable for RecoveryPoint… | |||||
} | } | ||||
if (SEQ_LT(tp->snd_nxt, tp->snd_una)) | if (SEQ_LT(tp->snd_nxt, tp->snd_una)) | ||||
tp->snd_nxt = tp->snd_una; | tp->snd_nxt = tp->snd_una; | ||||
switch (tp->t_state) { | switch (tp->t_state) { | ||||
/* | /* | ||||
* In FIN_WAIT_1 STATE in addition to the processing | * In FIN_WAIT_1 STATE in addition to the processing | ||||
▲ Show 20 Lines • Show All 972 Lines • Show Last 20 Lines |
Recovery Point (RFC) is set in this wrapper irrespective if the session supports SACK or not.