]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netinet/mptcp_timer.c
2 * Copyright (c) 2012-2013 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
);
80 switch (mp_tp
->mpt_timer_vals
) {
82 if (mp_tp
->mpt_rxtstart
== 0)
84 if ((now_msecs
- mp_tp
->mpt_rxtstart
) >
86 if (MPTCP_SEQ_GT(mp_tp
->mpt_snduna
,
88 mp_tp
->mpt_timer_vals
= 0;
92 mp_tp
->mpt_rxtshift
++;
93 if (mp_tp
->mpt_rxtshift
> mptcp_nrtos
) {
94 mp_tp
->mpt_softerror
= ETIMEDOUT
;
95 DTRACE_MPTCP1(error
, struct mptcb
*, mp_tp
);
97 mp_tp
->mpt_sndnxt
= mp_tp
->mpt_rtseq
;
99 mptcplog((LOG_DEBUG
, "MPTCP Socket: "
100 "%s: REXMT %d times.\n",
101 __func__
, mp_tp
->mpt_rxtshift
),
102 MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_LOG
);
111 /* Allows for break before make XXX */
112 if (mp_tp
->mpt_timewait
== 0)
114 if ((now_msecs
- mp_tp
->mpt_timewait
) >
116 mp_tp
->mpt_softerror
= ETIMEDOUT
;
117 DTRACE_MPTCP1(error
, struct mptcb
*, mp_tp
);
130 return (resched_timer
);
134 mptcp_timer(struct mppcbinfo
*mppi
)
136 struct mppcb
*mpp
, *tmpp
;
139 uint32_t resched_timer
= 0;
141 lck_mtx_assert(&mppi
->mppi_lock
, LCK_MTX_ASSERT_OWNED
);
144 now_msecs
= TIMEVAL_TO_HZ(now
);
145 TAILQ_FOREACH_SAFE(mpp
, &mppi
->mppi_pcbs
, mpp_entry
, tmpp
) {
146 struct socket
*mp_so
;
149 mp_so
= mpp
->mpp_socket
;
150 VERIFY(mp_so
!= NULL
);
151 mpte
= mptompte(mpp
);
152 VERIFY(mpte
!= NULL
);
154 VERIFY(mpp
->mpp_flags
& MPP_ATTACHED
);
156 if (mpp
->mpp_flags
& MPP_DEFUNCT
) {
161 if (mptcp_timer_demux(mpte
, now_msecs
))
166 return (resched_timer
);
170 mptcp_start_timer(struct mptses
*mpte
, int timer_type
)
173 struct mptcb
*mp_tp
= mpte
->mpte_mptcb
;
177 DTRACE_MPTCP2(start__timer
, struct mptcb
*, mp_tp
, int, timer_type
);
178 mptcplog((LOG_DEBUG
, "MPTCP Socket: %s: %d\n", __func__
, timer_type
),
179 MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_VERBOSE
);
181 switch (timer_type
) {
184 mp_tp
->mpt_timer_vals
|= MPTT_REXMT
;
185 mp_tp
->mpt_rxtstart
= TIMEVAL_TO_HZ(now
);
186 mp_tp
->mpt_rxtshift
= 0;
187 mp_tp
->mpt_rtseq
= mp_tp
->mpt_sndnxt
;
191 /* XXX: Not implemented yet */
193 mp_tp
->mpt_timer_vals
|= MPTT_TW
;
194 mp_tp
->mpt_timewait
= TIMEVAL_TO_HZ(now
);
208 mptcp_cancel_timer(struct mptcb
*mp_tp
, int timer_type
)
210 MPT_LOCK_ASSERT_HELD(mp_tp
);
211 DTRACE_MPTCP2(cancel__timer
, struct mptcb
*, mp_tp
, int, timer_type
);
213 switch (timer_type
) {
215 mp_tp
->mpt_rxtstart
= 0;
216 mp_tp
->mpt_rxtshift
= 0;
217 mp_tp
->mpt_timer_vals
= 0;
231 mptcp_cancel_all_timers(struct mptcb
*mp_tp
)
233 mptcp_cancel_timer(mp_tp
, MPTT_REXMT
);
234 mptcp_cancel_timer(mp_tp
, MPTT_TW
);
235 mptcp_cancel_timer(mp_tp
, MPTT_FASTCLOSE
);