Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1fba70e5 authored by Yuchung Cheng's avatar Yuchung Cheng Committed by David S. Miller
Browse files

tcp: socket option to set TCP fast open key



New socket option TCP_FASTOPEN_KEY to allow different keys per
listener.  The listener by default uses the global key until the
socket option is set.  The key is a 16 bytes long binary data. This
option has no effect on regular non-listener TCP sockets.

Signed-off-by: default avatarYuchung Cheng <ycheng@google.com>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarChristoph Paasch <cpaasch@apple.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ce12f7dd
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -150,6 +150,8 @@ struct fastopen_queue {
	spinlock_t	lock;
	int		qlen;		/* # of pending (TCP_SYN_RECV) reqs */
	int		max_qlen;	/* != 0 iff TFO is currently enabled */

	struct tcp_fastopen_context __rcu *ctx; /* cipher context for cookie */
};

/** struct request_sock_queue - queue of request_socks
+3 −2
Original line number Diff line number Diff line
@@ -1555,9 +1555,10 @@ struct tcp_fastopen_request {
	int				copied;	/* queued in tcp_connect() */
};
void tcp_free_fastopen_req(struct tcp_sock *tp);

void tcp_fastopen_destroy_cipher(struct sock *sk);
void tcp_fastopen_ctx_destroy(struct net *net);
int tcp_fastopen_reset_cipher(struct net *net, void *key, unsigned int len);
int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk,
			      void *key, unsigned int len);
void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb);
struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
			      struct request_sock *req,
+1 −0
Original line number Diff line number Diff line
@@ -119,6 +119,7 @@ enum {
#define TCP_FASTOPEN_CONNECT	30	/* Attempt FastOpen with connect */
#define TCP_ULP			31	/* Attach a ULP to a TCP connection */
#define TCP_MD5SIG_EXT		32	/* TCP MD5 Signature with extensions */
#define TCP_FASTOPEN_KEY	33	/* Set the key for Fast Open (cookie) */

struct tcp_repair_opt {
	__u32	opt_code;
+2 −1
Original line number Diff line number Diff line
@@ -284,7 +284,8 @@ static int proc_tcp_fastopen_key(struct ctl_table *table, int write,
			ret = -EINVAL;
			goto bad_key;
		}
		tcp_fastopen_reset_cipher(net, user_key, TCP_FASTOPEN_KEY_LENGTH);
		tcp_fastopen_reset_cipher(net, NULL, user_key,
					  TCP_FASTOPEN_KEY_LENGTH);
	}

bad_key:
+33 −0
Original line number Diff line number Diff line
@@ -2571,6 +2571,17 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
		release_sock(sk);
		return err;
	}
	case TCP_FASTOPEN_KEY: {
		__u8 key[TCP_FASTOPEN_KEY_LENGTH];

		if (optlen != sizeof(key))
			return -EINVAL;

		if (copy_from_user(key, optval, optlen))
			return -EFAULT;

		return tcp_fastopen_reset_cipher(net, sk, key, sizeof(key));
	}
	default:
		/* fallthru */
		break;
@@ -3157,6 +3168,28 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
			return -EFAULT;
		return 0;

	case TCP_FASTOPEN_KEY: {
		__u8 key[TCP_FASTOPEN_KEY_LENGTH];
		struct tcp_fastopen_context *ctx;

		if (get_user(len, optlen))
			return -EFAULT;

		rcu_read_lock();
		ctx = rcu_dereference(icsk->icsk_accept_queue.fastopenq.ctx);
		if (ctx)
			memcpy(key, ctx->key, sizeof(key));
		else
			len = 0;
		rcu_read_unlock();

		len = min_t(unsigned int, len, sizeof(key));
		if (put_user(len, optlen))
			return -EFAULT;
		if (copy_to_user(optval, key, len))
			return -EFAULT;
		return 0;
	}
	case TCP_THIN_LINEAR_TIMEOUTS:
		val = tp->thin_lto;
		break;
Loading