* Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCB is still * locked. */
| 8205 | * locked. |
| 8206 | */ |
| 8207 | static int |
| 8208 | bbr_process_data(struct mbuf *m, struct tcphdr *th, struct socket *so, |
| 8209 | struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen, |
| 8210 | uint32_t tiwin, int32_t thflags, int32_t nxt_pkt) |
| 8211 | { |
| 8212 | /* |
| 8213 | * Update window information. Don't look at window if no ACK: TAC's |
| 8214 | * send garbage on first SYN. |
| 8215 | */ |
| 8216 | uint16_t nsegs; |
| 8217 | int32_t tfo_syn; |
| 8218 | struct tcp_bbr *bbr; |
| 8219 | |
| 8220 | bbr = (struct tcp_bbr *)tp->t_fb_ptr; |
| 8221 | INP_WLOCK_ASSERT(tp->t_inpcb); |
| 8222 | nsegs = max(1, m->m_pkthdr.lro_nsegs); |
| 8223 | if ((thflags & TH_ACK) && |
| 8224 | (SEQ_LT(tp->snd_wl1, th->th_seq) || |
| 8225 | (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) || |
| 8226 | (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) { |
| 8227 | /* keep track of pure window updates */ |
| 8228 | if (tlen == 0 && |
| 8229 | tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd) |
| 8230 | KMOD_TCPSTAT_INC(tcps_rcvwinupd); |
| 8231 | tp->snd_wnd = tiwin; |
| 8232 | tp->snd_wl1 = th->th_seq; |
| 8233 | tp->snd_wl2 = th->th_ack; |
| 8234 | if (tp->snd_wnd > tp->max_sndwnd) |
| 8235 | tp->max_sndwnd = tp->snd_wnd; |
| 8236 | bbr->r_wanted_output = 1; |
| 8237 | } else if (thflags & TH_ACK) { |
| 8238 | if ((tp->snd_wl2 == th->th_ack) && (tiwin < tp->snd_wnd)) { |
| 8239 | tp->snd_wnd = tiwin; |
| 8240 | tp->snd_wl1 = th->th_seq; |
| 8241 | tp->snd_wl2 = th->th_ack; |
| 8242 | } |
| 8243 | } |
| 8244 | if (tp->snd_wnd < ctf_outstanding(tp)) |
| 8245 | /* The peer collapsed its window on us */ |
| 8246 | bbr_collapsed_window(bbr); |
| 8247 | else if (bbr->rc_has_collapsed) |
| 8248 | bbr_un_collapse_window(bbr); |
| 8249 | /* Was persist timer active and now we have window space? */ |
| 8250 | if ((bbr->rc_in_persist != 0) && |
| 8251 | (tp->snd_wnd >= min((bbr->r_ctl.rc_high_rwnd/2), |
| 8252 | bbr_minseg(bbr)))) { |
| 8253 | /* |
| 8254 | * Make the rate persist at end of persist mode if idle long |
| 8255 | * enough |
| 8256 | */ |
| 8257 | bbr_exit_persist(tp, bbr, bbr->r_ctl.rc_rcvtime, __LINE__); |
| 8258 | |
| 8259 | /* Make sure we output to start the timer */ |
| 8260 | bbr->r_wanted_output = 1; |
| 8261 | } |
| 8262 | /* Do we need to enter persist? */ |
| 8263 | if ((bbr->rc_in_persist == 0) && |
| 8264 | (tp->snd_wnd < min((bbr->r_ctl.rc_high_rwnd/2), bbr_minseg(bbr))) && |
no test coverage detected