syncookies.c (27eb2c4b3d3e13f376a359e293c212a2e9407af5) syncookies.c (0198230b7705eb2386e53778d944e307eef0cc71)
1/*
2 * Syncookies implementation for the Linux kernel
3 *
4 * Copyright (C) 1997 Andi Kleen
5 * Based on ideas by D.J.Bernstein and Eric Schenk.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License

--- 146 unchanged lines hidden (view full) ---

155 4312,
156 8960,
157};
158
159/*
160 * Generate a syncookie. mssp points to the mss, which is returned
161 * rounded down to the value encoded in the cookie.
162 */
1/*
2 * Syncookies implementation for the Linux kernel
3 *
4 * Copyright (C) 1997 Andi Kleen
5 * Based on ideas by D.J.Bernstein and Eric Schenk.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License

--- 146 unchanged lines hidden (view full) ---

155 4312,
156 8960,
157};
158
159/*
160 * Generate a syncookie. mssp points to the mss, which is returned
161 * rounded down to the value encoded in the cookie.
162 */
163__u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
163u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th,
164 u16 *mssp)
164{
165{
165 const struct iphdr *iph = ip_hdr(skb);
166 const struct tcphdr *th = tcp_hdr(skb);
167 int mssind;
168 const __u16 mss = *mssp;
169
166 int mssind;
167 const __u16 mss = *mssp;
168
170 tcp_synq_overflow(sk);
171
172 for (mssind = ARRAY_SIZE(msstab) - 1; mssind ; mssind--)
173 if (mss >= msstab[mssind])
174 break;
175 *mssp = msstab[mssind];
176
169 for (mssind = ARRAY_SIZE(msstab) - 1; mssind ; mssind--)
170 if (mss >= msstab[mssind])
171 break;
172 *mssp = msstab[mssind];
173
177 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESSENT);
178
179 return secure_tcp_syn_cookie(iph->saddr, iph->daddr,
180 th->source, th->dest, ntohl(th->seq),
181 jiffies / (HZ * 60), mssind);
182}
174 return secure_tcp_syn_cookie(iph->saddr, iph->daddr,
175 th->source, th->dest, ntohl(th->seq),
176 jiffies / (HZ * 60), mssind);
177}
178EXPORT_SYMBOL_GPL(__cookie_v4_init_sequence);
183
179
180__u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
181{
182 const struct iphdr *iph = ip_hdr(skb);
183 const struct tcphdr *th = tcp_hdr(skb);
184
185 tcp_synq_overflow(sk);
186 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESSENT);
187
188 return __cookie_v4_init_sequence(iph, th, mssp);
189}
190
184/*
185 * This (misnamed) value is the age of syncookie which is permitted.
186 * Its ideal value should be dependent on TCP_TIMEOUT_INIT and
187 * sysctl_tcp_retries1. It's a rather complicated formula (exponential
188 * backoff) to compute at runtime so it's currently hardcoded here.
189 */
190#define COUNTER_TRIES 4
191/*
192 * Check if a ack sequence number is a valid syncookie.
193 * Return the decoded mss if it is, or 0 if not.
194 */
191/*
192 * This (misnamed) value is the age of syncookie which is permitted.
193 * Its ideal value should be dependent on TCP_TIMEOUT_INIT and
194 * sysctl_tcp_retries1. It's a rather complicated formula (exponential
195 * backoff) to compute at runtime so it's currently hardcoded here.
196 */
197#define COUNTER_TRIES 4
198/*
199 * Check if a ack sequence number is a valid syncookie.
200 * Return the decoded mss if it is, or 0 if not.
201 */
195static inline int cookie_check(struct sk_buff *skb, __u32 cookie)
202int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th,
203 u32 cookie)
196{
204{
197 const struct iphdr *iph = ip_hdr(skb);
198 const struct tcphdr *th = tcp_hdr(skb);
199 __u32 seq = ntohl(th->seq) - 1;
200 __u32 mssind = check_tcp_syn_cookie(cookie, iph->saddr, iph->daddr,
201 th->source, th->dest, seq,
202 jiffies / (HZ * 60),
203 COUNTER_TRIES);
204
205 return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0;
206}
205 __u32 seq = ntohl(th->seq) - 1;
206 __u32 mssind = check_tcp_syn_cookie(cookie, iph->saddr, iph->daddr,
207 th->source, th->dest, seq,
208 jiffies / (HZ * 60),
209 COUNTER_TRIES);
210
211 return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0;
212}
213EXPORT_SYMBOL_GPL(__cookie_v4_check);
207
208static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
209 struct request_sock *req,
210 struct dst_entry *dst)
211{
212 struct inet_connection_sock *icsk = inet_csk(sk);
213 struct sock *child;
214

--- 64 unchanged lines hidden (view full) ---

279 __u8 rcv_wscale;
280 bool ecn_ok = false;
281 struct flowi4 fl4;
282
283 if (!sysctl_tcp_syncookies || !th->ack || th->rst)
284 goto out;
285
286 if (tcp_synq_no_recent_overflow(sk) ||
214
215static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
216 struct request_sock *req,
217 struct dst_entry *dst)
218{
219 struct inet_connection_sock *icsk = inet_csk(sk);
220 struct sock *child;
221

--- 64 unchanged lines hidden (view full) ---

286 __u8 rcv_wscale;
287 bool ecn_ok = false;
288 struct flowi4 fl4;
289
290 if (!sysctl_tcp_syncookies || !th->ack || th->rst)
291 goto out;
292
293 if (tcp_synq_no_recent_overflow(sk) ||
287 (mss = cookie_check(skb, cookie)) == 0) {
294 (mss = __cookie_v4_check(ip_hdr(skb), th, cookie)) == 0) {
288 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED);
289 goto out;
290 }
291
292 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV);
293
294 /* check for timestamp cookie support */
295 memset(&tcp_opt, 0, sizeof(tcp_opt));

--- 85 unchanged lines hidden ---
295 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED);
296 goto out;
297 }
298
299 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV);
300
301 /* check for timestamp cookie support */
302 memset(&tcp_opt, 0, sizeof(tcp_opt));

--- 85 unchanged lines hidden ---