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 #if 0
167 #include <sys/cdefs.h>
168 __FBSDID("$FreeBSD$");
169
170 #include "opt_inet.h"
171
172 #include <sys/param.h>
173 #include <sys/jail.h>
174 #include <sys/kernel.h>
175 #include <sys/hash.h>
176 #include <sys/limits.h>
177 #include <sys/lock.h>
178 #include <sys/proc.h>
179 #include <sys/rmlock.h>
180 #include <sys/sbuf.h>
181 #include <sys/socket.h>
182 #include <sys/socketvar.h>
183 #include <sys/sysctl.h>
184 #include <sys/systm.h>
185
186 #include <crypto/siphash/siphash.h>
187
188 #include <net/vnet.h>
189 #endif
190
191 #include "../tcplp.h"
192 #include "ip.h"
193 #include "tcp_const.h"
194 #include "tcp_var.h"
195 #include "tcp_fastopen.h"
196
197 #if 0
198
199 #define TCP_FASTOPEN_KEY_LEN SIPHASH_KEY_LENGTH
200
201 #if TCP_FASTOPEN_PSK_LEN != TCP_FASTOPEN_KEY_LEN
202 #error TCP_FASTOPEN_PSK_LEN must be equal to TCP_FASTOPEN_KEY_LEN
203 #endif
204
205 /*
206 * Because a PSK-mode setsockopt() uses tcpcb.t_tfo_cookie.client to hold
207 * the PSK until the connect occurs.
208 */
209 #if TCP_FASTOPEN_MAX_COOKIE_LEN < TCP_FASTOPEN_PSK_LEN
210 #error TCP_FASTOPEN_MAX_COOKIE_LEN must be >= TCP_FASTOPEN_PSK_LEN
211 #endif
212
213 #define TCP_FASTOPEN_CCACHE_BUCKET_LIMIT_DEFAULT 16
214 #define TCP_FASTOPEN_CCACHE_BUCKETS_DEFAULT 2048 /* must be power of 2 */
215
216 #define TCP_FASTOPEN_PATH_DISABLE_TIME_DEFAULT 900 /* seconds */
217
218 #if !defined(TCP_RFC7413_MAX_KEYS) || (TCP_RFC7413_MAX_KEYS < 1)
219 #define TCP_FASTOPEN_MAX_KEYS 2
220 #else
221 #define TCP_FASTOPEN_MAX_KEYS TCP_RFC7413_MAX_KEYS
222 #endif
223
224 #if TCP_FASTOPEN_MAX_KEYS > 10
225 #undef TCP_FASTOPEN_MAX_KEYS
226 #define TCP_FASTOPEN_MAX_KEYS 10
227 #endif
228
229 #if !defined(TCP_RFC7413_MAX_PSKS) || (TCP_RFC7413_MAX_PSKS < 1)
230 #define TCP_FASTOPEN_MAX_PSKS 2
231 #else
232 #define TCP_FASTOPEN_MAX_PSKS TCP_RFC7413_MAX_PSKS
233 #endif
234
235 #if TCP_FASTOPEN_MAX_PSKS > 10
236 #undef TCP_FASTOPEN_MAX_PSKS
237 #define TCP_FASTOPEN_MAX_PSKS 10
238 #endif
239
240 struct tcp_fastopen_keylist {
241 unsigned int newest;
242 unsigned int newest_psk;
243 uint8_t key[TCP_FASTOPEN_MAX_KEYS][TCP_FASTOPEN_KEY_LEN];
244 uint8_t psk[TCP_FASTOPEN_MAX_PSKS][TCP_FASTOPEN_KEY_LEN];
245 };
246
247 struct tcp_fastopen_callout {
248 struct callout c;
249 struct vnet *v;
250 };
251
252 static struct tcp_fastopen_ccache_entry *tcp_fastopen_ccache_lookup(
253 struct in_conninfo *, struct tcp_fastopen_ccache_bucket **);
254 static struct tcp_fastopen_ccache_entry *tcp_fastopen_ccache_create(
255 struct tcp_fastopen_ccache_bucket *, struct in_conninfo *, uint16_t, uint8_t,
256 uint8_t *);
257 static void tcp_fastopen_ccache_bucket_trim(struct tcp_fastopen_ccache_bucket *,
258 unsigned int);
259 static void tcp_fastopen_ccache_entry_drop(struct tcp_fastopen_ccache_entry *,
260 struct tcp_fastopen_ccache_bucket *);
261
262 SYSCTL_NODE(_net_inet_tcp, OID_AUTO, fastopen, CTLFLAG_RW, 0, "TCP Fast Open");
263
264 VNET_DEFINE_STATIC(int, tcp_fastopen_acceptany) = 0;
265 #define V_tcp_fastopen_acceptany VNET(tcp_fastopen_acceptany)
266 SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, acceptany,
267 CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_fastopen_acceptany), 0,
268 "Accept any non-empty cookie");
269
270 VNET_DEFINE_STATIC(unsigned int, tcp_fastopen_autokey) = 120;
271 #define V_tcp_fastopen_autokey VNET(tcp_fastopen_autokey)
272 static int sysctl_net_inet_tcp_fastopen_autokey(SYSCTL_HANDLER_ARGS);
273 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, autokey,
274 CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, NULL, 0,
275 &sysctl_net_inet_tcp_fastopen_autokey, "IU",
276 "Number of seconds between auto-generation of a new key; zero disables");
277
278 static int sysctl_net_inet_tcp_fastopen_ccache_bucket_limit(SYSCTL_HANDLER_ARGS);
279 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, ccache_bucket_limit,
280 CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RWTUN, NULL, 0,
281 &sysctl_net_inet_tcp_fastopen_ccache_bucket_limit, "IU",
282 "Max entries per bucket in client cookie cache");
283
284 VNET_DEFINE_STATIC(unsigned int, tcp_fastopen_ccache_buckets) =
285 TCP_FASTOPEN_CCACHE_BUCKETS_DEFAULT;
286 #define V_tcp_fastopen_ccache_buckets VNET(tcp_fastopen_ccache_buckets)
287 SYSCTL_UINT(_net_inet_tcp_fastopen, OID_AUTO, ccache_buckets,
288 CTLFLAG_VNET | CTLFLAG_RDTUN, &VNET_NAME(tcp_fastopen_ccache_buckets), 0,
289 "Client cookie cache number of buckets (power of 2)");
290
291 VNET_DEFINE(unsigned int, tcp_fastopen_client_enable) = 1;
292 static int sysctl_net_inet_tcp_fastopen_client_enable(SYSCTL_HANDLER_ARGS);
293 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, client_enable,
294 CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, NULL, 0,
295 &sysctl_net_inet_tcp_fastopen_client_enable, "IU",
296 "Enable/disable TCP Fast Open client functionality");
297
298 SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, keylen,
299 CTLFLAG_RD, SYSCTL_NULL_INT_PTR, TCP_FASTOPEN_KEY_LEN,
300 "Key length in bytes");
301
302 SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, maxkeys,
303 CTLFLAG_RD, SYSCTL_NULL_INT_PTR, TCP_FASTOPEN_MAX_KEYS,
304 "Maximum number of keys supported");
305
306 SYSCTL_INT(_net_inet_tcp_fastopen, OID_AUTO, maxpsks,
307 CTLFLAG_RD, SYSCTL_NULL_INT_PTR, TCP_FASTOPEN_MAX_PSKS,
308 "Maximum number of pre-shared keys supported");
309
310 VNET_DEFINE_STATIC(unsigned int, tcp_fastopen_numkeys) = 0;
311 #define V_tcp_fastopen_numkeys VNET(tcp_fastopen_numkeys)
312 SYSCTL_UINT(_net_inet_tcp_fastopen, OID_AUTO, numkeys,
313 CTLFLAG_VNET | CTLFLAG_RD, &VNET_NAME(tcp_fastopen_numkeys), 0,
314 "Number of keys installed");
315
316 VNET_DEFINE_STATIC(unsigned int, tcp_fastopen_numpsks) = 0;
317 #define V_tcp_fastopen_numpsks VNET(tcp_fastopen_numpsks)
318 SYSCTL_UINT(_net_inet_tcp_fastopen, OID_AUTO, numpsks,
319 CTLFLAG_VNET | CTLFLAG_RD, &VNET_NAME(tcp_fastopen_numpsks), 0,
320 "Number of pre-shared keys installed");
321
322 VNET_DEFINE_STATIC(unsigned int, tcp_fastopen_path_disable_time) =
323 TCP_FASTOPEN_PATH_DISABLE_TIME_DEFAULT;
324 #define V_tcp_fastopen_path_disable_time VNET(tcp_fastopen_path_disable_time)
325 SYSCTL_UINT(_net_inet_tcp_fastopen, OID_AUTO, path_disable_time,
326 CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_fastopen_path_disable_time), 0,
327 "Seconds a TFO failure disables a {client_ip, server_ip, server_port} path");
328
329 VNET_DEFINE_STATIC(unsigned int, tcp_fastopen_psk_enable) = 0;
330 #define V_tcp_fastopen_psk_enable VNET(tcp_fastopen_psk_enable)
331 static int sysctl_net_inet_tcp_fastopen_psk_enable(SYSCTL_HANDLER_ARGS);
332 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, psk_enable,
333 CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, NULL, 0,
334 &sysctl_net_inet_tcp_fastopen_psk_enable, "IU",
335 "Enable/disable TCP Fast Open server pre-shared key mode");
336
337 VNET_DEFINE(unsigned int, tcp_fastopen_server_enable) = 0;
338 static int sysctl_net_inet_tcp_fastopen_server_enable(SYSCTL_HANDLER_ARGS);
339 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, server_enable,
340 CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW, NULL, 0,
341 &sysctl_net_inet_tcp_fastopen_server_enable, "IU",
342 "Enable/disable TCP Fast Open server functionality");
343
344 static int sysctl_net_inet_tcp_fastopen_setkey(SYSCTL_HANDLER_ARGS);
345 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, setkey,
346 CTLFLAG_VNET | CTLTYPE_OPAQUE | CTLFLAG_WR, NULL, 0,
347 &sysctl_net_inet_tcp_fastopen_setkey, "",
348 "Install a new key");
349
350 static int sysctl_net_inet_tcp_fastopen_setpsk(SYSCTL_HANDLER_ARGS);
351 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, setpsk,
352 CTLFLAG_VNET | CTLTYPE_OPAQUE | CTLFLAG_WR, NULL, 0,
353 &sysctl_net_inet_tcp_fastopen_setpsk, "",
354 "Install a new pre-shared key");
355
356 static int sysctl_net_inet_tcp_fastopen_ccache_list(SYSCTL_HANDLER_ARGS);
357 SYSCTL_PROC(_net_inet_tcp_fastopen, OID_AUTO, ccache_list,
358 CTLFLAG_VNET | CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_SKIP, NULL, 0,
359 sysctl_net_inet_tcp_fastopen_ccache_list, "A",
360 "List of all client cookie cache entries");
361
362 VNET_DEFINE_STATIC(struct rmlock, tcp_fastopen_keylock);
363 #define V_tcp_fastopen_keylock VNET(tcp_fastopen_keylock)
364
365 #define TCP_FASTOPEN_KEYS_RLOCK(t) rm_rlock(&V_tcp_fastopen_keylock, (t))
366 #define TCP_FASTOPEN_KEYS_RUNLOCK(t) rm_runlock(&V_tcp_fastopen_keylock, (t))
367 #define TCP_FASTOPEN_KEYS_WLOCK() rm_wlock(&V_tcp_fastopen_keylock)
368 #define TCP_FASTOPEN_KEYS_WUNLOCK() rm_wunlock(&V_tcp_fastopen_keylock)
369
370 VNET_DEFINE_STATIC(struct tcp_fastopen_keylist, tcp_fastopen_keys);
371 #define V_tcp_fastopen_keys VNET(tcp_fastopen_keys)
372
373 VNET_DEFINE_STATIC(struct tcp_fastopen_callout, tcp_fastopen_autokey_ctx);
374 #define V_tcp_fastopen_autokey_ctx VNET(tcp_fastopen_autokey_ctx)
375
376 VNET_DEFINE_STATIC(uma_zone_t, counter_zone);
377 #define V_counter_zone VNET(counter_zone)
378
379 static MALLOC_DEFINE(M_TCP_FASTOPEN_CCACHE, "tfo_ccache", "TFO client cookie cache buckets");
380
381 VNET_DEFINE_STATIC(struct tcp_fastopen_ccache, tcp_fastopen_ccache);
382 #define V_tcp_fastopen_ccache VNET(tcp_fastopen_ccache)
383
384 #define CCB_LOCK(ccb) mtx_lock(&(ccb)->ccb_mtx)
385 #define CCB_UNLOCK(ccb) mtx_unlock(&(ccb)->ccb_mtx)
386 #define CCB_LOCK_ASSERT(ccb) mtx_assert(&(ccb)->ccb_mtx, MA_OWNED)
387
388 #endif
389
390 void
tcp_fastopen_init(void)391 tcp_fastopen_init(void)
392 {
393 #if 0
394 unsigned int i;
395
396 V_counter_zone = uma_zcreate("tfo", sizeof(unsigned int),
397 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
398 rm_init(&V_tcp_fastopen_keylock, "tfo_keylock");
399 callout_init_rm(&V_tcp_fastopen_autokey_ctx.c,
400 &V_tcp_fastopen_keylock, 0);
401 V_tcp_fastopen_autokey_ctx.v = curvnet;
402 V_tcp_fastopen_keys.newest = TCP_FASTOPEN_MAX_KEYS - 1;
403 V_tcp_fastopen_keys.newest_psk = TCP_FASTOPEN_MAX_PSKS - 1;
404
405 /* May already be non-zero if kernel tunable was set */
406 if (V_tcp_fastopen_ccache.bucket_limit == 0)
407 V_tcp_fastopen_ccache.bucket_limit =
408 TCP_FASTOPEN_CCACHE_BUCKET_LIMIT_DEFAULT;
409
410 /* May already be non-zero if kernel tunable was set */
411 if ((V_tcp_fastopen_ccache_buckets == 0) ||
412 !powerof2(V_tcp_fastopen_ccache_buckets))
413 V_tcp_fastopen_ccache.buckets =
414 TCP_FASTOPEN_CCACHE_BUCKETS_DEFAULT;
415 else
416 V_tcp_fastopen_ccache.buckets = V_tcp_fastopen_ccache_buckets;
417
418 V_tcp_fastopen_ccache.mask = V_tcp_fastopen_ccache.buckets - 1;
419 V_tcp_fastopen_ccache.secret = arc4random();
420
421 V_tcp_fastopen_ccache.base = malloc(V_tcp_fastopen_ccache.buckets *
422 sizeof(struct tcp_fastopen_ccache_bucket), M_TCP_FASTOPEN_CCACHE,
423 M_WAITOK | M_ZERO);
424
425 for (i = 0; i < V_tcp_fastopen_ccache.buckets; i++) {
426 TAILQ_INIT(&V_tcp_fastopen_ccache.base[i].ccb_entries);
427 mtx_init(&V_tcp_fastopen_ccache.base[i].ccb_mtx, "tfo_ccache_bucket",
428 NULL, MTX_DEF);
429 if (V_tcp_fastopen_client_enable) {
430 /* enable bucket */
431 V_tcp_fastopen_ccache.base[i].ccb_num_entries = 0;
432 } else {
433 /* disable bucket */
434 V_tcp_fastopen_ccache.base[i].ccb_num_entries = -1;
435 }
436 V_tcp_fastopen_ccache.base[i].ccb_ccache = &V_tcp_fastopen_ccache;
437 }
438
439 /*
440 * Note that while the total number of entries in the cookie cache
441 * is limited by the table management logic to
442 * V_tcp_fastopen_ccache.buckets *
443 * V_tcp_fastopen_ccache.bucket_limit, the total number of items in
444 * this zone can exceed that amount by the number of CPUs in the
445 * system times the maximum number of unallocated items that can be
446 * present in each UMA per-CPU cache for this zone.
447 */
448 V_tcp_fastopen_ccache.zone = uma_zcreate("tfo_ccache_entries",
449 sizeof(struct tcp_fastopen_ccache_entry), NULL, NULL, NULL, NULL,
450 UMA_ALIGN_CACHE, 0);
451 #endif
452 }
453
454 void
tcp_fastopen_destroy(void)455 tcp_fastopen_destroy(void)
456 {
457 #if 0
458 struct tcp_fastopen_ccache_bucket *ccb;
459 unsigned int i;
460
461 for (i = 0; i < V_tcp_fastopen_ccache.buckets; i++) {
462 ccb = &V_tcp_fastopen_ccache.base[i];
463 tcp_fastopen_ccache_bucket_trim(ccb, 0);
464 mtx_destroy(&ccb->ccb_mtx);
465 }
466
467 KASSERT(uma_zone_get_cur(V_tcp_fastopen_ccache.zone) == 0,
468 ("%s: TFO ccache zone allocation count not 0", __func__));
469 uma_zdestroy(V_tcp_fastopen_ccache.zone);
470 free(V_tcp_fastopen_ccache.base, M_TCP_FASTOPEN_CCACHE);
471
472 callout_drain(&V_tcp_fastopen_autokey_ctx.c);
473 rm_destroy(&V_tcp_fastopen_keylock);
474 uma_zdestroy(V_counter_zone);
475 #endif
476 }
477
478 /*
479 * samkumar: The original FreeBSD code has a counter for each listen
480 * socket keeping track of how many TFO connections on that socket
481 * are "pending" (i.e., in the SYN-RCVD state). This counter is
482 * heap-allocated because the connections may decrement it upon
483 * leaving that state after the listen socket has been deallocated.
484 *
485 * In TCPlp, we skip this counter. Technically, RFC 7413 mandates
486 * only a global counter (not yet implemented in TCPlp). So I've
487 * replaced these with stubs.
488 */
489
490 unsigned int *
tcp_fastopen_alloc_counter(void)491 tcp_fastopen_alloc_counter(void)
492 {
493 #if 0
494 unsigned int *counter;
495 counter = uma_zalloc(V_counter_zone, M_NOWAIT);
496 if (counter)
497 *counter = 1;
498 return (counter);
499 #endif
500 return NULL;
501 }
502
503 void
tcp_fastopen_decrement_counter(unsigned int * counter)504 tcp_fastopen_decrement_counter(unsigned int *counter)
505 {
506 #if 0
507 if (*counter == 1)
508 uma_zfree(V_counter_zone, counter);
509 else
510 atomic_subtract_int(counter, 1);
511 #endif
512 }
513
514 #if 0
515
516 static void
517 tcp_fastopen_addkey_locked(uint8_t *key)
518 {
519
520 V_tcp_fastopen_keys.newest++;
521 if (V_tcp_fastopen_keys.newest == TCP_FASTOPEN_MAX_KEYS)
522 V_tcp_fastopen_keys.newest = 0;
523 memcpy(V_tcp_fastopen_keys.key[V_tcp_fastopen_keys.newest], key,
524 TCP_FASTOPEN_KEY_LEN);
525 if (V_tcp_fastopen_numkeys < TCP_FASTOPEN_MAX_KEYS)
526 V_tcp_fastopen_numkeys++;
527 }
528
529 static void
530 tcp_fastopen_addpsk_locked(uint8_t *psk)
531 {
532
533 V_tcp_fastopen_keys.newest_psk++;
534 if (V_tcp_fastopen_keys.newest_psk == TCP_FASTOPEN_MAX_PSKS)
535 V_tcp_fastopen_keys.newest_psk = 0;
536 memcpy(V_tcp_fastopen_keys.psk[V_tcp_fastopen_keys.newest_psk], psk,
537 TCP_FASTOPEN_KEY_LEN);
538 if (V_tcp_fastopen_numpsks < TCP_FASTOPEN_MAX_PSKS)
539 V_tcp_fastopen_numpsks++;
540 }
541
542 static void
543 tcp_fastopen_autokey_locked(void)
544 {
545 uint8_t newkey[TCP_FASTOPEN_KEY_LEN];
546
547 arc4rand(newkey, TCP_FASTOPEN_KEY_LEN, 0);
548 tcp_fastopen_addkey_locked(newkey);
549 }
550
551 static void
552 tcp_fastopen_autokey_callout(void *arg)
553 {
554 struct tcp_fastopen_callout *ctx = arg;
555
556 CURVNET_SET(ctx->v);
557 tcp_fastopen_autokey_locked();
558 callout_reset(&ctx->c, V_tcp_fastopen_autokey * hz,
559 tcp_fastopen_autokey_callout, ctx);
560 CURVNET_RESTORE();
561 }
562
563
564 static uint64_t
565 tcp_fastopen_make_cookie(uint8_t key[SIPHASH_KEY_LENGTH], struct in_conninfo *inc)
566 {
567 SIPHASH_CTX ctx;
568 uint64_t siphash;
569
570 SipHash24_Init(&ctx);
571 SipHash_SetKey(&ctx, key);
572 switch (inc->inc_flags & INC_ISIPV6) {
573 #ifdef INET
574 case 0:
575 SipHash_Update(&ctx, &inc->inc_faddr, sizeof(inc->inc_faddr));
576 break;
577 #endif
578 #ifdef INET6
579 case INC_ISIPV6:
580 SipHash_Update(&ctx, &inc->inc6_faddr, sizeof(inc->inc6_faddr));
581 break;
582 #endif
583 }
584 SipHash_Final((u_int8_t *)&siphash, &ctx);
585
586 return (siphash);
587 }
588
589 static uint64_t
590 tcp_fastopen_make_psk_cookie(uint8_t *psk, uint8_t *cookie, uint8_t cookie_len)
591 {
592 SIPHASH_CTX ctx;
593 uint64_t psk_cookie;
594
595 SipHash24_Init(&ctx);
596 SipHash_SetKey(&ctx, psk);
597 SipHash_Update(&ctx, cookie, cookie_len);
598 SipHash_Final((u_int8_t *)&psk_cookie, &ctx);
599
600 return (psk_cookie);
601 }
602
603 static int
604 tcp_fastopen_find_cookie_match_locked(uint8_t *wire_cookie, uint64_t *cur_cookie)
605 {
606 unsigned int i, psk_index;
607 uint64_t psk_cookie;
608
609 if (V_tcp_fastopen_psk_enable) {
610 psk_index = V_tcp_fastopen_keys.newest_psk;
611 for (i = 0; i < V_tcp_fastopen_numpsks; i++) {
612 psk_cookie =
613 tcp_fastopen_make_psk_cookie(
614 V_tcp_fastopen_keys.psk[psk_index],
615 (uint8_t *)cur_cookie,
616 TCP_FASTOPEN_COOKIE_LEN);
617
618 if (memcmp(wire_cookie, &psk_cookie,
619 TCP_FASTOPEN_COOKIE_LEN) == 0)
620 return (1);
621
622 if (psk_index == 0)
623 psk_index = TCP_FASTOPEN_MAX_PSKS - 1;
624 else
625 psk_index--;
626 }
627 } else if (memcmp(wire_cookie, cur_cookie, TCP_FASTOPEN_COOKIE_LEN) == 0)
628 return (1);
629
630 return (0);
631 }
632
633 #endif
634
635 /*
636 * Return values:
637 * -1 the cookie is invalid and no valid cookie is available
638 * 0 the cookie is invalid and the latest cookie has been returned
639 * 1 the cookie is valid and the latest cookie has been returned
640 */
641 /*
642 * samkumar: In the signature, changed "struct in_conninfo *inc" to
643 * "struct tcpcb* tp".
644 */
645 int
tcp_fastopen_check_cookie(struct tcpcb * tp,uint8_t * cookie,unsigned int len,uint64_t * latest_cookie)646 tcp_fastopen_check_cookie(struct tcpcb* tp, uint8_t *cookie,
647 unsigned int len, uint64_t *latest_cookie)
648 {
649 #if 0
650 struct rm_priotracker tracker;
651 unsigned int i, key_index;
652 int rv;
653 uint64_t cur_cookie;
654 #endif
655
656 if (V_tcp_fastopen_acceptany) {
657 *latest_cookie = 0;
658 return (1);
659 }
660
661 /*
662 * samkumar: For TCPlp, assume that we always accept any cookie.
663 *
664 * The original code is commented out below this return statement.
665 */
666
667 return -1;
668
669 #if 0
670
671 TCP_FASTOPEN_KEYS_RLOCK(&tracker);
672 if (len != TCP_FASTOPEN_COOKIE_LEN) {
673 if (V_tcp_fastopen_numkeys > 0) {
674 *latest_cookie =
675 tcp_fastopen_make_cookie(
676 V_tcp_fastopen_keys.key[V_tcp_fastopen_keys.newest],
677 inc);
678 rv = 0;
679 } else
680 rv = -1;
681 goto out;
682 }
683
684 /*
685 * Check against each available key, from newest to oldest.
686 */
687 key_index = V_tcp_fastopen_keys.newest;
688 for (i = 0; i < V_tcp_fastopen_numkeys; i++) {
689 cur_cookie =
690 tcp_fastopen_make_cookie(V_tcp_fastopen_keys.key[key_index],
691 inc);
692 if (i == 0)
693 *latest_cookie = cur_cookie;
694 rv = tcp_fastopen_find_cookie_match_locked(cookie, &cur_cookie);
695 if (rv)
696 goto out;
697 if (key_index == 0)
698 key_index = TCP_FASTOPEN_MAX_KEYS - 1;
699 else
700 key_index--;
701 }
702 rv = 0;
703
704 out:
705 TCP_FASTOPEN_KEYS_RUNLOCK(&tracker);
706 return (rv);
707 #endif
708 }
709
710 #if 0
711 static int
712 sysctl_net_inet_tcp_fastopen_autokey(SYSCTL_HANDLER_ARGS)
713 {
714 int error;
715 unsigned int new;
716
717 new = V_tcp_fastopen_autokey;
718 error = sysctl_handle_int(oidp, &new, 0, req);
719 if (error == 0 && req->newptr) {
720 if (new > (INT_MAX / hz))
721 return (EINVAL);
722
723 TCP_FASTOPEN_KEYS_WLOCK();
724 if (V_tcp_fastopen_server_enable) {
725 if (V_tcp_fastopen_autokey && !new)
726 callout_stop(&V_tcp_fastopen_autokey_ctx.c);
727 else if (new)
728 callout_reset(&V_tcp_fastopen_autokey_ctx.c,
729 new * hz, tcp_fastopen_autokey_callout,
730 &V_tcp_fastopen_autokey_ctx);
731 }
732 V_tcp_fastopen_autokey = new;
733 TCP_FASTOPEN_KEYS_WUNLOCK();
734 }
735
736 return (error);
737 }
738
739 static int
740 sysctl_net_inet_tcp_fastopen_psk_enable(SYSCTL_HANDLER_ARGS)
741 {
742 int error;
743 unsigned int new;
744
745 new = V_tcp_fastopen_psk_enable;
746 error = sysctl_handle_int(oidp, &new, 0, req);
747 if (error == 0 && req->newptr) {
748 if (V_tcp_fastopen_psk_enable && !new) {
749 /* enabled -> disabled */
750 TCP_FASTOPEN_KEYS_WLOCK();
751 V_tcp_fastopen_numpsks = 0;
752 V_tcp_fastopen_keys.newest_psk =
753 TCP_FASTOPEN_MAX_PSKS - 1;
754 V_tcp_fastopen_psk_enable = 0;
755 TCP_FASTOPEN_KEYS_WUNLOCK();
756 } else if (!V_tcp_fastopen_psk_enable && new) {
757 /* disabled -> enabled */
758 TCP_FASTOPEN_KEYS_WLOCK();
759 V_tcp_fastopen_psk_enable = 1;
760 TCP_FASTOPEN_KEYS_WUNLOCK();
761 }
762 }
763 return (error);
764 }
765
766 static int
767 sysctl_net_inet_tcp_fastopen_server_enable(SYSCTL_HANDLER_ARGS)
768 {
769 int error;
770 unsigned int new;
771
772 new = V_tcp_fastopen_server_enable;
773 error = sysctl_handle_int(oidp, &new, 0, req);
774 if (error == 0 && req->newptr) {
775 if (V_tcp_fastopen_server_enable && !new) {
776 /* enabled -> disabled */
777 TCP_FASTOPEN_KEYS_WLOCK();
778 V_tcp_fastopen_numkeys = 0;
779 V_tcp_fastopen_keys.newest = TCP_FASTOPEN_MAX_KEYS - 1;
780 if (V_tcp_fastopen_autokey)
781 callout_stop(&V_tcp_fastopen_autokey_ctx.c);
782 V_tcp_fastopen_numpsks = 0;
783 V_tcp_fastopen_keys.newest_psk =
784 TCP_FASTOPEN_MAX_PSKS - 1;
785 V_tcp_fastopen_server_enable = 0;
786 TCP_FASTOPEN_KEYS_WUNLOCK();
787 } else if (!V_tcp_fastopen_server_enable && new) {
788 /* disabled -> enabled */
789 TCP_FASTOPEN_KEYS_WLOCK();
790 if (V_tcp_fastopen_autokey &&
791 (V_tcp_fastopen_numkeys == 0)) {
792 tcp_fastopen_autokey_locked();
793 callout_reset(&V_tcp_fastopen_autokey_ctx.c,
794 V_tcp_fastopen_autokey * hz,
795 tcp_fastopen_autokey_callout,
796 &V_tcp_fastopen_autokey_ctx);
797 }
798 V_tcp_fastopen_server_enable = 1;
799 TCP_FASTOPEN_KEYS_WUNLOCK();
800 }
801 }
802 return (error);
803 }
804
805 static int
806 sysctl_net_inet_tcp_fastopen_setkey(SYSCTL_HANDLER_ARGS)
807 {
808 int error;
809 uint8_t newkey[TCP_FASTOPEN_KEY_LEN];
810
811 if (req->oldptr != NULL || req->oldlen != 0)
812 return (EINVAL);
813 if (req->newptr == NULL)
814 return (EPERM);
815 if (req->newlen != sizeof(newkey))
816 return (EINVAL);
817 error = SYSCTL_IN(req, newkey, sizeof(newkey));
818 if (error)
819 return (error);
820
821 TCP_FASTOPEN_KEYS_WLOCK();
822 tcp_fastopen_addkey_locked(newkey);
823 TCP_FASTOPEN_KEYS_WUNLOCK();
824
825 return (0);
826 }
827
828 static int
829 sysctl_net_inet_tcp_fastopen_setpsk(SYSCTL_HANDLER_ARGS)
830 {
831 int error;
832 uint8_t newpsk[TCP_FASTOPEN_KEY_LEN];
833
834 if (req->oldptr != NULL || req->oldlen != 0)
835 return (EINVAL);
836 if (req->newptr == NULL)
837 return (EPERM);
838 if (req->newlen != sizeof(newpsk))
839 return (EINVAL);
840 error = SYSCTL_IN(req, newpsk, sizeof(newpsk));
841 if (error)
842 return (error);
843
844 TCP_FASTOPEN_KEYS_WLOCK();
845 tcp_fastopen_addpsk_locked(newpsk);
846 TCP_FASTOPEN_KEYS_WUNLOCK();
847
848 return (0);
849 }
850
851 static int
852 sysctl_net_inet_tcp_fastopen_ccache_bucket_limit(SYSCTL_HANDLER_ARGS)
853 {
854 struct tcp_fastopen_ccache_bucket *ccb;
855 int error;
856 unsigned int new;
857 unsigned int i;
858
859 new = V_tcp_fastopen_ccache.bucket_limit;
860 error = sysctl_handle_int(oidp, &new, 0, req);
861 if (error == 0 && req->newptr) {
862 if ((new == 0) || (new > INT_MAX))
863 error = EINVAL;
864 else {
865 if (new < V_tcp_fastopen_ccache.bucket_limit) {
866 for (i = 0; i < V_tcp_fastopen_ccache.buckets;
867 i++) {
868 ccb = &V_tcp_fastopen_ccache.base[i];
869 tcp_fastopen_ccache_bucket_trim(ccb, new);
870 }
871 }
872 V_tcp_fastopen_ccache.bucket_limit = new;
873 }
874
875 }
876 return (error);
877 }
878
879 static int
880 sysctl_net_inet_tcp_fastopen_client_enable(SYSCTL_HANDLER_ARGS)
881 {
882 struct tcp_fastopen_ccache_bucket *ccb;
883 int error;
884 unsigned int new, i;
885
886 new = V_tcp_fastopen_client_enable;
887 error = sysctl_handle_int(oidp, &new, 0, req);
888 if (error == 0 && req->newptr) {
889 if (V_tcp_fastopen_client_enable && !new) {
890 /* enabled -> disabled */
891 for (i = 0; i < V_tcp_fastopen_ccache.buckets; i++) {
892 ccb = &V_tcp_fastopen_ccache.base[i];
893 KASSERT(ccb->ccb_num_entries > -1,
894 ("%s: ccb->ccb_num_entries %d is negative",
895 __func__, ccb->ccb_num_entries));
896 tcp_fastopen_ccache_bucket_trim(ccb, 0);
897 }
898 V_tcp_fastopen_client_enable = 0;
899 } else if (!V_tcp_fastopen_client_enable && new) {
900 /* disabled -> enabled */
901 for (i = 0; i < V_tcp_fastopen_ccache.buckets; i++) {
902 ccb = &V_tcp_fastopen_ccache.base[i];
903 CCB_LOCK(ccb);
904 KASSERT(TAILQ_EMPTY(&ccb->ccb_entries),
905 ("%s: ccb->ccb_entries not empty", __func__));
906 KASSERT(ccb->ccb_num_entries == -1,
907 ("%s: ccb->ccb_num_entries %d not -1", __func__,
908 ccb->ccb_num_entries));
909 ccb->ccb_num_entries = 0; /* enable bucket */
910 CCB_UNLOCK(ccb);
911 }
912 V_tcp_fastopen_client_enable = 1;
913 }
914 }
915 return (error);
916 }
917
918 #endif
919
920 void
tcp_fastopen_connect(struct tcpcb * tp)921 tcp_fastopen_connect(struct tcpcb *tp)
922 {
923 /*
924 * samkumar: In TCPlp, we always act as though there is
925 * a cache miss.
926 *
927 * However, we would like to be able to send data with
928 * cookie requests. Therefore, we leave tp->t_maxseg at
929 * the default value instead of calling tcp_mss(tp, -1)
930 * and we set tp->snd_wnd as if there is a cache hit.
931 */
932 tp->snd_wnd = tp->t_maxseg;
933
934 #if 0
935 struct inpcb *inp;
936 struct tcp_fastopen_ccache_bucket *ccb;
937 struct tcp_fastopen_ccache_entry *cce;
938 sbintime_t now;
939 uint16_t server_mss;
940 uint64_t psk_cookie;
941
942 psk_cookie = 0;
943 inp = tp->t_inpcb;
944 cce = tcp_fastopen_ccache_lookup(&inp->inp_inc, &ccb);
945 if (cce) {
946 if (cce->disable_time == 0) {
947 if ((cce->cookie_len > 0) &&
948 (tp->t_tfo_client_cookie_len ==
949 TCP_FASTOPEN_PSK_LEN)) {
950 psk_cookie =
951 tcp_fastopen_make_psk_cookie(
952 tp->t_tfo_cookie.client,
953 cce->cookie, cce->cookie_len);
954 } else {
955 tp->t_tfo_client_cookie_len = cce->cookie_len;
956 memcpy(tp->t_tfo_cookie.client, cce->cookie,
957 cce->cookie_len);
958 }
959 server_mss = cce->server_mss;
960 CCB_UNLOCK(ccb);
961 if (tp->t_tfo_client_cookie_len ==
962 TCP_FASTOPEN_PSK_LEN && psk_cookie) {
963 tp->t_tfo_client_cookie_len =
964 TCP_FASTOPEN_COOKIE_LEN;
965 memcpy(tp->t_tfo_cookie.client, &psk_cookie,
966 TCP_FASTOPEN_COOKIE_LEN);
967 }
968 tcp_mss(tp, server_mss ? server_mss : -1);
969 tp->snd_wnd = tp->t_maxseg;
970 } else {
971 /*
972 * The path is disabled. Check the time and
973 * possibly re-enable.
974 */
975 now = getsbinuptime();
976 if (now - cce->disable_time >
977 ((sbintime_t)V_tcp_fastopen_path_disable_time << 32)) {
978 /*
979 * Re-enable path. Force a TFO cookie
980 * request. Forget the old MSS as it may be
981 * bogus now, and we will rediscover it in
982 * the SYN|ACK.
983 */
984 cce->disable_time = 0;
985 cce->server_mss = 0;
986 cce->cookie_len = 0;
987 /*
988 * tp->t_tfo... cookie details are already
989 * zero from the tcpcb init.
990 */
991 } else {
992 /*
993 * Path is disabled, so disable TFO on this
994 * connection.
995 */
996 tp->t_flags &= ~TF_FASTOPEN;
997 }
998 CCB_UNLOCK(ccb);
999 tcp_mss(tp, -1);
1000 /*
1001 * snd_wnd is irrelevant since we are either forcing
1002 * a TFO cookie request or disabling TFO - either
1003 * way, no data with the SYN.
1004 */
1005 }
1006 } else {
1007 /*
1008 * A new entry for this path will be created when a SYN|ACK
1009 * comes back, or the attempt otherwise fails.
1010 */
1011 CCB_UNLOCK(ccb);
1012 tcp_mss(tp, -1);
1013 /*
1014 * snd_wnd is irrelevant since we are forcing a TFO cookie
1015 * request.
1016 */
1017 }
1018 #endif
1019 }
1020
1021 void
tcp_fastopen_disable_path(struct tcpcb * tp)1022 tcp_fastopen_disable_path(struct tcpcb *tp)
1023 {
1024 #if 0
1025 struct in_conninfo *inc = &tp->t_inpcb->inp_inc;
1026 struct tcp_fastopen_ccache_bucket *ccb;
1027 struct tcp_fastopen_ccache_entry *cce;
1028
1029 cce = tcp_fastopen_ccache_lookup(inc, &ccb);
1030 if (cce) {
1031 cce->server_mss = 0;
1032 cce->cookie_len = 0;
1033 /*
1034 * Preserve the existing disable time if it is already
1035 * disabled.
1036 */
1037 if (cce->disable_time == 0)
1038 cce->disable_time = getsbinuptime();
1039 } else /* use invalid cookie len to create disabled entry */
1040 tcp_fastopen_ccache_create(ccb, inc, 0,
1041 TCP_FASTOPEN_MAX_COOKIE_LEN + 1, NULL);
1042
1043 CCB_UNLOCK(ccb);
1044 #endif
1045 tp->t_flags &= ~TF_FASTOPEN;
1046 }
1047
1048 void
tcp_fastopen_update_cache(struct tcpcb * tp,uint16_t mss,uint8_t cookie_len,uint8_t * cookie)1049 tcp_fastopen_update_cache(struct tcpcb *tp, uint16_t mss,
1050 uint8_t cookie_len, uint8_t *cookie)
1051 {
1052 #if 0
1053 struct in_conninfo *inc = &tp->t_inpcb->inp_inc;
1054 struct tcp_fastopen_ccache_bucket *ccb;
1055 struct tcp_fastopen_ccache_entry *cce;
1056
1057 cce = tcp_fastopen_ccache_lookup(inc, &ccb);
1058 if (cce) {
1059 if ((cookie_len >= TCP_FASTOPEN_MIN_COOKIE_LEN) &&
1060 (cookie_len <= TCP_FASTOPEN_MAX_COOKIE_LEN) &&
1061 ((cookie_len & 0x1) == 0)) {
1062 cce->server_mss = mss;
1063 cce->cookie_len = cookie_len;
1064 memcpy(cce->cookie, cookie, cookie_len);
1065 cce->disable_time = 0;
1066 } else {
1067 /* invalid cookie length, disable entry */
1068 cce->server_mss = 0;
1069 cce->cookie_len = 0;
1070 /*
1071 * Preserve the existing disable time if it is
1072 * already disabled.
1073 */
1074 if (cce->disable_time == 0)
1075 cce->disable_time = getsbinuptime();
1076 }
1077 } else
1078 tcp_fastopen_ccache_create(ccb, inc, mss, cookie_len, cookie);
1079
1080 CCB_UNLOCK(ccb);
1081 #endif
1082 }
1083
1084 #if 0
1085
1086 static struct tcp_fastopen_ccache_entry *
1087 tcp_fastopen_ccache_lookup(struct in_conninfo *inc,
1088 struct tcp_fastopen_ccache_bucket **ccbp)
1089 {
1090 struct tcp_fastopen_ccache_bucket *ccb;
1091 struct tcp_fastopen_ccache_entry *cce;
1092 uint32_t last_word;
1093 uint32_t hash;
1094
1095 hash = jenkins_hash32((uint32_t *)&inc->inc_ie.ie_dependladdr, 4,
1096 V_tcp_fastopen_ccache.secret);
1097 hash = jenkins_hash32((uint32_t *)&inc->inc_ie.ie_dependfaddr, 4,
1098 hash);
1099 last_word = inc->inc_fport;
1100 hash = jenkins_hash32(&last_word, 1, hash);
1101 ccb = &V_tcp_fastopen_ccache.base[hash & V_tcp_fastopen_ccache.mask];
1102 *ccbp = ccb;
1103 CCB_LOCK(ccb);
1104
1105 /*
1106 * Always returns with locked bucket.
1107 */
1108 TAILQ_FOREACH(cce, &ccb->ccb_entries, cce_link)
1109 if ((!(cce->af == AF_INET6) == !(inc->inc_flags & INC_ISIPV6)) &&
1110 (cce->server_port == inc->inc_ie.ie_fport) &&
1111 (((cce->af == AF_INET) &&
1112 (cce->cce_client_ip.v4.s_addr == inc->inc_laddr.s_addr) &&
1113 (cce->cce_server_ip.v4.s_addr == inc->inc_faddr.s_addr)) ||
1114 ((cce->af == AF_INET6) &&
1115 IN6_ARE_ADDR_EQUAL(&cce->cce_client_ip.v6, &inc->inc6_laddr) &&
1116 IN6_ARE_ADDR_EQUAL(&cce->cce_server_ip.v6, &inc->inc6_faddr))))
1117 break;
1118
1119 return (cce);
1120 }
1121
1122 static struct tcp_fastopen_ccache_entry *
1123 tcp_fastopen_ccache_create(struct tcp_fastopen_ccache_bucket *ccb,
1124 struct in_conninfo *inc, uint16_t mss, uint8_t cookie_len, uint8_t *cookie)
1125 {
1126 struct tcp_fastopen_ccache_entry *cce;
1127
1128 /*
1129 * 1. Create a new entry, or
1130 * 2. Reclaim an existing entry, or
1131 * 3. Fail
1132 */
1133
1134 CCB_LOCK_ASSERT(ccb);
1135
1136 cce = NULL;
1137 if (ccb->ccb_num_entries < V_tcp_fastopen_ccache.bucket_limit)
1138 cce = uma_zalloc(V_tcp_fastopen_ccache.zone, M_NOWAIT);
1139
1140 if (cce == NULL) {
1141 /*
1142 * At bucket limit, or out of memory - reclaim last
1143 * entry in bucket.
1144 */
1145 cce = TAILQ_LAST(&ccb->ccb_entries, bucket_entries);
1146 if (cce == NULL) {
1147 /* XXX count this event */
1148 return (NULL);
1149 }
1150
1151 TAILQ_REMOVE(&ccb->ccb_entries, cce, cce_link);
1152 } else
1153 ccb->ccb_num_entries++;
1154
1155 TAILQ_INSERT_HEAD(&ccb->ccb_entries, cce, cce_link);
1156 cce->af = (inc->inc_flags & INC_ISIPV6) ? AF_INET6 : AF_INET;
1157 if (cce->af == AF_INET) {
1158 cce->cce_client_ip.v4 = inc->inc_laddr;
1159 cce->cce_server_ip.v4 = inc->inc_faddr;
1160 } else {
1161 cce->cce_client_ip.v6 = inc->inc6_laddr;
1162 cce->cce_server_ip.v6 = inc->inc6_faddr;
1163 }
1164 cce->server_port = inc->inc_fport;
1165 if ((cookie_len >= TCP_FASTOPEN_MIN_COOKIE_LEN) &&
1166 (cookie_len <= TCP_FASTOPEN_MAX_COOKIE_LEN) &&
1167 ((cookie_len & 0x1) == 0)) {
1168 cce->server_mss = mss;
1169 cce->cookie_len = cookie_len;
1170 memcpy(cce->cookie, cookie, cookie_len);
1171 cce->disable_time = 0;
1172 } else {
1173 /* invalid cookie length, disable cce */
1174 cce->server_mss = 0;
1175 cce->cookie_len = 0;
1176 cce->disable_time = getsbinuptime();
1177 }
1178
1179 return (cce);
1180 }
1181
1182 static void
1183 tcp_fastopen_ccache_bucket_trim(struct tcp_fastopen_ccache_bucket *ccb,
1184 unsigned int limit)
1185 {
1186 struct tcp_fastopen_ccache_entry *cce, *cce_tmp;
1187 unsigned int entries;
1188
1189 CCB_LOCK(ccb);
1190 entries = 0;
1191 TAILQ_FOREACH_SAFE(cce, &ccb->ccb_entries, cce_link, cce_tmp) {
1192 entries++;
1193 if (entries > limit)
1194 tcp_fastopen_ccache_entry_drop(cce, ccb);
1195 }
1196 KASSERT(ccb->ccb_num_entries <= (int)limit,
1197 ("%s: ccb->ccb_num_entries %d exceeds limit %d", __func__,
1198 ccb->ccb_num_entries, limit));
1199 if (limit == 0) {
1200 KASSERT(TAILQ_EMPTY(&ccb->ccb_entries),
1201 ("%s: ccb->ccb_entries not empty", __func__));
1202 ccb->ccb_num_entries = -1; /* disable bucket */
1203 }
1204 CCB_UNLOCK(ccb);
1205 }
1206
1207 static void
1208 tcp_fastopen_ccache_entry_drop(struct tcp_fastopen_ccache_entry *cce,
1209 struct tcp_fastopen_ccache_bucket *ccb)
1210 {
1211
1212 CCB_LOCK_ASSERT(ccb);
1213
1214 TAILQ_REMOVE(&ccb->ccb_entries, cce, cce_link);
1215 ccb->ccb_num_entries--;
1216 uma_zfree(V_tcp_fastopen_ccache.zone, cce);
1217 }
1218
1219 static int
1220 sysctl_net_inet_tcp_fastopen_ccache_list(SYSCTL_HANDLER_ARGS)
1221 {
1222 struct sbuf sb;
1223 struct tcp_fastopen_ccache_bucket *ccb;
1224 struct tcp_fastopen_ccache_entry *cce;
1225 sbintime_t now, duration, limit;
1226 const int linesize = 128;
1227 int i, error, num_entries;
1228 unsigned int j;
1229 #ifdef INET6
1230 char clt_buf[INET6_ADDRSTRLEN], srv_buf[INET6_ADDRSTRLEN];
1231 #else
1232 char clt_buf[INET_ADDRSTRLEN], srv_buf[INET_ADDRSTRLEN];
1233 #endif
1234
1235 if (jailed_without_vnet(curthread->td_ucred) != 0)
1236 return (EPERM);
1237
1238 /* Only allow root to read the client cookie cache */
1239 if (curthread->td_ucred->cr_uid != 0)
1240 return (EPERM);
1241
1242 num_entries = 0;
1243 for (i = 0; i < V_tcp_fastopen_ccache.buckets; i++) {
1244 ccb = &V_tcp_fastopen_ccache.base[i];
1245 CCB_LOCK(ccb);
1246 if (ccb->ccb_num_entries > 0)
1247 num_entries += ccb->ccb_num_entries;
1248 CCB_UNLOCK(ccb);
1249 }
1250 sbuf_new(&sb, NULL, linesize * (num_entries + 1), SBUF_INCLUDENUL);
1251
1252 sbuf_printf(&sb,
1253 "\nLocal IP address Remote IP address Port MSS"
1254 " Disabled Cookie\n");
1255
1256 now = getsbinuptime();
1257 limit = (sbintime_t)V_tcp_fastopen_path_disable_time << 32;
1258 for (i = 0; i < V_tcp_fastopen_ccache.buckets; i++) {
1259 ccb = &V_tcp_fastopen_ccache.base[i];
1260 CCB_LOCK(ccb);
1261 TAILQ_FOREACH(cce, &ccb->ccb_entries, cce_link) {
1262 if (cce->disable_time != 0) {
1263 duration = now - cce->disable_time;
1264 if (limit >= duration)
1265 duration = limit - duration;
1266 else
1267 duration = 0;
1268 } else
1269 duration = 0;
1270 sbuf_printf(&sb,
1271 "%-20s %-20s %5u %5u ",
1272 inet_ntop(cce->af, &cce->cce_client_ip,
1273 clt_buf, sizeof(clt_buf)),
1274 inet_ntop(cce->af, &cce->cce_server_ip,
1275 srv_buf, sizeof(srv_buf)),
1276 ntohs(cce->server_port),
1277 cce->server_mss);
1278 if (duration > 0)
1279 sbuf_printf(&sb, "%7ds ", sbintime_getsec(duration));
1280 else
1281 sbuf_printf(&sb, "%8s ", "No");
1282 for (j = 0; j < cce->cookie_len; j++)
1283 sbuf_printf(&sb, "%02x", cce->cookie[j]);
1284 sbuf_putc(&sb, '\n');
1285 }
1286 CCB_UNLOCK(ccb);
1287 }
1288 error = sbuf_finish(&sb);
1289 if (error == 0)
1290 error = SYSCTL_OUT(req, sbuf_data(&sb), sbuf_len(&sb));
1291 sbuf_delete(&sb);
1292 return (error);
1293 }
1294
1295 #endif