1 /*- 2 * Copyright (c) 2015-2017 Patrick Kelsey 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 /* 28 * This is an implementation of TCP Fast Open (TFO) [RFC7413]. To include 29 * this code, add the following line to your kernel config: 30 * 31 * options TCP_RFC7413 32 * 33 * 34 * The generated TFO cookies are the 64-bit output of 35 * SipHash24(key=<16-byte-key>, msg=<client-ip>). Multiple concurrent valid 36 * keys are supported so that time-based rolling cookie invalidation 37 * policies can be implemented in the system. The default number of 38 * concurrent keys is 2. This can be adjusted in the kernel config as 39 * follows: 40 * 41 * options TCP_RFC7413_MAX_KEYS=<num-keys> 42 * 43 * 44 * In addition to the facilities defined in RFC7413, this implementation 45 * supports a pre-shared key (PSK) mode of operation in which the TFO server 46 * requires the client to be in posession of a shared secret in order for 47 * the client to be able to successfully open TFO connections with the 48 * server. This is useful, for example, in environments where TFO servers 49 * are exposed to both internal and external clients and only wish to allow 50 * TFO connections from internal clients. 51 * 52 * In the PSK mode of operation, the server generates and sends TFO cookies 53 * to requesting clients as usual. However, when validating cookies 54 * received in TFO SYNs from clients, the server requires the 55 * client-supplied cookie to equal SipHash24(key=<16-byte-psk>, 56 * msg=<cookie-sent-to-client>). 57 * 58 * Multiple concurrent valid pre-shared keys are supported so that 59 * time-based rolling PSK invalidation policies can be implemented in the 60 * system. The default number of concurrent pre-shared keys is 2. This can 61 * be adjusted in the kernel config as follows: 62 * 63 * options TCP_RFC7413_MAX_PSKS=<num-psks> 64 * 65 * 66 * The following TFO-specific sysctls are defined: 67 * 68 * net.inet.tcp.fastopen.acceptany (RW, default 0) 69 * When non-zero, all client-supplied TFO cookies will be considered to 70 * be valid. 71 * 72 * net.inet.tcp.fastopen.autokey (RW, default 120) 73 * When this and net.inet.tcp.fastopen.server_enable are non-zero, a new 74 * key will be automatically generated after this many seconds. 75 * 76 * net.inet.tcp.fastopen.ccache_bucket_limit 77 * (RWTUN, default TCP_FASTOPEN_CCACHE_BUCKET_LIMIT_DEFAULT) 78 * The maximum number of entries in a client cookie cache bucket. 79 * 80 * net.inet.tcp.fastopen.ccache_buckets 81 * (RDTUN, default TCP_FASTOPEN_CCACHE_BUCKETS_DEFAULT) 82 * The number of client cookie cache buckets. 83 * 84 * net.inet.tcp.fastopen.ccache_list (RO) 85 * Print the client cookie cache. 86 * 87 * net.inet.tcp.fastopen.client_enable (RW, default 0) 88 * When zero, no new active (i.e., client) TFO connections can be 89 * created. On the transition from enabled to disabled, the client 90 * cookie cache is cleared and disabled. The transition from enabled to 91 * disabled does not affect any active TFO connections in progress; it 92 * only prevents new ones from being made. 93 * 94 * net.inet.tcp.fastopen.keylen (RD) 95 * The key length in bytes. 96 * 97 * net.inet.tcp.fastopen.maxkeys (RD) 98 * The maximum number of keys supported. 99 * 100 * net.inet.tcp.fastopen.maxpsks (RD) 101 * The maximum number of pre-shared keys supported. 102 * 103 * net.inet.tcp.fastopen.numkeys (RD) 104 * The current number of keys installed. 105 * 106 * net.inet.tcp.fastopen.numpsks (RD) 107 * The current number of pre-shared keys installed. 108 * 109 * net.inet.tcp.fastopen.path_disable_time 110 * (RW, default TCP_FASTOPEN_PATH_DISABLE_TIME_DEFAULT) 111 * When a failure occurs while trying to create a new active (i.e., 112 * client) TFO connection, new active connections on the same path, as 113 * determined by the tuple {client_ip, server_ip, server_port}, will be 114 * forced to be non-TFO for this many seconds. Note that the path 115 * disable mechanism relies on state stored in client cookie cache 116 * entries, so it is possible for the disable time for a given path to 117 * be reduced if the corresponding client cookie cache entry is reused 118 * due to resource pressure before the disable period has elapsed. 119 * 120 * net.inet.tcp.fastopen.psk_enable (RW, default 0) 121 * When non-zero, pre-shared key (PSK) mode is enabled for all TFO 122 * servers. On the transition from enabled to disabled, all installed 123 * pre-shared keys are removed. 124 * 125 * net.inet.tcp.fastopen.server_enable (RW, default 0) 126 * When zero, no new passive (i.e., server) TFO connections can be 127 * created. On the transition from enabled to disabled, all installed 128 * keys and pre-shared keys are removed. On the transition from 129 * disabled to enabled, if net.inet.tcp.fastopen.autokey is non-zero and 130 * there are no keys installed, a new key will be generated immediately. 131 * The transition from enabled to disabled does not affect any passive 132 * TFO connections in progress; it only prevents new ones from being 133 * made. 134 * 135 * net.inet.tcp.fastopen.setkey (WR) 136 * Install a new key by writing net.inet.tcp.fastopen.keylen bytes to 137 * this sysctl. 138 * 139 * net.inet.tcp.fastopen.setpsk (WR) 140 * Install a new pre-shared key by writing net.inet.tcp.fastopen.keylen 141 * bytes to this sysctl. 142 * 143 * In order for TFO connections to be created via a listen socket, that 144 * socket must have the TCP_FASTOPEN socket option set on it. This option 145 * can be set on the socket either before or after the listen() is invoked. 146 * Clearing this option on a listen socket after it has been set has no 147 * effect on existing TFO connections or TFO connections in progress; it 148 * only prevents new TFO connections from being made. 149 * 150 * For passively-created sockets, the TCP_FASTOPEN socket option can be 151 * queried to determine whether the connection was established using TFO. 152 * Note that connections that are established via a TFO SYN, but that fall 153 * back to using a non-TFO SYN|ACK will have the TCP_FASTOPEN socket option 154 * set. 155 * 156 * Per the RFC, this implementation limits the number of TFO connections 157 * that can be in the SYN_RECEIVED state on a per listen-socket basis. 158 * Whenever this limit is exceeded, requests for new TFO connections are 159 * serviced as non-TFO requests. Without such a limit, given a valid TFO 160 * cookie, an attacker could keep the listen queue in an overflow condition 161 * using a TFO SYN flood. This implementation sets the limit at half the 162 * configured listen backlog. 163 * 164 */ 165 166 #include <sys/cdefs.h> 167 __FBSDID("$FreeBSD$"); 168 169 #include "opt_inet.h" 170 171 #include <sys/param.h> 172 #include <sys/jail.h> 173 #include <sys/kernel.h> 174 #include <sys/hash.h> 175 #include <sys/limits.h> 176 #include <sys/lock.h> 177 #include <sys/proc.h> 178 #include <sys/rmlock.h> 179 #include <sys/sbuf.h> 180 #include <sys/socket.h> 181 #include <sys/socketvar.h> 182 #include <sys/sysctl.h> 183 #include <sys/systm.h> 184 185 #include <crypto/siphash/siphash.h> 186 187 #include <net/vnet.h> 188 189 #include <netinet/in.h> 190 #include <netinet/in_pcb.h> 191 #include <netinet/tcp_var.h> 192 #include <netinet/tcp_fastopen.h> 193 194 195 #define TCP_FASTOPEN_KEY_LEN SIPHASH_KEY_LENGTH 196 197 #if TCP_FASTOPEN_PSK_LEN != TCP_FASTOPEN_KEY_LEN 198 #error TCP_FASTOPEN_PSK_LEN must be equal to TCP_FASTOPEN_KEY_LEN 199 #endif 200 201 /* 202 * Because a PSK-mode setsockopt() uses tcpcb.t_tfo_cookie.client to hold 203 * the PSK until the connect occurs. 204 */ 205 #if TCP_FASTOPEN_MAX_COOKIE_LEN < TCP_FASTOPEN_PSK_LEN 206 #error TCP_FASTOPEN_MAX_COOKIE_LEN must be >= TCP_FASTOPEN_PSK_LEN 207 #endif 208 209 #define TCP_FASTOPEN_CCACHE_BUCKET_LIMIT_DEFAULT 16 210 #define TCP_FASTOPEN_CCACHE_BUCKETS_DEFAULT 2048 /* must be power of 2 */ 211 212 #define TCP_FASTOPEN_PATH_DISABLE_TIME_DEFAULT 900 /* seconds */ 213 214 #if !defined(TCP_RFC7413_MAX_KEYS) || (TCP_RFC7413_MAX_KEYS < 1) 215 #define TCP_FASTOPEN_MAX_KEYS 2 216 #else 217 #define TCP_FASTOPEN_MAX_KEYS TCP_RFC7413_MAX_KEYS 218 #endif 219 220 #if TCP_FASTOPEN_MAX_KEYS > 10 221 #undef TCP_FASTOPEN_MAX_KEYS 222 #define TCP_FASTOPEN_MAX_KEYS 10 223 #endif 224 225 #if !defined(TCP_RFC7413_MAX_PSKS) || (TCP_RFC7413_MAX_PSKS < 1) 226 #define TCP_FASTOPEN_MAX_PSKS 2 227 #else 228 #define TCP_FASTOPEN_MAX_PSKS TCP_RFC7413_MAX_PSKS 229 #endif 230 231 #if TCP_FASTOPEN_MAX_PSKS > 10 232 #undef TCP_FASTOPEN_MAX_PSKS 233 #define TCP_FASTOPEN_MAX_PSKS 10 234 #endif 235 236 struct tcp_fastopen_keylist { 237 unsigned int newest; 238 unsigned int newest_psk; 239 uint8_t key[TCP_FASTOPEN_MAX_KEYS][TCP_FASTOPEN_KEY_LEN]; 240 uint8_t psk[TCP_FASTOPEN_MAX_PSKS][TCP_FASTOPEN_KEY_LEN]; 241 }; 242 243 struct tcp_fastopen_callout { 244 struct callout c; 245 struct vnet *v; 246 }; 247 248 static struct tcp_fastopen_ccache_entry *tcp_fastopen_ccache_lookup( 249 struct in_conninfo *, struct tcp_fastopen_ccache_bucket **); 250 static struct tcp_fastopen_ccache_entry *tcp_fastopen_ccache_create( 251 struct tcp_fastopen_ccache_bucket *, struct in_conninfo *, uint16_t, uint8_t, 252 uint8_t *); 253 static void tcp_fastopen_ccache_bucket_trim(struct tcp_fastopen_ccache_bucket *, 254 unsigned int); 255 static void tcp_fastopen_ccache_entry_drop(struct tcp_fastopen_ccache_entry *, 256 struct tcp_fastopen_ccache_bucket *); 257 258 SYSCTL_NODE(_net_inet_tcp, OID_AUTO, fastopen, CTLFLAG_RW, 0, "TCP Fast Open"); 259 260 VNET_DEFINE_STATIC(int, tcp_fastopen_acceptany) = 0; 261 #define V_tcp_fastopen_acceptany VNET(tcp_fastopen_acceptany) 262 SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, acceptany, 263 CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_fastopen_acceptany), 0, 264 "Accept any non-empty cookie"); 265 266 VNET_DEFINE_STATIC(unsigned int, tcp_fastopen_autokey) = 120; 267 #define V_tcp_fastopen_autokey VNET(tcp_fastopen_autokey) 268 static int sysctl_net_inet_tcp_fastopen_autokey(SYSCTL_HANDLER_ARGS); 269 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, autokey, 270 CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, NULL, 0, 271 &sysctl_net_inet_tcp_fastopen_autokey, "IU", 272 "Number of seconds between auto-generation of a new key; zero disables"); 273 274 static int sysctl_net_inet_tcp_fastopen_ccache_bucket_limit(SYSCTL_HANDLER_ARGS); 275 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, ccache_bucket_limit, 276 CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RWTUN, NULL, 0, 277 &sysctl_net_inet_tcp_fastopen_ccache_bucket_limit, "IU", 278 "Max entries per bucket in client cookie cache"); 279 280 VNET_DEFINE_STATIC(unsigned int, tcp_fastopen_ccache_buckets) = 281 TCP_FASTOPEN_CCACHE_BUCKETS_DEFAULT; 282 #define V_tcp_fastopen_ccache_buckets VNET(tcp_fastopen_ccache_buckets) 283 SYSCTL_UINT(_net_inet_tcp_fastopen, OID_AUTO, ccache_buckets, 284 CTLFLAG_VNET | CTLFLAG_RDTUN, &VNET_NAME(tcp_fastopen_ccache_buckets), 0, 285 "Client cookie cache number of buckets (power of 2)"); 286 287 VNET_DEFINE(unsigned int, tcp_fastopen_client_enable) = 1; 288 static int sysctl_net_inet_tcp_fastopen_client_enable(SYSCTL_HANDLER_ARGS); 289 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, client_enable, 290 CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, NULL, 0, 291 &sysctl_net_inet_tcp_fastopen_client_enable, "IU", 292 "Enable/disable TCP Fast Open client functionality"); 293 294 SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, keylen, 295 CTLFLAG_RD, SYSCTL_NULL_INT_PTR, TCP_FASTOPEN_KEY_LEN, 296 "Key length in bytes"); 297 298 SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, maxkeys, 299 CTLFLAG_RD, SYSCTL_NULL_INT_PTR, TCP_FASTOPEN_MAX_KEYS, 300 "Maximum number of keys supported"); 301 302 SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, maxpsks, 303 CTLFLAG_RD, SYSCTL_NULL_INT_PTR, TCP_FASTOPEN_MAX_PSKS, 304 "Maximum number of pre-shared keys supported"); 305 306 VNET_DEFINE_STATIC(unsigned int, tcp_fastopen_numkeys) = 0; 307 #define V_tcp_fastopen_numkeys VNET(tcp_fastopen_numkeys) 308 SYSCTL_UINT(_net_inet_tcp_fastopen, OID_AUTO, numkeys, 309 CTLFLAG_VNET | CTLFLAG_RD, &VNET_NAME(tcp_fastopen_numkeys), 0, 310 "Number of keys installed"); 311 312 VNET_DEFINE_STATIC(unsigned int, tcp_fastopen_numpsks) = 0; 313 #define V_tcp_fastopen_numpsks VNET(tcp_fastopen_numpsks) 314 SYSCTL_UINT(_net_inet_tcp_fastopen, OID_AUTO, numpsks, 315 CTLFLAG_VNET | CTLFLAG_RD, &VNET_NAME(tcp_fastopen_numpsks), 0, 316 "Number of pre-shared keys installed"); 317 318 VNET_DEFINE_STATIC(unsigned int, tcp_fastopen_path_disable_time) = 319 TCP_FASTOPEN_PATH_DISABLE_TIME_DEFAULT; 320 #define V_tcp_fastopen_path_disable_time VNET(tcp_fastopen_path_disable_time) 321 SYSCTL_UINT(_net_inet_tcp_fastopen, OID_AUTO, path_disable_time, 322 CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_fastopen_path_disable_time), 0, 323 "Seconds a TFO failure disables a {client_ip, server_ip, server_port} path"); 324 325 VNET_DEFINE_STATIC(unsigned int, tcp_fastopen_psk_enable) = 0; 326 #define V_tcp_fastopen_psk_enable VNET(tcp_fastopen_psk_enable) 327 static int sysctl_net_inet_tcp_fastopen_psk_enable(SYSCTL_HANDLER_ARGS); 328 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, psk_enable, 329 CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, NULL, 0, 330 &sysctl_net_inet_tcp_fastopen_psk_enable, "IU", 331 "Enable/disable TCP Fast Open server pre-shared key mode"); 332 333 VNET_DEFINE(unsigned int, tcp_fastopen_server_enable) = 0; 334 static int sysctl_net_inet_tcp_fastopen_server_enable(SYSCTL_HANDLER_ARGS); 335 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, server_enable, 336 CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, NULL, 0, 337 &sysctl_net_inet_tcp_fastopen_server_enable, "IU", 338 "Enable/disable TCP Fast Open server functionality"); 339 340 static int sysctl_net_inet_tcp_fastopen_setkey(SYSCTL_HANDLER_ARGS); 341 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, setkey, 342 CTLFLAG_VNET | CTLTYPE_OPAQUE | CTLFLAG_WR, NULL, 0, 343 &sysctl_net_inet_tcp_fastopen_setkey, "", 344 "Install a new key"); 345 346 static int sysctl_net_inet_tcp_fastopen_setpsk(SYSCTL_HANDLER_ARGS); 347 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, setpsk, 348 CTLFLAG_VNET | CTLTYPE_OPAQUE | CTLFLAG_WR, NULL, 0, 349 &sysctl_net_inet_tcp_fastopen_setpsk, "", 350 "Install a new pre-shared key"); 351 352 static int sysctl_net_inet_tcp_fastopen_ccache_list(SYSCTL_HANDLER_ARGS); 353 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, ccache_list, 354 CTLFLAG_VNET | CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_SKIP, NULL, 0, 355 sysctl_net_inet_tcp_fastopen_ccache_list, "A", 356 "List of all client cookie cache entries"); 357 358 VNET_DEFINE_STATIC(struct rmlock, tcp_fastopen_keylock); 359 #define V_tcp_fastopen_keylock VNET(tcp_fastopen_keylock) 360 361 #define TCP_FASTOPEN_KEYS_RLOCK(t) rm_rlock(&V_tcp_fastopen_keylock, (t)) 362 #define TCP_FASTOPEN_KEYS_RUNLOCK(t) rm_runlock(&V_tcp_fastopen_keylock, (t)) 363 #define TCP_FASTOPEN_KEYS_WLOCK() rm_wlock(&V_tcp_fastopen_keylock) 364 #define TCP_FASTOPEN_KEYS_WUNLOCK() rm_wunlock(&V_tcp_fastopen_keylock) 365 366 VNET_DEFINE_STATIC(struct tcp_fastopen_keylist, tcp_fastopen_keys); 367 #define V_tcp_fastopen_keys VNET(tcp_fastopen_keys) 368 369 VNET_DEFINE_STATIC(struct tcp_fastopen_callout, tcp_fastopen_autokey_ctx); 370 #define V_tcp_fastopen_autokey_ctx VNET(tcp_fastopen_autokey_ctx) 371 372 VNET_DEFINE_STATIC(uma_zone_t, counter_zone); 373 #define V_counter_zone VNET(counter_zone) 374 375 static MALLOC_DEFINE(M_TCP_FASTOPEN_CCACHE, "tfo_ccache", "TFO client cookie cache buckets"); 376 377 VNET_DEFINE_STATIC(struct tcp_fastopen_ccache, tcp_fastopen_ccache); 378 #define V_tcp_fastopen_ccache VNET(tcp_fastopen_ccache) 379 380 #define CCB_LOCK(ccb) mtx_lock(&(ccb)->ccb_mtx) 381 #define CCB_UNLOCK(ccb) mtx_unlock(&(ccb)->ccb_mtx) 382 #define CCB_LOCK_ASSERT(ccb) mtx_assert(&(ccb)->ccb_mtx, MA_OWNED) 383 384 385 void 386 tcp_fastopen_init(void) 387 { 388 unsigned int i; 389 390 V_counter_zone = uma_zcreate("tfo", sizeof(unsigned int), 391 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 392 rm_init(&V_tcp_fastopen_keylock, "tfo_keylock"); 393 callout_init_rm(&V_tcp_fastopen_autokey_ctx.c, 394 &V_tcp_fastopen_keylock, 0); 395 V_tcp_fastopen_autokey_ctx.v = curvnet; 396 V_tcp_fastopen_keys.newest = TCP_FASTOPEN_MAX_KEYS - 1; 397 V_tcp_fastopen_keys.newest_psk = TCP_FASTOPEN_MAX_PSKS - 1; 398 399 /* May already be non-zero if kernel tunable was set */ 400 if (V_tcp_fastopen_ccache.bucket_limit == 0) 401 V_tcp_fastopen_ccache.bucket_limit = 402 TCP_FASTOPEN_CCACHE_BUCKET_LIMIT_DEFAULT; 403 404 /* May already be non-zero if kernel tunable was set */ 405 if ((V_tcp_fastopen_ccache_buckets == 0) || 406 !powerof2(V_tcp_fastopen_ccache_buckets)) 407 V_tcp_fastopen_ccache.buckets = 408 TCP_FASTOPEN_CCACHE_BUCKETS_DEFAULT; 409 else 410 V_tcp_fastopen_ccache.buckets = V_tcp_fastopen_ccache_buckets; 411 412 V_tcp_fastopen_ccache.mask = V_tcp_fastopen_ccache.buckets - 1; 413 V_tcp_fastopen_ccache.secret = arc4random(); 414 415 V_tcp_fastopen_ccache.base = malloc(V_tcp_fastopen_ccache.buckets * 416 sizeof(struct tcp_fastopen_ccache_bucket), M_TCP_FASTOPEN_CCACHE, 417 M_WAITOK | M_ZERO); 418 419 for (i = 0; i < V_tcp_fastopen_ccache.buckets; i++) { 420 TAILQ_INIT(&V_tcp_fastopen_ccache.base[i].ccb_entries); 421 mtx_init(&V_tcp_fastopen_ccache.base[i].ccb_mtx, "tfo_ccache_bucket", 422 NULL, MTX_DEF); 423 if (V_tcp_fastopen_client_enable) { 424 /* enable bucket */ 425 V_tcp_fastopen_ccache.base[i].ccb_num_entries = 0; 426 } else { 427 /* disable bucket */ 428 V_tcp_fastopen_ccache.base[i].ccb_num_entries = -1; 429 } 430 V_tcp_fastopen_ccache.base[i].ccb_ccache = &V_tcp_fastopen_ccache; 431 } 432 433 /* 434 * Note that while the total number of entries in the cookie cache 435 * is limited by the table management logic to 436 * V_tcp_fastopen_ccache.buckets * 437 * V_tcp_fastopen_ccache.bucket_limit, the total number of items in 438 * this zone can exceed that amount by the number of CPUs in the 439 * system times the maximum number of unallocated items that can be 440 * present in each UMA per-CPU cache for this zone. 441 */ 442 V_tcp_fastopen_ccache.zone = uma_zcreate("tfo_ccache_entries", 443 sizeof(struct tcp_fastopen_ccache_entry), NULL, NULL, NULL, NULL, 444 UMA_ALIGN_CACHE, 0); 445 } 446 447 void 448 tcp_fastopen_destroy(void) 449 { 450 struct tcp_fastopen_ccache_bucket *ccb; 451 unsigned int i; 452 453 for (i = 0; i < V_tcp_fastopen_ccache.buckets; i++) { 454 ccb = &V_tcp_fastopen_ccache.base[i]; 455 tcp_fastopen_ccache_bucket_trim(ccb, 0); 456 mtx_destroy(&ccb->ccb_mtx); 457 } 458 459 KASSERT(uma_zone_get_cur(V_tcp_fastopen_ccache.zone) == 0, 460 ("%s: TFO ccache zone allocation count not 0", __func__)); 461 uma_zdestroy(V_tcp_fastopen_ccache.zone); 462 free(V_tcp_fastopen_ccache.base, M_TCP_FASTOPEN_CCACHE); 463 464 callout_drain(&V_tcp_fastopen_autokey_ctx.c); 465 rm_destroy(&V_tcp_fastopen_keylock); 466 uma_zdestroy(V_counter_zone); 467 } 468 469 unsigned int * 470 tcp_fastopen_alloc_counter(void) 471 { 472 unsigned int *counter; 473 counter = uma_zalloc(V_counter_zone, M_NOWAIT); 474 if (counter) 475 *counter = 1; 476 return (counter); 477 } 478 479 void 480 tcp_fastopen_decrement_counter(unsigned int *counter) 481 { 482 if (*counter == 1) 483 uma_zfree(V_counter_zone, counter); 484 else 485 atomic_subtract_int(counter, 1); 486 } 487 488 static void 489 tcp_fastopen_addkey_locked(uint8_t *key) 490 { 491 492 V_tcp_fastopen_keys.newest++; 493 if (V_tcp_fastopen_keys.newest == TCP_FASTOPEN_MAX_KEYS) 494 V_tcp_fastopen_keys.newest = 0; 495 memcpy(V_tcp_fastopen_keys.key[V_tcp_fastopen_keys.newest], key, 496 TCP_FASTOPEN_KEY_LEN); 497 if (V_tcp_fastopen_numkeys < TCP_FASTOPEN_MAX_KEYS) 498 V_tcp_fastopen_numkeys++; 499 } 500 501 static void 502 tcp_fastopen_addpsk_locked(uint8_t *psk) 503 { 504 505 V_tcp_fastopen_keys.newest_psk++; 506 if (V_tcp_fastopen_keys.newest_psk == TCP_FASTOPEN_MAX_PSKS) 507 V_tcp_fastopen_keys.newest_psk = 0; 508 memcpy(V_tcp_fastopen_keys.psk[V_tcp_fastopen_keys.newest_psk], psk, 509 TCP_FASTOPEN_KEY_LEN); 510 if (V_tcp_fastopen_numpsks < TCP_FASTOPEN_MAX_PSKS) 511 V_tcp_fastopen_numpsks++; 512 } 513 514 static void 515 tcp_fastopen_autokey_locked(void) 516 { 517 uint8_t newkey[TCP_FASTOPEN_KEY_LEN]; 518 519 arc4rand(newkey, TCP_FASTOPEN_KEY_LEN, 0); 520 tcp_fastopen_addkey_locked(newkey); 521 } 522 523 static void 524 tcp_fastopen_autokey_callout(void *arg) 525 { 526 struct tcp_fastopen_callout *ctx = arg; 527 528 CURVNET_SET(ctx->v); 529 tcp_fastopen_autokey_locked(); 530 callout_reset(&ctx->c, V_tcp_fastopen_autokey * hz, 531 tcp_fastopen_autokey_callout, ctx); 532 CURVNET_RESTORE(); 533 } 534 535 536 static uint64_t 537 tcp_fastopen_make_cookie(uint8_t key[SIPHASH_KEY_LENGTH], struct in_conninfo *inc) 538 { 539 SIPHASH_CTX ctx; 540 uint64_t siphash; 541 542 SipHash24_Init(&ctx); 543 SipHash_SetKey(&ctx, key); 544 switch (inc->inc_flags & INC_ISIPV6) { 545 #ifdef INET 546 case 0: 547 SipHash_Update(&ctx, &inc->inc_faddr, sizeof(inc->inc_faddr)); 548 break; 549 #endif 550 #ifdef INET6 551 case INC_ISIPV6: 552 SipHash_Update(&ctx, &inc->inc6_faddr, sizeof(inc->inc6_faddr)); 553 break; 554 #endif 555 } 556 SipHash_Final((u_int8_t *)&siphash, &ctx); 557 558 return (siphash); 559 } 560 561 static uint64_t 562 tcp_fastopen_make_psk_cookie(uint8_t *psk, uint8_t *cookie, uint8_t cookie_len) 563 { 564 SIPHASH_CTX ctx; 565 uint64_t psk_cookie; 566 567 SipHash24_Init(&ctx); 568 SipHash_SetKey(&ctx, psk); 569 SipHash_Update(&ctx, cookie, cookie_len); 570 SipHash_Final((u_int8_t *)&psk_cookie, &ctx); 571 572 return (psk_cookie); 573 } 574 575 static int 576 tcp_fastopen_find_cookie_match_locked(uint8_t *wire_cookie, uint64_t *cur_cookie) 577 { 578 unsigned int i, psk_index; 579 uint64_t psk_cookie; 580 581 if (V_tcp_fastopen_psk_enable) { 582 psk_index = V_tcp_fastopen_keys.newest_psk; 583 for (i = 0; i < V_tcp_fastopen_numpsks; i++) { 584 psk_cookie = 585 tcp_fastopen_make_psk_cookie( 586 V_tcp_fastopen_keys.psk[psk_index], 587 (uint8_t *)cur_cookie, 588 TCP_FASTOPEN_COOKIE_LEN); 589 590 if (memcmp(wire_cookie, &psk_cookie, 591 TCP_FASTOPEN_COOKIE_LEN) == 0) 592 return (1); 593 594 if (psk_index == 0) 595 psk_index = TCP_FASTOPEN_MAX_PSKS - 1; 596 else 597 psk_index--; 598 } 599 } else if (memcmp(wire_cookie, cur_cookie, TCP_FASTOPEN_COOKIE_LEN) == 0) 600 return (1); 601 602 return (0); 603 } 604 605 /* 606 * Return values: 607 * -1 the cookie is invalid and no valid cookie is available 608 * 0 the cookie is invalid and the latest cookie has been returned 609 * 1 the cookie is valid and the latest cookie has been returned 610 */ 611 int 612 tcp_fastopen_check_cookie(struct in_conninfo *inc, uint8_t *cookie, 613 unsigned int len, uint64_t *latest_cookie) 614 { 615 struct rm_priotracker tracker; 616 unsigned int i, key_index; 617 int rv; 618 uint64_t cur_cookie; 619 620 if (V_tcp_fastopen_acceptany) { 621 *latest_cookie = 0; 622 return (1); 623 } 624 625 TCP_FASTOPEN_KEYS_RLOCK(&tracker); 626 if (len != TCP_FASTOPEN_COOKIE_LEN) { 627 if (V_tcp_fastopen_numkeys > 0) { 628 *latest_cookie = 629 tcp_fastopen_make_cookie( 630 V_tcp_fastopen_keys.key[V_tcp_fastopen_keys.newest], 631 inc); 632 rv = 0; 633 } else 634 rv = -1; 635 goto out; 636 } 637 638 /* 639 * Check against each available key, from newest to oldest. 640 */ 641 key_index = V_tcp_fastopen_keys.newest; 642 for (i = 0; i < V_tcp_fastopen_numkeys; i++) { 643 cur_cookie = 644 tcp_fastopen_make_cookie(V_tcp_fastopen_keys.key[key_index], 645 inc); 646 if (i == 0) 647 *latest_cookie = cur_cookie; 648 rv = tcp_fastopen_find_cookie_match_locked(cookie, &cur_cookie); 649 if (rv) 650 goto out; 651 if (key_index == 0) 652 key_index = TCP_FASTOPEN_MAX_KEYS - 1; 653 else 654 key_index--; 655 } 656 rv = 0; 657 658 out: 659 TCP_FASTOPEN_KEYS_RUNLOCK(&tracker); 660 return (rv); 661 } 662 663 static int 664 sysctl_net_inet_tcp_fastopen_autokey(SYSCTL_HANDLER_ARGS) 665 { 666 int error; 667 unsigned int new; 668 669 new = V_tcp_fastopen_autokey; 670 error = sysctl_handle_int(oidp, &new, 0, req); 671 if (error == 0 && req->newptr) { 672 if (new > (INT_MAX / hz)) 673 return (EINVAL); 674 675 TCP_FASTOPEN_KEYS_WLOCK(); 676 if (V_tcp_fastopen_server_enable) { 677 if (V_tcp_fastopen_autokey && !new) 678 callout_stop(&V_tcp_fastopen_autokey_ctx.c); 679 else if (new) 680 callout_reset(&V_tcp_fastopen_autokey_ctx.c, 681 new * hz, tcp_fastopen_autokey_callout, 682 &V_tcp_fastopen_autokey_ctx); 683 } 684 V_tcp_fastopen_autokey = new; 685 TCP_FASTOPEN_KEYS_WUNLOCK(); 686 } 687 688 return (error); 689 } 690 691 static int 692 sysctl_net_inet_tcp_fastopen_psk_enable(SYSCTL_HANDLER_ARGS) 693 { 694 int error; 695 unsigned int new; 696 697 new = V_tcp_fastopen_psk_enable; 698 error = sysctl_handle_int(oidp, &new, 0, req); 699 if (error == 0 && req->newptr) { 700 if (V_tcp_fastopen_psk_enable && !new) { 701 /* enabled -> disabled */ 702 TCP_FASTOPEN_KEYS_WLOCK(); 703 V_tcp_fastopen_numpsks = 0; 704 V_tcp_fastopen_keys.newest_psk = 705 TCP_FASTOPEN_MAX_PSKS - 1; 706 V_tcp_fastopen_psk_enable = 0; 707 TCP_FASTOPEN_KEYS_WUNLOCK(); 708 } else if (!V_tcp_fastopen_psk_enable && new) { 709 /* disabled -> enabled */ 710 TCP_FASTOPEN_KEYS_WLOCK(); 711 V_tcp_fastopen_psk_enable = 1; 712 TCP_FASTOPEN_KEYS_WUNLOCK(); 713 } 714 } 715 return (error); 716 } 717 718 static int 719 sysctl_net_inet_tcp_fastopen_server_enable(SYSCTL_HANDLER_ARGS) 720 { 721 int error; 722 unsigned int new; 723 724 new = V_tcp_fastopen_server_enable; 725 error = sysctl_handle_int(oidp, &new, 0, req); 726 if (error == 0 && req->newptr) { 727 if (V_tcp_fastopen_server_enable && !new) { 728 /* enabled -> disabled */ 729 TCP_FASTOPEN_KEYS_WLOCK(); 730 V_tcp_fastopen_numkeys = 0; 731 V_tcp_fastopen_keys.newest = TCP_FASTOPEN_MAX_KEYS - 1; 732 if (V_tcp_fastopen_autokey) 733 callout_stop(&V_tcp_fastopen_autokey_ctx.c); 734 V_tcp_fastopen_numpsks = 0; 735 V_tcp_fastopen_keys.newest_psk = 736 TCP_FASTOPEN_MAX_PSKS - 1; 737 V_tcp_fastopen_server_enable = 0; 738 TCP_FASTOPEN_KEYS_WUNLOCK(); 739 } else if (!V_tcp_fastopen_server_enable && new) { 740 /* disabled -> enabled */ 741 TCP_FASTOPEN_KEYS_WLOCK(); 742 if (V_tcp_fastopen_autokey && 743 (V_tcp_fastopen_numkeys == 0)) { 744 tcp_fastopen_autokey_locked(); 745 callout_reset(&V_tcp_fastopen_autokey_ctx.c, 746 V_tcp_fastopen_autokey * hz, 747 tcp_fastopen_autokey_callout, 748 &V_tcp_fastopen_autokey_ctx); 749 } 750 V_tcp_fastopen_server_enable = 1; 751 TCP_FASTOPEN_KEYS_WUNLOCK(); 752 } 753 } 754 return (error); 755 } 756 757 static int 758 sysctl_net_inet_tcp_fastopen_setkey(SYSCTL_HANDLER_ARGS) 759 { 760 int error; 761 uint8_t newkey[TCP_FASTOPEN_KEY_LEN]; 762 763 if (req->oldptr != NULL || req->oldlen != 0) 764 return (EINVAL); 765 if (req->newptr == NULL) 766 return (EPERM); 767 if (req->newlen != sizeof(newkey)) 768 return (EINVAL); 769 error = SYSCTL_IN(req, newkey, sizeof(newkey)); 770 if (error) 771 return (error); 772 773 TCP_FASTOPEN_KEYS_WLOCK(); 774 tcp_fastopen_addkey_locked(newkey); 775 TCP_FASTOPEN_KEYS_WUNLOCK(); 776 777 return (0); 778 } 779 780 static int 781 sysctl_net_inet_tcp_fastopen_setpsk(SYSCTL_HANDLER_ARGS) 782 { 783 int error; 784 uint8_t newpsk[TCP_FASTOPEN_KEY_LEN]; 785 786 if (req->oldptr != NULL || req->oldlen != 0) 787 return (EINVAL); 788 if (req->newptr == NULL) 789 return (EPERM); 790 if (req->newlen != sizeof(newpsk)) 791 return (EINVAL); 792 error = SYSCTL_IN(req, newpsk, sizeof(newpsk)); 793 if (error) 794 return (error); 795 796 TCP_FASTOPEN_KEYS_WLOCK(); 797 tcp_fastopen_addpsk_locked(newpsk); 798 TCP_FASTOPEN_KEYS_WUNLOCK(); 799 800 return (0); 801 } 802 803 static int 804 sysctl_net_inet_tcp_fastopen_ccache_bucket_limit(SYSCTL_HANDLER_ARGS) 805 { 806 struct tcp_fastopen_ccache_bucket *ccb; 807 int error; 808 unsigned int new; 809 unsigned int i; 810 811 new = V_tcp_fastopen_ccache.bucket_limit; 812 error = sysctl_handle_int(oidp, &new, 0, req); 813 if (error == 0 && req->newptr) { 814 if ((new == 0) || (new > INT_MAX)) 815 error = EINVAL; 816 else { 817 if (new < V_tcp_fastopen_ccache.bucket_limit) { 818 for (i = 0; i < V_tcp_fastopen_ccache.buckets; 819 i++) { 820 ccb = &V_tcp_fastopen_ccache.base[i]; 821 tcp_fastopen_ccache_bucket_trim(ccb, new); 822 } 823 } 824 V_tcp_fastopen_ccache.bucket_limit = new; 825 } 826 827 } 828 return (error); 829 } 830 831 static int 832 sysctl_net_inet_tcp_fastopen_client_enable(SYSCTL_HANDLER_ARGS) 833 { 834 struct tcp_fastopen_ccache_bucket *ccb; 835 int error; 836 unsigned int new, i; 837 838 new = V_tcp_fastopen_client_enable; 839 error = sysctl_handle_int(oidp, &new, 0, req); 840 if (error == 0 && req->newptr) { 841 if (V_tcp_fastopen_client_enable && !new) { 842 /* enabled -> disabled */ 843 for (i = 0; i < V_tcp_fastopen_ccache.buckets; i++) { 844 ccb = &V_tcp_fastopen_ccache.base[i]; 845 KASSERT(ccb->ccb_num_entries > -1, 846 ("%s: ccb->ccb_num_entries %d is negative", 847 __func__, ccb->ccb_num_entries)); 848 tcp_fastopen_ccache_bucket_trim(ccb, 0); 849 } 850 V_tcp_fastopen_client_enable = 0; 851 } else if (!V_tcp_fastopen_client_enable && new) { 852 /* disabled -> enabled */ 853 for (i = 0; i < V_tcp_fastopen_ccache.buckets; i++) { 854 ccb = &V_tcp_fastopen_ccache.base[i]; 855 CCB_LOCK(ccb); 856 KASSERT(TAILQ_EMPTY(&ccb->ccb_entries), 857 ("%s: ccb->ccb_entries not empty", __func__)); 858 KASSERT(ccb->ccb_num_entries == -1, 859 ("%s: ccb->ccb_num_entries %d not -1", __func__, 860 ccb->ccb_num_entries)); 861 ccb->ccb_num_entries = 0; /* enable bucket */ 862 CCB_UNLOCK(ccb); 863 } 864 V_tcp_fastopen_client_enable = 1; 865 } 866 } 867 return (error); 868 } 869 870 void 871 tcp_fastopen_connect(struct tcpcb *tp) 872 { 873 struct inpcb *inp; 874 struct tcp_fastopen_ccache_bucket *ccb; 875 struct tcp_fastopen_ccache_entry *cce; 876 sbintime_t now; 877 uint16_t server_mss; 878 uint64_t psk_cookie; 879 880 psk_cookie = 0; 881 inp = tp->t_inpcb; 882 cce = tcp_fastopen_ccache_lookup(&inp->inp_inc, &ccb); 883 if (cce) { 884 if (cce->disable_time == 0) { 885 if ((cce->cookie_len > 0) && 886 (tp->t_tfo_client_cookie_len == 887 TCP_FASTOPEN_PSK_LEN)) { 888 psk_cookie = 889 tcp_fastopen_make_psk_cookie( 890 tp->t_tfo_cookie.client, 891 cce->cookie, cce->cookie_len); 892 } else { 893 tp->t_tfo_client_cookie_len = cce->cookie_len; 894 memcpy(tp->t_tfo_cookie.client, cce->cookie, 895 cce->cookie_len); 896 } 897 server_mss = cce->server_mss; 898 CCB_UNLOCK(ccb); 899 if (tp->t_tfo_client_cookie_len == 900 TCP_FASTOPEN_PSK_LEN && psk_cookie) { 901 tp->t_tfo_client_cookie_len = 902 TCP_FASTOPEN_COOKIE_LEN; 903 memcpy(tp->t_tfo_cookie.client, &psk_cookie, 904 TCP_FASTOPEN_COOKIE_LEN); 905 } 906 tcp_mss(tp, server_mss ? server_mss : -1); 907 tp->snd_wnd = tp->t_maxseg; 908 } else { 909 /* 910 * The path is disabled. Check the time and 911 * possibly re-enable. 912 */ 913 now = getsbinuptime(); 914 if (now - cce->disable_time > 915 ((sbintime_t)V_tcp_fastopen_path_disable_time << 32)) { 916 /* 917 * Re-enable path. Force a TFO cookie 918 * request. Forget the old MSS as it may be 919 * bogus now, and we will rediscover it in 920 * the SYN|ACK. 921 */ 922 cce->disable_time = 0; 923 cce->server_mss = 0; 924 cce->cookie_len = 0; 925 /* 926 * tp->t_tfo... cookie details are already 927 * zero from the tcpcb init. 928 */ 929 } else { 930 /* 931 * Path is disabled, so disable TFO on this 932 * connection. 933 */ 934 tp->t_flags &= ~TF_FASTOPEN; 935 } 936 CCB_UNLOCK(ccb); 937 tcp_mss(tp, -1); 938 /* 939 * snd_wnd is irrelevant since we are either forcing 940 * a TFO cookie request or disabling TFO - either 941 * way, no data with the SYN. 942 */ 943 } 944 } else { 945 /* 946 * A new entry for this path will be created when a SYN|ACK 947 * comes back, or the attempt otherwise fails. 948 */ 949 CCB_UNLOCK(ccb); 950 tcp_mss(tp, -1); 951 /* 952 * snd_wnd is irrelevant since we are forcing a TFO cookie 953 * request. 954 */ 955 } 956 } 957 958 void 959 tcp_fastopen_disable_path(struct tcpcb *tp) 960 { 961 struct in_conninfo *inc = &tp->t_inpcb->inp_inc; 962 struct tcp_fastopen_ccache_bucket *ccb; 963 struct tcp_fastopen_ccache_entry *cce; 964 965 cce = tcp_fastopen_ccache_lookup(inc, &ccb); 966 if (cce) { 967 cce->server_mss = 0; 968 cce->cookie_len = 0; 969 /* 970 * Preserve the existing disable time if it is already 971 * disabled. 972 */ 973 if (cce->disable_time == 0) 974 cce->disable_time = getsbinuptime(); 975 } else /* use invalid cookie len to create disabled entry */ 976 tcp_fastopen_ccache_create(ccb, inc, 0, 977 TCP_FASTOPEN_MAX_COOKIE_LEN + 1, NULL); 978 979 CCB_UNLOCK(ccb); 980 tp->t_flags &= ~TF_FASTOPEN; 981 } 982 983 void 984 tcp_fastopen_update_cache(struct tcpcb *tp, uint16_t mss, 985 uint8_t cookie_len, uint8_t *cookie) 986 { 987 struct in_conninfo *inc = &tp->t_inpcb->inp_inc; 988 struct tcp_fastopen_ccache_bucket *ccb; 989 struct tcp_fastopen_ccache_entry *cce; 990 991 cce = tcp_fastopen_ccache_lookup(inc, &ccb); 992 if (cce) { 993 if ((cookie_len >= TCP_FASTOPEN_MIN_COOKIE_LEN) && 994 (cookie_len <= TCP_FASTOPEN_MAX_COOKIE_LEN) && 995 ((cookie_len & 0x1) == 0)) { 996 cce->server_mss = mss; 997 cce->cookie_len = cookie_len; 998 memcpy(cce->cookie, cookie, cookie_len); 999 cce->disable_time = 0; 1000 } else { 1001 /* invalid cookie length, disable entry */ 1002 cce->server_mss = 0; 1003 cce->cookie_len = 0; 1004 /* 1005 * Preserve the existing disable time if it is 1006 * already disabled. 1007 */ 1008 if (cce->disable_time == 0) 1009 cce->disable_time = getsbinuptime(); 1010 } 1011 } else 1012 tcp_fastopen_ccache_create(ccb, inc, mss, cookie_len, cookie); 1013 1014 CCB_UNLOCK(ccb); 1015 } 1016 1017 static struct tcp_fastopen_ccache_entry * 1018 tcp_fastopen_ccache_lookup(struct in_conninfo *inc, 1019 struct tcp_fastopen_ccache_bucket **ccbp) 1020 { 1021 struct tcp_fastopen_ccache_bucket *ccb; 1022 struct tcp_fastopen_ccache_entry *cce; 1023 uint32_t last_word; 1024 uint32_t hash; 1025 1026 hash = jenkins_hash32((uint32_t *)&inc->inc_ie.ie_dependladdr, 4, 1027 V_tcp_fastopen_ccache.secret); 1028 hash = jenkins_hash32((uint32_t *)&inc->inc_ie.ie_dependfaddr, 4, 1029 hash); 1030 last_word = inc->inc_fport; 1031 hash = jenkins_hash32(&last_word, 1, hash); 1032 ccb = &V_tcp_fastopen_ccache.base[hash & V_tcp_fastopen_ccache.mask]; 1033 *ccbp = ccb; 1034 CCB_LOCK(ccb); 1035 1036 /* 1037 * Always returns with locked bucket. 1038 */ 1039 TAILQ_FOREACH(cce, &ccb->ccb_entries, cce_link) 1040 if ((!(cce->af == AF_INET6) == !(inc->inc_flags & INC_ISIPV6)) && 1041 (cce->server_port == inc->inc_ie.ie_fport) && 1042 (((cce->af == AF_INET) && 1043 (cce->cce_client_ip.v4.s_addr == inc->inc_laddr.s_addr) && 1044 (cce->cce_server_ip.v4.s_addr == inc->inc_faddr.s_addr)) || 1045 ((cce->af == AF_INET6) && 1046 IN6_ARE_ADDR_EQUAL(&cce->cce_client_ip.v6, &inc->inc6_laddr) && 1047 IN6_ARE_ADDR_EQUAL(&cce->cce_server_ip.v6, &inc->inc6_faddr)))) 1048 break; 1049 1050 return (cce); 1051 } 1052 1053 static struct tcp_fastopen_ccache_entry * 1054 tcp_fastopen_ccache_create(struct tcp_fastopen_ccache_bucket *ccb, 1055 struct in_conninfo *inc, uint16_t mss, uint8_t cookie_len, uint8_t *cookie) 1056 { 1057 struct tcp_fastopen_ccache_entry *cce; 1058 1059 /* 1060 * 1. Create a new entry, or 1061 * 2. Reclaim an existing entry, or 1062 * 3. Fail 1063 */ 1064 1065 CCB_LOCK_ASSERT(ccb); 1066 1067 cce = NULL; 1068 if (ccb->ccb_num_entries < V_tcp_fastopen_ccache.bucket_limit) 1069 cce = uma_zalloc(V_tcp_fastopen_ccache.zone, M_NOWAIT); 1070 1071 if (cce == NULL) { 1072 /* 1073 * At bucket limit, or out of memory - reclaim last 1074 * entry in bucket. 1075 */ 1076 cce = TAILQ_LAST(&ccb->ccb_entries, bucket_entries); 1077 if (cce == NULL) { 1078 /* XXX count this event */ 1079 return (NULL); 1080 } 1081 1082 TAILQ_REMOVE(&ccb->ccb_entries, cce, cce_link); 1083 } else 1084 ccb->ccb_num_entries++; 1085 1086 TAILQ_INSERT_HEAD(&ccb->ccb_entries, cce, cce_link); 1087 cce->af = (inc->inc_flags & INC_ISIPV6) ? AF_INET6 : AF_INET; 1088 if (cce->af == AF_INET) { 1089 cce->cce_client_ip.v4 = inc->inc_laddr; 1090 cce->cce_server_ip.v4 = inc->inc_faddr; 1091 } else { 1092 cce->cce_client_ip.v6 = inc->inc6_laddr; 1093 cce->cce_server_ip.v6 = inc->inc6_faddr; 1094 } 1095 cce->server_port = inc->inc_fport; 1096 if ((cookie_len >= TCP_FASTOPEN_MIN_COOKIE_LEN) && 1097 (cookie_len <= TCP_FASTOPEN_MAX_COOKIE_LEN) && 1098 ((cookie_len & 0x1) == 0)) { 1099 cce->server_mss = mss; 1100 cce->cookie_len = cookie_len; 1101 memcpy(cce->cookie, cookie, cookie_len); 1102 cce->disable_time = 0; 1103 } else { 1104 /* invalid cookie length, disable cce */ 1105 cce->server_mss = 0; 1106 cce->cookie_len = 0; 1107 cce->disable_time = getsbinuptime(); 1108 } 1109 1110 return (cce); 1111 } 1112 1113 static void 1114 tcp_fastopen_ccache_bucket_trim(struct tcp_fastopen_ccache_bucket *ccb, 1115 unsigned int limit) 1116 { 1117 struct tcp_fastopen_ccache_entry *cce, *cce_tmp; 1118 unsigned int entries; 1119 1120 CCB_LOCK(ccb); 1121 entries = 0; 1122 TAILQ_FOREACH_SAFE(cce, &ccb->ccb_entries, cce_link, cce_tmp) { 1123 entries++; 1124 if (entries > limit) 1125 tcp_fastopen_ccache_entry_drop(cce, ccb); 1126 } 1127 KASSERT(ccb->ccb_num_entries <= (int)limit, 1128 ("%s: ccb->ccb_num_entries %d exceeds limit %d", __func__, 1129 ccb->ccb_num_entries, limit)); 1130 if (limit == 0) { 1131 KASSERT(TAILQ_EMPTY(&ccb->ccb_entries), 1132 ("%s: ccb->ccb_entries not empty", __func__)); 1133 ccb->ccb_num_entries = -1; /* disable bucket */ 1134 } 1135 CCB_UNLOCK(ccb); 1136 } 1137 1138 static void 1139 tcp_fastopen_ccache_entry_drop(struct tcp_fastopen_ccache_entry *cce, 1140 struct tcp_fastopen_ccache_bucket *ccb) 1141 { 1142 1143 CCB_LOCK_ASSERT(ccb); 1144 1145 TAILQ_REMOVE(&ccb->ccb_entries, cce, cce_link); 1146 ccb->ccb_num_entries--; 1147 uma_zfree(V_tcp_fastopen_ccache.zone, cce); 1148 } 1149 1150 static int 1151 sysctl_net_inet_tcp_fastopen_ccache_list(SYSCTL_HANDLER_ARGS) 1152 { 1153 struct sbuf sb; 1154 struct tcp_fastopen_ccache_bucket *ccb; 1155 struct tcp_fastopen_ccache_entry *cce; 1156 sbintime_t now, duration, limit; 1157 const int linesize = 128; 1158 int i, error, num_entries; 1159 unsigned int j; 1160 #ifdef INET6 1161 char clt_buf[INET6_ADDRSTRLEN], srv_buf[INET6_ADDRSTRLEN]; 1162 #else 1163 char clt_buf[INET_ADDRSTRLEN], srv_buf[INET_ADDRSTRLEN]; 1164 #endif 1165 1166 if (jailed_without_vnet(curthread->td_ucred) != 0) 1167 return (EPERM); 1168 1169 /* Only allow root to read the client cookie cache */ 1170 if (curthread->td_ucred->cr_uid != 0) 1171 return (EPERM); 1172 1173 num_entries = 0; 1174 for (i = 0; i < V_tcp_fastopen_ccache.buckets; i++) { 1175 ccb = &V_tcp_fastopen_ccache.base[i]; 1176 CCB_LOCK(ccb); 1177 if (ccb->ccb_num_entries > 0) 1178 num_entries += ccb->ccb_num_entries; 1179 CCB_UNLOCK(ccb); 1180 } 1181 sbuf_new(&sb, NULL, linesize * (num_entries + 1), SBUF_INCLUDENUL); 1182 1183 sbuf_printf(&sb, 1184 "\nLocal IP address Remote IP address Port MSS" 1185 " Disabled Cookie\n"); 1186 1187 now = getsbinuptime(); 1188 limit = (sbintime_t)V_tcp_fastopen_path_disable_time << 32; 1189 for (i = 0; i < V_tcp_fastopen_ccache.buckets; i++) { 1190 ccb = &V_tcp_fastopen_ccache.base[i]; 1191 CCB_LOCK(ccb); 1192 TAILQ_FOREACH(cce, &ccb->ccb_entries, cce_link) { 1193 if (cce->disable_time != 0) { 1194 duration = now - cce->disable_time; 1195 if (limit >= duration) 1196 duration = limit - duration; 1197 else 1198 duration = 0; 1199 } else 1200 duration = 0; 1201 sbuf_printf(&sb, 1202 "%-20s %-20s %5u %5u ", 1203 inet_ntop(cce->af, &cce->cce_client_ip, 1204 clt_buf, sizeof(clt_buf)), 1205 inet_ntop(cce->af, &cce->cce_server_ip, 1206 srv_buf, sizeof(srv_buf)), 1207 ntohs(cce->server_port), 1208 cce->server_mss); 1209 if (duration > 0) 1210 sbuf_printf(&sb, "%7ds ", sbintime_getsec(duration)); 1211 else 1212 sbuf_printf(&sb, "%8s ", "No"); 1213 for (j = 0; j < cce->cookie_len; j++) 1214 sbuf_printf(&sb, "%02x", cce->cookie[j]); 1215 sbuf_putc(&sb, '\n'); 1216 } 1217 CCB_UNLOCK(ccb); 1218 } 1219 error = sbuf_finish(&sb); 1220 if (error == 0) 1221 error = SYSCTL_OUT(req, sbuf_data(&sb), sbuf_len(&sb)); 1222 sbuf_delete(&sb); 1223 return (error); 1224 } 1225 1226