2 * Copyright (c) 2012-2016 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>
33 #include <sys/syslog.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_cache.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>
57 * SYSCTL for enforcing 64 bit dsn
59 int32_t force_64bit_dsn
= 0;
60 SYSCTL_INT(_net_inet_mptcp
, OID_AUTO
, force_64bit_dsn
,
61 CTLFLAG_RW
|CTLFLAG_LOCKED
, &force_64bit_dsn
, 0,
62 "Force MPTCP 64bit dsn");
65 static int mptcp_validate_join_hmac(struct tcpcb
*, u_char
*, int);
66 static int mptcp_snd_mpprio(struct tcpcb
*tp
, u_char
*cp
, int optlen
);
69 * MPTCP Options Output Processing
73 mptcp_setup_first_subflow_syn_opts(struct socket
*so
, int flags
, u_char
*opt
,
76 struct tcpcb
*tp
= sototcpcb(so
);
77 struct mptcb
*mp_tp
= NULL
;
81 * Avoid retransmitting the MP_CAPABLE option.
83 if (tp
->t_rxtshift
> mptcp_mpcap_retries
) {
84 if (!(mp_tp
->mpt_flags
& (MPTCPF_FALLBACK_HEURISTIC
| MPTCPF_HEURISTIC_TRAC
))) {
85 mp_tp
->mpt_flags
|= MPTCPF_HEURISTIC_TRAC
;
86 tcp_heuristic_mptcp_loss(tp
);
91 if (!tcp_heuristic_do_mptcp(tp
)) {
92 mp_tp
->mpt_flags
|= MPTCPF_FALLBACK_HEURISTIC
;
96 if ((flags
& (TH_SYN
| TH_ACK
)) == (TH_SYN
| TH_ACK
)) {
97 struct mptcp_mpcapable_opt_rsp mptcp_opt
;
98 mptcp_key_t mp_localkey
= 0;
100 mp_localkey
= mptcp_get_localkey(mp_tp
);
101 if (mp_localkey
== 0) {
102 /* an embryonic connection was closed from above */
106 sizeof (struct mptcp_mpcapable_opt_rsp
));
107 mptcp_opt
.mmc_common
.mmco_kind
= TCPOPT_MULTIPATH
;
108 mptcp_opt
.mmc_common
.mmco_len
=
109 sizeof (struct mptcp_mpcapable_opt_rsp
);
110 mptcp_opt
.mmc_common
.mmco_subtype
= MPO_CAPABLE
;
111 MPT_LOCK_SPIN(mp_tp
);
112 mptcp_opt
.mmc_common
.mmco_version
= mp_tp
->mpt_version
;
113 mptcp_opt
.mmc_common
.mmco_flags
|= MPCAP_PROPOSAL_SBIT
;
114 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
)
115 mptcp_opt
.mmc_common
.mmco_flags
|=
118 mptcp_opt
.mmc_localkey
= mp_localkey
;
119 memcpy(opt
+ optlen
, &mptcp_opt
,
120 mptcp_opt
.mmc_common
.mmco_len
);
121 optlen
+= mptcp_opt
.mmc_common
.mmco_len
;
123 /* Only the SYN flag is set */
124 struct mptcp_mpcapable_opt_common mptcp_opt
;
125 mptcp_key_t mp_localkey
= 0;
126 mp_localkey
= mptcp_get_localkey(mp_tp
);
127 so
->so_flags
|= SOF_MPTCP_CLIENT
;
128 if (mp_localkey
== 0) {
129 /* an embryonic connection was closed */
133 sizeof (struct mptcp_mpcapable_opt_common
));
134 mptcp_opt
.mmco_kind
= TCPOPT_MULTIPATH
;
136 sizeof (struct mptcp_mpcapable_opt_common
) +
137 sizeof (mptcp_key_t
);
138 mptcp_opt
.mmco_subtype
= MPO_CAPABLE
;
139 MPT_LOCK_SPIN(mp_tp
);
140 mptcp_opt
.mmco_version
= mp_tp
->mpt_version
;
141 mptcp_opt
.mmco_flags
|= MPCAP_PROPOSAL_SBIT
;
142 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
)
143 mptcp_opt
.mmco_flags
|= MPCAP_CHECKSUM_CBIT
;
145 (void) memcpy(opt
+ optlen
, &mptcp_opt
,
146 sizeof (struct mptcp_mpcapable_opt_common
));
147 optlen
+= sizeof (struct mptcp_mpcapable_opt_common
);
148 (void) memcpy(opt
+ optlen
, &mp_localkey
,
149 sizeof (mptcp_key_t
));
150 optlen
+= sizeof (mptcp_key_t
);
157 mptcp_setup_join_subflow_syn_opts(struct socket
*so
, int flags
, u_char
*opt
,
160 struct inpcb
*inp
= sotoinpcb(so
);
161 struct tcpcb
*tp
= NULL
;
173 if ((flags
& (TH_SYN
| TH_ACK
)) == (TH_SYN
| TH_ACK
)) {
174 struct mptcp_mpjoin_opt_rsp mpjoin_rsp
;
175 struct mptcb
*mp_tp
= tptomptp(tp
);
181 if (mptcp_get_localkey(mp_tp
) == 0) {
186 bzero(&mpjoin_rsp
, sizeof (mpjoin_rsp
));
187 mpjoin_rsp
.mmjo_kind
= TCPOPT_MULTIPATH
;
188 mpjoin_rsp
.mmjo_len
= sizeof (mpjoin_rsp
);
189 mpjoin_rsp
.mmjo_subtype_bkp
= MPO_JOIN
<< 4;
190 if (tp
->t_mpflags
& TMPF_BACKUP_PATH
)
191 mpjoin_rsp
.mmjo_subtype_bkp
|= MPTCP_BACKUP
;
192 mpjoin_rsp
.mmjo_addr_id
= tp
->t_local_aid
;
193 mptcp_get_rands(tp
->t_local_aid
, tptomptp(tp
),
194 &mpjoin_rsp
.mmjo_rand
, NULL
);
195 mpjoin_rsp
.mmjo_mac
= mptcp_get_trunced_hmac(tp
->t_local_aid
,
197 memcpy(opt
+ optlen
, &mpjoin_rsp
, mpjoin_rsp
.mmjo_len
);
198 optlen
+= mpjoin_rsp
.mmjo_len
;
200 struct mptcp_mpjoin_opt_req mpjoin_req
;
202 bzero(&mpjoin_req
, sizeof (mpjoin_req
));
203 mpjoin_req
.mmjo_kind
= TCPOPT_MULTIPATH
;
204 mpjoin_req
.mmjo_len
= sizeof (mpjoin_req
);
205 mpjoin_req
.mmjo_subtype_bkp
= MPO_JOIN
<< 4;
206 if (tp
->t_mpflags
& TMPF_BACKUP_PATH
)
207 mpjoin_req
.mmjo_subtype_bkp
|= MPTCP_BACKUP
;
208 mpjoin_req
.mmjo_addr_id
= tp
->t_local_aid
;
209 mpjoin_req
.mmjo_peer_token
= mptcp_get_remotetoken(tp
->t_mptcb
);
210 if (mpjoin_req
.mmjo_peer_token
== 0) {
211 mptcplog((LOG_DEBUG
, "MPTCP Socket: %s: peer token 0",
213 MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_ERR
);
215 mptcp_get_rands(tp
->t_local_aid
, tptomptp(tp
),
216 &mpjoin_req
.mmjo_rand
, NULL
);
217 memcpy(opt
+ optlen
, &mpjoin_req
, mpjoin_req
.mmjo_len
);
218 optlen
+= mpjoin_req
.mmjo_len
;
219 /* send an event up, if Fast Join is requested */
220 if (mptcp_zerortt_fastjoin
&&
221 (so
->so_flags
& SOF_MPTCP_FASTJOIN
)) {
222 soevent(so
, (SO_FILT_HINT_LOCKED
| SO_FILT_HINT_MPFASTJ
));
229 mptcp_setup_join_ack_opts(struct tcpcb
*tp
, u_char
*opt
, unsigned optlen
)
232 struct mptcp_mpjoin_opt_rsp2 join_rsp2
;
234 if ((MAX_TCPOPTLEN
- optlen
) < sizeof (struct mptcp_mpjoin_opt_rsp2
)) {
235 printf("%s: no space left %d \n", __func__
, optlen
);
239 bzero(&join_rsp2
, sizeof (struct mptcp_mpjoin_opt_rsp2
));
240 join_rsp2
.mmjo_kind
= TCPOPT_MULTIPATH
;
241 join_rsp2
.mmjo_len
= sizeof (struct mptcp_mpjoin_opt_rsp2
);
242 join_rsp2
.mmjo_subtype
= MPO_JOIN
;
243 mptcp_get_hmac(tp
->t_local_aid
, tptomptp(tp
),
244 (u_char
*)&join_rsp2
.mmjo_mac
,
245 sizeof (join_rsp2
.mmjo_mac
));
246 memcpy(opt
+ optlen
, &join_rsp2
, join_rsp2
.mmjo_len
);
247 new_optlen
= optlen
+ join_rsp2
.mmjo_len
;
248 tp
->t_mpflags
|= TMPF_FASTJOINBY2_SEND
;
253 mptcp_setup_syn_opts(struct socket
*so
, int flags
, u_char
*opt
, unsigned optlen
)
257 if (!(so
->so_flags
& SOF_MP_SEC_SUBFLOW
)) {
258 new_optlen
= mptcp_setup_first_subflow_syn_opts(so
, flags
, opt
,
262 * To simulate SYN_ACK with no join opt, comment this line on
263 * OS X server side. This serves as a testing hook.
265 new_optlen
= mptcp_setup_join_subflow_syn_opts(so
, flags
, opt
,
272 mptcp_send_mpfail(struct tcpcb
*tp
, u_char
*opt
, unsigned int optlen
)
274 #pragma unused(tp, opt, optlen)
276 struct mptcb
*mp_tp
= NULL
;
277 struct mptcp_mpfail_opt fail_opt
;
279 int len
= sizeof (struct mptcp_mpfail_opt
);
281 mp_tp
= tptomptp(tp
);
283 tp
->t_mpflags
&= ~TMPF_SND_MPFAIL
;
287 /* if option space low give up */
288 if ((MAX_TCPOPTLEN
- optlen
) < sizeof (struct mptcp_mpfail_opt
)) {
289 tp
->t_mpflags
&= ~TMPF_SND_MPFAIL
;
294 dsn
= mp_tp
->mpt_rcvnxt
;
297 bzero(&fail_opt
, sizeof (fail_opt
));
298 fail_opt
.mfail_kind
= TCPOPT_MULTIPATH
;
299 fail_opt
.mfail_len
= len
;
300 fail_opt
.mfail_subtype
= MPO_FAIL
;
301 fail_opt
.mfail_dsn
= mptcp_hton64(dsn
);
302 memcpy(opt
+ optlen
, &fail_opt
, len
);
304 tp
->t_mpflags
&= ~TMPF_SND_MPFAIL
;
305 mptcplog((LOG_DEBUG
, "MPTCP Socket: %s: %d \n", __func__
,
306 tp
->t_local_aid
), (MPTCP_SOCKET_DBG
| MPTCP_SENDER_DBG
),
312 mptcp_send_infinite_mapping(struct tcpcb
*tp
, u_char
*opt
, unsigned int optlen
)
314 struct mptcp_dsn_opt infin_opt
;
315 struct mptcb
*mp_tp
= NULL
;
316 size_t len
= sizeof (struct mptcp_dsn_opt
);
317 struct socket
*so
= tp
->t_inpcb
->inp_socket
;
324 mp_tp
= tptomptp(tp
);
329 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
)
333 if ((MAX_TCPOPTLEN
- optlen
) < (len
+ csum_len
)) {
337 bzero(&infin_opt
, sizeof (infin_opt
));
338 infin_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
339 infin_opt
.mdss_copt
.mdss_len
= len
+ csum_len
;
340 infin_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
341 infin_opt
.mdss_copt
.mdss_flags
|= MDSS_M
;
342 if (mp_tp
->mpt_flags
& MPTCPF_RECVD_MPFAIL
) {
343 infin_opt
.mdss_dsn
= (u_int32_t
)
344 MPTCP_DATASEQ_LOW32(mp_tp
->mpt_dsn_at_csum_fail
);
345 infin_opt
.mdss_subflow_seqn
= mp_tp
->mpt_ssn_at_csum_fail
;
348 * If MPTCP fallback happens, but TFO succeeds, the data on the
349 * SYN does not belong to the MPTCP data sequence space.
351 if ((tp
->t_tfo_stats
& TFO_S_SYN_DATA_ACKED
) &&
352 ((mp_tp
->mpt_local_idsn
+ 1) == mp_tp
->mpt_snduna
)) {
353 infin_opt
.mdss_subflow_seqn
= 1;
355 mptcplog((LOG_DEBUG
, "MPTCP Socket: %s: idsn %llu"
356 "snduna %llu \n", __func__
, mp_tp
->mpt_local_idsn
,
358 (MPTCP_SOCKET_DBG
| MPTCP_SENDER_DBG
),
361 infin_opt
.mdss_subflow_seqn
= tp
->snd_una
- tp
->iss
;
363 infin_opt
.mdss_dsn
= (u_int32_t
)
364 MPTCP_DATASEQ_LOW32(mp_tp
->mpt_snduna
);
369 if ((infin_opt
.mdss_dsn
== 0) || (infin_opt
.mdss_subflow_seqn
== 0)) {
372 infin_opt
.mdss_dsn
= htonl(infin_opt
.mdss_dsn
);
373 infin_opt
.mdss_subflow_seqn
= htonl(infin_opt
.mdss_subflow_seqn
);
374 infin_opt
.mdss_data_len
= 0;
376 memcpy(opt
+ optlen
, &infin_opt
, len
);
379 /* The checksum field is set to 0 for infinite mapping */
381 memcpy(opt
+ optlen
, &csum
, csum_len
);
385 mptcplog((LOG_DEBUG
, "MPTCP Socket: %s: dsn = %x, seq = %x len = %x\n",
387 ntohl(infin_opt
.mdss_dsn
),
388 ntohl(infin_opt
.mdss_subflow_seqn
),
389 ntohs(infin_opt
.mdss_data_len
)),
390 (MPTCP_SOCKET_DBG
| MPTCP_SENDER_DBG
),
393 /* so->so_flags &= ~SOF_MPTCP_CLIENT; */
394 tp
->t_mpflags
|= TMPF_INFIN_SENT
;
395 tcpstat
.tcps_estab_fallback
++;
401 mptcp_ok_to_fin(struct tcpcb
*tp
, u_int64_t dsn
, u_int32_t datalen
)
403 struct mptcb
*mp_tp
= NULL
;
404 mp_tp
= tptomptp(tp
);
407 dsn
= (mp_tp
->mpt_sndmax
& MPTCP_DATASEQ_LOW32_MASK
) | dsn
;
408 if ((dsn
+ datalen
) == mp_tp
->mpt_sndmax
) {
417 mptcp_setup_opts(struct tcpcb
*tp
, int32_t off
, u_char
*opt
,
418 unsigned int optlen
, int flags
, int datalen
,
419 unsigned int **dss_lenp
, u_int8_t
**finp
, u_int64_t
*dss_valp
,
420 u_int32_t
**sseqp
, boolean_t
*p_mptcp_acknow
)
422 struct inpcb
*inp
= (struct inpcb
*)tp
->t_inpcb
;
423 struct socket
*so
= inp
->inp_socket
;
424 struct mptcb
*mp_tp
= tptomptp(tp
);
425 boolean_t do_csum
= FALSE
;
426 boolean_t send_64bit_dsn
= FALSE
;
427 boolean_t send_64bit_ack
= FALSE
;
428 u_int32_t old_mpt_flags
= tp
->t_mpflags
&
429 (TMPF_SND_MPPRIO
| TMPF_SND_REM_ADDR
| TMPF_SND_MPFAIL
|
430 TMPF_MPCAP_RETRANSMIT
);
432 if ((mptcp_enable
== 0) ||
434 (mp_tp
->mpt_flags
& MPTCPF_PEEL_OFF
) ||
435 (tp
->t_state
== TCPS_CLOSED
)) {
440 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
) {
444 /* tcp_output handles the SYN path separately */
445 if (flags
& TH_SYN
) {
449 if ((MAX_TCPOPTLEN
- optlen
) <
450 sizeof (struct mptcp_mpcapable_opt_common
)) {
451 mptcplog((LOG_ERR
, "MPTCP Socket: "
452 "%s: no space left %d flags %x "
454 "len %d\n", __func__
, optlen
, flags
, tp
->t_mpflags
,
455 datalen
), MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_ERR
);
459 if (tp
->t_mpflags
& TMPF_TCP_FALLBACK
) {
460 if (tp
->t_mpflags
& TMPF_SND_MPFAIL
)
461 optlen
= mptcp_send_mpfail(tp
, opt
, optlen
);
462 else if (!(tp
->t_mpflags
& TMPF_INFIN_SENT
))
463 optlen
= mptcp_send_infinite_mapping(tp
, opt
, optlen
);
467 if (((tp
->t_mpflags
& TMPF_FASTJOINBY2_SEND
) ||
468 (tp
->t_mpflags
& TMPF_FASTJOIN_SEND
)) &&
470 tp
->t_mpflags
&= ~TMPF_FASTJOINBY2_SEND
;
471 tp
->t_mpflags
&= ~TMPF_FASTJOIN_SEND
;
475 if (((tp
->t_mpflags
& TMPF_PREESTABLISHED
) &&
476 (!(tp
->t_mpflags
& TMPF_SENT_KEYS
)) &&
477 (!(tp
->t_mpflags
& TMPF_JOINED_FLOW
))) ||
478 (tp
->t_mpflags
& TMPF_MPCAP_RETRANSMIT
)) {
479 struct mptcp_mpcapable_opt_rsp1 mptcp_opt
;
480 if ((MAX_TCPOPTLEN
- optlen
) <
481 sizeof (struct mptcp_mpcapable_opt_rsp1
))
483 bzero(&mptcp_opt
, sizeof (struct mptcp_mpcapable_opt_rsp1
));
484 mptcp_opt
.mmc_common
.mmco_kind
= TCPOPT_MULTIPATH
;
485 mptcp_opt
.mmc_common
.mmco_len
=
486 sizeof (struct mptcp_mpcapable_opt_rsp1
);
487 mptcp_opt
.mmc_common
.mmco_subtype
= MPO_CAPABLE
;
488 mptcp_opt
.mmc_common
.mmco_version
= mp_tp
->mpt_version
;
489 /* HMAC-SHA1 is the proposal */
490 mptcp_opt
.mmc_common
.mmco_flags
|= MPCAP_PROPOSAL_SBIT
;
492 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
)
493 mptcp_opt
.mmc_common
.mmco_flags
|= MPCAP_CHECKSUM_CBIT
;
494 mptcp_opt
.mmc_localkey
= mptcp_get_localkey(mp_tp
);
495 mptcp_opt
.mmc_remotekey
= mptcp_get_remotekey(mp_tp
);
497 memcpy(opt
+ optlen
, &mptcp_opt
, mptcp_opt
.mmc_common
.mmco_len
);
498 optlen
+= mptcp_opt
.mmc_common
.mmco_len
;
499 tp
->t_mpflags
|= TMPF_SENT_KEYS
| TMPF_MPTCP_TRUE
;
500 so
->so_flags
|= SOF_MPTCP_TRUE
;
501 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
502 tp
->t_mpflags
&= ~TMPF_MPCAP_RETRANSMIT
;
505 tp
->t_mpuna
= tp
->snd_una
;
507 /* its a retransmission of the MP_CAPABLE ACK */
512 if ((tp
->t_mpflags
& TMPF_JOINED_FLOW
) &&
513 (tp
->t_mpflags
& TMPF_PREESTABLISHED
) &&
514 (!(tp
->t_mpflags
& TMPF_RECVD_JOIN
)) &&
515 (tp
->t_mpflags
& TMPF_SENT_JOIN
) &&
516 (!(tp
->t_mpflags
& TMPF_MPTCP_TRUE
))) {
518 if (mptcp_get_localkey(mp_tp
) == 0) {
523 /* Do the ACK part */
524 optlen
= mptcp_setup_join_ack_opts(tp
, opt
, optlen
);
526 tp
->t_mpuna
= tp
->snd_una
;
528 /* Start a timer to retransmit the ACK */
529 tp
->t_timer
[TCPT_JACK_RXMT
] =
530 OFFSET_FROM_START(tp
, tcp_jack_rxmt
);
534 if (!(tp
->t_mpflags
& TMPF_MPTCP_TRUE
))
538 * From here on, all options are sent only if MPTCP_TRUE
539 * or when data is sent early on as in Fast Join
542 if ((tp
->t_mpflags
& TMPF_MPTCP_TRUE
) &&
543 (tp
->t_mpflags
& TMPF_SND_REM_ADDR
)) {
544 int rem_opt_len
= sizeof (struct mptcp_remaddr_opt
);
545 if ((optlen
+ rem_opt_len
) <= MAX_TCPOPTLEN
) {
546 mptcp_send_remaddr_opt(tp
,
547 (struct mptcp_remaddr_opt
*)(opt
+ optlen
));
548 optlen
+= rem_opt_len
;
550 tp
->t_mpflags
&= ~TMPF_SND_REM_ADDR
;
554 if (tp
->t_mpflags
& TMPF_SND_MPPRIO
) {
555 optlen
= mptcp_snd_mpprio(tp
, opt
, optlen
);
559 if ((mp_tp
->mpt_flags
& MPTCPF_SND_64BITDSN
) || force_64bit_dsn
) {
560 send_64bit_dsn
= TRUE
;
562 if (mp_tp
->mpt_flags
& MPTCPF_SND_64BITACK
)
563 send_64bit_ack
= TRUE
;
567 #define CHECK_OPTLEN { \
568 if ((MAX_TCPOPTLEN - optlen) < len) { \
569 mptcplog((LOG_ERR, "MPTCP Socket: " \
570 "%s: len %d optlen %d \n", __func__, len, optlen), \
571 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR); \
576 #define DO_FIN(dsn_opt) { \
578 sndfin = mptcp_ok_to_fin(tp, dsn_opt.mdss_dsn, datalen); \
580 dsn_opt.mdss_copt.mdss_flags |= MDSS_F; \
581 *finp = opt + optlen + offsetof(struct mptcp_dss_copt, \
583 dsn_opt.mdss_data_len += 1; \
587 #define CHECK_DATALEN { \
588 /* MPTCP socket does not support IP options */ \
589 if ((datalen + optlen + len) > tp->t_maxopd) { \
590 mptcplog((LOG_ERR, "MPTCP Socket: " \
591 "%s: nosp %d len %d opt %d %d %d\n", \
592 __func__, datalen, len, optlen, \
593 tp->t_maxseg, tp->t_maxopd), \
594 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR); \
595 /* remove option length from payload len */ \
596 datalen = tp->t_maxopd - optlen - len; \
600 if ((tp
->t_mpflags
& TMPF_SEND_DSN
) &&
603 * If there was the need to send 64-bit Data ACK along
604 * with 64-bit DSN, then 26 or 28 bytes would be used.
605 * With timestamps and NOOP padding that will cause
606 * overflow. Hence, in the rare event that both 64-bit
607 * DSN and 64-bit ACK have to be sent, delay the send of
608 * 64-bit ACK until our 64-bit DSN is acked with a 64-bit ack.
609 * XXX If this delay causes issue, remove the 2-byte padding.
611 struct mptcp_dss64_ack32_opt dsn_ack_opt
;
612 unsigned int len
= sizeof (dsn_ack_opt
);
620 bzero(&dsn_ack_opt
, sizeof (dsn_ack_opt
));
621 dsn_ack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
622 dsn_ack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
623 dsn_ack_opt
.mdss_copt
.mdss_len
= len
;
624 dsn_ack_opt
.mdss_copt
.mdss_flags
|=
625 MDSS_M
| MDSS_m
| MDSS_A
;
629 mptcp_output_getm_dsnmap64(so
, off
, (u_int32_t
)datalen
,
630 &dsn_ack_opt
.mdss_dsn
,
631 &dsn_ack_opt
.mdss_subflow_seqn
,
632 &dsn_ack_opt
.mdss_data_len
);
634 *dss_valp
= dsn_ack_opt
.mdss_dsn
;
636 if ((dsn_ack_opt
.mdss_data_len
== 0) ||
637 (dsn_ack_opt
.mdss_dsn
== 0)) {
641 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
646 dsn_ack_opt
.mdss_ack
=
647 htonl(MPTCP_DATAACK_LOW32(mp_tp
->mpt_rcvnxt
));
650 dsn_ack_opt
.mdss_dsn
= mptcp_hton64(dsn_ack_opt
.mdss_dsn
);
651 dsn_ack_opt
.mdss_subflow_seqn
= htonl(
652 dsn_ack_opt
.mdss_subflow_seqn
);
653 dsn_ack_opt
.mdss_data_len
= htons(
654 dsn_ack_opt
.mdss_data_len
);
655 *dss_lenp
= (unsigned int *)(void *)(opt
+ optlen
+
656 offsetof(struct mptcp_dss64_ack32_opt
, mdss_data_len
));
658 memcpy(opt
+ optlen
, &dsn_ack_opt
, sizeof (dsn_ack_opt
));
661 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
662 offsetof(struct mptcp_dss64_ack32_opt
,
666 mptcplog((LOG_DEBUG
,"MPTCP Socket: "
667 "%s: long DSS = %llx ACK = %llx \n",
669 mptcp_ntoh64(dsn_ack_opt
.mdss_dsn
),
670 mptcp_ntoh64(dsn_ack_opt
.mdss_ack
)),
671 MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_LOG
);
673 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
677 if ((tp
->t_mpflags
& TMPF_SEND_DSN
) &&
679 !(tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
)) {
680 struct mptcp_dsn_opt dsn_opt
;
681 unsigned int len
= sizeof (struct mptcp_dsn_opt
);
689 bzero(&dsn_opt
, sizeof (dsn_opt
));
690 dsn_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
691 dsn_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
692 dsn_opt
.mdss_copt
.mdss_len
= len
;
693 dsn_opt
.mdss_copt
.mdss_flags
|= MDSS_M
;
697 mptcp_output_getm_dsnmap32(so
, off
, (u_int32_t
)datalen
,
699 &dsn_opt
.mdss_subflow_seqn
, &dsn_opt
.mdss_data_len
,
702 if ((dsn_opt
.mdss_data_len
== 0) ||
703 (dsn_opt
.mdss_dsn
== 0)) {
707 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
711 dsn_opt
.mdss_dsn
= htonl(dsn_opt
.mdss_dsn
);
712 dsn_opt
.mdss_subflow_seqn
= htonl(dsn_opt
.mdss_subflow_seqn
);
713 dsn_opt
.mdss_data_len
= htons(dsn_opt
.mdss_data_len
);
714 *dss_lenp
= (unsigned int *)(void *)(opt
+ optlen
+
715 offsetof(struct mptcp_dsn_opt
, mdss_data_len
));
716 memcpy(opt
+ optlen
, &dsn_opt
, sizeof (dsn_opt
));
718 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
719 offsetof(struct mptcp_dsn_opt
, mdss_subflow_seqn
));
722 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
726 /* 32-bit Data ACK option */
727 if ((tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
) &&
729 !(tp
->t_mpflags
& TMPF_SEND_DSN
) &&
730 !(tp
->t_mpflags
& TMPF_SEND_DFIN
)) {
732 struct mptcp_data_ack_opt dack_opt
;
733 unsigned int len
= 0;
735 len
= sizeof (dack_opt
);
739 bzero(&dack_opt
, len
);
740 dack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
741 dack_opt
.mdss_copt
.mdss_len
= len
;
742 dack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
743 dack_opt
.mdss_copt
.mdss_flags
|= MDSS_A
;
744 MPT_LOCK_SPIN(mp_tp
);
746 htonl(MPTCP_DATAACK_LOW32(mp_tp
->mpt_rcvnxt
));
748 memcpy(opt
+ optlen
, &dack_opt
, len
);
750 VERIFY(optlen
<= MAX_TCPOPTLEN
);
751 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
755 /* 64-bit Data ACK option */
756 if ((tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
) &&
758 !(tp
->t_mpflags
& TMPF_SEND_DSN
) &&
759 !(tp
->t_mpflags
& TMPF_SEND_DFIN
)) {
760 struct mptcp_data_ack64_opt dack_opt
;
761 unsigned int len
= 0;
763 len
= sizeof (dack_opt
);
767 bzero(&dack_opt
, len
);
768 dack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
769 dack_opt
.mdss_copt
.mdss_len
= len
;
770 dack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
771 dack_opt
.mdss_copt
.mdss_flags
|= (MDSS_A
| MDSS_a
);
772 MPT_LOCK_SPIN(mp_tp
);
773 dack_opt
.mdss_ack
= mptcp_hton64(mp_tp
->mpt_rcvnxt
);
775 * The other end should retransmit 64-bit DSN until it
776 * receives a 64-bit ACK.
778 mp_tp
->mpt_flags
&= ~MPTCPF_SND_64BITACK
;
780 memcpy(opt
+ optlen
, &dack_opt
, len
);
782 VERIFY(optlen
<= MAX_TCPOPTLEN
);
783 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
787 /* 32-bit DSS+Data ACK option */
788 if ((tp
->t_mpflags
& TMPF_SEND_DSN
) &&
791 (tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
)) {
792 struct mptcp_dss_ack_opt dss_ack_opt
;
793 unsigned int len
= sizeof (dss_ack_opt
);
800 bzero(&dss_ack_opt
, sizeof (dss_ack_opt
));
801 dss_ack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
802 dss_ack_opt
.mdss_copt
.mdss_len
= len
;
803 dss_ack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
804 dss_ack_opt
.mdss_copt
.mdss_flags
|= MDSS_A
| MDSS_M
;
805 MPT_LOCK_SPIN(mp_tp
);
806 dss_ack_opt
.mdss_ack
=
807 htonl(MPTCP_DATAACK_LOW32(mp_tp
->mpt_rcvnxt
));
812 mptcp_output_getm_dsnmap32(so
, off
, (u_int32_t
)datalen
,
813 &dss_ack_opt
.mdss_dsn
,
814 &dss_ack_opt
.mdss_subflow_seqn
,
815 &dss_ack_opt
.mdss_data_len
,
818 if ((dss_ack_opt
.mdss_data_len
== 0) ||
819 (dss_ack_opt
.mdss_dsn
== 0)) {
823 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
827 dss_ack_opt
.mdss_dsn
= htonl(dss_ack_opt
.mdss_dsn
);
828 dss_ack_opt
.mdss_subflow_seqn
=
829 htonl(dss_ack_opt
.mdss_subflow_seqn
);
830 dss_ack_opt
.mdss_data_len
= htons(dss_ack_opt
.mdss_data_len
);
831 *dss_lenp
= (unsigned int *)(void *)(opt
+ optlen
+
832 offsetof(struct mptcp_dss_ack_opt
, mdss_data_len
));
833 memcpy(opt
+ optlen
, &dss_ack_opt
, sizeof (dss_ack_opt
));
835 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
836 offsetof(struct mptcp_dss_ack_opt
,
842 if (optlen
> MAX_TCPOPTLEN
)
843 panic("optlen too large");
844 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
848 /* 32-bit DSS + 64-bit DACK option */
849 if ((tp
->t_mpflags
& TMPF_SEND_DSN
) &&
852 (tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
)) {
853 struct mptcp_dss32_ack64_opt dss_ack_opt
;
854 unsigned int len
= sizeof (dss_ack_opt
);
861 bzero(&dss_ack_opt
, sizeof (dss_ack_opt
));
862 dss_ack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
863 dss_ack_opt
.mdss_copt
.mdss_len
= len
;
864 dss_ack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
865 dss_ack_opt
.mdss_copt
.mdss_flags
|= MDSS_M
| MDSS_A
| MDSS_a
;
866 MPT_LOCK_SPIN(mp_tp
);
867 dss_ack_opt
.mdss_ack
=
868 mptcp_hton64(mp_tp
->mpt_rcvnxt
);
873 mptcp_output_getm_dsnmap32(so
, off
, (u_int32_t
)datalen
,
874 &dss_ack_opt
.mdss_dsn
, &dss_ack_opt
.mdss_subflow_seqn
,
875 &dss_ack_opt
.mdss_data_len
, dss_valp
);
877 if ((dss_ack_opt
.mdss_data_len
== 0) ||
878 (dss_ack_opt
.mdss_dsn
== 0)) {
882 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
886 dss_ack_opt
.mdss_dsn
= htonl(dss_ack_opt
.mdss_dsn
);
887 dss_ack_opt
.mdss_subflow_seqn
=
888 htonl(dss_ack_opt
.mdss_subflow_seqn
);
889 dss_ack_opt
.mdss_data_len
= htons(dss_ack_opt
.mdss_data_len
);
890 *dss_lenp
= (unsigned int *)(void *)(opt
+ optlen
+
891 offsetof(struct mptcp_dss32_ack64_opt
, mdss_data_len
));
892 memcpy(opt
+ optlen
, &dss_ack_opt
, sizeof (dss_ack_opt
));
894 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
895 offsetof(struct mptcp_dss32_ack64_opt
,
901 if (optlen
> MAX_TCPOPTLEN
)
902 panic("optlen too large");
903 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
907 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
908 struct mptcp_dss_ack_opt dss_ack_opt
;
909 unsigned int len
= sizeof (struct mptcp_dss_ack_opt
);
916 bzero(&dss_ack_opt
, sizeof (dss_ack_opt
));
920 * Data FIN occupies one sequence space.
921 * Don't send it if it has been Acked.
923 if (((mp_tp
->mpt_sndnxt
+ 1) != mp_tp
->mpt_sndmax
) ||
924 (mp_tp
->mpt_snduna
== mp_tp
->mpt_sndmax
)) {
929 dss_ack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
930 dss_ack_opt
.mdss_copt
.mdss_len
= len
;
931 dss_ack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
932 dss_ack_opt
.mdss_copt
.mdss_flags
|= MDSS_A
| MDSS_M
| MDSS_F
;
933 dss_ack_opt
.mdss_ack
=
934 htonl(MPTCP_DATAACK_LOW32(mp_tp
->mpt_rcvnxt
));
935 dss_ack_opt
.mdss_dsn
=
936 htonl(MPTCP_DATASEQ_LOW32(mp_tp
->mpt_sndnxt
));
938 dss_ack_opt
.mdss_subflow_seqn
= 0;
939 dss_ack_opt
.mdss_data_len
= 1;
940 dss_ack_opt
.mdss_data_len
= htons(dss_ack_opt
.mdss_data_len
);
941 memcpy(opt
+ optlen
, &dss_ack_opt
, sizeof (dss_ack_opt
));
943 *dss_valp
= mp_tp
->mpt_sndnxt
;
944 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
945 offsetof(struct mptcp_dss_ack_opt
,
952 if (TRUE
== *p_mptcp_acknow
) {
953 VERIFY(old_mpt_flags
!= 0);
954 u_int32_t new_mpt_flags
= tp
->t_mpflags
&
955 (TMPF_SND_MPPRIO
| TMPF_SND_REM_ADDR
| TMPF_SND_MPFAIL
|
956 TMPF_MPCAP_RETRANSMIT
);
959 * If none of the above mpflags were acted on by
960 * this routine, reset these flags and set p_mptcp_acknow
962 * XXX The reset value of p_mptcp_acknow can be used
963 * to communicate tcp_output to NOT send a pure ack without any
964 * MPTCP options as it will be treated as a dup ack.
965 * Since the instances of mptcp_setup_opts not acting on
966 * these options are mostly corner cases and sending a dup
967 * ack here would only have an impact if the system
968 * has sent consecutive dup acks before this false one,
969 * we haven't modified the logic in tcp_output to avoid
972 if ((old_mpt_flags
== new_mpt_flags
) || (new_mpt_flags
== 0)) {
973 tp
->t_mpflags
&= ~(TMPF_SND_MPPRIO
974 | TMPF_SND_REM_ADDR
| TMPF_SND_MPFAIL
|
975 TMPF_MPCAP_RETRANSMIT
);
976 *p_mptcp_acknow
= FALSE
;
977 mptcplog((LOG_DEBUG
, "MPTCP Sender: %s: no action \n",
978 __func__
), MPTCP_SENDER_DBG
, MPTCP_LOGLVL_LOG
);
980 mptcplog((LOG_DEBUG
, "MPTCP Sender: acknow set, "
981 "old flags %x new flags %x \n",
982 old_mpt_flags
, new_mpt_flags
),
983 MPTCP_SENDER_DBG
, MPTCP_LOGLVL_LOG
);
991 * MPTCP Options Input Processing
995 mptcp_sanitize_option(struct tcpcb
*tp
, int mptcp_subtype
)
997 struct mptcb
*mp_tp
= tptomptp(tp
);
1000 if (mp_tp
== NULL
) {
1001 mptcplog((LOG_ERR
, "MPTCP Socket: %s: NULL mpsocket \n",
1002 __func__
), MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_ERR
);
1006 switch (mptcp_subtype
) {
1009 case MPO_JOIN
: /* fall through */
1010 case MPO_DSS
: /* fall through */
1011 case MPO_FASTCLOSE
: /* fall through */
1012 case MPO_FAIL
: /* fall through */
1013 case MPO_REMOVE_ADDR
: /* fall through */
1014 case MPO_ADD_ADDR
: /* fall through */
1015 case MPO_PRIO
: /* fall through */
1016 if (mp_tp
->mpt_state
< MPTCPS_ESTABLISHED
)
1021 mptcplog((LOG_ERR
, "MPTCP Socket: "
1022 "%s: type = %d \n", __func__
,
1024 MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_ERR
);
1031 mptcp_valid_mpcapable_common_opt(u_char
*cp
)
1033 struct mptcp_mpcapable_opt_common
*rsp
=
1034 (struct mptcp_mpcapable_opt_common
*)cp
;
1036 /* mmco_kind, mmco_len and mmco_subtype are validated before */
1038 if (!(rsp
->mmco_flags
& MPCAP_PROPOSAL_SBIT
))
1041 if (rsp
->mmco_flags
& (MPCAP_BBIT
| MPCAP_CBIT
| MPCAP_DBIT
|
1042 MPCAP_EBIT
| MPCAP_FBIT
| MPCAP_GBIT
))
1050 mptcp_do_mpcapable_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
,
1053 struct mptcp_mpcapable_opt_rsp
*rsp
= NULL
;
1054 struct mptcb
*mp_tp
= tptomptp(tp
);
1056 /* Only valid on SYN/ACK */
1057 if ((th
->th_flags
& (TH_SYN
| TH_ACK
)) != (TH_SYN
| TH_ACK
))
1060 /* Validate the kind, len, flags */
1061 if (mptcp_valid_mpcapable_common_opt(cp
) != 1) {
1062 tcpstat
.tcps_invalid_mpcap
++;
1066 /* Handle old duplicate SYN/ACK retransmission */
1067 if (SEQ_GT(tp
->rcv_nxt
, (tp
->irs
+ 1)))
1070 /* handle SYN/ACK retransmission by acknowledging with ACK */
1071 if (mp_tp
->mpt_state
>= MPTCPS_ESTABLISHED
) {
1072 tp
->t_mpflags
|= TMPF_MPCAP_RETRANSMIT
;
1076 /* A SYN/ACK contains peer's key and flags */
1077 if (optlen
!= sizeof (struct mptcp_mpcapable_opt_rsp
)) {
1079 mptcplog((LOG_ERR
, "MPTCP Socket: "
1080 "%s: SYN_ACK optlen = %d, sizeof mp opt = %lu \n",
1082 sizeof (struct mptcp_mpcapable_opt_rsp
)),
1083 MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_ERR
);
1084 tcpstat
.tcps_invalid_mpcap
++;
1089 * If checksum flag is set, enable MPTCP checksum, even if
1090 * it was not negotiated on the first SYN.
1092 if (((struct mptcp_mpcapable_opt_common
*)cp
)->mmco_flags
&
1093 MPCAP_CHECKSUM_CBIT
)
1094 mp_tp
->mpt_flags
|= MPTCPF_CHECKSUM
;
1096 rsp
= (struct mptcp_mpcapable_opt_rsp
*)cp
;
1098 mp_tp
->mpt_remotekey
= rsp
->mmc_localkey
;
1099 /* For now just downgrade to the peer's version */
1100 mp_tp
->mpt_peer_version
= rsp
->mmc_common
.mmco_version
;
1101 if (rsp
->mmc_common
.mmco_version
< mp_tp
->mpt_version
) {
1102 mp_tp
->mpt_version
= rsp
->mmc_common
.mmco_version
;
1103 tcpstat
.tcps_mp_verdowngrade
++;
1105 if (mptcp_init_remote_parms(mp_tp
) != 0) {
1106 tcpstat
.tcps_invalid_mpcap
++;
1111 tcp_heuristic_mptcp_success(tp
);
1112 tp
->t_mpflags
|= TMPF_PREESTABLISHED
;
1117 mptcp_do_mpjoin_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
, int optlen
)
1119 #define MPTCP_JOPT_ERROR_PATH(tp) { \
1120 tp->t_mpflags |= TMPF_RESET; \
1121 tcpstat.tcps_invalid_joins++; \
1122 if (tp->t_inpcb->inp_socket != NULL) { \
1123 soevent(tp->t_inpcb->inp_socket, \
1124 SO_FILT_HINT_LOCKED | SO_FILT_HINT_MUSTRST); \
1128 struct mptcp_mpjoin_opt_rsp
*join_rsp
=
1129 (struct mptcp_mpjoin_opt_rsp
*)cp
;
1131 /* Only valid on SYN/ACK */
1132 if ((th
->th_flags
& (TH_SYN
| TH_ACK
)) != (TH_SYN
| TH_ACK
))
1135 if (optlen
!= sizeof (struct mptcp_mpjoin_opt_rsp
)) {
1136 mptcplog((LOG_ERR
, "MPTCP Socket: "
1137 "SYN_ACK: unexpected optlen = %d mp "
1138 "option = %lu\n", optlen
,
1139 sizeof (struct mptcp_mpjoin_opt_rsp
)),
1140 MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_ERR
);
1141 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
1142 /* send RST and close */
1143 MPTCP_JOPT_ERROR_PATH(tp
);
1147 mptcp_set_raddr_rand(tp
->t_local_aid
, tptomptp(tp
),
1148 join_rsp
->mmjo_addr_id
, join_rsp
->mmjo_rand
);
1149 error
= mptcp_validate_join_hmac(tp
,
1150 (u_char
*)&join_rsp
->mmjo_mac
, SHA1_TRUNCATED
);
1152 mptcplog((LOG_ERR
, "MPTCP Socket: %s: "
1153 "SYN_ACK error = %d \n", __func__
, error
),
1154 MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_ERR
);
1155 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
1156 /* send RST and close */
1157 MPTCP_JOPT_ERROR_PATH(tp
);
1160 tp
->t_mpflags
|= TMPF_SENT_JOIN
;
1164 mptcp_validate_join_hmac(struct tcpcb
*tp
, u_char
* hmac
, int mac_len
)
1166 u_char digest
[SHA1_RESULTLEN
] = {0};
1167 struct mptcb
*mp_tp
= NULL
;
1168 mptcp_key_t rem_key
, loc_key
;
1169 u_int32_t rem_rand
, loc_rand
;
1171 mp_tp
= tp
->t_mptcb
;
1173 rem_rand
= loc_rand
= 0;
1176 rem_key
= mp_tp
->mpt_remotekey
;
1179 * Can happen if the MPTCP-connection is about to be closed and we
1180 * receive an MP_JOIN in-between the events are being handled by the
1183 if (mp_tp
->mpt_localkey
== NULL
) {
1188 loc_key
= *mp_tp
->mpt_localkey
;
1191 mptcp_get_rands(tp
->t_local_aid
, mp_tp
, &loc_rand
, &rem_rand
);
1192 if ((rem_rand
== 0) || (loc_rand
== 0))
1195 mptcp_hmac_sha1(rem_key
, loc_key
, rem_rand
, loc_rand
,
1196 digest
, sizeof (digest
));
1198 if (bcmp(digest
, hmac
, mac_len
) == 0)
1199 return (0); /* matches */
1201 printf("%s: remote key %llx local key %llx remote rand %x "
1202 "local rand %x \n", __func__
, rem_key
, loc_key
,
1203 rem_rand
, loc_rand
);
1209 mptcp_do_dss_opt_ack_meat(u_int64_t full_dack
, struct tcpcb
*tp
)
1211 struct mptcb
*mp_tp
= tptomptp(tp
);
1212 int close_notify
= 0;
1214 tp
->t_mpflags
|= TMPF_RCVD_DACK
;
1217 if (MPTCP_SEQ_LEQ(full_dack
, mp_tp
->mpt_sndmax
) &&
1218 MPTCP_SEQ_GEQ(full_dack
, mp_tp
->mpt_snduna
)) {
1219 mptcp_data_ack_rcvd(mp_tp
, tp
, full_dack
);
1220 if (mp_tp
->mpt_state
> MPTCPS_FIN_WAIT_2
)
1223 if (mp_tp
->mpt_flags
& MPTCPF_RCVD_64BITACK
) {
1224 mp_tp
->mpt_flags
&= ~MPTCPF_RCVD_64BITACK
;
1225 mp_tp
->mpt_flags
&= ~MPTCPF_SND_64BITDSN
;
1227 mptcp_notify_mpready(tp
->t_inpcb
->inp_socket
);
1229 mptcp_notify_close(tp
->t_inpcb
->inp_socket
);
1232 mptcplog((LOG_ERR
,"MPTCP Socket: "
1233 "%s: unexpected dack %llx snduna %llx "
1234 "sndmax %llx\n", __func__
, full_dack
,
1235 mp_tp
->mpt_snduna
, mp_tp
->mpt_sndmax
),
1236 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1242 mptcp_do_dss_opt_meat(u_char
*cp
, struct tcpcb
*tp
)
1244 struct mptcp_dss_copt
*dss_rsp
= (struct mptcp_dss_copt
*)cp
;
1245 u_int64_t full_dack
= 0;
1246 struct mptcb
*mp_tp
= tptomptp(tp
);
1249 #define MPTCP_DSS_OPT_SZ_CHK(len, expected_len) { \
1250 if (len != expected_len) { \
1251 mptcplog((LOG_ERR, "MPTCP Socket: " \
1252 "%s: bad len = %d dss: %x \n", __func__, \
1253 len, dss_rsp->mdss_flags), \
1254 (MPTCP_SOCKET_DBG|MPTCP_RECEIVER_DBG), \
1255 MPTCP_LOGLVL_LOG); \
1261 * mp_tp might become NULL after the call to mptcp_do_fin_opt().
1262 * Review after rdar://problem/24083886
1267 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
)
1270 dss_rsp
->mdss_flags
&= (MDSS_A
|MDSS_a
|MDSS_M
|MDSS_m
);
1271 switch (dss_rsp
->mdss_flags
) {
1274 /* 32-bit DSS, No Data ACK */
1275 struct mptcp_dsn_opt
*dss_rsp1
;
1276 dss_rsp1
= (struct mptcp_dsn_opt
*)cp
;
1278 MPTCP_DSS_OPT_SZ_CHK(dss_rsp1
->mdss_copt
.mdss_len
,
1279 sizeof (struct mptcp_dsn_opt
) + csum_len
);
1281 mptcp_update_dss_rcv_state(dss_rsp1
, tp
, 0);
1283 mptcp_update_dss_rcv_state(dss_rsp1
, tp
,
1284 *(uint16_t *)(void *)(cp
+
1285 (dss_rsp1
->mdss_copt
.mdss_len
- csum_len
)));
1290 /* 32-bit Data ACK, no DSS */
1291 struct mptcp_data_ack_opt
*dack_opt
;
1292 dack_opt
= (struct mptcp_data_ack_opt
*)cp
;
1294 MPTCP_DSS_OPT_SZ_CHK(dack_opt
->mdss_copt
.mdss_len
,
1295 sizeof (struct mptcp_data_ack_opt
));
1297 u_int32_t dack
= dack_opt
->mdss_ack
;
1299 MPT_LOCK_SPIN(mp_tp
);
1300 MPTCP_EXTEND_DSN(mp_tp
->mpt_snduna
, dack
, full_dack
);
1302 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1305 case (MDSS_M
| MDSS_A
):
1307 /* 32-bit Data ACK + 32-bit DSS */
1308 struct mptcp_dss_ack_opt
*dss_ack_rsp
;
1309 dss_ack_rsp
= (struct mptcp_dss_ack_opt
*)cp
;
1311 MPTCP_DSS_OPT_SZ_CHK(dss_ack_rsp
->mdss_copt
.mdss_len
,
1312 sizeof (struct mptcp_dss_ack_opt
) + csum_len
);
1314 u_int32_t dack
= dss_ack_rsp
->mdss_ack
;
1316 MPT_LOCK_SPIN(mp_tp
);
1317 MPTCP_EXTEND_DSN(mp_tp
->mpt_snduna
, dack
, full_dack
);
1319 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1321 mptcp_update_rcv_state_f(dss_ack_rsp
, tp
, 0);
1323 mptcp_update_rcv_state_f(dss_ack_rsp
, tp
,
1324 *(uint16_t *)(void *)(cp
+
1325 (dss_ack_rsp
->mdss_copt
.mdss_len
-
1329 case (MDSS_M
| MDSS_m
):
1331 /* 64-bit DSS , No Data ACK */
1332 struct mptcp_dsn64_opt
*dsn64
;
1333 dsn64
= (struct mptcp_dsn64_opt
*)cp
;
1336 MPTCP_DSS_OPT_SZ_CHK(dsn64
->mdss_copt
.mdss_len
,
1337 sizeof (struct mptcp_dsn64_opt
) + csum_len
);
1339 mptcplog((LOG_DEBUG
,"MPTCP Socket: "
1340 "%s: 64-bit M present.\n", __func__
),
1341 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1344 MPT_LOCK_SPIN(mp_tp
);
1345 mp_tp
->mpt_flags
|= MPTCPF_SND_64BITACK
;
1348 full_dsn
= mptcp_ntoh64(dsn64
->mdss_dsn
);
1349 NTOHL(dsn64
->mdss_subflow_seqn
);
1350 NTOHS(dsn64
->mdss_data_len
);
1352 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1353 dsn64
->mdss_subflow_seqn
,
1354 dsn64
->mdss_data_len
,
1357 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1358 dsn64
->mdss_subflow_seqn
,
1359 dsn64
->mdss_data_len
,
1360 *(uint16_t *)(void *)(cp
+
1361 dsn64
->mdss_copt
.mdss_len
- csum_len
));
1364 case (MDSS_A
| MDSS_a
):
1366 /* 64-bit Data ACK, no DSS */
1367 struct mptcp_data_ack64_opt
*dack64
;
1368 dack64
= (struct mptcp_data_ack64_opt
*)cp
;
1370 MPTCP_DSS_OPT_SZ_CHK(dack64
->mdss_copt
.mdss_len
,
1371 sizeof (struct mptcp_data_ack64_opt
));
1373 mptcplog((LOG_DEBUG
,"MPTCP Socket: "
1374 "%s: 64-bit A present. \n", __func__
),
1375 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1378 MPT_LOCK_SPIN(mp_tp
);
1379 mp_tp
->mpt_flags
|= MPTCPF_RCVD_64BITACK
;
1382 full_dack
= mptcp_ntoh64(dack64
->mdss_ack
);
1383 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1386 case (MDSS_M
| MDSS_m
| MDSS_A
):
1388 /* 64-bit DSS + 32-bit Data ACK */
1389 struct mptcp_dss64_ack32_opt
*dss_ack_rsp
;
1390 dss_ack_rsp
= (struct mptcp_dss64_ack32_opt
*)cp
;
1392 MPTCP_DSS_OPT_SZ_CHK(dss_ack_rsp
->mdss_copt
.mdss_len
,
1393 sizeof (struct mptcp_dss64_ack32_opt
) + csum_len
);
1395 mptcplog((LOG_DEBUG
,"MPTCP Socket: "
1396 "%s: 64-bit M and 32-bit A present.\n", __func__
),
1397 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1400 u_int32_t dack
= dss_ack_rsp
->mdss_ack
;
1402 MPT_LOCK_SPIN(mp_tp
);
1403 mp_tp
->mpt_flags
|= MPTCPF_SND_64BITACK
;
1404 MPTCP_EXTEND_DSN(mp_tp
->mpt_snduna
, dack
, full_dack
);
1406 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1408 mptcp_update_rcv_state_g(dss_ack_rsp
, tp
, 0);
1410 mptcp_update_rcv_state_g(dss_ack_rsp
, tp
,
1411 *(uint16_t *)(void *)(cp
+
1412 dss_ack_rsp
->mdss_copt
.mdss_len
-
1416 case (MDSS_M
| MDSS_A
| MDSS_a
):
1418 /* 32-bit DSS + 64-bit Data ACK */
1419 struct mptcp_dss32_ack64_opt
*dss32_ack64_opt
;
1420 dss32_ack64_opt
= (struct mptcp_dss32_ack64_opt
*)cp
;
1423 MPTCP_DSS_OPT_SZ_CHK(
1424 dss32_ack64_opt
->mdss_copt
.mdss_len
,
1425 sizeof (struct mptcp_dss32_ack64_opt
) + csum_len
);
1427 mptcplog((LOG_DEBUG
,"MPTCP Socket: "
1428 "%s: 32-bit M and 64-bit A present.\n", __func__
),
1429 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1432 full_dack
= mptcp_ntoh64(dss32_ack64_opt
->mdss_ack
);
1433 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1434 NTOHL(dss32_ack64_opt
->mdss_dsn
);
1435 MPT_LOCK_SPIN(mp_tp
);
1436 mp_tp
->mpt_flags
|= MPTCPF_RCVD_64BITACK
;
1437 MPTCP_EXTEND_DSN(mp_tp
->mpt_rcvnxt
,
1438 dss32_ack64_opt
->mdss_dsn
, full_dsn
);
1440 NTOHL(dss32_ack64_opt
->mdss_subflow_seqn
);
1441 NTOHS(dss32_ack64_opt
->mdss_data_len
);
1443 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1444 dss32_ack64_opt
->mdss_subflow_seqn
,
1445 dss32_ack64_opt
->mdss_data_len
, 0);
1447 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1448 dss32_ack64_opt
->mdss_subflow_seqn
,
1449 dss32_ack64_opt
->mdss_data_len
,
1450 *(uint16_t *)(void *)(cp
+
1451 dss32_ack64_opt
->mdss_copt
.mdss_len
-
1455 case (MDSS_M
| MDSS_m
| MDSS_A
| MDSS_a
):
1457 /* 64-bit DSS + 64-bit Data ACK */
1458 struct mptcp_dss64_ack64_opt
*dss64_ack64
;
1459 dss64_ack64
= (struct mptcp_dss64_ack64_opt
*)cp
;
1462 MPTCP_DSS_OPT_SZ_CHK(dss64_ack64
->mdss_copt
.mdss_len
,
1463 sizeof (struct mptcp_dss64_ack64_opt
) + csum_len
);
1465 mptcplog((LOG_DEBUG
,"MPTCP Socket: "
1466 "%s: 64-bit M and 64-bit A present.\n", __func__
),
1467 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1470 MPT_LOCK_SPIN(mp_tp
);
1471 mp_tp
->mpt_flags
|= MPTCPF_RCVD_64BITACK
;
1472 mp_tp
->mpt_flags
|= MPTCPF_SND_64BITACK
;
1474 full_dsn
= mptcp_ntoh64(dss64_ack64
->mdss_dsn
);
1475 full_dack
= mptcp_ntoh64(dss64_ack64
->mdss_dsn
);
1476 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1477 NTOHL(dss64_ack64
->mdss_subflow_seqn
);
1478 NTOHS(dss64_ack64
->mdss_data_len
);
1480 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1481 dss64_ack64
->mdss_subflow_seqn
,
1482 dss64_ack64
->mdss_data_len
, 0);
1484 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1485 dss64_ack64
->mdss_subflow_seqn
,
1486 dss64_ack64
->mdss_data_len
,
1487 *(uint16_t *)(void *)(cp
+
1488 dss64_ack64
->mdss_copt
.mdss_len
-
1493 mptcplog((LOG_DEBUG
,"MPTCP Socket: "
1494 "%s: File bug, DSS flags = %x\n", __func__
,
1495 dss_rsp
->mdss_flags
),
1496 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1504 mptcp_do_fin_opt(struct tcpcb
*tp
)
1506 struct mptcb
*mp_tp
= (struct mptcb
*)tp
->t_mptcb
;
1508 mptcplog((LOG_DEBUG
,"MPTCP Socket: %s \n", __func__
),
1509 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1512 if (!(tp
->t_mpflags
& TMPF_RECV_DFIN
)) {
1513 if (mp_tp
!= NULL
) {
1515 mptcp_close_fsm(mp_tp
, MPCE_RECV_DATA_FIN
);
1518 if (tp
->t_inpcb
->inp_socket
!= NULL
) {
1519 soevent(tp
->t_inpcb
->inp_socket
,
1520 SO_FILT_HINT_LOCKED
|
1521 SO_FILT_HINT_MPCANTRCVMORE
);
1525 tp
->t_mpflags
|= TMPF_RECV_DFIN
;
1528 tp
->t_mpflags
|= TMPF_MPTCP_ACKNOW
;
1530 * Since this is a data level FIN, TCP needs to be explicitly told
1531 * to send back an ACK on which the Data ACK is piggybacked.
1533 tp
->t_flags
|= TF_ACKNOW
;
1537 mptcp_do_dss_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
, int optlen
)
1539 #pragma unused(th, optlen)
1540 struct mptcb
*mp_tp
= (struct mptcb
*)tp
->t_mptcb
;
1545 /* We may get Data ACKs just during fallback, so don't ignore those */
1546 if ((tp
->t_mpflags
& TMPF_MPTCP_TRUE
) ||
1547 (tp
->t_mpflags
& TMPF_TCP_FALLBACK
)) {
1548 struct mptcp_dss_copt
*dss_rsp
= (struct mptcp_dss_copt
*)cp
;
1550 if (dss_rsp
->mdss_subtype
== MPO_DSS
) {
1551 if (dss_rsp
->mdss_flags
& MDSS_F
) {
1552 mptcp_do_fin_opt(tp
);
1555 mptcp_do_dss_opt_meat(cp
, tp
);
1561 mptcp_do_fastclose_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
)
1563 struct mptcb
*mp_tp
= NULL
;
1564 struct mptcp_fastclose_opt
*fc_opt
= (struct mptcp_fastclose_opt
*)cp
;
1566 if (th
->th_flags
!= TH_ACK
)
1569 mptcplog((LOG_DEBUG
,"MPTCP Socket: %s: \n", __func__
),
1570 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1573 if (fc_opt
->mfast_len
!= sizeof (struct mptcp_fastclose_opt
)) {
1574 tcpstat
.tcps_invalid_opt
++;
1578 mp_tp
= (struct mptcb
*)tp
->t_mptcb
;
1582 if (fc_opt
->mfast_key
!= mptcp_get_localkey(mp_tp
)) {
1583 tcpstat
.tcps_invalid_opt
++;
1588 * fastclose could make us more vulnerable to attacks, hence
1589 * accept only those that are at the next expected sequence number.
1591 if (th
->th_seq
!= tp
->rcv_nxt
) {
1592 tcpstat
.tcps_invalid_opt
++;
1596 /* Reset this flow */
1597 tp
->t_mpflags
|= (TMPF_RESET
| TMPF_FASTCLOSERCV
);
1599 if (tp
->t_inpcb
->inp_socket
!= NULL
) {
1600 soevent(tp
->t_inpcb
->inp_socket
,
1601 SO_FILT_HINT_LOCKED
| SO_FILT_HINT_MUSTRST
);
1607 mptcp_do_mpfail_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
)
1609 struct mptcb
*mp_tp
= NULL
;
1610 struct mptcp_mpfail_opt
*fail_opt
= (struct mptcp_mpfail_opt
*)cp
;
1611 u_int32_t mdss_subflow_seqn
= 0;
1615 * mpfail could make us more vulnerable to attacks. Hence accept
1616 * only those that are the next expected sequence number.
1618 if (th
->th_seq
!= tp
->rcv_nxt
) {
1619 tcpstat
.tcps_invalid_opt
++;
1623 /* A packet without RST, must atleast have the ACK bit set */
1624 if ((th
->th_flags
!= TH_ACK
) && (th
->th_flags
!= TH_RST
))
1627 mptcplog((LOG_DEBUG
, "MPTCP Socket: %s: \n", __func__
),
1628 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
), MPTCP_LOGLVL_LOG
);
1630 if (fail_opt
->mfail_len
!= sizeof (struct mptcp_mpfail_opt
))
1633 mp_tp
= (struct mptcb
*)tp
->t_mptcb
;
1635 mp_tp
->mpt_flags
|= MPTCPF_RECVD_MPFAIL
;
1636 mp_tp
->mpt_dsn_at_csum_fail
= mptcp_hton64(fail_opt
->mfail_dsn
);
1638 error
= mptcp_get_map_for_dsn(tp
->t_inpcb
->inp_socket
,
1639 mp_tp
->mpt_dsn_at_csum_fail
, &mdss_subflow_seqn
);
1641 mp_tp
->mpt_ssn_at_csum_fail
= mdss_subflow_seqn
;
1644 mptcp_notify_mpfail(tp
->t_inpcb
->inp_socket
);
1648 tcp_do_mptcp_options(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
,
1649 struct tcpopt
*to
, int optlen
)
1653 /* All MPTCP options have atleast 4 bytes */
1657 mptcp_subtype
= (cp
[2] >> 4);
1659 if (mptcp_sanitize_option(tp
, mptcp_subtype
) == 0)
1662 switch (mptcp_subtype
) {
1664 mptcp_do_mpcapable_opt(tp
, cp
, th
, optlen
);
1667 mptcp_do_mpjoin_opt(tp
, cp
, th
, optlen
);
1670 mptcp_do_dss_opt(tp
, cp
, th
, optlen
);
1673 mptcp_do_fastclose_opt(tp
, cp
, th
);
1676 mptcp_do_mpfail_opt(tp
, cp
, th
);
1678 case MPO_ADD_ADDR
: /* fall through */
1679 case MPO_REMOVE_ADDR
: /* fall through */
1681 to
->to_flags
|= TOF_MPTCP
;
1690 * MPTCP ADD_ADDR and REMOVE_ADDR options
1694 * ADD_ADDR is only placeholder code - not sent on wire
1695 * The ADD_ADDR option is not sent on wire because of security issues
1696 * around connection hijacking.
1699 mptcp_send_addaddr_opt(struct tcpcb
*tp
, struct mptcp_addaddr_opt
*opt
)
1702 opt
->ma_kind
= TCPOPT_MULTIPATH
;
1703 opt
->ma_len
= sizeof (struct mptcp_addaddr_opt
);
1704 opt
->ma_subtype
= MPO_ADD_ADDR
;
1705 opt
->ma_addr_id
= tp
->t_local_aid
;
1707 struct inpcb
*inp
= tp
->t_inpcb
;
1708 if (inp
->inp_vflag
== AF_INET
) {
1709 opt
->ma_ipver
= MA_IPVer_V4
;
1710 bcopy((char *)&sin
->sin_addr
.s_addr
, (char *)opt
+ opt
->ma_len
,
1711 sizeof (in_addr_t
));
1712 opt
->ma_len
+= sizeof (in_addr_t
);
1713 } else if (inp
->inp_vflag
== AF_INET6
) {
1714 opt
->ma_ipver
= MA_IPVer_V6
;
1715 bcopy((char *)&sin6
->sin6_addr
, (char *)opt
+ opt
->ma_len
,
1716 sizeof (struct in6_addr
));
1717 opt
->ma_len
+= sizeof (struct in6_addr
);
1720 if (tp
->t_mp_port
) {
1727 /* REMOVE_ADDR option is sent when a source address goes away */
1729 mptcp_send_remaddr_opt(struct tcpcb
*tp
, struct mptcp_remaddr_opt
*opt
)
1731 mptcplog((LOG_DEBUG
,"MPTCP Socket: %s: local id %d remove id %d \n",
1732 __func__
, tp
->t_local_aid
, tp
->t_rem_aid
),
1733 (MPTCP_SOCKET_DBG
|MPTCP_SENDER_DBG
), MPTCP_LOGLVL_LOG
);
1735 bzero(opt
, sizeof (*opt
));
1736 opt
->mr_kind
= TCPOPT_MULTIPATH
;
1737 opt
->mr_len
= sizeof (*opt
);
1738 opt
->mr_subtype
= MPO_REMOVE_ADDR
;
1739 opt
->mr_addr_id
= tp
->t_rem_aid
;
1740 tp
->t_mpflags
&= ~TMPF_SND_REM_ADDR
;
1744 * MPTCP MP_PRIO option
1749 * Current implementation drops incoming MP_PRIO option and this code is
1750 * just a placeholder. The option is dropped because only the mobile client can
1751 * decide which of the subflows is preferred (usually wifi is preferred
1755 mptcp_do_mpprio_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
,
1759 struct mptcp_mpprio_opt
*mpprio
= (struct mptcp_mpprio_opt
*)cp
;
1761 if ((tp
== NULL
) || !(tp
->t_mpflags
& TMPF_MPTCP_TRUE
))
1764 if ((mpprio
->mpprio_len
!= sizeof (struct mptcp_mpprio_addr_opt
)) &&
1765 (mpprio
->mpprio_len
!= sizeof (struct mptcp_mpprio_opt
)))
1770 /* We send MP_PRIO option based on the values set by the SIOCSCONNORDER ioctl */
1772 mptcp_snd_mpprio(struct tcpcb
*tp
, u_char
*cp
, int optlen
)
1774 struct mptcp_mpprio_addr_opt mpprio
;
1776 if (tp
->t_state
!= TCPS_ESTABLISHED
) {
1777 tp
->t_mpflags
&= ~TMPF_SND_MPPRIO
;
1781 if (mptcp_mpprio_enable
!= 1) {
1782 tp
->t_mpflags
&= ~TMPF_SND_MPPRIO
;
1786 if ((MAX_TCPOPTLEN
- optlen
) <
1787 (int)sizeof (mpprio
))
1790 bzero(&mpprio
, sizeof (mpprio
));
1791 mpprio
.mpprio_kind
= TCPOPT_MULTIPATH
;
1792 mpprio
.mpprio_len
= sizeof (mpprio
);
1793 mpprio
.mpprio_subtype
= MPO_PRIO
;
1794 if (tp
->t_mpflags
& TMPF_BACKUP_PATH
)
1795 mpprio
.mpprio_flags
|= MPTCP_MPPRIO_BKP
;
1796 mpprio
.mpprio_addrid
= tp
->t_local_aid
;
1797 memcpy(cp
+ optlen
, &mpprio
, sizeof (mpprio
));
1798 optlen
+= sizeof (mpprio
);
1799 tp
->t_mpflags
&= ~TMPF_SND_MPPRIO
;
1800 mptcplog((LOG_DEBUG
, "MPTCP Socket: %s: aid = %d \n", __func__
,
1802 (MPTCP_SOCKET_DBG
|MPTCP_SENDER_DBG
), MPTCP_LOGLVL_LOG
);