1 /*- 2 * Copyright (c) 2015 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 a server-side implementation of TCP Fast Open (TFO) [RFC7413]. 29 * 30 * This implementation is currently considered to be experimental and is not 31 * included in kernel builds by default. To include this code, add the 32 * following line to your kernel config: 33 * 34 * options TCP_RFC7413 35 * 36 * The generated TFO cookies are the 64-bit output of 37 * SipHash24(<16-byte-key><client-ip>). Multiple concurrent valid keys are 38 * supported so that time-based rolling cookie invalidation policies can be 39 * implemented in the system. The default number of concurrent keys is 2. 40 * This can be adjusted in the kernel config as follows: 41 * 42 * options TCP_RFC7413_MAX_KEYS=<num-keys> 43 * 44 * 45 * The following TFO-specific sysctls are defined: 46 * 47 * net.inet.tcp.fastopen.acceptany (RW, default 0) 48 * When non-zero, all client-supplied TFO cookies will be considered to 49 * be valid. 50 * 51 * net.inet.tcp.fastopen.autokey (RW, default 120) 52 * When this and net.inet.tcp.fastopen.enabled are non-zero, a new key 53 * will be automatically generated after this many seconds. 54 * 55 * net.inet.tcp.fastopen.enabled (RW, default 0) 56 * When zero, no new TFO connections can be created. On the transition 57 * from enabled to disabled, all installed keys are removed. On the 58 * transition from disabled to enabled, if net.inet.tcp.fastopen.autokey 59 * is non-zero and there are no keys installed, a new key will be 60 * generated immediately. The transition from enabled to disabled does 61 * not affect any TFO connections in progress; it only prevents new ones 62 * from being made. 63 * 64 * net.inet.tcp.fastopen.keylen (RO) 65 * The key length in bytes. 66 * 67 * net.inet.tcp.fastopen.maxkeys (RO) 68 * The maximum number of keys supported. 69 * 70 * net.inet.tcp.fastopen.numkeys (RO) 71 * The current number of keys installed. 72 * 73 * net.inet.tcp.fastopen.setkey (WO) 74 * Install a new key by writing net.inet.tcp.fastopen.keylen bytes to this 75 * sysctl. 76 * 77 * 78 * In order for TFO connections to be created via a listen socket, that 79 * socket must have the TCP_FASTOPEN socket option set on it. This option 80 * can be set on the socket either before or after the listen() is invoked. 81 * Clearing this option on a listen socket after it has been set has no 82 * effect on existing TFO connections or TFO connections in progress; it 83 * only prevents new TFO connections from being made. 84 * 85 * For passively-created sockets, the TCP_FASTOPEN socket option can be 86 * queried to determine whether the connection was established using TFO. 87 * Note that connections that are established via a TFO SYN, but that fall 88 * back to using a non-TFO SYN|ACK will have the TCP_FASTOPEN socket option 89 * set. 90 * 91 * Per the RFC, this implementation limits the number of TFO connections 92 * that can be in the SYN_RECEIVED state on a per listen-socket basis. 93 * Whenever this limit is exceeded, requests for new TFO connections are 94 * serviced as non-TFO requests. Without such a limit, given a valid TFO 95 * cookie, an attacker could keep the listen queue in an overflow condition 96 * using a TFO SYN flood. This implementation sets the limit at half the 97 * configured listen backlog. 98 * 99 */ 100 101 #include <sys/cdefs.h> 102 __FBSDID("$FreeBSD$"); 103 104 #include "opt_inet.h" 105 106 #include <sys/param.h> 107 #include <sys/kernel.h> 108 #include <sys/limits.h> 109 #include <sys/lock.h> 110 #include <sys/rmlock.h> 111 #include <sys/socket.h> 112 #include <sys/socketvar.h> 113 #include <sys/sysctl.h> 114 #include <sys/systm.h> 115 116 #include <crypto/siphash/siphash.h> 117 118 #include <net/vnet.h> 119 120 #include <netinet/in.h> 121 #include <netinet/in_pcb.h> 122 #include <netinet/tcp_fastopen.h> 123 #include <netinet/tcp_var.h> 124 125 126 #define TCP_FASTOPEN_KEY_LEN SIPHASH_KEY_LENGTH 127 128 #if !defined(TCP_RFC7413_MAX_KEYS) || (TCP_RFC7413_MAX_KEYS < 1) 129 #define TCP_FASTOPEN_MAX_KEYS 2 130 #else 131 #define TCP_FASTOPEN_MAX_KEYS TCP_RFC7413_MAX_KEYS 132 #endif 133 134 struct tcp_fastopen_keylist { 135 unsigned int newest; 136 uint8_t key[TCP_FASTOPEN_MAX_KEYS][TCP_FASTOPEN_KEY_LEN]; 137 }; 138 139 struct tcp_fastopen_callout { 140 struct callout c; 141 struct vnet *v; 142 }; 143 144 SYSCTL_NODE(_net_inet_tcp, OID_AUTO, fastopen, CTLFLAG_RW, 0, "TCP Fast Open"); 145 146 static VNET_DEFINE(int, tcp_fastopen_acceptany) = 0; 147 #define V_tcp_fastopen_acceptany VNET(tcp_fastopen_acceptany) 148 SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, acceptany, 149 CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_fastopen_acceptany), 0, 150 "Accept any non-empty cookie"); 151 152 static VNET_DEFINE(unsigned int, tcp_fastopen_autokey) = 120; 153 #define V_tcp_fastopen_autokey VNET(tcp_fastopen_autokey) 154 static int sysctl_net_inet_tcp_fastopen_autokey(SYSCTL_HANDLER_ARGS); 155 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, autokey, 156 CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, NULL, 0, 157 &sysctl_net_inet_tcp_fastopen_autokey, "IU", 158 "Number of seconds between auto-generation of a new key; zero disables"); 159 160 VNET_DEFINE(unsigned int, tcp_fastopen_enabled) = 0; 161 static int sysctl_net_inet_tcp_fastopen_enabled(SYSCTL_HANDLER_ARGS); 162 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, enabled, 163 CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, NULL, 0, 164 &sysctl_net_inet_tcp_fastopen_enabled, "IU", 165 "Enable/disable TCP Fast Open processing"); 166 167 SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, keylen, 168 CTLFLAG_RD, SYSCTL_NULL_INT_PTR, TCP_FASTOPEN_KEY_LEN, 169 "Key length in bytes"); 170 171 SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, maxkeys, 172 CTLFLAG_RD, SYSCTL_NULL_INT_PTR, TCP_FASTOPEN_MAX_KEYS, 173 "Maximum number of keys supported"); 174 175 static VNET_DEFINE(unsigned int, tcp_fastopen_numkeys) = 0; 176 #define V_tcp_fastopen_numkeys VNET(tcp_fastopen_numkeys) 177 SYSCTL_UINT(_net_inet_tcp_fastopen, OID_AUTO, numkeys, 178 CTLFLAG_VNET | CTLFLAG_RD, &VNET_NAME(tcp_fastopen_numkeys), 0, 179 "Number of keys installed"); 180 181 static int sysctl_net_inet_tcp_fastopen_setkey(SYSCTL_HANDLER_ARGS); 182 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, setkey, 183 CTLFLAG_VNET | CTLTYPE_OPAQUE | CTLFLAG_WR, NULL, 0, 184 &sysctl_net_inet_tcp_fastopen_setkey, "", 185 "Install a new key"); 186 187 static VNET_DEFINE(struct rmlock, tcp_fastopen_keylock); 188 #define V_tcp_fastopen_keylock VNET(tcp_fastopen_keylock) 189 190 #define TCP_FASTOPEN_KEYS_RLOCK(t) rm_rlock(&V_tcp_fastopen_keylock, (t)) 191 #define TCP_FASTOPEN_KEYS_RUNLOCK(t) rm_runlock(&V_tcp_fastopen_keylock, (t)) 192 #define TCP_FASTOPEN_KEYS_WLOCK() rm_wlock(&V_tcp_fastopen_keylock) 193 #define TCP_FASTOPEN_KEYS_WUNLOCK() rm_wunlock(&V_tcp_fastopen_keylock) 194 195 static VNET_DEFINE(struct tcp_fastopen_keylist, tcp_fastopen_keys); 196 #define V_tcp_fastopen_keys VNET(tcp_fastopen_keys) 197 198 static VNET_DEFINE(struct tcp_fastopen_callout, tcp_fastopen_autokey_ctx); 199 #define V_tcp_fastopen_autokey_ctx VNET(tcp_fastopen_autokey_ctx) 200 201 static VNET_DEFINE(uma_zone_t, counter_zone); 202 #define V_counter_zone VNET(counter_zone) 203 204 void 205 tcp_fastopen_init(void) 206 { 207 V_counter_zone = uma_zcreate("tfo", sizeof(unsigned int), 208 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 209 rm_init(&V_tcp_fastopen_keylock, "tfo_keylock"); 210 callout_init_rm(&V_tcp_fastopen_autokey_ctx.c, 211 &V_tcp_fastopen_keylock, 0); 212 V_tcp_fastopen_autokey_ctx.v = curvnet; 213 V_tcp_fastopen_keys.newest = TCP_FASTOPEN_MAX_KEYS - 1; 214 } 215 216 void 217 tcp_fastopen_destroy(void) 218 { 219 callout_drain(&V_tcp_fastopen_autokey_ctx.c); 220 rm_destroy(&V_tcp_fastopen_keylock); 221 uma_zdestroy(V_counter_zone); 222 } 223 224 unsigned int * 225 tcp_fastopen_alloc_counter(void) 226 { 227 unsigned int *counter; 228 counter = uma_zalloc(V_counter_zone, M_NOWAIT); 229 if (counter) 230 *counter = 1; 231 return (counter); 232 } 233 234 void 235 tcp_fastopen_decrement_counter(unsigned int *counter) 236 { 237 if (*counter == 1) 238 uma_zfree(V_counter_zone, counter); 239 else 240 atomic_subtract_int(counter, 1); 241 } 242 243 static void 244 tcp_fastopen_addkey_locked(uint8_t *key) 245 { 246 247 V_tcp_fastopen_keys.newest++; 248 if (V_tcp_fastopen_keys.newest == TCP_FASTOPEN_MAX_KEYS) 249 V_tcp_fastopen_keys.newest = 0; 250 memcpy(V_tcp_fastopen_keys.key[V_tcp_fastopen_keys.newest], key, 251 TCP_FASTOPEN_KEY_LEN); 252 if (V_tcp_fastopen_numkeys < TCP_FASTOPEN_MAX_KEYS) 253 V_tcp_fastopen_numkeys++; 254 } 255 256 static void 257 tcp_fastopen_autokey_locked(void) 258 { 259 uint8_t newkey[TCP_FASTOPEN_KEY_LEN]; 260 261 arc4rand(newkey, TCP_FASTOPEN_KEY_LEN, 0); 262 tcp_fastopen_addkey_locked(newkey); 263 } 264 265 static void 266 tcp_fastopen_autokey_callout(void *arg) 267 { 268 struct tcp_fastopen_callout *ctx = arg; 269 270 CURVNET_SET(ctx->v); 271 tcp_fastopen_autokey_locked(); 272 callout_reset(&ctx->c, V_tcp_fastopen_autokey * hz, 273 tcp_fastopen_autokey_callout, ctx); 274 CURVNET_RESTORE(); 275 } 276 277 278 static uint64_t 279 tcp_fastopen_make_cookie(uint8_t key[SIPHASH_KEY_LENGTH], struct in_conninfo *inc) 280 { 281 SIPHASH_CTX ctx; 282 uint64_t siphash; 283 284 SipHash24_Init(&ctx); 285 SipHash_SetKey(&ctx, key); 286 switch (inc->inc_flags & INC_ISIPV6) { 287 #ifdef INET 288 case 0: 289 SipHash_Update(&ctx, &inc->inc_faddr, sizeof(inc->inc_faddr)); 290 break; 291 #endif 292 #ifdef INET6 293 case INC_ISIPV6: 294 SipHash_Update(&ctx, &inc->inc6_faddr, sizeof(inc->inc6_faddr)); 295 break; 296 #endif 297 } 298 SipHash_Final((u_int8_t *)&siphash, &ctx); 299 300 return (siphash); 301 } 302 303 304 /* 305 * Return values: 306 * -1 the cookie is invalid and no valid cookie is available 307 * 0 the cookie is invalid and the latest cookie has been returned 308 * 1 the cookie is valid and the latest cookie has been returned 309 */ 310 int 311 tcp_fastopen_check_cookie(struct in_conninfo *inc, uint8_t *cookie, 312 unsigned int len, uint64_t *latest_cookie) 313 { 314 struct rm_priotracker tracker; 315 unsigned int i, key_index; 316 uint64_t cur_cookie; 317 318 if (V_tcp_fastopen_acceptany) { 319 *latest_cookie = 0; 320 return (1); 321 } 322 323 if (len != TCP_FASTOPEN_COOKIE_LEN) { 324 if (V_tcp_fastopen_numkeys > 0) { 325 *latest_cookie = 326 tcp_fastopen_make_cookie( 327 V_tcp_fastopen_keys.key[V_tcp_fastopen_keys.newest], 328 inc); 329 return (0); 330 } 331 return (-1); 332 } 333 334 /* 335 * Check against each available key, from newest to oldest. 336 */ 337 TCP_FASTOPEN_KEYS_RLOCK(&tracker); 338 key_index = V_tcp_fastopen_keys.newest; 339 for (i = 0; i < V_tcp_fastopen_numkeys; i++) { 340 cur_cookie = 341 tcp_fastopen_make_cookie(V_tcp_fastopen_keys.key[key_index], 342 inc); 343 if (i == 0) 344 *latest_cookie = cur_cookie; 345 if (memcmp(cookie, &cur_cookie, TCP_FASTOPEN_COOKIE_LEN) == 0) { 346 TCP_FASTOPEN_KEYS_RUNLOCK(&tracker); 347 return (1); 348 } 349 if (key_index == 0) 350 key_index = TCP_FASTOPEN_MAX_KEYS - 1; 351 else 352 key_index--; 353 } 354 TCP_FASTOPEN_KEYS_RUNLOCK(&tracker); 355 356 return (0); 357 } 358 359 static int 360 sysctl_net_inet_tcp_fastopen_autokey(SYSCTL_HANDLER_ARGS) 361 { 362 int error; 363 unsigned int new; 364 365 new = V_tcp_fastopen_autokey; 366 error = sysctl_handle_int(oidp, &new, 0, req); 367 if (error == 0 && req->newptr) { 368 if (new > (INT_MAX / hz)) 369 return (EINVAL); 370 371 TCP_FASTOPEN_KEYS_WLOCK(); 372 if (V_tcp_fastopen_enabled) { 373 if (V_tcp_fastopen_autokey && !new) 374 callout_stop(&V_tcp_fastopen_autokey_ctx.c); 375 else if (new) 376 callout_reset(&V_tcp_fastopen_autokey_ctx.c, 377 new * hz, tcp_fastopen_autokey_callout, 378 &V_tcp_fastopen_autokey_ctx); 379 } 380 V_tcp_fastopen_autokey = new; 381 TCP_FASTOPEN_KEYS_WUNLOCK(); 382 } 383 384 return (error); 385 } 386 387 static int 388 sysctl_net_inet_tcp_fastopen_enabled(SYSCTL_HANDLER_ARGS) 389 { 390 int error; 391 unsigned int new; 392 393 new = V_tcp_fastopen_enabled; 394 error = sysctl_handle_int(oidp, &new, 0, req); 395 if (error == 0 && req->newptr) { 396 if (V_tcp_fastopen_enabled && !new) { 397 /* enabled -> disabled */ 398 TCP_FASTOPEN_KEYS_WLOCK(); 399 V_tcp_fastopen_numkeys = 0; 400 V_tcp_fastopen_keys.newest = TCP_FASTOPEN_MAX_KEYS - 1; 401 if (V_tcp_fastopen_autokey) 402 callout_stop(&V_tcp_fastopen_autokey_ctx.c); 403 V_tcp_fastopen_enabled = 0; 404 TCP_FASTOPEN_KEYS_WUNLOCK(); 405 } else if (!V_tcp_fastopen_enabled && new) { 406 /* disabled -> enabled */ 407 TCP_FASTOPEN_KEYS_WLOCK(); 408 if (V_tcp_fastopen_autokey && 409 (V_tcp_fastopen_numkeys == 0)) { 410 tcp_fastopen_autokey_locked(); 411 callout_reset(&V_tcp_fastopen_autokey_ctx.c, 412 V_tcp_fastopen_autokey * hz, 413 tcp_fastopen_autokey_callout, 414 &V_tcp_fastopen_autokey_ctx); 415 } 416 V_tcp_fastopen_enabled = 1; 417 TCP_FASTOPEN_KEYS_WUNLOCK(); 418 } 419 } 420 return (error); 421 } 422 423 static int 424 sysctl_net_inet_tcp_fastopen_setkey(SYSCTL_HANDLER_ARGS) 425 { 426 int error; 427 uint8_t newkey[TCP_FASTOPEN_KEY_LEN]; 428 429 if (req->oldptr != NULL || req->oldlen != 0) 430 return (EINVAL); 431 if (req->newptr == NULL) 432 return (EPERM); 433 if (req->newlen != sizeof(newkey)) 434 return (EINVAL); 435 error = SYSCTL_IN(req, newkey, sizeof(newkey)); 436 if (error) 437 return (error); 438 439 TCP_FASTOPEN_KEYS_WLOCK(); 440 tcp_fastopen_addkey_locked(newkey); 441 TCP_FASTOPEN_KEYS_WUNLOCK(); 442 443 return (0); 444 } 445