[APPLETALK]: Fix potential OOPS in atalk_sendmsg().
[powerpc.git] / net / dccp / timer.c
index 8c396ee..8447742 100644 (file)
@@ -10,7 +10,6 @@
  *     2 of the License, or (at your option) any later version.
  */
 
-#include <linux/config.h>
 #include <linux/dccp.h>
 #include <linux/skbuff.h>
 
@@ -31,7 +30,7 @@ static void dccp_write_err(struct sock *sk)
        sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT;
        sk->sk_error_report(sk);
 
-       dccp_v4_send_reset(sk, DCCP_RESET_CODE_ABORTED);
+       dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED);
        dccp_done(sk);
        DCCP_INC_STATS_BH(DCCP_MIB_ABORTONTIMEOUT);
 }
@@ -45,11 +44,13 @@ static int dccp_write_timeout(struct sock *sk)
        if (sk->sk_state == DCCP_REQUESTING || sk->sk_state == DCCP_PARTOPEN) {
                if (icsk->icsk_retransmits != 0)
                        dst_negative_advice(&sk->sk_dst_cache);
-               retry_until = icsk->icsk_syn_retries ? :  /* FIXME! */ 3 /* FIXME! sysctl_tcp_syn_retries */;
+               retry_until = icsk->icsk_syn_retries ? :
+                           /* FIXME! */ 3 /* FIXME! sysctl_tcp_syn_retries */;
        } else {
-               if (icsk->icsk_retransmits >= /* FIXME! sysctl_tcp_retries1 */ 5 /* FIXME! */) {
-                       /* NOTE. draft-ietf-tcpimpl-pmtud-01.txt requires pmtu black
-                          hole detection. :-(
+               if (icsk->icsk_retransmits >=
+                    /* FIXME! sysctl_tcp_retries1 */ 5 /* FIXME! */) {
+                       /* NOTE. draft-ietf-tcpimpl-pmtud-01.txt requires pmtu
+                          black hole detection. :-(
 
                           It is place to make it. It is not made. I do not want
                           to make it. It is disguisting. It does not work in any
@@ -96,14 +97,17 @@ static void dccp_delack_timer(unsigned long data)
                /* Try again later. */
                icsk->icsk_ack.blocked = 1;
                NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKLOCKED);
-               sk_reset_timer(sk, &icsk->icsk_delack_timer, jiffies + TCP_DELACK_MIN);
+               sk_reset_timer(sk, &icsk->icsk_delack_timer,
+                              jiffies + TCP_DELACK_MIN);
                goto out;
        }
 
-       if (sk->sk_state == DCCP_CLOSED || !(icsk->icsk_ack.pending & ICSK_ACK_TIMER))
+       if (sk->sk_state == DCCP_CLOSED ||
+           !(icsk->icsk_ack.pending & ICSK_ACK_TIMER))
                goto out;
        if (time_after(icsk->icsk_ack.timeout, jiffies)) {
-               sk_reset_timer(sk, &icsk->icsk_delack_timer, icsk->icsk_ack.timeout);
+               sk_reset_timer(sk, &icsk->icsk_delack_timer,
+                              icsk->icsk_ack.timeout);
                goto out;
        }
 
@@ -112,7 +116,8 @@ static void dccp_delack_timer(unsigned long data)
        if (inet_csk_ack_scheduled(sk)) {
                if (!icsk->icsk_ack.pingpong) {
                        /* Delayed ACK missed: inflate ATO. */
-                       icsk->icsk_ack.ato = min(icsk->icsk_ack.ato << 1, icsk->icsk_rto);
+                       icsk->icsk_ack.ato = min(icsk->icsk_ack.ato << 1,
+                                                icsk->icsk_rto);
                } else {
                        /* Delayed ACK missed: leave pingpong mode and
                         * deflate ATO.
@@ -135,10 +140,21 @@ static void dccp_retransmit_timer(struct sock *sk)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
 
+       /* retransmit timer is used for feature negotiation throughout
+        * connection.  In this case, no packet is re-transmitted, but rather an
+        * ack is generated and pending changes are splaced into its options.
+        */
+       if (sk->sk_send_head == NULL) {
+               dccp_pr_debug("feat negotiation retransmit timeout %p\n", sk);
+               if (sk->sk_state == DCCP_OPEN)
+                       dccp_send_ack(sk);
+               goto backoff;
+       }
+
        /*
         * sk->sk_send_head has to have one skb with
         * DCCP_SKB_CB(skb)->dccpd_type set to one of the retransmittable DCCP
-        * packet types (REQUEST, RESPONSE, the ACK in the 3way hanshake
+        * packet types (REQUEST, RESPONSE, the ACK in the 3way handshake
         * (PARTOPEN timer), etc).
         */
        BUG_TRAP(sk->sk_send_head != NULL);
@@ -167,15 +183,17 @@ static void dccp_retransmit_timer(struct sock *sk)
                inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
                                          min(icsk->icsk_rto,
                                              TCP_RESOURCE_PROBE_INTERVAL),
-                                         TCP_RTO_MAX);
+                                         DCCP_RTO_MAX);
                goto out;
        }
 
+backoff:
        icsk->icsk_backoff++;
        icsk->icsk_retransmits++;
 
        icsk->icsk_rto = min(icsk->icsk_rto << 1, DCCP_RTO_MAX);
-       inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX);
+       inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto,
+                                 DCCP_RTO_MAX);
        if (icsk->icsk_retransmits > 3 /* FIXME: sysctl_dccp_retries1 */)
                __sk_dst_reset(sk);
 out:;
@@ -190,7 +208,8 @@ static void dccp_write_timer(unsigned long data)
        bh_lock_sock(sk);
        if (sock_owned_by_user(sk)) {
                /* Try again later */
-               sk_reset_timer(sk, &icsk->icsk_retransmit_timer, jiffies + (HZ / 20));
+               sk_reset_timer(sk, &icsk->icsk_retransmit_timer,
+                              jiffies + (HZ / 20));
                goto out;
        }
 
@@ -198,7 +217,8 @@ static void dccp_write_timer(unsigned long data)
                goto out;
 
        if (time_after(icsk->icsk_timeout, jiffies)) {
-               sk_reset_timer(sk, &icsk->icsk_retransmit_timer, icsk->icsk_timeout);
+               sk_reset_timer(sk, &icsk->icsk_retransmit_timer,
+                              icsk->icsk_timeout);
                goto out;
        }
 
@@ -220,11 +240,8 @@ out:
  */
 static void dccp_response_timer(struct sock *sk)
 {
-       struct inet_connection_sock *icsk = inet_csk(sk);
-       const int max_retries = icsk->icsk_syn_retries ? : TCP_SYNACK_RETRIES /* FIXME sysctl_tcp_synack_retries */;
-
-       reqsk_queue_prune(&icsk->icsk_accept_queue, sk, TCP_SYNQ_INTERVAL,
-                         DCCP_TIMEOUT_INIT, DCCP_RTO_MAX, max_retries);
+       inet_csk_reqsk_queue_prune(sk, TCP_SYNQ_INTERVAL, DCCP_TIMEOUT_INIT,
+                                  DCCP_RTO_MAX);
 }
 
 static void dccp_keepalive_timer(unsigned long data)