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>
This commit is contained in:

committed by
David S. Miller

parent
2a35cfa591
commit
1046716368
@@ -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 */
|
||||
|
Reference in New Issue
Block a user