2 * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
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>
34 #include <net/route.h>
35 #include <netinet/in.h>
38 #include <netinet/ip.h>
39 #include <netinet/ip_var.h>
40 #include <netinet/in_var.h>
41 #include <netinet/tcp.h>
42 #include <netinet/tcp_var.h>
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>
51 #include <libkern/crypto/sha1.h>
52 #include <netinet/mptcp_timer.h>
56 static int mptcp_validate_join_hmac(struct tcpcb
*, u_char
*, int);
57 static int mptcp_snd_mpprio(struct tcpcb
*tp
, u_char
*cp
, int optlen
);
60 * MPTCP Options Output Processing
64 mptcp_setup_first_subflow_syn_opts(struct socket
*so
, int flags
, u_char
*opt
,
67 struct tcpcb
*tp
= sototcpcb(so
);
68 struct mptcb
*mp_tp
= NULL
;
71 if (!(so
->so_flags
& SOF_MP_SUBFLOW
))
75 * Avoid retransmitting the MP_CAPABLE option.
77 if (tp
->t_rxtshift
> mptcp_mpcap_retries
)
80 if ((flags
& (TH_SYN
| TH_ACK
)) == (TH_SYN
| TH_ACK
)) {
81 struct mptcp_mpcapable_opt_rsp mptcp_opt
;
82 mptcp_key_t mp_localkey
= 0;
84 mp_localkey
= mptcp_get_localkey(mp_tp
);
85 if (mp_localkey
== 0) {
86 /* an embryonic connection was closed from above */
90 sizeof (struct mptcp_mpcapable_opt_rsp
));
91 mptcp_opt
.mmc_common
.mmco_kind
= TCPOPT_MULTIPATH
;
92 mptcp_opt
.mmc_common
.mmco_len
=
93 sizeof (struct mptcp_mpcapable_opt_rsp
);
94 mptcp_opt
.mmc_common
.mmco_subtype
= MPO_CAPABLE
;
96 mptcp_opt
.mmc_common
.mmco_version
= mp_tp
->mpt_version
;
97 mptcp_opt
.mmc_common
.mmco_flags
|= MPCAP_PROPOSAL_SBIT
;
98 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
)
99 mptcp_opt
.mmc_common
.mmco_flags
|=
102 mptcp_opt
.mmc_localkey
= mp_localkey
;
103 memcpy(opt
+ optlen
, &mptcp_opt
,
104 mptcp_opt
.mmc_common
.mmco_len
);
105 optlen
+= mptcp_opt
.mmc_common
.mmco_len
;
106 if (mptcp_dbg
>= MP_VERBOSE_DEBUG_2
) {
107 printf("%s: SYN_ACK localkey = %llx \n",
108 __func__
, mp_localkey
);
111 /* Only the SYN flag is set */
112 struct mptcp_mpcapable_opt_common mptcp_opt
;
113 mptcp_key_t mp_localkey
= 0;
114 mp_localkey
= mptcp_get_localkey(mp_tp
);
115 so
->so_flags
|= SOF_MPTCP_CLIENT
;
116 if (mp_localkey
== 0) {
117 /* an embryonic connection was closed */
121 sizeof (struct mptcp_mpcapable_opt_common
));
122 mptcp_opt
.mmco_kind
= TCPOPT_MULTIPATH
;
124 sizeof (struct mptcp_mpcapable_opt_common
) +
125 sizeof (mptcp_key_t
);
126 mptcp_opt
.mmco_subtype
= MPO_CAPABLE
;
127 MPT_LOCK_SPIN(mp_tp
);
128 mptcp_opt
.mmco_version
= mp_tp
->mpt_version
;
129 mptcp_opt
.mmco_flags
|= MPCAP_PROPOSAL_SBIT
;
130 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
)
131 mptcp_opt
.mmco_flags
|= MPCAP_CHECKSUM_CBIT
;
133 (void) memcpy(opt
+ optlen
, &mptcp_opt
,
134 sizeof (struct mptcp_mpcapable_opt_common
));
135 optlen
+= sizeof (struct mptcp_mpcapable_opt_common
);
136 (void) memcpy(opt
+ optlen
, &mp_localkey
,
137 sizeof (mptcp_key_t
));
138 optlen
+= sizeof (mptcp_key_t
);
145 mptcp_setup_join_subflow_syn_opts(struct socket
*so
, int flags
, u_char
*opt
,
148 struct inpcb
*inp
= sotoinpcb(so
);
149 struct tcpcb
*tp
= NULL
;
161 if ((flags
& (TH_SYN
| TH_ACK
)) == (TH_SYN
| TH_ACK
)) {
162 struct mptcp_mpjoin_opt_rsp mpjoin_rsp
;
163 bzero(&mpjoin_rsp
, sizeof (mpjoin_rsp
));
164 mpjoin_rsp
.mmjo_kind
= TCPOPT_MULTIPATH
;
165 mpjoin_rsp
.mmjo_len
= sizeof (mpjoin_rsp
);
166 mpjoin_rsp
.mmjo_subtype_bkp
= MPO_JOIN
<< 4;
167 if (tp
->t_mpflags
& TMPF_BACKUP_PATH
)
168 mpjoin_rsp
.mmjo_subtype_bkp
|= MPTCP_BACKUP
;
169 mpjoin_rsp
.mmjo_addr_id
= tp
->t_local_aid
;
170 mptcp_get_rands(tp
->t_local_aid
, tptomptp(tp
),
171 &mpjoin_rsp
.mmjo_rand
, NULL
);
172 mpjoin_rsp
.mmjo_mac
= mptcp_get_trunced_hmac(tp
->t_local_aid
,
174 memcpy(opt
+ optlen
, &mpjoin_rsp
, mpjoin_rsp
.mmjo_len
);
175 optlen
+= mpjoin_rsp
.mmjo_len
;
177 struct mptcp_mpjoin_opt_req mpjoin_req
;
178 bzero(&mpjoin_req
, sizeof (mpjoin_req
));
179 mpjoin_req
.mmjo_kind
= TCPOPT_MULTIPATH
;
180 mpjoin_req
.mmjo_len
= sizeof (mpjoin_req
);
181 mpjoin_req
.mmjo_subtype_bkp
= MPO_JOIN
<< 4;
182 /* A secondary subflow is started off as backup */
183 mpjoin_req
.mmjo_subtype_bkp
|= MPTCP_BACKUP
;
184 tp
->t_mpflags
|= TMPF_BACKUP_PATH
;
185 mpjoin_req
.mmjo_addr_id
= tp
->t_local_aid
;
186 mpjoin_req
.mmjo_peer_token
= mptcp_get_remotetoken(tp
->t_mptcb
);
187 if (mpjoin_req
.mmjo_peer_token
== 0) {
188 if (mptcp_dbg
>= MP_ERR_DEBUG
)
189 printf("%s: zero peer token \n", __func__
);
191 mptcp_get_rands(tp
->t_local_aid
, tptomptp(tp
),
192 &mpjoin_req
.mmjo_rand
, NULL
);
193 memcpy(opt
+ optlen
, &mpjoin_req
, mpjoin_req
.mmjo_len
);
194 optlen
+= mpjoin_req
.mmjo_len
;
200 mptcp_setup_join_ack_opts(struct tcpcb
*tp
, u_char
*opt
, unsigned optlen
)
203 struct mptcp_mpjoin_opt_rsp2 join_rsp2
;
205 if ((MAX_TCPOPTLEN
- optlen
) < sizeof (struct mptcp_mpjoin_opt_rsp2
)) {
206 printf("%s: no space left %d \n", __func__
, optlen
);
210 bzero(&join_rsp2
, sizeof (struct mptcp_mpjoin_opt_rsp2
));
211 join_rsp2
.mmjo_kind
= TCPOPT_MULTIPATH
;
212 join_rsp2
.mmjo_len
= sizeof (struct mptcp_mpjoin_opt_rsp2
);
213 join_rsp2
.mmjo_subtype
= MPO_JOIN
;
214 mptcp_get_hmac(tp
->t_local_aid
, tptomptp(tp
),
215 (u_char
*)&join_rsp2
.mmjo_mac
,
216 sizeof (join_rsp2
.mmjo_mac
));
217 memcpy(opt
+ optlen
, &join_rsp2
, join_rsp2
.mmjo_len
);
218 new_optlen
= optlen
+ join_rsp2
.mmjo_len
;
223 mptcp_setup_syn_opts(struct socket
*so
, int flags
, u_char
*opt
, unsigned optlen
)
227 if (mptcp_enable
== 0) {
232 if (!(so
->so_flags
& SOF_MP_SEC_SUBFLOW
)) {
233 new_optlen
= mptcp_setup_first_subflow_syn_opts(so
, flags
, opt
,
237 * To simulate SYN_ACK with no join opt, comment this line on
238 * OS X server side. This serves as a testing hook.
240 new_optlen
= mptcp_setup_join_subflow_syn_opts(so
, flags
, opt
,
247 mptcp_send_mpfail(struct tcpcb
*tp
, u_char
*opt
, unsigned int optlen
)
249 #pragma unused(tp, opt, optlen)
251 struct mptcb
*mp_tp
= NULL
;
252 struct mptcp_mpfail_opt fail_opt
;
254 int len
= sizeof (struct mptcp_mpfail_opt
);
256 mp_tp
= tptomptp(tp
);
258 tp
->t_mpflags
&= ~TMPF_SND_MPFAIL
;
262 /* if option space low give up */
263 if ((MAX_TCPOPTLEN
- optlen
) < sizeof (struct mptcp_mpfail_opt
)) {
264 tp
->t_mpflags
&= ~TMPF_SND_MPFAIL
;
269 dsn
= mp_tp
->mpt_rcvnxt
;
272 bzero(&fail_opt
, sizeof (fail_opt
));
273 fail_opt
.mfail_kind
= TCPOPT_MULTIPATH
;
274 fail_opt
.mfail_len
= len
;
275 fail_opt
.mfail_subtype
= MPO_FAIL
;
276 fail_opt
.mfail_dsn
= mptcp_hton64(dsn
);
277 memcpy(opt
+ optlen
, &fail_opt
, len
);
279 tp
->t_mpflags
&= ~TMPF_SND_MPFAIL
;
280 if (mptcp_dbg
>= MP_ERR_DEBUG
)
281 printf("%s: %d \n", __func__
, tp
->t_local_aid
);
286 mptcp_send_infinite_mapping(struct tcpcb
*tp
, u_char
*opt
, unsigned int optlen
)
288 struct mptcp_dsn_opt infin_opt
;
289 struct mptcb
*mp_tp
= NULL
;
290 size_t len
= sizeof (struct mptcp_dsn_opt
);
291 struct socket
*so
= tp
->t_inpcb
->inp_socket
;
298 mp_tp
= tptomptp(tp
);
303 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
)
307 if ((MAX_TCPOPTLEN
- optlen
) < (len
+ csum_len
)) {
311 bzero(&infin_opt
, sizeof (infin_opt
));
312 infin_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
313 infin_opt
.mdss_copt
.mdss_len
= len
+ csum_len
;
314 infin_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
315 infin_opt
.mdss_copt
.mdss_flags
|= MDSS_M
;
316 if (mp_tp
->mpt_flags
& MPTCPF_RECVD_MPFAIL
) {
317 infin_opt
.mdss_dsn
= (u_int32_t
)
318 MPTCP_DATASEQ_LOW32(mp_tp
->mpt_dsn_at_csum_fail
);
319 error
= mptcp_get_map_for_dsn(so
, mp_tp
->mpt_dsn_at_csum_fail
,
320 &infin_opt
.mdss_subflow_seqn
);
322 infin_opt
.mdss_dsn
= (u_int32_t
)
323 MPTCP_DATASEQ_LOW32(mp_tp
->mpt_snduna
);
324 infin_opt
.mdss_subflow_seqn
= tp
->snd_una
- tp
->iss
;
329 if ((infin_opt
.mdss_dsn
== 0) || (infin_opt
.mdss_subflow_seqn
== 0)) {
332 infin_opt
.mdss_dsn
= htonl(infin_opt
.mdss_dsn
);
333 infin_opt
.mdss_subflow_seqn
= htonl(infin_opt
.mdss_subflow_seqn
);
334 infin_opt
.mdss_data_len
= 0;
336 memcpy(opt
+ optlen
, &infin_opt
, len
);
339 /* The checksum field is set to 0 for infinite mapping */
341 memcpy(opt
+ optlen
, &csum
, csum_len
);
345 if (mptcp_dbg
== MP_VERBOSE_DEBUG_1
) {
346 printf("%s: dsn = %x, seq = %x len = %x\n", __func__
,
347 ntohl(infin_opt
.mdss_dsn
),
348 ntohl(infin_opt
.mdss_subflow_seqn
),
349 ntohs(infin_opt
.mdss_data_len
));
352 /* so->so_flags &= ~SOF_MPTCP_CLIENT; */
353 tp
->t_mpflags
|= TMPF_INFIN_SENT
;
354 tcpstat
.tcps_estab_fallback
++;
360 mptcp_ok_to_fin(struct tcpcb
*tp
, u_int64_t dsn
, u_int32_t datalen
)
362 struct mptcb
*mp_tp
= NULL
;
363 mp_tp
= tptomptp(tp
);
366 dsn
= (mp_tp
->mpt_sndmax
& MPTCP_DATASEQ_LOW32_MASK
) | dsn
;
367 if ((dsn
+ datalen
) == mp_tp
->mpt_sndmax
) {
376 /* Must be called from tcp_output to fill in the fast close option */
378 mptcp_send_fastclose(struct tcpcb
*tp
, u_char
*opt
, unsigned int optlen
,
381 struct mptcp_fastclose_opt fastclose_opt
;
382 struct mptcb
*mp_tp
= tptomptp(tp
);
384 /* Only ACK flag should be set */
388 if ((MAX_TCPOPTLEN
- optlen
) <
389 sizeof (struct mptcp_fastclose_opt
)) {
393 bzero(&fastclose_opt
, sizeof (struct mptcp_fastclose_opt
));
394 fastclose_opt
.mfast_kind
= TCPOPT_MULTIPATH
;
395 fastclose_opt
.mfast_len
= sizeof (struct mptcp_fastclose_opt
);
396 fastclose_opt
.mfast_subtype
= MPO_FASTCLOSE
;
397 MPT_LOCK_SPIN(mp_tp
);
398 fastclose_opt
.mfast_key
= mptcp_get_remotekey(mp_tp
);
400 memcpy(opt
+ optlen
, &fastclose_opt
, fastclose_opt
.mfast_len
);
401 optlen
+= fastclose_opt
.mfast_len
;
407 mptcp_setup_opts(struct tcpcb
*tp
, int32_t off
, u_char
*opt
,
408 unsigned int optlen
, int flags
, int datalen
,
409 unsigned int **dss_lenp
, u_int8_t
**finp
, u_int64_t
*dss_valp
,
412 struct inpcb
*inp
= (struct inpcb
*)tp
->t_inpcb
;
413 struct socket
*so
= inp
->inp_socket
;
414 struct mptcb
*mp_tp
= tptomptp(tp
);
415 boolean_t do_csum
= FALSE
;
416 boolean_t send_64bit_dsn
= FALSE
;
417 boolean_t send_64bit_ack
= FALSE
;
419 if (mptcp_enable
== 0) {
428 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
)
431 /* tcp_output handles the SYN path separately */
435 if ((MAX_TCPOPTLEN
- optlen
) <
436 sizeof (struct mptcp_mpcapable_opt_common
)) {
437 if (mptcp_dbg
>= MP_ERR_DEBUG
) {
438 printf("MPTCP ERROR %s: no space left %d flags %x "
440 "len %d\n", __func__
, optlen
, flags
, tp
->t_mpflags
,
446 if (tp
->t_mpflags
& TMPF_FASTCLOSE
) {
447 optlen
= mptcp_send_fastclose(tp
, opt
, optlen
, flags
);
448 VERIFY(datalen
== 0);
452 if (tp
->t_mpflags
& TMPF_TCP_FALLBACK
) {
453 if (tp
->t_mpflags
& TMPF_SND_MPFAIL
)
454 optlen
= mptcp_send_mpfail(tp
, opt
, optlen
);
455 else if (!(tp
->t_mpflags
& TMPF_INFIN_SENT
))
456 optlen
= mptcp_send_infinite_mapping(tp
, opt
, optlen
);
460 if (tp
->t_mpflags
& TMPF_SND_MPPRIO
) {
461 optlen
= mptcp_snd_mpprio(tp
, opt
, optlen
);
465 if ((tp
->t_mpflags
& TMPF_PREESTABLISHED
) &&
466 (!(tp
->t_mpflags
& TMPF_SENT_KEYS
)) &&
467 (!(tp
->t_mpflags
& TMPF_JOINED_FLOW
))) {
468 struct mptcp_mpcapable_opt_rsp1 mptcp_opt
;
469 if ((MAX_TCPOPTLEN
- optlen
) <
470 sizeof (struct mptcp_mpcapable_opt_rsp1
))
472 bzero(&mptcp_opt
, sizeof (struct mptcp_mpcapable_opt_rsp1
));
473 mptcp_opt
.mmc_common
.mmco_kind
= TCPOPT_MULTIPATH
;
474 mptcp_opt
.mmc_common
.mmco_len
=
475 sizeof (struct mptcp_mpcapable_opt_rsp1
);
476 mptcp_opt
.mmc_common
.mmco_subtype
= MPO_CAPABLE
;
477 mptcp_opt
.mmc_common
.mmco_version
= MP_DRAFT_VERSION_12
;
478 /* HMAC-SHA1 is the proposal */
479 mptcp_opt
.mmc_common
.mmco_flags
|= MPCAP_PROPOSAL_SBIT
;
481 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
)
482 mptcp_opt
.mmc_common
.mmco_flags
|= MPCAP_CHECKSUM_CBIT
;
483 mptcp_opt
.mmc_localkey
= mptcp_get_localkey(mp_tp
);
484 mptcp_opt
.mmc_remotekey
= mptcp_get_remotekey(mp_tp
);
486 memcpy(opt
+ optlen
, &mptcp_opt
, mptcp_opt
.mmc_common
.mmco_len
);
487 optlen
+= mptcp_opt
.mmc_common
.mmco_len
;
488 tp
->t_mpflags
|= TMPF_SENT_KEYS
;
489 so
->so_flags
|= SOF_MPTCP_TRUE
;
490 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
491 tp
->t_mpflags
|= TMPF_MPTCP_TRUE
;
494 tp
->t_mpuna
= tp
->snd_una
;
496 /* its a retransmission of the MP_CAPABLE ACK */
498 if (mptcp_dbg
>= MP_ERR_DEBUG
) {
499 printf("MPTCP SUCCESS %s: established.\n", __func__
);
502 } else if (tp
->t_mpflags
& TMPF_MPTCP_TRUE
) {
503 if (tp
->t_mpflags
& TMPF_SND_REM_ADDR
) {
504 int rem_opt_len
= sizeof (struct mptcp_remaddr_opt
);
505 if ((optlen
+ rem_opt_len
) <= MAX_TCPOPTLEN
) {
506 mptcp_send_remaddr_opt(tp
,
507 (struct mptcp_remaddr_opt
*)(opt
+ optlen
));
508 optlen
+= rem_opt_len
;
511 tp
->t_mpflags
&= ~TMPF_SND_REM_ADDR
;
516 if ((tp
->t_mpflags
& TMPF_JOINED_FLOW
) &&
517 (tp
->t_mpflags
& TMPF_PREESTABLISHED
) &&
518 (!(tp
->t_mpflags
& TMPF_RECVD_JOIN
)) &&
519 (tp
->t_mpflags
& TMPF_SENT_JOIN
) &&
520 (!(tp
->t_mpflags
& TMPF_MPTCP_TRUE
))) {
521 /* Do the ACK part */
522 optlen
= mptcp_setup_join_ack_opts(tp
, opt
, optlen
);
524 tp
->t_mpuna
= tp
->snd_una
;
526 /* Start a timer to retransmit the ACK */
527 tp
->t_timer
[TCPT_JACK_RXMT
] =
528 OFFSET_FROM_START(tp
, tcp_jack_rxmt
);
532 if (!(tp
->t_mpflags
& TMPF_MPTCP_TRUE
))
535 /* From here on, all options are sent only if MPTCP_TRUE */
538 if (mp_tp
->mpt_flags
& MPTCPF_SND_64BITDSN
) {
539 send_64bit_dsn
= TRUE
;
541 if (mp_tp
->mpt_flags
& MPTCPF_SND_64BITACK
) {
542 send_64bit_ack
= TRUE
;
546 #define CHECK_OPTLEN { \
547 if ((MAX_TCPOPTLEN - optlen) < len) { \
548 if (mptcp_dbg >= MP_ERR_DEBUG) { \
549 printf("MPTCP ERROR %s: len %d optlen %d \n", \
557 #define DO_FIN(dsn_opt) { \
559 sndfin = mptcp_ok_to_fin(tp, dsn_opt.mdss_dsn, datalen); \
561 dsn_opt.mdss_copt.mdss_flags |= MDSS_F; \
562 *finp = opt + optlen + offsetof(struct mptcp_dss_copt, \
564 dsn_opt.mdss_data_len += 1; \
568 #define CHECK_DATALEN { \
569 /* MPTCP socket does not support IP options */ \
570 if ((datalen + optlen + len) > tp->t_maxopd) { \
571 if (mptcp_dbg >= MP_VERBOSE_DEBUG_2) \
572 printf("%s: nosp %d len %d opt %d %d %d\n", \
573 __func__, datalen, len, optlen, \
574 tp->t_maxseg, tp->t_maxopd); \
575 /* remove option length from payload len */ \
576 datalen = tp->t_maxopd - optlen - len; \
580 if ((tp
->t_mpflags
& TMPF_SEND_DSN
) &&
583 * If there was the need to send 64-bit Data ACK along
584 * with 64-bit DSN, then 26 or 28 bytes would be used.
585 * With timestamps and NOOP padding that will cause
586 * overflow. Hence, in the rare event that both 64-bit
587 * DSN and 64-bit ACK have to be sent, delay the send of
588 * 64-bit ACK until our 64-bit DSN is acked with a 64-bit ack.
589 * XXX If this delay causes issue, remove the 2-byte padding.
591 struct mptcp_dss64_ack32_opt dsn_ack_opt
;
592 unsigned int len
= sizeof (dsn_ack_opt
);
600 bzero(&dsn_ack_opt
, sizeof (dsn_ack_opt
));
601 dsn_ack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
602 dsn_ack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
603 dsn_ack_opt
.mdss_copt
.mdss_len
= len
;
604 dsn_ack_opt
.mdss_copt
.mdss_flags
|=
605 MDSS_M
| MDSS_m
| MDSS_A
;
609 mptcp_output_getm_dsnmap64(so
, off
, (u_int32_t
)datalen
,
610 &dsn_ack_opt
.mdss_dsn
,
611 &dsn_ack_opt
.mdss_subflow_seqn
,
612 &dsn_ack_opt
.mdss_data_len
);
614 *dss_valp
= dsn_ack_opt
.mdss_dsn
;
616 if ((dsn_ack_opt
.mdss_data_len
== 0) ||
617 (dsn_ack_opt
.mdss_dsn
== 0)) {
621 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
626 dsn_ack_opt
.mdss_ack
=
627 htonl(MPTCP_DATAACK_LOW32(mp_tp
->mpt_rcvnxt
));
630 dsn_ack_opt
.mdss_dsn
= mptcp_hton64(dsn_ack_opt
.mdss_dsn
);
631 dsn_ack_opt
.mdss_subflow_seqn
= htonl(
632 dsn_ack_opt
.mdss_subflow_seqn
);
633 dsn_ack_opt
.mdss_data_len
= htons(
634 dsn_ack_opt
.mdss_data_len
);
635 *dss_lenp
= (unsigned int *)(void *)(opt
+ optlen
+
636 offsetof(struct mptcp_dss64_ack32_opt
, mdss_data_len
));
638 memcpy(opt
+ optlen
, &dsn_ack_opt
, sizeof (dsn_ack_opt
));
641 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
642 offsetof(struct mptcp_dss64_ack32_opt
,
646 if (mptcp_dbg
== MP_VERBOSE_DEBUG_2
) {
647 printf("%s: long DSS = %llx ACK = %llx \n",
649 mptcp_ntoh64(dsn_ack_opt
.mdss_dsn
),
650 mptcp_ntoh64(dsn_ack_opt
.mdss_ack
));
652 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
656 if ((tp
->t_mpflags
& TMPF_SEND_DSN
) &&
658 !(tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
)) {
659 struct mptcp_dsn_opt dsn_opt
;
660 unsigned int len
= sizeof (struct mptcp_dsn_opt
);
668 bzero(&dsn_opt
, sizeof (dsn_opt
));
669 dsn_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
670 dsn_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
671 dsn_opt
.mdss_copt
.mdss_len
= len
;
672 dsn_opt
.mdss_copt
.mdss_flags
|= MDSS_M
;
676 mptcp_output_getm_dsnmap32(so
, off
, (u_int32_t
)datalen
,
678 &dsn_opt
.mdss_subflow_seqn
, &dsn_opt
.mdss_data_len
,
681 if ((dsn_opt
.mdss_data_len
== 0) ||
682 (dsn_opt
.mdss_dsn
== 0)) {
686 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
690 dsn_opt
.mdss_dsn
= htonl(dsn_opt
.mdss_dsn
);
691 dsn_opt
.mdss_subflow_seqn
= htonl(dsn_opt
.mdss_subflow_seqn
);
692 dsn_opt
.mdss_data_len
= htons(dsn_opt
.mdss_data_len
);
693 *dss_lenp
= (unsigned int *)(void *)(opt
+ optlen
+
694 offsetof(struct mptcp_dsn_opt
, mdss_data_len
));
695 memcpy(opt
+ optlen
, &dsn_opt
, sizeof (dsn_opt
));
697 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
698 offsetof(struct mptcp_dsn_opt
, mdss_subflow_seqn
));
701 if (mptcp_dbg
== MP_VERBOSE_DEBUG_2
) {
702 printf("%s: DSS option. dsn = %x, seq = %x len = %x\n",
704 ntohl(dsn_opt
.mdss_dsn
),
705 ntohl(dsn_opt
.mdss_subflow_seqn
),
706 ntohs(dsn_opt
.mdss_data_len
));
708 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
712 /* 32-bit Data ACK option */
713 if ((tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
) &&
715 !(tp
->t_mpflags
& TMPF_SEND_DSN
) &&
716 !(tp
->t_mpflags
& TMPF_SEND_DFIN
)) {
718 struct mptcp_data_ack_opt dack_opt
;
719 unsigned int len
= 0;
721 len
= sizeof (dack_opt
);
725 bzero(&dack_opt
, len
);
726 dack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
727 dack_opt
.mdss_copt
.mdss_len
= len
;
728 dack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
729 dack_opt
.mdss_copt
.mdss_flags
|= MDSS_A
;
730 MPT_LOCK_SPIN(mp_tp
);
732 htonl(MPTCP_DATAACK_LOW32(mp_tp
->mpt_rcvnxt
));
734 memcpy(opt
+ optlen
, &dack_opt
, len
);
736 VERIFY(optlen
<= MAX_TCPOPTLEN
);
737 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
741 /* 64-bit Data ACK option */
742 if ((tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
) &&
744 !(tp
->t_mpflags
& TMPF_SEND_DSN
) &&
745 !(tp
->t_mpflags
& TMPF_SEND_DFIN
)) {
746 struct mptcp_data_ack64_opt dack_opt
;
747 unsigned int len
= 0;
749 len
= sizeof (dack_opt
);
753 bzero(&dack_opt
, len
);
754 dack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
755 dack_opt
.mdss_copt
.mdss_len
= len
;
756 dack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
757 dack_opt
.mdss_copt
.mdss_flags
|= (MDSS_A
| MDSS_a
);
758 MPT_LOCK_SPIN(mp_tp
);
759 dack_opt
.mdss_ack
= mptcp_hton64(mp_tp
->mpt_rcvnxt
);
761 * The other end should retransmit 64-bit DSN until it
762 * receives a 64-bit ACK.
764 mp_tp
->mpt_flags
&= ~MPTCPF_SND_64BITACK
;
766 memcpy(opt
+ optlen
, &dack_opt
, len
);
768 VERIFY(optlen
<= MAX_TCPOPTLEN
);
769 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
773 /* 32-bit DSS+Data ACK option */
774 if ((tp
->t_mpflags
& TMPF_SEND_DSN
) &&
777 (tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
)) {
778 struct mptcp_dss_ack_opt dss_ack_opt
;
779 unsigned int len
= sizeof (dss_ack_opt
);
786 bzero(&dss_ack_opt
, sizeof (dss_ack_opt
));
787 dss_ack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
788 dss_ack_opt
.mdss_copt
.mdss_len
= len
;
789 dss_ack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
790 dss_ack_opt
.mdss_copt
.mdss_flags
|= MDSS_A
| MDSS_M
;
791 MPT_LOCK_SPIN(mp_tp
);
792 dss_ack_opt
.mdss_ack
=
793 htonl(MPTCP_DATAACK_LOW32(mp_tp
->mpt_rcvnxt
));
798 mptcp_output_getm_dsnmap32(so
, off
, (u_int32_t
)datalen
,
799 &dss_ack_opt
.mdss_dsn
,
800 &dss_ack_opt
.mdss_subflow_seqn
,
801 &dss_ack_opt
.mdss_data_len
,
804 if ((dss_ack_opt
.mdss_data_len
== 0) ||
805 (dss_ack_opt
.mdss_dsn
== 0)) {
809 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
813 dss_ack_opt
.mdss_dsn
= htonl(dss_ack_opt
.mdss_dsn
);
814 dss_ack_opt
.mdss_subflow_seqn
=
815 htonl(dss_ack_opt
.mdss_subflow_seqn
);
816 dss_ack_opt
.mdss_data_len
= htons(dss_ack_opt
.mdss_data_len
);
817 *dss_lenp
= (unsigned int *)(void *)(opt
+ optlen
+
818 offsetof(struct mptcp_dss_ack_opt
, mdss_data_len
));
819 memcpy(opt
+ optlen
, &dss_ack_opt
, sizeof (dss_ack_opt
));
821 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
822 offsetof(struct mptcp_dss_ack_opt
,
828 if (optlen
> MAX_TCPOPTLEN
)
829 panic("optlen too large");
830 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
834 /* 32-bit DSS + 64-bit DACK option */
835 if ((tp
->t_mpflags
& TMPF_SEND_DSN
) &&
838 (tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
)) {
839 struct mptcp_dss32_ack64_opt dss_ack_opt
;
840 unsigned int len
= sizeof (dss_ack_opt
);
847 bzero(&dss_ack_opt
, sizeof (dss_ack_opt
));
848 dss_ack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
849 dss_ack_opt
.mdss_copt
.mdss_len
= len
;
850 dss_ack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
851 dss_ack_opt
.mdss_copt
.mdss_flags
|= MDSS_M
| MDSS_A
| MDSS_a
;
852 MPT_LOCK_SPIN(mp_tp
);
853 dss_ack_opt
.mdss_ack
=
854 mptcp_hton64(mp_tp
->mpt_rcvnxt
);
859 mptcp_output_getm_dsnmap32(so
, off
, (u_int32_t
)datalen
,
860 &dss_ack_opt
.mdss_dsn
, &dss_ack_opt
.mdss_subflow_seqn
,
861 &dss_ack_opt
.mdss_data_len
, dss_valp
);
863 if ((dss_ack_opt
.mdss_data_len
== 0) ||
864 (dss_ack_opt
.mdss_dsn
== 0)) {
868 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
872 dss_ack_opt
.mdss_dsn
= htonl(dss_ack_opt
.mdss_dsn
);
873 dss_ack_opt
.mdss_subflow_seqn
=
874 htonl(dss_ack_opt
.mdss_subflow_seqn
);
875 dss_ack_opt
.mdss_data_len
= htons(dss_ack_opt
.mdss_data_len
);
876 *dss_lenp
= (unsigned int *)(void *)(opt
+ optlen
+
877 offsetof(struct mptcp_dss32_ack64_opt
, mdss_data_len
));
878 memcpy(opt
+ optlen
, &dss_ack_opt
, sizeof (dss_ack_opt
));
880 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
881 offsetof(struct mptcp_dss32_ack64_opt
,
887 if (optlen
> MAX_TCPOPTLEN
)
888 panic("optlen too large");
889 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
893 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
894 struct mptcp_dss_ack_opt dss_ack_opt
;
895 unsigned int len
= sizeof (struct mptcp_dss_ack_opt
);
902 bzero(&dss_ack_opt
, sizeof (dss_ack_opt
));
905 /* Data FIN occupies one sequence space */
906 if ((mp_tp
->mpt_sndnxt
+ 1) != mp_tp
->mpt_sndmax
) {
908 if (mptcp_dbg
== MP_VERBOSE_DEBUG_2
)
909 printf("%s: Fin state %d %llu %llu\n", __func__
,
910 mp_tp
->mpt_state
, mp_tp
->mpt_sndnxt
,
915 dss_ack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
916 dss_ack_opt
.mdss_copt
.mdss_len
= len
;
917 dss_ack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
918 dss_ack_opt
.mdss_copt
.mdss_flags
|= MDSS_A
| MDSS_M
| MDSS_F
;
919 dss_ack_opt
.mdss_ack
=
920 htonl(MPTCP_DATAACK_LOW32(mp_tp
->mpt_rcvnxt
));
921 dss_ack_opt
.mdss_dsn
=
922 htonl(MPTCP_DATASEQ_LOW32(mp_tp
->mpt_sndnxt
));
924 dss_ack_opt
.mdss_subflow_seqn
= 0;
925 dss_ack_opt
.mdss_data_len
= 1;
926 dss_ack_opt
.mdss_data_len
= htons(dss_ack_opt
.mdss_data_len
);
927 memcpy(opt
+ optlen
, &dss_ack_opt
, sizeof (dss_ack_opt
));
929 *dss_valp
= mp_tp
->mpt_sndnxt
;
930 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
931 offsetof(struct mptcp_dss_ack_opt
,
941 * MPTCP Options Input Processing
946 mptcp_valid_mpcapable_common_opt(u_char
*cp
, u_int32_t mptcp_version
)
948 struct mptcp_mpcapable_opt_common
*rsp
=
949 (struct mptcp_mpcapable_opt_common
*)cp
;
951 /* mmco_kind, mmco_len and mmco_subtype are validated before */
953 /* In future, there can be more than one version supported */
954 if (rsp
->mmco_version
!= mptcp_version
)
957 if (!(rsp
->mmco_flags
& MPCAP_PROPOSAL_SBIT
))
960 if (rsp
->mmco_flags
& (MPCAP_BBIT
| MPCAP_CBIT
| MPCAP_DBIT
|
961 MPCAP_EBIT
| MPCAP_FBIT
| MPCAP_GBIT
))
969 mptcp_do_mpcapable_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
,
972 struct mptcp_mpcapable_opt_rsp1
*rsp1
= NULL
;
973 struct mptcp_mpcapable_opt_rsp
*rsp
= NULL
;
974 struct mptcb
*mp_tp
= tptomptp(tp
);
976 #define MPTCP_OPT_ERROR_PATH(tp) { \
977 tp->t_mpflags |= TMPF_RESET; \
978 tcpstat.tcps_invalid_mpcap++; \
979 if (tp->t_inpcb->inp_socket != NULL) { \
980 soevent(tp->t_inpcb->inp_socket, \
981 SO_FILT_HINT_LOCKED | SO_FILT_HINT_MUSTRST); \
986 if (mptcp_dbg
== MP_ERR_DEBUG
)
987 printf("MPTCP ERROR %s: NULL mpsocket \n", __func__
);
988 tcpstat
.tcps_invalid_mpcap
++;
992 /* Validate the kind, len, flags */
993 if (mptcp_valid_mpcapable_common_opt(cp
, mp_tp
->mpt_version
) != 1) {
994 tcpstat
.tcps_invalid_mpcap
++;
998 /* A SYN contains only the MP_CAPABLE option */
999 if ((th
->th_flags
& (TH_SYN
| TH_ACK
)) == TH_SYN
) {
1000 /* XXX passive side not supported yet */
1002 } else if ((th
->th_flags
& (TH_SYN
| TH_ACK
)) == (TH_SYN
| TH_ACK
)) {
1004 /* A SYN/ACK contains peer's key and flags */
1005 if (optlen
!= sizeof (struct mptcp_mpcapable_opt_rsp
)) {
1007 if (mptcp_dbg
== MP_ERR_DEBUG
) {
1008 printf("%s: SYN_ACK optlen = %d, sizeof mp opt \
1009 = %lu \n", __func__
, optlen
,
1010 sizeof (struct mptcp_mpcapable_opt_rsp
));
1012 tcpstat
.tcps_invalid_mpcap
++;
1017 * If checksum flag is set, enable MPTCP checksum, even if
1018 * it was not negotiated on the first SYN.
1020 if (((struct mptcp_mpcapable_opt_common
*)cp
)->mmco_flags
&
1021 MPCAP_CHECKSUM_CBIT
)
1022 mp_tp
->mpt_flags
|= MPTCPF_CHECKSUM
;
1024 rsp
= (struct mptcp_mpcapable_opt_rsp
*)cp
;
1025 MPT_LOCK_SPIN(mp_tp
);
1026 mp_tp
->mpt_remotekey
= rsp
->mmc_localkey
;
1028 tp
->t_mpflags
|= TMPF_PREESTABLISHED
;
1030 if (mptcp_dbg
> MP_VERBOSE_DEBUG_1
) {
1031 printf("SYN_ACK pre established, optlen = %d, tp \
1032 state = %d sport = %x dport = %x key = %llx \n",
1033 optlen
, tp
->t_state
, th
->th_sport
, th
->th_dport
,
1034 mp_tp
->mpt_remotekey
);
1037 } else if ((th
->th_flags
& TH_ACK
) &&
1038 (tp
->t_mpflags
& TMPF_PREESTABLISHED
)) {
1041 * Verify checksum flag is set, if we initially negotiated
1044 if ((mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
) &&
1045 !(((struct mptcp_mpcapable_opt_common
*)cp
)->mmco_flags
&
1046 MPCAP_CHECKSUM_CBIT
)) {
1047 if (mptcp_dbg
== MP_ERR_DEBUG
) {
1048 printf("%s: checksum negotiation failure \n",
1051 MPTCP_OPT_ERROR_PATH(tp
);
1055 if (!(mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
) &&
1056 (((struct mptcp_mpcapable_opt_common
*)cp
)->mmco_flags
&
1057 MPCAP_CHECKSUM_CBIT
)) {
1058 if (mptcp_dbg
== MP_ERR_DEBUG
) {
1059 printf("%s: checksum negotiation failure 2.\n",
1062 MPTCP_OPT_ERROR_PATH(tp
);
1067 * The ACK of a three way handshake contains peer's key and
1070 if (optlen
!= sizeof (struct mptcp_mpcapable_opt_rsp1
)) {
1072 if (mptcp_dbg
== MP_ERR_DEBUG
) {
1073 printf("%s: ACK optlen = %d , sizeof mp option \
1074 = %lu, state = %d \n",
1077 sizeof (struct mptcp_mpcapable_opt_rsp1
),
1080 MPTCP_OPT_ERROR_PATH(tp
);
1084 rsp1
= (struct mptcp_mpcapable_opt_rsp1
*)cp
;
1085 /* Skipping MPT_LOCK for invariant key */
1086 if (rsp1
->mmc_remotekey
!= *mp_tp
->mpt_localkey
) {
1087 if (mptcp_dbg
== MP_ERR_DEBUG
) {
1088 printf("MPTCP ERROR %s: key mismatch locally "
1089 "stored key. rsp = %llx local = %llx \n",
1090 __func__
, rsp1
->mmc_remotekey
,
1091 *mp_tp
->mpt_localkey
);
1093 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
1094 MPTCP_OPT_ERROR_PATH(tp
);
1097 /* We received both keys. Almost an MPTCP connection */
1098 /* Skipping MPT_LOCK for invariant key */
1099 if (mp_tp
->mpt_remotekey
!= rsp1
->mmc_localkey
) {
1100 if (mptcp_dbg
== MP_ERR_DEBUG
) {
1101 printf("MPTCP ERROR %s: keys don't"
1102 " match\n", __func__
);
1104 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
1105 MPTCP_OPT_ERROR_PATH(tp
);
1108 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
1109 tp
->t_mpflags
|= TMPF_MPTCP_RCVD_KEY
;
1110 tp
->t_mpflags
|= TMPF_MPTCP_TRUE
;
1111 tp
->t_inpcb
->inp_socket
->so_flags
|= SOF_MPTCP_TRUE
;
1113 DTRACE_MPTCP2(state__change
, struct mptcb
*, mp_tp
,
1114 uint32_t, 0 /* event */);
1115 mp_tp
->mpt_state
= MPTCPS_ESTABLISHED
;
1117 if (mptcp_dbg
>= MP_VERBOSE_DEBUG_2
) {
1118 printf("MPTCP SUCCESS %s: rem key = %llx local \
1120 __func__
, mp_tp
->mpt_remotekey
,
1121 *mp_tp
->mpt_localkey
);
1132 mptcp_do_mpjoin_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
, int optlen
)
1134 #define MPTCP_JOPT_ERROR_PATH(tp) { \
1135 tp->t_mpflags |= TMPF_RESET; \
1136 tcpstat.tcps_invalid_joins++; \
1137 if (tp->t_inpcb->inp_socket != NULL) { \
1138 soevent(tp->t_inpcb->inp_socket, \
1139 SO_FILT_HINT_LOCKED | SO_FILT_HINT_MUSTRST); \
1143 struct mptcb
*mp_tp
= tptomptp(tp
);
1145 if ((th
->th_flags
& (TH_SYN
| TH_ACK
)) == TH_SYN
) {
1146 /* We won't accept join requests as an active opener */
1147 if (tp
->t_inpcb
->inp_socket
->so_flags
& SOF_MPTCP_CLIENT
) {
1148 MPTCP_JOPT_ERROR_PATH(tp
);
1152 if (optlen
!= sizeof (struct mptcp_mpjoin_opt_req
)) {
1153 if (mptcp_dbg
== MP_ERR_DEBUG
) {
1154 printf("SYN: unexpected optlen = %d, mp option"
1157 sizeof (struct mptcp_mpjoin_opt_req
));
1159 /* send RST and close */
1160 MPTCP_JOPT_ERROR_PATH(tp
);
1163 /* not supported yet */
1166 struct mptcp_mpjoin_opt_req
*join_req
=
1167 (struct mptcp_mpjoin_opt_req
*)cp
;
1168 mp_so
= mptcp_find_mpso(join_req
->mmjo_peer_token
);
1170 if (mptcp_dbg
>= MP_ERR_DEBUG
)
1171 printf("%s: cannot find mp_so token = %x\n",
1172 __func__
, join_req
->mmjo_peer_token
);
1174 MPTCP_JOPT_ERROR_PATH(tp
);
1177 if (tp
->t_mpflags
& TMPF_PREESTABLISHED
) {
1180 mp_so
->ms_remote_addr_id
= join_req
->mmjo_addr_id
;
1181 mp_so
->ms_remote_rand
= join_req
->mmjo_rand
;
1182 tp
->t_mpflags
|= TMPF_PREESTABLISHED
| TMPF_JOINED_FLOW
;
1183 tp
->t_mpflags
|= TMPF_RECVD_JOIN
;
1184 tp
->t_inpcb
->inp_socket
->so_flags
|= SOF_MP_SEC_SUBFLOW
;
1185 if (join_req
->mmjo_subtype
& MPTCP_BACKUP
) {
1186 tp
->t_mpflags
|= TMPF_BACKUP_PATH
;
1189 } else if ((th
->th_flags
& (TH_SYN
| TH_ACK
)) == (TH_SYN
| TH_ACK
)) {
1190 struct mptcp_mpjoin_opt_rsp
*join_rsp
=
1191 (struct mptcp_mpjoin_opt_rsp
*)cp
;
1193 if (optlen
!= sizeof (struct mptcp_mpjoin_opt_rsp
)) {
1194 if (mptcp_dbg
>= MP_ERR_DEBUG
) {
1195 printf("SYN_ACK: unexpected optlen = %d mp "
1196 "option = %lu\n", optlen
,
1197 sizeof (struct mptcp_mpjoin_opt_rsp
));
1199 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
1200 /* send RST and close */
1201 MPTCP_JOPT_ERROR_PATH(tp
);
1205 if (mp_tp
== NULL
) {
1206 if (mptcp_dbg
>= MP_ERR_DEBUG
)
1207 printf("%s: cannot find mp_tp in SYN_ACK\n",
1209 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
1210 /* send RST and close */
1211 MPTCP_JOPT_ERROR_PATH(tp
);
1215 mptcp_set_raddr_rand(tp
->t_local_aid
,
1217 join_rsp
->mmjo_addr_id
, join_rsp
->mmjo_rand
);
1218 error
= mptcp_validate_join_hmac(tp
,
1219 (u_char
*)&join_rsp
->mmjo_mac
, SHA1_TRUNCATED
);
1221 if (mptcp_dbg
>= MP_ERR_DEBUG
) {
1222 printf("%s: SYN_ACK error = %d \n", __func__
,
1225 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
1226 /* send RST and close */
1227 MPTCP_JOPT_ERROR_PATH(tp
);
1230 tp
->t_mpflags
|= TMPF_SENT_JOIN
;
1231 } else if ((th
->th_flags
& TH_ACK
) &&
1232 (tp
->t_mpflags
& TMPF_PREESTABLISHED
)) {
1233 struct mptcp_mpjoin_opt_rsp2
*join_rsp2
=
1234 (struct mptcp_mpjoin_opt_rsp2
*)cp
;
1236 if (optlen
!= sizeof (struct mptcp_mpjoin_opt_rsp2
)) {
1237 if (mptcp_dbg
>= MP_ERR_DEBUG
) {
1238 printf("ACK: unexpected optlen = %d mp option "
1240 sizeof (struct mptcp_mpjoin_opt_rsp2
));
1242 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
1243 /* send RST and close */
1244 MPTCP_JOPT_ERROR_PATH(tp
);
1248 if (mp_tp
== NULL
) {
1249 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
1250 MPTCP_JOPT_ERROR_PATH(tp
);
1254 error
= mptcp_validate_join_hmac(tp
, join_rsp2
->mmjo_mac
,
1257 if (mptcp_dbg
>= MP_ERR_DEBUG
) {
1258 printf("%s: ACK error = %d\n", __func__
,
1261 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
1262 MPTCP_JOPT_ERROR_PATH(tp
);
1265 tp
->t_mpflags
|= TMPF_MPTCP_TRUE
;
1266 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
1267 tp
->t_flags
|= TF_ACKNOW
;
1268 tp
->t_mpflags
|= TMPF_MPTCP_ACKNOW
;
1269 tp
->t_inpcb
->inp_socket
->so_flags
|= SOF_MPTCP_TRUE
;
1270 if (mptcp_dbg
>= MP_ERR_DEBUG
) {
1271 printf("MPTCP SUCCESS %s: join \n", __func__
);
1277 mptcp_validate_join_hmac(struct tcpcb
*tp
, u_char
* hmac
, int mac_len
)
1279 u_char digest
[SHA1_RESULTLEN
] = {0};
1280 struct mptcb
*mp_tp
= NULL
;
1281 mptcp_key_t rem_key
, loc_key
;
1282 u_int32_t rem_rand
, loc_rand
;
1284 mp_tp
= tp
->t_mptcb
;
1288 rem_rand
= loc_rand
= 0;
1291 rem_key
= mp_tp
->mpt_remotekey
;
1292 loc_key
= *mp_tp
->mpt_localkey
;
1295 mptcp_get_rands(tp
->t_local_aid
, mp_tp
, &loc_rand
, &rem_rand
);
1296 if ((rem_rand
== 0) || (loc_rand
== 0))
1299 mptcp_hmac_sha1(rem_key
, loc_key
, rem_rand
, loc_rand
,
1300 digest
, sizeof (digest
));
1302 if (bcmp(digest
, hmac
, mac_len
) == 0)
1303 return (0); /* matches */
1305 printf("%s: remote key %llx local key %llx remote rand %x "
1306 "local rand %x \n", __func__
, rem_key
, loc_key
,
1307 rem_rand
, loc_rand
);
1313 mptcp_do_dss_opt_ack_meat(u_int64_t full_dack
, struct tcpcb
*tp
)
1315 struct mptcb
*mp_tp
= tptomptp(tp
);
1316 int close_notify
= 0;
1322 if (MPTCP_SEQ_LEQ(full_dack
, mp_tp
->mpt_sndmax
) &&
1323 MPTCP_SEQ_GEQ(full_dack
, mp_tp
->mpt_snduna
)) {
1324 mptcp_data_ack_rcvd(mp_tp
, tp
, full_dack
);
1325 if ((mp_tp
->mpt_state
== MPTCPS_CLOSED
) ||
1326 (mp_tp
->mpt_state
> MPTCPS_FIN_WAIT_2
))
1329 mptcp_notify_mpready(tp
->t_inpcb
->inp_socket
);
1331 mptcp_notify_close(tp
->t_inpcb
->inp_socket
);
1332 if (mp_tp
->mpt_flags
& MPTCPF_RCVD_64BITACK
) {
1333 mp_tp
->mpt_flags
&= ~MPTCPF_RCVD_64BITACK
;
1334 mp_tp
->mpt_flags
&= ~MPTCPF_SND_64BITDSN
;
1338 if (mptcp_dbg
== MP_VERBOSE_DEBUG_2
) {
1339 printf("%s: unexpected dack %llx snduna %llx "
1340 "sndmax %llx\n", __func__
, full_dack
,
1341 mp_tp
->mpt_snduna
, mp_tp
->mpt_sndmax
);
1345 if (mptcp_dbg
== MP_VERBOSE_DEBUG_2
) {
1346 printf("%s: full_dack = %llu \n", __func__
, full_dack
);
1351 mptcp_do_dss_opt_meat(u_char
*cp
, struct tcpcb
*tp
)
1353 struct mptcp_dss_copt
*dss_rsp
= (struct mptcp_dss_copt
*)cp
;
1354 u_int64_t full_dack
= 0;
1355 struct mptcb
*mp_tp
= tptomptp(tp
);
1358 #define MPTCP_DSS_OPT_SZ_CHK(len, expected_len) { \
1359 if (len != expected_len) { \
1360 if (mptcp_dbg >= MP_ERR_DEBUG) { \
1361 printf("MPTCP ERROR %s: bad len = %d" \
1362 "dss: %x \n", __func__, \
1364 dss_rsp->mdss_flags); \
1372 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
)
1375 dss_rsp
->mdss_flags
&= (MDSS_A
|MDSS_a
|MDSS_M
|MDSS_m
);
1376 switch (dss_rsp
->mdss_flags
) {
1379 /* 32-bit DSS, No Data ACK */
1380 struct mptcp_dsn_opt
*dss_rsp1
;
1381 dss_rsp1
= (struct mptcp_dsn_opt
*)cp
;
1383 MPTCP_DSS_OPT_SZ_CHK(dss_rsp1
->mdss_copt
.mdss_len
,
1384 sizeof (struct mptcp_dsn_opt
) + csum_len
);
1386 mptcp_update_dss_rcv_state(dss_rsp1
, tp
, 0);
1388 mptcp_update_dss_rcv_state(dss_rsp1
, tp
,
1389 *(uint16_t *)(void *)(cp
+
1390 (dss_rsp1
->mdss_copt
.mdss_len
- csum_len
)));
1395 /* 32-bit Data ACK, no DSS */
1396 struct mptcp_data_ack_opt
*dack_opt
;
1397 dack_opt
= (struct mptcp_data_ack_opt
*)cp
;
1399 MPTCP_DSS_OPT_SZ_CHK(dack_opt
->mdss_copt
.mdss_len
,
1400 sizeof (struct mptcp_data_ack_opt
));
1402 u_int32_t dack
= dack_opt
->mdss_ack
;
1404 MPT_LOCK_SPIN(mp_tp
);
1405 MPTCP_EXTEND_DSN(mp_tp
->mpt_snduna
, dack
, full_dack
);
1407 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1410 case (MDSS_M
| MDSS_A
):
1412 /* 32-bit Data ACK + 32-bit DSS */
1413 struct mptcp_dss_ack_opt
*dss_ack_rsp
;
1414 dss_ack_rsp
= (struct mptcp_dss_ack_opt
*)cp
;
1416 MPTCP_DSS_OPT_SZ_CHK(dss_ack_rsp
->mdss_copt
.mdss_len
,
1417 sizeof (struct mptcp_dss_ack_opt
) + csum_len
);
1419 u_int32_t dack
= dss_ack_rsp
->mdss_ack
;
1421 MPT_LOCK_SPIN(mp_tp
);
1422 MPTCP_EXTEND_DSN(mp_tp
->mpt_snduna
, dack
, full_dack
);
1424 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1426 mptcp_update_rcv_state_f(dss_ack_rsp
, tp
, 0);
1428 mptcp_update_rcv_state_f(dss_ack_rsp
, tp
,
1429 *(uint16_t *)(void *)(cp
+
1430 (dss_ack_rsp
->mdss_copt
.mdss_len
-
1434 case (MDSS_M
| MDSS_m
):
1436 /* 64-bit DSS , No Data ACK */
1437 struct mptcp_dsn64_opt
*dsn64
;
1438 dsn64
= (struct mptcp_dsn64_opt
*)cp
;
1441 MPTCP_DSS_OPT_SZ_CHK(dsn64
->mdss_copt
.mdss_len
,
1442 sizeof (struct mptcp_dsn64_opt
) + csum_len
);
1444 if (mptcp_dbg
== MP_VERBOSE_DEBUG_4
) {
1445 printf("%s: 64-bit M present.\n", __func__
);
1448 MPT_LOCK_SPIN(mp_tp
);
1449 mp_tp
->mpt_flags
|= MPTCPF_SND_64BITACK
;
1452 full_dsn
= mptcp_ntoh64(dsn64
->mdss_dsn
);
1453 NTOHL(dsn64
->mdss_subflow_seqn
);
1454 NTOHS(dsn64
->mdss_data_len
);
1456 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1457 dsn64
->mdss_subflow_seqn
,
1458 dsn64
->mdss_data_len
,
1461 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1462 dsn64
->mdss_subflow_seqn
,
1463 dsn64
->mdss_data_len
,
1464 *(uint16_t *)(void *)(cp
+
1465 dsn64
->mdss_copt
.mdss_len
- csum_len
));
1468 case (MDSS_A
| MDSS_a
):
1470 /* 64-bit Data ACK, no DSS */
1471 struct mptcp_data_ack64_opt
*dack64
;
1472 dack64
= (struct mptcp_data_ack64_opt
*)cp
;
1474 MPTCP_DSS_OPT_SZ_CHK(dack64
->mdss_copt
.mdss_len
,
1475 sizeof (struct mptcp_data_ack64_opt
));
1478 if (mptcp_dbg
== MP_VERBOSE_DEBUG_4
) {
1479 printf("%s: 64-bit A present. \n", __func__
);
1482 MPT_LOCK_SPIN(mp_tp
);
1483 mp_tp
->mpt_flags
|= MPTCPF_RCVD_64BITACK
;
1486 full_dack
= mptcp_ntoh64(dack64
->mdss_ack
);
1487 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1490 case (MDSS_M
| MDSS_m
| MDSS_A
):
1492 /* 64-bit DSS + 32-bit Data ACK */
1493 struct mptcp_dss64_ack32_opt
*dss_ack_rsp
;
1494 dss_ack_rsp
= (struct mptcp_dss64_ack32_opt
*)cp
;
1496 MPTCP_DSS_OPT_SZ_CHK(dss_ack_rsp
->mdss_copt
.mdss_len
,
1497 sizeof (struct mptcp_dss64_ack32_opt
) + csum_len
);
1499 if (mptcp_dbg
== MP_VERBOSE_DEBUG_4
) {
1500 printf("%s: 64-bit M and 32-bit A present.\n",
1504 u_int32_t dack
= dss_ack_rsp
->mdss_ack
;
1506 MPT_LOCK_SPIN(mp_tp
);
1507 mp_tp
->mpt_flags
|= MPTCPF_SND_64BITACK
;
1508 MPTCP_EXTEND_DSN(mp_tp
->mpt_snduna
, dack
, full_dack
);
1510 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1512 mptcp_update_rcv_state_g(dss_ack_rsp
, tp
, 0);
1514 mptcp_update_rcv_state_g(dss_ack_rsp
, tp
,
1515 *(uint16_t *)(void *)(cp
+
1516 dss_ack_rsp
->mdss_copt
.mdss_len
-
1520 case (MDSS_M
| MDSS_A
| MDSS_a
):
1522 /* 32-bit DSS + 64-bit Data ACK */
1523 struct mptcp_dss32_ack64_opt
*dss32_ack64_opt
;
1524 dss32_ack64_opt
= (struct mptcp_dss32_ack64_opt
*)cp
;
1527 MPTCP_DSS_OPT_SZ_CHK(
1528 dss32_ack64_opt
->mdss_copt
.mdss_len
,
1529 sizeof (struct mptcp_dss32_ack64_opt
) + csum_len
);
1531 if (mptcp_dbg
== MP_VERBOSE_DEBUG_4
) {
1532 printf("%s: 32-bit M and 64-bit A present.\n",
1535 full_dack
= mptcp_ntoh64(dss32_ack64_opt
->mdss_ack
);
1536 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1537 NTOHL(dss32_ack64_opt
->mdss_dsn
);
1538 MPT_LOCK_SPIN(mp_tp
);
1539 mp_tp
->mpt_flags
|= MPTCPF_RCVD_64BITACK
;
1540 MPTCP_EXTEND_DSN(mp_tp
->mpt_rcvnxt
,
1541 dss32_ack64_opt
->mdss_dsn
, full_dsn
);
1543 NTOHL(dss32_ack64_opt
->mdss_subflow_seqn
);
1544 NTOHS(dss32_ack64_opt
->mdss_data_len
);
1546 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1547 dss32_ack64_opt
->mdss_subflow_seqn
,
1548 dss32_ack64_opt
->mdss_data_len
, 0);
1550 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1551 dss32_ack64_opt
->mdss_subflow_seqn
,
1552 dss32_ack64_opt
->mdss_data_len
,
1553 *(uint16_t *)(void *)(cp
+
1554 dss32_ack64_opt
->mdss_copt
.mdss_len
-
1558 case (MDSS_M
| MDSS_m
| MDSS_A
| MDSS_a
):
1560 /* 64-bit DSS + 64-bit Data ACK */
1561 struct mptcp_dss64_ack64_opt
*dss64_ack64
;
1562 dss64_ack64
= (struct mptcp_dss64_ack64_opt
*)cp
;
1565 MPTCP_DSS_OPT_SZ_CHK(dss64_ack64
->mdss_copt
.mdss_len
,
1566 sizeof (struct mptcp_dss64_ack64_opt
) + csum_len
);
1568 if (mptcp_dbg
== MP_VERBOSE_DEBUG_4
) {
1569 printf("%s: 64-bit M and 64-bit A present.\n",
1572 MPT_LOCK_SPIN(mp_tp
);
1573 mp_tp
->mpt_flags
|= MPTCPF_RCVD_64BITACK
;
1574 mp_tp
->mpt_flags
|= MPTCPF_SND_64BITACK
;
1576 full_dsn
= mptcp_ntoh64(dss64_ack64
->mdss_dsn
);
1577 full_dack
= mptcp_ntoh64(dss64_ack64
->mdss_dsn
);
1578 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1579 NTOHL(dss64_ack64
->mdss_subflow_seqn
);
1580 NTOHS(dss64_ack64
->mdss_data_len
);
1582 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1583 dss64_ack64
->mdss_subflow_seqn
,
1584 dss64_ack64
->mdss_data_len
, 0);
1586 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1587 dss64_ack64
->mdss_subflow_seqn
,
1588 dss64_ack64
->mdss_data_len
,
1589 *(uint16_t *)(void *)(cp
+
1590 dss64_ack64
->mdss_copt
.mdss_len
-
1595 if (mptcp_dbg
>= MP_ERR_DEBUG
) {
1596 printf("MPTCP ERROR %s: File bug, DSS flags = %x\n",
1597 __func__
, dss_rsp
->mdss_flags
);
1605 mptcp_do_fin_opt(struct tcpcb
*tp
)
1607 struct mptcb
*mp_tp
= (struct mptcb
*)tp
->t_mptcb
;
1609 if (!(tp
->t_mpflags
& TMPF_RECV_DFIN
)) {
1610 if (mp_tp
!= NULL
) {
1612 mp_tp
->mpt_rcvnxt
+= 1;
1613 mptcp_close_fsm(mp_tp
, MPCE_RECV_DATA_FIN
);
1616 tp
->t_mpflags
|= TMPF_RECV_DFIN
;
1619 tp
->t_mpflags
|= TMPF_MPTCP_ACKNOW
;
1621 * Since this is a data level FIN, TCP needs to be explicitly told
1622 * to send back an ACK on which the Data ACK is piggybacked.
1624 tp
->t_flags
|= TF_ACKNOW
;
1628 mptcp_do_dss_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
, int optlen
)
1630 #pragma unused(th, optlen)
1631 struct mptcb
*mp_tp
= (struct mptcb
*)tp
->t_mptcb
;
1636 if (tp
->t_mpflags
& TMPF_MPTCP_TRUE
) {
1637 struct mptcp_dss_copt
*dss_rsp
= (struct mptcp_dss_copt
*)cp
;
1639 if (dss_rsp
->mdss_subtype
== MPO_DSS
) {
1640 if (mptcp_dbg
> MP_VERBOSE_DEBUG_4
) {
1641 printf("%s: DSS option received: %d ",
1642 __func__
, dss_rsp
->mdss_flags
);
1644 if (dss_rsp
->mdss_flags
& MDSS_F
) {
1645 if (mptcp_dbg
>= MP_VERBOSE_DEBUG_1
)
1646 printf("%s: received FIN\n", __func__
);
1647 mptcp_do_fin_opt(tp
);
1650 mptcp_do_dss_opt_meat(cp
, tp
);
1656 mptcp_do_fastclose_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
)
1658 struct mptcb
*mp_tp
= NULL
;
1659 struct mptcp_fastclose_opt
*fc_opt
= (struct mptcp_fastclose_opt
*)cp
;
1661 if (th
->th_flags
!= TH_ACK
)
1664 if (mptcp_dbg
> MP_VERBOSE_DEBUG_2
)
1665 printf("%s: received \n", __func__
);
1667 if (fc_opt
->mfast_len
!= sizeof (struct mptcp_fastclose_opt
)) {
1668 tcpstat
.tcps_invalid_opt
++;
1672 mp_tp
= (struct mptcb
*)tp
->t_mptcb
;
1676 if (fc_opt
->mfast_key
!= mptcp_get_localkey(mp_tp
)) {
1677 tcpstat
.tcps_invalid_opt
++;
1682 * fastclose could make us more vulnerable to attacks, hence
1683 * accept only those that are at the next expected sequence number.
1685 if (th
->th_seq
!= tp
->rcv_nxt
) {
1686 tcpstat
.tcps_invalid_opt
++;
1691 if (mp_tp
->mpt_state
!= MPTCPS_FASTCLOSE_WAIT
) {
1692 mp_tp
->mpt_state
= MPTCPS_FASTCLOSE_WAIT
;
1693 DTRACE_MPTCP2(state__change
, struct mptcb
*, mp_tp
,
1694 uint32_t, 0 /* event */);
1695 mptcp_start_timer(mp_tp
, MPTT_FASTCLOSE
);
1699 /* Reset this flow */
1700 tp
->t_mpflags
|= TMPF_RESET
;
1702 if (tp
->t_inpcb
->inp_socket
!= NULL
) {
1703 soevent(tp
->t_inpcb
->inp_socket
,
1704 SO_FILT_HINT_LOCKED
| SO_FILT_HINT_MUSTRST
);
1710 mptcp_do_mpfail_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
)
1712 struct mptcb
*mp_tp
= NULL
;
1713 struct mptcp_mpfail_opt
*fail_opt
= (struct mptcp_mpfail_opt
*)cp
;
1715 if ((th
->th_flags
!= TH_ACK
) || (th
->th_flags
!= TH_RST
))
1718 if (fail_opt
->mfail_len
!= sizeof (struct mptcp_mpfail_opt
))
1721 mp_tp
= (struct mptcb
*)tp
->t_mptcb
;
1726 mp_tp
->mpt_flags
|= MPTCPF_RECVD_MPFAIL
;
1727 mp_tp
->mpt_dsn_at_csum_fail
= mptcp_hton64(fail_opt
->mfail_dsn
);
1730 mptcp_notify_mpfail(tp
->t_inpcb
->inp_socket
);
1734 tcp_do_mptcp_options(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
,
1735 struct tcpopt
*to
, int optlen
)
1739 /* All MPTCP options have atleast 4 bytes */
1743 mptcp_subtype
= (cp
[2] >> 4);
1745 switch (mptcp_subtype
) {
1747 mptcp_do_mpcapable_opt(tp
, cp
, th
, optlen
);
1750 mptcp_do_mpjoin_opt(tp
, cp
, th
, optlen
);
1753 mptcp_do_dss_opt(tp
, cp
, th
, optlen
);
1756 mptcp_do_fastclose_opt(tp
, cp
, th
);
1759 mptcp_do_mpfail_opt(tp
, cp
, th
);
1761 case MPO_ADD_ADDR
: /* fall through */
1762 case MPO_REMOVE_ADDR
: /* fall through */
1764 to
->to_flags
|= TOF_MPTCP
;
1767 printf("%s: type = %d\n", __func__
, mptcp_subtype
);
1774 * MPTCP ADD_ADDR and REMOVE_ADDR options
1778 * ADD_ADDR is only placeholder code - not sent on wire
1779 * The ADD_ADDR option is not sent on wire because of security issues
1780 * around connection hijacking.
1783 mptcp_send_addaddr_opt(struct tcpcb
*tp
, struct mptcp_addaddr_opt
*opt
)
1786 opt
->ma_kind
= TCPOPT_MULTIPATH
;
1787 opt
->ma_len
= sizeof (struct mptcp_addaddr_opt
);
1788 opt
->ma_subtype
= MPO_ADD_ADDR
;
1789 opt
->ma_addr_id
= tp
->t_local_aid
;
1791 struct inpcb
*inp
= tp
->t_inpcb
;
1792 if (inp
->inp_vflag
== AF_INET
) {
1793 opt
->ma_ipver
= MA_IPVer_V4
;
1794 bcopy((char *)&sin
->sin_addr
.s_addr
, (char *)opt
+ opt
->ma_len
,
1795 sizeof (in_addr_t
));
1796 opt
->ma_len
+= sizeof (in_addr_t
);
1797 } else if (inp
->inp_vflag
== AF_INET6
) {
1798 opt
->ma_ipver
= MA_IPVer_V6
;
1799 bcopy((char *)&sin6
->sin6_addr
, (char *)opt
+ opt
->ma_len
,
1800 sizeof (struct in6_addr
));
1801 opt
->ma_len
+= sizeof (struct in6_addr
);
1804 if (tp
->t_mp_port
) {
1811 /* REMOVE_ADDR option is sent when a source address goes away */
1813 mptcp_send_remaddr_opt(struct tcpcb
*tp
, struct mptcp_remaddr_opt
*opt
)
1815 if (mptcp_dbg
>= MP_ERR_DEBUG
)
1816 printf("%s: local id %d remove id %d \n", __func__
,
1817 tp
->t_local_aid
, tp
->t_rem_aid
);
1819 bzero(opt
, sizeof (opt
));
1820 opt
->mr_kind
= TCPOPT_MULTIPATH
;
1821 opt
->mr_len
= sizeof (opt
);
1822 opt
->mr_subtype
= MPO_REMOVE_ADDR
;
1823 opt
->mr_addr_id
= tp
->t_rem_aid
;
1824 tp
->t_mpflags
&= ~TMPF_SND_REM_ADDR
;
1828 * MPTCP MP_PRIO option
1833 * Current implementation drops incoming MP_PRIO option and this code is
1834 * just a placeholder. The option is dropped because only the mobile client can
1835 * decide which of the subflows is preferred (usually wifi is preferred
1839 mptcp_do_mpprio_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
,
1843 struct mptcp_mpprio_opt
*mpprio
= (struct mptcp_mpprio_opt
*)cp
;
1845 if ((tp
== NULL
) || !(tp
->t_mpflags
& TMPF_MPTCP_TRUE
))
1848 if ((mpprio
->mpprio_len
!= sizeof (struct mptcp_mpprio_addr_opt
)) &&
1849 (mpprio
->mpprio_len
!= sizeof (struct mptcp_mpprio_opt
)))
1854 /* We send MP_PRIO option based on the values set by the SIOCSCONNORDER ioctl */
1856 mptcp_snd_mpprio(struct tcpcb
*tp
, u_char
*cp
, int optlen
)
1858 struct mptcp_mpprio_addr_opt mpprio
;
1860 if (tp
->t_state
!= TCPS_ESTABLISHED
) {
1861 tp
->t_mpflags
&= ~TMPF_SND_MPPRIO
;
1865 if (mptcp_mpprio_enable
!= 1) {
1866 tp
->t_mpflags
&= ~TMPF_SND_MPPRIO
;
1870 if ((MAX_TCPOPTLEN
- optlen
) <
1871 (int)sizeof (mpprio
))
1874 bzero(&mpprio
, sizeof (mpprio
));
1875 mpprio
.mpprio_kind
= TCPOPT_MULTIPATH
;
1876 mpprio
.mpprio_len
= sizeof (mpprio
);
1877 mpprio
.mpprio_subtype
= MPO_PRIO
;
1878 if (tp
->t_mpflags
& TMPF_BACKUP_PATH
)
1879 mpprio
.mpprio_flags
|= MPTCP_MPPRIO_BKP
;
1880 mpprio
.mpprio_addrid
= tp
->t_local_aid
;
1881 memcpy(cp
+ optlen
, &mpprio
, sizeof (mpprio
));
1882 optlen
+= sizeof (mpprio
);
1883 tp
->t_mpflags
&= ~TMPF_SND_MPPRIO
;
1884 if (mptcp_dbg
>= MP_ERR_DEBUG
)
1885 printf("%s: aid = %d \n", __func__
, tp
->t_local_aid
);