[DCCP]: Initial implementation
[safe/jmp/linux-2.6] / net / dccp / timer.c
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/config.h>
14 #include <linux/dccp.h>
15 #include <linux/skbuff.h>
16
17 #include "dccp.h"
18
19 static void dccp_write_timer(unsigned long data);
20 static void dccp_keepalive_timer(unsigned long data);
21 static void dccp_delack_timer(unsigned long data);
22
23 void dccp_init_xmit_timers(struct sock *sk)
24 {
25         inet_csk_init_xmit_timers(sk, &dccp_write_timer, &dccp_delack_timer,
26                                   &dccp_keepalive_timer);
27 }
28
29 static void dccp_write_err(struct sock *sk)
30 {
31         sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT;
32         sk->sk_error_report(sk);
33
34         dccp_v4_send_reset(sk, DCCP_RESET_CODE_ABORTED);
35         dccp_done(sk);
36         DCCP_INC_STATS_BH(DCCP_MIB_ABORTONTIMEOUT);
37 }
38
39 /* A write timeout has occurred. Process the after effects. */
40 static int dccp_write_timeout(struct sock *sk)
41 {
42         const struct inet_connection_sock *icsk = inet_csk(sk);
43         int retry_until;
44
45         if (sk->sk_state == DCCP_REQUESTING || sk->sk_state == DCCP_PARTOPEN) {
46                 if (icsk->icsk_retransmits != 0)
47                         dst_negative_advice(&sk->sk_dst_cache);
48                 retry_until = icsk->icsk_syn_retries ? :  /* FIXME! */ 3 /* FIXME! sysctl_tcp_syn_retries */;
49         } else {
50                 if (icsk->icsk_retransmits >= /* FIXME! sysctl_tcp_retries1 */ 5 /* FIXME! */) {
51                         /* NOTE. draft-ietf-tcpimpl-pmtud-01.txt requires pmtu black
52                            hole detection. :-(
53
54                            It is place to make it. It is not made. I do not want
55                            to make it. It is disguisting. It does not work in any
56                            case. Let me to cite the same draft, which requires for
57                            us to implement this:
58
59    "The one security concern raised by this memo is that ICMP black holes
60    are often caused by over-zealous security administrators who block
61    all ICMP messages.  It is vitally important that those who design and
62    deploy security systems understand the impact of strict filtering on
63    upper-layer protocols.  The safest web site in the world is worthless
64    if most TCP implementations cannot transfer data from it.  It would
65    be far nicer to have all of the black holes fixed rather than fixing
66    all of the TCP implementations."
67
68                            Golden words :-).
69                    */
70
71                         dst_negative_advice(&sk->sk_dst_cache);
72                 }
73
74                 retry_until = /* FIXME! */ 15 /* FIXME! sysctl_tcp_retries2 */;
75                 /*
76                  * FIXME: see tcp_write_timout and tcp_out_of_resources
77                  */
78         }
79
80         if (icsk->icsk_retransmits >= retry_until) {
81                 /* Has it gone just too far? */
82                 dccp_write_err(sk);
83                 return 1;
84         }
85         return 0;
86 }
87
88 /* This is the same as tcp_delack_timer, sans prequeue & mem_reclaim stuff */
89 static void dccp_delack_timer(unsigned long data)
90 {
91         struct sock *sk = (struct sock *)data;
92         struct inet_connection_sock *icsk = inet_csk(sk);
93
94         bh_lock_sock(sk);
95         if (sock_owned_by_user(sk)) {
96                 /* Try again later. */
97                 icsk->icsk_ack.blocked = 1;
98                 NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKLOCKED);
99                 sk_reset_timer(sk, &icsk->icsk_delack_timer, jiffies + TCP_DELACK_MIN);
100                 goto out;
101         }
102
103         if (sk->sk_state == DCCP_CLOSED || !(icsk->icsk_ack.pending & ICSK_ACK_TIMER))
104                 goto out;
105         if (time_after(icsk->icsk_ack.timeout, jiffies)) {
106                 sk_reset_timer(sk, &icsk->icsk_delack_timer, icsk->icsk_ack.timeout);
107                 goto out;
108         }
109
110         icsk->icsk_ack.pending &= ~ICSK_ACK_TIMER;
111
112         if (inet_csk_ack_scheduled(sk)) {
113                 if (!icsk->icsk_ack.pingpong) {
114                         /* Delayed ACK missed: inflate ATO. */
115                         icsk->icsk_ack.ato = min(icsk->icsk_ack.ato << 1, icsk->icsk_rto);
116                 } else {
117                         /* Delayed ACK missed: leave pingpong mode and
118                          * deflate ATO.
119                          */
120                         icsk->icsk_ack.pingpong = 0;
121                         icsk->icsk_ack.ato = TCP_ATO_MIN;
122                 }
123                 dccp_send_ack(sk);
124                 NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKS);
125         }
126 out:
127         bh_unlock_sock(sk);
128         sock_put(sk);
129 }
130
131 /*
132  *      The DCCP retransmit timer.
133  */
134 static void dccp_retransmit_timer(struct sock *sk)
135 {
136         struct inet_connection_sock *icsk = inet_csk(sk);
137
138         /*
139          * sk->sk_send_head has to have one skb with
140          * DCCP_SKB_CB(skb)->dccpd_type set to one of the retransmittable DCCP
141          * packet types (REQUEST, RESPONSE, the ACK in the 3way hanshake
142          * (PARTOPEN timer), etc).
143          */
144         BUG_TRAP(sk->sk_send_head != NULL);
145
146         /* 
147          * More than than 4MSL (8 minutes) has passed, a RESET(aborted) was
148          * sent, no need to retransmit, this sock is dead.
149          */
150         if (dccp_write_timeout(sk))
151                 goto out;
152
153         /*
154          * We want to know the number of packets retransmitted, not the
155          * total number of retransmissions of clones of original packets.
156          */
157         if (icsk->icsk_retransmits == 0)
158                 DCCP_INC_STATS_BH(DCCP_MIB_TIMEOUTS);
159
160         if (dccp_retransmit_skb(sk, sk->sk_send_head) < 0) {
161                 /*
162                  * Retransmission failed because of local congestion,
163                  * do not backoff.
164                  */
165                 if (icsk->icsk_retransmits == 0)
166                         icsk->icsk_retransmits = 1;
167                 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
168                                           min(icsk->icsk_rto,
169                                               TCP_RESOURCE_PROBE_INTERVAL),
170                                           TCP_RTO_MAX);
171                 goto out;
172         }
173
174         icsk->icsk_backoff++;
175         icsk->icsk_retransmits++;
176
177         icsk->icsk_rto = min(icsk->icsk_rto << 1, DCCP_RTO_MAX);
178         inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX);
179         if (icsk->icsk_retransmits > 3 /* FIXME: sysctl_dccp_retries1 */)
180                 __sk_dst_reset(sk);
181 out:;
182 }
183
184 static void dccp_write_timer(unsigned long data)
185 {
186         struct sock *sk = (struct sock *)data;
187         struct inet_connection_sock *icsk = inet_csk(sk);
188         int event = 0;
189
190         bh_lock_sock(sk);
191         if (sock_owned_by_user(sk)) {
192                 /* Try again later */
193                 sk_reset_timer(sk, &icsk->icsk_retransmit_timer, jiffies + (HZ / 20));
194                 goto out;
195         }
196
197         if (sk->sk_state == DCCP_CLOSED || !icsk->icsk_pending)
198                 goto out;
199
200         if (time_after(icsk->icsk_timeout, jiffies)) {
201                 sk_reset_timer(sk, &icsk->icsk_retransmit_timer, icsk->icsk_timeout);
202                 goto out;
203         }
204
205         event = icsk->icsk_pending;
206         icsk->icsk_pending = 0;
207
208         switch (event) {
209         case ICSK_TIME_RETRANS:
210                 dccp_retransmit_timer(sk);
211                 break;
212         }
213 out:
214         bh_unlock_sock(sk);
215         sock_put(sk);
216 }
217
218 /*
219  *      Timer for listening sockets
220  */
221 static void dccp_response_timer(struct sock *sk)
222 {
223         struct inet_connection_sock *icsk = inet_csk(sk);
224         const int max_retries = icsk->icsk_syn_retries ? : TCP_SYNACK_RETRIES /* FIXME sysctl_tcp_synack_retries */;
225
226         reqsk_queue_prune(&icsk->icsk_accept_queue, sk, TCP_SYNQ_INTERVAL,
227                           DCCP_TIMEOUT_INIT, DCCP_RTO_MAX, max_retries);
228 }
229
230 static void dccp_keepalive_timer(unsigned long data)
231 {
232         struct sock *sk = (struct sock *)data;
233
234         /* Only process if socket is not in use. */
235         bh_lock_sock(sk);
236         if (sock_owned_by_user(sk)) {
237                 /* Try again later. */ 
238                 inet_csk_reset_keepalive_timer(sk, HZ / 20);
239                 goto out;
240         }
241
242         if (sk->sk_state == DCCP_LISTEN) {
243                 dccp_response_timer(sk);
244                 goto out;
245         }
246 out:
247         bh_unlock_sock(sk);
248         sock_put(sk);
249 }