+/*
+ * Update the mptcb send state variables, but the actual sbdrop occurs
+ * in MPTCP layer
+ */
+void
+mptcp_data_ack_rcvd(struct mptcb *mp_tp, struct tcpcb *tp, u_int64_t full_dack)
+{
+ u_int64_t acked = 0;
+
+ acked = full_dack - mp_tp->mpt_snduna;
+
+ if (acked) {
+ struct socket *mp_so = mptetoso(mp_tp->mpt_mpte);
+
+ if (acked > mp_so->so_snd.sb_cc) {
+ if (acked > mp_so->so_snd.sb_cc + 1 ||
+ mp_tp->mpt_state < MPTCPS_FIN_WAIT_1)
+ mptcplog((LOG_ERR, "%s: acked %u, sb_cc %u full %u suna %u state %u\n",
+ __func__, (uint32_t)acked, mp_so->so_snd.sb_cc,
+ (uint32_t)full_dack, (uint32_t)mp_tp->mpt_snduna,
+ mp_tp->mpt_state),
+ MPTCP_RECEIVER_DBG, MPTCP_LOGLVL_ERR);
+
+ sbdrop(&mp_so->so_snd, (int)mp_so->so_snd.sb_cc);
+ } else {
+ sbdrop(&mp_so->so_snd, acked);
+ }
+
+ mp_tp->mpt_snduna += acked;
+ /* In degraded mode, we may get some Data ACKs */
+ if ((tp->t_mpflags & TMPF_TCP_FALLBACK) &&
+ !(mp_tp->mpt_flags & MPTCPF_POST_FALLBACK_SYNC) &&
+ MPTCP_SEQ_GT(mp_tp->mpt_sndnxt, mp_tp->mpt_snduna)) {
+ /* bring back sndnxt to retransmit MPTCP data */
+ mp_tp->mpt_sndnxt = mp_tp->mpt_dsn_at_csum_fail;
+ mp_tp->mpt_flags |= MPTCPF_POST_FALLBACK_SYNC;
+ tp->t_inpcb->inp_socket->so_flags1 |=
+ SOF1_POST_FALLBACK_SYNC;
+ }
+
+ mptcp_clean_reinjectq(mp_tp->mpt_mpte);
+
+ sowwakeup(mp_so);
+ }
+ if (full_dack == mp_tp->mpt_sndmax &&
+ mp_tp->mpt_state >= MPTCPS_FIN_WAIT_1) {
+ mptcp_close_fsm(mp_tp, MPCE_RECV_DATA_ACK);
+ tp->t_mpflags &= ~TMPF_SEND_DFIN;
+ }
+}
+
+void
+mptcp_update_window_fallback(struct tcpcb *tp)
+{
+ struct mptcb *mp_tp = tptomptp(tp);
+
+ mpte_lock_assert_held(mp_tp->mpt_mpte);
+
+ if (!(mp_tp->mpt_flags & MPTCPF_FALLBACK_TO_TCP))
+ return;
+
+ mptcplog((LOG_DEBUG, "%s: update window to %u\n", __func__, tp->snd_wnd),
+ MPTCP_SOCKET_DBG, MPTCP_LOGLVL_VERBOSE);
+
+ mp_tp->mpt_sndwnd = tp->snd_wnd;
+ mp_tp->mpt_sndwl1 = mp_tp->mpt_rcvnxt;
+ mp_tp->mpt_sndwl2 = mp_tp->mpt_snduna;
+
+ sowwakeup(tp->t_inpcb->inp_socket);
+}
+
+static void
+mptcp_update_window(struct mptcb *mp_tp, u_int64_t ack, u_int64_t seq,
+ u_int32_t tiwin)
+{
+ /* Don't look at the window if there is no ACK flag */
+ if ((SEQ_LT(mp_tp->mpt_sndwl1, seq) ||
+ (mp_tp->mpt_sndwl1 == seq && (SEQ_LT(mp_tp->mpt_sndwl2, ack) ||
+ (mp_tp->mpt_sndwl2 == ack && tiwin > mp_tp->mpt_sndwnd))))) {
+ mp_tp->mpt_sndwnd = tiwin;
+ mp_tp->mpt_sndwl1 = seq;
+ mp_tp->mpt_sndwl2 = ack;
+
+ mptcplog((LOG_DEBUG, "%s: Updating window to %u\n", __func__,
+ mp_tp->mpt_sndwnd), MPTCP_RECEIVER_DBG, MPTCP_LOGLVL_VERBOSE);
+ }
+}
+