Commit | Line | Data |
---|---|---|
37de812c | 1 | /* tcp_timer.c 4.8 81/12/19 */ |
f03530e6 BJ |
2 | |
3 | #include "../h/param.h" | |
4 | #include "../h/systm.h" | |
5 | #include "../h/mbuf.h" | |
6 | #include "../h/socket.h" | |
7 | #include "../h/socketvar.h" | |
8 | #include "../h/protosw.h" | |
0974b45c BJ |
9 | #include "../net/in.h" |
10 | #include "../net/in_pcb.h" | |
11 | #include "../net/in_systm.h" | |
f03530e6 | 12 | #include "../net/if.h" |
f03530e6 BJ |
13 | #include "../net/ip.h" |
14 | #include "../net/ip_var.h" | |
15 | #include "../net/tcp.h" | |
16 | #include "../net/tcp_fsm.h" | |
0974b45c BJ |
17 | #include "../net/tcp_seq.h" |
18 | #include "../net/tcp_timer.h" | |
f03530e6 | 19 | #include "../net/tcp_var.h" |
0974b45c | 20 | #include "../net/tcpip.h" |
f1b2fa5b | 21 | #include "../errno.h" |
f03530e6 BJ |
22 | |
23 | /* | |
24 | * Fast timeout routine for processing delayed acks | |
25 | */ | |
26 | tcp_fasttimo() | |
27 | { | |
28 | ||
0974b45c | 29 | COUNT(TCP_FASTTIMO); |
f03530e6 BJ |
30 | } |
31 | ||
32 | /* | |
33 | * Tcp protocol timeout routine called every 500 ms. | |
34 | * Updates the timers in all active tcb's and | |
35 | * causes finite state machine actions if timers expire. | |
36 | */ | |
37 | tcp_slowtimo() | |
38 | { | |
39 | register struct inpcb *ip; | |
40 | register struct tcpcb *tp; | |
41 | int s = splnet(); | |
f03530e6 | 42 | register int i; |
0974b45c | 43 | COUNT(TCP_SLOWTIMO); |
f03530e6 BJ |
44 | |
45 | /* | |
46 | * Search through tcb's and update active timers. | |
47 | */ | |
4aed14e3 BJ |
48 | ip = tcb.inp_next; |
49 | if (ip == 0) { | |
50 | splx(s); | |
51 | return; | |
52 | } | |
53 | for (; ip != &tcb; ip = ip->inp_next) { | |
f03530e6 | 54 | tp = intotcpcb(ip); |
37de812c BJ |
55 | if (tp == 0) |
56 | continue; | |
a6503abf | 57 | for (i = 0; i < TCPT_NTIMERS; i++) { |
0974b45c | 58 | if (tp->t_timer[i] && --tp->t_timer[i] == 0) |
f03530e6 BJ |
59 | (void) tcp_usrreq(tp->t_inpcb->inp_socket, |
60 | PRU_SLOWTIMO, (struct mbuf *)0, | |
61 | (caddr_t)i); | |
f03530e6 | 62 | } |
405c9168 BJ |
63 | tp->t_idle++; |
64 | if (tp->t_rtt) | |
65 | tp->t_rtt++; | |
f03530e6 | 66 | } |
a6503abf | 67 | tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */ |
f03530e6 BJ |
68 | splx(s); |
69 | } | |
70 | ||
71 | /* | |
a6503abf | 72 | * Cancel all timers for TCP tp. |
f03530e6 | 73 | */ |
0974b45c | 74 | tcp_canceltimers(tp) |
f03530e6 BJ |
75 | struct tcpcb *tp; |
76 | { | |
f03530e6 BJ |
77 | register int i; |
78 | ||
0974b45c | 79 | COUNT(TCP_CANCELTIMERS); |
a6503abf BJ |
80 | for (i = 0; i < TCPT_NTIMERS; i++) |
81 | tp->t_timer[i] = 0; | |
f03530e6 BJ |
82 | } |
83 | ||
84 | /* | |
405c9168 | 85 | * TCP timer processing. |
f03530e6 | 86 | */ |
a6503abf | 87 | tcp_timers(tp, timer) |
f03530e6 | 88 | register struct tcpcb *tp; |
a6503abf | 89 | int timer; |
f03530e6 BJ |
90 | { |
91 | ||
92 | COUNT(TCP_TIMERS); | |
0974b45c | 93 | switch (timer) { |
f03530e6 | 94 | |
405c9168 BJ |
95 | /* |
96 | * 2 MSL timeout in shutdown went off. Delete connection | |
97 | * control block. | |
98 | */ | |
a6503abf BJ |
99 | case TCPT_2MSL: |
100 | tcp_close(tp); | |
101 | return; | |
f03530e6 | 102 | |
405c9168 BJ |
103 | /* |
104 | * Retransmission timer went off. Message has not | |
105 | * been acked within retransmit interval. Back off | |
106 | * to a longer retransmit interval and retransmit all | |
107 | * unacknowledged messages in the window. | |
108 | */ | |
a6503abf | 109 | case TCPT_REXMT: |
405c9168 BJ |
110 | tp->t_rxtshift++; |
111 | TCPT_RANGESET(tp->t_timer[TCPT_REXMT], | |
112 | ((int)(2 * tp->t_srtt)) << tp->t_rxtshift, | |
113 | TCPTV_MIN, TCPTV_MAX); | |
114 | tp->snd_nxt = tp->snd_una; | |
115 | /* this only transmits one segment! */ | |
116 | (void) tcp_output(tp); | |
a6503abf | 117 | return; |
f03530e6 | 118 | |
405c9168 BJ |
119 | /* |
120 | * Persistance timer into zero window. | |
121 | * Force a byte to be output, if possible. | |
122 | */ | |
a6503abf | 123 | case TCPT_PERSIST: |
405c9168 BJ |
124 | tp->t_force = 1; |
125 | (void) tcp_output(tp); | |
126 | tp->t_force = 0; | |
127 | TCPT_RANGESET(tp->t_timer[TCPT_PERSIST], | |
128 | 2 * tp->t_srtt, TCPTV_PERSMIN, TCPTV_MAX); | |
0974b45c | 129 | return; |
f03530e6 | 130 | |
405c9168 BJ |
131 | /* |
132 | * Keep-alive timer went off; send something | |
133 | * or drop connection if idle for too long. | |
134 | */ | |
a6503abf | 135 | case TCPT_KEEP: |
405c9168 BJ |
136 | if (tp->t_state < TCPS_ESTABLISHED || |
137 | tp->t_idle >= TCPTV_MAXIDLE) { | |
138 | tcp_drop(tp, ETIMEDOUT); | |
139 | return; | |
140 | } | |
141 | tcp_respond(tp->t_template, tp->rcv_nxt, tp->snd_una-1, 0); | |
142 | tp->t_timer[TCPT_KEEP] = TCPTV_KEEP; | |
a6503abf | 143 | return; |
f03530e6 | 144 | } |
f03530e6 | 145 | } |