diff options
Diffstat (limited to 'net/ipv4/tcp_fastopen.c')
| -rw-r--r-- | net/ipv4/tcp_fastopen.c | 29 | 
1 files changed, 17 insertions, 12 deletions
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index ab7bd35bb312..f195d9316e55 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c @@ -8,12 +8,26 @@  #include <net/inetpeer.h>  #include <net/tcp.h> -int sysctl_tcp_fastopen __read_mostly; +int sysctl_tcp_fastopen __read_mostly = TFO_CLIENT_ENABLE;  struct tcp_fastopen_context __rcu *tcp_fastopen_ctx;  static DEFINE_SPINLOCK(tcp_fastopen_ctx_lock); +void tcp_fastopen_init_key_once(bool publish) +{ +	static u8 key[TCP_FASTOPEN_KEY_LENGTH]; + +	/* tcp_fastopen_reset_cipher publishes the new context +	 * atomically, so we allow this race happening here. +	 * +	 * All call sites of tcp_fastopen_cookie_gen also check +	 * for a valid cookie, so this is an acceptable risk. +	 */ +	if (net_get_random_once(key, sizeof(key)) && publish) +		tcp_fastopen_reset_cipher(key, sizeof(key)); +} +  static void tcp_fastopen_ctx_free(struct rcu_head *head)  {  	struct tcp_fastopen_context *ctx = @@ -70,6 +84,8 @@ void tcp_fastopen_cookie_gen(__be32 src, __be32 dst,  	__be32 path[4] = { src, dst, 0, 0 };  	struct tcp_fastopen_context *ctx; +	tcp_fastopen_init_key_once(true); +  	rcu_read_lock();  	ctx = rcu_dereference(tcp_fastopen_ctx);  	if (ctx) { @@ -78,14 +94,3 @@ void tcp_fastopen_cookie_gen(__be32 src, __be32 dst,  	}  	rcu_read_unlock();  } - -static int __init tcp_fastopen_init(void) -{ -	__u8 key[TCP_FASTOPEN_KEY_LENGTH]; - -	get_random_bytes(key, sizeof(key)); -	tcp_fastopen_reset_cipher(key, sizeof(key)); -	return 0; -} - -late_initcall(tcp_fastopen_init);  | 
