]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/ipv6/syncookies.c
inet{6}_request_sock: Init ->opt and ->pktopts in the constructor
[net-next-2.6.git] / net / ipv6 / syncookies.c
index 827c5aa7524c79064065c0aac1aa9c3938314c88..3ecc1157994edf91e64261b0226b371c17800cf6 100644 (file)
@@ -22,7 +22,7 @@
 #include <net/tcp.h>
 
 extern int sysctl_tcp_syncookies;
-extern __u32 syncookie_secret[2][16-3+SHA_DIGEST_WORDS];
+extern __u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS];
 
 #define COOKIEBITS 24  /* Upper bits store count */
 #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
@@ -170,6 +170,7 @@ 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;
@@ -182,6 +183,13 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
 
        NET_INC_STATS_BH(LINUX_MIB_SYNCOOKIESRECV);
 
+       /* check for timestamp cookie support */
+       memset(&tcp_opt, 0, sizeof(tcp_opt));
+       tcp_parse_options(skb, &tcp_opt, 0);
+
+       if (tcp_opt.saw_tstamp)
+               cookie_check_timestamp(&tcp_opt);
+
        ret = NULL;
        req = inet6_reqsk_alloc(&tcp6_request_sock_ops);
        if (!req)
@@ -190,7 +198,6 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
        ireq = inet_rsk(req);
        ireq6 = inet6_rsk(req);
        treq = tcp_rsk(req);
-       ireq6->pktopts = NULL;
 
        if (security_inet_conn_request(sk, skb, req)) {
                reqsk_free(req);
@@ -216,8 +223,12 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
 
        req->expires = 0UL;
        req->retrans = 0;
-       ireq->snd_wscale = ireq->rcv_wscale = ireq->tstamp_ok = 0;
-       ireq->wscale_ok = ireq->sack_ok = 0;
+       ireq->snd_wscale        = tcp_opt.snd_wscale;
+       ireq->rcv_wscale        = tcp_opt.rcv_wscale;
+       ireq->sack_ok           = tcp_opt.sack_ok;
+       ireq->wscale_ok         = tcp_opt.wscale_ok;
+       ireq->tstamp_ok         = tcp_opt.saw_tstamp;
+       req->ts_recent          = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
        treq->rcv_isn = ntohl(th->seq) - 1;
        treq->snt_isn = cookie;
 
@@ -253,10 +264,10 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
                        goto out;
        }
 
-       req->window_clamp = dst_metric(dst, RTAX_WINDOW);
+       req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW);
        tcp_select_initial_window(tcp_full_space(sk), req->mss,
                                  &req->rcv_wnd, &req->window_clamp,
-                                 0, &rcv_wscale);
+                                 ireq->wscale_ok, &rcv_wscale);
 
        ireq->rcv_wscale = rcv_wscale;