]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netinet/mptcp_timer.c
2 * Copyright (c) 2012-2017 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/kernel.h>
32 #include <sys/mcache.h>
33 #include <sys/socket.h>
34 #include <sys/socketvar.h>
35 #include <sys/syslog.h>
36 #include <sys/protosw.h>
37 #include <sys/sysctl.h>
41 #include <netinet/mp_pcb.h>
42 #include <netinet/mptcp_var.h>
43 #include <netinet/mptcp_timer.h>
44 #include <netinet/mptcp_seq.h>
46 #include <kern/locks.h>
49 * MPTCP Retransmission Timer comes into play only when subflow level
50 * data is acked, but Data ACK is not received. Time is in seconds.
52 static u_int32_t mptcp_rto
= 3;
53 SYSCTL_INT(_net_inet_mptcp
, OID_AUTO
, rto
, CTLFLAG_RW
| CTLFLAG_LOCKED
,
54 &mptcp_rto
, 0, "MPTCP Retransmission Timeout");
56 static int mptcp_nrtos
= 3;
57 SYSCTL_INT(_net_inet_mptcp
, OID_AUTO
, nrto
, CTLFLAG_RW
| CTLFLAG_LOCKED
,
58 &mptcp_rto
, 0, "MPTCP Retransmissions");
61 * MPTCP connections timewait interval in seconds.
63 static u_int32_t mptcp_tw
= 60;
64 SYSCTL_INT(_net_inet_mptcp
, OID_AUTO
, tw
, CTLFLAG_RW
| CTLFLAG_LOCKED
,
65 &mptcp_tw
, 0, "MPTCP Timewait Period");
67 #define TIMEVAL_TO_HZ(_tv_) ((_tv_).tv_sec * hz + (_tv_).tv_usec / hz)
70 mptcp_timer_demux(struct mptses
*mpte
, uint32_t now_msecs
)
72 struct mptcb
*mp_tp
= NULL
;
73 mp_tp
= mpte
->mpte_mptcb
;
74 int resched_timer
= 0;
76 DTRACE_MPTCP2(timer
, struct mptses
*, mpte
, struct mptcb
*, mp_tp
);
78 mpte_lock_assert_held(mpte
);
79 switch (mp_tp
->mpt_timer_vals
) {
81 if (mp_tp
->mpt_rxtstart
== 0)
83 if ((now_msecs
- mp_tp
->mpt_rxtstart
) >
85 if (MPTCP_SEQ_GT(mp_tp
->mpt_snduna
, mp_tp
->mpt_rtseq
)) {
86 mp_tp
->mpt_timer_vals
= 0;
90 mp_tp
->mpt_rxtshift
++;
91 if (mp_tp
->mpt_rxtshift
> mptcp_nrtos
) {
92 mp_tp
->mpt_softerror
= ETIMEDOUT
;
93 DTRACE_MPTCP1(error
, struct mptcb
*, mp_tp
);
95 mp_tp
->mpt_sndnxt
= mp_tp
->mpt_rtseq
;
96 os_log_info(mptcp_log_handle
,
97 "%s: REXMT %d sndnxt %u\n",
98 __func__
, mp_tp
->mpt_rxtshift
,
99 (uint32_t)mp_tp
->mpt_sndnxt
);
107 /* Allows for break before make XXX */
108 if (mp_tp
->mpt_timewait
== 0)
110 if ((now_msecs
- mp_tp
->mpt_timewait
) >
112 mp_tp
->mpt_softerror
= ETIMEDOUT
;
113 DTRACE_MPTCP1(error
, struct mptcb
*, mp_tp
);
125 return (resched_timer
);
129 mptcp_timer(struct mppcbinfo
*mppi
)
131 struct mppcb
*mpp
, *tmpp
;
134 uint32_t resched_timer
= 0;
136 LCK_MTX_ASSERT(&mppi
->mppi_lock
, LCK_MTX_ASSERT_OWNED
);
139 now_msecs
= TIMEVAL_TO_HZ(now
);
140 TAILQ_FOREACH_SAFE(mpp
, &mppi
->mppi_pcbs
, mpp_entry
, tmpp
) {
141 struct socket
*mp_so
;
144 mp_so
= mpp
->mpp_socket
;
145 VERIFY(mp_so
!= NULL
);
146 mpte
= mptompte(mpp
);
147 VERIFY(mpte
!= NULL
);
149 VERIFY(mpp
->mpp_flags
& MPP_ATTACHED
);
151 if (mptcp_timer_demux(mpte
, now_msecs
))
156 return (resched_timer
);
160 mptcp_start_timer(struct mptses
*mpte
, int timer_type
)
163 struct mptcb
*mp_tp
= mpte
->mpte_mptcb
;
167 DTRACE_MPTCP2(start__timer
, struct mptcb
*, mp_tp
, int, timer_type
);
168 mptcplog((LOG_DEBUG
, "MPTCP Socket: %s: %d\n", __func__
, timer_type
),
169 MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_VERBOSE
);
171 mpte_lock_assert_held(mpte
);
173 switch (timer_type
) {
175 mp_tp
->mpt_timer_vals
|= MPTT_REXMT
;
176 mp_tp
->mpt_rxtstart
= TIMEVAL_TO_HZ(now
);
177 mp_tp
->mpt_rxtshift
= 0;
178 mp_tp
->mpt_rtseq
= mp_tp
->mpt_sndnxt
;
181 /* XXX: Not implemented yet */
182 mp_tp
->mpt_timer_vals
|= MPTT_TW
;
183 mp_tp
->mpt_timewait
= TIMEVAL_TO_HZ(now
);
196 mptcp_cancel_timer(struct mptcb
*mp_tp
, int timer_type
)
198 mpte_lock_assert_held(mp_tp
->mpt_mpte
);
199 DTRACE_MPTCP2(cancel__timer
, struct mptcb
*, mp_tp
, int, timer_type
);
201 switch (timer_type
) {
203 mp_tp
->mpt_rxtstart
= 0;
204 mp_tp
->mpt_rxtshift
= 0;
205 mp_tp
->mpt_timer_vals
= 0;
219 mptcp_cancel_all_timers(struct mptcb
*mp_tp
)
221 mptcp_cancel_timer(mp_tp
, MPTT_REXMT
);
222 mptcp_cancel_timer(mp_tp
, MPTT_TW
);
223 mptcp_cancel_timer(mp_tp
, MPTT_FASTCLOSE
);