Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_input.c
Show First 20 Lines • Show All 1,476 Lines • ▼ Show 20 Lines | tcp_handle_wakeup(struct tcpcb *tp, struct socket *so) | ||||
if ((so->so_state & SS_ISCONNECTED) == 0) | if ((so->so_state & SS_ISCONNECTED) == 0) | ||||
return; | return; | ||||
INP_LOCK_ASSERT(tp->t_inpcb); | INP_LOCK_ASSERT(tp->t_inpcb); | ||||
if (tp->t_flags & TF_WAKESOR) { | if (tp->t_flags & TF_WAKESOR) { | ||||
tp->t_flags &= ~TF_WAKESOR; | tp->t_flags &= ~TF_WAKESOR; | ||||
SOCKBUF_UNLOCK_ASSERT(&so->so_rcv); | SOCKBUF_UNLOCK_ASSERT(&so->so_rcv); | ||||
sorwakeup(so); | sorwakeup(so); | ||||
} | } | ||||
if (tp->t_flags & TF_WAKESOW) { | |||||
tp->t_flags &= ~TF_WAKESOW; | |||||
SOCKBUF_UNLOCK_ASSERT(&so->so_snd); | |||||
sowwakeup(so); | |||||
} | } | ||||
} | |||||
void | void | ||||
tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, | tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, | ||||
struct tcpcb *tp, int drop_hdrlen, int tlen, uint8_t iptos) | struct tcpcb *tp, int drop_hdrlen, int tlen, uint8_t iptos) | ||||
{ | { | ||||
int thflags, acked, ourfinisacked, needoutput = 0, sack_changed; | int thflags, acked, ourfinisacked, needoutput = 0, sack_changed; | ||||
int rstreason, todrop, win, incforsyn = 0; | int rstreason, todrop, win, incforsyn = 0; | ||||
uint32_t tiwin; | uint32_t tiwin; | ||||
▲ Show 20 Lines • Show All 359 Lines • ▼ Show 20 Lines | #ifdef TCPDEBUG | ||||
&tcp_savetcp, 0); | &tcp_savetcp, 0); | ||||
#endif | #endif | ||||
TCP_PROBE3(debug__input, tp, th, m); | TCP_PROBE3(debug__input, tp, th, m); | ||||
if (tp->snd_una == tp->snd_max) | if (tp->snd_una == tp->snd_max) | ||||
tcp_timer_activate(tp, TT_REXMT, 0); | tcp_timer_activate(tp, TT_REXMT, 0); | ||||
else if (!tcp_timer_active(tp, TT_PERSIST)) | else if (!tcp_timer_active(tp, TT_PERSIST)) | ||||
tcp_timer_activate(tp, TT_REXMT, | tcp_timer_activate(tp, TT_REXMT, | ||||
tp->t_rxtcur); | tp->t_rxtcur); | ||||
tp->t_flags |= TF_WAKESOW; | sowwakeup(so); | ||||
rscheff: This causes a doule-lock of so_snd later in the processing. Need to protect it by checking the… | |||||
if (sbavail(&so->so_snd)) | if (sbavail(&so->so_snd)) | ||||
(void) tp->t_fb->tfb_tcp_output(tp); | (void) tp->t_fb->tfb_tcp_output(tp); | ||||
goto check_delack; | goto check_delack; | ||||
} | } | ||||
} else if (th->th_ack == tp->snd_una && | } else if (th->th_ack == tp->snd_una && | ||||
tlen <= sbspace(&so->so_rcv)) { | tlen <= sbspace(&so->so_rcv)) { | ||||
int newsize = 0; /* automatic sockbuf scaling */ | int newsize = 0; /* automatic sockbuf scaling */ | ||||
▲ Show 20 Lines • Show All 721 Lines • ▼ Show 20 Lines | if (SEQ_LEQ(th->th_ack, tp->snd_una)) { | ||||
if (awnd < tp->snd_ssthresh) { | if (awnd < tp->snd_ssthresh) { | ||||
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); | ||||
Not Done Inline Actionsperhaps getting rid of these could reduce diff? otis: perhaps getting rid of these could reduce diff? | |||||
goto drop; | goto drop; | ||||
} else if (tp->t_dupacks == tcprexmtthresh || | } else if (tp->t_dupacks == tcprexmtthresh || | ||||
(tp->t_flags & TF_SACK_PERMIT && | (tp->t_flags & TF_SACK_PERMIT && | ||||
V_tcp_do_rfc6675_pipe && | V_tcp_do_rfc6675_pipe && | ||||
tp->sackhint.sacked_bytes > | tp->sackhint.sacked_bytes > | ||||
(tcprexmtthresh - 1) * maxseg)) { | (tcprexmtthresh - 1) * maxseg)) { | ||||
enter_recovery: | enter_recovery: | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 303 Lines • ▼ Show 20 Lines | process_ACK: | ||||
} else { | } else { | ||||
mfree = sbcut_locked(&so->so_snd, acked); | mfree = sbcut_locked(&so->so_snd, acked); | ||||
if (tp->snd_wnd >= (uint32_t) acked) | if (tp->snd_wnd >= (uint32_t) acked) | ||||
tp->snd_wnd -= acked; | tp->snd_wnd -= acked; | ||||
else | else | ||||
tp->snd_wnd = 0; | tp->snd_wnd = 0; | ||||
ourfinisacked = 0; | ourfinisacked = 0; | ||||
} | } | ||||
SOCKBUF_UNLOCK(&so->so_snd); | /* NB: sowwakeup_locked() does an implicit unlock. */ | ||||
tp->t_flags |= TF_WAKESOW; | sowwakeup_locked(so); | ||||
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) && | ||||
▲ Show 20 Lines • Show All 1,114 Lines • Show Last 20 Lines |
This causes a doule-lock of so_snd later in the processing. Need to protect it by checking the flag first. (381)