diff options
| author | Jerry Chu <hkchu@google.com> | 2012-08-31 12:29:11 +0000 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2012-08-31 20:02:18 -0400 | 
| commit | 1046716368979dee857a2b8a91c4a8833f21b9cb (patch) | |
| tree | fdda70278e6fa56c27d242fb1a0ec9b7e3e81d38 /include/linux/tcp.h | |
| parent | 2a35cfa591ac63f17815c2d9432b799e37527980 (diff) | |
| download | olio-linux-3.10-1046716368979dee857a2b8a91c4a8833f21b9cb.tar.xz olio-linux-3.10-1046716368979dee857a2b8a91c4a8833f21b9cb.zip  | |
tcp: TCP Fast Open Server - header & support functions
This patch adds all the necessary data structure and support
functions to implement TFO server side. It also documents a number
of flags for the sysctl_tcp_fastopen knob, and adds a few Linux
extension MIBs.
In addition, it includes the following:
1. a new TCP_FASTOPEN socket option an application must call to
supply a max backlog allowed in order to enable TFO on its listener.
2. A number of key data structures:
"fastopen_rsk" in tcp_sock - for a big socket to access its
request_sock for retransmission and ack processing purpose. It is
non-NULL iff 3WHS not completed.
"fastopenq" in request_sock_queue - points to a per Fast Open
listener data structure "fastopen_queue" to keep track of qlen (# of
outstanding Fast Open requests) and max_qlen, among other things.
"listener" in tcp_request_sock - to point to the original listener
for book-keeping purpose, i.e., to maintain qlen against max_qlen
as part of defense against IP spoofing attack.
3. various data structure and functions, many in tcp_fastopen.c, to
support server side Fast Open cookie operations, including
/proc/sys/net/ipv4/tcp_fastopen_key to allow manual rekeying.
Signed-off-by: H.K. Jerry Chu <hkchu@google.com>
Cc: Yuchung Cheng <ycheng@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/tcp.h')
| -rw-r--r-- | include/linux/tcp.h | 45 | 
1 files changed, 42 insertions, 3 deletions
diff --git a/include/linux/tcp.h b/include/linux/tcp.h index eb125a4c30b..ae46df59062 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -110,6 +110,7 @@ enum {  #define TCP_REPAIR_QUEUE	20  #define TCP_QUEUE_SEQ		21  #define TCP_REPAIR_OPTIONS	22 +#define TCP_FASTOPEN		23	/* Enable FastOpen on listeners */  struct tcp_repair_opt {  	__u32	opt_code; @@ -246,6 +247,7 @@ static inline unsigned int tcp_optlen(const struct sk_buff *skb)  /* TCP Fast Open */  #define TCP_FASTOPEN_COOKIE_MIN	4	/* Min Fast Open Cookie size in bytes */  #define TCP_FASTOPEN_COOKIE_MAX	16	/* Max Fast Open Cookie size in bytes */ +#define TCP_FASTOPEN_COOKIE_SIZE 8	/* the size employed by this impl. */  /* TCP Fast Open Cookie as stored in memory */  struct tcp_fastopen_cookie { @@ -312,9 +314,14 @@ struct tcp_request_sock {  	/* Only used by TCP MD5 Signature so far. */  	const struct tcp_request_sock_ops *af_specific;  #endif +	struct sock			*listener; /* needed for TFO */  	u32				rcv_isn;  	u32				snt_isn;  	u32				snt_synack; /* synack sent time */ +	u32				rcv_nxt; /* the ack # by SYNACK. For +						  * FastOpen it's the seq# +						  * after data-in-SYN. +						  */  };  static inline struct tcp_request_sock *tcp_rsk(const struct request_sock *req) @@ -505,14 +512,18 @@ struct tcp_sock {  	struct tcp_md5sig_info	__rcu *md5sig_info;  #endif -/* TCP fastopen related information */ -	struct tcp_fastopen_request *fastopen_req; -  	/* When the cookie options are generated and exchanged, then this  	 * object holds a reference to them (cookie_values->kref).  Also  	 * contains related tcp_cookie_transactions fields.  	 */  	struct tcp_cookie_values  *cookie_values; + +/* TCP fastopen related information */ +	struct tcp_fastopen_request *fastopen_req; +	/* fastopen_rsk points to request_sock that resulted in this big +	 * socket. Used to retransmit SYNACKs etc. +	 */ +	struct request_sock *fastopen_rsk;  };  enum tsq_flags { @@ -552,6 +563,34 @@ static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk)  	return (struct tcp_timewait_sock *)sk;  } +static inline bool tcp_passive_fastopen(const struct sock *sk) +{ +	return (sk->sk_state == TCP_SYN_RECV && +		tcp_sk(sk)->fastopen_rsk != NULL); +} + +static inline bool fastopen_cookie_present(struct tcp_fastopen_cookie *foc) +{ +	return foc->len != -1; +} + +static inline int fastopen_init_queue(struct sock *sk, int backlog) +{ +	struct request_sock_queue *queue = +	    &inet_csk(sk)->icsk_accept_queue; + +	if (queue->fastopenq == NULL) { +		queue->fastopenq = kzalloc( +		    sizeof(struct fastopen_queue), +		    sk->sk_allocation); +		if (queue->fastopenq == NULL) +			return -ENOMEM; +		spin_lock_init(&queue->fastopenq->lock); +	} +	queue->fastopenq->max_qlen = backlog; +	return 0; +} +  #endif	/* __KERNEL__ */  #endif	/* _LINUX_TCP_H */  |