* Return value of 1, the TCB is unlocked and most * likely gone, return value of 0, the TCP is still * locked. */
| 8525 | * locked. |
| 8526 | */ |
| 8527 | static int |
| 8528 | rack_process_data(struct mbuf *m, struct tcphdr *th, struct socket *so, |
| 8529 | struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen, |
| 8530 | uint32_t tiwin, int32_t thflags, int32_t nxt_pkt) |
| 8531 | { |
| 8532 | /* |
| 8533 | * Update window information. Don't look at window if no ACK: TAC's |
| 8534 | * send garbage on first SYN. |
| 8535 | */ |
| 8536 | int32_t nsegs; |
| 8537 | int32_t tfo_syn; |
| 8538 | struct tcp_rack *rack; |
| 8539 | |
| 8540 | rack = (struct tcp_rack *)tp->t_fb_ptr; |
| 8541 | INP_WLOCK_ASSERT(tp->t_inpcb); |
| 8542 | nsegs = max(1, m->m_pkthdr.lro_nsegs); |
| 8543 | if ((thflags & TH_ACK) && |
| 8544 | (SEQ_LT(tp->snd_wl1, th->th_seq) || |
| 8545 | (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) || |
| 8546 | (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) { |
| 8547 | /* keep track of pure window updates */ |
| 8548 | if (tlen == 0 && |
| 8549 | tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd) |
| 8550 | KMOD_TCPSTAT_INC(tcps_rcvwinupd); |
| 8551 | tp->snd_wnd = tiwin; |
| 8552 | tp->snd_wl1 = th->th_seq; |
| 8553 | tp->snd_wl2 = th->th_ack; |
| 8554 | if (tp->snd_wnd > tp->max_sndwnd) |
| 8555 | tp->max_sndwnd = tp->snd_wnd; |
| 8556 | rack->r_wanted_output = 1; |
| 8557 | } else if (thflags & TH_ACK) { |
| 8558 | if ((tp->snd_wl2 == th->th_ack) && (tiwin < tp->snd_wnd)) { |
| 8559 | tp->snd_wnd = tiwin; |
| 8560 | tp->snd_wl1 = th->th_seq; |
| 8561 | tp->snd_wl2 = th->th_ack; |
| 8562 | } |
| 8563 | } |
| 8564 | if (tp->snd_wnd < ctf_outstanding(tp)) |
| 8565 | /* The peer collapsed the window */ |
| 8566 | rack_collapsed_window(rack); |
| 8567 | else if (rack->rc_has_collapsed) |
| 8568 | rack_un_collapse_window(rack); |
| 8569 | /* Was persist timer active and now we have window space? */ |
| 8570 | if ((rack->rc_in_persist != 0) && |
| 8571 | (tp->snd_wnd >= min((rack->r_ctl.rc_high_rwnd/2), |
| 8572 | rack->r_ctl.rc_pace_min_segs))) { |
| 8573 | rack_exit_persist(tp, rack, rack->r_ctl.rc_rcvtime); |
| 8574 | tp->snd_nxt = tp->snd_max; |
| 8575 | /* Make sure we output to start the timer */ |
| 8576 | rack->r_wanted_output = 1; |
| 8577 | } |
| 8578 | /* Do we enter persists? */ |
| 8579 | if ((rack->rc_in_persist == 0) && |
| 8580 | (tp->snd_wnd < min((rack->r_ctl.rc_high_rwnd/2), rack->r_ctl.rc_pace_min_segs)) && |
| 8581 | TCPS_HAVEESTABLISHED(tp->t_state) && |
| 8582 | (tp->snd_max == tp->snd_una) && |
| 8583 | sbavail(&tp->t_inpcb->inp_socket->so_snd) && |
| 8584 | (sbavail(&tp->t_inpcb->inp_socket->so_snd) > tp->snd_wnd)) { |
no test coverage detected