aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/timer.c')
-rw-r--r--net/dccp/timer.c134
1 files changed, 68 insertions, 66 deletions
diff --git a/net/dccp/timer.c b/net/dccp/timer.c
index 8447742f5615..e8f519e7f481 100644
--- a/net/dccp/timer.c
+++ b/net/dccp/timer.c
@@ -15,15 +15,10 @@
15 15
16#include "dccp.h" 16#include "dccp.h"
17 17
18static void dccp_write_timer(unsigned long data); 18/* sysctl variables governing numbers of retransmission attempts */
19static void dccp_keepalive_timer(unsigned long data); 19int sysctl_dccp_request_retries __read_mostly = TCP_SYN_RETRIES;
20static void dccp_delack_timer(unsigned long data); 20int sysctl_dccp_retries1 __read_mostly = TCP_RETR1;
21 21int sysctl_dccp_retries2 __read_mostly = TCP_RETR2;
22void dccp_init_xmit_timers(struct sock *sk)
23{
24 inet_csk_init_xmit_timers(sk, &dccp_write_timer, &dccp_delack_timer,
25 &dccp_keepalive_timer);
26}
27 22
28static void dccp_write_err(struct sock *sk) 23static void dccp_write_err(struct sock *sk)
29{ 24{
@@ -44,11 +39,10 @@ static int dccp_write_timeout(struct sock *sk)
44 if (sk->sk_state == DCCP_REQUESTING || sk->sk_state == DCCP_PARTOPEN) { 39 if (sk->sk_state == DCCP_REQUESTING || sk->sk_state == DCCP_PARTOPEN) {
45 if (icsk->icsk_retransmits != 0) 40 if (icsk->icsk_retransmits != 0)
46 dst_negative_advice(&sk->sk_dst_cache); 41 dst_negative_advice(&sk->sk_dst_cache);
47 retry_until = icsk->icsk_syn_retries ? : 42 retry_until = icsk->icsk_syn_retries ?
48 /* FIXME! */ 3 /* FIXME! sysctl_tcp_syn_retries */; 43 : sysctl_dccp_request_retries;
49 } else { 44 } else {
50 if (icsk->icsk_retransmits >= 45 if (icsk->icsk_retransmits >= sysctl_dccp_retries1) {
51 /* FIXME! sysctl_tcp_retries1 */ 5 /* FIXME! */) {
52 /* NOTE. draft-ietf-tcpimpl-pmtud-01.txt requires pmtu 46 /* NOTE. draft-ietf-tcpimpl-pmtud-01.txt requires pmtu
53 black hole detection. :-( 47 black hole detection. :-(
54 48
@@ -72,7 +66,7 @@ static int dccp_write_timeout(struct sock *sk)
72 dst_negative_advice(&sk->sk_dst_cache); 66 dst_negative_advice(&sk->sk_dst_cache);
73 } 67 }
74 68
75 retry_until = /* FIXME! */ 15 /* FIXME! sysctl_tcp_retries2 */; 69 retry_until = sysctl_dccp_retries2;
76 /* 70 /*
77 * FIXME: see tcp_write_timout and tcp_out_of_resources 71 * FIXME: see tcp_write_timout and tcp_out_of_resources
78 */ 72 */
@@ -86,53 +80,6 @@ static int dccp_write_timeout(struct sock *sk)
86 return 0; 80 return 0;
87} 81}
88 82
89/* This is the same as tcp_delack_timer, sans prequeue & mem_reclaim stuff */
90static void dccp_delack_timer(unsigned long data)
91{
92 struct sock *sk = (struct sock *)data;
93 struct inet_connection_sock *icsk = inet_csk(sk);
94
95 bh_lock_sock(sk);
96 if (sock_owned_by_user(sk)) {
97 /* Try again later. */
98 icsk->icsk_ack.blocked = 1;
99 NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKLOCKED);
100 sk_reset_timer(sk, &icsk->icsk_delack_timer,
101 jiffies + TCP_DELACK_MIN);
102 goto out;
103 }
104
105 if (sk->sk_state == DCCP_CLOSED ||
106 !(icsk->icsk_ack.pending & ICSK_ACK_TIMER))
107 goto out;
108 if (time_after(icsk->icsk_ack.timeout, jiffies)) {
109 sk_reset_timer(sk, &icsk->icsk_delack_timer,
110 icsk->icsk_ack.timeout);
111 goto out;
112 }
113
114 icsk->icsk_ack.pending &= ~ICSK_ACK_TIMER;
115
116 if (inet_csk_ack_scheduled(sk)) {
117 if (!icsk->icsk_ack.pingpong) {
118 /* Delayed ACK missed: inflate ATO. */
119 icsk->icsk_ack.ato = min(icsk->icsk_ack.ato << 1,
120 icsk->icsk_rto);
121 } else {
122 /* Delayed ACK missed: leave pingpong mode and
123 * deflate ATO.
124 */
125 icsk->icsk_ack.pingpong = 0;
126 icsk->icsk_ack.ato = TCP_ATO_MIN;
127 }
128 dccp_send_ack(sk);
129 NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKS);
130 }
131out:
132 bh_unlock_sock(sk);
133 sock_put(sk);
134}
135
136/* 83/*
137 * The DCCP retransmit timer. 84 * The DCCP retransmit timer.
138 */ 85 */
@@ -142,7 +89,7 @@ static void dccp_retransmit_timer(struct sock *sk)
142 89
143 /* retransmit timer is used for feature negotiation throughout 90 /* retransmit timer is used for feature negotiation throughout
144 * connection. In this case, no packet is re-transmitted, but rather an 91 * connection. In this case, no packet is re-transmitted, but rather an
145 * ack is generated and pending changes are splaced into its options. 92 * ack is generated and pending changes are placed into its options.
146 */ 93 */
147 if (sk->sk_send_head == NULL) { 94 if (sk->sk_send_head == NULL) {
148 dccp_pr_debug("feat negotiation retransmit timeout %p\n", sk); 95 dccp_pr_debug("feat negotiation retransmit timeout %p\n", sk);
@@ -154,9 +101,11 @@ static void dccp_retransmit_timer(struct sock *sk)
154 /* 101 /*
155 * sk->sk_send_head has to have one skb with 102 * sk->sk_send_head has to have one skb with
156 * DCCP_SKB_CB(skb)->dccpd_type set to one of the retransmittable DCCP 103 * DCCP_SKB_CB(skb)->dccpd_type set to one of the retransmittable DCCP
157 * packet types (REQUEST, RESPONSE, the ACK in the 3way handshake 104 * packet types. The only packets eligible for retransmission are:
158 * (PARTOPEN timer), etc). 105 * -- Requests in client-REQUEST state (sec. 8.1.1)
159 */ 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) */
160 BUG_TRAP(sk->sk_send_head != NULL); 109 BUG_TRAP(sk->sk_send_head != NULL);
161 110
162 /* 111 /*
@@ -194,7 +143,7 @@ backoff:
194 icsk->icsk_rto = min(icsk->icsk_rto << 1, DCCP_RTO_MAX); 143 icsk->icsk_rto = min(icsk->icsk_rto << 1, DCCP_RTO_MAX);
195 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, 144 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto,
196 DCCP_RTO_MAX); 145 DCCP_RTO_MAX);
197 if (icsk->icsk_retransmits > 3 /* FIXME: sysctl_dccp_retries1 */) 146 if (icsk->icsk_retransmits > sysctl_dccp_retries1)
198 __sk_dst_reset(sk); 147 __sk_dst_reset(sk);
199out:; 148out:;
200} 149}
@@ -264,3 +213,56 @@ out:
264 bh_unlock_sock(sk); 213 bh_unlock_sock(sk);
265 sock_put(sk); 214 sock_put(sk);
266} 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
264void dccp_init_xmit_timers(struct sock *sk)
265{
266 inet_csk_init_xmit_timers(sk, &dccp_write_timer, &dccp_delack_timer,
267 &dccp_keepalive_timer);
268}