]> git.saurik.com Git - apple/xnu.git/blame - bsd/netinet/mptcp_opt.c
xnu-4903.270.47.tar.gz
[apple/xnu.git] / bsd / netinet / mptcp_opt.c
CommitLineData
39236c6e 1/*
5ba3f43e 2 * Copyright (c) 2012-2017 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
56static int mptcp_validate_join_hmac(struct tcpcb *, u_char*, int);
57static int mptcp_snd_mpprio(struct tcpcb *tp, u_char *cp, int optlen);
5ba3f43e 58static void mptcp_send_remaddr_opt(struct tcpcb *, struct mptcp_remaddr_opt *);
39236c6e
A
59
60/*
61 * MPTCP Options Output Processing
62 */
63
64static unsigned
5ba3f43e 65mptcp_setup_first_subflow_syn_opts(struct socket *so, u_char *opt, unsigned optlen)
39236c6e 66{
5ba3f43e 67 struct mptcp_mpcapable_opt_common mptcp_opt;
39236c6e 68 struct tcpcb *tp = sototcpcb(so);
5ba3f43e
A
69 struct mptcb *mp_tp = tptomptp(tp);
70
71 mpte_lock_assert_held(mp_tp->mpt_mpte);
39236c6e 72
39236c6e
A
73 /*
74 * Avoid retransmitting the MP_CAPABLE option.
75 */
39037602
A
76 if (tp->t_rxtshift > mptcp_mpcap_retries) {
77 if (!(mp_tp->mpt_flags & (MPTCPF_FALLBACK_HEURISTIC | MPTCPF_HEURISTIC_TRAC))) {
78 mp_tp->mpt_flags |= MPTCPF_HEURISTIC_TRAC;
79 tcp_heuristic_mptcp_loss(tp);
80 }
0a7de745 81 return optlen;
39037602
A
82 }
83
84 if (!tcp_heuristic_do_mptcp(tp)) {
85 mp_tp->mpt_flags |= MPTCPF_FALLBACK_HEURISTIC;
0a7de745 86 return optlen;
39037602 87 }
39236c6e 88
0a7de745 89 bzero(&mptcp_opt, sizeof(struct mptcp_mpcapable_opt_common));
39236c6e 90
5ba3f43e
A
91 mptcp_opt.mmco_kind = TCPOPT_MULTIPATH;
92 mptcp_opt.mmco_len =
0a7de745
A
93 sizeof(struct mptcp_mpcapable_opt_common) +
94 sizeof(mptcp_key_t);
5ba3f43e
A
95 mptcp_opt.mmco_subtype = MPO_CAPABLE;
96 mptcp_opt.mmco_version = mp_tp->mpt_version;
97 mptcp_opt.mmco_flags |= MPCAP_PROPOSAL_SBIT;
0a7de745 98 if (mp_tp->mpt_flags & MPTCPF_CHECKSUM) {
5ba3f43e 99 mptcp_opt.mmco_flags |= MPCAP_CHECKSUM_CBIT;
0a7de745
A
100 }
101 memcpy(opt + optlen, &mptcp_opt, sizeof(struct mptcp_mpcapable_opt_common));
102 optlen += sizeof(struct mptcp_mpcapable_opt_common);
103 memcpy(opt + optlen, &mp_tp->mpt_localkey, sizeof(mptcp_key_t));
104 optlen += sizeof(mptcp_key_t);
39236c6e 105
0a7de745 106 return optlen;
39236c6e
A
107}
108
109static unsigned
5ba3f43e 110mptcp_setup_join_subflow_syn_opts(struct socket *so, u_char *opt, unsigned optlen)
39236c6e 111{
5ba3f43e 112 struct mptcp_mpjoin_opt_req mpjoin_req;
39236c6e
A
113 struct inpcb *inp = sotoinpcb(so);
114 struct tcpcb *tp = NULL;
5ba3f43e 115 struct mptsub *mpts;
39236c6e 116
0a7de745
A
117 if (!inp) {
118 return optlen;
119 }
39236c6e
A
120
121 tp = intotcpcb(inp);
0a7de745
A
122 if (!tp) {
123 return optlen;
124 }
39236c6e 125
5ba3f43e 126 mpts = tp->t_mpsub;
39236c6e 127
5ba3f43e
A
128 VERIFY(tptomptp(tp));
129 mpte_lock_assert_held(tptomptp(tp)->mpt_mpte);
fe8ab488 130
0a7de745 131 bzero(&mpjoin_req, sizeof(mpjoin_req));
5ba3f43e 132 mpjoin_req.mmjo_kind = TCPOPT_MULTIPATH;
0a7de745 133 mpjoin_req.mmjo_len = sizeof(mpjoin_req);
5ba3f43e 134 mpjoin_req.mmjo_subtype_bkp = MPO_JOIN << 4;
fe8ab488 135
5ba3f43e
A
136 if (tp->t_mpflags & TMPF_BACKUP_PATH) {
137 mpjoin_req.mmjo_subtype_bkp |= MPTCP_BACKUP;
138 } else if (inp->inp_boundifp && IFNET_IS_CELLULAR(inp->inp_boundifp) &&
0a7de745 139 mpts->mpts_mpte->mpte_svctype != MPTCP_SVCTYPE_AGGREGATE) {
5ba3f43e
A
140 mpjoin_req.mmjo_subtype_bkp |= MPTCP_BACKUP;
141 tp->t_mpflags |= TMPF_BACKUP_PATH;
39236c6e 142 } else {
5ba3f43e
A
143 mpts->mpts_flags |= MPTSF_PREFERRED;
144 }
145
146 mpjoin_req.mmjo_addr_id = tp->t_local_aid;
147 mpjoin_req.mmjo_peer_token = tptomptp(tp)->mpt_remotetoken;
148 if (mpjoin_req.mmjo_peer_token == 0) {
149 mptcplog((LOG_DEBUG, "%s: peer token 0", __func__),
0a7de745 150 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
39236c6e 151 }
5ba3f43e
A
152 mptcp_get_rands(tp->t_local_aid, tptomptp(tp),
153 &mpjoin_req.mmjo_rand, NULL);
154 memcpy(opt + optlen, &mpjoin_req, mpjoin_req.mmjo_len);
155 optlen += mpjoin_req.mmjo_len;
156
0a7de745 157 return optlen;
39236c6e
A
158}
159
160unsigned
161mptcp_setup_join_ack_opts(struct tcpcb *tp, u_char *opt, unsigned optlen)
162{
163 unsigned new_optlen;
164 struct mptcp_mpjoin_opt_rsp2 join_rsp2;
165
0a7de745 166 if ((MAX_TCPOPTLEN - optlen) < sizeof(struct mptcp_mpjoin_opt_rsp2)) {
39236c6e 167 printf("%s: no space left %d \n", __func__, optlen);
0a7de745 168 return optlen;
39236c6e
A
169 }
170
0a7de745 171 bzero(&join_rsp2, sizeof(struct mptcp_mpjoin_opt_rsp2));
39236c6e 172 join_rsp2.mmjo_kind = TCPOPT_MULTIPATH;
0a7de745 173 join_rsp2.mmjo_len = sizeof(struct mptcp_mpjoin_opt_rsp2);
39236c6e
A
174 join_rsp2.mmjo_subtype = MPO_JOIN;
175 mptcp_get_hmac(tp->t_local_aid, tptomptp(tp),
5ba3f43e 176 (u_char*)&join_rsp2.mmjo_mac);
39236c6e
A
177 memcpy(opt + optlen, &join_rsp2, join_rsp2.mmjo_len);
178 new_optlen = optlen + join_rsp2.mmjo_len;
0a7de745 179 return new_optlen;
39236c6e
A
180}
181
182unsigned
5ba3f43e 183mptcp_setup_syn_opts(struct socket *so, u_char *opt, unsigned optlen)
39236c6e
A
184{
185 unsigned new_optlen;
186
0a7de745 187 if (!(so->so_flags & SOF_MP_SEC_SUBFLOW)) {
5ba3f43e 188 new_optlen = mptcp_setup_first_subflow_syn_opts(so, opt, optlen);
0a7de745 189 } else {
5ba3f43e 190 new_optlen = mptcp_setup_join_subflow_syn_opts(so, opt, optlen);
0a7de745 191 }
5ba3f43e 192
0a7de745 193 return new_optlen;
39236c6e
A
194}
195
196static int
197mptcp_send_mpfail(struct tcpcb *tp, u_char *opt, unsigned int optlen)
198{
199#pragma unused(tp, opt, optlen)
200
201 struct mptcb *mp_tp = NULL;
202 struct mptcp_mpfail_opt fail_opt;
203 uint64_t dsn;
0a7de745 204 int len = sizeof(struct mptcp_mpfail_opt);
39236c6e
A
205
206 mp_tp = tptomptp(tp);
207 if (mp_tp == NULL) {
208 tp->t_mpflags &= ~TMPF_SND_MPFAIL;
0a7de745 209 return optlen;
39236c6e
A
210 }
211
5ba3f43e
A
212 mpte_lock_assert_held(mp_tp->mpt_mpte);
213
39236c6e 214 /* if option space low give up */
0a7de745 215 if ((MAX_TCPOPTLEN - optlen) < sizeof(struct mptcp_mpfail_opt)) {
39236c6e 216 tp->t_mpflags &= ~TMPF_SND_MPFAIL;
0a7de745 217 return optlen;
39037602 218 }
39236c6e 219
39236c6e 220 dsn = mp_tp->mpt_rcvnxt;
39236c6e 221
0a7de745 222 bzero(&fail_opt, sizeof(fail_opt));
39236c6e
A
223 fail_opt.mfail_kind = TCPOPT_MULTIPATH;
224 fail_opt.mfail_len = len;
225 fail_opt.mfail_subtype = MPO_FAIL;
226 fail_opt.mfail_dsn = mptcp_hton64(dsn);
227 memcpy(opt + optlen, &fail_opt, len);
228 optlen += len;
229 tp->t_mpflags &= ~TMPF_SND_MPFAIL;
5ba3f43e 230 mptcplog((LOG_DEBUG, "%s: %d \n", __func__,
39037602 231 tp->t_local_aid), (MPTCP_SOCKET_DBG | MPTCP_SENDER_DBG),
3e170ce0 232 MPTCP_LOGLVL_LOG);
0a7de745 233 return optlen;
39236c6e
A
234}
235
236static int
237mptcp_send_infinite_mapping(struct tcpcb *tp, u_char *opt, unsigned int optlen)
238{
239 struct mptcp_dsn_opt infin_opt;
240 struct mptcb *mp_tp = NULL;
0a7de745 241 size_t len = sizeof(struct mptcp_dsn_opt);
39236c6e 242 struct socket *so = tp->t_inpcb->inp_socket;
39236c6e
A
243 int csum_len = 0;
244
0a7de745
A
245 if (!so) {
246 return optlen;
247 }
39236c6e
A
248
249 mp_tp = tptomptp(tp);
0a7de745
A
250 if (mp_tp == NULL) {
251 return optlen;
252 }
39236c6e 253
5ba3f43e
A
254 mpte_lock_assert_held(mp_tp->mpt_mpte);
255
0a7de745 256 if (mp_tp->mpt_flags & MPTCPF_CHECKSUM) {
39236c6e 257 csum_len = 2;
0a7de745 258 }
39236c6e
A
259
260 /* try later */
0a7de745
A
261 if ((MAX_TCPOPTLEN - optlen) < (len + csum_len)) {
262 return optlen;
263 }
5ba3f43e 264
0a7de745 265 bzero(&infin_opt, sizeof(infin_opt));
39236c6e
A
266 infin_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
267 infin_opt.mdss_copt.mdss_len = len + csum_len;
268 infin_opt.mdss_copt.mdss_subtype = MPO_DSS;
269 infin_opt.mdss_copt.mdss_flags |= MDSS_M;
270 if (mp_tp->mpt_flags & MPTCPF_RECVD_MPFAIL) {
271 infin_opt.mdss_dsn = (u_int32_t)
272 MPTCP_DATASEQ_LOW32(mp_tp->mpt_dsn_at_csum_fail);
fe8ab488 273 infin_opt.mdss_subflow_seqn = mp_tp->mpt_ssn_at_csum_fail;
39236c6e 274 } else {
490019cf
A
275 /*
276 * If MPTCP fallback happens, but TFO succeeds, the data on the
277 * SYN does not belong to the MPTCP data sequence space.
278 */
279 if ((tp->t_tfo_stats & TFO_S_SYN_DATA_ACKED) &&
280 ((mp_tp->mpt_local_idsn + 1) == mp_tp->mpt_snduna)) {
281 infin_opt.mdss_subflow_seqn = 1;
282
5ba3f43e
A
283 mptcplog((LOG_DEBUG, "%s: idsn %llu snduna %llu \n",
284 __func__, mp_tp->mpt_local_idsn,
490019cf
A
285 mp_tp->mpt_snduna),
286 (MPTCP_SOCKET_DBG | MPTCP_SENDER_DBG),
287 MPTCP_LOGLVL_LOG);
288 } else {
5ba3f43e 289 infin_opt.mdss_subflow_seqn = tp->snd_una - tp->t_mpsub->mpts_iss;
490019cf 290 }
39236c6e
A
291 infin_opt.mdss_dsn = (u_int32_t)
292 MPTCP_DATASEQ_LOW32(mp_tp->mpt_snduna);
39236c6e 293 }
5ba3f43e 294
39236c6e 295 if ((infin_opt.mdss_dsn == 0) || (infin_opt.mdss_subflow_seqn == 0)) {
0a7de745 296 return optlen;
39236c6e
A
297 }
298 infin_opt.mdss_dsn = htonl(infin_opt.mdss_dsn);
299 infin_opt.mdss_subflow_seqn = htonl(infin_opt.mdss_subflow_seqn);
300 infin_opt.mdss_data_len = 0;
301
302 memcpy(opt + optlen, &infin_opt, len);
303 optlen += len;
304 if (csum_len != 0) {
305 /* The checksum field is set to 0 for infinite mapping */
306 uint16_t csum = 0;
307 memcpy(opt + optlen, &csum, csum_len);
308 optlen += csum_len;
309 }
310
5ba3f43e 311 mptcplog((LOG_DEBUG, "%s: dsn = %x, seq = %x len = %x\n", __func__,
3e170ce0
A
312 ntohl(infin_opt.mdss_dsn),
313 ntohl(infin_opt.mdss_subflow_seqn),
314 ntohs(infin_opt.mdss_data_len)),
315 (MPTCP_SOCKET_DBG | MPTCP_SENDER_DBG),
316 MPTCP_LOGLVL_LOG);
39236c6e 317
39236c6e
A
318 tp->t_mpflags |= TMPF_INFIN_SENT;
319 tcpstat.tcps_estab_fallback++;
0a7de745 320 return optlen;
39236c6e
A
321}
322
323
324static int
325mptcp_ok_to_fin(struct tcpcb *tp, u_int64_t dsn, u_int32_t datalen)
326{
5ba3f43e
A
327 struct mptcb *mp_tp = tptomptp(tp);
328
329 mpte_lock_assert_held(mp_tp->mpt_mpte);
39236c6e 330
39236c6e 331 dsn = (mp_tp->mpt_sndmax & MPTCP_DATASEQ_LOW32_MASK) | dsn;
0a7de745
A
332 if ((dsn + datalen) == mp_tp->mpt_sndmax) {
333 return 1;
334 }
5ba3f43e 335
0a7de745 336 return 0;
39236c6e
A
337}
338
39236c6e
A
339unsigned int
340mptcp_setup_opts(struct tcpcb *tp, int32_t off, u_char *opt,
0a7de745
A
341 unsigned int optlen, int flags, int len,
342 boolean_t *p_mptcp_acknow)
39236c6e
A
343{
344 struct inpcb *inp = (struct inpcb *)tp->t_inpcb;
345 struct socket *so = inp->inp_socket;
346 struct mptcb *mp_tp = tptomptp(tp);
347 boolean_t do_csum = FALSE;
348 boolean_t send_64bit_dsn = FALSE;
349 boolean_t send_64bit_ack = FALSE;
5ba3f43e 350 u_int32_t old_mpt_flags = tp->t_mpflags & TMPF_MPTCP_SIGNALS;
39236c6e 351
5ba3f43e 352 if (mptcp_enable == 0 || mp_tp == NULL || tp->t_state == TCPS_CLOSED) {
39236c6e 353 /* do nothing */
fe8ab488 354 goto ret_optlen;
39236c6e
A
355 }
356
5ba3f43e
A
357 mpte_lock_assert_held(mp_tp->mpt_mpte);
358
fe8ab488 359 if (mp_tp->mpt_flags & MPTCPF_CHECKSUM) {
39236c6e 360 do_csum = TRUE;
fe8ab488 361 }
39236c6e
A
362
363 /* tcp_output handles the SYN path separately */
fe8ab488
A
364 if (flags & TH_SYN) {
365 goto ret_optlen;
366 }
39236c6e
A
367
368 if ((MAX_TCPOPTLEN - optlen) <
0a7de745 369 sizeof(struct mptcp_mpcapable_opt_common)) {
5ba3f43e
A
370 mptcplog((LOG_ERR, "%s: no space left %d flags %x tp->t_mpflags %x len %d\n",
371 __func__, optlen, flags, tp->t_mpflags, len),
372 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
fe8ab488 373 goto ret_optlen;
39236c6e
A
374 }
375
39236c6e 376 if (tp->t_mpflags & TMPF_TCP_FALLBACK) {
0a7de745 377 if (tp->t_mpflags & TMPF_SND_MPFAIL) {
39236c6e 378 optlen = mptcp_send_mpfail(tp, opt, optlen);
0a7de745 379 } else if (!(tp->t_mpflags & TMPF_INFIN_SENT)) {
39236c6e 380 optlen = mptcp_send_infinite_mapping(tp, opt, optlen);
0a7de745 381 }
fe8ab488 382 goto ret_optlen;
39236c6e
A
383 }
384
5ba3f43e 385 if (tp->t_mpflags & TMPF_SND_KEYS) {
39236c6e
A
386 struct mptcp_mpcapable_opt_rsp1 mptcp_opt;
387 if ((MAX_TCPOPTLEN - optlen) <
0a7de745 388 sizeof(struct mptcp_mpcapable_opt_rsp1)) {
fe8ab488 389 goto ret_optlen;
0a7de745
A
390 }
391 bzero(&mptcp_opt, sizeof(struct mptcp_mpcapable_opt_rsp1));
39236c6e
A
392 mptcp_opt.mmc_common.mmco_kind = TCPOPT_MULTIPATH;
393 mptcp_opt.mmc_common.mmco_len =
0a7de745 394 sizeof(struct mptcp_mpcapable_opt_rsp1);
39236c6e 395 mptcp_opt.mmc_common.mmco_subtype = MPO_CAPABLE;
3e170ce0 396 mptcp_opt.mmc_common.mmco_version = mp_tp->mpt_version;
39236c6e
A
397 /* HMAC-SHA1 is the proposal */
398 mptcp_opt.mmc_common.mmco_flags |= MPCAP_PROPOSAL_SBIT;
0a7de745 399 if (mp_tp->mpt_flags & MPTCPF_CHECKSUM) {
39236c6e 400 mptcp_opt.mmc_common.mmco_flags |= MPCAP_CHECKSUM_CBIT;
0a7de745 401 }
5ba3f43e
A
402 mptcp_opt.mmc_localkey = mp_tp->mpt_localkey;
403 mptcp_opt.mmc_remotekey = mp_tp->mpt_remotekey;
39236c6e
A
404 memcpy(opt + optlen, &mptcp_opt, mptcp_opt.mmc_common.mmco_len);
405 optlen += mptcp_opt.mmc_common.mmco_len;
5ba3f43e 406 tp->t_mpflags &= ~TMPF_SND_KEYS;
39236c6e
A
407
408 if (!tp->t_mpuna) {
409 tp->t_mpuna = tp->snd_una;
410 } else {
411 /* its a retransmission of the MP_CAPABLE ACK */
412 }
fe8ab488 413 goto ret_optlen;
39236c6e
A
414 }
415
5ba3f43e 416 if (tp->t_mpflags & TMPF_SND_JACK) {
39236c6e
A
417 /* Do the ACK part */
418 optlen = mptcp_setup_join_ack_opts(tp, opt, optlen);
419 if (!tp->t_mpuna) {
420 tp->t_mpuna = tp->snd_una;
421 }
422 /* Start a timer to retransmit the ACK */
423 tp->t_timer[TCPT_JACK_RXMT] =
0a7de745 424 OFFSET_FROM_START(tp, tcp_jack_rxmt);
5ba3f43e
A
425
426 tp->t_mpflags &= ~TMPF_SND_JACK;
fe8ab488 427 goto ret_optlen;
39236c6e
A
428 }
429
0a7de745 430 if (!(tp->t_mpflags & TMPF_MPTCP_TRUE)) {
fe8ab488 431 goto ret_optlen;
0a7de745 432 }
39037602
A
433 /*
434 * From here on, all options are sent only if MPTCP_TRUE
fe8ab488
A
435 * or when data is sent early on as in Fast Join
436 */
39236c6e 437
39037602
A
438 if ((tp->t_mpflags & TMPF_MPTCP_TRUE) &&
439 (tp->t_mpflags & TMPF_SND_REM_ADDR)) {
0a7de745 440 int rem_opt_len = sizeof(struct mptcp_remaddr_opt);
39037602
A
441 if ((optlen + rem_opt_len) <= MAX_TCPOPTLEN) {
442 mptcp_send_remaddr_opt(tp,
443 (struct mptcp_remaddr_opt *)(opt + optlen));
444 optlen += rem_opt_len;
445 } else {
446 tp->t_mpflags &= ~TMPF_SND_REM_ADDR;
447 }
448 }
449
450 if (tp->t_mpflags & TMPF_SND_MPPRIO) {
451 optlen = mptcp_snd_mpprio(tp, opt, optlen);
452 }
453
5ba3f43e 454 if (mp_tp->mpt_flags & MPTCPF_SND_64BITDSN) {
39236c6e
A
455 send_64bit_dsn = TRUE;
456 }
0a7de745 457 if (mp_tp->mpt_flags & MPTCPF_SND_64BITACK) {
39236c6e 458 send_64bit_ack = TRUE;
0a7de745 459 }
39037602 460
0a7de745
A
461#define CHECK_OPTLEN { \
462 if ((MAX_TCPOPTLEN - optlen) < dssoptlen) { \
463 mptcplog((LOG_ERR, "%s: dssoptlen %d optlen %d \n", __func__, \
464 dssoptlen, optlen), \
465 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR); \
466 goto ret_optlen; \
467 } \
39236c6e
A
468}
469
0a7de745
A
470#define DO_FIN(dsn_opt) { \
471 int sndfin = 0; \
472 sndfin = mptcp_ok_to_fin(tp, dsn_opt.mdss_dsn, len); \
473 if (sndfin) { \
474 dsn_opt.mdss_copt.mdss_flags |= MDSS_F; \
475 dsn_opt.mdss_data_len += 1; \
476 if (do_csum) \
477 dss_csum = in_addword(dss_csum, 1); \
478 } \
39236c6e
A
479}
480
0a7de745
A
481#define CHECK_DATALEN { \
482 /* MPTCP socket does not support IP options */ \
483 if ((len + optlen + dssoptlen) > tp->t_maxopd) { \
484 mptcplog((LOG_ERR, "%s: nosp %d len %d opt %d %d %d\n", \
485 __func__, len, dssoptlen, optlen, \
486 tp->t_maxseg, tp->t_maxopd), \
487 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR); \
488 /* remove option length from payload len */ \
489 len = tp->t_maxopd - optlen - dssoptlen; \
490 } \
39236c6e
A
491}
492
493 if ((tp->t_mpflags & TMPF_SEND_DSN) &&
494 (send_64bit_dsn)) {
495 /*
496 * If there was the need to send 64-bit Data ACK along
497 * with 64-bit DSN, then 26 or 28 bytes would be used.
498 * With timestamps and NOOP padding that will cause
499 * overflow. Hence, in the rare event that both 64-bit
500 * DSN and 64-bit ACK have to be sent, delay the send of
501 * 64-bit ACK until our 64-bit DSN is acked with a 64-bit ack.
502 * XXX If this delay causes issue, remove the 2-byte padding.
503 */
504 struct mptcp_dss64_ack32_opt dsn_ack_opt;
0a7de745 505 unsigned int dssoptlen = sizeof(dsn_ack_opt);
5ba3f43e 506 uint16_t dss_csum;
39236c6e
A
507
508 if (do_csum) {
5ba3f43e 509 dssoptlen += 2;
39236c6e
A
510 }
511
512 CHECK_OPTLEN;
513
0a7de745 514 bzero(&dsn_ack_opt, sizeof(dsn_ack_opt));
39236c6e
A
515 dsn_ack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
516 dsn_ack_opt.mdss_copt.mdss_subtype = MPO_DSS;
5ba3f43e 517 dsn_ack_opt.mdss_copt.mdss_len = dssoptlen;
39236c6e
A
518 dsn_ack_opt.mdss_copt.mdss_flags |=
519 MDSS_M | MDSS_m | MDSS_A;
520
521 CHECK_DATALEN;
522
5ba3f43e 523 mptcp_output_getm_dsnmap64(so, off,
0a7de745
A
524 &dsn_ack_opt.mdss_dsn,
525 &dsn_ack_opt.mdss_subflow_seqn,
526 &dsn_ack_opt.mdss_data_len,
527 &dss_csum);
39236c6e
A
528
529 if ((dsn_ack_opt.mdss_data_len == 0) ||
530 (dsn_ack_opt.mdss_dsn == 0)) {
fe8ab488 531 goto ret_optlen;
39236c6e
A
532 }
533
534 if (tp->t_mpflags & TMPF_SEND_DFIN) {
535 DO_FIN(dsn_ack_opt);
536 }
537
39236c6e
A
538 dsn_ack_opt.mdss_ack =
539 htonl(MPTCP_DATAACK_LOW32(mp_tp->mpt_rcvnxt));
39236c6e
A
540
541 dsn_ack_opt.mdss_dsn = mptcp_hton64(dsn_ack_opt.mdss_dsn);
542 dsn_ack_opt.mdss_subflow_seqn = htonl(
0a7de745 543 dsn_ack_opt.mdss_subflow_seqn);
39236c6e 544 dsn_ack_opt.mdss_data_len = htons(
0a7de745 545 dsn_ack_opt.mdss_data_len);
39236c6e 546
0a7de745
A
547 memcpy(opt + optlen, &dsn_ack_opt, sizeof(dsn_ack_opt));
548 if (do_csum) {
549 *((uint16_t *)(void *)(opt + optlen + sizeof(dsn_ack_opt))) = dss_csum;
550 }
39236c6e 551
5ba3f43e 552 optlen += dssoptlen;
0a7de745 553 mptcplog((LOG_DEBUG, "%s: long DSS = %llx ACK = %llx \n", __func__,
3e170ce0
A
554 mptcp_ntoh64(dsn_ack_opt.mdss_dsn),
555 mptcp_ntoh64(dsn_ack_opt.mdss_ack)),
556 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_LOG);
39037602 557
39236c6e 558 tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
fe8ab488 559 goto ret_optlen;
39236c6e
A
560 }
561
562 if ((tp->t_mpflags & TMPF_SEND_DSN) &&
563 (!send_64bit_dsn) &&
0a7de745 564 !(tp->t_mpflags & TMPF_MPTCP_ACKNOW)) {
39236c6e 565 struct mptcp_dsn_opt dsn_opt;
0a7de745 566 unsigned int dssoptlen = sizeof(struct mptcp_dsn_opt);
5ba3f43e 567 uint16_t dss_csum;
39236c6e
A
568
569 if (do_csum) {
5ba3f43e 570 dssoptlen += 2;
39236c6e
A
571 }
572
573 CHECK_OPTLEN;
574
0a7de745 575 bzero(&dsn_opt, sizeof(dsn_opt));
39236c6e
A
576 dsn_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
577 dsn_opt.mdss_copt.mdss_subtype = MPO_DSS;
5ba3f43e 578 dsn_opt.mdss_copt.mdss_len = dssoptlen;
39236c6e
A
579 dsn_opt.mdss_copt.mdss_flags |= MDSS_M;
580
581 CHECK_DATALEN;
582
5ba3f43e 583 mptcp_output_getm_dsnmap32(so, off, &dsn_opt.mdss_dsn,
0a7de745
A
584 &dsn_opt.mdss_subflow_seqn,
585 &dsn_opt.mdss_data_len,
586 &dss_csum);
39236c6e
A
587
588 if ((dsn_opt.mdss_data_len == 0) ||
589 (dsn_opt.mdss_dsn == 0)) {
fe8ab488 590 goto ret_optlen;
39236c6e
A
591 }
592
593 if (tp->t_mpflags & TMPF_SEND_DFIN) {
594 DO_FIN(dsn_opt);
595 }
596
597 dsn_opt.mdss_dsn = htonl(dsn_opt.mdss_dsn);
598 dsn_opt.mdss_subflow_seqn = htonl(dsn_opt.mdss_subflow_seqn);
599 dsn_opt.mdss_data_len = htons(dsn_opt.mdss_data_len);
0a7de745
A
600 memcpy(opt + optlen, &dsn_opt, sizeof(dsn_opt));
601 if (do_csum) {
602 *((uint16_t *)(void *)(opt + optlen + sizeof(dsn_opt))) = dss_csum;
603 }
5ba3f43e
A
604
605 optlen += dssoptlen;
39236c6e 606 tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
fe8ab488 607 goto ret_optlen;
39236c6e
A
608 }
609
610 /* 32-bit Data ACK option */
611 if ((tp->t_mpflags & TMPF_MPTCP_ACKNOW) &&
612 (!send_64bit_ack) &&
613 !(tp->t_mpflags & TMPF_SEND_DSN) &&
614 !(tp->t_mpflags & TMPF_SEND_DFIN)) {
39236c6e 615 struct mptcp_data_ack_opt dack_opt;
5ba3f43e 616 unsigned int dssoptlen = 0;
39236c6e 617do_ack32_only:
0a7de745 618 dssoptlen = sizeof(dack_opt);
39236c6e
A
619
620 CHECK_OPTLEN;
621
5ba3f43e 622 bzero(&dack_opt, dssoptlen);
39236c6e 623 dack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
5ba3f43e 624 dack_opt.mdss_copt.mdss_len = dssoptlen;
39236c6e
A
625 dack_opt.mdss_copt.mdss_subtype = MPO_DSS;
626 dack_opt.mdss_copt.mdss_flags |= MDSS_A;
39236c6e
A
627 dack_opt.mdss_ack =
628 htonl(MPTCP_DATAACK_LOW32(mp_tp->mpt_rcvnxt));
5ba3f43e
A
629 memcpy(opt + optlen, &dack_opt, dssoptlen);
630 optlen += dssoptlen;
39236c6e
A
631 VERIFY(optlen <= MAX_TCPOPTLEN);
632 tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
fe8ab488 633 goto ret_optlen;
39236c6e
A
634 }
635
636 /* 64-bit Data ACK option */
637 if ((tp->t_mpflags & TMPF_MPTCP_ACKNOW) &&
638 (send_64bit_ack) &&
639 !(tp->t_mpflags & TMPF_SEND_DSN) &&
640 !(tp->t_mpflags & TMPF_SEND_DFIN)) {
641 struct mptcp_data_ack64_opt dack_opt;
5ba3f43e 642 unsigned int dssoptlen = 0;
39236c6e 643do_ack64_only:
0a7de745 644 dssoptlen = sizeof(dack_opt);
39236c6e
A
645
646 CHECK_OPTLEN;
647
5ba3f43e 648 bzero(&dack_opt, dssoptlen);
39236c6e 649 dack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
5ba3f43e 650 dack_opt.mdss_copt.mdss_len = dssoptlen;
39236c6e
A
651 dack_opt.mdss_copt.mdss_subtype = MPO_DSS;
652 dack_opt.mdss_copt.mdss_flags |= (MDSS_A | MDSS_a);
39236c6e
A
653 dack_opt.mdss_ack = mptcp_hton64(mp_tp->mpt_rcvnxt);
654 /*
655 * The other end should retransmit 64-bit DSN until it
656 * receives a 64-bit ACK.
657 */
658 mp_tp->mpt_flags &= ~MPTCPF_SND_64BITACK;
5ba3f43e
A
659 memcpy(opt + optlen, &dack_opt, dssoptlen);
660 optlen += dssoptlen;
39236c6e
A
661 VERIFY(optlen <= MAX_TCPOPTLEN);
662 tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
fe8ab488 663 goto ret_optlen;
39236c6e
A
664 }
665
666 /* 32-bit DSS+Data ACK option */
667 if ((tp->t_mpflags & TMPF_SEND_DSN) &&
668 (!send_64bit_dsn) &&
669 (!send_64bit_ack) &&
670 (tp->t_mpflags & TMPF_MPTCP_ACKNOW)) {
671 struct mptcp_dss_ack_opt dss_ack_opt;
0a7de745 672 unsigned int dssoptlen = sizeof(dss_ack_opt);
5ba3f43e 673 uint16_t dss_csum;
39236c6e 674
0a7de745 675 if (do_csum) {
5ba3f43e 676 dssoptlen += 2;
0a7de745 677 }
39236c6e
A
678
679 CHECK_OPTLEN;
680
0a7de745 681 bzero(&dss_ack_opt, sizeof(dss_ack_opt));
39236c6e 682 dss_ack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
5ba3f43e 683 dss_ack_opt.mdss_copt.mdss_len = dssoptlen;
39236c6e
A
684 dss_ack_opt.mdss_copt.mdss_subtype = MPO_DSS;
685 dss_ack_opt.mdss_copt.mdss_flags |= MDSS_A | MDSS_M;
39236c6e
A
686 dss_ack_opt.mdss_ack =
687 htonl(MPTCP_DATAACK_LOW32(mp_tp->mpt_rcvnxt));
39236c6e
A
688
689 CHECK_DATALEN;
690
5ba3f43e 691 mptcp_output_getm_dsnmap32(so, off, &dss_ack_opt.mdss_dsn,
0a7de745
A
692 &dss_ack_opt.mdss_subflow_seqn,
693 &dss_ack_opt.mdss_data_len,
694 &dss_csum);
39236c6e
A
695
696 if ((dss_ack_opt.mdss_data_len == 0) ||
697 (dss_ack_opt.mdss_dsn == 0)) {
698 goto do_ack32_only;
699 }
700
701 if (tp->t_mpflags & TMPF_SEND_DFIN) {
702 DO_FIN(dss_ack_opt);
703 }
704
705 dss_ack_opt.mdss_dsn = htonl(dss_ack_opt.mdss_dsn);
706 dss_ack_opt.mdss_subflow_seqn =
707 htonl(dss_ack_opt.mdss_subflow_seqn);
708 dss_ack_opt.mdss_data_len = htons(dss_ack_opt.mdss_data_len);
0a7de745
A
709 memcpy(opt + optlen, &dss_ack_opt, sizeof(dss_ack_opt));
710 if (do_csum) {
711 *((uint16_t *)(void *)(opt + optlen + sizeof(dss_ack_opt))) = dss_csum;
712 }
39236c6e 713
5ba3f43e 714 optlen += dssoptlen;
39236c6e 715
0a7de745 716 if (optlen > MAX_TCPOPTLEN) {
39236c6e 717 panic("optlen too large");
0a7de745 718 }
39236c6e 719 tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
fe8ab488 720 goto ret_optlen;
39236c6e
A
721 }
722
723 /* 32-bit DSS + 64-bit DACK option */
724 if ((tp->t_mpflags & TMPF_SEND_DSN) &&
725 (!send_64bit_dsn) &&
726 (send_64bit_ack) &&
727 (tp->t_mpflags & TMPF_MPTCP_ACKNOW)) {
728 struct mptcp_dss32_ack64_opt dss_ack_opt;
0a7de745 729 unsigned int dssoptlen = sizeof(dss_ack_opt);
5ba3f43e 730 uint16_t dss_csum;
39236c6e 731
0a7de745 732 if (do_csum) {
5ba3f43e 733 dssoptlen += 2;
0a7de745 734 }
39236c6e
A
735
736 CHECK_OPTLEN;
737
0a7de745 738 bzero(&dss_ack_opt, sizeof(dss_ack_opt));
39236c6e 739 dss_ack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
5ba3f43e 740 dss_ack_opt.mdss_copt.mdss_len = dssoptlen;
39236c6e
A
741 dss_ack_opt.mdss_copt.mdss_subtype = MPO_DSS;
742 dss_ack_opt.mdss_copt.mdss_flags |= MDSS_M | MDSS_A | MDSS_a;
39236c6e
A
743 dss_ack_opt.mdss_ack =
744 mptcp_hton64(mp_tp->mpt_rcvnxt);
39236c6e
A
745
746 CHECK_DATALEN;
747
5ba3f43e 748 mptcp_output_getm_dsnmap32(so, off, &dss_ack_opt.mdss_dsn,
0a7de745
A
749 &dss_ack_opt.mdss_subflow_seqn,
750 &dss_ack_opt.mdss_data_len,
751 &dss_csum);
39236c6e
A
752
753 if ((dss_ack_opt.mdss_data_len == 0) ||
754 (dss_ack_opt.mdss_dsn == 0)) {
755 goto do_ack64_only;
756 }
757
758 if (tp->t_mpflags & TMPF_SEND_DFIN) {
759 DO_FIN(dss_ack_opt);
760 }
761
762 dss_ack_opt.mdss_dsn = htonl(dss_ack_opt.mdss_dsn);
763 dss_ack_opt.mdss_subflow_seqn =
764 htonl(dss_ack_opt.mdss_subflow_seqn);
765 dss_ack_opt.mdss_data_len = htons(dss_ack_opt.mdss_data_len);
0a7de745
A
766 memcpy(opt + optlen, &dss_ack_opt, sizeof(dss_ack_opt));
767 if (do_csum) {
768 *((uint16_t *)(void *)(opt + optlen + sizeof(dss_ack_opt))) = dss_csum;
769 }
39236c6e 770
5ba3f43e 771 optlen += dssoptlen;
39236c6e 772
0a7de745 773 if (optlen > MAX_TCPOPTLEN) {
39236c6e 774 panic("optlen too large");
0a7de745 775 }
39236c6e 776 tp->t_mpflags &= ~TMPF_MPTCP_ACKNOW;
fe8ab488 777 goto ret_optlen;
39236c6e
A
778 }
779
780 if (tp->t_mpflags & TMPF_SEND_DFIN) {
a39ff7e2 781 unsigned int dssoptlen = sizeof(struct mptcp_dss_ack_opt);
39236c6e 782 struct mptcp_dss_ack_opt dss_ack_opt;
a39ff7e2
A
783 uint16_t dss_csum;
784
785 if (do_csum) {
786 uint64_t dss_val = mptcp_hton64(mp_tp->mpt_sndmax - 1);
787 uint16_t dlen = htons(1);
788 uint32_t sseq = 0;
789 uint32_t sum;
790
39236c6e 791
5ba3f43e 792 dssoptlen += 2;
39236c6e 793
a39ff7e2
A
794 sum = in_pseudo64(dss_val, sseq, dlen);
795 ADDCARRY(sum);
796 dss_csum = ~sum & 0xffff;
797 }
798
39236c6e
A
799 CHECK_OPTLEN;
800
0a7de745 801 bzero(&dss_ack_opt, sizeof(dss_ack_opt));
39236c6e 802
fe8ab488
A
803 /*
804 * Data FIN occupies one sequence space.
805 * Don't send it if it has been Acked.
806 */
a39ff7e2 807 if ((mp_tp->mpt_sndnxt + 1 != mp_tp->mpt_sndmax) ||
0a7de745 808 (mp_tp->mpt_snduna == mp_tp->mpt_sndmax)) {
fe8ab488 809 goto ret_optlen;
0a7de745 810 }
39236c6e
A
811
812 dss_ack_opt.mdss_copt.mdss_kind = TCPOPT_MULTIPATH;
5ba3f43e 813 dss_ack_opt.mdss_copt.mdss_len = dssoptlen;
39236c6e
A
814 dss_ack_opt.mdss_copt.mdss_subtype = MPO_DSS;
815 dss_ack_opt.mdss_copt.mdss_flags |= MDSS_A | MDSS_M | MDSS_F;
816 dss_ack_opt.mdss_ack =
817 htonl(MPTCP_DATAACK_LOW32(mp_tp->mpt_rcvnxt));
818 dss_ack_opt.mdss_dsn =
a39ff7e2 819 htonl(MPTCP_DATASEQ_LOW32(mp_tp->mpt_sndmax - 1));
39236c6e
A
820 dss_ack_opt.mdss_subflow_seqn = 0;
821 dss_ack_opt.mdss_data_len = 1;
822 dss_ack_opt.mdss_data_len = htons(dss_ack_opt.mdss_data_len);
0a7de745
A
823 memcpy(opt + optlen, &dss_ack_opt, sizeof(dss_ack_opt));
824 if (do_csum) {
825 *((uint16_t *)(void *)(opt + optlen + sizeof(dss_ack_opt))) = dss_csum;
826 }
a39ff7e2 827
5ba3f43e 828 optlen += dssoptlen;
39236c6e
A
829 }
830
fe8ab488 831ret_optlen:
0a7de745 832 if (TRUE == *p_mptcp_acknow) {
fe8ab488 833 VERIFY(old_mpt_flags != 0);
5ba3f43e 834 u_int32_t new_mpt_flags = tp->t_mpflags & TMPF_MPTCP_SIGNALS;
fe8ab488
A
835
836 /*
837 * If none of the above mpflags were acted on by
838 * this routine, reset these flags and set p_mptcp_acknow
839 * to false.
5ba3f43e 840 *
39037602 841 * XXX The reset value of p_mptcp_acknow can be used
fe8ab488
A
842 * to communicate tcp_output to NOT send a pure ack without any
843 * MPTCP options as it will be treated as a dup ack.
844 * Since the instances of mptcp_setup_opts not acting on
845 * these options are mostly corner cases and sending a dup
846 * ack here would only have an impact if the system
847 * has sent consecutive dup acks before this false one,
848 * we haven't modified the logic in tcp_output to avoid
849 * that.
850 */
5ba3f43e
A
851 if (old_mpt_flags == new_mpt_flags) {
852 tp->t_mpflags &= ~TMPF_MPTCP_SIGNALS;
fe8ab488 853 *p_mptcp_acknow = FALSE;
5ba3f43e 854 mptcplog((LOG_DEBUG, "%s: no action \n", __func__),
0a7de745 855 MPTCP_SENDER_DBG, MPTCP_LOGLVL_LOG);
3e170ce0 856 } else {
5ba3f43e
A
857 mptcplog((LOG_DEBUG, "%s: acknow set, old flags %x new flags %x \n",
858 __func__, old_mpt_flags, new_mpt_flags),
3e170ce0 859 MPTCP_SENDER_DBG, MPTCP_LOGLVL_LOG);
fe8ab488
A
860 }
861 }
862
863 return optlen;
39236c6e
A
864}
865
866/*
867 * MPTCP Options Input Processing
868 */
869
3e170ce0
A
870static int
871mptcp_sanitize_option(struct tcpcb *tp, int mptcp_subtype)
872{
873 struct mptcb *mp_tp = tptomptp(tp);
874 int ret = 1;
875
876 if (mp_tp == NULL) {
5ba3f43e
A
877 mptcplog((LOG_ERR, "%s: NULL mpsocket \n", __func__),
878 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
0a7de745 879 return 0;
3e170ce0
A
880 }
881
882 switch (mptcp_subtype) {
0a7de745
A
883 case MPO_CAPABLE:
884 break;
885 case MPO_JOIN: /* fall through */
886 case MPO_DSS: /* fall through */
887 case MPO_FASTCLOSE: /* fall through */
888 case MPO_FAIL: /* fall through */
889 case MPO_REMOVE_ADDR: /* fall through */
890 case MPO_ADD_ADDR: /* fall through */
891 case MPO_PRIO: /* fall through */
892 if (mp_tp->mpt_state < MPTCPS_ESTABLISHED) {
3e170ce0 893 ret = 0;
0a7de745
A
894 }
895 break;
896 default:
897 ret = 0;
898 mptcplog((LOG_ERR, "%s: type = %d \n", __func__,
899 mptcp_subtype),
900 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
901 break;
3e170ce0 902 }
0a7de745 903 return ret;
3e170ce0 904}
39236c6e
A
905
906static int
3e170ce0 907mptcp_valid_mpcapable_common_opt(u_char *cp)
39236c6e
A
908{
909 struct mptcp_mpcapable_opt_common *rsp =
910 (struct mptcp_mpcapable_opt_common *)cp;
911
912 /* mmco_kind, mmco_len and mmco_subtype are validated before */
913
0a7de745
A
914 if (!(rsp->mmco_flags & MPCAP_PROPOSAL_SBIT)) {
915 return 0;
916 }
39236c6e
A
917
918 if (rsp->mmco_flags & (MPCAP_BBIT | MPCAP_CBIT | MPCAP_DBIT |
0a7de745
A
919 MPCAP_EBIT | MPCAP_FBIT | MPCAP_GBIT)) {
920 return 0;
921 }
39236c6e 922
0a7de745 923 return 1;
39236c6e
A
924}
925
926
927static void
928mptcp_do_mpcapable_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th,
929 int optlen)
930{
39236c6e
A
931 struct mptcp_mpcapable_opt_rsp *rsp = NULL;
932 struct mptcb *mp_tp = tptomptp(tp);
933
5ba3f43e
A
934 mpte_lock_assert_held(mp_tp->mpt_mpte);
935
39037602 936 /* Only valid on SYN/ACK */
0a7de745 937 if ((th->th_flags & (TH_SYN | TH_ACK)) != (TH_SYN | TH_ACK)) {
39037602 938 return;
0a7de745 939 }
39236c6e 940
39236c6e 941 /* Validate the kind, len, flags */
3e170ce0 942 if (mptcp_valid_mpcapable_common_opt(cp) != 1) {
39236c6e
A
943 tcpstat.tcps_invalid_mpcap++;
944 return;
945 }
946
39037602 947 /* handle SYN/ACK retransmission by acknowledging with ACK */
0a7de745 948 if (mp_tp->mpt_state >= MPTCPS_ESTABLISHED) {
39037602 949 return;
0a7de745 950 }
3e170ce0 951
39037602 952 /* A SYN/ACK contains peer's key and flags */
0a7de745 953 if (optlen != sizeof(struct mptcp_mpcapable_opt_rsp)) {
39037602 954 /* complain */
5ba3f43e 955 mptcplog((LOG_ERR, "%s: SYN_ACK optlen = %d, sizeof mp opt = %lu \n",
39037602 956 __func__, optlen,
0a7de745 957 sizeof(struct mptcp_mpcapable_opt_rsp)),
39037602
A
958 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
959 tcpstat.tcps_invalid_mpcap++;
960 return;
961 }
39236c6e 962
39037602
A
963 /*
964 * If checksum flag is set, enable MPTCP checksum, even if
965 * it was not negotiated on the first SYN.
966 */
967 if (((struct mptcp_mpcapable_opt_common *)cp)->mmco_flags &
0a7de745 968 MPCAP_CHECKSUM_CBIT) {
39037602 969 mp_tp->mpt_flags |= MPTCPF_CHECKSUM;
0a7de745 970 }
39236c6e 971
39037602 972 rsp = (struct mptcp_mpcapable_opt_rsp *)cp;
39037602
A
973 mp_tp->mpt_remotekey = rsp->mmc_localkey;
974 /* For now just downgrade to the peer's version */
975 mp_tp->mpt_peer_version = rsp->mmc_common.mmco_version;
976 if (rsp->mmc_common.mmco_version < mp_tp->mpt_version) {
977 mp_tp->mpt_version = rsp->mmc_common.mmco_version;
978 tcpstat.tcps_mp_verdowngrade++;
979 }
980 if (mptcp_init_remote_parms(mp_tp) != 0) {
981 tcpstat.tcps_invalid_mpcap++;
39037602 982 return;
39236c6e 983 }
39037602 984 tcp_heuristic_mptcp_success(tp);
5ba3f43e 985 tp->t_mpflags |= (TMPF_SND_KEYS | TMPF_MPTCP_TRUE);
39236c6e
A
986}
987
988
989static void
990mptcp_do_mpjoin_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th, int optlen)
991{
0a7de745
A
992#define MPTCP_JOPT_ERROR_PATH(tp) { \
993 tp->t_mpflags |= TMPF_RESET; \
994 tcpstat.tcps_invalid_joins++; \
995 if (tp->t_inpcb->inp_socket != NULL) { \
996 soevent(tp->t_inpcb->inp_socket, \
997 SO_FILT_HINT_LOCKED | SO_FILT_HINT_MUSTRST); \
998 } \
39236c6e
A
999}
1000 int error = 0;
39037602
A
1001 struct mptcp_mpjoin_opt_rsp *join_rsp =
1002 (struct mptcp_mpjoin_opt_rsp *)cp;
39236c6e 1003
39037602 1004 /* Only valid on SYN/ACK */
0a7de745 1005 if ((th->th_flags & (TH_SYN | TH_ACK)) != (TH_SYN | TH_ACK)) {
39236c6e 1006 return;
0a7de745 1007 }
39236c6e 1008
0a7de745 1009 if (optlen != sizeof(struct mptcp_mpjoin_opt_rsp)) {
5ba3f43e
A
1010 mptcplog((LOG_ERR, "%s: SYN_ACK: unexpected optlen = %d mp "
1011 "option = %lu\n", __func__, optlen,
0a7de745 1012 sizeof(struct mptcp_mpjoin_opt_rsp)),
39037602
A
1013 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
1014 tp->t_mpflags &= ~TMPF_PREESTABLISHED;
1015 /* send RST and close */
1016 MPTCP_JOPT_ERROR_PATH(tp);
1017 return;
1018 }
39236c6e 1019
39037602
A
1020 mptcp_set_raddr_rand(tp->t_local_aid, tptomptp(tp),
1021 join_rsp->mmjo_addr_id, join_rsp->mmjo_rand);
1022 error = mptcp_validate_join_hmac(tp,
1023 (u_char*)&join_rsp->mmjo_mac, SHA1_TRUNCATED);
1024 if (error) {
5ba3f43e 1025 mptcplog((LOG_ERR, "%s: SYN_ACK error = %d \n", __func__, error),
39037602 1026 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR);
39236c6e 1027 tp->t_mpflags &= ~TMPF_PREESTABLISHED;
39037602
A
1028 /* send RST and close */
1029 MPTCP_JOPT_ERROR_PATH(tp);
1030 return;
39236c6e 1031 }
5ba3f43e 1032 tp->t_mpflags |= (TMPF_SENT_JOIN | TMPF_SND_JACK);
39236c6e
A
1033}
1034
1035static int
1036mptcp_validate_join_hmac(struct tcpcb *tp, u_char* hmac, int mac_len)
1037{
1038 u_char digest[SHA1_RESULTLEN] = {0};
5ba3f43e 1039 struct mptcb *mp_tp = tptomptp(tp);
39236c6e
A
1040 u_int32_t rem_rand, loc_rand;
1041
5ba3f43e 1042 mpte_lock_assert_held(mp_tp->mpt_mpte);
39236c6e
A
1043
1044 rem_rand = loc_rand = 0;
1045
39236c6e 1046 mptcp_get_rands(tp->t_local_aid, mp_tp, &loc_rand, &rem_rand);
0a7de745
A
1047 if ((rem_rand == 0) || (loc_rand == 0)) {
1048 return -1;
1049 }
39236c6e 1050
5ba3f43e
A
1051 mptcp_hmac_sha1(mp_tp->mpt_remotekey, mp_tp->mpt_localkey, rem_rand, loc_rand,
1052 digest);
39236c6e 1053
0a7de745
A
1054 if (bcmp(digest, hmac, mac_len) == 0) {
1055 return 0; /* matches */
1056 } else {
39236c6e 1057 printf("%s: remote key %llx local key %llx remote rand %x "
5ba3f43e 1058 "local rand %x \n", __func__, mp_tp->mpt_remotekey, mp_tp->mpt_localkey,
39236c6e 1059 rem_rand, loc_rand);
0a7de745 1060 return -1;
39236c6e
A
1061 }
1062}
1063
5ba3f43e
A
1064/*
1065 * Update the mptcb send state variables, but the actual sbdrop occurs
1066 * in MPTCP layer
1067 */
1068void
1069mptcp_data_ack_rcvd(struct mptcb *mp_tp, struct tcpcb *tp, u_int64_t full_dack)
1070{
a39ff7e2 1071 u_int64_t acked = full_dack - mp_tp->mpt_snduna;
5ba3f43e
A
1072
1073 if (acked) {
1074 struct socket *mp_so = mptetoso(mp_tp->mpt_mpte);
1075
1076 if (acked > mp_so->so_snd.sb_cc) {
1077 if (acked > mp_so->so_snd.sb_cc + 1 ||
0a7de745 1078 mp_tp->mpt_state < MPTCPS_FIN_WAIT_1) {
5ba3f43e 1079 mptcplog((LOG_ERR, "%s: acked %u, sb_cc %u full %u suna %u state %u\n",
0a7de745
A
1080 __func__, (uint32_t)acked, mp_so->so_snd.sb_cc,
1081 (uint32_t)full_dack, (uint32_t)mp_tp->mpt_snduna,
1082 mp_tp->mpt_state),
1083 MPTCP_RECEIVER_DBG, MPTCP_LOGLVL_ERR);
1084 }
5ba3f43e
A
1085
1086 sbdrop(&mp_so->so_snd, (int)mp_so->so_snd.sb_cc);
1087 } else {
1088 sbdrop(&mp_so->so_snd, acked);
1089 }
1090
1091 mp_tp->mpt_snduna += acked;
1092 /* In degraded mode, we may get some Data ACKs */
1093 if ((tp->t_mpflags & TMPF_TCP_FALLBACK) &&
1094 !(mp_tp->mpt_flags & MPTCPF_POST_FALLBACK_SYNC) &&
1095 MPTCP_SEQ_GT(mp_tp->mpt_sndnxt, mp_tp->mpt_snduna)) {
1096 /* bring back sndnxt to retransmit MPTCP data */
1097 mp_tp->mpt_sndnxt = mp_tp->mpt_dsn_at_csum_fail;
1098 mp_tp->mpt_flags |= MPTCPF_POST_FALLBACK_SYNC;
1099 tp->t_inpcb->inp_socket->so_flags1 |=
1100 SOF1_POST_FALLBACK_SYNC;
1101 }
1102
1103 mptcp_clean_reinjectq(mp_tp->mpt_mpte);
1104
1105 sowwakeup(mp_so);
1106 }
1107 if (full_dack == mp_tp->mpt_sndmax &&
1108 mp_tp->mpt_state >= MPTCPS_FIN_WAIT_1) {
1109 mptcp_close_fsm(mp_tp, MPCE_RECV_DATA_ACK);
1110 tp->t_mpflags &= ~TMPF_SEND_DFIN;
1111 }
1112}
1113
1114void
d9a64523 1115mptcp_update_window_wakeup(struct tcpcb *tp)
5ba3f43e
A
1116{
1117 struct mptcb *mp_tp = tptomptp(tp);
1118
1119 mpte_lock_assert_held(mp_tp->mpt_mpte);
1120
d9a64523
A
1121 if (mp_tp->mpt_flags & MPTCPF_FALLBACK_TO_TCP) {
1122 mp_tp->mpt_sndwnd = tp->snd_wnd;
1123 mp_tp->mpt_sndwl1 = mp_tp->mpt_rcvnxt;
1124 mp_tp->mpt_sndwl2 = mp_tp->mpt_snduna;
1125 }
5ba3f43e
A
1126
1127 sowwakeup(tp->t_inpcb->inp_socket);
1128}
1129
1130static void
d9a64523 1131mptcp_update_window(struct mptcb *mp_tp, u_int64_t ack, u_int64_t seq, u_int32_t tiwin)
5ba3f43e 1132{
d9a64523
A
1133 if (SEQ_LT(mp_tp->mpt_sndwl1, seq) ||
1134 (mp_tp->mpt_sndwl1 == seq &&
0a7de745
A
1135 (SEQ_LT(mp_tp->mpt_sndwl2, ack) ||
1136 (mp_tp->mpt_sndwl2 == ack && tiwin > mp_tp->mpt_sndwnd)))) {
5ba3f43e
A
1137 mp_tp->mpt_sndwnd = tiwin;
1138 mp_tp->mpt_sndwl1 = seq;
1139 mp_tp->mpt_sndwl2 = ack;
5ba3f43e
A
1140 }
1141}
1142
39236c6e 1143static void
5ba3f43e 1144mptcp_do_dss_opt_ack_meat(u_int64_t full_dack, u_int64_t full_dsn,
0a7de745 1145 struct tcpcb *tp, u_int32_t tiwin)
39236c6e
A
1146{
1147 struct mptcb *mp_tp = tptomptp(tp);
1148 int close_notify = 0;
1149
39037602
A
1150 tp->t_mpflags |= TMPF_RCVD_DACK;
1151
39236c6e
A
1152 if (MPTCP_SEQ_LEQ(full_dack, mp_tp->mpt_sndmax) &&
1153 MPTCP_SEQ_GEQ(full_dack, mp_tp->mpt_snduna)) {
1154 mptcp_data_ack_rcvd(mp_tp, tp, full_dack);
0a7de745 1155 if (mp_tp->mpt_state > MPTCPS_FIN_WAIT_2) {
39236c6e 1156 close_notify = 1;
0a7de745 1157 }
39236c6e
A
1158 if (mp_tp->mpt_flags & MPTCPF_RCVD_64BITACK) {
1159 mp_tp->mpt_flags &= ~MPTCPF_RCVD_64BITACK;
1160 mp_tp->mpt_flags &= ~MPTCPF_SND_64BITDSN;
1161 }
490019cf 1162 mptcp_notify_mpready(tp->t_inpcb->inp_socket);
0a7de745 1163 if (close_notify) {
490019cf 1164 mptcp_notify_close(tp->t_inpcb->inp_socket);
0a7de745 1165 }
39236c6e 1166 } else {
d9a64523 1167 os_log_error(mptcp_log_handle,
0a7de745
A
1168 "%s: unexpected dack %u snduna %u sndmax %u\n",
1169 __func__, (u_int32_t)full_dack,
1170 (u_int32_t)mp_tp->mpt_snduna,
1171 (u_int32_t)mp_tp->mpt_sndmax);
39236c6e 1172 }
5ba3f43e
A
1173
1174 mptcp_update_window(mp_tp, full_dack, full_dsn, tiwin);
39236c6e
A
1175}
1176
1177static void
5ba3f43e 1178mptcp_do_dss_opt_meat(u_char *cp, struct tcpcb *tp, struct tcphdr *th)
39236c6e
A
1179{
1180 struct mptcp_dss_copt *dss_rsp = (struct mptcp_dss_copt *)cp;
1181 u_int64_t full_dack = 0;
5ba3f43e 1182 u_int32_t tiwin = th->th_win << tp->snd_scale;
39236c6e
A
1183 struct mptcb *mp_tp = tptomptp(tp);
1184 int csum_len = 0;
1185
0a7de745
A
1186#define MPTCP_DSS_OPT_SZ_CHK(len, expected_len) { \
1187 if (len != expected_len) { \
1188 mptcplog((LOG_ERR, "%s: bad len = %d dss: %x \n", __func__, \
1189 len, dss_rsp->mdss_flags), \
1190 (MPTCP_SOCKET_DBG|MPTCP_RECEIVER_DBG), \
1191 MPTCP_LOGLVL_LOG); \
1192 return; \
1193 } \
39236c6e 1194}
39236c6e 1195
0a7de745 1196 if (mp_tp->mpt_flags & MPTCPF_CHECKSUM) {
39236c6e 1197 csum_len = 2;
0a7de745 1198 }
39236c6e 1199
0a7de745 1200 dss_rsp->mdss_flags &= (MDSS_A | MDSS_a | MDSS_M | MDSS_m);
39236c6e 1201 switch (dss_rsp->mdss_flags) {
0a7de745
A
1202 case (MDSS_M):
1203 {
1204 /* 32-bit DSS, No Data ACK */
1205 struct mptcp_dsn_opt *dss_rsp1;
1206 dss_rsp1 = (struct mptcp_dsn_opt *)cp;
1207
1208 MPTCP_DSS_OPT_SZ_CHK(dss_rsp1->mdss_copt.mdss_len,
1209 sizeof(struct mptcp_dsn_opt) + csum_len);
1210 if (csum_len == 0) {
1211 mptcp_update_dss_rcv_state(dss_rsp1, tp, 0);
1212 } else {
1213 mptcp_update_dss_rcv_state(dss_rsp1, tp,
1214 *(uint16_t *)(void *)(cp +
1215 (dss_rsp1->mdss_copt.mdss_len - csum_len)));
39236c6e 1216 }
0a7de745
A
1217 break;
1218 }
1219 case (MDSS_A):
1220 {
1221 /* 32-bit Data ACK, no DSS */
1222 struct mptcp_data_ack_opt *dack_opt;
1223 dack_opt = (struct mptcp_data_ack_opt *)cp;
1224
1225 MPTCP_DSS_OPT_SZ_CHK(dack_opt->mdss_copt.mdss_len,
1226 sizeof(struct mptcp_data_ack_opt));
1227
1228 u_int32_t dack = dack_opt->mdss_ack;
1229 NTOHL(dack);
1230 MPTCP_EXTEND_DSN(mp_tp->mpt_snduna, dack, full_dack);
1231 mptcp_do_dss_opt_ack_meat(full_dack, mp_tp->mpt_sndwl1, tp, tiwin);
1232 break;
1233 }
1234 case (MDSS_M | MDSS_A):
1235 {
1236 /* 32-bit Data ACK + 32-bit DSS */
1237 struct mptcp_dss_ack_opt *dss_ack_rsp;
1238 dss_ack_rsp = (struct mptcp_dss_ack_opt *)cp;
1239 u_int64_t full_dsn;
1240 uint16_t csum = 0;
39236c6e 1241
0a7de745
A
1242 MPTCP_DSS_OPT_SZ_CHK(dss_ack_rsp->mdss_copt.mdss_len,
1243 sizeof(struct mptcp_dss_ack_opt) + csum_len);
39236c6e 1244
0a7de745
A
1245 u_int32_t dack = dss_ack_rsp->mdss_ack;
1246 NTOHL(dack);
1247 MPTCP_EXTEND_DSN(mp_tp->mpt_snduna, dack, full_dack);
39236c6e 1248
0a7de745
A
1249 NTOHL(dss_ack_rsp->mdss_dsn);
1250 NTOHL(dss_ack_rsp->mdss_subflow_seqn);
1251 NTOHS(dss_ack_rsp->mdss_data_len);
1252 MPTCP_EXTEND_DSN(mp_tp->mpt_rcvnxt, dss_ack_rsp->mdss_dsn, full_dsn);
5ba3f43e 1253
0a7de745 1254 mptcp_do_dss_opt_ack_meat(full_dack, full_dsn, tp, tiwin);
5ba3f43e 1255
0a7de745
A
1256 if (csum_len != 0) {
1257 csum = *(uint16_t *)(void *)(cp + (dss_ack_rsp->mdss_copt.mdss_len - csum_len));
39236c6e 1258 }
39236c6e 1259
0a7de745
A
1260 mptcp_update_rcv_state_meat(mp_tp, tp,
1261 full_dsn,
1262 dss_ack_rsp->mdss_subflow_seqn,
1263 dss_ack_rsp->mdss_data_len,
1264 csum);
1265 break;
1266 }
1267 case (MDSS_M | MDSS_m):
1268 {
1269 /* 64-bit DSS , No Data ACK */
1270 struct mptcp_dsn64_opt *dsn64;
1271 dsn64 = (struct mptcp_dsn64_opt *)cp;
1272 u_int64_t full_dsn;
1273 uint16_t csum = 0;
1274
1275 MPTCP_DSS_OPT_SZ_CHK(dsn64->mdss_copt.mdss_len,
1276 sizeof(struct mptcp_dsn64_opt) + csum_len);
39236c6e 1277
0a7de745 1278 mp_tp->mpt_flags |= MPTCPF_SND_64BITACK;
39236c6e 1279
0a7de745
A
1280 full_dsn = mptcp_ntoh64(dsn64->mdss_dsn);
1281 NTOHL(dsn64->mdss_subflow_seqn);
1282 NTOHS(dsn64->mdss_data_len);
1283
1284 if (csum_len != 0) {
1285 csum = *(uint16_t *)(void *)(cp + dsn64->mdss_copt.mdss_len - csum_len);
39236c6e 1286 }
39236c6e 1287
0a7de745
A
1288 mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1289 dsn64->mdss_subflow_seqn,
1290 dsn64->mdss_data_len,
1291 csum);
1292 break;
1293 }
1294 case (MDSS_A | MDSS_a):
1295 {
1296 /* 64-bit Data ACK, no DSS */
1297 struct mptcp_data_ack64_opt *dack64;
1298 dack64 = (struct mptcp_data_ack64_opt *)cp;
1299
1300 MPTCP_DSS_OPT_SZ_CHK(dack64->mdss_copt.mdss_len,
1301 sizeof(struct mptcp_data_ack64_opt));
39236c6e 1302
0a7de745 1303 mp_tp->mpt_flags |= MPTCPF_RCVD_64BITACK;
5ba3f43e 1304
0a7de745
A
1305 full_dack = mptcp_ntoh64(dack64->mdss_ack);
1306 mptcp_do_dss_opt_ack_meat(full_dack, mp_tp->mpt_sndwl1, tp, tiwin);
1307 break;
1308 }
1309 case (MDSS_M | MDSS_m | MDSS_A):
1310 {
1311 /* 64-bit DSS + 32-bit Data ACK */
1312 struct mptcp_dss64_ack32_opt *dss_ack_rsp;
1313 dss_ack_rsp = (struct mptcp_dss64_ack32_opt *)cp;
1314 u_int64_t full_dsn;
1315 uint16_t csum = 0;
5ba3f43e 1316
0a7de745
A
1317 MPTCP_DSS_OPT_SZ_CHK(dss_ack_rsp->mdss_copt.mdss_len,
1318 sizeof(struct mptcp_dss64_ack32_opt) + csum_len);
5ba3f43e 1319
0a7de745
A
1320 u_int32_t dack = dss_ack_rsp->mdss_ack;
1321 NTOHL(dack);
1322 mp_tp->mpt_flags |= MPTCPF_SND_64BITACK;
1323 MPTCP_EXTEND_DSN(mp_tp->mpt_snduna, dack, full_dack);
5ba3f43e 1324
0a7de745
A
1325 full_dsn = mptcp_ntoh64(dss_ack_rsp->mdss_dsn);
1326 NTOHL(dss_ack_rsp->mdss_subflow_seqn);
1327 NTOHS(dss_ack_rsp->mdss_data_len);
5ba3f43e 1328
0a7de745
A
1329 mptcp_do_dss_opt_ack_meat(full_dack, full_dsn, tp, tiwin);
1330
1331 if (csum_len != 0) {
1332 csum = *(uint16_t *)(void *)(cp + dss_ack_rsp->mdss_copt.mdss_len - csum_len);
39236c6e 1333 }
0a7de745
A
1334
1335 mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1336 dss_ack_rsp->mdss_subflow_seqn,
1337 dss_ack_rsp->mdss_data_len,
1338 csum);
1339
1340 break;
1341 }
1342 case (MDSS_M | MDSS_A | MDSS_a):
1343 {
1344 /* 32-bit DSS + 64-bit Data ACK */
1345 struct mptcp_dss32_ack64_opt *dss32_ack64_opt;
1346 dss32_ack64_opt = (struct mptcp_dss32_ack64_opt *)cp;
1347 u_int64_t full_dsn;
1348
1349 MPTCP_DSS_OPT_SZ_CHK(
1350 dss32_ack64_opt->mdss_copt.mdss_len,
1351 sizeof(struct mptcp_dss32_ack64_opt) + csum_len);
1352
1353 full_dack = mptcp_ntoh64(dss32_ack64_opt->mdss_ack);
1354 NTOHL(dss32_ack64_opt->mdss_dsn);
1355 mp_tp->mpt_flags |= MPTCPF_RCVD_64BITACK;
1356 MPTCP_EXTEND_DSN(mp_tp->mpt_rcvnxt,
1357 dss32_ack64_opt->mdss_dsn, full_dsn);
1358 NTOHL(dss32_ack64_opt->mdss_subflow_seqn);
1359 NTOHS(dss32_ack64_opt->mdss_data_len);
1360
1361 mptcp_do_dss_opt_ack_meat(full_dack, full_dsn, tp, tiwin);
1362 if (csum_len == 0) {
1363 mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1364 dss32_ack64_opt->mdss_subflow_seqn,
1365 dss32_ack64_opt->mdss_data_len, 0);
1366 } else {
1367 mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1368 dss32_ack64_opt->mdss_subflow_seqn,
1369 dss32_ack64_opt->mdss_data_len,
1370 *(uint16_t *)(void *)(cp +
1371 dss32_ack64_opt->mdss_copt.mdss_len -
1372 csum_len));
39236c6e 1373 }
0a7de745
A
1374 break;
1375 }
1376 case (MDSS_M | MDSS_m | MDSS_A | MDSS_a):
1377 {
1378 /* 64-bit DSS + 64-bit Data ACK */
1379 struct mptcp_dss64_ack64_opt *dss64_ack64;
1380 dss64_ack64 = (struct mptcp_dss64_ack64_opt *)cp;
1381 u_int64_t full_dsn;
1382
1383 MPTCP_DSS_OPT_SZ_CHK(dss64_ack64->mdss_copt.mdss_len,
1384 sizeof(struct mptcp_dss64_ack64_opt) + csum_len);
1385
1386 mp_tp->mpt_flags |= MPTCPF_RCVD_64BITACK;
1387 mp_tp->mpt_flags |= MPTCPF_SND_64BITACK;
1388 full_dsn = mptcp_ntoh64(dss64_ack64->mdss_dsn);
1389 full_dack = mptcp_ntoh64(dss64_ack64->mdss_dsn);
1390 mptcp_do_dss_opt_ack_meat(full_dack, full_dsn, tp, tiwin);
1391 NTOHL(dss64_ack64->mdss_subflow_seqn);
1392 NTOHS(dss64_ack64->mdss_data_len);
1393 if (csum_len == 0) {
1394 mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1395 dss64_ack64->mdss_subflow_seqn,
1396 dss64_ack64->mdss_data_len, 0);
1397 } else {
1398 mptcp_update_rcv_state_meat(mp_tp, tp, full_dsn,
1399 dss64_ack64->mdss_subflow_seqn,
1400 dss64_ack64->mdss_data_len,
1401 *(uint16_t *)(void *)(cp +
1402 dss64_ack64->mdss_copt.mdss_len -
1403 csum_len));
39236c6e 1404 }
0a7de745
A
1405 break;
1406 }
1407 default:
1408 mptcplog((LOG_DEBUG, "%s: File bug, DSS flags = %x\n",
1409 __func__, dss_rsp->mdss_flags),
1410 (MPTCP_SOCKET_DBG | MPTCP_RECEIVER_DBG),
1411 MPTCP_LOGLVL_LOG);
1412 break;
39236c6e
A
1413 }
1414}
1415
39236c6e
A
1416static void
1417mptcp_do_dss_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th, int optlen)
1418{
5ba3f43e
A
1419#pragma unused(optlen)
1420 struct mptcb *mp_tp = tptomptp(tp);
39236c6e 1421
0a7de745 1422 if (!mp_tp) {
39236c6e 1423 return;
0a7de745 1424 }
39236c6e 1425
fe8ab488
A
1426 /* We may get Data ACKs just during fallback, so don't ignore those */
1427 if ((tp->t_mpflags & TMPF_MPTCP_TRUE) ||
1428 (tp->t_mpflags & TMPF_TCP_FALLBACK)) {
39236c6e
A
1429 struct mptcp_dss_copt *dss_rsp = (struct mptcp_dss_copt *)cp;
1430
1431 if (dss_rsp->mdss_subtype == MPO_DSS) {
0a7de745 1432 if (dss_rsp->mdss_flags & MDSS_F) {
5c9f4661 1433 tp->t_rcv_map.mpt_dfin = 1;
0a7de745 1434 }
39236c6e 1435
5ba3f43e 1436 mptcp_do_dss_opt_meat(cp, tp, th);
39236c6e
A
1437 }
1438 }
1439}
1440
1441static void
1442mptcp_do_fastclose_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th)
1443{
1444 struct mptcb *mp_tp = NULL;
1445 struct mptcp_fastclose_opt *fc_opt = (struct mptcp_fastclose_opt *)cp;
1446
0a7de745 1447 if (th->th_flags != TH_ACK) {
39236c6e 1448 return;
0a7de745 1449 }
39236c6e 1450
0a7de745 1451 if (fc_opt->mfast_len != sizeof(struct mptcp_fastclose_opt)) {
39236c6e
A
1452 tcpstat.tcps_invalid_opt++;
1453 return;
1454 }
1455
5ba3f43e 1456 mp_tp = tptomptp(tp);
0a7de745 1457 if (!mp_tp) {
39236c6e 1458 return;
0a7de745 1459 }
39236c6e 1460
5ba3f43e 1461 if (fc_opt->mfast_key != mp_tp->mpt_localkey) {
39236c6e
A
1462 tcpstat.tcps_invalid_opt++;
1463 return;
1464 }
1465
1466 /*
1467 * fastclose could make us more vulnerable to attacks, hence
1468 * accept only those that are at the next expected sequence number.
1469 */
1470 if (th->th_seq != tp->rcv_nxt) {
1471 tcpstat.tcps_invalid_opt++;
1472 return;
1473 }
1474
39236c6e 1475 /* Reset this flow */
39037602 1476 tp->t_mpflags |= (TMPF_RESET | TMPF_FASTCLOSERCV);
39236c6e
A
1477
1478 if (tp->t_inpcb->inp_socket != NULL) {
1479 soevent(tp->t_inpcb->inp_socket,
1480 SO_FILT_HINT_LOCKED | SO_FILT_HINT_MUSTRST);
1481 }
1482}
1483
1484
1485static void
1486mptcp_do_mpfail_opt(struct tcpcb *tp, u_char *cp, struct tcphdr *th)
1487{
1488 struct mptcb *mp_tp = NULL;
1489 struct mptcp_mpfail_opt *fail_opt = (struct mptcp_mpfail_opt *)cp;
fe8ab488
A
1490 u_int32_t mdss_subflow_seqn = 0;
1491 int error = 0;
39236c6e 1492
fe8ab488
A
1493 /*
1494 * mpfail could make us more vulnerable to attacks. Hence accept
1495 * only those that are the next expected sequence number.
1496 */
1497 if (th->th_seq != tp->rcv_nxt) {
1498 tcpstat.tcps_invalid_opt++;
1499 return;
1500 }
1501
1502 /* A packet without RST, must atleast have the ACK bit set */
0a7de745 1503 if ((th->th_flags != TH_ACK) && (th->th_flags != TH_RST)) {
39236c6e 1504 return;
0a7de745 1505 }
39236c6e 1506
0a7de745 1507 if (fail_opt->mfail_len != sizeof(struct mptcp_mpfail_opt)) {
39236c6e 1508 return;
0a7de745 1509 }
39236c6e 1510
5ba3f43e
A
1511 mp_tp = tptomptp(tp);
1512
39236c6e
A
1513 mp_tp->mpt_flags |= MPTCPF_RECVD_MPFAIL;
1514 mp_tp->mpt_dsn_at_csum_fail = mptcp_hton64(fail_opt->mfail_dsn);
5ba3f43e 1515 error = mptcp_get_map_for_dsn(tp->t_inpcb->inp_socket,
fe8ab488
A
1516 mp_tp->mpt_dsn_at_csum_fail, &mdss_subflow_seqn);
1517 if (error == 0) {
1518 mp_tp->mpt_ssn_at_csum_fail = mdss_subflow_seqn;
1519 }
39236c6e
A
1520
1521 mptcp_notify_mpfail(tp->t_inpcb->inp_socket);
1522}
1523
3e170ce0 1524void
39236c6e
A
1525tcp_do_mptcp_options(struct tcpcb *tp, u_char *cp, struct tcphdr *th,
1526 struct tcpopt *to, int optlen)
1527{
1528 int mptcp_subtype;
5ba3f43e
A
1529 struct mptcb *mp_tp = tptomptp(tp);
1530
0a7de745 1531 if (mp_tp == NULL) {
5ba3f43e 1532 return;
0a7de745 1533 }
5ba3f43e
A
1534
1535 mpte_lock_assert_held(mp_tp->mpt_mpte);
39236c6e
A
1536
1537 /* All MPTCP options have atleast 4 bytes */
0a7de745 1538 if (optlen < 4) {
3e170ce0 1539 return;
0a7de745 1540 }
39236c6e
A
1541
1542 mptcp_subtype = (cp[2] >> 4);
1543
0a7de745 1544 if (mptcp_sanitize_option(tp, mptcp_subtype) == 0) {
3e170ce0 1545 return;
0a7de745 1546 }
3e170ce0 1547
39236c6e 1548 switch (mptcp_subtype) {
0a7de745
A
1549 case MPO_CAPABLE:
1550 mptcp_do_mpcapable_opt(tp, cp, th, optlen);
1551 break;
1552 case MPO_JOIN:
1553 mptcp_do_mpjoin_opt(tp, cp, th, optlen);
1554 break;
1555 case MPO_DSS:
1556 mptcp_do_dss_opt(tp, cp, th, optlen);
1557 break;
1558 case MPO_FASTCLOSE:
1559 mptcp_do_fastclose_opt(tp, cp, th);
1560 break;
1561 case MPO_FAIL:
1562 mptcp_do_mpfail_opt(tp, cp, th);
1563 break;
1564 case MPO_ADD_ADDR: /* fall through */
1565 case MPO_REMOVE_ADDR: /* fall through */
1566 case MPO_PRIO:
1567 to->to_flags |= TOF_MPTCP;
1568 break;
1569 default:
1570 break;
39236c6e 1571 }
3e170ce0 1572 return;
39236c6e
A
1573}
1574
39236c6e 1575/* REMOVE_ADDR option is sent when a source address goes away */
5ba3f43e 1576static void
39236c6e
A
1577mptcp_send_remaddr_opt(struct tcpcb *tp, struct mptcp_remaddr_opt *opt)
1578{
0a7de745 1579 mptcplog((LOG_DEBUG, "%s: local id %d remove id %d \n",
3e170ce0 1580 __func__, tp->t_local_aid, tp->t_rem_aid),
0a7de745 1581 (MPTCP_SOCKET_DBG | MPTCP_SENDER_DBG), MPTCP_LOGLVL_LOG);
39236c6e 1582
0a7de745 1583 bzero(opt, sizeof(*opt));
39236c6e 1584 opt->mr_kind = TCPOPT_MULTIPATH;
0a7de745 1585 opt->mr_len = sizeof(*opt);
39236c6e
A
1586 opt->mr_subtype = MPO_REMOVE_ADDR;
1587 opt->mr_addr_id = tp->t_rem_aid;
1588 tp->t_mpflags &= ~TMPF_SND_REM_ADDR;
1589}
1590
39236c6e
A
1591/* We send MP_PRIO option based on the values set by the SIOCSCONNORDER ioctl */
1592static int
1593mptcp_snd_mpprio(struct tcpcb *tp, u_char *cp, int optlen)
1594{
1595 struct mptcp_mpprio_addr_opt mpprio;
1596
1597 if (tp->t_state != TCPS_ESTABLISHED) {
1598 tp->t_mpflags &= ~TMPF_SND_MPPRIO;
0a7de745 1599 return optlen;
39236c6e
A
1600 }
1601
39236c6e 1602 if ((MAX_TCPOPTLEN - optlen) <
0a7de745
A
1603 (int)sizeof(mpprio)) {
1604 return optlen;
1605 }
39236c6e 1606
0a7de745 1607 bzero(&mpprio, sizeof(mpprio));
39236c6e 1608 mpprio.mpprio_kind = TCPOPT_MULTIPATH;
0a7de745 1609 mpprio.mpprio_len = sizeof(mpprio);
39236c6e 1610 mpprio.mpprio_subtype = MPO_PRIO;
0a7de745 1611 if (tp->t_mpflags & TMPF_BACKUP_PATH) {
39236c6e 1612 mpprio.mpprio_flags |= MPTCP_MPPRIO_BKP;
0a7de745 1613 }
39236c6e 1614 mpprio.mpprio_addrid = tp->t_local_aid;
0a7de745
A
1615 memcpy(cp + optlen, &mpprio, sizeof(mpprio));
1616 optlen += sizeof(mpprio);
39236c6e 1617 tp->t_mpflags &= ~TMPF_SND_MPPRIO;
5ba3f43e 1618 mptcplog((LOG_DEBUG, "%s: aid = %d \n", __func__,
0a7de745
A
1619 tp->t_local_aid),
1620 (MPTCP_SOCKET_DBG | MPTCP_SENDER_DBG), MPTCP_LOGLVL_LOG);
1621 return optlen;
39236c6e 1622}