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
);
431 if ((mptcp_enable
== 0) ||
433 (mp_tp
->mpt_flags
& MPTCPF_PEEL_OFF
) ||
434 (tp
->t_state
== TCPS_CLOSED
)) {
439 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
) {
443 /* tcp_output handles the SYN path separately */
444 if (flags
& TH_SYN
) {
448 if ((MAX_TCPOPTLEN
- optlen
) <
449 sizeof (struct mptcp_mpcapable_opt_common
)) {
450 mptcplog((LOG_ERR
, "MPTCP Socket: "
451 "%s: no space left %d flags %x "
453 "len %d\n", __func__
, optlen
, flags
, tp
->t_mpflags
,
454 datalen
), MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_ERR
);
458 if (tp
->t_mpflags
& TMPF_TCP_FALLBACK
) {
459 if (tp
->t_mpflags
& TMPF_SND_MPFAIL
)
460 optlen
= mptcp_send_mpfail(tp
, opt
, optlen
);
461 else if (!(tp
->t_mpflags
& TMPF_INFIN_SENT
))
462 optlen
= mptcp_send_infinite_mapping(tp
, opt
, optlen
);
466 if (((tp
->t_mpflags
& TMPF_FASTJOINBY2_SEND
) ||
467 (tp
->t_mpflags
& TMPF_FASTJOIN_SEND
)) &&
469 tp
->t_mpflags
&= ~TMPF_FASTJOINBY2_SEND
;
470 tp
->t_mpflags
&= ~TMPF_FASTJOIN_SEND
;
474 if (((tp
->t_mpflags
& TMPF_PREESTABLISHED
) &&
475 (!(tp
->t_mpflags
& TMPF_SENT_KEYS
)) &&
476 (!(tp
->t_mpflags
& TMPF_JOINED_FLOW
)))) {
477 struct mptcp_mpcapable_opt_rsp1 mptcp_opt
;
478 if ((MAX_TCPOPTLEN
- optlen
) <
479 sizeof (struct mptcp_mpcapable_opt_rsp1
))
481 bzero(&mptcp_opt
, sizeof (struct mptcp_mpcapable_opt_rsp1
));
482 mptcp_opt
.mmc_common
.mmco_kind
= TCPOPT_MULTIPATH
;
483 mptcp_opt
.mmc_common
.mmco_len
=
484 sizeof (struct mptcp_mpcapable_opt_rsp1
);
485 mptcp_opt
.mmc_common
.mmco_subtype
= MPO_CAPABLE
;
486 mptcp_opt
.mmc_common
.mmco_version
= mp_tp
->mpt_version
;
487 /* HMAC-SHA1 is the proposal */
488 mptcp_opt
.mmc_common
.mmco_flags
|= MPCAP_PROPOSAL_SBIT
;
490 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
)
491 mptcp_opt
.mmc_common
.mmco_flags
|= MPCAP_CHECKSUM_CBIT
;
492 mptcp_opt
.mmc_localkey
= mptcp_get_localkey(mp_tp
);
493 mptcp_opt
.mmc_remotekey
= mptcp_get_remotekey(mp_tp
);
495 memcpy(opt
+ optlen
, &mptcp_opt
, mptcp_opt
.mmc_common
.mmco_len
);
496 optlen
+= mptcp_opt
.mmc_common
.mmco_len
;
497 tp
->t_mpflags
|= TMPF_SENT_KEYS
| TMPF_MPTCP_TRUE
;
498 so
->so_flags
|= SOF_MPTCP_TRUE
;
499 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
502 tp
->t_mpuna
= tp
->snd_una
;
504 /* its a retransmission of the MP_CAPABLE ACK */
509 if ((tp
->t_mpflags
& TMPF_JOINED_FLOW
) &&
510 (tp
->t_mpflags
& TMPF_PREESTABLISHED
) &&
511 (!(tp
->t_mpflags
& TMPF_RECVD_JOIN
)) &&
512 (tp
->t_mpflags
& TMPF_SENT_JOIN
) &&
513 (!(tp
->t_mpflags
& TMPF_MPTCP_TRUE
))) {
515 if (mptcp_get_localkey(mp_tp
) == 0) {
520 /* Do the ACK part */
521 optlen
= mptcp_setup_join_ack_opts(tp
, opt
, optlen
);
523 tp
->t_mpuna
= tp
->snd_una
;
525 /* Start a timer to retransmit the ACK */
526 tp
->t_timer
[TCPT_JACK_RXMT
] =
527 OFFSET_FROM_START(tp
, tcp_jack_rxmt
);
531 if (!(tp
->t_mpflags
& TMPF_MPTCP_TRUE
))
535 * From here on, all options are sent only if MPTCP_TRUE
536 * or when data is sent early on as in Fast Join
539 if ((tp
->t_mpflags
& TMPF_MPTCP_TRUE
) &&
540 (tp
->t_mpflags
& TMPF_SND_REM_ADDR
)) {
541 int rem_opt_len
= sizeof (struct mptcp_remaddr_opt
);
542 if ((optlen
+ rem_opt_len
) <= MAX_TCPOPTLEN
) {
543 mptcp_send_remaddr_opt(tp
,
544 (struct mptcp_remaddr_opt
*)(opt
+ optlen
));
545 optlen
+= rem_opt_len
;
547 tp
->t_mpflags
&= ~TMPF_SND_REM_ADDR
;
551 if (tp
->t_mpflags
& TMPF_SND_MPPRIO
) {
552 optlen
= mptcp_snd_mpprio(tp
, opt
, optlen
);
556 if ((mp_tp
->mpt_flags
& MPTCPF_SND_64BITDSN
) || force_64bit_dsn
) {
557 send_64bit_dsn
= TRUE
;
559 if (mp_tp
->mpt_flags
& MPTCPF_SND_64BITACK
)
560 send_64bit_ack
= TRUE
;
564 #define CHECK_OPTLEN { \
565 if ((MAX_TCPOPTLEN - optlen) < len) { \
566 mptcplog((LOG_ERR, "MPTCP Socket: " \
567 "%s: len %d optlen %d \n", __func__, len, optlen), \
568 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR); \
573 #define DO_FIN(dsn_opt) { \
575 sndfin = mptcp_ok_to_fin(tp, dsn_opt.mdss_dsn, datalen); \
577 dsn_opt.mdss_copt.mdss_flags |= MDSS_F; \
578 *finp = opt + optlen + offsetof(struct mptcp_dss_copt, \
580 dsn_opt.mdss_data_len += 1; \
584 #define CHECK_DATALEN { \
585 /* MPTCP socket does not support IP options */ \
586 if ((datalen + optlen + len) > tp->t_maxopd) { \
587 mptcplog((LOG_ERR, "MPTCP Socket: " \
588 "%s: nosp %d len %d opt %d %d %d\n", \
589 __func__, datalen, len, optlen, \
590 tp->t_maxseg, tp->t_maxopd), \
591 MPTCP_SOCKET_DBG, MPTCP_LOGLVL_ERR); \
592 /* remove option length from payload len */ \
593 datalen = tp->t_maxopd - optlen - len; \
597 if ((tp
->t_mpflags
& TMPF_SEND_DSN
) &&
600 * If there was the need to send 64-bit Data ACK along
601 * with 64-bit DSN, then 26 or 28 bytes would be used.
602 * With timestamps and NOOP padding that will cause
603 * overflow. Hence, in the rare event that both 64-bit
604 * DSN and 64-bit ACK have to be sent, delay the send of
605 * 64-bit ACK until our 64-bit DSN is acked with a 64-bit ack.
606 * XXX If this delay causes issue, remove the 2-byte padding.
608 struct mptcp_dss64_ack32_opt dsn_ack_opt
;
609 unsigned int len
= sizeof (dsn_ack_opt
);
617 bzero(&dsn_ack_opt
, sizeof (dsn_ack_opt
));
618 dsn_ack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
619 dsn_ack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
620 dsn_ack_opt
.mdss_copt
.mdss_len
= len
;
621 dsn_ack_opt
.mdss_copt
.mdss_flags
|=
622 MDSS_M
| MDSS_m
| MDSS_A
;
626 mptcp_output_getm_dsnmap64(so
, off
, (u_int32_t
)datalen
,
627 &dsn_ack_opt
.mdss_dsn
,
628 &dsn_ack_opt
.mdss_subflow_seqn
,
629 &dsn_ack_opt
.mdss_data_len
);
631 *dss_valp
= dsn_ack_opt
.mdss_dsn
;
633 if ((dsn_ack_opt
.mdss_data_len
== 0) ||
634 (dsn_ack_opt
.mdss_dsn
== 0)) {
638 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
643 dsn_ack_opt
.mdss_ack
=
644 htonl(MPTCP_DATAACK_LOW32(mp_tp
->mpt_rcvnxt
));
647 dsn_ack_opt
.mdss_dsn
= mptcp_hton64(dsn_ack_opt
.mdss_dsn
);
648 dsn_ack_opt
.mdss_subflow_seqn
= htonl(
649 dsn_ack_opt
.mdss_subflow_seqn
);
650 dsn_ack_opt
.mdss_data_len
= htons(
651 dsn_ack_opt
.mdss_data_len
);
652 *dss_lenp
= (unsigned int *)(void *)(opt
+ optlen
+
653 offsetof(struct mptcp_dss64_ack32_opt
, mdss_data_len
));
655 memcpy(opt
+ optlen
, &dsn_ack_opt
, sizeof (dsn_ack_opt
));
658 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
659 offsetof(struct mptcp_dss64_ack32_opt
,
663 mptcplog((LOG_DEBUG
,"MPTCP Socket: "
664 "%s: long DSS = %llx ACK = %llx \n",
666 mptcp_ntoh64(dsn_ack_opt
.mdss_dsn
),
667 mptcp_ntoh64(dsn_ack_opt
.mdss_ack
)),
668 MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_LOG
);
670 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
674 if ((tp
->t_mpflags
& TMPF_SEND_DSN
) &&
676 !(tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
)) {
677 struct mptcp_dsn_opt dsn_opt
;
678 unsigned int len
= sizeof (struct mptcp_dsn_opt
);
686 bzero(&dsn_opt
, sizeof (dsn_opt
));
687 dsn_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
688 dsn_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
689 dsn_opt
.mdss_copt
.mdss_len
= len
;
690 dsn_opt
.mdss_copt
.mdss_flags
|= MDSS_M
;
694 mptcp_output_getm_dsnmap32(so
, off
, (u_int32_t
)datalen
,
696 &dsn_opt
.mdss_subflow_seqn
, &dsn_opt
.mdss_data_len
,
699 if ((dsn_opt
.mdss_data_len
== 0) ||
700 (dsn_opt
.mdss_dsn
== 0)) {
704 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
708 dsn_opt
.mdss_dsn
= htonl(dsn_opt
.mdss_dsn
);
709 dsn_opt
.mdss_subflow_seqn
= htonl(dsn_opt
.mdss_subflow_seqn
);
710 dsn_opt
.mdss_data_len
= htons(dsn_opt
.mdss_data_len
);
711 *dss_lenp
= (unsigned int *)(void *)(opt
+ optlen
+
712 offsetof(struct mptcp_dsn_opt
, mdss_data_len
));
713 memcpy(opt
+ optlen
, &dsn_opt
, sizeof (dsn_opt
));
715 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
716 offsetof(struct mptcp_dsn_opt
, mdss_subflow_seqn
));
719 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
723 /* 32-bit Data ACK option */
724 if ((tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
) &&
726 !(tp
->t_mpflags
& TMPF_SEND_DSN
) &&
727 !(tp
->t_mpflags
& TMPF_SEND_DFIN
)) {
729 struct mptcp_data_ack_opt dack_opt
;
730 unsigned int len
= 0;
732 len
= sizeof (dack_opt
);
736 bzero(&dack_opt
, len
);
737 dack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
738 dack_opt
.mdss_copt
.mdss_len
= len
;
739 dack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
740 dack_opt
.mdss_copt
.mdss_flags
|= MDSS_A
;
741 MPT_LOCK_SPIN(mp_tp
);
743 htonl(MPTCP_DATAACK_LOW32(mp_tp
->mpt_rcvnxt
));
745 memcpy(opt
+ optlen
, &dack_opt
, len
);
747 VERIFY(optlen
<= MAX_TCPOPTLEN
);
748 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
752 /* 64-bit Data ACK option */
753 if ((tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
) &&
755 !(tp
->t_mpflags
& TMPF_SEND_DSN
) &&
756 !(tp
->t_mpflags
& TMPF_SEND_DFIN
)) {
757 struct mptcp_data_ack64_opt dack_opt
;
758 unsigned int len
= 0;
760 len
= sizeof (dack_opt
);
764 bzero(&dack_opt
, len
);
765 dack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
766 dack_opt
.mdss_copt
.mdss_len
= len
;
767 dack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
768 dack_opt
.mdss_copt
.mdss_flags
|= (MDSS_A
| MDSS_a
);
769 MPT_LOCK_SPIN(mp_tp
);
770 dack_opt
.mdss_ack
= mptcp_hton64(mp_tp
->mpt_rcvnxt
);
772 * The other end should retransmit 64-bit DSN until it
773 * receives a 64-bit ACK.
775 mp_tp
->mpt_flags
&= ~MPTCPF_SND_64BITACK
;
777 memcpy(opt
+ optlen
, &dack_opt
, len
);
779 VERIFY(optlen
<= MAX_TCPOPTLEN
);
780 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
784 /* 32-bit DSS+Data ACK option */
785 if ((tp
->t_mpflags
& TMPF_SEND_DSN
) &&
788 (tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
)) {
789 struct mptcp_dss_ack_opt dss_ack_opt
;
790 unsigned int len
= sizeof (dss_ack_opt
);
797 bzero(&dss_ack_opt
, sizeof (dss_ack_opt
));
798 dss_ack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
799 dss_ack_opt
.mdss_copt
.mdss_len
= len
;
800 dss_ack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
801 dss_ack_opt
.mdss_copt
.mdss_flags
|= MDSS_A
| MDSS_M
;
802 MPT_LOCK_SPIN(mp_tp
);
803 dss_ack_opt
.mdss_ack
=
804 htonl(MPTCP_DATAACK_LOW32(mp_tp
->mpt_rcvnxt
));
809 mptcp_output_getm_dsnmap32(so
, off
, (u_int32_t
)datalen
,
810 &dss_ack_opt
.mdss_dsn
,
811 &dss_ack_opt
.mdss_subflow_seqn
,
812 &dss_ack_opt
.mdss_data_len
,
815 if ((dss_ack_opt
.mdss_data_len
== 0) ||
816 (dss_ack_opt
.mdss_dsn
== 0)) {
820 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
824 dss_ack_opt
.mdss_dsn
= htonl(dss_ack_opt
.mdss_dsn
);
825 dss_ack_opt
.mdss_subflow_seqn
=
826 htonl(dss_ack_opt
.mdss_subflow_seqn
);
827 dss_ack_opt
.mdss_data_len
= htons(dss_ack_opt
.mdss_data_len
);
828 *dss_lenp
= (unsigned int *)(void *)(opt
+ optlen
+
829 offsetof(struct mptcp_dss_ack_opt
, mdss_data_len
));
830 memcpy(opt
+ optlen
, &dss_ack_opt
, sizeof (dss_ack_opt
));
832 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
833 offsetof(struct mptcp_dss_ack_opt
,
839 if (optlen
> MAX_TCPOPTLEN
)
840 panic("optlen too large");
841 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
845 /* 32-bit DSS + 64-bit DACK option */
846 if ((tp
->t_mpflags
& TMPF_SEND_DSN
) &&
849 (tp
->t_mpflags
& TMPF_MPTCP_ACKNOW
)) {
850 struct mptcp_dss32_ack64_opt dss_ack_opt
;
851 unsigned int len
= sizeof (dss_ack_opt
);
858 bzero(&dss_ack_opt
, sizeof (dss_ack_opt
));
859 dss_ack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
860 dss_ack_opt
.mdss_copt
.mdss_len
= len
;
861 dss_ack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
862 dss_ack_opt
.mdss_copt
.mdss_flags
|= MDSS_M
| MDSS_A
| MDSS_a
;
863 MPT_LOCK_SPIN(mp_tp
);
864 dss_ack_opt
.mdss_ack
=
865 mptcp_hton64(mp_tp
->mpt_rcvnxt
);
870 mptcp_output_getm_dsnmap32(so
, off
, (u_int32_t
)datalen
,
871 &dss_ack_opt
.mdss_dsn
, &dss_ack_opt
.mdss_subflow_seqn
,
872 &dss_ack_opt
.mdss_data_len
, dss_valp
);
874 if ((dss_ack_opt
.mdss_data_len
== 0) ||
875 (dss_ack_opt
.mdss_dsn
== 0)) {
879 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
883 dss_ack_opt
.mdss_dsn
= htonl(dss_ack_opt
.mdss_dsn
);
884 dss_ack_opt
.mdss_subflow_seqn
=
885 htonl(dss_ack_opt
.mdss_subflow_seqn
);
886 dss_ack_opt
.mdss_data_len
= htons(dss_ack_opt
.mdss_data_len
);
887 *dss_lenp
= (unsigned int *)(void *)(opt
+ optlen
+
888 offsetof(struct mptcp_dss32_ack64_opt
, mdss_data_len
));
889 memcpy(opt
+ optlen
, &dss_ack_opt
, sizeof (dss_ack_opt
));
891 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
892 offsetof(struct mptcp_dss32_ack64_opt
,
898 if (optlen
> MAX_TCPOPTLEN
)
899 panic("optlen too large");
900 tp
->t_mpflags
&= ~TMPF_MPTCP_ACKNOW
;
904 if (tp
->t_mpflags
& TMPF_SEND_DFIN
) {
905 struct mptcp_dss_ack_opt dss_ack_opt
;
906 unsigned int len
= sizeof (struct mptcp_dss_ack_opt
);
913 bzero(&dss_ack_opt
, sizeof (dss_ack_opt
));
917 * Data FIN occupies one sequence space.
918 * Don't send it if it has been Acked.
920 if (((mp_tp
->mpt_sndnxt
+ 1) != mp_tp
->mpt_sndmax
) ||
921 (mp_tp
->mpt_snduna
== mp_tp
->mpt_sndmax
)) {
926 dss_ack_opt
.mdss_copt
.mdss_kind
= TCPOPT_MULTIPATH
;
927 dss_ack_opt
.mdss_copt
.mdss_len
= len
;
928 dss_ack_opt
.mdss_copt
.mdss_subtype
= MPO_DSS
;
929 dss_ack_opt
.mdss_copt
.mdss_flags
|= MDSS_A
| MDSS_M
| MDSS_F
;
930 dss_ack_opt
.mdss_ack
=
931 htonl(MPTCP_DATAACK_LOW32(mp_tp
->mpt_rcvnxt
));
932 dss_ack_opt
.mdss_dsn
=
933 htonl(MPTCP_DATASEQ_LOW32(mp_tp
->mpt_sndnxt
));
935 dss_ack_opt
.mdss_subflow_seqn
= 0;
936 dss_ack_opt
.mdss_data_len
= 1;
937 dss_ack_opt
.mdss_data_len
= htons(dss_ack_opt
.mdss_data_len
);
938 memcpy(opt
+ optlen
, &dss_ack_opt
, sizeof (dss_ack_opt
));
940 *dss_valp
= mp_tp
->mpt_sndnxt
;
941 *sseqp
= (u_int32_t
*)(void *)(opt
+ optlen
+
942 offsetof(struct mptcp_dss_ack_opt
,
949 if (TRUE
== *p_mptcp_acknow
) {
950 VERIFY(old_mpt_flags
!= 0);
951 u_int32_t new_mpt_flags
= tp
->t_mpflags
&
952 (TMPF_SND_MPPRIO
| TMPF_SND_REM_ADDR
| TMPF_SND_MPFAIL
);
955 * If none of the above mpflags were acted on by
956 * this routine, reset these flags and set p_mptcp_acknow
958 * XXX The reset value of p_mptcp_acknow can be used
959 * to communicate tcp_output to NOT send a pure ack without any
960 * MPTCP options as it will be treated as a dup ack.
961 * Since the instances of mptcp_setup_opts not acting on
962 * these options are mostly corner cases and sending a dup
963 * ack here would only have an impact if the system
964 * has sent consecutive dup acks before this false one,
965 * we haven't modified the logic in tcp_output to avoid
968 if ((old_mpt_flags
== new_mpt_flags
) || (new_mpt_flags
== 0)) {
969 tp
->t_mpflags
&= ~(TMPF_SND_MPPRIO
970 | TMPF_SND_REM_ADDR
| TMPF_SND_MPFAIL
);
971 *p_mptcp_acknow
= FALSE
;
972 mptcplog((LOG_DEBUG
, "MPTCP Sender: %s: no action \n",
973 __func__
), MPTCP_SENDER_DBG
, MPTCP_LOGLVL_LOG
);
975 mptcplog((LOG_DEBUG
, "MPTCP Sender: acknow set, "
976 "old flags %x new flags %x \n",
977 old_mpt_flags
, new_mpt_flags
),
978 MPTCP_SENDER_DBG
, MPTCP_LOGLVL_LOG
);
986 * MPTCP Options Input Processing
990 mptcp_sanitize_option(struct tcpcb
*tp
, int mptcp_subtype
)
992 struct mptcb
*mp_tp
= tptomptp(tp
);
996 mptcplog((LOG_ERR
, "MPTCP Socket: %s: NULL mpsocket \n",
997 __func__
), MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_ERR
);
1001 switch (mptcp_subtype
) {
1004 case MPO_JOIN
: /* fall through */
1005 case MPO_DSS
: /* fall through */
1006 case MPO_FASTCLOSE
: /* fall through */
1007 case MPO_FAIL
: /* fall through */
1008 case MPO_REMOVE_ADDR
: /* fall through */
1009 case MPO_ADD_ADDR
: /* fall through */
1010 case MPO_PRIO
: /* fall through */
1011 if (mp_tp
->mpt_state
< MPTCPS_ESTABLISHED
)
1016 mptcplog((LOG_ERR
, "MPTCP Socket: "
1017 "%s: type = %d \n", __func__
,
1019 MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_ERR
);
1026 mptcp_valid_mpcapable_common_opt(u_char
*cp
)
1028 struct mptcp_mpcapable_opt_common
*rsp
=
1029 (struct mptcp_mpcapable_opt_common
*)cp
;
1031 /* mmco_kind, mmco_len and mmco_subtype are validated before */
1033 if (!(rsp
->mmco_flags
& MPCAP_PROPOSAL_SBIT
))
1036 if (rsp
->mmco_flags
& (MPCAP_BBIT
| MPCAP_CBIT
| MPCAP_DBIT
|
1037 MPCAP_EBIT
| MPCAP_FBIT
| MPCAP_GBIT
))
1045 mptcp_do_mpcapable_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
,
1048 struct mptcp_mpcapable_opt_rsp
*rsp
= NULL
;
1049 struct mptcb
*mp_tp
= tptomptp(tp
);
1051 /* Only valid on SYN/ACK */
1052 if ((th
->th_flags
& (TH_SYN
| TH_ACK
)) != (TH_SYN
| TH_ACK
))
1055 /* Validate the kind, len, flags */
1056 if (mptcp_valid_mpcapable_common_opt(cp
) != 1) {
1057 tcpstat
.tcps_invalid_mpcap
++;
1061 /* handle SYN/ACK retransmission by acknowledging with ACK */
1062 if (mp_tp
->mpt_state
>= MPTCPS_ESTABLISHED
)
1065 /* A SYN/ACK contains peer's key and flags */
1066 if (optlen
!= sizeof (struct mptcp_mpcapable_opt_rsp
)) {
1068 mptcplog((LOG_ERR
, "MPTCP Socket: "
1069 "%s: SYN_ACK optlen = %d, sizeof mp opt = %lu \n",
1071 sizeof (struct mptcp_mpcapable_opt_rsp
)),
1072 MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_ERR
);
1073 tcpstat
.tcps_invalid_mpcap
++;
1078 * If checksum flag is set, enable MPTCP checksum, even if
1079 * it was not negotiated on the first SYN.
1081 if (((struct mptcp_mpcapable_opt_common
*)cp
)->mmco_flags
&
1082 MPCAP_CHECKSUM_CBIT
)
1083 mp_tp
->mpt_flags
|= MPTCPF_CHECKSUM
;
1085 rsp
= (struct mptcp_mpcapable_opt_rsp
*)cp
;
1087 mp_tp
->mpt_remotekey
= rsp
->mmc_localkey
;
1088 /* For now just downgrade to the peer's version */
1089 mp_tp
->mpt_peer_version
= rsp
->mmc_common
.mmco_version
;
1090 if (rsp
->mmc_common
.mmco_version
< mp_tp
->mpt_version
) {
1091 mp_tp
->mpt_version
= rsp
->mmc_common
.mmco_version
;
1092 tcpstat
.tcps_mp_verdowngrade
++;
1094 if (mptcp_init_remote_parms(mp_tp
) != 0) {
1095 tcpstat
.tcps_invalid_mpcap
++;
1100 tcp_heuristic_mptcp_success(tp
);
1101 tp
->t_mpflags
|= TMPF_PREESTABLISHED
;
1106 mptcp_do_mpjoin_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
, int optlen
)
1108 #define MPTCP_JOPT_ERROR_PATH(tp) { \
1109 tp->t_mpflags |= TMPF_RESET; \
1110 tcpstat.tcps_invalid_joins++; \
1111 if (tp->t_inpcb->inp_socket != NULL) { \
1112 soevent(tp->t_inpcb->inp_socket, \
1113 SO_FILT_HINT_LOCKED | SO_FILT_HINT_MUSTRST); \
1117 struct mptcp_mpjoin_opt_rsp
*join_rsp
=
1118 (struct mptcp_mpjoin_opt_rsp
*)cp
;
1120 /* Only valid on SYN/ACK */
1121 if ((th
->th_flags
& (TH_SYN
| TH_ACK
)) != (TH_SYN
| TH_ACK
))
1124 if (optlen
!= sizeof (struct mptcp_mpjoin_opt_rsp
)) {
1125 mptcplog((LOG_ERR
, "MPTCP Socket: "
1126 "SYN_ACK: unexpected optlen = %d mp "
1127 "option = %lu\n", optlen
,
1128 sizeof (struct mptcp_mpjoin_opt_rsp
)),
1129 MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_ERR
);
1130 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
1131 /* send RST and close */
1132 MPTCP_JOPT_ERROR_PATH(tp
);
1136 mptcp_set_raddr_rand(tp
->t_local_aid
, tptomptp(tp
),
1137 join_rsp
->mmjo_addr_id
, join_rsp
->mmjo_rand
);
1138 error
= mptcp_validate_join_hmac(tp
,
1139 (u_char
*)&join_rsp
->mmjo_mac
, SHA1_TRUNCATED
);
1141 mptcplog((LOG_ERR
, "MPTCP Socket: %s: "
1142 "SYN_ACK error = %d \n", __func__
, error
),
1143 MPTCP_SOCKET_DBG
, MPTCP_LOGLVL_ERR
);
1144 tp
->t_mpflags
&= ~TMPF_PREESTABLISHED
;
1145 /* send RST and close */
1146 MPTCP_JOPT_ERROR_PATH(tp
);
1149 tp
->t_mpflags
|= TMPF_SENT_JOIN
;
1153 mptcp_validate_join_hmac(struct tcpcb
*tp
, u_char
* hmac
, int mac_len
)
1155 u_char digest
[SHA1_RESULTLEN
] = {0};
1156 struct mptcb
*mp_tp
= NULL
;
1157 mptcp_key_t rem_key
, loc_key
;
1158 u_int32_t rem_rand
, loc_rand
;
1160 mp_tp
= tp
->t_mptcb
;
1162 rem_rand
= loc_rand
= 0;
1165 rem_key
= mp_tp
->mpt_remotekey
;
1168 * Can happen if the MPTCP-connection is about to be closed and we
1169 * receive an MP_JOIN in-between the events are being handled by the
1172 if (mp_tp
->mpt_localkey
== NULL
) {
1177 loc_key
= *mp_tp
->mpt_localkey
;
1180 mptcp_get_rands(tp
->t_local_aid
, mp_tp
, &loc_rand
, &rem_rand
);
1181 if ((rem_rand
== 0) || (loc_rand
== 0))
1184 mptcp_hmac_sha1(rem_key
, loc_key
, rem_rand
, loc_rand
,
1185 digest
, sizeof (digest
));
1187 if (bcmp(digest
, hmac
, mac_len
) == 0)
1188 return (0); /* matches */
1190 printf("%s: remote key %llx local key %llx remote rand %x "
1191 "local rand %x \n", __func__
, rem_key
, loc_key
,
1192 rem_rand
, loc_rand
);
1198 mptcp_do_dss_opt_ack_meat(u_int64_t full_dack
, struct tcpcb
*tp
)
1200 struct mptcb
*mp_tp
= tptomptp(tp
);
1201 int close_notify
= 0;
1203 tp
->t_mpflags
|= TMPF_RCVD_DACK
;
1206 if (MPTCP_SEQ_LEQ(full_dack
, mp_tp
->mpt_sndmax
) &&
1207 MPTCP_SEQ_GEQ(full_dack
, mp_tp
->mpt_snduna
)) {
1208 mptcp_data_ack_rcvd(mp_tp
, tp
, full_dack
);
1209 if (mp_tp
->mpt_state
> MPTCPS_FIN_WAIT_2
)
1212 if (mp_tp
->mpt_flags
& MPTCPF_RCVD_64BITACK
) {
1213 mp_tp
->mpt_flags
&= ~MPTCPF_RCVD_64BITACK
;
1214 mp_tp
->mpt_flags
&= ~MPTCPF_SND_64BITDSN
;
1216 mptcp_notify_mpready(tp
->t_inpcb
->inp_socket
);
1218 mptcp_notify_close(tp
->t_inpcb
->inp_socket
);
1221 mptcplog((LOG_ERR
,"MPTCP Socket: "
1222 "%s: unexpected dack %llx snduna %llx "
1223 "sndmax %llx\n", __func__
, full_dack
,
1224 mp_tp
->mpt_snduna
, mp_tp
->mpt_sndmax
),
1225 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1231 mptcp_do_dss_opt_meat(u_char
*cp
, struct tcpcb
*tp
)
1233 struct mptcp_dss_copt
*dss_rsp
= (struct mptcp_dss_copt
*)cp
;
1234 u_int64_t full_dack
= 0;
1235 struct mptcb
*mp_tp
= tptomptp(tp
);
1238 #define MPTCP_DSS_OPT_SZ_CHK(len, expected_len) { \
1239 if (len != expected_len) { \
1240 mptcplog((LOG_ERR, "MPTCP Socket: " \
1241 "%s: bad len = %d dss: %x \n", __func__, \
1242 len, dss_rsp->mdss_flags), \
1243 (MPTCP_SOCKET_DBG|MPTCP_RECEIVER_DBG), \
1244 MPTCP_LOGLVL_LOG); \
1250 * mp_tp might become NULL after the call to mptcp_do_fin_opt().
1251 * Review after rdar://problem/24083886
1256 if (mp_tp
->mpt_flags
& MPTCPF_CHECKSUM
)
1259 dss_rsp
->mdss_flags
&= (MDSS_A
|MDSS_a
|MDSS_M
|MDSS_m
);
1260 switch (dss_rsp
->mdss_flags
) {
1263 /* 32-bit DSS, No Data ACK */
1264 struct mptcp_dsn_opt
*dss_rsp1
;
1265 dss_rsp1
= (struct mptcp_dsn_opt
*)cp
;
1267 MPTCP_DSS_OPT_SZ_CHK(dss_rsp1
->mdss_copt
.mdss_len
,
1268 sizeof (struct mptcp_dsn_opt
) + csum_len
);
1270 mptcp_update_dss_rcv_state(dss_rsp1
, tp
, 0);
1272 mptcp_update_dss_rcv_state(dss_rsp1
, tp
,
1273 *(uint16_t *)(void *)(cp
+
1274 (dss_rsp1
->mdss_copt
.mdss_len
- csum_len
)));
1279 /* 32-bit Data ACK, no DSS */
1280 struct mptcp_data_ack_opt
*dack_opt
;
1281 dack_opt
= (struct mptcp_data_ack_opt
*)cp
;
1283 MPTCP_DSS_OPT_SZ_CHK(dack_opt
->mdss_copt
.mdss_len
,
1284 sizeof (struct mptcp_data_ack_opt
));
1286 u_int32_t dack
= dack_opt
->mdss_ack
;
1288 MPT_LOCK_SPIN(mp_tp
);
1289 MPTCP_EXTEND_DSN(mp_tp
->mpt_snduna
, dack
, full_dack
);
1291 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1294 case (MDSS_M
| MDSS_A
):
1296 /* 32-bit Data ACK + 32-bit DSS */
1297 struct mptcp_dss_ack_opt
*dss_ack_rsp
;
1298 dss_ack_rsp
= (struct mptcp_dss_ack_opt
*)cp
;
1300 MPTCP_DSS_OPT_SZ_CHK(dss_ack_rsp
->mdss_copt
.mdss_len
,
1301 sizeof (struct mptcp_dss_ack_opt
) + csum_len
);
1303 u_int32_t dack
= dss_ack_rsp
->mdss_ack
;
1305 MPT_LOCK_SPIN(mp_tp
);
1306 MPTCP_EXTEND_DSN(mp_tp
->mpt_snduna
, dack
, full_dack
);
1308 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1310 mptcp_update_rcv_state_f(dss_ack_rsp
, tp
, 0);
1312 mptcp_update_rcv_state_f(dss_ack_rsp
, tp
,
1313 *(uint16_t *)(void *)(cp
+
1314 (dss_ack_rsp
->mdss_copt
.mdss_len
-
1318 case (MDSS_M
| MDSS_m
):
1320 /* 64-bit DSS , No Data ACK */
1321 struct mptcp_dsn64_opt
*dsn64
;
1322 dsn64
= (struct mptcp_dsn64_opt
*)cp
;
1325 MPTCP_DSS_OPT_SZ_CHK(dsn64
->mdss_copt
.mdss_len
,
1326 sizeof (struct mptcp_dsn64_opt
) + csum_len
);
1328 mptcplog((LOG_DEBUG
,"MPTCP Socket: "
1329 "%s: 64-bit M present.\n", __func__
),
1330 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1333 MPT_LOCK_SPIN(mp_tp
);
1334 mp_tp
->mpt_flags
|= MPTCPF_SND_64BITACK
;
1337 full_dsn
= mptcp_ntoh64(dsn64
->mdss_dsn
);
1338 NTOHL(dsn64
->mdss_subflow_seqn
);
1339 NTOHS(dsn64
->mdss_data_len
);
1341 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1342 dsn64
->mdss_subflow_seqn
,
1343 dsn64
->mdss_data_len
,
1346 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1347 dsn64
->mdss_subflow_seqn
,
1348 dsn64
->mdss_data_len
,
1349 *(uint16_t *)(void *)(cp
+
1350 dsn64
->mdss_copt
.mdss_len
- csum_len
));
1353 case (MDSS_A
| MDSS_a
):
1355 /* 64-bit Data ACK, no DSS */
1356 struct mptcp_data_ack64_opt
*dack64
;
1357 dack64
= (struct mptcp_data_ack64_opt
*)cp
;
1359 MPTCP_DSS_OPT_SZ_CHK(dack64
->mdss_copt
.mdss_len
,
1360 sizeof (struct mptcp_data_ack64_opt
));
1362 mptcplog((LOG_DEBUG
,"MPTCP Socket: "
1363 "%s: 64-bit A present. \n", __func__
),
1364 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1367 MPT_LOCK_SPIN(mp_tp
);
1368 mp_tp
->mpt_flags
|= MPTCPF_RCVD_64BITACK
;
1371 full_dack
= mptcp_ntoh64(dack64
->mdss_ack
);
1372 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1375 case (MDSS_M
| MDSS_m
| MDSS_A
):
1377 /* 64-bit DSS + 32-bit Data ACK */
1378 struct mptcp_dss64_ack32_opt
*dss_ack_rsp
;
1379 dss_ack_rsp
= (struct mptcp_dss64_ack32_opt
*)cp
;
1381 MPTCP_DSS_OPT_SZ_CHK(dss_ack_rsp
->mdss_copt
.mdss_len
,
1382 sizeof (struct mptcp_dss64_ack32_opt
) + csum_len
);
1384 mptcplog((LOG_DEBUG
,"MPTCP Socket: "
1385 "%s: 64-bit M and 32-bit A present.\n", __func__
),
1386 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1389 u_int32_t dack
= dss_ack_rsp
->mdss_ack
;
1391 MPT_LOCK_SPIN(mp_tp
);
1392 mp_tp
->mpt_flags
|= MPTCPF_SND_64BITACK
;
1393 MPTCP_EXTEND_DSN(mp_tp
->mpt_snduna
, dack
, full_dack
);
1395 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1397 mptcp_update_rcv_state_g(dss_ack_rsp
, tp
, 0);
1399 mptcp_update_rcv_state_g(dss_ack_rsp
, tp
,
1400 *(uint16_t *)(void *)(cp
+
1401 dss_ack_rsp
->mdss_copt
.mdss_len
-
1405 case (MDSS_M
| MDSS_A
| MDSS_a
):
1407 /* 32-bit DSS + 64-bit Data ACK */
1408 struct mptcp_dss32_ack64_opt
*dss32_ack64_opt
;
1409 dss32_ack64_opt
= (struct mptcp_dss32_ack64_opt
*)cp
;
1412 MPTCP_DSS_OPT_SZ_CHK(
1413 dss32_ack64_opt
->mdss_copt
.mdss_len
,
1414 sizeof (struct mptcp_dss32_ack64_opt
) + csum_len
);
1416 mptcplog((LOG_DEBUG
,"MPTCP Socket: "
1417 "%s: 32-bit M and 64-bit A present.\n", __func__
),
1418 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1421 full_dack
= mptcp_ntoh64(dss32_ack64_opt
->mdss_ack
);
1422 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1423 NTOHL(dss32_ack64_opt
->mdss_dsn
);
1424 MPT_LOCK_SPIN(mp_tp
);
1425 mp_tp
->mpt_flags
|= MPTCPF_RCVD_64BITACK
;
1426 MPTCP_EXTEND_DSN(mp_tp
->mpt_rcvnxt
,
1427 dss32_ack64_opt
->mdss_dsn
, full_dsn
);
1429 NTOHL(dss32_ack64_opt
->mdss_subflow_seqn
);
1430 NTOHS(dss32_ack64_opt
->mdss_data_len
);
1432 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1433 dss32_ack64_opt
->mdss_subflow_seqn
,
1434 dss32_ack64_opt
->mdss_data_len
, 0);
1436 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1437 dss32_ack64_opt
->mdss_subflow_seqn
,
1438 dss32_ack64_opt
->mdss_data_len
,
1439 *(uint16_t *)(void *)(cp
+
1440 dss32_ack64_opt
->mdss_copt
.mdss_len
-
1444 case (MDSS_M
| MDSS_m
| MDSS_A
| MDSS_a
):
1446 /* 64-bit DSS + 64-bit Data ACK */
1447 struct mptcp_dss64_ack64_opt
*dss64_ack64
;
1448 dss64_ack64
= (struct mptcp_dss64_ack64_opt
*)cp
;
1451 MPTCP_DSS_OPT_SZ_CHK(dss64_ack64
->mdss_copt
.mdss_len
,
1452 sizeof (struct mptcp_dss64_ack64_opt
) + csum_len
);
1454 mptcplog((LOG_DEBUG
,"MPTCP Socket: "
1455 "%s: 64-bit M and 64-bit A present.\n", __func__
),
1456 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1459 MPT_LOCK_SPIN(mp_tp
);
1460 mp_tp
->mpt_flags
|= MPTCPF_RCVD_64BITACK
;
1461 mp_tp
->mpt_flags
|= MPTCPF_SND_64BITACK
;
1463 full_dsn
= mptcp_ntoh64(dss64_ack64
->mdss_dsn
);
1464 full_dack
= mptcp_ntoh64(dss64_ack64
->mdss_dsn
);
1465 mptcp_do_dss_opt_ack_meat(full_dack
, tp
);
1466 NTOHL(dss64_ack64
->mdss_subflow_seqn
);
1467 NTOHS(dss64_ack64
->mdss_data_len
);
1469 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1470 dss64_ack64
->mdss_subflow_seqn
,
1471 dss64_ack64
->mdss_data_len
, 0);
1473 mptcp_update_rcv_state_meat(mp_tp
, tp
, full_dsn
,
1474 dss64_ack64
->mdss_subflow_seqn
,
1475 dss64_ack64
->mdss_data_len
,
1476 *(uint16_t *)(void *)(cp
+
1477 dss64_ack64
->mdss_copt
.mdss_len
-
1482 mptcplog((LOG_DEBUG
,"MPTCP Socket: "
1483 "%s: File bug, DSS flags = %x\n", __func__
,
1484 dss_rsp
->mdss_flags
),
1485 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1493 mptcp_do_fin_opt(struct tcpcb
*tp
)
1495 struct mptcb
*mp_tp
= (struct mptcb
*)tp
->t_mptcb
;
1497 mptcplog((LOG_DEBUG
,"MPTCP Socket: %s \n", __func__
),
1498 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1501 if (!(tp
->t_mpflags
& TMPF_RECV_DFIN
)) {
1502 if (mp_tp
!= NULL
) {
1504 mptcp_close_fsm(mp_tp
, MPCE_RECV_DATA_FIN
);
1507 if (tp
->t_inpcb
->inp_socket
!= NULL
) {
1508 soevent(tp
->t_inpcb
->inp_socket
,
1509 SO_FILT_HINT_LOCKED
|
1510 SO_FILT_HINT_MPCANTRCVMORE
);
1514 tp
->t_mpflags
|= TMPF_RECV_DFIN
;
1517 tp
->t_mpflags
|= TMPF_MPTCP_ACKNOW
;
1519 * Since this is a data level FIN, TCP needs to be explicitly told
1520 * to send back an ACK on which the Data ACK is piggybacked.
1522 tp
->t_flags
|= TF_ACKNOW
;
1526 mptcp_do_dss_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
, int optlen
)
1528 #pragma unused(th, optlen)
1529 struct mptcb
*mp_tp
= (struct mptcb
*)tp
->t_mptcb
;
1534 /* We may get Data ACKs just during fallback, so don't ignore those */
1535 if ((tp
->t_mpflags
& TMPF_MPTCP_TRUE
) ||
1536 (tp
->t_mpflags
& TMPF_TCP_FALLBACK
)) {
1537 struct mptcp_dss_copt
*dss_rsp
= (struct mptcp_dss_copt
*)cp
;
1539 if (dss_rsp
->mdss_subtype
== MPO_DSS
) {
1540 if (dss_rsp
->mdss_flags
& MDSS_F
) {
1541 mptcp_do_fin_opt(tp
);
1544 mptcp_do_dss_opt_meat(cp
, tp
);
1550 mptcp_do_fastclose_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
)
1552 struct mptcb
*mp_tp
= NULL
;
1553 struct mptcp_fastclose_opt
*fc_opt
= (struct mptcp_fastclose_opt
*)cp
;
1555 if (th
->th_flags
!= TH_ACK
)
1558 mptcplog((LOG_DEBUG
,"MPTCP Socket: %s: \n", __func__
),
1559 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
),
1562 if (fc_opt
->mfast_len
!= sizeof (struct mptcp_fastclose_opt
)) {
1563 tcpstat
.tcps_invalid_opt
++;
1567 mp_tp
= (struct mptcb
*)tp
->t_mptcb
;
1571 if (fc_opt
->mfast_key
!= mptcp_get_localkey(mp_tp
)) {
1572 tcpstat
.tcps_invalid_opt
++;
1577 * fastclose could make us more vulnerable to attacks, hence
1578 * accept only those that are at the next expected sequence number.
1580 if (th
->th_seq
!= tp
->rcv_nxt
) {
1581 tcpstat
.tcps_invalid_opt
++;
1585 /* Reset this flow */
1586 tp
->t_mpflags
|= (TMPF_RESET
| TMPF_FASTCLOSERCV
);
1588 if (tp
->t_inpcb
->inp_socket
!= NULL
) {
1589 soevent(tp
->t_inpcb
->inp_socket
,
1590 SO_FILT_HINT_LOCKED
| SO_FILT_HINT_MUSTRST
);
1596 mptcp_do_mpfail_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
)
1598 struct mptcb
*mp_tp
= NULL
;
1599 struct mptcp_mpfail_opt
*fail_opt
= (struct mptcp_mpfail_opt
*)cp
;
1600 u_int32_t mdss_subflow_seqn
= 0;
1604 * mpfail could make us more vulnerable to attacks. Hence accept
1605 * only those that are the next expected sequence number.
1607 if (th
->th_seq
!= tp
->rcv_nxt
) {
1608 tcpstat
.tcps_invalid_opt
++;
1612 /* A packet without RST, must atleast have the ACK bit set */
1613 if ((th
->th_flags
!= TH_ACK
) && (th
->th_flags
!= TH_RST
))
1616 mptcplog((LOG_DEBUG
, "MPTCP Socket: %s: \n", __func__
),
1617 (MPTCP_SOCKET_DBG
|MPTCP_RECEIVER_DBG
), MPTCP_LOGLVL_LOG
);
1619 if (fail_opt
->mfail_len
!= sizeof (struct mptcp_mpfail_opt
))
1622 mp_tp
= (struct mptcb
*)tp
->t_mptcb
;
1624 mp_tp
->mpt_flags
|= MPTCPF_RECVD_MPFAIL
;
1625 mp_tp
->mpt_dsn_at_csum_fail
= mptcp_hton64(fail_opt
->mfail_dsn
);
1627 error
= mptcp_get_map_for_dsn(tp
->t_inpcb
->inp_socket
,
1628 mp_tp
->mpt_dsn_at_csum_fail
, &mdss_subflow_seqn
);
1630 mp_tp
->mpt_ssn_at_csum_fail
= mdss_subflow_seqn
;
1633 mptcp_notify_mpfail(tp
->t_inpcb
->inp_socket
);
1637 tcp_do_mptcp_options(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
,
1638 struct tcpopt
*to
, int optlen
)
1642 /* All MPTCP options have atleast 4 bytes */
1646 mptcp_subtype
= (cp
[2] >> 4);
1648 if (mptcp_sanitize_option(tp
, mptcp_subtype
) == 0)
1651 switch (mptcp_subtype
) {
1653 mptcp_do_mpcapable_opt(tp
, cp
, th
, optlen
);
1656 mptcp_do_mpjoin_opt(tp
, cp
, th
, optlen
);
1659 mptcp_do_dss_opt(tp
, cp
, th
, optlen
);
1662 mptcp_do_fastclose_opt(tp
, cp
, th
);
1665 mptcp_do_mpfail_opt(tp
, cp
, th
);
1667 case MPO_ADD_ADDR
: /* fall through */
1668 case MPO_REMOVE_ADDR
: /* fall through */
1670 to
->to_flags
|= TOF_MPTCP
;
1679 * MPTCP ADD_ADDR and REMOVE_ADDR options
1683 * ADD_ADDR is only placeholder code - not sent on wire
1684 * The ADD_ADDR option is not sent on wire because of security issues
1685 * around connection hijacking.
1688 mptcp_send_addaddr_opt(struct tcpcb
*tp
, struct mptcp_addaddr_opt
*opt
)
1691 opt
->ma_kind
= TCPOPT_MULTIPATH
;
1692 opt
->ma_len
= sizeof (struct mptcp_addaddr_opt
);
1693 opt
->ma_subtype
= MPO_ADD_ADDR
;
1694 opt
->ma_addr_id
= tp
->t_local_aid
;
1696 struct inpcb
*inp
= tp
->t_inpcb
;
1697 if (inp
->inp_vflag
== AF_INET
) {
1698 opt
->ma_ipver
= MA_IPVer_V4
;
1699 bcopy((char *)&sin
->sin_addr
.s_addr
, (char *)opt
+ opt
->ma_len
,
1700 sizeof (in_addr_t
));
1701 opt
->ma_len
+= sizeof (in_addr_t
);
1702 } else if (inp
->inp_vflag
== AF_INET6
) {
1703 opt
->ma_ipver
= MA_IPVer_V6
;
1704 bcopy((char *)&sin6
->sin6_addr
, (char *)opt
+ opt
->ma_len
,
1705 sizeof (struct in6_addr
));
1706 opt
->ma_len
+= sizeof (struct in6_addr
);
1709 if (tp
->t_mp_port
) {
1716 /* REMOVE_ADDR option is sent when a source address goes away */
1718 mptcp_send_remaddr_opt(struct tcpcb
*tp
, struct mptcp_remaddr_opt
*opt
)
1720 mptcplog((LOG_DEBUG
,"MPTCP Socket: %s: local id %d remove id %d \n",
1721 __func__
, tp
->t_local_aid
, tp
->t_rem_aid
),
1722 (MPTCP_SOCKET_DBG
|MPTCP_SENDER_DBG
), MPTCP_LOGLVL_LOG
);
1724 bzero(opt
, sizeof (*opt
));
1725 opt
->mr_kind
= TCPOPT_MULTIPATH
;
1726 opt
->mr_len
= sizeof (*opt
);
1727 opt
->mr_subtype
= MPO_REMOVE_ADDR
;
1728 opt
->mr_addr_id
= tp
->t_rem_aid
;
1729 tp
->t_mpflags
&= ~TMPF_SND_REM_ADDR
;
1733 * MPTCP MP_PRIO option
1738 * Current implementation drops incoming MP_PRIO option and this code is
1739 * just a placeholder. The option is dropped because only the mobile client can
1740 * decide which of the subflows is preferred (usually wifi is preferred
1744 mptcp_do_mpprio_opt(struct tcpcb
*tp
, u_char
*cp
, struct tcphdr
*th
,
1748 struct mptcp_mpprio_opt
*mpprio
= (struct mptcp_mpprio_opt
*)cp
;
1750 if ((tp
== NULL
) || !(tp
->t_mpflags
& TMPF_MPTCP_TRUE
))
1753 if ((mpprio
->mpprio_len
!= sizeof (struct mptcp_mpprio_addr_opt
)) &&
1754 (mpprio
->mpprio_len
!= sizeof (struct mptcp_mpprio_opt
)))
1759 /* We send MP_PRIO option based on the values set by the SIOCSCONNORDER ioctl */
1761 mptcp_snd_mpprio(struct tcpcb
*tp
, u_char
*cp
, int optlen
)
1763 struct mptcp_mpprio_addr_opt mpprio
;
1765 if (tp
->t_state
!= TCPS_ESTABLISHED
) {
1766 tp
->t_mpflags
&= ~TMPF_SND_MPPRIO
;
1770 if (mptcp_mpprio_enable
!= 1) {
1771 tp
->t_mpflags
&= ~TMPF_SND_MPPRIO
;
1775 if ((MAX_TCPOPTLEN
- optlen
) <
1776 (int)sizeof (mpprio
))
1779 bzero(&mpprio
, sizeof (mpprio
));
1780 mpprio
.mpprio_kind
= TCPOPT_MULTIPATH
;
1781 mpprio
.mpprio_len
= sizeof (mpprio
);
1782 mpprio
.mpprio_subtype
= MPO_PRIO
;
1783 if (tp
->t_mpflags
& TMPF_BACKUP_PATH
)
1784 mpprio
.mpprio_flags
|= MPTCP_MPPRIO_BKP
;
1785 mpprio
.mpprio_addrid
= tp
->t_local_aid
;
1786 memcpy(cp
+ optlen
, &mpprio
, sizeof (mpprio
));
1787 optlen
+= sizeof (mpprio
);
1788 tp
->t_mpflags
&= ~TMPF_SND_MPPRIO
;
1789 mptcplog((LOG_DEBUG
, "MPTCP Socket: %s: aid = %d \n", __func__
,
1791 (MPTCP_SOCKET_DBG
|MPTCP_SENDER_DBG
), MPTCP_LOGLVL_LOG
);