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