Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_input.c
Show First 20 Lines • Show All 1,491 Lines • ▼ Show 20 Lines | tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, | ||||
int rstreason, todrop, win, incforsyn = 0; | int rstreason, todrop, win, incforsyn = 0; | ||||
uint32_t tiwin; | uint32_t tiwin; | ||||
uint16_t nsegs; | uint16_t nsegs; | ||||
char *s; | char *s; | ||||
struct in_conninfo *inc; | struct in_conninfo *inc; | ||||
struct mbuf *mfree; | struct mbuf *mfree; | ||||
struct tcpopt to; | struct tcpopt to; | ||||
int tfo_syn; | int tfo_syn; | ||||
u_int maxseg; | |||||
#ifdef TCPDEBUG | #ifdef TCPDEBUG | ||||
/* | /* | ||||
* The size of tcp_saveipgen must be the size of the max ip header, | * The size of tcp_saveipgen must be the size of the max ip header, | ||||
* now IPv6. | * now IPv6. | ||||
*/ | */ | ||||
u_char tcp_saveipgen[IP6_HDR_LEN]; | u_char tcp_saveipgen[IP6_HDR_LEN]; | ||||
struct tcphdr tcp_savetcp; | struct tcphdr tcp_savetcp; | ||||
▲ Show 20 Lines • Show All 960 Lines • ▼ Show 20 Lines | #endif | ||||
case TCPS_CLOSING: | case TCPS_CLOSING: | ||||
case TCPS_LAST_ACK: | case TCPS_LAST_ACK: | ||||
if (SEQ_GT(th->th_ack, tp->snd_max)) { | if (SEQ_GT(th->th_ack, tp->snd_max)) { | ||||
TCPSTAT_INC(tcps_rcvacktoomuch); | TCPSTAT_INC(tcps_rcvacktoomuch); | ||||
goto dropafterack; | goto dropafterack; | ||||
} | } | ||||
if ((tp->t_flags & TF_SACK_PERMIT) && | if ((tp->t_flags & TF_SACK_PERMIT) && | ||||
((to.to_flags & TOF_SACK) || | ((to.to_flags & TOF_SACK) || | ||||
!TAILQ_EMPTY(&tp->snd_holes))) | !TAILQ_EMPTY(&tp->snd_holes))) | ||||
rscheff: remove style changes. | |||||
sack_changed = tcp_sack_doack(tp, &to, th->th_ack); | sack_changed = tcp_sack_doack(tp, &to, th->th_ack); | ||||
else | else | ||||
/* | /* | ||||
* Reset the value so that previous (valid) value | * Reset the value so that previous (valid) value | ||||
* from the last ack with SACK doesn't get used. | * from the last ack with SACK doesn't get used. | ||||
*/ | */ | ||||
tp->sackhint.sacked_bytes = 0; | tp->sackhint.sacked_bytes = 0; | ||||
#ifdef TCP_HHOOK | #ifdef TCP_HHOOK | ||||
/* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */ | /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */ | ||||
hhook_run_tcp_est_in(tp, th, &to); | hhook_run_tcp_est_in(tp, th, &to); | ||||
#endif | #endif | ||||
Done Inline ActionsNew variables should not be declared in the middle of a function. hselasky: New variables should not be declared in the middle of a function. | |||||
if (SEQ_LEQ(th->th_ack, tp->snd_una)) { | if (SEQ_LEQ(th->th_ack, tp->snd_una)) { | ||||
u_int maxseg; | |||||
maxseg = tcp_maxseg(tp); | maxseg = tcp_maxseg(tp); | ||||
if (tlen == 0 && | if (tlen == 0 && | ||||
(tiwin == tp->snd_wnd || | (tiwin == tp->snd_wnd || | ||||
(tp->t_flags & TF_SACK_PERMIT))) { | (tp->t_flags & TF_SACK_PERMIT))) { | ||||
/* | /* | ||||
* If this is the first time we've seen a | * If this is the first time we've seen a | ||||
* FIN from the remote, this is not a | * FIN from the remote, this is not a | ||||
* duplicate and it needs to be processed | * duplicate and it needs to be processed | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | if (SEQ_LEQ(th->th_ack, tp->snd_una)) { | ||||
tp->snd_cwnd += maxseg; | tp->snd_cwnd += maxseg; | ||||
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 || | ||||
(tp->t_flags & TF_SACK_PERMIT && | |||||
V_tcp_do_rfc6675_pipe && | |||||
tp->sackhint.sacked_bytes > | |||||
(tcprexmtthresh - 1) * maxseg)) { | |||||
enter_recovery: | |||||
/* | |||||
* Above is the RFC6675 trigger condition of | |||||
* more than (dupthresh-1)*maxseg sacked data. | |||||
* If the count of holes in the | |||||
* scoreboard is >= dupthresh, we could | |||||
* also enter loss recovery, but don't | |||||
* have that value readily available. | |||||
*/ | |||||
tp->t_dupacks = tcprexmtthresh; | |||||
Done Inline Actionsremove superfluous (), and move comment within the bracket, and rewrite comment rscheff: remove superfluous (), and move comment within the bracket, and rewrite comment | |||||
tcp_seq onxt = tp->snd_nxt; | tcp_seq onxt = tp->snd_nxt; | ||||
/* | /* | ||||
* If we're doing sack, check to | * If we're doing sack, check to | ||||
* see if we're already in sack | * see if we're already in sack | ||||
* recovery. If we're not doing sack, | * recovery. If we're not doing sack, | ||||
* check to see if we're in newreno | * check to see if we're in newreno | ||||
* recovery. | * recovery. | ||||
Show All 17 Lines | enter_recovery: | ||||
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->snd_recover = tp->snd_nxt; | tp->snd_recover = tp->snd_nxt; | ||||
tp->snd_cwnd = maxseg; | tp->snd_cwnd = maxseg; | ||||
(void) tp->t_fb->tfb_tcp_output(tp); | (void) tp->t_fb->tfb_tcp_output(tp); | ||||
if (SEQ_GT(th->th_ack, tp->snd_una)) | |||||
goto resume_partialack; | |||||
goto drop; | goto drop; | ||||
} | } | ||||
tp->snd_nxt = th->th_ack; | tp->snd_nxt = th->th_ack; | ||||
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__)); | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | enter_recovery: | ||||
* sack_changed tracks all changes to the SACK | * sack_changed tracks all changes to the SACK | ||||
* scoreboard, including when partial ACKs without | * scoreboard, including when partial ACKs without | ||||
* SACK options are received, and clear the scoreboard | * SACK options are received, and clear the scoreboard | ||||
* from the left side. Such partial ACKs should not be | * from the left side. Such partial ACKs should not be | ||||
* counted as dupacks here. | * counted as dupacks here. | ||||
*/ | */ | ||||
if ((tp->t_flags & TF_SACK_PERMIT) && | if ((tp->t_flags & TF_SACK_PERMIT) && | ||||
(to.to_flags & TOF_SACK) && | (to.to_flags & TOF_SACK) && | ||||
sack_changed) | sack_changed) { | ||||
tp->t_dupacks++; | tp->t_dupacks++; | ||||
/* limit overhead by setting maxseg last */ | |||||
if (!IN_FASTRECOVERY(tp->t_flags) && | |||||
(tp->sackhint.sacked_bytes > | |||||
((tcprexmtthresh - 1) * | |||||
(maxseg = tcp_maxseg(tp))))) { | |||||
goto enter_recovery; | |||||
} | } | ||||
} | |||||
} | |||||
resume_partialack: | |||||
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)) { | ||||
▲ Show 20 Lines • Show All 1,201 Lines • Show Last 20 Lines |
remove style changes.