OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [net/] [ipv4/] [tcp_timer.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * INET         An implementation of the TCP/IP protocol suite for the LINUX
3
 *              operating system.  INET is implemented using the  BSD Socket
4
 *              interface as the means of communication with the user level.
5
 *
6
 *              Implementation of the Transmission Control Protocol(TCP).
7
 *
8
 * Version:     @(#)tcp.c       1.0.16  05/25/93
9
 *
10
 * Authors:     Ross Biro, <bir7@leland.Stanford.Edu>
11
 *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12
 *              Mark Evans, <evansmp@uhura.aston.ac.uk>
13
 *              Corey Minyard <wf-rch!minyard@relay.EU.net>
14
 *              Florian La Roche, <flla@stud.uni-sb.de>
15
 *              Charles Hedrick, <hedrick@klinzhai.rutgers.edu>
16
 *              Linus Torvalds, <torvalds@cs.helsinki.fi>
17
 *              Alan Cox, <gw4pts@gw4pts.ampr.org>
18
 *              Matthew Dillon, <dillon@apollo.west.oic.com>
19
 *              Arnt Gulbrandsen, <agulbra@nvg.unit.no>
20
 *              Jorge Cwik, <jorge@laser.satlink.net>
21
 *
22
 * Fixes:
23
 *
24
 *              Eric Schenk     : Fix retransmission timeout counting.
25
 */
26
 
27
#include <net/tcp.h>
28
 
29
void tcp_delack_timer(unsigned long data)
30
{
31
        tcp_send_ack((struct sock *) data);
32
}
33
 
34
/*
35
 *      Reset the retransmission timer
36
 */
37
 
38
void tcp_reset_xmit_timer(struct sock *sk, int why, unsigned long when)
39
{
40
        del_timer(&sk->retransmit_timer);
41
        sk->ip_xmit_timeout = why;
42
        if (why == TIME_WRITE) {
43
                /* In this case we want to timeout on the first packet
44
                 * in the resend queue. If the resend queue is empty,
45
                 * then the packet we are sending hasn't made it there yet,
46
                 * so we timeout from the current time.
47
                 */
48
                if (sk->send_head) {
49
                        sk->retransmit_timer.expires =
50
                                sk->send_head->when + when;
51
                } else {
52
                        /* This should never happen!
53
                         */
54
                        printk(KERN_ERR "Error: send_head NULL in xmit_timer\n");
55
                        sk->ip_xmit_timeout = 0;
56
                        return;
57
                }
58
        } else {
59
                sk->retransmit_timer.expires = jiffies+when;
60
        }
61
 
62
        if (sk->retransmit_timer.expires < jiffies) {
63
                /* We can get here if we reset the timer on an event
64
                 * that could not fire because the interrupts were disabled.
65
                 * make sure it happens soon.
66
                 */
67
                sk->retransmit_timer.expires = jiffies+2;
68
        }
69
        add_timer(&sk->retransmit_timer);
70
}
71
 
72
/*
73
 *      POLICY:
74
 *
75
 *      This is the normal code called for timeouts.  It does the retransmission
76
 *      and then does backoff.  tcp_do_retransmit is separated out because
77
 *      tcp_ack needs to send stuff from the retransmit queue without
78
 *      initiating a backoff.
79
 */
80
 
81
 
82
static void tcp_retransmit_time(struct sock *sk, int all)
83
{
84
        /*
85
         * record how many times we've timed out.
86
         * This determines when we should quite trying.
87
         * This needs to be counted here, because we should not be
88
         * counting one per packet we send, but rather one per round
89
         * trip timeout.
90
         */
91
        sk->retransmits++;
92
 
93
        tcp_do_retransmit(sk, all);
94
 
95
        /*
96
         * Increase the timeout each time we retransmit.  Note that
97
         * we do not increase the rtt estimate.  rto is initialized
98
         * from rtt, but increases here.  Jacobson (SIGCOMM 88) suggests
99
         * that doubling rto each time is the least we can get away with.
100
         * In KA9Q, Karn uses this for the first few times, and then
101
         * goes to quadratic.  netBSD doubles, but only goes up to *64,
102
         * and clamps at 1 to 64 sec afterwards.  Note that 120 sec is
103
         * defined in the protocol as the maximum possible RTT.  I guess
104
         * we'll have to use something other than TCP to talk to the
105
         * University of Mars.
106
         *
107
         * PAWS allows us longer timeouts and large windows, so once
108
         * implemented ftp to mars will work nicely. We will have to fix
109
         * the 120 second clamps though!
110
         */
111
 
112
        sk->backoff++;
113
        sk->rto = min(sk->rto << 1, 120*HZ);
114
 
115
        /* be paranoid about the data structure... */
116
        if (sk->send_head)
117
                tcp_reset_xmit_timer(sk, TIME_WRITE, sk->rto);
118
        else
119
                /* This should never happen! */
120
                printk(KERN_ERR "send_head NULL in tcp_retransmit_time\n");
121
}
122
 
123
/*
124
 *      POLICY:
125
 *              Congestion control.
126
 *
127
 *      A timer event has trigger a tcp retransmit timeout. The
128
 *      socket xmit queue is ready and set up to send. Because
129
 *      the ack receive code keeps the queue straight we do
130
 *      nothing clever here.
131
 */
132
 
133
void tcp_retransmit(struct sock *sk, int all)
134
{
135
        if (all)
136
        {
137
                tcp_retransmit_time(sk, all);
138
                return;
139
        }
140
 
141
        /* remember window where we lost */
142
        sk->ssthresh = min(sk->cong_window,
143
                        (sk->window_seq-sk->rcv_ack_seq)/max(sk->mss,1)) >> 1;
144
        /* sk->ssthresh in theory can be zero.  I guess that's OK */
145
        sk->cong_count = 0;
146
        sk->cong_window = 1;
147
 
148
        /* Do the actual retransmit. */
149
        tcp_retransmit_time(sk, all);
150
}
151
 
152
/*
153
 *      A write timeout has occurred. Process the after effects. BROKEN (badly)
154
 */
155
 
156
static int tcp_write_timeout(struct sock *sk)
157
{
158
        /*
159
         *      Look for a 'soft' timeout.
160
         */
161
        if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7))
162
                || (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1))
163
        {
164
                /*
165
                 *      Attempt to recover if arp has changed (unlikely!) or
166
                 *      a route has shifted (not supported prior to 1.3).
167
                 */
168
                ip_rt_advice(&sk->ip_route_cache, 0);
169
        }
170
 
171
        /*
172
         *      Have we tried to SYN too many times (repent repent 8))
173
         *      NOTE: we must be careful to do this test for both
174
         *      the SYN_SENT and SYN_RECV states, otherwise we take
175
         *      23 minutes to timeout on the SYN_RECV state, which
176
         *      leaves us (more) open to denial of service attacks
177
         *      than we would like.
178
         */
179
 
180
        if (sk->retransmits > TCP_SYN_RETRIES
181
        && (sk->state==TCP_SYN_SENT || sk->state==TCP_SYN_RECV))
182
        {
183
                if(sk->err_soft)
184
                        sk->err=sk->err_soft;
185
                else
186
                        sk->err=ETIMEDOUT;
187
                sk->error_report(sk);
188
                del_timer(&sk->retransmit_timer);
189
                tcp_statistics.TcpAttemptFails++;       /* Is this right ??? - FIXME - */
190
                tcp_set_state(sk,TCP_CLOSE);
191
                /* Don't FIN, we got nothing back */
192
                return 0;
193
        }
194
        /*
195
         *      Has it gone just too far ?
196
         */
197
        if (sk->retransmits > TCP_RETR2)
198
        {
199
                if(sk->err_soft)
200
                        sk->err = sk->err_soft;
201
                else
202
                        sk->err = ETIMEDOUT;
203
                sk->error_report(sk);
204
                del_timer(&sk->retransmit_timer);
205
                /*
206
                 *      Time wait the socket
207
                 */
208
                if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 || sk->state == TCP_CLOSING )
209
                {
210
                        tcp_set_state(sk,TCP_TIME_WAIT);
211
                        tcp_reset_msl_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);
212
                }
213
                else
214
                {
215
                        /*
216
                         *      Clean up time.
217
                         */
218
                        tcp_set_state(sk, TCP_CLOSE);
219
                        return 0;
220
                }
221
        }
222
        return 1;
223
}
224
 
225
/*
226
 *      It could be we got here because we needed to send an ack,
227
 *      so we need to check for that and not just normal retransmit.
228
 */
229
static void tcp_time_write_timeout(struct sock * sk)
230
{
231
        /*
232
         *      Retransmission
233
         */
234
        sk->prot->retransmit (sk, 0);
235
        tcp_write_timeout(sk);
236
}
237
 
238
 
239
/*
240
 *      The TCP retransmit timer. This lacks a few small details.
241
 *
242
 *      1.      An initial rtt timeout on the probe0 should cause what we can
243
 *              of the first write queue buffer to be split and sent.
244
 *      2.      On a 'major timeout' as defined by RFC1122 we shouldn't report
245
 *              ETIMEDOUT if we know an additional 'soft' error caused this.
246
 *              tcp_err should save a 'soft error' for us.
247
 */
248
 
249
void tcp_retransmit_timer(unsigned long data)
250
{
251
        struct sock *sk = (struct sock*)data;
252
        int why = sk->ip_xmit_timeout;
253
 
254
        /*
255
         *      We are reset. We will send no more retransmits.
256
         */
257
 
258
        if(sk->zapped)
259
                return;
260
 
261
        /*
262
         *      Only process if socket is not in use
263
         */
264
 
265
        if (sk->users)
266
        {
267
                /* Try again in 1 second */
268
                sk->retransmit_timer.expires = jiffies+HZ;
269
                add_timer(&sk->retransmit_timer);
270
                return;
271
        }
272
 
273
        if (sk->ack_backlog && !sk->dead)
274
                sk->data_ready(sk,0);
275
 
276
        /* Now we need to figure out why the socket was on the timer. */
277
 
278
        switch (why)
279
        {
280
        /* Window probing */
281
        case TIME_PROBE0:
282
                tcp_send_probe0(sk);
283
                tcp_write_timeout(sk);
284
                break;
285
 
286
        /* Retransmitting */
287
        case TIME_WRITE:
288
                tcp_time_write_timeout(sk);
289
                break;
290
 
291
        /* Sending Keepalives */
292
        case TIME_KEEPOPEN:
293
                /*
294
                 * this reset_timer() call is a hack, this is not
295
                 * how KEEPOPEN is supposed to work.
296
                 */
297
                tcp_reset_xmit_timer (sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN);
298
                /* Send something to keep the connection open. */
299
                if (sk->prot->write_wakeup)
300
                          sk->prot->write_wakeup (sk);
301
                sk->retransmits++;
302
                sk->prot->retransmits++;
303
                tcp_write_timeout(sk);
304
                break;
305
 
306
        default:
307
                printk (KERN_ERR "rexmit_timer: timer expired - reason unknown\n");
308
                break;
309
        }
310
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.