gems-kernel/source/THIRDPARTY/xnu/bsd/netinet/mptcp.h
2024-06-03 11:29:39 -05:00

379 lines
12 KiB
C

/*
* Copyright (c) 2012-2017 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
#ifndef _NETINET_MPTCP_H_
#define _NETINET_MPTCP_H_
#ifdef BSD_KERNEL_PRIVATE
#include <machine/endian.h>
#include <libkern/crypto/sha1.h>
#if BYTE_ORDER == BIG_ENDIAN
#define mptcp_hton64(x) (x)
#define mptcp_ntoh64(x) (x)
#else /* LITTLE_ENDIAN */
#define mptcp_hton64(x) __DARWIN_OSSwapInt64(x)
#define mptcp_ntoh64(x) __DARWIN_OSSwapInt64(x)
#endif
#include <netinet/mptcp_var.h>
/* Preferred MPTCP version to use when version discovery info is incomplete */
extern int mptcp_preferred_version;
/*
* MPTCP Option Subtype Field values
*/
#define MPO_CAPABLE 0x0
#define MPO_JOIN 0x1
#define MPO_DSS 0x2
#define MPO_ADD_ADDR 0x3
#define MPO_REMOVE_ADDR 0x4
#define MPO_PRIO 0x5
#define MPO_FAIL 0x6
#define MPO_FASTCLOSE 0x7
/* MPTCP Protocol version */
#define MPTCP_VERSION_0 0x0
#define MPTCP_VERSION_1 0x1
/*
* MPTCP MP_CAPABLE TCP Option definitions
*
* Used to establish an MPTCP connection and first subflow.
*/
struct mptcp_mpcapable_opt_common {
uint8_t mmco_kind;
uint8_t mmco_len;
#if BYTE_ORDER == LITTLE_ENDIAN
uint8_t mmco_version:4,
mmco_subtype:4;
#else /* BIG_ENDIAN */
uint8_t mmco_subtype:4,
mmco_version:4;
#endif
#define MPCAP_PROPOSAL_SBIT 0x01 /* SHA1 (v0) or SHA256 (v1) Algorithm */
#define MPCAP_GBIT 0x02 /* must be 0 */
#define MPCAP_FBIT 0x04 /* must be 0 */
#define MPCAP_EBIT 0x08 /* must be 0 */
#define MPCAP_DBIT 0x10 /* must be 0 */
#define MPCAP_UNICAST_IPBIT 0x20 /* Should MPTCP only use ADD_ADDR IPs for new subflows */
#define MPCAP_BBIT 0x40 /* Extensibility bit, must be 0 */
#define MPCAP_CHECKSUM_CBIT 0x80 /* DSS Checksum bit */
uint8_t mmco_flags;
} __attribute__((__packed__));
struct mptcp_mpcapable_opt_rsp {
struct mptcp_mpcapable_opt_common mmc_common;
mptcp_key_t mmc_localkey;
} __attribute__((__packed__));
struct mptcp_mpcapable_opt_rsp1 {
struct mptcp_mpcapable_opt_common mmc_common;
mptcp_key_t mmc_localkey;
mptcp_key_t mmc_remotekey;
} __attribute__((__packed__));
struct mptcp_mpcapable_opt_rsp2 {
struct mptcp_mpcapable_opt_rsp1 mmc_rsp1;
uint16_t data_len;
uint16_t csum;
} __attribute__((__packed__));
/*
* MPTCP MP_JOIN TCP Option definitions
*
* Used to add subflows to an existing MP_CAPABLE connection.
*/
/* MP_JOIN Option for SYN */
struct mptcp_mpjoin_opt_req {
uint8_t mmjo_kind;
uint8_t mmjo_len;
#define MPTCP_BACKUP 0x1
uint8_t mmjo_subtype_bkp;
uint8_t mmjo_addr_id;
uint32_t mmjo_peer_token;
uint32_t mmjo_rand;
} __attribute__((__packed__));
/* MP_JOIN Option for SYN/ACK */
struct mptcp_mpjoin_opt_rsp {
uint8_t mmjo_kind;
uint8_t mmjo_len;
#define MPTCP_BACKUP 0x1
uint8_t mmjo_subtype_bkp;
uint8_t mmjo_addr_id;
uint64_t mmjo_mac; /* Truncated message auth code */
uint32_t mmjo_rand;
} __attribute__((__packed__));
/* MP_Join Option for ACK */
struct mptcp_mpjoin_opt_rsp2 {
uint8_t mmjo_kind;
uint8_t mmjo_len;
#if BYTE_ORDER == LITTLE_ENDIAN
uint8_t mmjo_reserved1:4,
mmjo_subtype:4;
#else /* BIG_ENDIAN */
uint8_t mmjo_subtype:4,
mmjo_reserved1:4;
#endif
uint8_t mmjo_reserved2;
uint8_t mmjo_mac[HMAC_TRUNCATED_ACK]; /* This is 160 bits HMAC per RFC */
} __attribute__((__packed__));
/* Remove Address Option */
struct mptcp_remaddr_opt {
uint8_t mr_kind;
uint8_t mr_len;
#if BYTE_ORDER == LITTLE_ENDIAN
uint8_t mr_rest:4,
mr_subtype:4;
#else /* BIG_ENDIAN */
uint8_t mr_subtype:4,
mr_rest:4;
#endif
uint8_t mr_addr_id;
} __attribute__((__packed__));
/*
* MPTCP Data Sequence Signal (DSS) TCP Options
*
* Used to map subflow sequence space to MPTCP data sequence space.
* Used to send Data ACKs
*/
/*
* DSS Option variants coded as flags in the DSS option flags field
*/
#define MDSS_A 0x01 /* Data ACK present if set */
#define MDSS_a 0x02 /* 64-bit Data ACK present if set */
#define MDSS_M 0x04 /* Data Sequence Number present if set */
#define MDSS_m 0x08 /* 64-bit Data Sequence Number present if set */
#define MDSS_F 0x10 /* Data FIN present */
/* DSS fields common to all DSS option variants */
struct mptcp_dss_copt {
uint8_t mdss_kind;
uint8_t mdss_len;
#if BYTE_ORDER == LITTLE_ENDIAN
uint8_t mdss_reserved1:4,
mdss_subtype:4;
#else /* BIG_ENDIAN */
uint8_t mdss_subtype:4,
mdss_reserved1:4;
#endif
uint8_t mdss_flags;
}__attribute__((__packed__));
/* 32-bit DSS option */
struct mptcp_dsn_opt {
struct mptcp_dss_copt mdss_copt;
uint32_t mdss_dsn; /* Data Sequence Number */
uint32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */
uint16_t mdss_data_len; /* Data Length */
/* uint16_t mdss_xsum; */ /* Data checksum - optional */
}__attribute__((__packed__));
/* 64-bit DSS option */
struct mptcp_dsn64_opt {
struct mptcp_dss_copt mdss_copt;
uint64_t mdss_dsn; /* Data Sequence Number */
uint32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */
uint16_t mdss_data_len; /* Data Length */
/* uint16_t mdss_xsum; */ /* Data checksum - optional */
}__attribute__((__packed__));
/* 32-bit DSS Data ACK option */
struct mptcp_data_ack_opt {
struct mptcp_dss_copt mdss_copt;
uint32_t mdss_ack;
}__attribute__((__packed__));
/* 64-bit DSS Data ACK option */
struct mptcp_data_ack64_opt {
struct mptcp_dss_copt mdss_copt;
uint64_t mdss_ack;
}__attribute__((__packed__));
/* 32-bit DSS+Data ACK option */
struct mptcp_dss_ack_opt {
struct mptcp_dss_copt mdss_copt;
uint32_t mdss_ack; /* Data ACK */
uint32_t mdss_dsn; /* Data Sequence Number */
uint32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */
uint16_t mdss_data_len; /* Data Length */
/* uint16_t mdss_xsum; */ /* Data checksum - optional */
}__attribute__((__packed__));
/* 64-bit DSS+Data ACK option */
struct mptcp_dss64_ack64_opt {
struct mptcp_dss_copt mdss_copt;
uint64_t mdss_ack; /* Data ACK */
uint64_t mdss_dsn; /* Data Sequence Number */
uint32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */
uint16_t mdss_data_len; /* Data Length */
/* uint16_t mdss_xsum; */ /* Data checksum - optional */
}__attribute__((__packed__));
/* DSS+Data ACK mixed option variants */
struct mptcp_dss32_ack64_opt {
struct mptcp_dss_copt mdss_copt;
uint64_t mdss_ack; /* Data ACK */
uint32_t mdss_dsn; /* Data Sequence Number */
uint32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */
uint16_t mdss_data_len; /* Data Length */
/* uint16_t mdss_xsum; */ /* Data checksum - optional */
}__attribute__((__packed__));
struct mptcp_dss64_ack32_opt {
struct mptcp_dss_copt mdss_copt;
uint32_t mdss_ack; /* Data ACK */
uint64_t mdss_dsn; /* Data Sequence Number */
uint32_t mdss_subflow_seqn; /* Relative Subflow Seq Num */
uint16_t mdss_data_len; /* Data Length */
/* uint16_t mdss_xsum; */ /* Data checksum - optional */
}__attribute__((__packed__));
/*
* MPTCP Fast Close Option
*
* MPTCP connection is aborted if the FastClose option is received.
* In future, we may send this option if a MPTCP socket level abort
* API is supported.
*/
struct mptcp_fastclose_opt {
uint8_t mfast_kind;
uint8_t mfast_len;
#if BYTE_ORDER == LITTLE_ENDIAN
uint8_t mfast_reserved:4,
mfast_subtype:4;
#else /* BIG_ENDIAN */
uint8_t mfast_subtype:4,
mfast_reserved:4;
#endif
uint8_t mfast_reserved1;
uint64_t mfast_key; /* Option receiver's key */
}__attribute__((__packed__));
/*
* MPTCP MP_FAIL Option
*
* When DSS checksum is ON, and checksum fails, remote peer may send
* this option to indicate the failure. Likewise, we may send this
* option.
*/
struct mptcp_mpfail_opt {
uint8_t mfail_kind;
uint8_t mfail_len;
#if BYTE_ORDER == LITTLE_ENDIAN
uint8_t mfail_reserved:4,
mfail_subtype:4;
#else /* BIG_ENDIAN */
uint8_t mfail_subtype:4,
mfail_reserved:4;
#endif
uint8_t mfail_reserved1:8;
uint64_t mfail_dsn;
}__attribute__((__packed__));
struct mptcp_add_addr_opt {
uint8_t maddr_kind;
uint8_t maddr_len;
#if BYTE_ORDER == LITTLE_ENDIAN
uint8_t maddr_flags:4,
maddr_subtype:4;
#else /* BIG_ENDIAN */
uint8_t maddr_subtype:4,
maddr_flags:4;
#endif
uint8_t maddr_addrid;
union {
struct {
struct in_addr maddr_addrv4;
uint32_t maddr_pad[3];
};
struct {
struct in6_addr maddr_addrv6;
};
} maddr_u;
}__attribute__((__packed__));
struct mptcp_add_addr_hmac_msg_v4 {
uint8_t maddr_addrid;
struct in_addr maddr_addr;
uint16_t maddr_port;
}__attribute__((__packed__));
struct mptcp_add_addr_hmac_msg_v6 {
uint8_t maddr_addrid;
struct in6_addr maddr_addr;
uint16_t maddr_port;
}__attribute__((__packed__));
#define MPTCP_V0_ADD_ADDR_IPV4 4
#define MPTCP_V0_ADD_ADDR_IPV6 6
#define MPTCP_V1_ADD_ADDR_ECHO 0x1
#define MPTCP_V0_ADD_ADDR_OPT_LEN_V4 8
#define MPTCP_V0_ADD_ADDR_OPT_LEN_V6 20
#define MPTCP_V1_ADD_ADDR_OPT_LEN_V4 16
#define MPTCP_V1_ADD_ADDR_OPT_LEN_V6 28
#define MPTCP_V1_ADD_ADDR_ECHO_OPT_LEN_V4 8
#define MPTCP_V1_ADD_ADDR_ECHO_OPT_LEN_V6 20
/*
* MPTCP MP_PRIO Option
*
* When a subflow becomes unusable (due to bad radio coverage) or
* it is the costlier path or it is not the preferred path, the receiver may
* use this option to let the sender know of its path preference.
*/
/* Option to change priority of some other subflow(s) using addr_id */
struct mptcp_mpprio_addr_opt {
uint8_t mpprio_kind;
uint8_t mpprio_len;
#define MPTCP_MPPRIO_BKP 0x1
#if BYTE_ORDER == LITTLE_ENDIAN
uint8_t mpprio_flags:4,
mpprio_subtype:4;
#else /* BIG_ENDIAN */
uint8_t mpprio_subtype:4,
mpprio_flags:4;
#endif
uint8_t mpprio_addrid;
}__attribute__((__packed__));
#endif /* BSD_KERNEL_PRIVATE */
#endif /* _NETINET_MPTCP_H_ */