Merge davem@outer-richmond.davemloft.net:src/GIT/net-2.6/
[pandora-kernel.git] / net / dccp / ipv4.c
index cc5d60d..2afaa46 100644 (file)
@@ -309,6 +309,16 @@ static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
                                                            usin->sin_port);
        dccp_update_gss(sk, dp->dccps_iss);
 
+       /*
+        * SWL and AWL are initially adjusted so that they are not less than
+        * the initial Sequence Numbers received and sent, respectively:
+        *      SWL := max(GSR + 1 - floor(W/4), ISR),
+        *      AWL := max(GSS - W' + 1, ISS).
+        * These adjustments MUST be applied only at the beginning of the
+        * connection.
+        */
+       dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));
+
        inet->id = dp->dccps_iss ^ jiffies;
 
        err = dccp_connect(sk);
@@ -631,16 +641,12 @@ int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code)
 
        skb = dccp_make_reset(sk, sk->sk_dst_cache, code);
        if (skb != NULL) {
-               const struct dccp_sock *dp = dccp_sk(sk);
                const struct inet_sock *inet = inet_sk(sk);
 
                err = ip_build_and_send_pkt(skb, sk,
                                            inet->saddr, inet->daddr, NULL);
                if (err == NET_XMIT_CN)
                        err = 0;
-
-               ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk);
-               ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk);
        }
 
        return err;
@@ -887,6 +893,7 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
                                       sizeof(struct dccp_hdr_reset);
        struct sk_buff *skb;
        struct dst_entry *dst;
+       u64 seqno;
 
        /* Never send a reset in response to a reset. */
        if (rxdh->dccph_type == DCCP_PKT_RESET)
@@ -920,7 +927,12 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
        dccp_hdr_reset(skb)->dccph_reset_code =
                                DCCP_SKB_CB(rxskb)->dccpd_reset_code;
 
-       dccp_hdr_set_seq(dh, DCCP_SKB_CB(rxskb)->dccpd_ack_seq);
+       /* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */
+       seqno = 0;
+       if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
+               dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1);
+
+       dccp_hdr_set_seq(dh, seqno);
        dccp_hdr_set_ack(dccp_hdr_ack_bits(skb),
                         DCCP_SKB_CB(rxskb)->dccpd_seq);
 
@@ -1227,6 +1239,7 @@ static int dccp_v4_init_sock(struct sock *sk)
        static int dccp_ctl_socket_init = 1;
 
        dccp_options_init(&dp->dccps_options);
+       do_gettimeofday(&dp->dccps_epoch);
 
        if (dp->dccps_options.dccpo_send_ack_vector) {
                dp->dccps_hc_rx_ackpkts =
@@ -1264,6 +1277,7 @@ static int dccp_v4_init_sock(struct sock *sk)
        dccp_init_xmit_timers(sk);
        inet_csk(sk)->icsk_rto = DCCP_TIMEOUT_INIT;
        sk->sk_state = DCCP_CLOSED;
+       sk->sk_write_space = dccp_write_space;
        dp->dccps_mss_cache = 536;
        dp->dccps_role = DCCP_ROLE_UNDEFINED;
 
@@ -1287,6 +1301,8 @@ static int dccp_v4_destroy_sock(struct sock *sk)
        if (inet_csk(sk)->icsk_bind_hash != NULL)
                inet_put_port(&dccp_hashinfo, sk);
 
+       ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk);
+       ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk);
        dccp_ackpkts_free(dp->dccps_hc_rx_ackpkts);
        dp->dccps_hc_rx_ackpkts = NULL;
        ccid_exit(dp->dccps_hc_rx_ccid, sk);