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
@ -106,6 +106,34 @@ struct listen_sock {
|
||||
struct request_sock *syn_table[0];
|
||||
};
|
||||
|
||||
/*
|
||||
* For a TCP Fast Open listener -
|
||||
* lock - protects the access to all the reqsk, which is co-owned by
|
||||
* the listener and the child socket.
|
||||
* qlen - pending TFO requests (still in TCP_SYN_RECV).
|
||||
* max_qlen - max TFO reqs allowed before TFO is disabled.
|
||||
*
|
||||
* XXX (TFO) - ideally these fields can be made as part of "listen_sock"
|
||||
* structure above. But there is some implementation difficulty due to
|
||||
* listen_sock being part of request_sock_queue hence will be freed when
|
||||
* a listener is stopped. But TFO related fields may continue to be
|
||||
* accessed even after a listener is closed, until its sk_refcnt drops
|
||||
* to 0 implying no more outstanding TFO reqs. One solution is to keep
|
||||
* listen_opt around until sk_refcnt drops to 0. But there is some other
|
||||
* complexity that needs to be resolved. E.g., a listener can be disabled
|
||||
* temporarily through shutdown()->tcp_disconnect(), and re-enabled later.
|
||||
*/
|
||||
struct fastopen_queue {
|
||||
struct request_sock *rskq_rst_head; /* Keep track of past TFO */
|
||||
struct request_sock *rskq_rst_tail; /* requests that caused RST.
|
||||
* This is part of the defense
|
||||
* against spoofing attack.
|
||||
*/
|
||||
spinlock_t lock;
|
||||
int qlen; /* # of pending (TCP_SYN_RECV) reqs */
|
||||
int max_qlen; /* != 0 iff TFO is currently enabled */
|
||||
};
|
||||
|
||||
/** struct request_sock_queue - queue of request_socks
|
||||
*
|
||||
* @rskq_accept_head - FIFO head of established children
|
||||
@ -129,6 +157,12 @@ struct request_sock_queue {
|
||||
u8 rskq_defer_accept;
|
||||
/* 3 bytes hole, try to pack */
|
||||
struct listen_sock *listen_opt;
|
||||
struct fastopen_queue *fastopenq; /* This is non-NULL iff TFO has been
|
||||
* enabled on this listener. Check
|
||||
* max_qlen != 0 in fastopen_queue
|
||||
* to determine if TFO is enabled
|
||||
* right at this moment.
|
||||
*/
|
||||
};
|
||||
|
||||
extern int reqsk_queue_alloc(struct request_sock_queue *queue,
|
||||
@ -136,6 +170,8 @@ extern int reqsk_queue_alloc(struct request_sock_queue *queue,
|
||||
|
||||
extern void __reqsk_queue_destroy(struct request_sock_queue *queue);
|
||||
extern void reqsk_queue_destroy(struct request_sock_queue *queue);
|
||||
extern void reqsk_fastopen_remove(struct sock *sk,
|
||||
struct request_sock *req, bool reset);
|
||||
|
||||
static inline struct request_sock *
|
||||
reqsk_queue_yank_acceptq(struct request_sock_queue *queue)
|
||||
|
Reference in New Issue
Block a user