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