TCPCT part 1d: initial SYN exchange with SYNACK data
Subsystems (3)
PATCH 4/4 TCPCT part 1d: initial SYN exchange with SYNACK data
-------- Original Message --------
Subject: [net-next-2.6 PATCH 4/4] TCPCT part 1: initial SYN exchange with SYNACK data
Date: Thu, 15 Oct 2009 01:36:48 -0400
From: William Allen Simpson <[email protected]>
To: Linux Kernel Network Developers <[email protected]>
References: <[email protected]> <[email protected]> <[email protected]>
This is a significantly revised implementation of an earlier (year-old) patch that no longer applies cleanly, with permission of the original author (Adam Langley). That patch was previously reviewed:
http://thread.gmane.org/gmane.linux.network/102586
The principle difference is using a TCP option to carry the cookie nonce, instead of a user configured offset in the data. This is more flexible and less subject to user configuration error. Such a cookie option has been suggested for many years, and is also useful without SYN data, allowing several related concepts to use the same extension option.
"Re: SYN floods (was: does history repeat itself?)", September 9, 1996.
http://www.merit.net/mail.archives/nanog/1996-09/msg00235.html
"Re: what a new TCP header might look like", May 12, 1998. ftp://ftp.isi.edu/end2end/end2end-interest-1998.mail
Data structures are carefully composed to require minimal additions. For example, the struct tcp_options_received cookie_plus variable fits between existing 16-bit and 8-bit variables, requiring no additional space (taking alignment into consideration). There are no additions to tcp_request_sock, and only 1 pointer and 1 flag byte in tcp_sock.
Allocations have been rearranged to avoid requiring GFP_ATOMIC, with only one unavoidable exception in tcp_create_openreq_child(), where the tcp_sock itself is created GFP_ATOMIC.
These functions will also be used in subsequent patches that implement additional features.
Requires:
TCPCT part 1a: add function parameter for sending SYNACK TCPCT part 1b: sysctl_tcp_cookie_size and TCP_COOKIE_TRANSACTIONS TCPCT part 1c: redefine TCP header functions *_len_th(), cleanup
--- include/linux/tcp.h | 35 +++++++- include/net/tcp.h | 72 ++++++++++++++-- net/ipv4/syncookies.c | 5 +- net/ipv4/tcp.c | 133 +++++++++++++++++++++++++++- net/ipv4/tcp_input.c | 82 +++++++++++++++--- net/ipv4/tcp_ipv4.c | 62 +++++++++++-- net/ipv4/tcp_minisocks.c | 43 +++++++--- net/ipv4/tcp_output.c | 223 ++++++++++++++++++++++++++++++++++++++++++--- net/ipv6/syncookies.c | 5 +- net/ipv6/tcp_ipv6.c | 47 +++++++++- 10 files changed, 641 insertions(+), 66 deletions(-)
include/linux/tcp.h +31 -4
@@ -252,26 +252,36 @@ struct tcp_options_received { sack_ok : 4, /* SACK seen on SYN packet */ snd_wscale : 4, /* Window scaling received from sender */ rcv_wscale : 4; /* Window scaling to send to receiver */ -/* SACKs data */ + u8 cookie_plus: 6; /* bytes in authenticator/cookie option */u8 num_sacks;/* Number of SACK blocks */ -u16 user_mss;/* mss requested by user in ioctl */ +u16 user_mss;/* mss requested by user in ioctl */ u16 mss_clamp;/* Maximal mss, negotiated at connection setup */ }; +static inline void tcp_clear_options (struct tcp_options_received *rx_opt) +{ + rx_opt->tstamp_ok = rx_opt->sack_ok =0 ; + rx_opt->wscale_ok = rx_opt->snd_wscale =0 ; + rx_opt->cookie_plus =0 ; +} +/* This is the max number of SACKS that we'll generate and process. It's safe * to increse this, although since: * size = TCPOLEN_SACK_BASE_ALIGNED (4) + n * TCPOLEN_SACK_PERBLOCK (8) * only four options will fit in a standard TCP header */ #define TCP_NUM_SACKS 4 +struct tcp_cookie_values ; +struct tcp_request_sock_ops ; +struct tcp_request_sock {struct inet_request_sock req;#ifdef CONFIG_TCP_MD5SIG /* Only used by TCP MD5 Signature so far. */ const struct tcp_request_sock_ops *af_specific;#endif -u32 rcv_isn; -u32 snt_isn; +u32 rcv_isn; +u32 snt_isn; };static inline struct tcp_request_sock *tcp_rsk (const struct request_sock *req)
@@ -441,6 +451,19 @@ struct tcp_sock {/* TCP MD5 Signature Option information */ struct tcp_md5sig_info *md5sig_info;#endif + +/* 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; + + u8 cookie_in_always:1, + cookie_out_never:1, + extend_timestamp:1, + s_data_constant:1, + s_data_in:1, + s_data_out:1; };static inline struct tcp_sock *tcp_sk (const struct sock *sk)
@@ -459,6 +482,10 @@ struct tcp_timewait_sock {u16 tw_md5_keylen;u8 tw_md5_key[TCP_MD5SIG_MAXKEYLEN ];#endif +/* Few sockets in timewait have cookies; in that case, then this +* object holds a reference to it (tw_cookie_values->kref) +*/ +struct tcp_cookie_values *tw_cookie_values; };static inline struct tcp_timewait_sock *tcp_twsk (const struct sock *sk)
include/net/tcp.h +66 -6
108 lines not on this page · raw message
net/ipv4/syncookies.c +3 -2
@@ -253,6 +253,8 @@ EXPORT_SYMBOL(cookie_check_timestamp);struct sock *cookie_v4_check (struct sock *sk,struct sk_buff *skb,struct ip_options *opt) { +struct tcp_options_received tcp_opt; +u8 *cryptic_value;struct inet_request_sock *ireq;struct tcp_request_sock *treq;struct tcp_sock *tp =tcp_sk (sk);
@@ -263,7 +265,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,int mss;struct rtable *rt;__u8 rcv_wscale; -struct tcp_options_received tcp_opt;if (!sysctl_tcp_syncookies || !th->ack) goto out;
@@ -278,7 +279,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,/* check for timestamp cookie support */ memset (&tcp_opt,0 ,sizeof (tcp_opt)); -tcp_parse_options (skb, &tcp_opt,0 ); +tcp_parse_options (skb, &tcp_opt, &cryptic_value,0 );if (tcp_opt.saw_tstamp)cookie_check_timestamp (&tcp_opt);
net/ipv4/tcp.c +131 -2
151 lines not on this page · raw message
net/ipv4/tcp_input.c +71 -11
150 lines not on this page · raw message
net/ipv4/tcp_ipv4.c +54 -8
112 lines not on this page · raw message
net/ipv4/tcp_minisocks.c +32 -11
85 lines not on this page · raw message
net/ipv4/tcp_output.c +208 -15
324 lines not on this page · raw message
net/ipv6/syncookies.c +3 -2
@@ -159,6 +159,8 @@ static inline int cookie_check(struct sk_buff *skb, __u32 cookie)struct sock *cookie_v6_check (struct sock *sk,struct sk_buff *skb) { +struct tcp_options_received tcp_opt; +u8 *cryptic_value;struct inet_request_sock *ireq;struct inet6_request_sock *ireq6;struct tcp_request_sock *treq;
@@ -171,7 +173,6 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)int mss;struct dst_entry *dst;__u8 rcv_wscale; -struct tcp_options_received tcp_opt;if (!sysctl_tcp_syncookies || !th->ack) goto out;
@@ -186,7 +187,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)/* check for timestamp cookie support */ memset (&tcp_opt,0 ,sizeof (tcp_opt)); -tcp_parse_options (skb, &tcp_opt,0 ); +tcp_parse_options (skb, &tcp_opt, &cryptic_value,0 );if (tcp_opt.saw_tstamp)cookie_check_timestamp (&tcp_opt);
net/ipv6/tcp_ipv6.c +42 -5
80 lines not on this page · raw message
Signature · 1 line
1.6.0.4