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