1*aca3beaaSApple OSS Distributions /*
2*aca3beaaSApple OSS Distributions * Copyright (c) 2012-2017 Apple Inc. All rights reserved.
3*aca3beaaSApple OSS Distributions *
4*aca3beaaSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*aca3beaaSApple OSS Distributions *
6*aca3beaaSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*aca3beaaSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*aca3beaaSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*aca3beaaSApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*aca3beaaSApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*aca3beaaSApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*aca3beaaSApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*aca3beaaSApple OSS Distributions * terms of an Apple operating system software license agreement.
14*aca3beaaSApple OSS Distributions *
15*aca3beaaSApple OSS Distributions * Please obtain a copy of the License at
16*aca3beaaSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*aca3beaaSApple OSS Distributions *
18*aca3beaaSApple OSS Distributions * The Original Code and all software distributed under the License are
19*aca3beaaSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*aca3beaaSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*aca3beaaSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*aca3beaaSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*aca3beaaSApple OSS Distributions * Please see the License for the specific language governing rights and
24*aca3beaaSApple OSS Distributions * limitations under the License.
25*aca3beaaSApple OSS Distributions *
26*aca3beaaSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*aca3beaaSApple OSS Distributions */
28*aca3beaaSApple OSS Distributions #include <sys/param.h>
29*aca3beaaSApple OSS Distributions #include <sys/systm.h>
30*aca3beaaSApple OSS Distributions #include <netinet/in_systm.h>
31*aca3beaaSApple OSS Distributions #include <sys/socket.h>
32*aca3beaaSApple OSS Distributions #include <sys/socketvar.h>
33*aca3beaaSApple OSS Distributions #include <sys/syslog.h>
34*aca3beaaSApple OSS Distributions #include <net/route.h>
35*aca3beaaSApple OSS Distributions #include <netinet/in.h>
36*aca3beaaSApple OSS Distributions #include <net/if.h>
37*aca3beaaSApple OSS Distributions
38*aca3beaaSApple OSS Distributions #include <netinet/ip.h>
39*aca3beaaSApple OSS Distributions #include <netinet/ip_var.h>
40*aca3beaaSApple OSS Distributions #include <netinet/in_var.h>
41*aca3beaaSApple OSS Distributions #include <netinet/tcp.h>
42*aca3beaaSApple OSS Distributions #include <netinet/tcp_cache.h>
43*aca3beaaSApple OSS Distributions #include <netinet/tcp_seq.h>
44*aca3beaaSApple OSS Distributions #include <netinet/tcpip.h>
45*aca3beaaSApple OSS Distributions #include <netinet/tcp_fsm.h>
46*aca3beaaSApple OSS Distributions #include <netinet/mptcp_var.h>
47*aca3beaaSApple OSS Distributions #include <netinet/mptcp.h>
48*aca3beaaSApple OSS Distributions #include <netinet/mptcp_opt.h>
49*aca3beaaSApple OSS Distributions #include <netinet/mptcp_seq.h>
50*aca3beaaSApple OSS Distributions
51*aca3beaaSApple OSS Distributions #include <libkern/crypto/sha1.h>
52*aca3beaaSApple OSS Distributions #include <libkern/crypto/sha2.h>
53*aca3beaaSApple OSS Distributions #include <netinet/mptcp_timer.h>
54*aca3beaaSApple OSS Distributions
55*aca3beaaSApple OSS Distributions #include <mach/sdt.h>
56*aca3beaaSApple OSS Distributions
57*aca3beaaSApple OSS Distributions static int mptcp_validate_join_hmac(struct tcpcb *, u_char*, int);
58*aca3beaaSApple OSS Distributions static int mptcp_snd_mpprio(struct tcpcb *tp, u_char *cp, int optlen);
59*aca3beaaSApple OSS Distributions static void mptcp_send_remaddr_opt(struct tcpcb *, struct mptcp_remaddr_opt *);
60*aca3beaaSApple OSS Distributions static int mptcp_echo_add_addr(struct tcpcb *, u_char *, unsigned int);
61*aca3beaaSApple OSS Distributions
62*aca3beaaSApple OSS Distributions /*
63*aca3beaaSApple OSS Distributions * MPTCP Options Output Processing
64*aca3beaaSApple OSS Distributions */
65*aca3beaaSApple OSS Distributions
66*aca3beaaSApple OSS Distributions static unsigned
mptcp_setup_first_subflow_syn_opts(struct socket * so,u_char * opt,unsigned optlen)67*aca3beaaSApple OSS Distributions mptcp_setup_first_subflow_syn_opts(struct socket *so, u_char *opt, unsigned optlen)
68*aca3beaaSApple OSS Distributions {
69*aca3beaaSApple OSS Distributions struct mptcp_mpcapable_opt_rsp mptcp_opt;
70*aca3beaaSApple OSS Distributions struct tcpcb *tp = sototcpcb(so);
71*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
72*aca3beaaSApple OSS Distributions struct mptses *mpte = mp_tp->mpt_mpte;
73*aca3beaaSApple OSS Distributions int ret;
74*aca3beaaSApple OSS Distributions
75*aca3beaaSApple OSS Distributions uint8_t mmco_len = mp_tp->mpt_version == MPTCP_VERSION_0 ?
76*aca3beaaSApple OSS Distributions sizeof(struct mptcp_mpcapable_opt_rsp) :
77*aca3beaaSApple OSS Distributions sizeof(struct mptcp_mpcapable_opt_common);
78*aca3beaaSApple OSS Distributions
79*aca3beaaSApple OSS Distributions ret = tcp_heuristic_do_mptcp(tp);
80*aca3beaaSApple OSS Distributions if (ret > 0) {
81*aca3beaaSApple OSS Distributions os_log_info(mptcp_log_handle, "%s - %lx: Not doing MPTCP due to heuristics",
82*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mp_tp->mpt_mpte));
83*aca3beaaSApple OSS Distributions mp_tp->mpt_flags |= MPTCPF_FALLBACK_HEURISTIC;
84*aca3beaaSApple OSS Distributions return optlen;
85*aca3beaaSApple OSS Distributions }
86*aca3beaaSApple OSS Distributions
87*aca3beaaSApple OSS Distributions /*
88*aca3beaaSApple OSS Distributions * Avoid retransmitting the MP_CAPABLE option.
89*aca3beaaSApple OSS Distributions */
90*aca3beaaSApple OSS Distributions if (ret == 0 &&
91*aca3beaaSApple OSS Distributions tp->t_rxtshift > mptcp_mpcap_retries &&
92*aca3beaaSApple OSS Distributions !(mpte->mpte_flags & MPTE_FORCE_ENABLE)) {
93*aca3beaaSApple OSS Distributions if (!(mp_tp->mpt_flags & (MPTCPF_FALLBACK_HEURISTIC | MPTCPF_HEURISTIC_TRAC))) {
94*aca3beaaSApple OSS Distributions mp_tp->mpt_flags |= MPTCPF_HEURISTIC_TRAC;
95*aca3beaaSApple OSS Distributions tcp_heuristic_mptcp_loss(tp);
96*aca3beaaSApple OSS Distributions }
97*aca3beaaSApple OSS Distributions return optlen;
98*aca3beaaSApple OSS Distributions }
99*aca3beaaSApple OSS Distributions
100*aca3beaaSApple OSS Distributions bzero(&mptcp_opt, sizeof(struct mptcp_mpcapable_opt_rsp));
101*aca3beaaSApple OSS Distributions
102*aca3beaaSApple OSS Distributions mptcp_opt.mmc_common.mmco_kind = TCPOPT_MULTIPATH;
103*aca3beaaSApple OSS Distributions mptcp_opt.mmc_common.mmco_len = mmco_len;
104*aca3beaaSApple OSS Distributions mptcp_opt.mmc_common.mmco_subtype = MPO_CAPABLE;
105*aca3beaaSApple OSS Distributions mptcp_opt.mmc_common.mmco_version = mp_tp->mpt_version;
106*aca3beaaSApple OSS Distributions mptcp_opt.mmc_common.mmco_flags |= MPCAP_PROPOSAL_SBIT;
107*aca3beaaSApple OSS Distributions if (mp_tp->mpt_flags & MPTCPF_CHECKSUM) {
108*aca3beaaSApple OSS Distributions mptcp_opt.mmc_common.mmco_flags |= MPCAP_CHECKSUM_CBIT;
109*aca3beaaSApple OSS Distributions }
110*aca3beaaSApple OSS Distributions mptcp_opt.mmc_localkey = mp_tp->mpt_localkey;
111*aca3beaaSApple OSS Distributions
112*aca3beaaSApple OSS Distributions memcpy(opt + optlen, &mptcp_opt, mmco_len);
113*aca3beaaSApple OSS Distributions optlen += mmco_len;
114*aca3beaaSApple OSS Distributions
115*aca3beaaSApple OSS Distributions return optlen;
116*aca3beaaSApple OSS Distributions }
117*aca3beaaSApple OSS Distributions
118*aca3beaaSApple OSS Distributions static unsigned
mptcp_setup_join_subflow_syn_opts(struct socket * so,u_char * opt,unsigned optlen)119*aca3beaaSApple OSS Distributions mptcp_setup_join_subflow_syn_opts(struct socket *so, u_char *opt, unsigned optlen)
120*aca3beaaSApple OSS Distributions {
121*aca3beaaSApple OSS Distributions struct mptcp_mpjoin_opt_req mpjoin_req;
122*aca3beaaSApple OSS Distributions struct inpcb *inp = sotoinpcb(so);
123*aca3beaaSApple OSS Distributions struct tcpcb *tp = NULL;
124*aca3beaaSApple OSS Distributions struct mptsub *mpts;
125*aca3beaaSApple OSS Distributions
126*aca3beaaSApple OSS Distributions if (!inp) {
127*aca3beaaSApple OSS Distributions return optlen;
128*aca3beaaSApple OSS Distributions }
129*aca3beaaSApple OSS Distributions
130*aca3beaaSApple OSS Distributions tp = intotcpcb(inp);
131*aca3beaaSApple OSS Distributions if (!tp) {
132*aca3beaaSApple OSS Distributions return optlen;
133*aca3beaaSApple OSS Distributions }
134*aca3beaaSApple OSS Distributions
135*aca3beaaSApple OSS Distributions mpts = tp->t_mpsub;
136*aca3beaaSApple OSS Distributions
137*aca3beaaSApple OSS Distributions bzero(&mpjoin_req, sizeof(mpjoin_req));
138*aca3beaaSApple OSS Distributions mpjoin_req.mmjo_kind = TCPOPT_MULTIPATH;
139*aca3beaaSApple OSS Distributions mpjoin_req.mmjo_len = sizeof(mpjoin_req);
140*aca3beaaSApple OSS Distributions mpjoin_req.mmjo_subtype_bkp = MPO_JOIN << 4;
141*aca3beaaSApple OSS Distributions
142*aca3beaaSApple OSS Distributions if (tp->t_mpflags & TMPF_BACKUP_PATH) {
143*aca3beaaSApple OSS Distributions mpjoin_req.mmjo_subtype_bkp |= MPTCP_BACKUP;
144*aca3beaaSApple OSS Distributions } else if (inp->inp_boundifp && IFNET_IS_CELLULAR(inp->inp_boundifp) &&
145*aca3beaaSApple OSS Distributions mptcp_subflows_need_backup_flag(mpts->mpts_mpte)) {
146*aca3beaaSApple OSS Distributions mpjoin_req.mmjo_subtype_bkp |= MPTCP_BACKUP;
147*aca3beaaSApple OSS Distributions tp->t_mpflags |= TMPF_BACKUP_PATH;
148*aca3beaaSApple OSS Distributions } else {
149*aca3beaaSApple OSS Distributions mpts->mpts_flags |= MPTSF_PREFERRED;
150*aca3beaaSApple OSS Distributions }
151*aca3beaaSApple OSS Distributions
152*aca3beaaSApple OSS Distributions mpjoin_req.mmjo_addr_id = tp->t_local_aid;
153*aca3beaaSApple OSS Distributions mpjoin_req.mmjo_peer_token = tptomptp(tp)->mpt_remotetoken;
154*aca3beaaSApple OSS Distributions mptcp_get_rands(tp->t_local_aid, tptomptp(tp),
155*aca3beaaSApple OSS Distributions &mpjoin_req.mmjo_rand, NULL);
156*aca3beaaSApple OSS Distributions memcpy(opt + optlen, &mpjoin_req, mpjoin_req.mmjo_len);
157*aca3beaaSApple OSS Distributions optlen += mpjoin_req.mmjo_len;
158*aca3beaaSApple OSS Distributions
159*aca3beaaSApple OSS Distributions return optlen;
160*aca3beaaSApple OSS Distributions }
161*aca3beaaSApple OSS Distributions
162*aca3beaaSApple OSS Distributions unsigned
mptcp_setup_join_ack_opts(struct tcpcb * tp,u_char * opt,unsigned optlen)163*aca3beaaSApple OSS Distributions mptcp_setup_join_ack_opts(struct tcpcb *tp, u_char *opt, unsigned optlen)
164*aca3beaaSApple OSS Distributions {
165*aca3beaaSApple OSS Distributions unsigned new_optlen;
166*aca3beaaSApple OSS Distributions struct mptcp_mpjoin_opt_rsp2 join_rsp2;
167*aca3beaaSApple OSS Distributions
168*aca3beaaSApple OSS Distributions if ((MAX_TCPOPTLEN - optlen) < sizeof(struct mptcp_mpjoin_opt_rsp2)) {
169*aca3beaaSApple OSS Distributions printf("%s: no space left %d \n", __func__, optlen);
170*aca3beaaSApple OSS Distributions return optlen;
171*aca3beaaSApple OSS Distributions }
172*aca3beaaSApple OSS Distributions
173*aca3beaaSApple OSS Distributions bzero(&join_rsp2, sizeof(struct mptcp_mpjoin_opt_rsp2));
174*aca3beaaSApple OSS Distributions join_rsp2.mmjo_kind = TCPOPT_MULTIPATH;
175*aca3beaaSApple OSS Distributions join_rsp2.mmjo_len = sizeof(struct mptcp_mpjoin_opt_rsp2);
176*aca3beaaSApple OSS Distributions join_rsp2.mmjo_subtype = MPO_JOIN;
177*aca3beaaSApple OSS Distributions mptcp_get_mpjoin_hmac(tp->t_local_aid, tptomptp(tp),
178*aca3beaaSApple OSS Distributions (u_char*)&join_rsp2.mmjo_mac, HMAC_TRUNCATED_ACK);
179*aca3beaaSApple OSS Distributions memcpy(opt + optlen, &join_rsp2, join_rsp2.mmjo_len);
180*aca3beaaSApple OSS Distributions new_optlen = optlen + join_rsp2.mmjo_len;
181*aca3beaaSApple OSS Distributions return new_optlen;
182*aca3beaaSApple OSS Distributions }
183*aca3beaaSApple OSS Distributions
184*aca3beaaSApple OSS Distributions unsigned
mptcp_setup_syn_opts(struct socket * so,u_char * opt,unsigned optlen)185*aca3beaaSApple OSS Distributions mptcp_setup_syn_opts(struct socket *so, u_char *opt, unsigned optlen)
186*aca3beaaSApple OSS Distributions {
187*aca3beaaSApple OSS Distributions unsigned new_optlen;
188*aca3beaaSApple OSS Distributions
189*aca3beaaSApple OSS Distributions if (!(so->so_flags & SOF_MP_SEC_SUBFLOW)) {
190*aca3beaaSApple OSS Distributions new_optlen = mptcp_setup_first_subflow_syn_opts(so, opt, optlen);
191*aca3beaaSApple OSS Distributions } else {
192*aca3beaaSApple OSS Distributions new_optlen = mptcp_setup_join_subflow_syn_opts(so, opt, optlen);
193*aca3beaaSApple OSS Distributions }
194*aca3beaaSApple OSS Distributions
195*aca3beaaSApple OSS Distributions return new_optlen;
196*aca3beaaSApple OSS Distributions }
197*aca3beaaSApple OSS Distributions
198*aca3beaaSApple OSS Distributions static int
mptcp_send_mpfail(struct tcpcb * tp,u_char * opt,unsigned int optlen)199*aca3beaaSApple OSS Distributions mptcp_send_mpfail(struct tcpcb *tp, u_char *opt, unsigned int optlen)
200*aca3beaaSApple OSS Distributions {
201*aca3beaaSApple OSS Distributions #pragma unused(tp, opt, optlen)
202*aca3beaaSApple OSS Distributions
203*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = NULL;
204*aca3beaaSApple OSS Distributions struct mptcp_mpfail_opt fail_opt;
205*aca3beaaSApple OSS Distributions uint64_t dsn;
206*aca3beaaSApple OSS Distributions uint8_t len = sizeof(struct mptcp_mpfail_opt);
207*aca3beaaSApple OSS Distributions
208*aca3beaaSApple OSS Distributions mp_tp = tptomptp(tp);
209*aca3beaaSApple OSS Distributions if (mp_tp == NULL) {
210*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_SND_MPFAIL;
211*aca3beaaSApple OSS Distributions return optlen;
212*aca3beaaSApple OSS Distributions }
213*aca3beaaSApple OSS Distributions
214*aca3beaaSApple OSS Distributions /* if option space low give up */
215*aca3beaaSApple OSS Distributions if ((MAX_TCPOPTLEN - optlen) < sizeof(struct mptcp_mpfail_opt)) {
216*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_SND_MPFAIL;
217*aca3beaaSApple OSS Distributions return optlen;
218*aca3beaaSApple OSS Distributions }
219*aca3beaaSApple OSS Distributions
220*aca3beaaSApple OSS Distributions dsn = mp_tp->mpt_rcvnxt;
221*aca3beaaSApple OSS Distributions
222*aca3beaaSApple OSS Distributions bzero(&fail_opt, sizeof(fail_opt));
223*aca3beaaSApple OSS Distributions fail_opt.mfail_kind = TCPOPT_MULTIPATH;
224*aca3beaaSApple OSS Distributions fail_opt.mfail_len = len;
225*aca3beaaSApple OSS Distributions fail_opt.mfail_subtype = MPO_FAIL;
226*aca3beaaSApple OSS Distributions fail_opt.mfail_dsn = mptcp_hton64(dsn);
227*aca3beaaSApple OSS Distributions memcpy(opt + optlen, &fail_opt, len);
228*aca3beaaSApple OSS Distributions optlen += len;
229*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_SND_MPFAIL;
230*aca3beaaSApple OSS Distributions return optlen;
231*aca3beaaSApple OSS Distributions }
232*aca3beaaSApple OSS Distributions
233*aca3beaaSApple OSS Distributions static int
mptcp_send_infinite_mapping(struct tcpcb * tp,u_char * opt,unsigned int optlen)234*aca3beaaSApple OSS Distributions mptcp_send_infinite_mapping(struct tcpcb *tp, u_char *opt, unsigned int optlen)
235*aca3beaaSApple OSS Distributions {
236*aca3beaaSApple OSS Distributions struct socket *so = tp->t_inpcb->inp_socket;
237*aca3beaaSApple OSS Distributions uint8_t len = sizeof(struct mptcp_dsn_opt);
238*aca3beaaSApple OSS Distributions struct mptcp_dsn_opt infin_opt;
239*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = NULL;
240*aca3beaaSApple OSS Distributions uint8_t csum_len = 0;
241*aca3beaaSApple OSS Distributions
242*aca3beaaSApple OSS Distributions if (!so) {
243*aca3beaaSApple OSS Distributions return optlen;
244*aca3beaaSApple OSS Distributions }
245*aca3beaaSApple OSS Distributions
246*aca3beaaSApple OSS Distributions mp_tp = tptomptp(tp);
247*aca3beaaSApple OSS Distributions if (mp_tp == NULL) {
248*aca3beaaSApple OSS Distributions return optlen;
249*aca3beaaSApple OSS Distributions }
250*aca3beaaSApple OSS Distributions
251*aca3beaaSApple OSS Distributions if (mp_tp->mpt_flags & MPTCPF_CHECKSUM) {
252*aca3beaaSApple OSS Distributions csum_len = 2;
253*aca3beaaSApple OSS Distributions }
254*aca3beaaSApple OSS Distributions
255*aca3beaaSApple OSS Distributions /* try later */
256*aca3beaaSApple OSS Distributions if ((MAX_TCPOPTLEN - optlen) < (len + csum_len)) {
257*aca3beaaSApple OSS Distributions return optlen;
258*aca3beaaSApple OSS Distributions }
259*aca3beaaSApple OSS Distributions
260*aca3beaaSApple OSS Distributions bzero(&infin_opt, sizeof(infin_opt));
261*aca3beaaSApple OSS Distributions infin_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
262*aca3beaaSApple OSS Distributions infin_opt.mdss_copt.mdss_len = len + csum_len;
263*aca3beaaSApple OSS Distributions infin_opt.mdss_copt.mdss_subtype = MPO_DSS;
264*aca3beaaSApple OSS Distributions infin_opt.mdss_copt.mdss_flags |= MDSS_M;
265*aca3beaaSApple OSS Distributions if (mp_tp->mpt_flags & MPTCPF_RECVD_MPFAIL) {
266*aca3beaaSApple OSS Distributions infin_opt.mdss_dsn = (u_int32_t)
267*aca3beaaSApple OSS Distributions MPTCP_DATASEQ_LOW32(mp_tp->mpt_dsn_at_csum_fail);
268*aca3beaaSApple OSS Distributions infin_opt.mdss_subflow_seqn = mp_tp->mpt_ssn_at_csum_fail;
269*aca3beaaSApple OSS Distributions } else {
270*aca3beaaSApple OSS Distributions /*
271*aca3beaaSApple OSS Distributions * If MPTCP fallback happens, but TFO succeeds, the data on the
272*aca3beaaSApple OSS Distributions * SYN does not belong to the MPTCP data sequence space.
273*aca3beaaSApple OSS Distributions */
274*aca3beaaSApple OSS Distributions if ((tp->t_tfo_stats & TFO_S_SYN_DATA_ACKED) &&
275*aca3beaaSApple OSS Distributions ((mp_tp->mpt_local_idsn + 1) == mp_tp->mpt_snduna)) {
276*aca3beaaSApple OSS Distributions infin_opt.mdss_subflow_seqn = 1;
277*aca3beaaSApple OSS Distributions } else {
278*aca3beaaSApple OSS Distributions infin_opt.mdss_subflow_seqn = tp->snd_una - tp->t_mpsub->mpts_iss;
279*aca3beaaSApple OSS Distributions }
280*aca3beaaSApple OSS Distributions infin_opt.mdss_dsn = (u_int32_t)
281*aca3beaaSApple OSS Distributions MPTCP_DATASEQ_LOW32(mp_tp->mpt_snduna);
282*aca3beaaSApple OSS Distributions }
283*aca3beaaSApple OSS Distributions
284*aca3beaaSApple OSS Distributions if ((infin_opt.mdss_dsn == 0) || (infin_opt.mdss_subflow_seqn == 0)) {
285*aca3beaaSApple OSS Distributions return optlen;
286*aca3beaaSApple OSS Distributions }
287*aca3beaaSApple OSS Distributions infin_opt.mdss_dsn = htonl(infin_opt.mdss_dsn);
288*aca3beaaSApple OSS Distributions infin_opt.mdss_subflow_seqn = htonl(infin_opt.mdss_subflow_seqn);
289*aca3beaaSApple OSS Distributions infin_opt.mdss_data_len = 0;
290*aca3beaaSApple OSS Distributions
291*aca3beaaSApple OSS Distributions memcpy(opt + optlen, &infin_opt, len);
292*aca3beaaSApple OSS Distributions optlen += len;
293*aca3beaaSApple OSS Distributions if (csum_len != 0) {
294*aca3beaaSApple OSS Distributions /* The checksum field is set to 0 for infinite mapping */
295*aca3beaaSApple OSS Distributions uint16_t csum = 0;
296*aca3beaaSApple OSS Distributions memcpy(opt + optlen, &csum, csum_len);
297*aca3beaaSApple OSS Distributions optlen += csum_len;
298*aca3beaaSApple OSS Distributions }
299*aca3beaaSApple OSS Distributions
300*aca3beaaSApple OSS Distributions tp->t_mpflags |= TMPF_INFIN_SENT;
301*aca3beaaSApple OSS Distributions tcpstat.tcps_estab_fallback++;
302*aca3beaaSApple OSS Distributions return optlen;
303*aca3beaaSApple OSS Distributions }
304*aca3beaaSApple OSS Distributions
305*aca3beaaSApple OSS Distributions
306*aca3beaaSApple OSS Distributions static int
mptcp_ok_to_fin(struct tcpcb * tp,u_int64_t dsn,u_int32_t datalen)307*aca3beaaSApple OSS Distributions mptcp_ok_to_fin(struct tcpcb *tp, u_int64_t dsn, u_int32_t datalen)
308*aca3beaaSApple OSS Distributions {
309*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
310*aca3beaaSApple OSS Distributions
311*aca3beaaSApple OSS Distributions dsn = (mp_tp->mpt_sndmax & MPTCP_DATASEQ_LOW32_MASK) | dsn;
312*aca3beaaSApple OSS Distributions if ((dsn + datalen) == mp_tp->mpt_sndmax) {
313*aca3beaaSApple OSS Distributions return 1;
314*aca3beaaSApple OSS Distributions }
315*aca3beaaSApple OSS Distributions
316*aca3beaaSApple OSS Distributions return 0;
317*aca3beaaSApple OSS Distributions }
318*aca3beaaSApple OSS Distributions
319*aca3beaaSApple OSS Distributions unsigned int
mptcp_setup_opts(struct tcpcb * tp,int32_t off,u_char * opt,unsigned int optlen,int flags,int len,boolean_t * p_mptcp_acknow,boolean_t * do_not_compress)320*aca3beaaSApple OSS Distributions mptcp_setup_opts(struct tcpcb *tp, int32_t off, u_char *opt,
321*aca3beaaSApple OSS Distributions unsigned int optlen, int flags, int len,
322*aca3beaaSApple OSS Distributions boolean_t *p_mptcp_acknow, boolean_t *do_not_compress)
323*aca3beaaSApple OSS Distributions {
324*aca3beaaSApple OSS Distributions struct inpcb *inp = (struct inpcb *)tp->t_inpcb;
325*aca3beaaSApple OSS Distributions struct socket *so = inp->inp_socket;
326*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
327*aca3beaaSApple OSS Distributions boolean_t do_csum = FALSE;
328*aca3beaaSApple OSS Distributions boolean_t send_64bit_dsn = FALSE;
329*aca3beaaSApple OSS Distributions boolean_t send_64bit_ack = FALSE;
330*aca3beaaSApple OSS Distributions u_int32_t old_mpt_flags = tp->t_mpflags & TMPF_MPTCP_SIGNALS;
331*aca3beaaSApple OSS Distributions boolean_t initial_data = FALSE;
332*aca3beaaSApple OSS Distributions
333*aca3beaaSApple OSS Distributions if (mptcp_enable == 0 || mp_tp == NULL || tp->t_state == TCPS_CLOSED) {
334*aca3beaaSApple OSS Distributions /* do nothing */
335*aca3beaaSApple OSS Distributions goto ret_optlen;
336*aca3beaaSApple OSS Distributions }
337*aca3beaaSApple OSS Distributions
338*aca3beaaSApple OSS Distributions socket_lock_assert_owned(mptetoso(mp_tp->mpt_mpte));
339*aca3beaaSApple OSS Distributions
340*aca3beaaSApple OSS Distributions if (mp_tp->mpt_flags & MPTCPF_CHECKSUM) {
341*aca3beaaSApple OSS Distributions do_csum = TRUE;
342*aca3beaaSApple OSS Distributions }
343*aca3beaaSApple OSS Distributions
344*aca3beaaSApple OSS Distributions /* tcp_output handles the SYN path separately */
345*aca3beaaSApple OSS Distributions if (flags & TH_SYN) {
346*aca3beaaSApple OSS Distributions goto ret_optlen;
347*aca3beaaSApple OSS Distributions }
348*aca3beaaSApple OSS Distributions
349*aca3beaaSApple OSS Distributions if ((MAX_TCPOPTLEN - optlen) <
350*aca3beaaSApple OSS Distributions sizeof(struct mptcp_mpcapable_opt_common)) {
351*aca3beaaSApple OSS Distributions os_log_error(mptcp_log_handle, "%s - %lx: no space left %d flags %x tp->t_mpflags %x len %d\n",
352*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mp_tp->mpt_mpte),
353*aca3beaaSApple OSS Distributions optlen, flags, tp->t_mpflags, len);
354*aca3beaaSApple OSS Distributions goto ret_optlen;
355*aca3beaaSApple OSS Distributions }
356*aca3beaaSApple OSS Distributions
357*aca3beaaSApple OSS Distributions if (tp->t_mpflags & TMPF_TCP_FALLBACK) {
358*aca3beaaSApple OSS Distributions if (tp->t_mpflags & TMPF_SND_MPFAIL) {
359*aca3beaaSApple OSS Distributions optlen = mptcp_send_mpfail(tp, opt, optlen);
360*aca3beaaSApple OSS Distributions } else if (!(tp->t_mpflags & TMPF_INFIN_SENT)) {
361*aca3beaaSApple OSS Distributions optlen = mptcp_send_infinite_mapping(tp, opt, optlen);
362*aca3beaaSApple OSS Distributions }
363*aca3beaaSApple OSS Distributions
364*aca3beaaSApple OSS Distributions *do_not_compress = TRUE;
365*aca3beaaSApple OSS Distributions
366*aca3beaaSApple OSS Distributions goto ret_optlen;
367*aca3beaaSApple OSS Distributions }
368*aca3beaaSApple OSS Distributions
369*aca3beaaSApple OSS Distributions if (len > 0 && off == 0 && tp->t_mpflags & TMPF_SEND_DSN && tp->t_mpflags & TMPF_SND_KEYS) {
370*aca3beaaSApple OSS Distributions uint64_t dsn = 0;
371*aca3beaaSApple OSS Distributions uint32_t relseq = 0;
372*aca3beaaSApple OSS Distributions uint16_t data_len = 0, dss_csum = 0;
373*aca3beaaSApple OSS Distributions mptcp_output_getm_dsnmap64(so, off, &dsn, &relseq, &data_len, &dss_csum);
374*aca3beaaSApple OSS Distributions if (dsn == mp_tp->mpt_local_idsn + 1) {
375*aca3beaaSApple OSS Distributions initial_data = TRUE;
376*aca3beaaSApple OSS Distributions }
377*aca3beaaSApple OSS Distributions }
378*aca3beaaSApple OSS Distributions
379*aca3beaaSApple OSS Distributions /* send MP_CAPABLE when it's the INITIAL ACK or data */
380*aca3beaaSApple OSS Distributions if (tp->t_mpflags & TMPF_SND_KEYS &&
381*aca3beaaSApple OSS Distributions (mp_tp->mpt_version == MPTCP_VERSION_0 || initial_data ||
382*aca3beaaSApple OSS Distributions (mp_tp->mpt_sndnxt == mp_tp->mpt_local_idsn + 1 && len == 0))) {
383*aca3beaaSApple OSS Distributions struct mptcp_mpcapable_opt_rsp2 mptcp_opt;
384*aca3beaaSApple OSS Distributions boolean_t send_data_level_details = tp->t_mpflags & TMPF_SEND_DSN ? TRUE : FALSE;
385*aca3beaaSApple OSS Distributions
386*aca3beaaSApple OSS Distributions uint8_t mmco_len = sizeof(struct mptcp_mpcapable_opt_rsp1);
387*aca3beaaSApple OSS Distributions if (send_data_level_details) {
388*aca3beaaSApple OSS Distributions mmco_len += 2;
389*aca3beaaSApple OSS Distributions if (do_csum) {
390*aca3beaaSApple OSS Distributions mmco_len += 2;
391*aca3beaaSApple OSS Distributions }
392*aca3beaaSApple OSS Distributions }
393*aca3beaaSApple OSS Distributions if ((MAX_TCPOPTLEN - optlen) < mmco_len) {
394*aca3beaaSApple OSS Distributions os_log_error(mptcp_log_handle, "%s - %lx: not enough space in TCP option, "
395*aca3beaaSApple OSS Distributions "optlen: %u, mmco_len: %d\n", __func__,
396*aca3beaaSApple OSS Distributions (unsigned long)VM_KERNEL_ADDRPERM(mp_tp->mpt_mpte),
397*aca3beaaSApple OSS Distributions optlen, mmco_len);
398*aca3beaaSApple OSS Distributions goto ret_optlen;
399*aca3beaaSApple OSS Distributions }
400*aca3beaaSApple OSS Distributions
401*aca3beaaSApple OSS Distributions bzero(&mptcp_opt, sizeof(struct mptcp_mpcapable_opt_rsp2));
402*aca3beaaSApple OSS Distributions mptcp_opt.mmc_rsp1.mmc_common.mmco_kind = TCPOPT_MULTIPATH;
403*aca3beaaSApple OSS Distributions mptcp_opt.mmc_rsp1.mmc_common.mmco_len = mmco_len;
404*aca3beaaSApple OSS Distributions mptcp_opt.mmc_rsp1.mmc_common.mmco_subtype = MPO_CAPABLE;
405*aca3beaaSApple OSS Distributions mptcp_opt.mmc_rsp1.mmc_common.mmco_version = mp_tp->mpt_version;
406*aca3beaaSApple OSS Distributions mptcp_opt.mmc_rsp1.mmc_common.mmco_flags |= MPCAP_PROPOSAL_SBIT;
407*aca3beaaSApple OSS Distributions if (do_csum) {
408*aca3beaaSApple OSS Distributions mptcp_opt.mmc_rsp1.mmc_common.mmco_flags |= MPCAP_CHECKSUM_CBIT;
409*aca3beaaSApple OSS Distributions }
410*aca3beaaSApple OSS Distributions mptcp_opt.mmc_rsp1.mmc_localkey = mp_tp->mpt_localkey;
411*aca3beaaSApple OSS Distributions mptcp_opt.mmc_rsp1.mmc_remotekey = mp_tp->mpt_remotekey;
412*aca3beaaSApple OSS Distributions if (send_data_level_details) {
413*aca3beaaSApple OSS Distributions mptcp_output_getm_data_level_details(so, off, &mptcp_opt.data_len, &mptcp_opt.csum);
414*aca3beaaSApple OSS Distributions mptcp_opt.data_len = htons(mptcp_opt.data_len);
415*aca3beaaSApple OSS Distributions }
416*aca3beaaSApple OSS Distributions memcpy(opt + optlen, &mptcp_opt, mmco_len);
417*aca3beaaSApple OSS Distributions
418*aca3beaaSApple OSS Distributions if (mp_tp->mpt_version == MPTCP_VERSION_0) {
419*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_SND_KEYS;
420*aca3beaaSApple OSS Distributions }
421*aca3beaaSApple OSS Distributions optlen += mmco_len;
422*aca3beaaSApple OSS Distributions
423*aca3beaaSApple OSS Distributions if (!tp->t_mpuna) {
424*aca3beaaSApple OSS Distributions tp->t_mpuna = tp->snd_una;
425*aca3beaaSApple OSS Distributions } else {
426*aca3beaaSApple OSS Distributions /* its a retransmission of the MP_CAPABLE ACK */
427*aca3beaaSApple OSS Distributions }
428*aca3beaaSApple OSS Distributions
429*aca3beaaSApple OSS Distributions *do_not_compress = TRUE;
430*aca3beaaSApple OSS Distributions
431*aca3beaaSApple OSS Distributions goto ret_optlen;
432*aca3beaaSApple OSS Distributions }
433*aca3beaaSApple OSS Distributions
434*aca3beaaSApple OSS Distributions if (tp->t_mpflags & TMPF_SND_JACK) {
435*aca3beaaSApple OSS Distributions *do_not_compress = TRUE;
436*aca3beaaSApple OSS Distributions optlen = mptcp_setup_join_ack_opts(tp, opt, optlen);
437*aca3beaaSApple OSS Distributions if (!tp->t_mpuna) {
438*aca3beaaSApple OSS Distributions tp->t_mpuna = tp->snd_una;
439*aca3beaaSApple OSS Distributions }
440*aca3beaaSApple OSS Distributions /* Start a timer to retransmit the ACK */
441*aca3beaaSApple OSS Distributions tp->t_timer[TCPT_JACK_RXMT] =
442*aca3beaaSApple OSS Distributions OFFSET_FROM_START(tp, tcp_jack_rxmt);
443*aca3beaaSApple OSS Distributions
444*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_SND_JACK;
445*aca3beaaSApple OSS Distributions goto ret_optlen;
446*aca3beaaSApple OSS Distributions }
447*aca3beaaSApple OSS Distributions
448*aca3beaaSApple OSS Distributions if (!(tp->t_mpflags & (TMPF_MPTCP_TRUE | TMPF_PREESTABLISHED))) {
449*aca3beaaSApple OSS Distributions goto ret_optlen;
450*aca3beaaSApple OSS Distributions }
451*aca3beaaSApple OSS Distributions /*
452*aca3beaaSApple OSS Distributions * From here on, all options are sent only if MPTCP_TRUE
453*aca3beaaSApple OSS Distributions * or when data is sent early on as in Fast Join
454*aca3beaaSApple OSS Distributions */
455*aca3beaaSApple OSS Distributions
456*aca3beaaSApple OSS Distributions if ((tp->t_mpflags & TMPF_MPTCP_TRUE) &&
457*aca3beaaSApple OSS Distributions (tp->t_mpflags & TMPF_SND_REM_ADDR)) {
458*aca3beaaSApple OSS Distributions int rem_opt_len = sizeof(struct mptcp_remaddr_opt);
459*aca3beaaSApple OSS Distributions if (optlen + rem_opt_len <= MAX_TCPOPTLEN) {
460*aca3beaaSApple OSS Distributions mptcp_send_remaddr_opt(tp,
461*aca3beaaSApple OSS Distributions (struct mptcp_remaddr_opt *)(opt + optlen));
462*aca3beaaSApple OSS Distributions optlen += rem_opt_len;
463*aca3beaaSApple OSS Distributions } else {
464*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_SND_REM_ADDR;
465*aca3beaaSApple OSS Distributions }
466*aca3beaaSApple OSS Distributions
467*aca3beaaSApple OSS Distributions *do_not_compress = TRUE;
468*aca3beaaSApple OSS Distributions }
469*aca3beaaSApple OSS Distributions
470*aca3beaaSApple OSS Distributions if (tp->t_mpflags & TMPF_MPTCP_ECHO_ADDR) {
471*aca3beaaSApple OSS Distributions optlen = mptcp_echo_add_addr(tp, opt, optlen);
472*aca3beaaSApple OSS Distributions }
473*aca3beaaSApple OSS Distributions
474*aca3beaaSApple OSS Distributions if (tp->t_mpflags & TMPF_SND_MPPRIO) {
475*aca3beaaSApple OSS Distributions optlen = mptcp_snd_mpprio(tp, opt, optlen);
476*aca3beaaSApple OSS Distributions
477*aca3beaaSApple OSS Distributions *do_not_compress = TRUE;
478*aca3beaaSApple OSS Distributions }
479*aca3beaaSApple OSS Distributions
480*aca3beaaSApple OSS Distributions if (mp_tp->mpt_flags & MPTCPF_SND_64BITDSN) {
481*aca3beaaSApple OSS Distributions send_64bit_dsn = TRUE;
482*aca3beaaSApple OSS Distributions }
483*aca3beaaSApple OSS Distributions if (mp_tp->mpt_flags & MPTCPF_SND_64BITACK) {
484*aca3beaaSApple OSS Distributions send_64bit_ack = TRUE;
485*aca3beaaSApple OSS Distributions }
486*aca3beaaSApple OSS Distributions
487*aca3beaaSApple OSS Distributions #define CHECK_OPTLEN { \
488*aca3beaaSApple OSS Distributions if (MAX_TCPOPTLEN - optlen < dssoptlen) { \
489*aca3beaaSApple OSS Distributions os_log_error(mptcp_log_handle, "%s: dssoptlen %d optlen %d \n", __func__, \
490*aca3beaaSApple OSS Distributions dssoptlen, optlen); \
491*aca3beaaSApple OSS Distributions goto ret_optlen; \
492*aca3beaaSApple OSS Distributions } \
493*aca3beaaSApple OSS Distributions }
494*aca3beaaSApple OSS Distributions
495*aca3beaaSApple OSS Distributions #define DO_FIN(dsn_opt) { \
496*aca3beaaSApple OSS Distributions int sndfin = 0; \
497*aca3beaaSApple OSS Distributions sndfin = mptcp_ok_to_fin(tp, dsn_opt.mdss_dsn, len); \
498*aca3beaaSApple OSS Distributions if (sndfin) { \
499*aca3beaaSApple OSS Distributions dsn_opt.mdss_copt.mdss_flags |= MDSS_F; \
500*aca3beaaSApple OSS Distributions dsn_opt.mdss_data_len += 1; \
501*aca3beaaSApple OSS Distributions if (do_csum) \
502*aca3beaaSApple OSS Distributions dss_csum = in_addword(dss_csum, 1); \
503*aca3beaaSApple OSS Distributions } \
504*aca3beaaSApple OSS Distributions }
505*aca3beaaSApple OSS Distributions
506*aca3beaaSApple OSS Distributions #define CHECK_DATALEN { \
507*aca3beaaSApple OSS Distributions /* MPTCP socket does not support IP options */ \
508*aca3beaaSApple OSS Distributions if ((len + optlen + dssoptlen) > tp->t_maxopd) { \
509*aca3beaaSApple OSS Distributions os_log_error(mptcp_log_handle, "%s: nosp %d len %d opt %d %d %d\n", \
510*aca3beaaSApple OSS Distributions __func__, len, dssoptlen, optlen, \
511*aca3beaaSApple OSS Distributions tp->t_maxseg, tp->t_maxopd); \
512*aca3beaaSApple OSS Distributions /* remove option length from payload len */ \
513*aca3beaaSApple OSS Distributions len = tp->t_maxopd - optlen - dssoptlen; \
514*aca3beaaSApple OSS Distributions } \
515*aca3beaaSApple OSS Distributions }
516*aca3beaaSApple OSS Distributions
517*aca3beaaSApple OSS Distributions if ((tp->t_mpflags & TMPF_SEND_DSN) &&
518*aca3beaaSApple OSS Distributions (send_64bit_dsn)) {
519*aca3beaaSApple OSS Distributions /*
520*aca3beaaSApple OSS Distributions * If there was the need to send 64-bit Data ACK along
521*aca3beaaSApple OSS Distributions * with 64-bit DSN, then 26 or 28 bytes would be used.
522*aca3beaaSApple OSS Distributions * With timestamps and NOOP padding that will cause
523*aca3beaaSApple OSS Distributions * overflow. Hence, in the rare event that both 64-bit
524*aca3beaaSApple OSS Distributions * DSN and 64-bit ACK have to be sent, delay the send of
525*aca3beaaSApple OSS Distributions * 64-bit ACK until our 64-bit DSN is acked with a 64-bit ack.
526*aca3beaaSApple OSS Distributions * XXX If this delay causes issue, remove the 2-byte padding.
527*aca3beaaSApple OSS Distributions */
528*aca3beaaSApple OSS Distributions struct mptcp_dss64_ack32_opt dsn_ack_opt;
529*aca3beaaSApple OSS Distributions uint8_t dssoptlen = sizeof(dsn_ack_opt);
530*aca3beaaSApple OSS Distributions uint16_t dss_csum;
531*aca3beaaSApple OSS Distributions
532*aca3beaaSApple OSS Distributions if (do_csum) {
533*aca3beaaSApple OSS Distributions dssoptlen += 2;
534*aca3beaaSApple OSS Distributions }
535*aca3beaaSApple OSS Distributions
536*aca3beaaSApple OSS Distributions CHECK_OPTLEN;
537*aca3beaaSApple OSS Distributions
538*aca3beaaSApple OSS Distributions bzero(&dsn_ack_opt, sizeof(dsn_ack_opt));
539*aca3beaaSApple OSS Distributions dsn_ack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
540*aca3beaaSApple OSS Distributions dsn_ack_opt.mdss_copt.mdss_subtype = MPO_DSS;
541*aca3beaaSApple OSS Distributions dsn_ack_opt.mdss_copt.mdss_len = dssoptlen;
542*aca3beaaSApple OSS Distributions dsn_ack_opt.mdss_copt.mdss_flags |=
543*aca3beaaSApple OSS Distributions MDSS_M | MDSS_m | MDSS_A;
544*aca3beaaSApple OSS Distributions
545*aca3beaaSApple OSS Distributions CHECK_DATALEN;
546*aca3beaaSApple OSS Distributions
547*aca3beaaSApple OSS Distributions mptcp_output_getm_dsnmap64(so, off,
548*aca3beaaSApple OSS Distributions &dsn_ack_opt.mdss_dsn,
549*aca3beaaSApple OSS Distributions &dsn_ack_opt.mdss_subflow_seqn,
550*aca3beaaSApple OSS Distributions &dsn_ack_opt.mdss_data_len,
551*aca3beaaSApple OSS Distributions &dss_csum);
552*aca3beaaSApple OSS Distributions
553*aca3beaaSApple OSS Distributions if ((dsn_ack_opt.mdss_data_len == 0) ||
554*aca3beaaSApple OSS Distributions (dsn_ack_opt.mdss_dsn == 0)) {
555*aca3beaaSApple OSS Distributions goto ret_optlen;
556*aca3beaaSApple OSS Distributions }
557*aca3beaaSApple OSS Distributions
558*aca3beaaSApple OSS Distributions if (tp->t_mpflags & TMPF_SEND_DFIN) {
559*aca3beaaSApple OSS Distributions DO_FIN(dsn_ack_opt);
560*aca3beaaSApple OSS Distributions }
561*aca3beaaSApple OSS Distributions
562*aca3beaaSApple OSS Distributions dsn_ack_opt.mdss_ack =
563*aca3beaaSApple OSS Distributions htonl(MPTCP_DATAACK_LOW32(mp_tp->mpt_rcvnxt));
564*aca3beaaSApple OSS Distributions
565*aca3beaaSApple OSS Distributions dsn_ack_opt.mdss_dsn = mptcp_hton64(dsn_ack_opt.mdss_dsn);
566*aca3beaaSApple OSS Distributions dsn_ack_opt.mdss_subflow_seqn = htonl(
567*aca3beaaSApple OSS Distributions dsn_ack_opt.mdss_subflow_seqn);
568*aca3beaaSApple OSS Distributions dsn_ack_opt.mdss_data_len = htons(
569*aca3beaaSApple OSS Distributions dsn_ack_opt.mdss_data_len);
570*aca3beaaSApple OSS Distributions
571*aca3beaaSApple OSS Distributions memcpy(opt + optlen, &dsn_ack_opt, sizeof(dsn_ack_opt));
572*aca3beaaSApple OSS Distributions if (do_csum) {
573*aca3beaaSApple OSS Distributions *((uint16_t *)(void *)(opt + optlen + sizeof(dsn_ack_opt))) = dss_csum;
574*aca3beaaSApple OSS Distributions }
575*aca3beaaSApple OSS Distributions
576*aca3beaaSApple OSS Distributions optlen += dssoptlen;
577*aca3beaaSApple OSS Distributions
578*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
579*aca3beaaSApple OSS Distributions
580*aca3beaaSApple OSS Distributions *do_not_compress = TRUE;
581*aca3beaaSApple OSS Distributions
582*aca3beaaSApple OSS Distributions goto ret_optlen;
583*aca3beaaSApple OSS Distributions }
584*aca3beaaSApple OSS Distributions
585*aca3beaaSApple OSS Distributions if ((tp->t_mpflags & TMPF_SEND_DSN) &&
586*aca3beaaSApple OSS Distributions (!send_64bit_dsn) &&
587*aca3beaaSApple OSS Distributions !(tp->t_mpflags & TMPF_MPTCP_ACKNOW)) {
588*aca3beaaSApple OSS Distributions struct mptcp_dsn_opt dsn_opt;
589*aca3beaaSApple OSS Distributions uint8_t dssoptlen = sizeof(struct mptcp_dsn_opt);
590*aca3beaaSApple OSS Distributions uint16_t dss_csum;
591*aca3beaaSApple OSS Distributions
592*aca3beaaSApple OSS Distributions if (do_csum) {
593*aca3beaaSApple OSS Distributions dssoptlen += 2;
594*aca3beaaSApple OSS Distributions }
595*aca3beaaSApple OSS Distributions
596*aca3beaaSApple OSS Distributions CHECK_OPTLEN;
597*aca3beaaSApple OSS Distributions
598*aca3beaaSApple OSS Distributions bzero(&dsn_opt, sizeof(dsn_opt));
599*aca3beaaSApple OSS Distributions dsn_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
600*aca3beaaSApple OSS Distributions dsn_opt.mdss_copt.mdss_subtype = MPO_DSS;
601*aca3beaaSApple OSS Distributions dsn_opt.mdss_copt.mdss_len = dssoptlen;
602*aca3beaaSApple OSS Distributions dsn_opt.mdss_copt.mdss_flags |= MDSS_M;
603*aca3beaaSApple OSS Distributions
604*aca3beaaSApple OSS Distributions CHECK_DATALEN;
605*aca3beaaSApple OSS Distributions
606*aca3beaaSApple OSS Distributions mptcp_output_getm_dsnmap32(so, off, &dsn_opt.mdss_dsn,
607*aca3beaaSApple OSS Distributions &dsn_opt.mdss_subflow_seqn,
608*aca3beaaSApple OSS Distributions &dsn_opt.mdss_data_len,
609*aca3beaaSApple OSS Distributions &dss_csum);
610*aca3beaaSApple OSS Distributions
611*aca3beaaSApple OSS Distributions if ((dsn_opt.mdss_data_len == 0) ||
612*aca3beaaSApple OSS Distributions (dsn_opt.mdss_dsn == 0)) {
613*aca3beaaSApple OSS Distributions goto ret_optlen;
614*aca3beaaSApple OSS Distributions }
615*aca3beaaSApple OSS Distributions
616*aca3beaaSApple OSS Distributions if (tp->t_mpflags & TMPF_SEND_DFIN) {
617*aca3beaaSApple OSS Distributions DO_FIN(dsn_opt);
618*aca3beaaSApple OSS Distributions }
619*aca3beaaSApple OSS Distributions
620*aca3beaaSApple OSS Distributions dsn_opt.mdss_dsn = htonl(dsn_opt.mdss_dsn);
621*aca3beaaSApple OSS Distributions dsn_opt.mdss_subflow_seqn = htonl(dsn_opt.mdss_subflow_seqn);
622*aca3beaaSApple OSS Distributions dsn_opt.mdss_data_len = htons(dsn_opt.mdss_data_len);
623*aca3beaaSApple OSS Distributions memcpy(opt + optlen, &dsn_opt, sizeof(dsn_opt));
624*aca3beaaSApple OSS Distributions if (do_csum) {
625*aca3beaaSApple OSS Distributions *((uint16_t *)(void *)(opt + optlen + sizeof(dsn_opt))) = dss_csum;
626*aca3beaaSApple OSS Distributions }
627*aca3beaaSApple OSS Distributions
628*aca3beaaSApple OSS Distributions optlen += dssoptlen;
629*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
630*aca3beaaSApple OSS Distributions
631*aca3beaaSApple OSS Distributions *do_not_compress = TRUE;
632*aca3beaaSApple OSS Distributions
633*aca3beaaSApple OSS Distributions goto ret_optlen;
634*aca3beaaSApple OSS Distributions }
635*aca3beaaSApple OSS Distributions
636*aca3beaaSApple OSS Distributions /* 32-bit Data ACK option */
637*aca3beaaSApple OSS Distributions if ((tp->t_mpflags & TMPF_MPTCP_ACKNOW) &&
638*aca3beaaSApple OSS Distributions (!send_64bit_ack) &&
639*aca3beaaSApple OSS Distributions !(tp->t_mpflags & TMPF_SEND_DSN) &&
640*aca3beaaSApple OSS Distributions !(tp->t_mpflags & TMPF_SEND_DFIN)) {
641*aca3beaaSApple OSS Distributions struct mptcp_data_ack_opt dack_opt;
642*aca3beaaSApple OSS Distributions uint8_t dssoptlen = 0;
643*aca3beaaSApple OSS Distributions do_ack32_only:
644*aca3beaaSApple OSS Distributions dssoptlen = sizeof(dack_opt);
645*aca3beaaSApple OSS Distributions
646*aca3beaaSApple OSS Distributions CHECK_OPTLEN;
647*aca3beaaSApple OSS Distributions
648*aca3beaaSApple OSS Distributions bzero(&dack_opt, dssoptlen);
649*aca3beaaSApple OSS Distributions dack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
650*aca3beaaSApple OSS Distributions dack_opt.mdss_copt.mdss_len = dssoptlen;
651*aca3beaaSApple OSS Distributions dack_opt.mdss_copt.mdss_subtype = MPO_DSS;
652*aca3beaaSApple OSS Distributions dack_opt.mdss_copt.mdss_flags |= MDSS_A;
653*aca3beaaSApple OSS Distributions dack_opt.mdss_ack =
654*aca3beaaSApple OSS Distributions htonl(MPTCP_DATAACK_LOW32(mp_tp->mpt_rcvnxt));
655*aca3beaaSApple OSS Distributions memcpy(opt + optlen, &dack_opt, dssoptlen);
656*aca3beaaSApple OSS Distributions optlen += dssoptlen;
657*aca3beaaSApple OSS Distributions VERIFY(optlen <= MAX_TCPOPTLEN);
658*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
659*aca3beaaSApple OSS Distributions goto ret_optlen;
660*aca3beaaSApple OSS Distributions }
661*aca3beaaSApple OSS Distributions
662*aca3beaaSApple OSS Distributions /* 64-bit Data ACK option */
663*aca3beaaSApple OSS Distributions if ((tp->t_mpflags & TMPF_MPTCP_ACKNOW) &&
664*aca3beaaSApple OSS Distributions (send_64bit_ack) &&
665*aca3beaaSApple OSS Distributions !(tp->t_mpflags & TMPF_SEND_DSN) &&
666*aca3beaaSApple OSS Distributions !(tp->t_mpflags & TMPF_SEND_DFIN)) {
667*aca3beaaSApple OSS Distributions struct mptcp_data_ack64_opt dack_opt;
668*aca3beaaSApple OSS Distributions uint8_t dssoptlen = 0;
669*aca3beaaSApple OSS Distributions do_ack64_only:
670*aca3beaaSApple OSS Distributions dssoptlen = sizeof(dack_opt);
671*aca3beaaSApple OSS Distributions
672*aca3beaaSApple OSS Distributions CHECK_OPTLEN;
673*aca3beaaSApple OSS Distributions
674*aca3beaaSApple OSS Distributions bzero(&dack_opt, dssoptlen);
675*aca3beaaSApple OSS Distributions dack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
676*aca3beaaSApple OSS Distributions dack_opt.mdss_copt.mdss_len = dssoptlen;
677*aca3beaaSApple OSS Distributions dack_opt.mdss_copt.mdss_subtype = MPO_DSS;
678*aca3beaaSApple OSS Distributions dack_opt.mdss_copt.mdss_flags |= (MDSS_A | MDSS_a);
679*aca3beaaSApple OSS Distributions dack_opt.mdss_ack = mptcp_hton64(mp_tp->mpt_rcvnxt);
680*aca3beaaSApple OSS Distributions /*
681*aca3beaaSApple OSS Distributions * The other end should retransmit 64-bit DSN until it
682*aca3beaaSApple OSS Distributions * receives a 64-bit ACK.
683*aca3beaaSApple OSS Distributions */
684*aca3beaaSApple OSS Distributions mp_tp->mpt_flags &= ~MPTCPF_SND_64BITACK;
685*aca3beaaSApple OSS Distributions memcpy(opt + optlen, &dack_opt, dssoptlen);
686*aca3beaaSApple OSS Distributions optlen += dssoptlen;
687*aca3beaaSApple OSS Distributions VERIFY(optlen <= MAX_TCPOPTLEN);
688*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
689*aca3beaaSApple OSS Distributions goto ret_optlen;
690*aca3beaaSApple OSS Distributions }
691*aca3beaaSApple OSS Distributions
692*aca3beaaSApple OSS Distributions /* 32-bit DSS+Data ACK option */
693*aca3beaaSApple OSS Distributions if ((tp->t_mpflags & TMPF_SEND_DSN) &&
694*aca3beaaSApple OSS Distributions (!send_64bit_dsn) &&
695*aca3beaaSApple OSS Distributions (!send_64bit_ack) &&
696*aca3beaaSApple OSS Distributions (tp->t_mpflags & TMPF_MPTCP_ACKNOW)) {
697*aca3beaaSApple OSS Distributions struct mptcp_dss_ack_opt dss_ack_opt;
698*aca3beaaSApple OSS Distributions uint8_t dssoptlen = sizeof(dss_ack_opt);
699*aca3beaaSApple OSS Distributions uint16_t dss_csum;
700*aca3beaaSApple OSS Distributions
701*aca3beaaSApple OSS Distributions if (do_csum) {
702*aca3beaaSApple OSS Distributions dssoptlen += 2;
703*aca3beaaSApple OSS Distributions }
704*aca3beaaSApple OSS Distributions
705*aca3beaaSApple OSS Distributions CHECK_OPTLEN;
706*aca3beaaSApple OSS Distributions
707*aca3beaaSApple OSS Distributions bzero(&dss_ack_opt, sizeof(dss_ack_opt));
708*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
709*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_copt.mdss_len = dssoptlen;
710*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_copt.mdss_subtype = MPO_DSS;
711*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_copt.mdss_flags |= MDSS_A | MDSS_M;
712*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_ack =
713*aca3beaaSApple OSS Distributions htonl(MPTCP_DATAACK_LOW32(mp_tp->mpt_rcvnxt));
714*aca3beaaSApple OSS Distributions
715*aca3beaaSApple OSS Distributions CHECK_DATALEN;
716*aca3beaaSApple OSS Distributions
717*aca3beaaSApple OSS Distributions mptcp_output_getm_dsnmap32(so, off, &dss_ack_opt.mdss_dsn,
718*aca3beaaSApple OSS Distributions &dss_ack_opt.mdss_subflow_seqn,
719*aca3beaaSApple OSS Distributions &dss_ack_opt.mdss_data_len,
720*aca3beaaSApple OSS Distributions &dss_csum);
721*aca3beaaSApple OSS Distributions
722*aca3beaaSApple OSS Distributions if ((dss_ack_opt.mdss_data_len == 0) ||
723*aca3beaaSApple OSS Distributions (dss_ack_opt.mdss_dsn == 0)) {
724*aca3beaaSApple OSS Distributions goto do_ack32_only;
725*aca3beaaSApple OSS Distributions }
726*aca3beaaSApple OSS Distributions
727*aca3beaaSApple OSS Distributions if (tp->t_mpflags & TMPF_SEND_DFIN) {
728*aca3beaaSApple OSS Distributions DO_FIN(dss_ack_opt);
729*aca3beaaSApple OSS Distributions }
730*aca3beaaSApple OSS Distributions
731*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_dsn = htonl(dss_ack_opt.mdss_dsn);
732*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_subflow_seqn =
733*aca3beaaSApple OSS Distributions htonl(dss_ack_opt.mdss_subflow_seqn);
734*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_data_len = htons(dss_ack_opt.mdss_data_len);
735*aca3beaaSApple OSS Distributions memcpy(opt + optlen, &dss_ack_opt, sizeof(dss_ack_opt));
736*aca3beaaSApple OSS Distributions if (do_csum) {
737*aca3beaaSApple OSS Distributions *((uint16_t *)(void *)(opt + optlen + sizeof(dss_ack_opt))) = dss_csum;
738*aca3beaaSApple OSS Distributions }
739*aca3beaaSApple OSS Distributions
740*aca3beaaSApple OSS Distributions optlen += dssoptlen;
741*aca3beaaSApple OSS Distributions
742*aca3beaaSApple OSS Distributions if (optlen > MAX_TCPOPTLEN) {
743*aca3beaaSApple OSS Distributions panic("optlen too large");
744*aca3beaaSApple OSS Distributions }
745*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
746*aca3beaaSApple OSS Distributions goto ret_optlen;
747*aca3beaaSApple OSS Distributions }
748*aca3beaaSApple OSS Distributions
749*aca3beaaSApple OSS Distributions /* 32-bit DSS + 64-bit DACK option */
750*aca3beaaSApple OSS Distributions if ((tp->t_mpflags & TMPF_SEND_DSN) &&
751*aca3beaaSApple OSS Distributions (!send_64bit_dsn) &&
752*aca3beaaSApple OSS Distributions (send_64bit_ack) &&
753*aca3beaaSApple OSS Distributions (tp->t_mpflags & TMPF_MPTCP_ACKNOW)) {
754*aca3beaaSApple OSS Distributions struct mptcp_dss32_ack64_opt dss_ack_opt;
755*aca3beaaSApple OSS Distributions uint8_t dssoptlen = sizeof(dss_ack_opt);
756*aca3beaaSApple OSS Distributions uint16_t dss_csum;
757*aca3beaaSApple OSS Distributions
758*aca3beaaSApple OSS Distributions if (do_csum) {
759*aca3beaaSApple OSS Distributions dssoptlen += 2;
760*aca3beaaSApple OSS Distributions }
761*aca3beaaSApple OSS Distributions
762*aca3beaaSApple OSS Distributions CHECK_OPTLEN;
763*aca3beaaSApple OSS Distributions
764*aca3beaaSApple OSS Distributions bzero(&dss_ack_opt, sizeof(dss_ack_opt));
765*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
766*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_copt.mdss_len = dssoptlen;
767*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_copt.mdss_subtype = MPO_DSS;
768*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_copt.mdss_flags |= MDSS_M | MDSS_A | MDSS_a;
769*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_ack =
770*aca3beaaSApple OSS Distributions mptcp_hton64(mp_tp->mpt_rcvnxt);
771*aca3beaaSApple OSS Distributions
772*aca3beaaSApple OSS Distributions CHECK_DATALEN;
773*aca3beaaSApple OSS Distributions
774*aca3beaaSApple OSS Distributions mptcp_output_getm_dsnmap32(so, off, &dss_ack_opt.mdss_dsn,
775*aca3beaaSApple OSS Distributions &dss_ack_opt.mdss_subflow_seqn,
776*aca3beaaSApple OSS Distributions &dss_ack_opt.mdss_data_len,
777*aca3beaaSApple OSS Distributions &dss_csum);
778*aca3beaaSApple OSS Distributions
779*aca3beaaSApple OSS Distributions if ((dss_ack_opt.mdss_data_len == 0) ||
780*aca3beaaSApple OSS Distributions (dss_ack_opt.mdss_dsn == 0)) {
781*aca3beaaSApple OSS Distributions goto do_ack64_only;
782*aca3beaaSApple OSS Distributions }
783*aca3beaaSApple OSS Distributions
784*aca3beaaSApple OSS Distributions if (tp->t_mpflags & TMPF_SEND_DFIN) {
785*aca3beaaSApple OSS Distributions DO_FIN(dss_ack_opt);
786*aca3beaaSApple OSS Distributions }
787*aca3beaaSApple OSS Distributions
788*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_dsn = htonl(dss_ack_opt.mdss_dsn);
789*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_subflow_seqn =
790*aca3beaaSApple OSS Distributions htonl(dss_ack_opt.mdss_subflow_seqn);
791*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_data_len = htons(dss_ack_opt.mdss_data_len);
792*aca3beaaSApple OSS Distributions memcpy(opt + optlen, &dss_ack_opt, sizeof(dss_ack_opt));
793*aca3beaaSApple OSS Distributions if (do_csum) {
794*aca3beaaSApple OSS Distributions *((uint16_t *)(void *)(opt + optlen + sizeof(dss_ack_opt))) = dss_csum;
795*aca3beaaSApple OSS Distributions }
796*aca3beaaSApple OSS Distributions
797*aca3beaaSApple OSS Distributions optlen += dssoptlen;
798*aca3beaaSApple OSS Distributions
799*aca3beaaSApple OSS Distributions if (optlen > MAX_TCPOPTLEN) {
800*aca3beaaSApple OSS Distributions panic("optlen too large");
801*aca3beaaSApple OSS Distributions }
802*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
803*aca3beaaSApple OSS Distributions
804*aca3beaaSApple OSS Distributions *do_not_compress = TRUE;
805*aca3beaaSApple OSS Distributions
806*aca3beaaSApple OSS Distributions goto ret_optlen;
807*aca3beaaSApple OSS Distributions }
808*aca3beaaSApple OSS Distributions
809*aca3beaaSApple OSS Distributions if (tp->t_mpflags & TMPF_SEND_DFIN) {
810*aca3beaaSApple OSS Distributions uint8_t dssoptlen = sizeof(struct mptcp_dss_ack_opt);
811*aca3beaaSApple OSS Distributions struct mptcp_dss_ack_opt dss_ack_opt;
812*aca3beaaSApple OSS Distributions uint16_t dss_csum;
813*aca3beaaSApple OSS Distributions
814*aca3beaaSApple OSS Distributions if (do_csum) {
815*aca3beaaSApple OSS Distributions uint64_t dss_val = mptcp_hton64(mp_tp->mpt_sndmax - 1);
816*aca3beaaSApple OSS Distributions uint16_t dlen = htons(1);
817*aca3beaaSApple OSS Distributions uint32_t sseq = 0;
818*aca3beaaSApple OSS Distributions uint32_t sum;
819*aca3beaaSApple OSS Distributions
820*aca3beaaSApple OSS Distributions
821*aca3beaaSApple OSS Distributions dssoptlen += 2;
822*aca3beaaSApple OSS Distributions
823*aca3beaaSApple OSS Distributions sum = in_pseudo64(dss_val, sseq, dlen);
824*aca3beaaSApple OSS Distributions ADDCARRY(sum);
825*aca3beaaSApple OSS Distributions dss_csum = ~sum & 0xffff;
826*aca3beaaSApple OSS Distributions }
827*aca3beaaSApple OSS Distributions
828*aca3beaaSApple OSS Distributions CHECK_OPTLEN;
829*aca3beaaSApple OSS Distributions
830*aca3beaaSApple OSS Distributions bzero(&dss_ack_opt, sizeof(dss_ack_opt));
831*aca3beaaSApple OSS Distributions
832*aca3beaaSApple OSS Distributions /*
833*aca3beaaSApple OSS Distributions * Data FIN occupies one sequence space.
834*aca3beaaSApple OSS Distributions * Don't send it if it has been Acked.
835*aca3beaaSApple OSS Distributions */
836*aca3beaaSApple OSS Distributions if ((mp_tp->mpt_sndnxt + 1 != mp_tp->mpt_sndmax) ||
837*aca3beaaSApple OSS Distributions (mp_tp->mpt_snduna == mp_tp->mpt_sndmax)) {
838*aca3beaaSApple OSS Distributions goto ret_optlen;
839*aca3beaaSApple OSS Distributions }
840*aca3beaaSApple OSS Distributions
841*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
842*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_copt.mdss_len = dssoptlen;
843*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_copt.mdss_subtype = MPO_DSS;
844*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_copt.mdss_flags |= MDSS_A | MDSS_M | MDSS_F;
845*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_ack =
846*aca3beaaSApple OSS Distributions htonl(MPTCP_DATAACK_LOW32(mp_tp->mpt_rcvnxt));
847*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_dsn =
848*aca3beaaSApple OSS Distributions htonl(MPTCP_DATASEQ_LOW32(mp_tp->mpt_sndmax - 1));
849*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_subflow_seqn = 0;
850*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_data_len = 1;
851*aca3beaaSApple OSS Distributions dss_ack_opt.mdss_data_len = htons(dss_ack_opt.mdss_data_len);
852*aca3beaaSApple OSS Distributions memcpy(opt + optlen, &dss_ack_opt, sizeof(dss_ack_opt));
853*aca3beaaSApple OSS Distributions if (do_csum) {
854*aca3beaaSApple OSS Distributions *((uint16_t *)(void *)(opt + optlen + sizeof(dss_ack_opt))) = dss_csum;
855*aca3beaaSApple OSS Distributions }
856*aca3beaaSApple OSS Distributions
857*aca3beaaSApple OSS Distributions optlen += dssoptlen;
858*aca3beaaSApple OSS Distributions
859*aca3beaaSApple OSS Distributions *do_not_compress = TRUE;
860*aca3beaaSApple OSS Distributions }
861*aca3beaaSApple OSS Distributions
862*aca3beaaSApple OSS Distributions ret_optlen:
863*aca3beaaSApple OSS Distributions if (TRUE == *p_mptcp_acknow) {
864*aca3beaaSApple OSS Distributions u_int32_t new_mpt_flags = tp->t_mpflags & TMPF_MPTCP_SIGNALS;
865*aca3beaaSApple OSS Distributions
866*aca3beaaSApple OSS Distributions /*
867*aca3beaaSApple OSS Distributions * If none of the above mpflags were acted on by
868*aca3beaaSApple OSS Distributions * this routine, reset these flags and set p_mptcp_acknow
869*aca3beaaSApple OSS Distributions * to false.
870*aca3beaaSApple OSS Distributions *
871*aca3beaaSApple OSS Distributions * XXX The reset value of p_mptcp_acknow can be used
872*aca3beaaSApple OSS Distributions * to communicate tcp_output to NOT send a pure ack without any
873*aca3beaaSApple OSS Distributions * MPTCP options as it will be treated as a dup ack.
874*aca3beaaSApple OSS Distributions * Since the instances of mptcp_setup_opts not acting on
875*aca3beaaSApple OSS Distributions * these options are mostly corner cases and sending a dup
876*aca3beaaSApple OSS Distributions * ack here would only have an impact if the system
877*aca3beaaSApple OSS Distributions * has sent consecutive dup acks before this false one,
878*aca3beaaSApple OSS Distributions * we haven't modified the logic in tcp_output to avoid
879*aca3beaaSApple OSS Distributions * that.
880*aca3beaaSApple OSS Distributions */
881*aca3beaaSApple OSS Distributions if (old_mpt_flags == new_mpt_flags) {
882*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_MPTCP_SIGNALS;
883*aca3beaaSApple OSS Distributions *p_mptcp_acknow = FALSE;
884*aca3beaaSApple OSS Distributions }
885*aca3beaaSApple OSS Distributions }
886*aca3beaaSApple OSS Distributions
887*aca3beaaSApple OSS Distributions return optlen;
888*aca3beaaSApple OSS Distributions }
889*aca3beaaSApple OSS Distributions
890*aca3beaaSApple OSS Distributions /*
891*aca3beaaSApple OSS Distributions * MPTCP Options Input Processing
892*aca3beaaSApple OSS Distributions */
893*aca3beaaSApple OSS Distributions
894*aca3beaaSApple OSS Distributions static int
mptcp_sanitize_option(struct tcpcb * tp,int mptcp_subtype)895*aca3beaaSApple OSS Distributions mptcp_sanitize_option(struct tcpcb *tp, int mptcp_subtype)
896*aca3beaaSApple OSS Distributions {
897*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
898*aca3beaaSApple OSS Distributions int ret = 1;
899*aca3beaaSApple OSS Distributions
900*aca3beaaSApple OSS Distributions switch (mptcp_subtype) {
901*aca3beaaSApple OSS Distributions case MPO_CAPABLE:
902*aca3beaaSApple OSS Distributions break;
903*aca3beaaSApple OSS Distributions case MPO_JOIN: /* fall through */
904*aca3beaaSApple OSS Distributions case MPO_DSS: /* fall through */
905*aca3beaaSApple OSS Distributions case MPO_FASTCLOSE: /* fall through */
906*aca3beaaSApple OSS Distributions case MPO_FAIL: /* fall through */
907*aca3beaaSApple OSS Distributions case MPO_REMOVE_ADDR: /* fall through */
908*aca3beaaSApple OSS Distributions case MPO_ADD_ADDR: /* fall through */
909*aca3beaaSApple OSS Distributions case MPO_PRIO: /* fall through */
910*aca3beaaSApple OSS Distributions if (mp_tp->mpt_state < MPTCPS_ESTABLISHED) {
911*aca3beaaSApple OSS Distributions ret = 0;
912*aca3beaaSApple OSS Distributions }
913*aca3beaaSApple OSS Distributions break;
914*aca3beaaSApple OSS Distributions default:
915*aca3beaaSApple OSS Distributions ret = 0;
916*aca3beaaSApple OSS Distributions os_log_error(mptcp_log_handle, "%s - %lx: type = %d \n", __func__,
917*aca3beaaSApple OSS Distributions (unsigned long)VM_KERNEL_ADDRPERM(mp_tp->mpt_mpte), mptcp_subtype);
918*aca3beaaSApple OSS Distributions break;
919*aca3beaaSApple OSS Distributions }
920*aca3beaaSApple OSS Distributions return ret;
921*aca3beaaSApple OSS Distributions }
922*aca3beaaSApple OSS Distributions
923*aca3beaaSApple OSS Distributions static int
mptcp_valid_mpcapable_common_opt(u_char * cp)924*aca3beaaSApple OSS Distributions mptcp_valid_mpcapable_common_opt(u_char *cp)
925*aca3beaaSApple OSS Distributions {
926*aca3beaaSApple OSS Distributions struct mptcp_mpcapable_opt_common *rsp =
927*aca3beaaSApple OSS Distributions (struct mptcp_mpcapable_opt_common *)cp;
928*aca3beaaSApple OSS Distributions
929*aca3beaaSApple OSS Distributions /* mmco_kind, mmco_len and mmco_subtype are validated before */
930*aca3beaaSApple OSS Distributions
931*aca3beaaSApple OSS Distributions if (!(rsp->mmco_flags & MPCAP_PROPOSAL_SBIT)) {
932*aca3beaaSApple OSS Distributions return 0;
933*aca3beaaSApple OSS Distributions }
934*aca3beaaSApple OSS Distributions
935*aca3beaaSApple OSS Distributions if (rsp->mmco_flags & (MPCAP_BBIT | MPCAP_DBIT |
936*aca3beaaSApple OSS Distributions MPCAP_EBIT | MPCAP_FBIT | MPCAP_GBIT)) {
937*aca3beaaSApple OSS Distributions return 0;
938*aca3beaaSApple OSS Distributions }
939*aca3beaaSApple OSS Distributions
940*aca3beaaSApple OSS Distributions return 1;
941*aca3beaaSApple OSS Distributions }
942*aca3beaaSApple OSS Distributions
943*aca3beaaSApple OSS Distributions
944*aca3beaaSApple OSS Distributions static void
mptcp_do_mpcapable_opt(struct tcpcb * tp,u_char * cp,struct tcphdr * th,uint8_t optlen)945*aca3beaaSApple OSS Distributions mptcp_do_mpcapable_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th,
946*aca3beaaSApple OSS Distributions uint8_t optlen)
947*aca3beaaSApple OSS Distributions {
948*aca3beaaSApple OSS Distributions struct mptcp_mpcapable_opt_rsp *rsp = NULL;
949*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
950*aca3beaaSApple OSS Distributions struct mptses *mpte = mp_tp->mpt_mpte;
951*aca3beaaSApple OSS Distributions
952*aca3beaaSApple OSS Distributions /* Only valid on SYN/ACK */
953*aca3beaaSApple OSS Distributions if ((th->th_flags & (TH_SYN | TH_ACK)) != (TH_SYN | TH_ACK)) {
954*aca3beaaSApple OSS Distributions return;
955*aca3beaaSApple OSS Distributions }
956*aca3beaaSApple OSS Distributions
957*aca3beaaSApple OSS Distributions /* Validate the kind, len, flags */
958*aca3beaaSApple OSS Distributions if (mptcp_valid_mpcapable_common_opt(cp) != 1) {
959*aca3beaaSApple OSS Distributions tcpstat.tcps_invalid_mpcap++;
960*aca3beaaSApple OSS Distributions return;
961*aca3beaaSApple OSS Distributions }
962*aca3beaaSApple OSS Distributions
963*aca3beaaSApple OSS Distributions /* handle SYN/ACK retransmission by acknowledging with ACK */
964*aca3beaaSApple OSS Distributions if (mp_tp->mpt_state >= MPTCPS_ESTABLISHED) {
965*aca3beaaSApple OSS Distributions return;
966*aca3beaaSApple OSS Distributions }
967*aca3beaaSApple OSS Distributions
968*aca3beaaSApple OSS Distributions /* A SYN/ACK contains peer's key and flags */
969*aca3beaaSApple OSS Distributions if (optlen != sizeof(struct mptcp_mpcapable_opt_rsp)) {
970*aca3beaaSApple OSS Distributions /* complain */
971*aca3beaaSApple OSS Distributions os_log_error(mptcp_log_handle, "%s - %lx: SYN_ACK optlen = %u, sizeof mp opt = %lu \n",
972*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte), optlen,
973*aca3beaaSApple OSS Distributions sizeof(struct mptcp_mpcapable_opt_rsp));
974*aca3beaaSApple OSS Distributions tcpstat.tcps_invalid_mpcap++;
975*aca3beaaSApple OSS Distributions return;
976*aca3beaaSApple OSS Distributions }
977*aca3beaaSApple OSS Distributions
978*aca3beaaSApple OSS Distributions /*
979*aca3beaaSApple OSS Distributions * If checksum flag is set, enable MPTCP checksum, even if
980*aca3beaaSApple OSS Distributions * it was not negotiated on the first SYN.
981*aca3beaaSApple OSS Distributions */
982*aca3beaaSApple OSS Distributions if (((struct mptcp_mpcapable_opt_common *)cp)->mmco_flags &
983*aca3beaaSApple OSS Distributions MPCAP_CHECKSUM_CBIT) {
984*aca3beaaSApple OSS Distributions mp_tp->mpt_flags |= MPTCPF_CHECKSUM;
985*aca3beaaSApple OSS Distributions }
986*aca3beaaSApple OSS Distributions
987*aca3beaaSApple OSS Distributions if (((struct mptcp_mpcapable_opt_common *)cp)->mmco_flags &
988*aca3beaaSApple OSS Distributions MPCAP_UNICAST_IPBIT) {
989*aca3beaaSApple OSS Distributions mpte->mpte_flags |= MPTE_UNICAST_IP;
990*aca3beaaSApple OSS Distributions
991*aca3beaaSApple OSS Distributions /* We need an explicit signal for the addresses - zero the existing ones */
992*aca3beaaSApple OSS Distributions memset(&mpte->mpte_sub_dst_v4, 0, sizeof(mpte->mpte_sub_dst_v4));
993*aca3beaaSApple OSS Distributions memset(&mpte->mpte_sub_dst_v6, 0, sizeof(mpte->mpte_sub_dst_v6));
994*aca3beaaSApple OSS Distributions }
995*aca3beaaSApple OSS Distributions
996*aca3beaaSApple OSS Distributions rsp = (struct mptcp_mpcapable_opt_rsp *)cp;
997*aca3beaaSApple OSS Distributions mp_tp->mpt_remotekey = rsp->mmc_localkey;
998*aca3beaaSApple OSS Distributions /* For now just downgrade to the peer's version */
999*aca3beaaSApple OSS Distributions if (rsp->mmc_common.mmco_version < mp_tp->mpt_version) {
1000*aca3beaaSApple OSS Distributions os_log_error(mptcp_log_handle, "local version: %d > peer version %d", mp_tp->mpt_version, rsp->mmc_common.mmco_version);
1001*aca3beaaSApple OSS Distributions mp_tp->mpt_version = rsp->mmc_common.mmco_version;
1002*aca3beaaSApple OSS Distributions tcpstat.tcps_mp_verdowngrade++;
1003*aca3beaaSApple OSS Distributions return;
1004*aca3beaaSApple OSS Distributions }
1005*aca3beaaSApple OSS Distributions if (mptcp_init_remote_parms(mp_tp) != 0) {
1006*aca3beaaSApple OSS Distributions tcpstat.tcps_invalid_mpcap++;
1007*aca3beaaSApple OSS Distributions return;
1008*aca3beaaSApple OSS Distributions }
1009*aca3beaaSApple OSS Distributions tcp_heuristic_mptcp_success(tp);
1010*aca3beaaSApple OSS Distributions tcp_cache_update_mptcp_version(tp, TRUE);
1011*aca3beaaSApple OSS Distributions tp->t_mpflags |= (TMPF_SND_KEYS | TMPF_MPTCP_TRUE);
1012*aca3beaaSApple OSS Distributions }
1013*aca3beaaSApple OSS Distributions
1014*aca3beaaSApple OSS Distributions
1015*aca3beaaSApple OSS Distributions static void
mptcp_do_mpjoin_opt(struct tcpcb * tp,u_char * cp,struct tcphdr * th,uint8_t optlen)1016*aca3beaaSApple OSS Distributions mptcp_do_mpjoin_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th, uint8_t optlen)
1017*aca3beaaSApple OSS Distributions {
1018*aca3beaaSApple OSS Distributions #define MPTCP_JOPT_ERROR_PATH(tp) { \
1019*aca3beaaSApple OSS Distributions tcpstat.tcps_invalid_joins++; \
1020*aca3beaaSApple OSS Distributions if (tp->t_inpcb->inp_socket != NULL) { \
1021*aca3beaaSApple OSS Distributions soevent(tp->t_inpcb->inp_socket, \
1022*aca3beaaSApple OSS Distributions SO_FILT_HINT_LOCKED | SO_FILT_HINT_MUSTRST); \
1023*aca3beaaSApple OSS Distributions } \
1024*aca3beaaSApple OSS Distributions }
1025*aca3beaaSApple OSS Distributions int error = 0;
1026*aca3beaaSApple OSS Distributions struct mptcp_mpjoin_opt_rsp *join_rsp =
1027*aca3beaaSApple OSS Distributions (struct mptcp_mpjoin_opt_rsp *)cp;
1028*aca3beaaSApple OSS Distributions
1029*aca3beaaSApple OSS Distributions /* Only valid on SYN/ACK */
1030*aca3beaaSApple OSS Distributions if ((th->th_flags & (TH_SYN | TH_ACK)) != (TH_SYN | TH_ACK)) {
1031*aca3beaaSApple OSS Distributions return;
1032*aca3beaaSApple OSS Distributions }
1033*aca3beaaSApple OSS Distributions
1034*aca3beaaSApple OSS Distributions if (optlen != sizeof(struct mptcp_mpjoin_opt_rsp)) {
1035*aca3beaaSApple OSS Distributions os_log_error(mptcp_log_handle, "%s - %lx: SYN_ACK: unexpected optlen = %u mp option = %lu\n",
1036*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(tptomptp(tp)->mpt_mpte),
1037*aca3beaaSApple OSS Distributions optlen, sizeof(struct mptcp_mpjoin_opt_rsp));
1038*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_PREESTABLISHED;
1039*aca3beaaSApple OSS Distributions /* send RST and close */
1040*aca3beaaSApple OSS Distributions MPTCP_JOPT_ERROR_PATH(tp);
1041*aca3beaaSApple OSS Distributions return;
1042*aca3beaaSApple OSS Distributions }
1043*aca3beaaSApple OSS Distributions
1044*aca3beaaSApple OSS Distributions mptcp_set_raddr_rand(tp->t_local_aid, tptomptp(tp),
1045*aca3beaaSApple OSS Distributions join_rsp->mmjo_addr_id, join_rsp->mmjo_rand);
1046*aca3beaaSApple OSS Distributions error = mptcp_validate_join_hmac(tp,
1047*aca3beaaSApple OSS Distributions (u_char*)&join_rsp->mmjo_mac, HMAC_TRUNCATED_SYNACK);
1048*aca3beaaSApple OSS Distributions if (error) {
1049*aca3beaaSApple OSS Distributions os_log_error(mptcp_log_handle, "%s - %lx: SYN_ACK error = %d \n",
1050*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(tptomptp(tp)->mpt_mpte),
1051*aca3beaaSApple OSS Distributions error);
1052*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_PREESTABLISHED;
1053*aca3beaaSApple OSS Distributions /* send RST and close */
1054*aca3beaaSApple OSS Distributions MPTCP_JOPT_ERROR_PATH(tp);
1055*aca3beaaSApple OSS Distributions return;
1056*aca3beaaSApple OSS Distributions }
1057*aca3beaaSApple OSS Distributions tp->t_mpflags |= (TMPF_SENT_JOIN | TMPF_SND_JACK);
1058*aca3beaaSApple OSS Distributions }
1059*aca3beaaSApple OSS Distributions
1060*aca3beaaSApple OSS Distributions static int
mptcp_validate_join_hmac(struct tcpcb * tp,u_char * hmac,int mac_len)1061*aca3beaaSApple OSS Distributions mptcp_validate_join_hmac(struct tcpcb *tp, u_char* hmac, int mac_len)
1062*aca3beaaSApple OSS Distributions {
1063*aca3beaaSApple OSS Distributions u_char digest[MAX(SHA1_RESULTLEN, SHA256_DIGEST_LENGTH)] = {0};
1064*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
1065*aca3beaaSApple OSS Distributions u_int32_t rem_rand, loc_rand;
1066*aca3beaaSApple OSS Distributions
1067*aca3beaaSApple OSS Distributions rem_rand = loc_rand = 0;
1068*aca3beaaSApple OSS Distributions
1069*aca3beaaSApple OSS Distributions mptcp_get_rands(tp->t_local_aid, mp_tp, &loc_rand, &rem_rand);
1070*aca3beaaSApple OSS Distributions if ((rem_rand == 0) || (loc_rand == 0)) {
1071*aca3beaaSApple OSS Distributions return -1;
1072*aca3beaaSApple OSS Distributions }
1073*aca3beaaSApple OSS Distributions
1074*aca3beaaSApple OSS Distributions if (mp_tp->mpt_version == MPTCP_VERSION_0) {
1075*aca3beaaSApple OSS Distributions mptcp_hmac_sha1(mp_tp->mpt_remotekey, mp_tp->mpt_localkey, rem_rand, loc_rand,
1076*aca3beaaSApple OSS Distributions digest);
1077*aca3beaaSApple OSS Distributions } else {
1078*aca3beaaSApple OSS Distributions uint32_t data[2];
1079*aca3beaaSApple OSS Distributions data[0] = rem_rand;
1080*aca3beaaSApple OSS Distributions data[1] = loc_rand;
1081*aca3beaaSApple OSS Distributions mptcp_hmac_sha256(mp_tp->mpt_remotekey, mp_tp->mpt_localkey, (u_char *)data, 8, digest);
1082*aca3beaaSApple OSS Distributions }
1083*aca3beaaSApple OSS Distributions
1084*aca3beaaSApple OSS Distributions if (bcmp(digest, hmac, mac_len) == 0) {
1085*aca3beaaSApple OSS Distributions return 0; /* matches */
1086*aca3beaaSApple OSS Distributions } else {
1087*aca3beaaSApple OSS Distributions printf("%s: remote key %llx local key %llx remote rand %x "
1088*aca3beaaSApple OSS Distributions "local rand %x \n", __func__, mp_tp->mpt_remotekey, mp_tp->mpt_localkey,
1089*aca3beaaSApple OSS Distributions rem_rand, loc_rand);
1090*aca3beaaSApple OSS Distributions return -1;
1091*aca3beaaSApple OSS Distributions }
1092*aca3beaaSApple OSS Distributions }
1093*aca3beaaSApple OSS Distributions
1094*aca3beaaSApple OSS Distributions /*
1095*aca3beaaSApple OSS Distributions * Update the mptcb send state variables, but the actual sbdrop occurs
1096*aca3beaaSApple OSS Distributions * in MPTCP layer
1097*aca3beaaSApple OSS Distributions */
1098*aca3beaaSApple OSS Distributions void
mptcp_data_ack_rcvd(struct mptcb * mp_tp,struct tcpcb * tp,u_int64_t full_dack)1099*aca3beaaSApple OSS Distributions mptcp_data_ack_rcvd(struct mptcb *mp_tp, struct tcpcb *tp, u_int64_t full_dack)
1100*aca3beaaSApple OSS Distributions {
1101*aca3beaaSApple OSS Distributions uint64_t acked = full_dack - mp_tp->mpt_snduna;
1102*aca3beaaSApple OSS Distributions
1103*aca3beaaSApple OSS Distributions VERIFY(acked <= INT_MAX);
1104*aca3beaaSApple OSS Distributions
1105*aca3beaaSApple OSS Distributions if (acked) {
1106*aca3beaaSApple OSS Distributions struct socket *mp_so = mptetoso(mp_tp->mpt_mpte);
1107*aca3beaaSApple OSS Distributions
1108*aca3beaaSApple OSS Distributions if (acked > mp_so->so_snd.sb_cc) {
1109*aca3beaaSApple OSS Distributions if (acked > mp_so->so_snd.sb_cc + 1 ||
1110*aca3beaaSApple OSS Distributions mp_tp->mpt_state < MPTCPS_FIN_WAIT_1) {
1111*aca3beaaSApple OSS Distributions os_log_error(mptcp_log_handle, "%s - %lx: acked %u, sb_cc %u full %u suna %u state %u\n",
1112*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mp_tp->mpt_mpte),
1113*aca3beaaSApple OSS Distributions (uint32_t)acked, mp_so->so_snd.sb_cc,
1114*aca3beaaSApple OSS Distributions (uint32_t)full_dack, (uint32_t)mp_tp->mpt_snduna,
1115*aca3beaaSApple OSS Distributions mp_tp->mpt_state);
1116*aca3beaaSApple OSS Distributions }
1117*aca3beaaSApple OSS Distributions
1118*aca3beaaSApple OSS Distributions sbdrop(&mp_so->so_snd, (int)mp_so->so_snd.sb_cc);
1119*aca3beaaSApple OSS Distributions } else {
1120*aca3beaaSApple OSS Distributions sbdrop(&mp_so->so_snd, (int)acked);
1121*aca3beaaSApple OSS Distributions }
1122*aca3beaaSApple OSS Distributions
1123*aca3beaaSApple OSS Distributions mp_tp->mpt_snduna += acked;
1124*aca3beaaSApple OSS Distributions /* In degraded mode, we may get some Data ACKs */
1125*aca3beaaSApple OSS Distributions if ((tp->t_mpflags & TMPF_TCP_FALLBACK) &&
1126*aca3beaaSApple OSS Distributions !(mp_tp->mpt_flags & MPTCPF_POST_FALLBACK_SYNC) &&
1127*aca3beaaSApple OSS Distributions MPTCP_SEQ_GT(mp_tp->mpt_sndnxt, mp_tp->mpt_snduna)) {
1128*aca3beaaSApple OSS Distributions /* bring back sndnxt to retransmit MPTCP data */
1129*aca3beaaSApple OSS Distributions mp_tp->mpt_sndnxt = mp_tp->mpt_dsn_at_csum_fail;
1130*aca3beaaSApple OSS Distributions mp_tp->mpt_flags |= MPTCPF_POST_FALLBACK_SYNC;
1131*aca3beaaSApple OSS Distributions tp->t_inpcb->inp_socket->so_flags1 |=
1132*aca3beaaSApple OSS Distributions SOF1_POST_FALLBACK_SYNC;
1133*aca3beaaSApple OSS Distributions }
1134*aca3beaaSApple OSS Distributions
1135*aca3beaaSApple OSS Distributions mptcp_clean_reinjectq(mp_tp->mpt_mpte);
1136*aca3beaaSApple OSS Distributions
1137*aca3beaaSApple OSS Distributions sowwakeup(mp_so);
1138*aca3beaaSApple OSS Distributions }
1139*aca3beaaSApple OSS Distributions if (full_dack == mp_tp->mpt_sndmax &&
1140*aca3beaaSApple OSS Distributions mp_tp->mpt_state >= MPTCPS_FIN_WAIT_1) {
1141*aca3beaaSApple OSS Distributions mptcp_close_fsm(mp_tp, MPCE_RECV_DATA_ACK);
1142*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_SEND_DFIN;
1143*aca3beaaSApple OSS Distributions }
1144*aca3beaaSApple OSS Distributions
1145*aca3beaaSApple OSS Distributions if ((tp->t_mpflags & TMPF_SND_KEYS) &&
1146*aca3beaaSApple OSS Distributions MPTCP_SEQ_GT(mp_tp->mpt_snduna, mp_tp->mpt_local_idsn + 1)) {
1147*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_SND_KEYS;
1148*aca3beaaSApple OSS Distributions }
1149*aca3beaaSApple OSS Distributions }
1150*aca3beaaSApple OSS Distributions
1151*aca3beaaSApple OSS Distributions void
mptcp_update_window_wakeup(struct tcpcb * tp)1152*aca3beaaSApple OSS Distributions mptcp_update_window_wakeup(struct tcpcb *tp)
1153*aca3beaaSApple OSS Distributions {
1154*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
1155*aca3beaaSApple OSS Distributions
1156*aca3beaaSApple OSS Distributions socket_lock_assert_owned(mptetoso(mp_tp->mpt_mpte));
1157*aca3beaaSApple OSS Distributions
1158*aca3beaaSApple OSS Distributions if (mp_tp->mpt_flags & MPTCPF_FALLBACK_TO_TCP) {
1159*aca3beaaSApple OSS Distributions mp_tp->mpt_sndwnd = tp->snd_wnd;
1160*aca3beaaSApple OSS Distributions mp_tp->mpt_sndwl1 = mp_tp->mpt_rcvnxt;
1161*aca3beaaSApple OSS Distributions mp_tp->mpt_sndwl2 = mp_tp->mpt_snduna;
1162*aca3beaaSApple OSS Distributions }
1163*aca3beaaSApple OSS Distributions
1164*aca3beaaSApple OSS Distributions sowwakeup(tp->t_inpcb->inp_socket);
1165*aca3beaaSApple OSS Distributions }
1166*aca3beaaSApple OSS Distributions
1167*aca3beaaSApple OSS Distributions static void
mptcp_update_window(struct mptcb * mp_tp,u_int64_t ack,u_int64_t seq,u_int32_t tiwin)1168*aca3beaaSApple OSS Distributions mptcp_update_window(struct mptcb *mp_tp, u_int64_t ack, u_int64_t seq, u_int32_t tiwin)
1169*aca3beaaSApple OSS Distributions {
1170*aca3beaaSApple OSS Distributions if (MPTCP_SEQ_LT(mp_tp->mpt_sndwl1, seq) ||
1171*aca3beaaSApple OSS Distributions (mp_tp->mpt_sndwl1 == seq &&
1172*aca3beaaSApple OSS Distributions (MPTCP_SEQ_LT(mp_tp->mpt_sndwl2, ack) ||
1173*aca3beaaSApple OSS Distributions (mp_tp->mpt_sndwl2 == ack && tiwin > mp_tp->mpt_sndwnd)))) {
1174*aca3beaaSApple OSS Distributions mp_tp->mpt_sndwnd = tiwin;
1175*aca3beaaSApple OSS Distributions mp_tp->mpt_sndwl1 = seq;
1176*aca3beaaSApple OSS Distributions mp_tp->mpt_sndwl2 = ack;
1177*aca3beaaSApple OSS Distributions }
1178*aca3beaaSApple OSS Distributions }
1179*aca3beaaSApple OSS Distributions
1180*aca3beaaSApple OSS Distributions static void
mptcp_do_dss_opt_ack_meat(u_int64_t full_dack,u_int64_t full_dsn,struct tcpcb * tp,u_int32_t tiwin)1181*aca3beaaSApple OSS Distributions mptcp_do_dss_opt_ack_meat(u_int64_t full_dack, u_int64_t full_dsn,
1182*aca3beaaSApple OSS Distributions struct tcpcb *tp, u_int32_t tiwin)
1183*aca3beaaSApple OSS Distributions {
1184*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
1185*aca3beaaSApple OSS Distributions int close_notify = 0;
1186*aca3beaaSApple OSS Distributions
1187*aca3beaaSApple OSS Distributions tp->t_mpflags |= TMPF_RCVD_DACK;
1188*aca3beaaSApple OSS Distributions
1189*aca3beaaSApple OSS Distributions if (MPTCP_SEQ_LEQ(full_dack, mp_tp->mpt_sndmax) &&
1190*aca3beaaSApple OSS Distributions MPTCP_SEQ_GEQ(full_dack, mp_tp->mpt_snduna)) {
1191*aca3beaaSApple OSS Distributions mptcp_data_ack_rcvd(mp_tp, tp, full_dack);
1192*aca3beaaSApple OSS Distributions if (mp_tp->mpt_state > MPTCPS_FIN_WAIT_2) {
1193*aca3beaaSApple OSS Distributions close_notify = 1;
1194*aca3beaaSApple OSS Distributions }
1195*aca3beaaSApple OSS Distributions if (mp_tp->mpt_flags & MPTCPF_RCVD_64BITACK) {
1196*aca3beaaSApple OSS Distributions mp_tp->mpt_flags &= ~MPTCPF_RCVD_64BITACK;
1197*aca3beaaSApple OSS Distributions mp_tp->mpt_flags &= ~MPTCPF_SND_64BITDSN;
1198*aca3beaaSApple OSS Distributions }
1199*aca3beaaSApple OSS Distributions mptcp_notify_mpready(tp->t_inpcb->inp_socket);
1200*aca3beaaSApple OSS Distributions if (close_notify) {
1201*aca3beaaSApple OSS Distributions mptcp_notify_close(tp->t_inpcb->inp_socket);
1202*aca3beaaSApple OSS Distributions }
1203*aca3beaaSApple OSS Distributions }
1204*aca3beaaSApple OSS Distributions
1205*aca3beaaSApple OSS Distributions mptcp_update_window(mp_tp, full_dack, full_dsn, tiwin);
1206*aca3beaaSApple OSS Distributions }
1207*aca3beaaSApple OSS Distributions
1208*aca3beaaSApple OSS Distributions static void
mptcp_do_dss_opt_meat(u_char * cp,struct tcpcb * tp,struct tcphdr * th)1209*aca3beaaSApple OSS Distributions mptcp_do_dss_opt_meat(u_char *cp, struct tcpcb *tp, struct tcphdr *th)
1210*aca3beaaSApple OSS Distributions {
1211*aca3beaaSApple OSS Distributions struct mptcp_dss_copt *dss_rsp = (struct mptcp_dss_copt *)cp;
1212*aca3beaaSApple OSS Distributions u_int64_t full_dack = 0;
1213*aca3beaaSApple OSS Distributions u_int32_t tiwin = th->th_win << tp->snd_scale;
1214*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
1215*aca3beaaSApple OSS Distributions int csum_len = 0;
1216*aca3beaaSApple OSS Distributions
1217*aca3beaaSApple OSS Distributions #define MPTCP_DSS_OPT_SZ_CHK(len, expected_len) { \
1218*aca3beaaSApple OSS Distributions if (len != expected_len) { \
1219*aca3beaaSApple OSS Distributions os_log_error(mptcp_log_handle, "%s - %lx: bad len = %d dss: %x\n",\
1220*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mp_tp->mpt_mpte), \
1221*aca3beaaSApple OSS Distributions len, dss_rsp->mdss_flags); \
1222*aca3beaaSApple OSS Distributions return; \
1223*aca3beaaSApple OSS Distributions } \
1224*aca3beaaSApple OSS Distributions }
1225*aca3beaaSApple OSS Distributions
1226*aca3beaaSApple OSS Distributions if (mp_tp->mpt_flags & MPTCPF_CHECKSUM) {
1227*aca3beaaSApple OSS Distributions csum_len = 2;
1228*aca3beaaSApple OSS Distributions }
1229*aca3beaaSApple OSS Distributions
1230*aca3beaaSApple OSS Distributions dss_rsp->mdss_flags &= (MDSS_A | MDSS_a | MDSS_M | MDSS_m);
1231*aca3beaaSApple OSS Distributions switch (dss_rsp->mdss_flags) {
1232*aca3beaaSApple OSS Distributions case (MDSS_M):
1233*aca3beaaSApple OSS Distributions {
1234*aca3beaaSApple OSS Distributions /* 32-bit DSS, No Data ACK */
1235*aca3beaaSApple OSS Distributions struct mptcp_dsn_opt *dss_rsp1;
1236*aca3beaaSApple OSS Distributions dss_rsp1 = (struct mptcp_dsn_opt *)cp;
1237*aca3beaaSApple OSS Distributions
1238*aca3beaaSApple OSS Distributions MPTCP_DSS_OPT_SZ_CHK(dss_rsp1->mdss_copt.mdss_len,
1239*aca3beaaSApple OSS Distributions sizeof(struct mptcp_dsn_opt) + csum_len);
1240*aca3beaaSApple OSS Distributions if (csum_len == 0) {
1241*aca3beaaSApple OSS Distributions mptcp_update_dss_rcv_state(dss_rsp1, tp, 0);
1242*aca3beaaSApple OSS Distributions } else {
1243*aca3beaaSApple OSS Distributions mptcp_update_dss_rcv_state(dss_rsp1, tp,
1244*aca3beaaSApple OSS Distributions *(uint16_t *)(void *)(cp +
1245*aca3beaaSApple OSS Distributions (dss_rsp1->mdss_copt.mdss_len - csum_len)));
1246*aca3beaaSApple OSS Distributions }
1247*aca3beaaSApple OSS Distributions break;
1248*aca3beaaSApple OSS Distributions }
1249*aca3beaaSApple OSS Distributions case (MDSS_A):
1250*aca3beaaSApple OSS Distributions {
1251*aca3beaaSApple OSS Distributions /* 32-bit Data ACK, no DSS */
1252*aca3beaaSApple OSS Distributions struct mptcp_data_ack_opt *dack_opt;
1253*aca3beaaSApple OSS Distributions dack_opt = (struct mptcp_data_ack_opt *)cp;
1254*aca3beaaSApple OSS Distributions
1255*aca3beaaSApple OSS Distributions MPTCP_DSS_OPT_SZ_CHK(dack_opt->mdss_copt.mdss_len,
1256*aca3beaaSApple OSS Distributions sizeof(struct mptcp_data_ack_opt));
1257*aca3beaaSApple OSS Distributions
1258*aca3beaaSApple OSS Distributions u_int32_t dack = dack_opt->mdss_ack;
1259*aca3beaaSApple OSS Distributions NTOHL(dack);
1260*aca3beaaSApple OSS Distributions MPTCP_EXTEND_DSN(mp_tp->mpt_snduna, dack, full_dack);
1261*aca3beaaSApple OSS Distributions mptcp_do_dss_opt_ack_meat(full_dack, mp_tp->mpt_sndwl1, tp, tiwin);
1262*aca3beaaSApple OSS Distributions break;
1263*aca3beaaSApple OSS Distributions }
1264*aca3beaaSApple OSS Distributions case (MDSS_M | MDSS_A):
1265*aca3beaaSApple OSS Distributions {
1266*aca3beaaSApple OSS Distributions /* 32-bit Data ACK + 32-bit DSS */
1267*aca3beaaSApple OSS Distributions struct mptcp_dss_ack_opt *dss_ack_rsp;
1268*aca3beaaSApple OSS Distributions dss_ack_rsp = (struct mptcp_dss_ack_opt *)cp;
1269*aca3beaaSApple OSS Distributions u_int64_t full_dsn;
1270*aca3beaaSApple OSS Distributions uint16_t csum = 0;
1271*aca3beaaSApple OSS Distributions
1272*aca3beaaSApple OSS Distributions MPTCP_DSS_OPT_SZ_CHK(dss_ack_rsp->mdss_copt.mdss_len,
1273*aca3beaaSApple OSS Distributions sizeof(struct mptcp_dss_ack_opt) + csum_len);
1274*aca3beaaSApple OSS Distributions
1275*aca3beaaSApple OSS Distributions u_int32_t dack = dss_ack_rsp->mdss_ack;
1276*aca3beaaSApple OSS Distributions NTOHL(dack);
1277*aca3beaaSApple OSS Distributions MPTCP_EXTEND_DSN(mp_tp->mpt_snduna, dack, full_dack);
1278*aca3beaaSApple OSS Distributions
1279*aca3beaaSApple OSS Distributions NTOHL(dss_ack_rsp->mdss_dsn);
1280*aca3beaaSApple OSS Distributions NTOHL(dss_ack_rsp->mdss_subflow_seqn);
1281*aca3beaaSApple OSS Distributions NTOHS(dss_ack_rsp->mdss_data_len);
1282*aca3beaaSApple OSS Distributions MPTCP_EXTEND_DSN(mp_tp->mpt_rcvnxt, dss_ack_rsp->mdss_dsn, full_dsn);
1283*aca3beaaSApple OSS Distributions
1284*aca3beaaSApple OSS Distributions mptcp_do_dss_opt_ack_meat(full_dack, full_dsn, tp, tiwin);
1285*aca3beaaSApple OSS Distributions
1286*aca3beaaSApple OSS Distributions if (csum_len != 0) {
1287*aca3beaaSApple OSS Distributions csum = *(uint16_t *)(void *)(cp + (dss_ack_rsp->mdss_copt.mdss_len - csum_len));
1288*aca3beaaSApple OSS Distributions }
1289*aca3beaaSApple OSS Distributions
1290*aca3beaaSApple OSS Distributions mptcp_update_rcv_state_meat(mp_tp, tp,
1291*aca3beaaSApple OSS Distributions full_dsn,
1292*aca3beaaSApple OSS Distributions dss_ack_rsp->mdss_subflow_seqn,
1293*aca3beaaSApple OSS Distributions dss_ack_rsp->mdss_data_len,
1294*aca3beaaSApple OSS Distributions csum);
1295*aca3beaaSApple OSS Distributions break;
1296*aca3beaaSApple OSS Distributions }
1297*aca3beaaSApple OSS Distributions case (MDSS_M | MDSS_m):
1298*aca3beaaSApple OSS Distributions {
1299*aca3beaaSApple OSS Distributions /* 64-bit DSS , No Data ACK */
1300*aca3beaaSApple OSS Distributions struct mptcp_dsn64_opt *dsn64;
1301*aca3beaaSApple OSS Distributions dsn64 = (struct mptcp_dsn64_opt *)cp;
1302*aca3beaaSApple OSS Distributions u_int64_t full_dsn;
1303*aca3beaaSApple OSS Distributions uint16_t csum = 0;
1304*aca3beaaSApple OSS Distributions
1305*aca3beaaSApple OSS Distributions MPTCP_DSS_OPT_SZ_CHK(dsn64->mdss_copt.mdss_len,
1306*aca3beaaSApple OSS Distributions sizeof(struct mptcp_dsn64_opt) + csum_len);
1307*aca3beaaSApple OSS Distributions
1308*aca3beaaSApple OSS Distributions mp_tp->mpt_flags |= MPTCPF_SND_64BITACK;
1309*aca3beaaSApple OSS Distributions
1310*aca3beaaSApple OSS Distributions full_dsn = mptcp_ntoh64(dsn64->mdss_dsn);
1311*aca3beaaSApple OSS Distributions NTOHL(dsn64->mdss_subflow_seqn);
1312*aca3beaaSApple OSS Distributions NTOHS(dsn64->mdss_data_len);
1313*aca3beaaSApple OSS Distributions
1314*aca3beaaSApple OSS Distributions if (csum_len != 0) {
1315*aca3beaaSApple OSS Distributions csum = *(uint16_t *)(void *)(cp + dsn64->mdss_copt.mdss_len - csum_len);
1316*aca3beaaSApple OSS Distributions }
1317*aca3beaaSApple OSS Distributions
1318*aca3beaaSApple OSS Distributions mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1319*aca3beaaSApple OSS Distributions dsn64->mdss_subflow_seqn,
1320*aca3beaaSApple OSS Distributions dsn64->mdss_data_len,
1321*aca3beaaSApple OSS Distributions csum);
1322*aca3beaaSApple OSS Distributions break;
1323*aca3beaaSApple OSS Distributions }
1324*aca3beaaSApple OSS Distributions case (MDSS_A | MDSS_a):
1325*aca3beaaSApple OSS Distributions {
1326*aca3beaaSApple OSS Distributions /* 64-bit Data ACK, no DSS */
1327*aca3beaaSApple OSS Distributions struct mptcp_data_ack64_opt *dack64;
1328*aca3beaaSApple OSS Distributions dack64 = (struct mptcp_data_ack64_opt *)cp;
1329*aca3beaaSApple OSS Distributions
1330*aca3beaaSApple OSS Distributions MPTCP_DSS_OPT_SZ_CHK(dack64->mdss_copt.mdss_len,
1331*aca3beaaSApple OSS Distributions sizeof(struct mptcp_data_ack64_opt));
1332*aca3beaaSApple OSS Distributions
1333*aca3beaaSApple OSS Distributions mp_tp->mpt_flags |= MPTCPF_RCVD_64BITACK;
1334*aca3beaaSApple OSS Distributions
1335*aca3beaaSApple OSS Distributions full_dack = mptcp_ntoh64(dack64->mdss_ack);
1336*aca3beaaSApple OSS Distributions mptcp_do_dss_opt_ack_meat(full_dack, mp_tp->mpt_sndwl1, tp, tiwin);
1337*aca3beaaSApple OSS Distributions break;
1338*aca3beaaSApple OSS Distributions }
1339*aca3beaaSApple OSS Distributions case (MDSS_M | MDSS_m | MDSS_A):
1340*aca3beaaSApple OSS Distributions {
1341*aca3beaaSApple OSS Distributions /* 64-bit DSS + 32-bit Data ACK */
1342*aca3beaaSApple OSS Distributions struct mptcp_dss64_ack32_opt *dss_ack_rsp;
1343*aca3beaaSApple OSS Distributions dss_ack_rsp = (struct mptcp_dss64_ack32_opt *)cp;
1344*aca3beaaSApple OSS Distributions u_int64_t full_dsn;
1345*aca3beaaSApple OSS Distributions uint16_t csum = 0;
1346*aca3beaaSApple OSS Distributions
1347*aca3beaaSApple OSS Distributions MPTCP_DSS_OPT_SZ_CHK(dss_ack_rsp->mdss_copt.mdss_len,
1348*aca3beaaSApple OSS Distributions sizeof(struct mptcp_dss64_ack32_opt) + csum_len);
1349*aca3beaaSApple OSS Distributions
1350*aca3beaaSApple OSS Distributions u_int32_t dack = dss_ack_rsp->mdss_ack;
1351*aca3beaaSApple OSS Distributions NTOHL(dack);
1352*aca3beaaSApple OSS Distributions mp_tp->mpt_flags |= MPTCPF_SND_64BITACK;
1353*aca3beaaSApple OSS Distributions MPTCP_EXTEND_DSN(mp_tp->mpt_snduna, dack, full_dack);
1354*aca3beaaSApple OSS Distributions
1355*aca3beaaSApple OSS Distributions full_dsn = mptcp_ntoh64(dss_ack_rsp->mdss_dsn);
1356*aca3beaaSApple OSS Distributions NTOHL(dss_ack_rsp->mdss_subflow_seqn);
1357*aca3beaaSApple OSS Distributions NTOHS(dss_ack_rsp->mdss_data_len);
1358*aca3beaaSApple OSS Distributions
1359*aca3beaaSApple OSS Distributions mptcp_do_dss_opt_ack_meat(full_dack, full_dsn, tp, tiwin);
1360*aca3beaaSApple OSS Distributions
1361*aca3beaaSApple OSS Distributions if (csum_len != 0) {
1362*aca3beaaSApple OSS Distributions csum = *(uint16_t *)(void *)(cp + dss_ack_rsp->mdss_copt.mdss_len - csum_len);
1363*aca3beaaSApple OSS Distributions }
1364*aca3beaaSApple OSS Distributions
1365*aca3beaaSApple OSS Distributions mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1366*aca3beaaSApple OSS Distributions dss_ack_rsp->mdss_subflow_seqn,
1367*aca3beaaSApple OSS Distributions dss_ack_rsp->mdss_data_len,
1368*aca3beaaSApple OSS Distributions csum);
1369*aca3beaaSApple OSS Distributions
1370*aca3beaaSApple OSS Distributions break;
1371*aca3beaaSApple OSS Distributions }
1372*aca3beaaSApple OSS Distributions case (MDSS_M | MDSS_A | MDSS_a):
1373*aca3beaaSApple OSS Distributions {
1374*aca3beaaSApple OSS Distributions /* 32-bit DSS + 64-bit Data ACK */
1375*aca3beaaSApple OSS Distributions struct mptcp_dss32_ack64_opt *dss32_ack64_opt;
1376*aca3beaaSApple OSS Distributions dss32_ack64_opt = (struct mptcp_dss32_ack64_opt *)cp;
1377*aca3beaaSApple OSS Distributions u_int64_t full_dsn;
1378*aca3beaaSApple OSS Distributions
1379*aca3beaaSApple OSS Distributions MPTCP_DSS_OPT_SZ_CHK(
1380*aca3beaaSApple OSS Distributions dss32_ack64_opt->mdss_copt.mdss_len,
1381*aca3beaaSApple OSS Distributions sizeof(struct mptcp_dss32_ack64_opt) + csum_len);
1382*aca3beaaSApple OSS Distributions
1383*aca3beaaSApple OSS Distributions full_dack = mptcp_ntoh64(dss32_ack64_opt->mdss_ack);
1384*aca3beaaSApple OSS Distributions NTOHL(dss32_ack64_opt->mdss_dsn);
1385*aca3beaaSApple OSS Distributions mp_tp->mpt_flags |= MPTCPF_RCVD_64BITACK;
1386*aca3beaaSApple OSS Distributions MPTCP_EXTEND_DSN(mp_tp->mpt_rcvnxt,
1387*aca3beaaSApple OSS Distributions dss32_ack64_opt->mdss_dsn, full_dsn);
1388*aca3beaaSApple OSS Distributions NTOHL(dss32_ack64_opt->mdss_subflow_seqn);
1389*aca3beaaSApple OSS Distributions NTOHS(dss32_ack64_opt->mdss_data_len);
1390*aca3beaaSApple OSS Distributions
1391*aca3beaaSApple OSS Distributions mptcp_do_dss_opt_ack_meat(full_dack, full_dsn, tp, tiwin);
1392*aca3beaaSApple OSS Distributions if (csum_len == 0) {
1393*aca3beaaSApple OSS Distributions mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1394*aca3beaaSApple OSS Distributions dss32_ack64_opt->mdss_subflow_seqn,
1395*aca3beaaSApple OSS Distributions dss32_ack64_opt->mdss_data_len, 0);
1396*aca3beaaSApple OSS Distributions } else {
1397*aca3beaaSApple OSS Distributions mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1398*aca3beaaSApple OSS Distributions dss32_ack64_opt->mdss_subflow_seqn,
1399*aca3beaaSApple OSS Distributions dss32_ack64_opt->mdss_data_len,
1400*aca3beaaSApple OSS Distributions *(uint16_t *)(void *)(cp +
1401*aca3beaaSApple OSS Distributions dss32_ack64_opt->mdss_copt.mdss_len -
1402*aca3beaaSApple OSS Distributions csum_len));
1403*aca3beaaSApple OSS Distributions }
1404*aca3beaaSApple OSS Distributions break;
1405*aca3beaaSApple OSS Distributions }
1406*aca3beaaSApple OSS Distributions case (MDSS_M | MDSS_m | MDSS_A | MDSS_a):
1407*aca3beaaSApple OSS Distributions {
1408*aca3beaaSApple OSS Distributions /* 64-bit DSS + 64-bit Data ACK */
1409*aca3beaaSApple OSS Distributions struct mptcp_dss64_ack64_opt *dss64_ack64;
1410*aca3beaaSApple OSS Distributions dss64_ack64 = (struct mptcp_dss64_ack64_opt *)cp;
1411*aca3beaaSApple OSS Distributions u_int64_t full_dsn;
1412*aca3beaaSApple OSS Distributions
1413*aca3beaaSApple OSS Distributions MPTCP_DSS_OPT_SZ_CHK(dss64_ack64->mdss_copt.mdss_len,
1414*aca3beaaSApple OSS Distributions sizeof(struct mptcp_dss64_ack64_opt) + csum_len);
1415*aca3beaaSApple OSS Distributions
1416*aca3beaaSApple OSS Distributions mp_tp->mpt_flags |= MPTCPF_RCVD_64BITACK;
1417*aca3beaaSApple OSS Distributions mp_tp->mpt_flags |= MPTCPF_SND_64BITACK;
1418*aca3beaaSApple OSS Distributions full_dsn = mptcp_ntoh64(dss64_ack64->mdss_dsn);
1419*aca3beaaSApple OSS Distributions full_dack = mptcp_ntoh64(dss64_ack64->mdss_dsn);
1420*aca3beaaSApple OSS Distributions mptcp_do_dss_opt_ack_meat(full_dack, full_dsn, tp, tiwin);
1421*aca3beaaSApple OSS Distributions NTOHL(dss64_ack64->mdss_subflow_seqn);
1422*aca3beaaSApple OSS Distributions NTOHS(dss64_ack64->mdss_data_len);
1423*aca3beaaSApple OSS Distributions if (csum_len == 0) {
1424*aca3beaaSApple OSS Distributions mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1425*aca3beaaSApple OSS Distributions dss64_ack64->mdss_subflow_seqn,
1426*aca3beaaSApple OSS Distributions dss64_ack64->mdss_data_len, 0);
1427*aca3beaaSApple OSS Distributions } else {
1428*aca3beaaSApple OSS Distributions mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1429*aca3beaaSApple OSS Distributions dss64_ack64->mdss_subflow_seqn,
1430*aca3beaaSApple OSS Distributions dss64_ack64->mdss_data_len,
1431*aca3beaaSApple OSS Distributions *(uint16_t *)(void *)(cp +
1432*aca3beaaSApple OSS Distributions dss64_ack64->mdss_copt.mdss_len -
1433*aca3beaaSApple OSS Distributions csum_len));
1434*aca3beaaSApple OSS Distributions }
1435*aca3beaaSApple OSS Distributions break;
1436*aca3beaaSApple OSS Distributions }
1437*aca3beaaSApple OSS Distributions default:
1438*aca3beaaSApple OSS Distributions break;
1439*aca3beaaSApple OSS Distributions }
1440*aca3beaaSApple OSS Distributions }
1441*aca3beaaSApple OSS Distributions
1442*aca3beaaSApple OSS Distributions static void
mptcp_do_dss_opt(struct tcpcb * tp,u_char * cp,struct tcphdr * th)1443*aca3beaaSApple OSS Distributions mptcp_do_dss_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th)
1444*aca3beaaSApple OSS Distributions {
1445*aca3beaaSApple OSS Distributions struct mptcp_dss_copt *dss_rsp = (struct mptcp_dss_copt *)cp;
1446*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
1447*aca3beaaSApple OSS Distributions
1448*aca3beaaSApple OSS Distributions if (!mp_tp) {
1449*aca3beaaSApple OSS Distributions return;
1450*aca3beaaSApple OSS Distributions }
1451*aca3beaaSApple OSS Distributions
1452*aca3beaaSApple OSS Distributions if (dss_rsp->mdss_subtype == MPO_DSS) {
1453*aca3beaaSApple OSS Distributions if (dss_rsp->mdss_flags & MDSS_F) {
1454*aca3beaaSApple OSS Distributions tp->t_rcv_map.mpt_dfin = 1;
1455*aca3beaaSApple OSS Distributions } else {
1456*aca3beaaSApple OSS Distributions tp->t_rcv_map.mpt_dfin = 0;
1457*aca3beaaSApple OSS Distributions }
1458*aca3beaaSApple OSS Distributions
1459*aca3beaaSApple OSS Distributions mptcp_do_dss_opt_meat(cp, tp, th);
1460*aca3beaaSApple OSS Distributions }
1461*aca3beaaSApple OSS Distributions }
1462*aca3beaaSApple OSS Distributions
1463*aca3beaaSApple OSS Distributions static void
mptcp_do_fastclose_opt(struct tcpcb * tp,u_char * cp,struct tcphdr * th)1464*aca3beaaSApple OSS Distributions mptcp_do_fastclose_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th)
1465*aca3beaaSApple OSS Distributions {
1466*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = NULL;
1467*aca3beaaSApple OSS Distributions struct mptcp_fastclose_opt *fc_opt = (struct mptcp_fastclose_opt *)cp;
1468*aca3beaaSApple OSS Distributions
1469*aca3beaaSApple OSS Distributions if (th->th_flags != TH_ACK) {
1470*aca3beaaSApple OSS Distributions return;
1471*aca3beaaSApple OSS Distributions }
1472*aca3beaaSApple OSS Distributions
1473*aca3beaaSApple OSS Distributions if (fc_opt->mfast_len != sizeof(struct mptcp_fastclose_opt)) {
1474*aca3beaaSApple OSS Distributions tcpstat.tcps_invalid_opt++;
1475*aca3beaaSApple OSS Distributions return;
1476*aca3beaaSApple OSS Distributions }
1477*aca3beaaSApple OSS Distributions
1478*aca3beaaSApple OSS Distributions mp_tp = tptomptp(tp);
1479*aca3beaaSApple OSS Distributions if (!mp_tp) {
1480*aca3beaaSApple OSS Distributions return;
1481*aca3beaaSApple OSS Distributions }
1482*aca3beaaSApple OSS Distributions
1483*aca3beaaSApple OSS Distributions if (fc_opt->mfast_key != mp_tp->mpt_localkey) {
1484*aca3beaaSApple OSS Distributions tcpstat.tcps_invalid_opt++;
1485*aca3beaaSApple OSS Distributions return;
1486*aca3beaaSApple OSS Distributions }
1487*aca3beaaSApple OSS Distributions
1488*aca3beaaSApple OSS Distributions /*
1489*aca3beaaSApple OSS Distributions * fastclose could make us more vulnerable to attacks, hence
1490*aca3beaaSApple OSS Distributions * accept only those that are at the next expected sequence number.
1491*aca3beaaSApple OSS Distributions */
1492*aca3beaaSApple OSS Distributions if (th->th_seq != tp->rcv_nxt) {
1493*aca3beaaSApple OSS Distributions tcpstat.tcps_invalid_opt++;
1494*aca3beaaSApple OSS Distributions return;
1495*aca3beaaSApple OSS Distributions }
1496*aca3beaaSApple OSS Distributions
1497*aca3beaaSApple OSS Distributions /* Reset this flow */
1498*aca3beaaSApple OSS Distributions tp->t_mpflags |= TMPF_FASTCLOSERCV;
1499*aca3beaaSApple OSS Distributions
1500*aca3beaaSApple OSS Distributions if (tp->t_inpcb->inp_socket != NULL) {
1501*aca3beaaSApple OSS Distributions soevent(tp->t_inpcb->inp_socket,
1502*aca3beaaSApple OSS Distributions SO_FILT_HINT_LOCKED | SO_FILT_HINT_MUSTRST);
1503*aca3beaaSApple OSS Distributions }
1504*aca3beaaSApple OSS Distributions }
1505*aca3beaaSApple OSS Distributions
1506*aca3beaaSApple OSS Distributions
1507*aca3beaaSApple OSS Distributions static void
mptcp_do_mpfail_opt(struct tcpcb * tp,u_char * cp,struct tcphdr * th)1508*aca3beaaSApple OSS Distributions mptcp_do_mpfail_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th)
1509*aca3beaaSApple OSS Distributions {
1510*aca3beaaSApple OSS Distributions struct mptcp_mpfail_opt *fail_opt = (struct mptcp_mpfail_opt *)cp;
1511*aca3beaaSApple OSS Distributions u_int32_t mdss_subflow_seqn = 0;
1512*aca3beaaSApple OSS Distributions struct mptcb *mp_tp;
1513*aca3beaaSApple OSS Distributions int error = 0;
1514*aca3beaaSApple OSS Distributions
1515*aca3beaaSApple OSS Distributions /*
1516*aca3beaaSApple OSS Distributions * mpfail could make us more vulnerable to attacks. Hence accept
1517*aca3beaaSApple OSS Distributions * only those that are the next expected sequence number.
1518*aca3beaaSApple OSS Distributions */
1519*aca3beaaSApple OSS Distributions if (th->th_seq != tp->rcv_nxt) {
1520*aca3beaaSApple OSS Distributions tcpstat.tcps_invalid_opt++;
1521*aca3beaaSApple OSS Distributions return;
1522*aca3beaaSApple OSS Distributions }
1523*aca3beaaSApple OSS Distributions
1524*aca3beaaSApple OSS Distributions /* A packet without RST, must atleast have the ACK bit set */
1525*aca3beaaSApple OSS Distributions if ((th->th_flags != TH_ACK) && (th->th_flags != TH_RST)) {
1526*aca3beaaSApple OSS Distributions return;
1527*aca3beaaSApple OSS Distributions }
1528*aca3beaaSApple OSS Distributions
1529*aca3beaaSApple OSS Distributions if (fail_opt->mfail_len != sizeof(struct mptcp_mpfail_opt)) {
1530*aca3beaaSApple OSS Distributions return;
1531*aca3beaaSApple OSS Distributions }
1532*aca3beaaSApple OSS Distributions
1533*aca3beaaSApple OSS Distributions mp_tp = tptomptp(tp);
1534*aca3beaaSApple OSS Distributions
1535*aca3beaaSApple OSS Distributions mp_tp->mpt_flags |= MPTCPF_RECVD_MPFAIL;
1536*aca3beaaSApple OSS Distributions mp_tp->mpt_dsn_at_csum_fail = mptcp_hton64(fail_opt->mfail_dsn);
1537*aca3beaaSApple OSS Distributions error = mptcp_get_map_for_dsn(tp->t_inpcb->inp_socket,
1538*aca3beaaSApple OSS Distributions mp_tp->mpt_dsn_at_csum_fail, &mdss_subflow_seqn);
1539*aca3beaaSApple OSS Distributions if (error == 0) {
1540*aca3beaaSApple OSS Distributions mp_tp->mpt_ssn_at_csum_fail = mdss_subflow_seqn;
1541*aca3beaaSApple OSS Distributions }
1542*aca3beaaSApple OSS Distributions
1543*aca3beaaSApple OSS Distributions mptcp_notify_mpfail(tp->t_inpcb->inp_socket);
1544*aca3beaaSApple OSS Distributions }
1545*aca3beaaSApple OSS Distributions
1546*aca3beaaSApple OSS Distributions static boolean_t
mptcp_validate_add_addr_hmac(struct tcpcb * tp,u_char * hmac,u_char * msg,uint16_t msg_len,uint16_t mac_len)1547*aca3beaaSApple OSS Distributions mptcp_validate_add_addr_hmac(struct tcpcb *tp, u_char *hmac,
1548*aca3beaaSApple OSS Distributions u_char *msg, uint16_t msg_len, uint16_t mac_len)
1549*aca3beaaSApple OSS Distributions {
1550*aca3beaaSApple OSS Distributions u_char digest[SHA256_DIGEST_LENGTH] = {0};
1551*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
1552*aca3beaaSApple OSS Distributions
1553*aca3beaaSApple OSS Distributions VERIFY(mac_len <= SHA256_DIGEST_LENGTH);
1554*aca3beaaSApple OSS Distributions mptcp_hmac_sha256(mp_tp->mpt_remotekey, mp_tp->mpt_localkey, msg, msg_len, digest);
1555*aca3beaaSApple OSS Distributions
1556*aca3beaaSApple OSS Distributions if (bcmp(digest + SHA256_DIGEST_LENGTH - mac_len, hmac, mac_len) == 0) {
1557*aca3beaaSApple OSS Distributions return true; /* matches */
1558*aca3beaaSApple OSS Distributions } else {
1559*aca3beaaSApple OSS Distributions return false;
1560*aca3beaaSApple OSS Distributions }
1561*aca3beaaSApple OSS Distributions }
1562*aca3beaaSApple OSS Distributions
1563*aca3beaaSApple OSS Distributions static void
mptcp_do_add_addr_opt_v1(struct tcpcb * tp,u_char * cp)1564*aca3beaaSApple OSS Distributions mptcp_do_add_addr_opt_v1(struct tcpcb *tp, u_char *cp)
1565*aca3beaaSApple OSS Distributions {
1566*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
1567*aca3beaaSApple OSS Distributions struct mptses *mpte = mp_tp->mpt_mpte;
1568*aca3beaaSApple OSS Distributions
1569*aca3beaaSApple OSS Distributions struct mptcp_add_addr_opt *addr_opt = (struct mptcp_add_addr_opt *)cp;
1570*aca3beaaSApple OSS Distributions
1571*aca3beaaSApple OSS Distributions if (addr_opt->maddr_len != MPTCP_V1_ADD_ADDR_OPT_LEN_V4 &&
1572*aca3beaaSApple OSS Distributions addr_opt->maddr_len != MPTCP_V1_ADD_ADDR_OPT_LEN_V4 + 2 &&
1573*aca3beaaSApple OSS Distributions addr_opt->maddr_len != MPTCP_V1_ADD_ADDR_OPT_LEN_V6 &&
1574*aca3beaaSApple OSS Distributions addr_opt->maddr_len != MPTCP_V1_ADD_ADDR_OPT_LEN_V6 + 2) {
1575*aca3beaaSApple OSS Distributions os_log_info(mptcp_log_handle, "%s - %lx: Wrong ADD_ADDR length %u\n",
1576*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte),
1577*aca3beaaSApple OSS Distributions addr_opt->maddr_len);
1578*aca3beaaSApple OSS Distributions
1579*aca3beaaSApple OSS Distributions return;
1580*aca3beaaSApple OSS Distributions }
1581*aca3beaaSApple OSS Distributions
1582*aca3beaaSApple OSS Distributions if ((addr_opt->maddr_flags & MPTCP_V1_ADD_ADDR_ECHO) != 0) {
1583*aca3beaaSApple OSS Distributions os_log_info(mptcp_log_handle, "%s - %lx: Received ADD_ADDR with echo bit\n",
1584*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte));
1585*aca3beaaSApple OSS Distributions
1586*aca3beaaSApple OSS Distributions return;
1587*aca3beaaSApple OSS Distributions }
1588*aca3beaaSApple OSS Distributions
1589*aca3beaaSApple OSS Distributions if (addr_opt->maddr_len < MPTCP_V1_ADD_ADDR_OPT_LEN_V6) {
1590*aca3beaaSApple OSS Distributions struct sockaddr_in *dst = &mpte->mpte_sub_dst_v4;
1591*aca3beaaSApple OSS Distributions struct in_addr *addr = &addr_opt->maddr_u.maddr_addrv4;
1592*aca3beaaSApple OSS Distributions in_addr_t haddr = ntohl(addr->s_addr);
1593*aca3beaaSApple OSS Distributions
1594*aca3beaaSApple OSS Distributions if (IN_ZERONET(haddr) ||
1595*aca3beaaSApple OSS Distributions IN_LOOPBACK(haddr) ||
1596*aca3beaaSApple OSS Distributions IN_LINKLOCAL(haddr) ||
1597*aca3beaaSApple OSS Distributions IN_DS_LITE(haddr) ||
1598*aca3beaaSApple OSS Distributions IN_6TO4_RELAY_ANYCAST(haddr) ||
1599*aca3beaaSApple OSS Distributions IN_MULTICAST(haddr) ||
1600*aca3beaaSApple OSS Distributions INADDR_BROADCAST == haddr ||
1601*aca3beaaSApple OSS Distributions IN_PRIVATE(haddr) ||
1602*aca3beaaSApple OSS Distributions IN_SHARED_ADDRESS_SPACE(haddr)) {
1603*aca3beaaSApple OSS Distributions os_log_info(mptcp_log_handle, "%s - %lx: ADD_ADDR invalid addr: %x\n",
1604*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte),
1605*aca3beaaSApple OSS Distributions addr->s_addr);
1606*aca3beaaSApple OSS Distributions
1607*aca3beaaSApple OSS Distributions return;
1608*aca3beaaSApple OSS Distributions }
1609*aca3beaaSApple OSS Distributions
1610*aca3beaaSApple OSS Distributions u_char *hmac = (void *)(cp + addr_opt->maddr_len - HMAC_TRUNCATED_ADD_ADDR);
1611*aca3beaaSApple OSS Distributions uint16_t msg_len = sizeof(struct mptcp_add_addr_hmac_msg_v4);
1612*aca3beaaSApple OSS Distributions struct mptcp_add_addr_hmac_msg_v4 msg = {0};
1613*aca3beaaSApple OSS Distributions msg.maddr_addrid = addr_opt->maddr_addrid;
1614*aca3beaaSApple OSS Distributions msg.maddr_addr = addr_opt->maddr_u.maddr_addrv4;
1615*aca3beaaSApple OSS Distributions if (addr_opt->maddr_len > MPTCP_V1_ADD_ADDR_OPT_LEN_V4) {
1616*aca3beaaSApple OSS Distributions msg.maddr_port = *(uint16_t *)(void *)(cp + addr_opt->maddr_len - HMAC_TRUNCATED_ADD_ADDR - 2);
1617*aca3beaaSApple OSS Distributions }
1618*aca3beaaSApple OSS Distributions if (!mptcp_validate_add_addr_hmac(tp, hmac, (u_char *)&msg, msg_len, HMAC_TRUNCATED_ADD_ADDR)) {
1619*aca3beaaSApple OSS Distributions os_log_info(mptcp_log_handle, "%s - %lx: ADD_ADDR addr: %x invalid HMAC\n",
1620*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte),
1621*aca3beaaSApple OSS Distributions addr->s_addr);
1622*aca3beaaSApple OSS Distributions return;
1623*aca3beaaSApple OSS Distributions }
1624*aca3beaaSApple OSS Distributions
1625*aca3beaaSApple OSS Distributions dst->sin_len = sizeof(*dst);
1626*aca3beaaSApple OSS Distributions dst->sin_family = AF_INET;
1627*aca3beaaSApple OSS Distributions if (addr_opt->maddr_len > MPTCP_V1_ADD_ADDR_OPT_LEN_V4) {
1628*aca3beaaSApple OSS Distributions dst->sin_port = *(uint16_t *)(void *)(cp + addr_opt->maddr_len - HMAC_TRUNCATED_ADD_ADDR - 2);
1629*aca3beaaSApple OSS Distributions } else {
1630*aca3beaaSApple OSS Distributions dst->sin_port = mpte->__mpte_dst_v4.sin_port;
1631*aca3beaaSApple OSS Distributions }
1632*aca3beaaSApple OSS Distributions dst->sin_addr.s_addr = addr->s_addr;
1633*aca3beaaSApple OSS Distributions mpte->sub_dst_addr_id_v4 = addr_opt->maddr_addrid;
1634*aca3beaaSApple OSS Distributions mpte->mpte_last_added_addr_is_v4 = TRUE;
1635*aca3beaaSApple OSS Distributions } else {
1636*aca3beaaSApple OSS Distributions struct sockaddr_in6 *dst = &mpte->mpte_sub_dst_v6;
1637*aca3beaaSApple OSS Distributions struct in6_addr *addr = &addr_opt->maddr_u.maddr_addrv6;
1638*aca3beaaSApple OSS Distributions
1639*aca3beaaSApple OSS Distributions if (IN6_IS_ADDR_LINKLOCAL(addr) ||
1640*aca3beaaSApple OSS Distributions IN6_IS_ADDR_MULTICAST(addr) ||
1641*aca3beaaSApple OSS Distributions IN6_IS_ADDR_UNSPECIFIED(addr) ||
1642*aca3beaaSApple OSS Distributions IN6_IS_ADDR_LOOPBACK(addr) ||
1643*aca3beaaSApple OSS Distributions IN6_IS_ADDR_V4COMPAT(addr) ||
1644*aca3beaaSApple OSS Distributions IN6_IS_ADDR_V4MAPPED(addr)) {
1645*aca3beaaSApple OSS Distributions char dbuf[MAX_IPv6_STR_LEN];
1646*aca3beaaSApple OSS Distributions
1647*aca3beaaSApple OSS Distributions inet_ntop(AF_INET6, addr, dbuf, sizeof(dbuf));
1648*aca3beaaSApple OSS Distributions os_log_info(mptcp_log_handle, "%s - %lx: ADD_ADDRv6 invalid addr: %s\n",
1649*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte),
1650*aca3beaaSApple OSS Distributions dbuf);
1651*aca3beaaSApple OSS Distributions
1652*aca3beaaSApple OSS Distributions return;
1653*aca3beaaSApple OSS Distributions }
1654*aca3beaaSApple OSS Distributions
1655*aca3beaaSApple OSS Distributions u_char *hmac = (void *)(cp + addr_opt->maddr_len - HMAC_TRUNCATED_ADD_ADDR);
1656*aca3beaaSApple OSS Distributions uint16_t msg_len = sizeof(struct mptcp_add_addr_hmac_msg_v6);
1657*aca3beaaSApple OSS Distributions struct mptcp_add_addr_hmac_msg_v6 msg = {0};
1658*aca3beaaSApple OSS Distributions msg.maddr_addrid = addr_opt->maddr_addrid;
1659*aca3beaaSApple OSS Distributions msg.maddr_addr = addr_opt->maddr_u.maddr_addrv6;
1660*aca3beaaSApple OSS Distributions if (addr_opt->maddr_len > MPTCP_V1_ADD_ADDR_OPT_LEN_V6) {
1661*aca3beaaSApple OSS Distributions msg.maddr_port = *(uint16_t *)(void *)(cp + addr_opt->maddr_len - HMAC_TRUNCATED_ADD_ADDR - 2);
1662*aca3beaaSApple OSS Distributions }
1663*aca3beaaSApple OSS Distributions if (!mptcp_validate_add_addr_hmac(tp, hmac, (u_char *)&msg, msg_len, HMAC_TRUNCATED_ADD_ADDR)) {
1664*aca3beaaSApple OSS Distributions char dbuf[MAX_IPv6_STR_LEN];
1665*aca3beaaSApple OSS Distributions
1666*aca3beaaSApple OSS Distributions inet_ntop(AF_INET6, addr, dbuf, sizeof(dbuf));
1667*aca3beaaSApple OSS Distributions os_log_info(mptcp_log_handle, "%s - %lx: ADD_ADDR addr: %s invalid HMAC\n",
1668*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte),
1669*aca3beaaSApple OSS Distributions dbuf);
1670*aca3beaaSApple OSS Distributions return;
1671*aca3beaaSApple OSS Distributions }
1672*aca3beaaSApple OSS Distributions
1673*aca3beaaSApple OSS Distributions dst->sin6_len = sizeof(*dst);
1674*aca3beaaSApple OSS Distributions dst->sin6_family = AF_INET6;
1675*aca3beaaSApple OSS Distributions if (addr_opt->maddr_len > MPTCP_V1_ADD_ADDR_OPT_LEN_V6) {
1676*aca3beaaSApple OSS Distributions dst->sin6_port = *(uint16_t *)(void *)(cp + addr_opt->maddr_len - HMAC_TRUNCATED_ADD_ADDR - 2);
1677*aca3beaaSApple OSS Distributions } else {
1678*aca3beaaSApple OSS Distributions dst->sin6_port = mpte->__mpte_dst_v6.sin6_port;
1679*aca3beaaSApple OSS Distributions }
1680*aca3beaaSApple OSS Distributions memcpy(&dst->sin6_addr, addr, sizeof(*addr));
1681*aca3beaaSApple OSS Distributions mpte->sub_dst_addr_id_v6 = addr_opt->maddr_addrid;
1682*aca3beaaSApple OSS Distributions mpte->mpte_last_added_addr_is_v4 = FALSE;
1683*aca3beaaSApple OSS Distributions }
1684*aca3beaaSApple OSS Distributions
1685*aca3beaaSApple OSS Distributions os_log_info(mptcp_log_handle, "%s - %lx: Received ADD_ADDRv%u\n",
1686*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte),
1687*aca3beaaSApple OSS Distributions addr_opt->maddr_flags);
1688*aca3beaaSApple OSS Distributions
1689*aca3beaaSApple OSS Distributions tp->t_mpflags |= TMPF_MPTCP_ECHO_ADDR;
1690*aca3beaaSApple OSS Distributions mptcp_sched_create_subflows(mpte);
1691*aca3beaaSApple OSS Distributions }
1692*aca3beaaSApple OSS Distributions
1693*aca3beaaSApple OSS Distributions static void
mptcp_do_add_addr_opt_v0(struct mptses * mpte,u_char * cp)1694*aca3beaaSApple OSS Distributions mptcp_do_add_addr_opt_v0(struct mptses *mpte, u_char *cp)
1695*aca3beaaSApple OSS Distributions {
1696*aca3beaaSApple OSS Distributions struct mptcp_add_addr_opt *addr_opt = (struct mptcp_add_addr_opt *)cp;
1697*aca3beaaSApple OSS Distributions
1698*aca3beaaSApple OSS Distributions if (addr_opt->maddr_len != MPTCP_V0_ADD_ADDR_OPT_LEN_V4 &&
1699*aca3beaaSApple OSS Distributions addr_opt->maddr_len != MPTCP_V0_ADD_ADDR_OPT_LEN_V6) {
1700*aca3beaaSApple OSS Distributions os_log_info(mptcp_log_handle, "%s - %lx: Wrong ADD_ADDR length %u\n",
1701*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte),
1702*aca3beaaSApple OSS Distributions addr_opt->maddr_len);
1703*aca3beaaSApple OSS Distributions
1704*aca3beaaSApple OSS Distributions return;
1705*aca3beaaSApple OSS Distributions }
1706*aca3beaaSApple OSS Distributions
1707*aca3beaaSApple OSS Distributions if (addr_opt->maddr_len == MPTCP_V0_ADD_ADDR_OPT_LEN_V4 &&
1708*aca3beaaSApple OSS Distributions addr_opt->maddr_flags != MPTCP_V0_ADD_ADDR_IPV4) {
1709*aca3beaaSApple OSS Distributions os_log_info(mptcp_log_handle, "%s - %lx: ADD_ADDR length for v4 but version is %u\n",
1710*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte),
1711*aca3beaaSApple OSS Distributions addr_opt->maddr_flags);
1712*aca3beaaSApple OSS Distributions
1713*aca3beaaSApple OSS Distributions return;
1714*aca3beaaSApple OSS Distributions }
1715*aca3beaaSApple OSS Distributions
1716*aca3beaaSApple OSS Distributions if (addr_opt->maddr_len == MPTCP_V0_ADD_ADDR_OPT_LEN_V6 &&
1717*aca3beaaSApple OSS Distributions addr_opt->maddr_flags != MPTCP_V0_ADD_ADDR_IPV6) {
1718*aca3beaaSApple OSS Distributions os_log_info(mptcp_log_handle, "%s - %lx: ADD_ADDR length for v6 but version is %u\n",
1719*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte),
1720*aca3beaaSApple OSS Distributions addr_opt->maddr_flags);
1721*aca3beaaSApple OSS Distributions
1722*aca3beaaSApple OSS Distributions return;
1723*aca3beaaSApple OSS Distributions }
1724*aca3beaaSApple OSS Distributions
1725*aca3beaaSApple OSS Distributions if (addr_opt->maddr_len == MPTCP_V0_ADD_ADDR_OPT_LEN_V4) {
1726*aca3beaaSApple OSS Distributions struct sockaddr_in *dst = &mpte->mpte_sub_dst_v4;
1727*aca3beaaSApple OSS Distributions struct in_addr *addr = &addr_opt->maddr_u.maddr_addrv4;
1728*aca3beaaSApple OSS Distributions in_addr_t haddr = ntohl(addr->s_addr);
1729*aca3beaaSApple OSS Distributions
1730*aca3beaaSApple OSS Distributions if (IN_ZERONET(haddr) ||
1731*aca3beaaSApple OSS Distributions IN_LOOPBACK(haddr) ||
1732*aca3beaaSApple OSS Distributions IN_LINKLOCAL(haddr) ||
1733*aca3beaaSApple OSS Distributions IN_DS_LITE(haddr) ||
1734*aca3beaaSApple OSS Distributions IN_6TO4_RELAY_ANYCAST(haddr) ||
1735*aca3beaaSApple OSS Distributions IN_MULTICAST(haddr) ||
1736*aca3beaaSApple OSS Distributions INADDR_BROADCAST == haddr ||
1737*aca3beaaSApple OSS Distributions IN_PRIVATE(haddr) ||
1738*aca3beaaSApple OSS Distributions IN_SHARED_ADDRESS_SPACE(haddr)) {
1739*aca3beaaSApple OSS Distributions os_log_info(mptcp_log_handle, "%s - %lx: ADD_ADDR invalid addr: %x\n",
1740*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte),
1741*aca3beaaSApple OSS Distributions addr->s_addr);
1742*aca3beaaSApple OSS Distributions
1743*aca3beaaSApple OSS Distributions return;
1744*aca3beaaSApple OSS Distributions }
1745*aca3beaaSApple OSS Distributions
1746*aca3beaaSApple OSS Distributions dst->sin_len = sizeof(*dst);
1747*aca3beaaSApple OSS Distributions dst->sin_family = AF_INET;
1748*aca3beaaSApple OSS Distributions dst->sin_port = mpte->__mpte_dst_v4.sin_port;
1749*aca3beaaSApple OSS Distributions dst->sin_addr.s_addr = addr->s_addr;
1750*aca3beaaSApple OSS Distributions mpte->mpte_last_added_addr_is_v4 = TRUE;
1751*aca3beaaSApple OSS Distributions } else {
1752*aca3beaaSApple OSS Distributions struct sockaddr_in6 *dst = &mpte->mpte_sub_dst_v6;
1753*aca3beaaSApple OSS Distributions struct in6_addr *addr = &addr_opt->maddr_u.maddr_addrv6;
1754*aca3beaaSApple OSS Distributions
1755*aca3beaaSApple OSS Distributions if (IN6_IS_ADDR_LINKLOCAL(addr) ||
1756*aca3beaaSApple OSS Distributions IN6_IS_ADDR_MULTICAST(addr) ||
1757*aca3beaaSApple OSS Distributions IN6_IS_ADDR_UNSPECIFIED(addr) ||
1758*aca3beaaSApple OSS Distributions IN6_IS_ADDR_LOOPBACK(addr) ||
1759*aca3beaaSApple OSS Distributions IN6_IS_ADDR_V4COMPAT(addr) ||
1760*aca3beaaSApple OSS Distributions IN6_IS_ADDR_V4MAPPED(addr)) {
1761*aca3beaaSApple OSS Distributions char dbuf[MAX_IPv6_STR_LEN];
1762*aca3beaaSApple OSS Distributions
1763*aca3beaaSApple OSS Distributions inet_ntop(AF_INET6, addr, dbuf, sizeof(dbuf));
1764*aca3beaaSApple OSS Distributions os_log_info(mptcp_log_handle, "%s - %lx: ADD_ADDRv6 invalid addr: %s\n",
1765*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte),
1766*aca3beaaSApple OSS Distributions dbuf);
1767*aca3beaaSApple OSS Distributions
1768*aca3beaaSApple OSS Distributions return;
1769*aca3beaaSApple OSS Distributions }
1770*aca3beaaSApple OSS Distributions
1771*aca3beaaSApple OSS Distributions dst->sin6_len = sizeof(*dst);
1772*aca3beaaSApple OSS Distributions dst->sin6_family = AF_INET6;
1773*aca3beaaSApple OSS Distributions dst->sin6_port = mpte->__mpte_dst_v6.sin6_port;
1774*aca3beaaSApple OSS Distributions dst->sin6_addr = *addr;
1775*aca3beaaSApple OSS Distributions mpte->mpte_last_added_addr_is_v4 = FALSE;
1776*aca3beaaSApple OSS Distributions }
1777*aca3beaaSApple OSS Distributions
1778*aca3beaaSApple OSS Distributions os_log_info(mptcp_log_handle, "%s - %lx: Received ADD_ADDRv%u\n",
1779*aca3beaaSApple OSS Distributions __func__, (unsigned long)VM_KERNEL_ADDRPERM(mpte),
1780*aca3beaaSApple OSS Distributions addr_opt->maddr_flags);
1781*aca3beaaSApple OSS Distributions
1782*aca3beaaSApple OSS Distributions mptcp_sched_create_subflows(mpte);
1783*aca3beaaSApple OSS Distributions }
1784*aca3beaaSApple OSS Distributions
1785*aca3beaaSApple OSS Distributions void
tcp_do_mptcp_options(struct tcpcb * tp,u_char * cp,struct tcphdr * th,struct tcpopt * to,uint8_t optlen)1786*aca3beaaSApple OSS Distributions tcp_do_mptcp_options(struct tcpcb *tp, u_char *cp, struct tcphdr *th,
1787*aca3beaaSApple OSS Distributions struct tcpopt *to, uint8_t optlen)
1788*aca3beaaSApple OSS Distributions {
1789*aca3beaaSApple OSS Distributions int mptcp_subtype;
1790*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
1791*aca3beaaSApple OSS Distributions
1792*aca3beaaSApple OSS Distributions if (mp_tp == NULL) {
1793*aca3beaaSApple OSS Distributions return;
1794*aca3beaaSApple OSS Distributions }
1795*aca3beaaSApple OSS Distributions
1796*aca3beaaSApple OSS Distributions socket_lock_assert_owned(mptetoso(mp_tp->mpt_mpte));
1797*aca3beaaSApple OSS Distributions
1798*aca3beaaSApple OSS Distributions /* All MPTCP options have atleast 4 bytes */
1799*aca3beaaSApple OSS Distributions if (optlen < 4) {
1800*aca3beaaSApple OSS Distributions return;
1801*aca3beaaSApple OSS Distributions }
1802*aca3beaaSApple OSS Distributions
1803*aca3beaaSApple OSS Distributions mptcp_subtype = (cp[2] >> 4);
1804*aca3beaaSApple OSS Distributions
1805*aca3beaaSApple OSS Distributions if (mptcp_sanitize_option(tp, mptcp_subtype) == 0) {
1806*aca3beaaSApple OSS Distributions return;
1807*aca3beaaSApple OSS Distributions }
1808*aca3beaaSApple OSS Distributions
1809*aca3beaaSApple OSS Distributions switch (mptcp_subtype) {
1810*aca3beaaSApple OSS Distributions case MPO_CAPABLE:
1811*aca3beaaSApple OSS Distributions mptcp_do_mpcapable_opt(tp, cp, th, optlen);
1812*aca3beaaSApple OSS Distributions break;
1813*aca3beaaSApple OSS Distributions case MPO_JOIN:
1814*aca3beaaSApple OSS Distributions mptcp_do_mpjoin_opt(tp, cp, th, optlen);
1815*aca3beaaSApple OSS Distributions break;
1816*aca3beaaSApple OSS Distributions case MPO_DSS:
1817*aca3beaaSApple OSS Distributions mptcp_do_dss_opt(tp, cp, th);
1818*aca3beaaSApple OSS Distributions break;
1819*aca3beaaSApple OSS Distributions case MPO_FASTCLOSE:
1820*aca3beaaSApple OSS Distributions mptcp_do_fastclose_opt(tp, cp, th);
1821*aca3beaaSApple OSS Distributions break;
1822*aca3beaaSApple OSS Distributions case MPO_FAIL:
1823*aca3beaaSApple OSS Distributions mptcp_do_mpfail_opt(tp, cp, th);
1824*aca3beaaSApple OSS Distributions break;
1825*aca3beaaSApple OSS Distributions case MPO_ADD_ADDR:
1826*aca3beaaSApple OSS Distributions if (mp_tp->mpt_version == MPTCP_VERSION_0) {
1827*aca3beaaSApple OSS Distributions mptcp_do_add_addr_opt_v0(mp_tp->mpt_mpte, cp);
1828*aca3beaaSApple OSS Distributions } else {
1829*aca3beaaSApple OSS Distributions mptcp_do_add_addr_opt_v1(tp, cp);
1830*aca3beaaSApple OSS Distributions }
1831*aca3beaaSApple OSS Distributions break;
1832*aca3beaaSApple OSS Distributions case MPO_REMOVE_ADDR: /* fall through */
1833*aca3beaaSApple OSS Distributions case MPO_PRIO:
1834*aca3beaaSApple OSS Distributions to->to_flags |= TOF_MPTCP;
1835*aca3beaaSApple OSS Distributions break;
1836*aca3beaaSApple OSS Distributions default:
1837*aca3beaaSApple OSS Distributions break;
1838*aca3beaaSApple OSS Distributions }
1839*aca3beaaSApple OSS Distributions return;
1840*aca3beaaSApple OSS Distributions }
1841*aca3beaaSApple OSS Distributions
1842*aca3beaaSApple OSS Distributions /* REMOVE_ADDR option is sent when a source address goes away */
1843*aca3beaaSApple OSS Distributions static void
mptcp_send_remaddr_opt(struct tcpcb * tp,struct mptcp_remaddr_opt * opt)1844*aca3beaaSApple OSS Distributions mptcp_send_remaddr_opt(struct tcpcb *tp, struct mptcp_remaddr_opt *opt)
1845*aca3beaaSApple OSS Distributions {
1846*aca3beaaSApple OSS Distributions bzero(opt, sizeof(*opt));
1847*aca3beaaSApple OSS Distributions opt->mr_kind = TCPOPT_MULTIPATH;
1848*aca3beaaSApple OSS Distributions opt->mr_len = sizeof(*opt);
1849*aca3beaaSApple OSS Distributions opt->mr_subtype = MPO_REMOVE_ADDR;
1850*aca3beaaSApple OSS Distributions opt->mr_addr_id = tp->t_rem_aid;
1851*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_SND_REM_ADDR;
1852*aca3beaaSApple OSS Distributions }
1853*aca3beaaSApple OSS Distributions
1854*aca3beaaSApple OSS Distributions static int
mptcp_echo_add_addr(struct tcpcb * tp,u_char * cp,unsigned int optlen)1855*aca3beaaSApple OSS Distributions mptcp_echo_add_addr(struct tcpcb *tp, u_char *cp, unsigned int optlen)
1856*aca3beaaSApple OSS Distributions {
1857*aca3beaaSApple OSS Distributions struct mptcp_add_addr_opt mpaddr;
1858*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
1859*aca3beaaSApple OSS Distributions struct mptses *mpte = mp_tp->mpt_mpte;
1860*aca3beaaSApple OSS Distributions
1861*aca3beaaSApple OSS Distributions // MPTCP v0 doesn't require echoing add_addr
1862*aca3beaaSApple OSS Distributions if (mp_tp->mpt_version == MPTCP_VERSION_0) {
1863*aca3beaaSApple OSS Distributions return optlen;
1864*aca3beaaSApple OSS Distributions }
1865*aca3beaaSApple OSS Distributions
1866*aca3beaaSApple OSS Distributions size_t mpaddr_size = mpte->mpte_last_added_addr_is_v4 ? MPTCP_V1_ADD_ADDR_ECHO_OPT_LEN_V4 : MPTCP_V1_ADD_ADDR_ECHO_OPT_LEN_V6;
1867*aca3beaaSApple OSS Distributions if ((MAX_TCPOPTLEN - optlen) < mpaddr_size) {
1868*aca3beaaSApple OSS Distributions return optlen;
1869*aca3beaaSApple OSS Distributions }
1870*aca3beaaSApple OSS Distributions
1871*aca3beaaSApple OSS Distributions bzero(&mpaddr, sizeof(mpaddr));
1872*aca3beaaSApple OSS Distributions mpaddr.maddr_kind = TCPOPT_MULTIPATH;
1873*aca3beaaSApple OSS Distributions mpaddr.maddr_len = (uint8_t)mpaddr_size;
1874*aca3beaaSApple OSS Distributions mpaddr.maddr_subtype = MPO_ADD_ADDR;
1875*aca3beaaSApple OSS Distributions mpaddr.maddr_flags = MPTCP_V1_ADD_ADDR_ECHO;
1876*aca3beaaSApple OSS Distributions if (mpte->mpte_last_added_addr_is_v4) {
1877*aca3beaaSApple OSS Distributions mpaddr.maddr_u.maddr_addrv4.s_addr = mpte->mpte_sub_dst_v4.sin_addr.s_addr;
1878*aca3beaaSApple OSS Distributions mpaddr.maddr_addrid = mpte->sub_dst_addr_id_v4;
1879*aca3beaaSApple OSS Distributions } else {
1880*aca3beaaSApple OSS Distributions mpaddr.maddr_u.maddr_addrv6 = mpte->mpte_sub_dst_v6.sin6_addr;
1881*aca3beaaSApple OSS Distributions mpaddr.maddr_addrid = mpte->sub_dst_addr_id_v6;
1882*aca3beaaSApple OSS Distributions }
1883*aca3beaaSApple OSS Distributions
1884*aca3beaaSApple OSS Distributions memcpy(cp + optlen, &mpaddr, mpaddr_size);
1885*aca3beaaSApple OSS Distributions optlen += mpaddr_size;
1886*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_MPTCP_ECHO_ADDR;
1887*aca3beaaSApple OSS Distributions return optlen;
1888*aca3beaaSApple OSS Distributions }
1889*aca3beaaSApple OSS Distributions
1890*aca3beaaSApple OSS Distributions /* We send MP_PRIO option based on the values set by the SIOCSCONNORDER ioctl */
1891*aca3beaaSApple OSS Distributions static int
mptcp_snd_mpprio(struct tcpcb * tp,u_char * cp,int optlen)1892*aca3beaaSApple OSS Distributions mptcp_snd_mpprio(struct tcpcb *tp, u_char *cp, int optlen)
1893*aca3beaaSApple OSS Distributions {
1894*aca3beaaSApple OSS Distributions struct mptcp_mpprio_addr_opt mpprio;
1895*aca3beaaSApple OSS Distributions struct mptcb *mp_tp = tptomptp(tp);
1896*aca3beaaSApple OSS Distributions size_t mpprio_size = sizeof(mpprio);
1897*aca3beaaSApple OSS Distributions // MP_PRIO of MPTCPv1 doesn't include AddrID
1898*aca3beaaSApple OSS Distributions if (mp_tp->mpt_version == MPTCP_VERSION_1) {
1899*aca3beaaSApple OSS Distributions mpprio_size -= sizeof(uint8_t);
1900*aca3beaaSApple OSS Distributions }
1901*aca3beaaSApple OSS Distributions
1902*aca3beaaSApple OSS Distributions if (tp->t_state != TCPS_ESTABLISHED) {
1903*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_SND_MPPRIO;
1904*aca3beaaSApple OSS Distributions return optlen;
1905*aca3beaaSApple OSS Distributions }
1906*aca3beaaSApple OSS Distributions
1907*aca3beaaSApple OSS Distributions if ((MAX_TCPOPTLEN - optlen) < (int)mpprio_size) {
1908*aca3beaaSApple OSS Distributions return optlen;
1909*aca3beaaSApple OSS Distributions }
1910*aca3beaaSApple OSS Distributions
1911*aca3beaaSApple OSS Distributions bzero(&mpprio, sizeof(mpprio));
1912*aca3beaaSApple OSS Distributions mpprio.mpprio_kind = TCPOPT_MULTIPATH;
1913*aca3beaaSApple OSS Distributions mpprio.mpprio_len = (uint8_t)mpprio_size;
1914*aca3beaaSApple OSS Distributions mpprio.mpprio_subtype = MPO_PRIO;
1915*aca3beaaSApple OSS Distributions if (tp->t_mpflags & TMPF_BACKUP_PATH) {
1916*aca3beaaSApple OSS Distributions mpprio.mpprio_flags |= MPTCP_MPPRIO_BKP;
1917*aca3beaaSApple OSS Distributions }
1918*aca3beaaSApple OSS Distributions mpprio.mpprio_addrid = tp->t_local_aid;
1919*aca3beaaSApple OSS Distributions memcpy(cp + optlen, &mpprio, mpprio_size);
1920*aca3beaaSApple OSS Distributions optlen += mpprio_size;
1921*aca3beaaSApple OSS Distributions tp->t_mpflags &= ~TMPF_SND_MPPRIO;
1922*aca3beaaSApple OSS Distributions return optlen;
1923*aca3beaaSApple OSS Distributions }
1924