linux/net/dccp/timer.c
<<
>>
Prefs
   1/*
   2 *  net/dccp/timer.c
   3 *
   4 *  An implementation of the DCCP protocol
   5 *  Arnaldo Carvalho de Melo <acme@conectiva.com.br>
   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
   9 *      as published by the Free Software Foundation; either version
  10 *      2 of the License, or (at your option) any later version.
  11 */
  12
  13#include <linux/dccp.h>
  14#include <linux/skbuff.h>
  15
  16#include "dccp.h"
  17
  18/* sysctl variables governing numbers of retransmission attempts */
  19int  sysctl_dccp_request_retries        __read_mostly = TCP_SYN_RETRIES;
  20int  sysctl_dccp_retries1               __read_mostly = TCP_RETR1;
  21int  sysctl_dccp_retries2               __read_mostly = TCP_RETR2;
  22
  23static void dccp_write_err(struct sock *sk)
  24{
  25        sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT;
  26        sk->sk_error_report(sk);
  27
  28        dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED);
  29        dccp_done(sk);
  30        DCCP_INC_STATS_BH(DCCP_MIB_ABORTONTIMEOUT);
  31}
  32
  33/* A write timeout has occurred. Process the after effects. */
  34static int dccp_write_timeout(struct sock *sk)
  35{
  36        const struct inet_connection_sock *icsk = inet_csk(sk);
  37        int retry_until;
  38
  39        if (sk->sk_state == DCCP_REQUESTING || sk->sk_state == DCCP_PARTOPEN) {
  40                if (icsk->icsk_retransmits != 0)
  41                        dst_negative_advice(&sk->sk_dst_cache);
  42                retry_until = icsk->icsk_syn_retries ?
  43                            : sysctl_dccp_request_retries;
  44        } else {
  45                if (icsk->icsk_retransmits >= sysctl_dccp_retries1) {
  46                        /* NOTE. draft-ietf-tcpimpl-pmtud-01.txt requires pmtu
  47                           black hole detection. :-(
  48
  49                           It is place to make it. It is not made. I do not want
  50                           to make it. It is disguisting. It does not work in any
  51                           case. Let me to cite the same draft, which requires for
  52                           us to implement this:
  53
  54   "The one security concern raised by this memo is that ICMP black holes
  55   are often caused by over-zealous security administrators who block
  56   all ICMP messages.  It is vitally important that those who design and
  57   deploy security systems understand the impact of strict filtering on
  58   upper-layer protocols.  The safest web site in the world is worthless
  59   if most TCP implementations cannot transfer data from it.  It would
  60   be far nicer to have all of the black holes fixed rather than fixing
  61   all of the TCP implementations."
  62
  63                           Golden words :-).
  64                   */
  65
  66                        dst_negative_advice(&sk->sk_dst_cache);
  67                }
  68
  69                retry_until = sysctl_dccp_retries2;
  70                /*
  71                 * FIXME: see tcp_write_timout and tcp_out_of_resources
  72                 */
  73        }
  74
  75        if (icsk->icsk_retransmits >= retry_until) {
  76                /* Has it gone just too far? */
  77                dccp_write_err(sk);
  78                return 1;
  79        }
  80        return 0;
  81}
  82
  83/*
  84 *      The DCCP retransmit timer.
  85 */
  86static void dccp_retransmit_timer(struct sock *sk)
  87{
  88        struct inet_connection_sock *icsk = inet_csk(sk);
  89
  90        /* retransmit timer is used for feature negotiation throughout
  91         * connection.  In this case, no packet is re-transmitted, but rather an
  92         * ack is generated and pending changes are placed into its options.
  93         */
  94        if (sk->sk_send_head == NULL) {
  95                dccp_pr_debug("feat negotiation retransmit timeout %p\n", sk);
  96                if (sk->sk_state == DCCP_OPEN)
  97                        dccp_send_ack(sk);
  98                goto backoff;
  99        }
 100
 101        /*
 102         * sk->sk_send_head has to have one skb with
 103         * DCCP_SKB_CB(skb)->dccpd_type set to one of the retransmittable DCCP
 104         * packet types. The only packets eligible for retransmission are:
 105         *      -- Requests in client-REQUEST  state (sec. 8.1.1)
 106         *      -- Acks     in client-PARTOPEN state (sec. 8.1.5)
 107         *      -- CloseReq in server-CLOSEREQ state (sec. 8.3)
 108         *      -- Close    in   node-CLOSING  state (sec. 8.3)                */
 109        BUG_TRAP(sk->sk_send_head != NULL);
 110
 111        /*
 112         * More than than 4MSL (8 minutes) has passed, a RESET(aborted) was
 113         * sent, no need to retransmit, this sock is dead.
 114         */
 115        if (dccp_write_timeout(sk))
 116                goto out;
 117
 118        /*
 119         * We want to know the number of packets retransmitted, not the
 120         * total number of retransmissions of clones of original packets.
 121         */
 122        if (icsk->icsk_retransmits == 0)
 123                DCCP_INC_STATS_BH(DCCP_MIB_TIMEOUTS);
 124
 125        if (dccp_retransmit_skb(sk, sk->sk_send_head) < 0) {
 126                /*
 127                 * Retransmission failed because of local congestion,
 128                 * do not backoff.
 129                 */
 130                if (icsk->icsk_retransmits == 0)
 131                        icsk->icsk_retransmits = 1;
 132                inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
 133                                          min(icsk->icsk_rto,
 134                                              TCP_RESOURCE_PROBE_INTERVAL),
 135                                          DCCP_RTO_MAX);
 136                goto out;
 137        }
 138
 139backoff:
 140        icsk->icsk_backoff++;
 141        icsk->icsk_retransmits++;
 142
 143        icsk->icsk_rto = min(icsk->icsk_rto << 1, DCCP_RTO_MAX);
 144        inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto,
 145                                  DCCP_RTO_MAX);
 146        if (icsk->icsk_retransmits > sysctl_dccp_retries1)
 147                __sk_dst_reset(sk);
 148out:;
 149}
 150
 151static void dccp_write_timer(unsigned long data)
 152{
 153        struct sock *sk = (struct sock *)data;
 154        struct inet_connection_sock *icsk = inet_csk(sk);
 155        int event = 0;
 156
 157        bh_lock_sock(sk);
 158        if (sock_owned_by_user(sk)) {
 159                /* Try again later */
 160                sk_reset_timer(sk, &icsk->icsk_retransmit_timer,
 161                               jiffies + (HZ / 20));
 162                goto out;
 163        }
 164
 165        if (sk->sk_state == DCCP_CLOSED || !icsk->icsk_pending)
 166                goto out;
 167
 168        if (time_after(icsk->icsk_timeout, jiffies)) {
 169                sk_reset_timer(sk, &icsk->icsk_retransmit_timer,
 170                               icsk->icsk_timeout);
 171                goto out;
 172        }
 173
 174        event = icsk->icsk_pending;
 175        icsk->icsk_pending = 0;
 176
 177        switch (event) {
 178        case ICSK_TIME_RETRANS:
 179                dccp_retransmit_timer(sk);
 180                break;
 181        }
 182out:
 183        bh_unlock_sock(sk);
 184        sock_put(sk);
 185}
 186
 187/*
 188 *      Timer for listening sockets
 189 */
 190static void dccp_response_timer(struct sock *sk)
 191{
 192        inet_csk_reqsk_queue_prune(sk, TCP_SYNQ_INTERVAL, DCCP_TIMEOUT_INIT,
 193                                   DCCP_RTO_MAX);
 194}
 195
 196static void dccp_keepalive_timer(unsigned long data)
 197{
 198        struct sock *sk = (struct sock *)data;
 199
 200        /* Only process if socket is not in use. */
 201        bh_lock_sock(sk);
 202        if (sock_owned_by_user(sk)) {
 203                /* Try again later. */
 204                inet_csk_reset_keepalive_timer(sk, HZ / 20);
 205                goto out;
 206        }
 207
 208        if (sk->sk_state == DCCP_LISTEN) {
 209                dccp_response_timer(sk);
 210                goto out;
 211        }
 212out:
 213        bh_unlock_sock(sk);
 214        sock_put(sk);
 215}
 216
 217/* This is the same as tcp_delack_timer, sans prequeue & mem_reclaim stuff */
 218static void dccp_delack_timer(unsigned long data)
 219{
 220        struct sock *sk = (struct sock *)data;
 221        struct inet_connection_sock *icsk = inet_csk(sk);
 222
 223        bh_lock_sock(sk);
 224        if (sock_owned_by_user(sk)) {
 225                /* Try again later. */
 226                icsk->icsk_ack.blocked = 1;
 227                NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKLOCKED);
 228                sk_reset_timer(sk, &icsk->icsk_delack_timer,
 229                               jiffies + TCP_DELACK_MIN);
 230                goto out;
 231        }
 232
 233        if (sk->sk_state == DCCP_CLOSED ||
 234            !(icsk->icsk_ack.pending & ICSK_ACK_TIMER))
 235                goto out;
 236        if (time_after(icsk->icsk_ack.timeout, jiffies)) {
 237                sk_reset_timer(sk, &icsk->icsk_delack_timer,
 238                               icsk->icsk_ack.timeout);
 239                goto out;
 240        }
 241
 242        icsk->icsk_ack.pending &= ~ICSK_ACK_TIMER;
 243
 244        if (inet_csk_ack_scheduled(sk)) {
 245                if (!icsk->icsk_ack.pingpong) {
 246                        /* Delayed ACK missed: inflate ATO. */
 247                        icsk->icsk_ack.ato = min(icsk->icsk_ack.ato << 1,
 248                                                 icsk->icsk_rto);
 249                } else {
 250                        /* Delayed ACK missed: leave pingpong mode and
 251                         * deflate ATO.
 252                         */
 253                        icsk->icsk_ack.pingpong = 0;
 254                        icsk->icsk_ack.ato = TCP_ATO_MIN;
 255                }
 256                dccp_send_ack(sk);
 257                NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKS);
 258        }
 259out:
 260        bh_unlock_sock(sk);
 261        sock_put(sk);
 262}
 263
 264/* Transmit-delay timer: used by the CCIDs to delay actual send time */
 265static void dccp_write_xmit_timer(unsigned long data)
 266{
 267        struct sock *sk = (struct sock *)data;
 268        struct dccp_sock *dp = dccp_sk(sk);
 269
 270        bh_lock_sock(sk);
 271        if (sock_owned_by_user(sk))
 272                sk_reset_timer(sk, &dp->dccps_xmit_timer, jiffies+1);
 273        else
 274                dccp_write_xmit(sk, 0);
 275        bh_unlock_sock(sk);
 276        sock_put(sk);
 277}
 278
 279static void dccp_init_write_xmit_timer(struct sock *sk)
 280{
 281        struct dccp_sock *dp = dccp_sk(sk);
 282
 283        init_timer(&dp->dccps_xmit_timer);
 284        dp->dccps_xmit_timer.data = (unsigned long)sk;
 285        dp->dccps_xmit_timer.function = dccp_write_xmit_timer;
 286}
 287
 288void dccp_init_xmit_timers(struct sock *sk)
 289{
 290        dccp_init_write_xmit_timer(sk);
 291        inet_csk_init_xmit_timers(sk, &dccp_write_timer, &dccp_delack_timer,
 292                                  &dccp_keepalive_timer);
 293}
 294
 295static ktime_t dccp_timestamp_seed;
 296/**
 297 * dccp_timestamp  -  10s of microseconds time source
 298 * Returns the number of 10s of microseconds since loading DCCP. This is native
 299 * DCCP time difference format (RFC 4340, sec. 13).
 300 * Please note: This will wrap around about circa every 11.9 hours.
 301 */
 302u32 dccp_timestamp(void)
 303{
 304        s64 delta = ktime_us_delta(ktime_get_real(), dccp_timestamp_seed);
 305
 306        do_div(delta, 10);
 307        return delta;
 308}
 309EXPORT_SYMBOL_GPL(dccp_timestamp);
 310
 311void __init dccp_timestamping_init(void)
 312{
 313        dccp_timestamp_seed = ktime_get_real();
 314}
 315