TCPCT part 1d: define TCP cookie option, extend existing struct's
[safe/jmp/linux-2.6] / net / ipv6 / tcp_ipv6.c
index 34925f0..f2ec382 100644 (file)
@@ -461,7 +461,8 @@ out:
 }
 
 
-static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req)
+static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
+                             struct request_values *rvp)
 {
        struct inet6_request_sock *treq = inet6_rsk(req);
        struct ipv6_pinfo *np = inet6_sk(sk);
@@ -499,7 +500,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req)
        if ((err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0)
                goto done;
 
-       skb = tcp_make_synack(sk, dst, req);
+       skb = tcp_make_synack(sk, dst, req, rvp);
        if (skb) {
                struct tcphdr *th = tcp_hdr(skb);
 
@@ -1161,13 +1162,13 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
  */
 static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 {
+       struct tcp_options_received tmp_opt;
+       struct request_sock *req;
        struct inet6_request_sock *treq;
        struct ipv6_pinfo *np = inet6_sk(sk);
-       struct tcp_options_received tmp_opt;
        struct tcp_sock *tp = tcp_sk(sk);
-       struct request_sock *req = NULL;
-       __u32 isn = TCP_SKB_CB(skb)->when;
        struct dst_entry *dst = __sk_dst_get(sk);
+       __u32 isn = TCP_SKB_CB(skb)->when;
 #ifdef CONFIG_SYN_COOKIES
        int want_cookie = 0;
 #else
@@ -1239,23 +1240,19 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 
                isn = tcp_v6_init_sequence(skb);
        }
-
        tcp_rsk(req)->snt_isn = isn;
 
        security_inet_conn_request(sk, skb, req);
 
-       if (tcp_v6_send_synack(sk, req))
-               goto drop;
+       if (tcp_v6_send_synack(sk, req, NULL) || want_cookie)
+               goto drop_and_free;
 
-       if (!want_cookie) {
-               inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
-               return 0;
-       }
+       inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
+       return 0;
 
+drop_and_free:
+       reqsk_free(req);
 drop:
-       if (req)
-               reqsk_free(req);
-
        return 0; /* don't send reset */
 }
 
@@ -1851,7 +1848,7 @@ static int tcp_v6_init_sock(struct sock *sk)
         */
        tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
        tp->snd_cwnd_clamp = ~0;
-       tp->mss_cache = 536;
+       tp->mss_cache = TCP_MSS_DEFAULT;
 
        tp->reordering = sysctl_tcp_reordering;
 
@@ -1867,6 +1864,19 @@ static int tcp_v6_init_sock(struct sock *sk)
        tp->af_specific = &tcp_sock_ipv6_specific;
 #endif
 
+       /* TCP Cookie Transactions */
+       if (sysctl_tcp_cookie_size > 0) {
+               /* Default, cookies without s_data_payload. */
+               tp->cookie_values =
+                       kzalloc(sizeof(*tp->cookie_values),
+                               sk->sk_allocation);
+               if (tp->cookie_values != NULL)
+                       kref_init(&tp->cookie_values->kref);
+       }
+       /* Presumed zeroed, in order of appearance:
+        *      cookie_in_always, cookie_out_never,
+        *      s_data_constant, s_data_in, s_data_out
+        */
        sk->sk_sndbuf = sysctl_tcp_wmem[1];
        sk->sk_rcvbuf = sysctl_tcp_rmem[1];
 
@@ -2112,7 +2122,6 @@ static struct inet_protosw tcpv6_protosw = {
        .protocol       =       IPPROTO_TCP,
        .prot           =       &tcpv6_prot,
        .ops            =       &inet6_stream_ops,
-       .capability     =       -1,
        .no_check       =       0,
        .flags          =       INET_PROTOSW_PERMANENT |
                                INET_PROTOSW_ICSK,