1 /* 2 * Copyright (c) 2015-2025 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29 /* TCP-cache to store and retrieve TCP-related information */ 30 31 #ifndef _NETINET_TCP_CACHE_H 32 #define _NETINET_TCP_CACHE_H 33 34 #include <net/if_private.h> 35 #include <netinet/tcp_var.h> 36 #include <netinet/in.h> 37 38 #ifdef PRIVATE 39 40 #define TCP_HEURISTICS_LIST_ENTITLEMENT "com.apple.private.tcp.heuristics_list" 41 #define TCP_CACHE_LIST_ENTITLEMENT "com.apple.private.tcp.cache_list" 42 43 typedef union { 44 struct in_addr addr; 45 struct in6_addr addr6; 46 } in_4_6_addr; 47 48 struct tcp_heuristic_key { 49 union { 50 uint8_t thk_net_signature[IFNET_SIGNATURELEN]; 51 in_4_6_addr thk_ip; 52 }; 53 sa_family_t thk_family; 54 }; 55 56 /* Data structure for sysctl export - same as tcp_heuristic but without list field */ 57 struct tcp_heuristics_data { 58 uint32_t th_last_access; 59 60 struct tcp_heuristic_key th_key; 61 62 uint8_t th_tfo_data_loss; /* The number of times a SYN+data has been lost */ 63 uint8_t th_tfo_req_loss; /* The number of times a SYN+cookie-req has been lost */ 64 uint8_t th_tfo_data_rst; /* The number of times a SYN+data has received a RST */ 65 uint8_t th_tfo_req_rst; /* The number of times a SYN+cookie-req has received a RST */ 66 uint8_t th_mptcp_loss; /* The number of times a SYN+MP_CAPABLE has been lost */ 67 uint8_t th_mptcp_success; /* The number of times MPTCP-negotiation has been successful */ 68 uint8_t th_ecn_droprst; /* The number of times ECN connections received a RST after first data pkt */ 69 uint8_t th_ecn_synrst; /* number of times RST was received in response to an ECN enabled SYN */ 70 uint32_t th_tfo_enabled_time; /* The moment when we reenabled TFO after backing off */ 71 uint32_t th_tfo_backoff_until; /* Time until when we should not try out TFO */ 72 uint32_t th_tfo_backoff; /* Current backoff timer */ 73 uint32_t th_mptcp_backoff; /* Time until when we should not try out MPTCP */ 74 uint32_t th_ecn_backoff; /* Time until when we should not try out ECN */ 75 76 uint8_t th_tfo_in_backoff:1, /* Are we avoiding TFO due to the backoff timer? */ 77 th_mptcp_in_backoff:1, /* Are we avoiding MPTCP due to the backoff timer? */ 78 th_mptcp_heuristic_disabled:1; /* Are heuristics disabled? */ 79 }; 80 81 struct tcp_cache_key { 82 sa_family_t tck_family; 83 84 struct tcp_heuristic_key tck_src; 85 in_4_6_addr tck_dst; 86 }; 87 88 #define TFO_COOKIE_LEN_MAX 16 89 90 /* Data structure for sysctl export - same as tcp_cache but without list field */ 91 struct tcp_cache_data { 92 uint32_t tc_last_access; 93 94 struct tcp_cache_key tc_key; 95 96 uint8_t tc_tfo_cookie[TFO_COOKIE_LEN_MAX]; 97 uint8_t tc_tfo_cookie_len; 98 99 uint8_t tc_mptcp_version_confirmed:1; 100 uint8_t tc_mptcp_version; /* version to use right now */ 101 uint32_t tc_mptcp_next_version_try; /* Time, until we try preferred version again */ 102 }; 103 104 #define MPTCP_VERSION_SUPPORTED 1 105 #define MPTCP_VERSION_UNSUPPORTED -1 106 #define MPTCP_VERSION_SUPPORTED_UNKNOWN 0 107 108 #endif /* PRIVATE */ 109 110 #ifdef KERNEL_PRIVATE 111 112 #define ECN_MIN_CE_PROBES (20) /* Probes are basically the number of incoming packets */ 113 #define ECN_MAX_CE_RATIO (18) /* Ratio is the maximum number of E/CE-packets we accept per incoming "probe" */ 114 115 extern void tcp_cache_set_cookie(struct tcpcb *tp, u_char *__counted_by(len) cookie, u_int8_t len); 116 extern int tcp_cache_get_cookie(struct tcpcb *tp, u_char *__counted_by(buflen) cookie, uint8_t buflen, u_int8_t *len); 117 extern unsigned int tcp_cache_get_cookie_len(struct tcpcb *tp); 118 extern uint8_t tcp_cache_get_mptcp_version(struct sockaddr* dst); 119 extern void tcp_cache_update_mptcp_version(struct tcpcb *tp, boolean_t succeeded); 120 121 extern void tcp_heuristic_tfo_loss(struct tcpcb *tp); 122 extern void tcp_heuristic_tfo_rst(struct tcpcb *tp); 123 extern void tcp_heuristic_mptcp_loss(struct tcpcb *tp); 124 extern void tcp_heuristic_ecn_loss(struct tcpcb *tp); 125 extern void tcp_heuristic_ecn_aggressive(struct tcpcb *tp); 126 extern void tcp_heuristic_tfo_middlebox(struct tcpcb *tp); 127 extern void tcp_heuristic_tfo_success(struct tcpcb *tp); 128 extern void tcp_heuristic_mptcp_success(struct tcpcb *tp); 129 extern void tcp_heuristic_ecn_success(struct tcpcb *tp); 130 extern boolean_t tcp_heuristic_do_tfo(struct tcpcb *tp); 131 extern int tcp_heuristic_do_mptcp(struct tcpcb *tp); 132 extern boolean_t tcp_heuristic_do_ecn(struct tcpcb *tp); 133 extern void tcp_heuristic_ecn_droprst(struct tcpcb *tp); 134 extern void tcp_heuristic_ecn_synrst(struct tcpcb *tp); 135 136 extern boolean_t tcp_heuristic_do_ecn_with_address(struct ifnet *ifp, 137 union sockaddr_in_4_6 *local_address); 138 extern void tcp_heuristics_ecn_update(struct necp_tcp_ecn_cache *necp_buffer, 139 struct ifnet *ifp, union sockaddr_in_4_6 *local_address); 140 extern boolean_t tcp_heuristic_do_tfo_with_address(struct ifnet *ifp, 141 union sockaddr_in_4_6 *local_address, union sockaddr_in_4_6 *remote_address, 142 u_int8_t *__counted_by(maxlen) cookie, u_int8_t maxlen, u_int8_t *cookie_len); 143 extern void tcp_heuristics_tfo_update(struct necp_tcp_tfo_cache *necp_buffer, 144 struct ifnet *ifp, union sockaddr_in_4_6 *local_address, 145 union sockaddr_in_4_6 *remote_address); 146 147 extern void tcp_cache_init(void); 148 149 #endif /* KERNEL_PRIVATE */ 150 #endif /* _NETINET_TCP_CACHE_H */ 151