sctp_timer.c revision 1.1.2.2 1 1.1.2.2 skrll /* $KAME: sctp_timer.c,v 1.30 2005/06/16 18:29:25 jinmei Exp $ */
2 1.1.2.2 skrll /* $NetBSD: sctp_timer.c,v 1.1.2.2 2015/12/27 12:10:07 skrll Exp $ */
3 1.1.2.2 skrll
4 1.1.2.2 skrll /*
5 1.1.2.2 skrll * Copyright (C) 2002, 2003, 2004 Cisco Systems Inc,
6 1.1.2.2 skrll * All rights reserved.
7 1.1.2.2 skrll *
8 1.1.2.2 skrll * Redistribution and use in source and binary forms, with or without
9 1.1.2.2 skrll * modification, are permitted provided that the following conditions
10 1.1.2.2 skrll * are met:
11 1.1.2.2 skrll * 1. Redistributions of source code must retain the above copyright
12 1.1.2.2 skrll * notice, this list of conditions and the following disclaimer.
13 1.1.2.2 skrll * 2. Redistributions in binary form must reproduce the above copyright
14 1.1.2.2 skrll * notice, this list of conditions and the following disclaimer in the
15 1.1.2.2 skrll * documentation and/or other materials provided with the distribution.
16 1.1.2.2 skrll * 3. Neither the name of the project nor the names of its contributors
17 1.1.2.2 skrll * may be used to endorse or promote products derived from this software
18 1.1.2.2 skrll * without specific prior written permission.
19 1.1.2.2 skrll *
20 1.1.2.2 skrll * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 1.1.2.2 skrll * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 1.1.2.2 skrll * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 1.1.2.2 skrll * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 1.1.2.2 skrll * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 1.1.2.2 skrll * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 1.1.2.2 skrll * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 1.1.2.2 skrll * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 1.1.2.2 skrll * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 1.1.2.2 skrll * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 1.1.2.2 skrll * SUCH DAMAGE.
31 1.1.2.2 skrll */
32 1.1.2.2 skrll #include <sys/cdefs.h>
33 1.1.2.2 skrll __KERNEL_RCSID(0, "$NetBSD: sctp_timer.c,v 1.1.2.2 2015/12/27 12:10:07 skrll Exp $");
34 1.1.2.2 skrll
35 1.1.2.2 skrll #ifdef _KERNEL_OPT
36 1.1.2.2 skrll #include "opt_inet.h"
37 1.1.2.2 skrll #include "opt_sctp.h"
38 1.1.2.2 skrll #endif /* _KERNEL_OPT */
39 1.1.2.2 skrll
40 1.1.2.2 skrll #include <sys/param.h>
41 1.1.2.2 skrll #include <sys/systm.h>
42 1.1.2.2 skrll #include <sys/malloc.h>
43 1.1.2.2 skrll #include <sys/mbuf.h>
44 1.1.2.2 skrll #include <sys/domain.h>
45 1.1.2.2 skrll #include <sys/protosw.h>
46 1.1.2.2 skrll #include <sys/socket.h>
47 1.1.2.2 skrll #include <sys/socketvar.h>
48 1.1.2.2 skrll #include <sys/proc.h>
49 1.1.2.2 skrll #include <sys/kernel.h>
50 1.1.2.2 skrll #include <sys/sysctl.h>
51 1.1.2.2 skrll #ifdef INET6
52 1.1.2.2 skrll #include <sys/domain.h>
53 1.1.2.2 skrll #endif
54 1.1.2.2 skrll
55 1.1.2.2 skrll #include <machine/limits.h>
56 1.1.2.2 skrll
57 1.1.2.2 skrll #include <net/if.h>
58 1.1.2.2 skrll #include <net/if_types.h>
59 1.1.2.2 skrll #include <net/route.h>
60 1.1.2.2 skrll #include <netinet/in.h>
61 1.1.2.2 skrll #include <netinet/in_systm.h>
62 1.1.2.2 skrll #define _IP_VHL
63 1.1.2.2 skrll #include <netinet/ip.h>
64 1.1.2.2 skrll #include <netinet/in_pcb.h>
65 1.1.2.2 skrll #include <netinet/in_var.h>
66 1.1.2.2 skrll #include <netinet/ip_var.h>
67 1.1.2.2 skrll
68 1.1.2.2 skrll #ifdef INET6
69 1.1.2.2 skrll #include <netinet/ip6.h>
70 1.1.2.2 skrll #include <netinet6/ip6_var.h>
71 1.1.2.2 skrll #endif /* INET6 */
72 1.1.2.2 skrll
73 1.1.2.2 skrll #include <netinet/sctp_pcb.h>
74 1.1.2.2 skrll
75 1.1.2.2 skrll #ifdef IPSEC
76 1.1.2.2 skrll #include <netinet6/ipsec.h>
77 1.1.2.2 skrll #include <netkey/key.h>
78 1.1.2.2 skrll #endif /* IPSEC */
79 1.1.2.2 skrll #ifdef INET6
80 1.1.2.2 skrll #include <netinet6/sctp6_var.h>
81 1.1.2.2 skrll #endif
82 1.1.2.2 skrll #include <netinet/sctp_var.h>
83 1.1.2.2 skrll #include <netinet/sctp_timer.h>
84 1.1.2.2 skrll #include <netinet/sctputil.h>
85 1.1.2.2 skrll #include <netinet/sctp_output.h>
86 1.1.2.2 skrll #include <netinet/sctp_hashdriver.h>
87 1.1.2.2 skrll #include <netinet/sctp_header.h>
88 1.1.2.2 skrll #include <netinet/sctp_indata.h>
89 1.1.2.2 skrll #include <netinet/sctp_asconf.h>
90 1.1.2.2 skrll
91 1.1.2.2 skrll #include <netinet/sctp.h>
92 1.1.2.2 skrll #include <netinet/sctp_uio.h>
93 1.1.2.2 skrll
94 1.1.2.2 skrll #include <net/net_osdep.h>
95 1.1.2.2 skrll
96 1.1.2.2 skrll #ifdef SCTP_DEBUG
97 1.1.2.2 skrll extern u_int32_t sctp_debug_on;
98 1.1.2.2 skrll #endif /* SCTP_DEBUG */
99 1.1.2.2 skrll
100 1.1.2.2 skrll void
101 1.1.2.2 skrll sctp_audit_retranmission_queue(struct sctp_association *asoc)
102 1.1.2.2 skrll {
103 1.1.2.2 skrll struct sctp_tmit_chunk *chk;
104 1.1.2.2 skrll
105 1.1.2.2 skrll #ifdef SCTP_DEBUG
106 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
107 1.1.2.2 skrll printf("Audit invoked on send queue cnt:%d onqueue:%d\n",
108 1.1.2.2 skrll asoc->sent_queue_retran_cnt,
109 1.1.2.2 skrll asoc->sent_queue_cnt);
110 1.1.2.2 skrll }
111 1.1.2.2 skrll #endif /* SCTP_DEBUG */
112 1.1.2.2 skrll asoc->sent_queue_retran_cnt = 0;
113 1.1.2.2 skrll asoc->sent_queue_cnt = 0;
114 1.1.2.2 skrll TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
115 1.1.2.2 skrll if (chk->sent == SCTP_DATAGRAM_RESEND) {
116 1.1.2.2 skrll asoc->sent_queue_retran_cnt++;
117 1.1.2.2 skrll }
118 1.1.2.2 skrll asoc->sent_queue_cnt++;
119 1.1.2.2 skrll }
120 1.1.2.2 skrll TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
121 1.1.2.2 skrll if (chk->sent == SCTP_DATAGRAM_RESEND) {
122 1.1.2.2 skrll asoc->sent_queue_retran_cnt++;
123 1.1.2.2 skrll }
124 1.1.2.2 skrll }
125 1.1.2.2 skrll #ifdef SCTP_DEBUG
126 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
127 1.1.2.2 skrll printf("Audit completes retran:%d onqueue:%d\n",
128 1.1.2.2 skrll asoc->sent_queue_retran_cnt,
129 1.1.2.2 skrll asoc->sent_queue_cnt);
130 1.1.2.2 skrll }
131 1.1.2.2 skrll #endif /* SCTP_DEBUG */
132 1.1.2.2 skrll }
133 1.1.2.2 skrll
134 1.1.2.2 skrll int
135 1.1.2.2 skrll sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
136 1.1.2.2 skrll struct sctp_nets *net, uint16_t threshold)
137 1.1.2.2 skrll {
138 1.1.2.2 skrll if (net) {
139 1.1.2.2 skrll net->error_count++;
140 1.1.2.2 skrll #ifdef SCTP_DEBUG
141 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
142 1.1.2.2 skrll printf("Error count for %p now %d thresh:%d\n",
143 1.1.2.2 skrll net, net->error_count,
144 1.1.2.2 skrll net->failure_threshold);
145 1.1.2.2 skrll }
146 1.1.2.2 skrll #endif /* SCTP_DEBUG */
147 1.1.2.2 skrll if (net->error_count >= net->failure_threshold) {
148 1.1.2.2 skrll /* We had a threshold failure */
149 1.1.2.2 skrll if (net->dest_state & SCTP_ADDR_REACHABLE) {
150 1.1.2.2 skrll net->dest_state &= ~SCTP_ADDR_REACHABLE;
151 1.1.2.2 skrll net->dest_state |= SCTP_ADDR_NOT_REACHABLE;
152 1.1.2.2 skrll if (net == stcb->asoc.primary_destination) {
153 1.1.2.2 skrll net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
154 1.1.2.2 skrll }
155 1.1.2.2 skrll sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
156 1.1.2.2 skrll stcb,
157 1.1.2.2 skrll SCTP_FAILED_THRESHOLD,
158 1.1.2.2 skrll (void *)net);
159 1.1.2.2 skrll }
160 1.1.2.2 skrll }
161 1.1.2.2 skrll /*********HOLD THIS COMMENT FOR PATCH OF ALTERNATE
162 1.1.2.2 skrll *********ROUTING CODE
163 1.1.2.2 skrll */
164 1.1.2.2 skrll /*********HOLD THIS COMMENT FOR END OF PATCH OF ALTERNATE
165 1.1.2.2 skrll *********ROUTING CODE
166 1.1.2.2 skrll */
167 1.1.2.2 skrll }
168 1.1.2.2 skrll if (stcb == NULL)
169 1.1.2.2 skrll return (0);
170 1.1.2.2 skrll
171 1.1.2.2 skrll if (net) {
172 1.1.2.2 skrll if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) {
173 1.1.2.2 skrll stcb->asoc.overall_error_count++;
174 1.1.2.2 skrll }
175 1.1.2.2 skrll } else {
176 1.1.2.2 skrll stcb->asoc.overall_error_count++;
177 1.1.2.2 skrll }
178 1.1.2.2 skrll #ifdef SCTP_DEBUG
179 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
180 1.1.2.2 skrll printf("Overall error count for %p now %d thresh:%u state:%x\n",
181 1.1.2.2 skrll &stcb->asoc,
182 1.1.2.2 skrll stcb->asoc.overall_error_count,
183 1.1.2.2 skrll (u_int)threshold,
184 1.1.2.2 skrll ((net == NULL) ? (u_int)0 : (u_int)net->dest_state));
185 1.1.2.2 skrll }
186 1.1.2.2 skrll #endif /* SCTP_DEBUG */
187 1.1.2.2 skrll /* We specifically do not do >= to give the assoc one more
188 1.1.2.2 skrll * change before we fail it.
189 1.1.2.2 skrll */
190 1.1.2.2 skrll if (stcb->asoc.overall_error_count > threshold) {
191 1.1.2.2 skrll /* Abort notification sends a ULP notify */
192 1.1.2.2 skrll struct mbuf *oper;
193 1.1.2.2 skrll MGET(oper, M_DONTWAIT, MT_DATA);
194 1.1.2.2 skrll if (oper) {
195 1.1.2.2 skrll struct sctp_paramhdr *ph;
196 1.1.2.2 skrll u_int32_t *ippp;
197 1.1.2.2 skrll
198 1.1.2.2 skrll oper->m_len = sizeof(struct sctp_paramhdr) +
199 1.1.2.2 skrll sizeof(*ippp);
200 1.1.2.2 skrll ph = mtod(oper, struct sctp_paramhdr *);
201 1.1.2.2 skrll ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
202 1.1.2.2 skrll ph->param_length = htons(oper->m_len);
203 1.1.2.2 skrll ippp = (u_int32_t *)(ph + 1);
204 1.1.2.2 skrll *ippp = htonl(0x40000001);
205 1.1.2.2 skrll }
206 1.1.2.2 skrll sctp_abort_an_association(inp, stcb, SCTP_FAILED_THRESHOLD, oper);
207 1.1.2.2 skrll return (1);
208 1.1.2.2 skrll }
209 1.1.2.2 skrll return (0);
210 1.1.2.2 skrll }
211 1.1.2.2 skrll
212 1.1.2.2 skrll struct sctp_nets *
213 1.1.2.2 skrll sctp_find_alternate_net(struct sctp_tcb *stcb,
214 1.1.2.2 skrll struct sctp_nets *net)
215 1.1.2.2 skrll {
216 1.1.2.2 skrll /* Find and return an alternate network if possible */
217 1.1.2.2 skrll struct sctp_nets *alt, *mnet;
218 1.1.2.2 skrll struct rtentry *rt;
219 1.1.2.2 skrll int once;
220 1.1.2.2 skrll
221 1.1.2.2 skrll if (stcb->asoc.numnets == 1) {
222 1.1.2.2 skrll /* No others but net */
223 1.1.2.2 skrll return (TAILQ_FIRST(&stcb->asoc.nets));
224 1.1.2.2 skrll }
225 1.1.2.2 skrll mnet = net;
226 1.1.2.2 skrll once = 0;
227 1.1.2.2 skrll
228 1.1.2.2 skrll if (mnet == NULL) {
229 1.1.2.2 skrll mnet = TAILQ_FIRST(&stcb->asoc.nets);
230 1.1.2.2 skrll }
231 1.1.2.2 skrll do {
232 1.1.2.2 skrll alt = TAILQ_NEXT(mnet, sctp_next);
233 1.1.2.2 skrll if (alt == NULL) {
234 1.1.2.2 skrll once++;
235 1.1.2.2 skrll if (once > 1) {
236 1.1.2.2 skrll break;
237 1.1.2.2 skrll }
238 1.1.2.2 skrll alt = TAILQ_FIRST(&stcb->asoc.nets);
239 1.1.2.2 skrll }
240 1.1.2.2 skrll rt = rtcache_validate(&alt->ro);
241 1.1.2.2 skrll if (rt == NULL) {
242 1.1.2.2 skrll alt->src_addr_selected = 0;
243 1.1.2.2 skrll }
244 1.1.2.2 skrll if (
245 1.1.2.2 skrll ((alt->dest_state & SCTP_ADDR_REACHABLE) == SCTP_ADDR_REACHABLE) &&
246 1.1.2.2 skrll (rt != NULL) &&
247 1.1.2.2 skrll (!(alt->dest_state & SCTP_ADDR_UNCONFIRMED))
248 1.1.2.2 skrll ) {
249 1.1.2.2 skrll /* Found a reachable address */
250 1.1.2.2 skrll break;
251 1.1.2.2 skrll }
252 1.1.2.2 skrll mnet = alt;
253 1.1.2.2 skrll } while (alt != NULL);
254 1.1.2.2 skrll
255 1.1.2.2 skrll if (alt == NULL) {
256 1.1.2.2 skrll /* Case where NO insv network exists (dormant state) */
257 1.1.2.2 skrll /* we rotate destinations */
258 1.1.2.2 skrll once = 0;
259 1.1.2.2 skrll mnet = net;
260 1.1.2.2 skrll do {
261 1.1.2.2 skrll alt = TAILQ_NEXT(mnet, sctp_next);
262 1.1.2.2 skrll if (alt == NULL) {
263 1.1.2.2 skrll once++;
264 1.1.2.2 skrll if (once > 1) {
265 1.1.2.2 skrll break;
266 1.1.2.2 skrll }
267 1.1.2.2 skrll alt = TAILQ_FIRST(&stcb->asoc.nets);
268 1.1.2.2 skrll }
269 1.1.2.2 skrll if ((!(alt->dest_state & SCTP_ADDR_UNCONFIRMED)) &&
270 1.1.2.2 skrll (alt != net)) {
271 1.1.2.2 skrll /* Found an alternate address */
272 1.1.2.2 skrll break;
273 1.1.2.2 skrll }
274 1.1.2.2 skrll mnet = alt;
275 1.1.2.2 skrll } while (alt != NULL);
276 1.1.2.2 skrll }
277 1.1.2.2 skrll if (alt == NULL) {
278 1.1.2.2 skrll return (net);
279 1.1.2.2 skrll }
280 1.1.2.2 skrll return (alt);
281 1.1.2.2 skrll }
282 1.1.2.2 skrll
283 1.1.2.2 skrll static void
284 1.1.2.2 skrll sctp_backoff_on_timeout(struct sctp_tcb *stcb,
285 1.1.2.2 skrll struct sctp_nets *net,
286 1.1.2.2 skrll int win_probe,
287 1.1.2.2 skrll int num_marked)
288 1.1.2.2 skrll {
289 1.1.2.2 skrll #ifdef SCTP_DEBUG
290 1.1.2.2 skrll int oldRTO;
291 1.1.2.2 skrll
292 1.1.2.2 skrll oldRTO = net->RTO;
293 1.1.2.2 skrll #endif /* SCTP_DEBUG */
294 1.1.2.2 skrll net->RTO <<= 1;
295 1.1.2.2 skrll #ifdef SCTP_DEBUG
296 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER2) {
297 1.1.2.2 skrll printf("Timer doubles from %d ms -to-> %d ms\n",
298 1.1.2.2 skrll oldRTO, net->RTO);
299 1.1.2.2 skrll }
300 1.1.2.2 skrll #endif /* SCTP_DEBUG */
301 1.1.2.2 skrll
302 1.1.2.2 skrll if (net->RTO > stcb->asoc.maxrto) {
303 1.1.2.2 skrll net->RTO = stcb->asoc.maxrto;
304 1.1.2.2 skrll #ifdef SCTP_DEBUG
305 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER2) {
306 1.1.2.2 skrll printf("Growth capped by maxrto %d\n",
307 1.1.2.2 skrll net->RTO);
308 1.1.2.2 skrll }
309 1.1.2.2 skrll #endif /* SCTP_DEBUG */
310 1.1.2.2 skrll }
311 1.1.2.2 skrll
312 1.1.2.2 skrll
313 1.1.2.2 skrll if ((win_probe == 0) && num_marked) {
314 1.1.2.2 skrll /* We don't apply penalty to window probe scenarios */
315 1.1.2.2 skrll #ifdef SCTP_CWND_LOGGING
316 1.1.2.2 skrll int old_cwnd=net->cwnd;
317 1.1.2.2 skrll #endif
318 1.1.2.2 skrll net->ssthresh = net->cwnd >> 1;
319 1.1.2.2 skrll if (net->ssthresh < (net->mtu << 1)) {
320 1.1.2.2 skrll net->ssthresh = (net->mtu << 1);
321 1.1.2.2 skrll }
322 1.1.2.2 skrll net->cwnd = net->mtu;
323 1.1.2.2 skrll /* floor of 1 mtu */
324 1.1.2.2 skrll if (net->cwnd < net->mtu)
325 1.1.2.2 skrll net->cwnd = net->mtu;
326 1.1.2.2 skrll #ifdef SCTP_CWND_LOGGING
327 1.1.2.2 skrll sctp_log_cwnd(net, net->cwnd-old_cwnd, SCTP_CWND_LOG_FROM_RTX);
328 1.1.2.2 skrll #endif
329 1.1.2.2 skrll
330 1.1.2.2 skrll net->partial_bytes_acked = 0;
331 1.1.2.2 skrll #ifdef SCTP_DEBUG
332 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
333 1.1.2.2 skrll printf("collapse cwnd to 1MTU ssthresh to %d\n",
334 1.1.2.2 skrll net->ssthresh);
335 1.1.2.2 skrll }
336 1.1.2.2 skrll #endif
337 1.1.2.2 skrll
338 1.1.2.2 skrll }
339 1.1.2.2 skrll }
340 1.1.2.2 skrll
341 1.1.2.2 skrll
342 1.1.2.2 skrll static int
343 1.1.2.2 skrll sctp_mark_all_for_resend(struct sctp_tcb *stcb,
344 1.1.2.2 skrll struct sctp_nets *net,
345 1.1.2.2 skrll struct sctp_nets *alt,
346 1.1.2.2 skrll int *num_marked)
347 1.1.2.2 skrll {
348 1.1.2.2 skrll
349 1.1.2.2 skrll /*
350 1.1.2.2 skrll * Mark all chunks (well not all) that were sent to *net for retransmission.
351 1.1.2.2 skrll * Move them to alt for there destination as well... We only
352 1.1.2.2 skrll * mark chunks that have been outstanding long enough to have
353 1.1.2.2 skrll * received feed-back.
354 1.1.2.2 skrll */
355 1.1.2.2 skrll struct sctp_tmit_chunk *chk, *tp2;
356 1.1.2.2 skrll struct sctp_nets *lnets;
357 1.1.2.2 skrll struct timeval now, min_wait, tv;
358 1.1.2.2 skrll int cur_rto;
359 1.1.2.2 skrll int win_probes, non_win_probes, orig_rwnd, audit_tf, num_mk, fir;
360 1.1.2.2 skrll unsigned int cnt_mk;
361 1.1.2.2 skrll u_int32_t orig_flight;
362 1.1.2.2 skrll #ifdef SCTP_FR_LOGGING
363 1.1.2.2 skrll u_int32_t tsnfirst, tsnlast;
364 1.1.2.2 skrll #endif
365 1.1.2.2 skrll
366 1.1.2.2 skrll /* none in flight now */
367 1.1.2.2 skrll audit_tf = 0;
368 1.1.2.2 skrll fir=0;
369 1.1.2.2 skrll /* figure out how long a data chunk must be pending
370 1.1.2.2 skrll * before we can mark it ..
371 1.1.2.2 skrll */
372 1.1.2.2 skrll SCTP_GETTIME_TIMEVAL(&now);
373 1.1.2.2 skrll /* get cur rto in micro-seconds */
374 1.1.2.2 skrll cur_rto = (((net->lastsa >> 2) + net->lastsv) >> 1);
375 1.1.2.2 skrll #ifdef SCTP_FR_LOGGING
376 1.1.2.2 skrll sctp_log_fr(cur_rto, 0, 0, SCTP_FR_T3_MARK_TIME);
377 1.1.2.2 skrll #endif
378 1.1.2.2 skrll cur_rto *= 1000;
379 1.1.2.2 skrll #ifdef SCTP_FR_LOGGING
380 1.1.2.2 skrll sctp_log_fr(cur_rto, 0, 0, SCTP_FR_T3_MARK_TIME);
381 1.1.2.2 skrll #endif
382 1.1.2.2 skrll tv.tv_sec = cur_rto / 1000000;
383 1.1.2.2 skrll tv.tv_usec = cur_rto % 1000000;
384 1.1.2.2 skrll #ifndef __FreeBSD__
385 1.1.2.2 skrll timersub(&now, &tv, &min_wait);
386 1.1.2.2 skrll #else
387 1.1.2.2 skrll min_wait = now;
388 1.1.2.2 skrll timevalsub(&min_wait, &tv);
389 1.1.2.2 skrll #endif
390 1.1.2.2 skrll if (min_wait.tv_sec < 0 || min_wait.tv_usec < 0) {
391 1.1.2.2 skrll /*
392 1.1.2.2 skrll * if we hit here, we don't
393 1.1.2.2 skrll * have enough seconds on the clock to account
394 1.1.2.2 skrll * for the RTO. We just let the lower seconds
395 1.1.2.2 skrll * be the bounds and don't worry about it. This
396 1.1.2.2 skrll * may mean we will mark a lot more than we should.
397 1.1.2.2 skrll */
398 1.1.2.2 skrll min_wait.tv_sec = min_wait.tv_usec = 0;
399 1.1.2.2 skrll }
400 1.1.2.2 skrll #ifdef SCTP_FR_LOGGING
401 1.1.2.2 skrll sctp_log_fr(cur_rto, now.tv_sec, now.tv_usec, SCTP_FR_T3_MARK_TIME);
402 1.1.2.2 skrll sctp_log_fr(0, min_wait.tv_sec, min_wait.tv_usec, SCTP_FR_T3_MARK_TIME);
403 1.1.2.2 skrll #endif
404 1.1.2.2 skrll if (stcb->asoc.total_flight >= net->flight_size) {
405 1.1.2.2 skrll stcb->asoc.total_flight -= net->flight_size;
406 1.1.2.2 skrll } else {
407 1.1.2.2 skrll audit_tf = 1;
408 1.1.2.2 skrll stcb->asoc.total_flight = 0;
409 1.1.2.2 skrll }
410 1.1.2.2 skrll /* Our rwnd will be incorrect here since we are not adding
411 1.1.2.2 skrll * back the cnt * mbuf but we will fix that down below.
412 1.1.2.2 skrll */
413 1.1.2.2 skrll orig_rwnd = stcb->asoc.peers_rwnd;
414 1.1.2.2 skrll orig_flight = net->flight_size;
415 1.1.2.2 skrll stcb->asoc.peers_rwnd += net->flight_size;
416 1.1.2.2 skrll net->flight_size = 0;
417 1.1.2.2 skrll net->rto_pending = 0;
418 1.1.2.2 skrll net->fast_retran_ip= 0;
419 1.1.2.2 skrll win_probes = non_win_probes = 0;
420 1.1.2.2 skrll #ifdef SCTP_DEBUG
421 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER2) {
422 1.1.2.2 skrll printf("Marking ALL un-acked for retransmission at t3-timeout\n");
423 1.1.2.2 skrll }
424 1.1.2.2 skrll #endif /* SCTP_DEBUG */
425 1.1.2.2 skrll /* Now on to each chunk */
426 1.1.2.2 skrll num_mk = cnt_mk = 0;
427 1.1.2.2 skrll #ifdef SCTP_FR_LOGGING
428 1.1.2.2 skrll tsnlast = tsnfirst = 0;
429 1.1.2.2 skrll #endif
430 1.1.2.2 skrll chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
431 1.1.2.2 skrll for (;chk != NULL; chk = tp2) {
432 1.1.2.2 skrll tp2 = TAILQ_NEXT(chk, sctp_next);
433 1.1.2.2 skrll if ((compare_with_wrap(stcb->asoc.last_acked_seq,
434 1.1.2.2 skrll chk->rec.data.TSN_seq,
435 1.1.2.2 skrll MAX_TSN)) ||
436 1.1.2.2 skrll (stcb->asoc.last_acked_seq == chk->rec.data.TSN_seq)) {
437 1.1.2.2 skrll /* Strange case our list got out of order? */
438 1.1.2.2 skrll printf("Our list is out of order?\n");
439 1.1.2.2 skrll TAILQ_REMOVE(&stcb->asoc.sent_queue, chk, sctp_next);
440 1.1.2.2 skrll if (chk->data) {
441 1.1.2.2 skrll sctp_release_pr_sctp_chunk(stcb, chk, 0xffff,
442 1.1.2.2 skrll &stcb->asoc.sent_queue);
443 1.1.2.2 skrll if (chk->flags & SCTP_PR_SCTP_BUFFER) {
444 1.1.2.2 skrll stcb->asoc.sent_queue_cnt_removeable--;
445 1.1.2.2 skrll }
446 1.1.2.2 skrll }
447 1.1.2.2 skrll stcb->asoc.sent_queue_cnt--;
448 1.1.2.2 skrll sctp_free_remote_addr(chk->whoTo);
449 1.1.2.2 skrll sctppcbinfo.ipi_count_chunk--;
450 1.1.2.2 skrll if ((int)sctppcbinfo.ipi_count_chunk < 0) {
451 1.1.2.2 skrll panic("Chunk count is going negative");
452 1.1.2.2 skrll }
453 1.1.2.2 skrll SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
454 1.1.2.2 skrll sctppcbinfo.ipi_gencnt_chunk++;
455 1.1.2.2 skrll continue;
456 1.1.2.2 skrll }
457 1.1.2.2 skrll if ((chk->whoTo == net) && (chk->sent < SCTP_DATAGRAM_ACKED)) {
458 1.1.2.2 skrll /* found one to mark:
459 1.1.2.2 skrll * If it is less than DATAGRAM_ACKED it MUST
460 1.1.2.2 skrll * not be a skipped or marked TSN but instead
461 1.1.2.2 skrll * one that is either already set for retransmission OR
462 1.1.2.2 skrll * one that needs retransmission.
463 1.1.2.2 skrll */
464 1.1.2.2 skrll
465 1.1.2.2 skrll /* validate its been outstanding long enough */
466 1.1.2.2 skrll #ifdef SCTP_FR_LOGGING
467 1.1.2.2 skrll sctp_log_fr(chk->rec.data.TSN_seq,
468 1.1.2.2 skrll chk->sent_rcv_time.tv_sec,
469 1.1.2.2 skrll chk->sent_rcv_time.tv_usec,
470 1.1.2.2 skrll SCTP_FR_T3_MARK_TIME);
471 1.1.2.2 skrll #endif
472 1.1.2.2 skrll if (chk->sent_rcv_time.tv_sec > min_wait.tv_sec) {
473 1.1.2.2 skrll /* we have reached a chunk that was sent some
474 1.1.2.2 skrll * seconds past our min.. forget it we will
475 1.1.2.2 skrll * find no more to send.
476 1.1.2.2 skrll */
477 1.1.2.2 skrll #ifdef SCTP_FR_LOGGING
478 1.1.2.2 skrll sctp_log_fr(0,
479 1.1.2.2 skrll chk->sent_rcv_time.tv_sec,
480 1.1.2.2 skrll chk->sent_rcv_time.tv_usec,
481 1.1.2.2 skrll SCTP_FR_T3_STOPPED);
482 1.1.2.2 skrll #endif
483 1.1.2.2 skrll continue;
484 1.1.2.2 skrll } else if (chk->sent_rcv_time.tv_sec == min_wait.tv_sec) {
485 1.1.2.2 skrll /* we must look at the micro seconds to know.
486 1.1.2.2 skrll */
487 1.1.2.2 skrll if (chk->sent_rcv_time.tv_usec >= min_wait.tv_usec) {
488 1.1.2.2 skrll /* ok it was sent after our boundary time. */
489 1.1.2.2 skrll #ifdef SCTP_FR_LOGGING
490 1.1.2.2 skrll sctp_log_fr(0,
491 1.1.2.2 skrll chk->sent_rcv_time.tv_sec,
492 1.1.2.2 skrll chk->sent_rcv_time.tv_usec,
493 1.1.2.2 skrll SCTP_FR_T3_STOPPED);
494 1.1.2.2 skrll #endif
495 1.1.2.2 skrll continue;
496 1.1.2.2 skrll }
497 1.1.2.2 skrll }
498 1.1.2.2 skrll if (stcb->asoc.total_flight_count > 0) {
499 1.1.2.2 skrll stcb->asoc.total_flight_count--;
500 1.1.2.2 skrll }
501 1.1.2.2 skrll if ((chk->flags & (SCTP_PR_SCTP_ENABLED|SCTP_PR_SCTP_BUFFER)) == SCTP_PR_SCTP_ENABLED) {
502 1.1.2.2 skrll /* Is it expired? */
503 1.1.2.2 skrll if ((now.tv_sec > chk->rec.data.timetodrop.tv_sec) ||
504 1.1.2.2 skrll ((chk->rec.data.timetodrop.tv_sec == now.tv_sec) &&
505 1.1.2.2 skrll (now.tv_usec > chk->rec.data.timetodrop.tv_usec))) {
506 1.1.2.2 skrll /* Yes so drop it */
507 1.1.2.2 skrll if (chk->data) {
508 1.1.2.2 skrll sctp_release_pr_sctp_chunk(stcb,
509 1.1.2.2 skrll chk,
510 1.1.2.2 skrll (SCTP_RESPONSE_TO_USER_REQ|SCTP_NOTIFY_DATAGRAM_SENT),
511 1.1.2.2 skrll &stcb->asoc.sent_queue);
512 1.1.2.2 skrll }
513 1.1.2.2 skrll }
514 1.1.2.2 skrll continue;
515 1.1.2.2 skrll }
516 1.1.2.2 skrll if (chk->sent != SCTP_DATAGRAM_RESEND) {
517 1.1.2.2 skrll stcb->asoc.sent_queue_retran_cnt++;
518 1.1.2.2 skrll num_mk++;
519 1.1.2.2 skrll if (fir == 0) {
520 1.1.2.2 skrll fir = 1;
521 1.1.2.2 skrll #ifdef SCTP_DEBUG
522 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
523 1.1.2.2 skrll printf("First TSN marked was %x\n",
524 1.1.2.2 skrll chk->rec.data.TSN_seq);
525 1.1.2.2 skrll }
526 1.1.2.2 skrll #endif
527 1.1.2.2 skrll #ifdef SCTP_FR_LOGGING
528 1.1.2.2 skrll tsnfirst = chk->rec.data.TSN_seq;
529 1.1.2.2 skrll #endif
530 1.1.2.2 skrll }
531 1.1.2.2 skrll #ifdef SCTP_FR_LOGGING
532 1.1.2.2 skrll tsnlast = chk->rec.data.TSN_seq;
533 1.1.2.2 skrll sctp_log_fr(chk->rec.data.TSN_seq, chk->snd_count,
534 1.1.2.2 skrll 0, SCTP_FR_T3_MARKED);
535 1.1.2.2 skrll
536 1.1.2.2 skrll #endif
537 1.1.2.2 skrll }
538 1.1.2.2 skrll chk->sent = SCTP_DATAGRAM_RESEND;
539 1.1.2.2 skrll /* reset the TSN for striking and other FR stuff */
540 1.1.2.2 skrll chk->rec.data.doing_fast_retransmit = 0;
541 1.1.2.2 skrll #ifdef SCTP_DEBUG
542 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER3) {
543 1.1.2.2 skrll printf("mark TSN:%x for retransmission\n", chk->rec.data.TSN_seq);
544 1.1.2.2 skrll }
545 1.1.2.2 skrll #endif /* SCTP_DEBUG */
546 1.1.2.2 skrll /* Clear any time so NO RTT is being done */
547 1.1.2.2 skrll chk->do_rtt = 0;
548 1.1.2.2 skrll /* Bump up the count */
549 1.1.2.2 skrll if (compare_with_wrap(chk->rec.data.TSN_seq,
550 1.1.2.2 skrll stcb->asoc.t3timeout_highest_marked,
551 1.1.2.2 skrll MAX_TSN)) {
552 1.1.2.2 skrll /* TSN_seq > than t3timeout so update */
553 1.1.2.2 skrll stcb->asoc.t3timeout_highest_marked = chk->rec.data.TSN_seq;
554 1.1.2.2 skrll }
555 1.1.2.2 skrll if (alt != net) {
556 1.1.2.2 skrll sctp_free_remote_addr(chk->whoTo);
557 1.1.2.2 skrll chk->whoTo = alt;
558 1.1.2.2 skrll alt->ref_count++;
559 1.1.2.2 skrll }
560 1.1.2.2 skrll if ((chk->rec.data.state_flags & SCTP_WINDOW_PROBE) !=
561 1.1.2.2 skrll SCTP_WINDOW_PROBE) {
562 1.1.2.2 skrll non_win_probes++;
563 1.1.2.2 skrll } else {
564 1.1.2.2 skrll chk->rec.data.state_flags &= ~SCTP_WINDOW_PROBE;
565 1.1.2.2 skrll win_probes++;
566 1.1.2.2 skrll }
567 1.1.2.2 skrll }
568 1.1.2.2 skrll if (chk->sent == SCTP_DATAGRAM_RESEND) {
569 1.1.2.2 skrll cnt_mk++;
570 1.1.2.2 skrll }
571 1.1.2.2 skrll }
572 1.1.2.2 skrll
573 1.1.2.2 skrll #ifdef SCTP_FR_LOGGING
574 1.1.2.2 skrll sctp_log_fr(tsnfirst, tsnlast, num_mk, SCTP_FR_T3_TIMEOUT);
575 1.1.2.2 skrll #endif
576 1.1.2.2 skrll /* compensate for the number we marked */
577 1.1.2.2 skrll stcb->asoc.peers_rwnd += (num_mk /* * sizeof(struct mbuf)*/);
578 1.1.2.2 skrll
579 1.1.2.2 skrll #ifdef SCTP_DEBUG
580 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
581 1.1.2.2 skrll if (num_mk) {
582 1.1.2.2 skrll #ifdef SCTP_FR_LOGGING
583 1.1.2.2 skrll printf("LAST TSN marked was %x\n", tsnlast);
584 1.1.2.2 skrll #endif
585 1.1.2.2 skrll printf("Num marked for retransmission was %d peer-rwd:%ld\n",
586 1.1.2.2 skrll num_mk, (u_long)stcb->asoc.peers_rwnd);
587 1.1.2.2 skrll #ifdef SCTP_FR_LOGGING
588 1.1.2.2 skrll printf("LAST TSN marked was %x\n", tsnlast);
589 1.1.2.2 skrll #endif
590 1.1.2.2 skrll printf("Num marked for retransmission was %d peer-rwd:%d\n",
591 1.1.2.2 skrll num_mk,
592 1.1.2.2 skrll (int)stcb->asoc.peers_rwnd
593 1.1.2.2 skrll );
594 1.1.2.2 skrll }
595 1.1.2.2 skrll }
596 1.1.2.2 skrll #endif
597 1.1.2.2 skrll *num_marked = num_mk;
598 1.1.2.2 skrll if (stcb->asoc.sent_queue_retran_cnt != cnt_mk) {
599 1.1.2.2 skrll printf("Local Audit says there are %d for retran asoc cnt:%d\n",
600 1.1.2.2 skrll cnt_mk, stcb->asoc.sent_queue_retran_cnt);
601 1.1.2.2 skrll #ifndef SCTP_AUDITING_ENABLED
602 1.1.2.2 skrll stcb->asoc.sent_queue_retran_cnt = cnt_mk;
603 1.1.2.2 skrll #endif
604 1.1.2.2 skrll }
605 1.1.2.2 skrll #ifdef SCTP_DEBUG
606 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER3) {
607 1.1.2.2 skrll printf("**************************\n");
608 1.1.2.2 skrll }
609 1.1.2.2 skrll #endif /* SCTP_DEBUG */
610 1.1.2.2 skrll
611 1.1.2.2 skrll /* Now check for a ECN Echo that may be stranded */
612 1.1.2.2 skrll TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
613 1.1.2.2 skrll if ((chk->whoTo == net) &&
614 1.1.2.2 skrll (chk->rec.chunk_id == SCTP_ECN_ECHO)) {
615 1.1.2.2 skrll sctp_free_remote_addr(chk->whoTo);
616 1.1.2.2 skrll chk->whoTo = alt;
617 1.1.2.2 skrll if (chk->sent != SCTP_DATAGRAM_RESEND) {
618 1.1.2.2 skrll chk->sent = SCTP_DATAGRAM_RESEND;
619 1.1.2.2 skrll stcb->asoc.sent_queue_retran_cnt++;
620 1.1.2.2 skrll }
621 1.1.2.2 skrll alt->ref_count++;
622 1.1.2.2 skrll }
623 1.1.2.2 skrll }
624 1.1.2.2 skrll if ((orig_rwnd == 0) && (stcb->asoc.total_flight == 0) &&
625 1.1.2.2 skrll (orig_flight <= net->mtu)) {
626 1.1.2.2 skrll /*
627 1.1.2.2 skrll * If the LAST packet sent was not acked and our rwnd is 0
628 1.1.2.2 skrll * then we are in a win-probe state.
629 1.1.2.2 skrll */
630 1.1.2.2 skrll win_probes = 1;
631 1.1.2.2 skrll non_win_probes = 0;
632 1.1.2.2 skrll #ifdef SCTP_DEBUG
633 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
634 1.1.2.2 skrll printf("WIN_PROBE set via o_rwnd=0 tf=0 and all:%d fit in mtu:%d\n",
635 1.1.2.2 skrll orig_flight, net->mtu);
636 1.1.2.2 skrll }
637 1.1.2.2 skrll #endif
638 1.1.2.2 skrll }
639 1.1.2.2 skrll
640 1.1.2.2 skrll if (audit_tf) {
641 1.1.2.2 skrll #ifdef SCTP_DEBUG
642 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
643 1.1.2.2 skrll printf("Audit total flight due to negative value net:%p\n",
644 1.1.2.2 skrll net);
645 1.1.2.2 skrll }
646 1.1.2.2 skrll #endif /* SCTP_DEBUG */
647 1.1.2.2 skrll stcb->asoc.total_flight = 0;
648 1.1.2.2 skrll stcb->asoc.total_flight_count = 0;
649 1.1.2.2 skrll /* Clear all networks flight size */
650 1.1.2.2 skrll TAILQ_FOREACH(lnets, &stcb->asoc.nets, sctp_next) {
651 1.1.2.2 skrll lnets->flight_size = 0;
652 1.1.2.2 skrll #ifdef SCTP_DEBUG
653 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
654 1.1.2.2 skrll printf("Net:%p c-f cwnd:%d ssthresh:%d\n",
655 1.1.2.2 skrll lnets, lnets->cwnd, lnets->ssthresh);
656 1.1.2.2 skrll }
657 1.1.2.2 skrll #endif /* SCTP_DEBUG */
658 1.1.2.2 skrll }
659 1.1.2.2 skrll TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
660 1.1.2.2 skrll if (chk->sent < SCTP_DATAGRAM_RESEND) {
661 1.1.2.2 skrll stcb->asoc.total_flight += chk->book_size;
662 1.1.2.2 skrll chk->whoTo->flight_size += chk->book_size;
663 1.1.2.2 skrll stcb->asoc.total_flight_count++;
664 1.1.2.2 skrll }
665 1.1.2.2 skrll }
666 1.1.2.2 skrll }
667 1.1.2.2 skrll /* Setup the ecn nonce re-sync point. We
668 1.1.2.2 skrll * do this since retranmissions are NOT
669 1.1.2.2 skrll * setup for ECN. This means that do to
670 1.1.2.2 skrll * Karn's rule, we don't know the total
671 1.1.2.2 skrll * of the peers ecn bits.
672 1.1.2.2 skrll */
673 1.1.2.2 skrll chk = TAILQ_FIRST(&stcb->asoc.send_queue);
674 1.1.2.2 skrll if (chk == NULL) {
675 1.1.2.2 skrll stcb->asoc.nonce_resync_tsn = stcb->asoc.sending_seq;
676 1.1.2.2 skrll } else {
677 1.1.2.2 skrll stcb->asoc.nonce_resync_tsn = chk->rec.data.TSN_seq;
678 1.1.2.2 skrll }
679 1.1.2.2 skrll stcb->asoc.nonce_wait_for_ecne = 0;
680 1.1.2.2 skrll stcb->asoc.nonce_sum_check = 0;
681 1.1.2.2 skrll /* We return 1 if we only have a window probe outstanding */
682 1.1.2.2 skrll if (win_probes && (non_win_probes == 0)) {
683 1.1.2.2 skrll return (1);
684 1.1.2.2 skrll }
685 1.1.2.2 skrll return (0);
686 1.1.2.2 skrll }
687 1.1.2.2 skrll
688 1.1.2.2 skrll static void
689 1.1.2.2 skrll sctp_move_all_chunks_to_alt(struct sctp_tcb *stcb,
690 1.1.2.2 skrll struct sctp_nets *net,
691 1.1.2.2 skrll struct sctp_nets *alt)
692 1.1.2.2 skrll {
693 1.1.2.2 skrll struct sctp_association *asoc;
694 1.1.2.2 skrll struct sctp_stream_out *outs;
695 1.1.2.2 skrll struct sctp_tmit_chunk *chk;
696 1.1.2.2 skrll
697 1.1.2.2 skrll if (net == alt)
698 1.1.2.2 skrll /* nothing to do */
699 1.1.2.2 skrll return;
700 1.1.2.2 skrll
701 1.1.2.2 skrll asoc = &stcb->asoc;
702 1.1.2.2 skrll
703 1.1.2.2 skrll /*
704 1.1.2.2 skrll * now through all the streams checking for chunks sent to our
705 1.1.2.2 skrll * bad network.
706 1.1.2.2 skrll */
707 1.1.2.2 skrll TAILQ_FOREACH(outs, &asoc->out_wheel, next_spoke) {
708 1.1.2.2 skrll /* now clean up any chunks here */
709 1.1.2.2 skrll TAILQ_FOREACH(chk, &outs->outqueue, sctp_next) {
710 1.1.2.2 skrll if (chk->whoTo == net) {
711 1.1.2.2 skrll sctp_free_remote_addr(chk->whoTo);
712 1.1.2.2 skrll chk->whoTo = alt;
713 1.1.2.2 skrll alt->ref_count++;
714 1.1.2.2 skrll }
715 1.1.2.2 skrll }
716 1.1.2.2 skrll }
717 1.1.2.2 skrll /* Now check the pending queue */
718 1.1.2.2 skrll TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
719 1.1.2.2 skrll if (chk->whoTo == net) {
720 1.1.2.2 skrll sctp_free_remote_addr(chk->whoTo);
721 1.1.2.2 skrll chk->whoTo = alt;
722 1.1.2.2 skrll alt->ref_count++;
723 1.1.2.2 skrll }
724 1.1.2.2 skrll }
725 1.1.2.2 skrll
726 1.1.2.2 skrll }
727 1.1.2.2 skrll
728 1.1.2.2 skrll int
729 1.1.2.2 skrll sctp_t3rxt_timer(struct sctp_inpcb *inp,
730 1.1.2.2 skrll struct sctp_tcb *stcb,
731 1.1.2.2 skrll struct sctp_nets *net)
732 1.1.2.2 skrll {
733 1.1.2.2 skrll struct sctp_nets *alt;
734 1.1.2.2 skrll int win_probe, num_mk;
735 1.1.2.2 skrll
736 1.1.2.2 skrll
737 1.1.2.2 skrll #ifdef SCTP_FR_LOGGING
738 1.1.2.2 skrll sctp_log_fr(0, 0, 0, SCTP_FR_T3_TIMEOUT);
739 1.1.2.2 skrll #endif
740 1.1.2.2 skrll /* Find an alternate and mark those for retransmission */
741 1.1.2.2 skrll alt = sctp_find_alternate_net(stcb, net);
742 1.1.2.2 skrll win_probe = sctp_mark_all_for_resend(stcb, net, alt, &num_mk);
743 1.1.2.2 skrll
744 1.1.2.2 skrll /* FR Loss recovery just ended with the T3. */
745 1.1.2.2 skrll stcb->asoc.fast_retran_loss_recovery = 0;
746 1.1.2.2 skrll
747 1.1.2.2 skrll /* setup the sat loss recovery that prevents
748 1.1.2.2 skrll * satellite cwnd advance.
749 1.1.2.2 skrll */
750 1.1.2.2 skrll stcb->asoc.sat_t3_loss_recovery = 1;
751 1.1.2.2 skrll stcb->asoc.sat_t3_recovery_tsn = stcb->asoc.sending_seq;
752 1.1.2.2 skrll
753 1.1.2.2 skrll /* Backoff the timer and cwnd */
754 1.1.2.2 skrll sctp_backoff_on_timeout(stcb, net, win_probe, num_mk);
755 1.1.2.2 skrll if (win_probe == 0) {
756 1.1.2.2 skrll /* We don't do normal threshold management on window probes */
757 1.1.2.2 skrll if (sctp_threshold_management(inp, stcb, net,
758 1.1.2.2 skrll stcb->asoc.max_send_times)) {
759 1.1.2.2 skrll /* Association was destroyed */
760 1.1.2.2 skrll return (1);
761 1.1.2.2 skrll } else {
762 1.1.2.2 skrll if (net != stcb->asoc.primary_destination) {
763 1.1.2.2 skrll /* send a immediate HB if our RTO is stale */
764 1.1.2.2 skrll struct timeval now;
765 1.1.2.2 skrll unsigned int ms_goneby;
766 1.1.2.2 skrll SCTP_GETTIME_TIMEVAL(&now);
767 1.1.2.2 skrll if (net->last_sent_time.tv_sec) {
768 1.1.2.2 skrll ms_goneby = (now.tv_sec - net->last_sent_time.tv_sec) * 1000;
769 1.1.2.2 skrll } else {
770 1.1.2.2 skrll ms_goneby = 0;
771 1.1.2.2 skrll }
772 1.1.2.2 skrll if ((ms_goneby > net->RTO) || (net->RTO == 0)) {
773 1.1.2.2 skrll /* no recent feed back in an RTO or more, request a RTT update */
774 1.1.2.2 skrll sctp_send_hb(stcb, 1, net);
775 1.1.2.2 skrll }
776 1.1.2.2 skrll }
777 1.1.2.2 skrll }
778 1.1.2.2 skrll } else {
779 1.1.2.2 skrll /*
780 1.1.2.2 skrll * For a window probe we don't penalize the net's but only
781 1.1.2.2 skrll * the association. This may fail it if SACKs are not coming
782 1.1.2.2 skrll * back. If sack's are coming with rwnd locked at 0, we will
783 1.1.2.2 skrll * continue to hold things waiting for rwnd to raise
784 1.1.2.2 skrll */
785 1.1.2.2 skrll if (sctp_threshold_management(inp, stcb, NULL,
786 1.1.2.2 skrll stcb->asoc.max_send_times)) {
787 1.1.2.2 skrll /* Association was destroyed */
788 1.1.2.2 skrll return (1);
789 1.1.2.2 skrll }
790 1.1.2.2 skrll }
791 1.1.2.2 skrll if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) {
792 1.1.2.2 skrll /* Move all pending over too */
793 1.1.2.2 skrll sctp_move_all_chunks_to_alt(stcb, net, alt);
794 1.1.2.2 skrll /* Was it our primary? */
795 1.1.2.2 skrll if ((stcb->asoc.primary_destination == net) && (alt != net)) {
796 1.1.2.2 skrll /*
797 1.1.2.2 skrll * Yes, note it as such and find an alternate
798 1.1.2.2 skrll * note: this means HB code must use this to resent
799 1.1.2.2 skrll * the primary if it goes active AND if someone does
800 1.1.2.2 skrll * a change-primary then this flag must be cleared
801 1.1.2.2 skrll * from any net structures.
802 1.1.2.2 skrll */
803 1.1.2.2 skrll if (sctp_set_primary_addr(stcb,
804 1.1.2.2 skrll (struct sockaddr *)NULL,
805 1.1.2.2 skrll alt) == 0) {
806 1.1.2.2 skrll net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
807 1.1.2.2 skrll net->src_addr_selected = 0;
808 1.1.2.2 skrll }
809 1.1.2.2 skrll }
810 1.1.2.2 skrll }
811 1.1.2.2 skrll /*
812 1.1.2.2 skrll * Special case for cookie-echo'ed case, we don't do output
813 1.1.2.2 skrll * but must await the COOKIE-ACK before retransmission
814 1.1.2.2 skrll */
815 1.1.2.2 skrll if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
816 1.1.2.2 skrll /*
817 1.1.2.2 skrll * Here we just reset the timer and start again since we
818 1.1.2.2 skrll * have not established the asoc
819 1.1.2.2 skrll */
820 1.1.2.2 skrll #ifdef SCTP_DEBUG
821 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
822 1.1.2.2 skrll printf("Special cookie case return\n");
823 1.1.2.2 skrll }
824 1.1.2.2 skrll #endif /* SCTP_DEBUG */
825 1.1.2.2 skrll sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
826 1.1.2.2 skrll return (0);
827 1.1.2.2 skrll }
828 1.1.2.2 skrll if (stcb->asoc.peer_supports_prsctp) {
829 1.1.2.2 skrll struct sctp_tmit_chunk *lchk;
830 1.1.2.2 skrll lchk = sctp_try_advance_peer_ack_point(stcb, &stcb->asoc);
831 1.1.2.2 skrll /* C3. See if we need to send a Fwd-TSN */
832 1.1.2.2 skrll if (compare_with_wrap(stcb->asoc.advanced_peer_ack_point,
833 1.1.2.2 skrll stcb->asoc.last_acked_seq, MAX_TSN)) {
834 1.1.2.2 skrll /*
835 1.1.2.2 skrll * ISSUE with ECN, see FWD-TSN processing for notes
836 1.1.2.2 skrll * on issues that will occur when the ECN NONCE stuff
837 1.1.2.2 skrll * is put into SCTP for cross checking.
838 1.1.2.2 skrll */
839 1.1.2.2 skrll #ifdef SCTP_DEBUG
840 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
841 1.1.2.2 skrll printf("Forward TSN time\n");
842 1.1.2.2 skrll }
843 1.1.2.2 skrll #endif /* SCTP_DEBUG */
844 1.1.2.2 skrll send_forward_tsn(stcb, &stcb->asoc);
845 1.1.2.2 skrll if (lchk) {
846 1.1.2.2 skrll /* Assure a timer is up */
847 1.1.2.2 skrll sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, lchk->whoTo);
848 1.1.2.2 skrll }
849 1.1.2.2 skrll }
850 1.1.2.2 skrll }
851 1.1.2.2 skrll return (0);
852 1.1.2.2 skrll }
853 1.1.2.2 skrll
854 1.1.2.2 skrll int
855 1.1.2.2 skrll sctp_t1init_timer(struct sctp_inpcb *inp,
856 1.1.2.2 skrll struct sctp_tcb *stcb,
857 1.1.2.2 skrll struct sctp_nets *net)
858 1.1.2.2 skrll {
859 1.1.2.2 skrll /* bump the thresholds */
860 1.1.2.2 skrll if (stcb->asoc.delayed_connection) {
861 1.1.2.2 skrll /* special hook for delayed connection. The
862 1.1.2.2 skrll * library did NOT complete the rest of its
863 1.1.2.2 skrll * sends.
864 1.1.2.2 skrll */
865 1.1.2.2 skrll stcb->asoc.delayed_connection = 0;
866 1.1.2.2 skrll sctp_send_initiate(inp, stcb);
867 1.1.2.2 skrll return (0);
868 1.1.2.2 skrll }
869 1.1.2.2 skrll if (sctp_threshold_management(inp, stcb, net,
870 1.1.2.2 skrll stcb->asoc.max_init_times)) {
871 1.1.2.2 skrll /* Association was destroyed */
872 1.1.2.2 skrll return (1);
873 1.1.2.2 skrll }
874 1.1.2.2 skrll stcb->asoc.dropped_special_cnt = 0;
875 1.1.2.2 skrll sctp_backoff_on_timeout(stcb, stcb->asoc.primary_destination, 1, 0);
876 1.1.2.2 skrll if (stcb->asoc.initial_init_rto_max < net->RTO) {
877 1.1.2.2 skrll net->RTO = stcb->asoc.initial_init_rto_max;
878 1.1.2.2 skrll }
879 1.1.2.2 skrll if (stcb->asoc.numnets > 1) {
880 1.1.2.2 skrll /* If we have more than one addr use it */
881 1.1.2.2 skrll struct sctp_nets *alt;
882 1.1.2.2 skrll alt = sctp_find_alternate_net(stcb, stcb->asoc.primary_destination);
883 1.1.2.2 skrll if ((alt != NULL) && (alt != stcb->asoc.primary_destination)) {
884 1.1.2.2 skrll sctp_move_all_chunks_to_alt(stcb, stcb->asoc.primary_destination, alt);
885 1.1.2.2 skrll stcb->asoc.primary_destination = alt;
886 1.1.2.2 skrll }
887 1.1.2.2 skrll }
888 1.1.2.2 skrll /* Send out a new init */
889 1.1.2.2 skrll sctp_send_initiate(inp, stcb);
890 1.1.2.2 skrll return (0);
891 1.1.2.2 skrll }
892 1.1.2.2 skrll
893 1.1.2.2 skrll /*
894 1.1.2.2 skrll * For cookie and asconf we actually need to find and mark for resend,
895 1.1.2.2 skrll * then increment the resend counter (after all the threshold management
896 1.1.2.2 skrll * stuff of course).
897 1.1.2.2 skrll */
898 1.1.2.2 skrll int sctp_cookie_timer(struct sctp_inpcb *inp,
899 1.1.2.2 skrll struct sctp_tcb *stcb,
900 1.1.2.2 skrll struct sctp_nets *net)
901 1.1.2.2 skrll {
902 1.1.2.2 skrll struct sctp_nets *alt;
903 1.1.2.2 skrll struct sctp_tmit_chunk *cookie;
904 1.1.2.2 skrll /* first before all else we must find the cookie */
905 1.1.2.2 skrll TAILQ_FOREACH(cookie, &stcb->asoc.control_send_queue, sctp_next) {
906 1.1.2.2 skrll if (cookie->rec.chunk_id == SCTP_COOKIE_ECHO) {
907 1.1.2.2 skrll break;
908 1.1.2.2 skrll }
909 1.1.2.2 skrll }
910 1.1.2.2 skrll if (cookie == NULL) {
911 1.1.2.2 skrll if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
912 1.1.2.2 skrll /* FOOBAR! */
913 1.1.2.2 skrll struct mbuf *oper;
914 1.1.2.2 skrll MGET(oper, M_DONTWAIT, MT_DATA);
915 1.1.2.2 skrll if (oper) {
916 1.1.2.2 skrll struct sctp_paramhdr *ph;
917 1.1.2.2 skrll u_int32_t *ippp;
918 1.1.2.2 skrll
919 1.1.2.2 skrll oper->m_len = sizeof(struct sctp_paramhdr) +
920 1.1.2.2 skrll sizeof(*ippp);
921 1.1.2.2 skrll ph = mtod(oper, struct sctp_paramhdr *);
922 1.1.2.2 skrll ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
923 1.1.2.2 skrll ph->param_length = htons(oper->m_len);
924 1.1.2.2 skrll ippp = (u_int32_t *)(ph + 1);
925 1.1.2.2 skrll *ippp = htonl(0x40000002);
926 1.1.2.2 skrll }
927 1.1.2.2 skrll sctp_abort_an_association(inp, stcb, SCTP_INTERNAL_ERROR,
928 1.1.2.2 skrll oper);
929 1.1.2.2 skrll }
930 1.1.2.2 skrll return (1);
931 1.1.2.2 skrll }
932 1.1.2.2 skrll /* Ok we found the cookie, threshold management next */
933 1.1.2.2 skrll if (sctp_threshold_management(inp, stcb, cookie->whoTo,
934 1.1.2.2 skrll stcb->asoc.max_init_times)) {
935 1.1.2.2 skrll /* Assoc is over */
936 1.1.2.2 skrll return (1);
937 1.1.2.2 skrll }
938 1.1.2.2 skrll /*
939 1.1.2.2 skrll * cleared theshold management now lets backoff the address &
940 1.1.2.2 skrll * select an alternate
941 1.1.2.2 skrll */
942 1.1.2.2 skrll stcb->asoc.dropped_special_cnt = 0;
943 1.1.2.2 skrll sctp_backoff_on_timeout(stcb, cookie->whoTo, 1, 0);
944 1.1.2.2 skrll alt = sctp_find_alternate_net(stcb, cookie->whoTo);
945 1.1.2.2 skrll if (alt != cookie->whoTo) {
946 1.1.2.2 skrll sctp_free_remote_addr(cookie->whoTo);
947 1.1.2.2 skrll cookie->whoTo = alt;
948 1.1.2.2 skrll alt->ref_count++;
949 1.1.2.2 skrll }
950 1.1.2.2 skrll /* Now mark the retran info */
951 1.1.2.2 skrll if (cookie->sent != SCTP_DATAGRAM_RESEND) {
952 1.1.2.2 skrll stcb->asoc.sent_queue_retran_cnt++;
953 1.1.2.2 skrll }
954 1.1.2.2 skrll cookie->sent = SCTP_DATAGRAM_RESEND;
955 1.1.2.2 skrll /*
956 1.1.2.2 skrll * Now call the output routine to kick out the cookie again, Note we
957 1.1.2.2 skrll * don't mark any chunks for retran so that FR will need to kick in
958 1.1.2.2 skrll * to move these (or a send timer).
959 1.1.2.2 skrll */
960 1.1.2.2 skrll return (0);
961 1.1.2.2 skrll }
962 1.1.2.2 skrll
963 1.1.2.2 skrll int sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
964 1.1.2.2 skrll struct sctp_nets *net)
965 1.1.2.2 skrll {
966 1.1.2.2 skrll struct sctp_nets *alt;
967 1.1.2.2 skrll struct sctp_tmit_chunk *strrst, *chk;
968 1.1.2.2 skrll struct sctp_stream_reset_req *strreq;
969 1.1.2.2 skrll /* find the existing STRRESET */
970 1.1.2.2 skrll TAILQ_FOREACH(strrst, &stcb->asoc.control_send_queue,
971 1.1.2.2 skrll sctp_next) {
972 1.1.2.2 skrll if (strrst->rec.chunk_id == SCTP_STREAM_RESET) {
973 1.1.2.2 skrll /* is it what we want */
974 1.1.2.2 skrll strreq = mtod(strrst->data, struct sctp_stream_reset_req *);
975 1.1.2.2 skrll if (strreq->sr_req.ph.param_type == ntohs(SCTP_STR_RESET_REQUEST)) {
976 1.1.2.2 skrll break;
977 1.1.2.2 skrll }
978 1.1.2.2 skrll }
979 1.1.2.2 skrll }
980 1.1.2.2 skrll if (strrst == NULL) {
981 1.1.2.2 skrll #ifdef SCTP_DEBUG
982 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
983 1.1.2.2 skrll printf("Strange, strreset timer fires, but I can't find an str-reset?\n");
984 1.1.2.2 skrll }
985 1.1.2.2 skrll #endif /* SCTP_DEBUG */
986 1.1.2.2 skrll return (0);
987 1.1.2.2 skrll }
988 1.1.2.2 skrll /* do threshold management */
989 1.1.2.2 skrll if (sctp_threshold_management(inp, stcb, strrst->whoTo,
990 1.1.2.2 skrll stcb->asoc.max_send_times)) {
991 1.1.2.2 skrll /* Assoc is over */
992 1.1.2.2 skrll return (1);
993 1.1.2.2 skrll }
994 1.1.2.2 skrll
995 1.1.2.2 skrll /*
996 1.1.2.2 skrll * cleared theshold management
997 1.1.2.2 skrll * now lets backoff the address & select an alternate
998 1.1.2.2 skrll */
999 1.1.2.2 skrll sctp_backoff_on_timeout(stcb, strrst->whoTo, 1, 0);
1000 1.1.2.2 skrll alt = sctp_find_alternate_net(stcb, strrst->whoTo);
1001 1.1.2.2 skrll sctp_free_remote_addr(strrst->whoTo);
1002 1.1.2.2 skrll strrst->whoTo = alt;
1003 1.1.2.2 skrll alt->ref_count++;
1004 1.1.2.2 skrll
1005 1.1.2.2 skrll /* See if a ECN Echo is also stranded */
1006 1.1.2.2 skrll TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
1007 1.1.2.2 skrll if ((chk->whoTo == net) &&
1008 1.1.2.2 skrll (chk->rec.chunk_id == SCTP_ECN_ECHO)) {
1009 1.1.2.2 skrll sctp_free_remote_addr(chk->whoTo);
1010 1.1.2.2 skrll if (chk->sent != SCTP_DATAGRAM_RESEND) {
1011 1.1.2.2 skrll chk->sent = SCTP_DATAGRAM_RESEND;
1012 1.1.2.2 skrll stcb->asoc.sent_queue_retran_cnt++;
1013 1.1.2.2 skrll }
1014 1.1.2.2 skrll chk->whoTo = alt;
1015 1.1.2.2 skrll alt->ref_count++;
1016 1.1.2.2 skrll }
1017 1.1.2.2 skrll }
1018 1.1.2.2 skrll if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) {
1019 1.1.2.2 skrll /*
1020 1.1.2.2 skrll * If the address went un-reachable, we need to move
1021 1.1.2.2 skrll * to alternates for ALL chk's in queue
1022 1.1.2.2 skrll */
1023 1.1.2.2 skrll sctp_move_all_chunks_to_alt(stcb, net, alt);
1024 1.1.2.2 skrll }
1025 1.1.2.2 skrll /* mark the retran info */
1026 1.1.2.2 skrll if (strrst->sent != SCTP_DATAGRAM_RESEND)
1027 1.1.2.2 skrll stcb->asoc.sent_queue_retran_cnt++;
1028 1.1.2.2 skrll strrst->sent = SCTP_DATAGRAM_RESEND;
1029 1.1.2.2 skrll
1030 1.1.2.2 skrll /* restart the timer */
1031 1.1.2.2 skrll sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, inp, stcb, strrst->whoTo);
1032 1.1.2.2 skrll return (0);
1033 1.1.2.2 skrll }
1034 1.1.2.2 skrll
1035 1.1.2.2 skrll int sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1036 1.1.2.2 skrll struct sctp_nets *net)
1037 1.1.2.2 skrll {
1038 1.1.2.2 skrll struct sctp_nets *alt;
1039 1.1.2.2 skrll struct sctp_tmit_chunk *asconf, *chk;
1040 1.1.2.2 skrll
1041 1.1.2.2 skrll /* is this the first send, or a retransmission? */
1042 1.1.2.2 skrll if (stcb->asoc.asconf_sent == 0) {
1043 1.1.2.2 skrll /* compose a new ASCONF chunk and send it */
1044 1.1.2.2 skrll sctp_send_asconf(stcb, net);
1045 1.1.2.2 skrll } else {
1046 1.1.2.2 skrll /* Retransmission of the existing ASCONF needed... */
1047 1.1.2.2 skrll
1048 1.1.2.2 skrll /* find the existing ASCONF */
1049 1.1.2.2 skrll TAILQ_FOREACH(asconf, &stcb->asoc.control_send_queue,
1050 1.1.2.2 skrll sctp_next) {
1051 1.1.2.2 skrll if (asconf->rec.chunk_id == SCTP_ASCONF) {
1052 1.1.2.2 skrll break;
1053 1.1.2.2 skrll }
1054 1.1.2.2 skrll }
1055 1.1.2.2 skrll if (asconf == NULL) {
1056 1.1.2.2 skrll #ifdef SCTP_DEBUG
1057 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
1058 1.1.2.2 skrll printf("Strange, asconf timer fires, but I can't find an asconf?\n");
1059 1.1.2.2 skrll }
1060 1.1.2.2 skrll #endif /* SCTP_DEBUG */
1061 1.1.2.2 skrll return (0);
1062 1.1.2.2 skrll }
1063 1.1.2.2 skrll /* do threshold management */
1064 1.1.2.2 skrll if (sctp_threshold_management(inp, stcb, asconf->whoTo,
1065 1.1.2.2 skrll stcb->asoc.max_send_times)) {
1066 1.1.2.2 skrll /* Assoc is over */
1067 1.1.2.2 skrll return (1);
1068 1.1.2.2 skrll }
1069 1.1.2.2 skrll
1070 1.1.2.2 skrll /* PETER? FIX? How will the following code ever run? If
1071 1.1.2.2 skrll * the max_send_times is hit, threshold managment will
1072 1.1.2.2 skrll * blow away the association?
1073 1.1.2.2 skrll */
1074 1.1.2.2 skrll if (asconf->snd_count > stcb->asoc.max_send_times) {
1075 1.1.2.2 skrll /*
1076 1.1.2.2 skrll * Something is rotten, peer is not responding to
1077 1.1.2.2 skrll * ASCONFs but maybe is to data etc. e.g. it is not
1078 1.1.2.2 skrll * properly handling the chunk type upper bits
1079 1.1.2.2 skrll * Mark this peer as ASCONF incapable and cleanup
1080 1.1.2.2 skrll */
1081 1.1.2.2 skrll #ifdef SCTP_DEBUG
1082 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
1083 1.1.2.2 skrll printf("asconf_timer: Peer has not responded to our repeated ASCONFs\n");
1084 1.1.2.2 skrll }
1085 1.1.2.2 skrll #endif /* SCTP_DEBUG */
1086 1.1.2.2 skrll sctp_asconf_cleanup(stcb, net);
1087 1.1.2.2 skrll return (0);
1088 1.1.2.2 skrll }
1089 1.1.2.2 skrll /*
1090 1.1.2.2 skrll * cleared theshold management
1091 1.1.2.2 skrll * now lets backoff the address & select an alternate
1092 1.1.2.2 skrll */
1093 1.1.2.2 skrll sctp_backoff_on_timeout(stcb, asconf->whoTo, 1, 0);
1094 1.1.2.2 skrll alt = sctp_find_alternate_net(stcb, asconf->whoTo);
1095 1.1.2.2 skrll sctp_free_remote_addr(asconf->whoTo);
1096 1.1.2.2 skrll asconf->whoTo = alt;
1097 1.1.2.2 skrll alt->ref_count++;
1098 1.1.2.2 skrll
1099 1.1.2.2 skrll /* See if a ECN Echo is also stranded */
1100 1.1.2.2 skrll TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
1101 1.1.2.2 skrll if ((chk->whoTo == net) &&
1102 1.1.2.2 skrll (chk->rec.chunk_id == SCTP_ECN_ECHO)) {
1103 1.1.2.2 skrll sctp_free_remote_addr(chk->whoTo);
1104 1.1.2.2 skrll chk->whoTo = alt;
1105 1.1.2.2 skrll if (chk->sent != SCTP_DATAGRAM_RESEND) {
1106 1.1.2.2 skrll chk->sent = SCTP_DATAGRAM_RESEND;
1107 1.1.2.2 skrll stcb->asoc.sent_queue_retran_cnt++;
1108 1.1.2.2 skrll }
1109 1.1.2.2 skrll alt->ref_count++;
1110 1.1.2.2 skrll
1111 1.1.2.2 skrll }
1112 1.1.2.2 skrll }
1113 1.1.2.2 skrll if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) {
1114 1.1.2.2 skrll /*
1115 1.1.2.2 skrll * If the address went un-reachable, we need to move
1116 1.1.2.2 skrll * to alternates for ALL chk's in queue
1117 1.1.2.2 skrll */
1118 1.1.2.2 skrll sctp_move_all_chunks_to_alt(stcb, net, alt);
1119 1.1.2.2 skrll }
1120 1.1.2.2 skrll /* mark the retran info */
1121 1.1.2.2 skrll if (asconf->sent != SCTP_DATAGRAM_RESEND)
1122 1.1.2.2 skrll stcb->asoc.sent_queue_retran_cnt++;
1123 1.1.2.2 skrll asconf->sent = SCTP_DATAGRAM_RESEND;
1124 1.1.2.2 skrll }
1125 1.1.2.2 skrll return (0);
1126 1.1.2.2 skrll }
1127 1.1.2.2 skrll
1128 1.1.2.2 skrll /*
1129 1.1.2.2 skrll * For the shutdown and shutdown-ack, we do not keep one around on the
1130 1.1.2.2 skrll * control queue. This means we must generate a new one and call the general
1131 1.1.2.2 skrll * chunk output routine, AFTER having done threshold
1132 1.1.2.2 skrll * management.
1133 1.1.2.2 skrll */
1134 1.1.2.2 skrll int
1135 1.1.2.2 skrll sctp_shutdown_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1136 1.1.2.2 skrll struct sctp_nets *net)
1137 1.1.2.2 skrll {
1138 1.1.2.2 skrll struct sctp_nets *alt;
1139 1.1.2.2 skrll /* first threshold managment */
1140 1.1.2.2 skrll if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
1141 1.1.2.2 skrll /* Assoc is over */
1142 1.1.2.2 skrll return (1);
1143 1.1.2.2 skrll }
1144 1.1.2.2 skrll /* second select an alternative */
1145 1.1.2.2 skrll alt = sctp_find_alternate_net(stcb, net);
1146 1.1.2.2 skrll
1147 1.1.2.2 skrll /* third generate a shutdown into the queue for out net */
1148 1.1.2.2 skrll #ifdef SCTP_DEBUG
1149 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_OUTPUT4) {
1150 1.1.2.2 skrll printf("%s:%d sends a shutdown\n",
1151 1.1.2.2 skrll __FILE__,
1152 1.1.2.2 skrll __LINE__
1153 1.1.2.2 skrll );
1154 1.1.2.2 skrll }
1155 1.1.2.2 skrll #endif
1156 1.1.2.2 skrll if (alt) {
1157 1.1.2.2 skrll sctp_send_shutdown(stcb, alt);
1158 1.1.2.2 skrll } else {
1159 1.1.2.2 skrll /* if alt is NULL, there is no dest
1160 1.1.2.2 skrll * to send to??
1161 1.1.2.2 skrll */
1162 1.1.2.2 skrll return (0);
1163 1.1.2.2 skrll }
1164 1.1.2.2 skrll /* fourth restart timer */
1165 1.1.2.2 skrll sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, inp, stcb, alt);
1166 1.1.2.2 skrll return (0);
1167 1.1.2.2 skrll }
1168 1.1.2.2 skrll
1169 1.1.2.2 skrll int sctp_shutdownack_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1170 1.1.2.2 skrll struct sctp_nets *net)
1171 1.1.2.2 skrll {
1172 1.1.2.2 skrll struct sctp_nets *alt;
1173 1.1.2.2 skrll /* first threshold managment */
1174 1.1.2.2 skrll if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
1175 1.1.2.2 skrll /* Assoc is over */
1176 1.1.2.2 skrll return (1);
1177 1.1.2.2 skrll }
1178 1.1.2.2 skrll /* second select an alternative */
1179 1.1.2.2 skrll alt = sctp_find_alternate_net(stcb, net);
1180 1.1.2.2 skrll
1181 1.1.2.2 skrll /* third generate a shutdown into the queue for out net */
1182 1.1.2.2 skrll sctp_send_shutdown_ack(stcb, alt);
1183 1.1.2.2 skrll
1184 1.1.2.2 skrll /* fourth restart timer */
1185 1.1.2.2 skrll sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK, inp, stcb, alt);
1186 1.1.2.2 skrll return (0);
1187 1.1.2.2 skrll }
1188 1.1.2.2 skrll
1189 1.1.2.2 skrll static void
1190 1.1.2.2 skrll sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp,
1191 1.1.2.2 skrll struct sctp_tcb *stcb)
1192 1.1.2.2 skrll {
1193 1.1.2.2 skrll struct sctp_stream_out *outs;
1194 1.1.2.2 skrll struct sctp_tmit_chunk *chk;
1195 1.1.2.2 skrll unsigned int chks_in_queue=0;
1196 1.1.2.2 skrll
1197 1.1.2.2 skrll if ((stcb == NULL) || (inp == NULL))
1198 1.1.2.2 skrll return;
1199 1.1.2.2 skrll if (TAILQ_EMPTY(&stcb->asoc.out_wheel)) {
1200 1.1.2.2 skrll printf("Strange, out_wheel empty nothing on sent/send and tot=%lu?\n",
1201 1.1.2.2 skrll (u_long)stcb->asoc.total_output_queue_size);
1202 1.1.2.2 skrll stcb->asoc.total_output_queue_size = 0;
1203 1.1.2.2 skrll return;
1204 1.1.2.2 skrll }
1205 1.1.2.2 skrll if (stcb->asoc.sent_queue_retran_cnt) {
1206 1.1.2.2 skrll printf("Hmm, sent_queue_retran_cnt is non-zero %d\n",
1207 1.1.2.2 skrll stcb->asoc.sent_queue_retran_cnt);
1208 1.1.2.2 skrll stcb->asoc.sent_queue_retran_cnt = 0;
1209 1.1.2.2 skrll }
1210 1.1.2.2 skrll /* Check to see if some data queued, if so report it */
1211 1.1.2.2 skrll TAILQ_FOREACH(outs, &stcb->asoc.out_wheel, next_spoke) {
1212 1.1.2.2 skrll if (!TAILQ_EMPTY(&outs->outqueue)) {
1213 1.1.2.2 skrll TAILQ_FOREACH(chk, &outs->outqueue, sctp_next) {
1214 1.1.2.2 skrll chks_in_queue++;
1215 1.1.2.2 skrll }
1216 1.1.2.2 skrll }
1217 1.1.2.2 skrll }
1218 1.1.2.2 skrll if (chks_in_queue != stcb->asoc.stream_queue_cnt) {
1219 1.1.2.2 skrll printf("Hmm, stream queue cnt at %d I counted %d in stream out wheel\n",
1220 1.1.2.2 skrll stcb->asoc.stream_queue_cnt, chks_in_queue);
1221 1.1.2.2 skrll }
1222 1.1.2.2 skrll if (chks_in_queue) {
1223 1.1.2.2 skrll /* call the output queue function */
1224 1.1.2.2 skrll sctp_chunk_output(inp, stcb, 1);
1225 1.1.2.2 skrll if ((TAILQ_EMPTY(&stcb->asoc.send_queue)) &&
1226 1.1.2.2 skrll (TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
1227 1.1.2.2 skrll /* Probably should go in and make it go back through and add fragments allowed */
1228 1.1.2.2 skrll printf("Still nothing moved %d chunks are stuck\n", chks_in_queue);
1229 1.1.2.2 skrll }
1230 1.1.2.2 skrll } else {
1231 1.1.2.2 skrll printf("Found no chunks on any queue tot:%lu\n",
1232 1.1.2.2 skrll (u_long)stcb->asoc.total_output_queue_size);
1233 1.1.2.2 skrll stcb->asoc.total_output_queue_size = 0;
1234 1.1.2.2 skrll }
1235 1.1.2.2 skrll }
1236 1.1.2.2 skrll
1237 1.1.2.2 skrll int
1238 1.1.2.2 skrll sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1239 1.1.2.2 skrll struct sctp_nets *net)
1240 1.1.2.2 skrll {
1241 1.1.2.2 skrll int cnt_of_unconf=0;
1242 1.1.2.2 skrll
1243 1.1.2.2 skrll if (net) {
1244 1.1.2.2 skrll if (net->hb_responded == 0) {
1245 1.1.2.2 skrll sctp_backoff_on_timeout(stcb, net, 1, 0);
1246 1.1.2.2 skrll }
1247 1.1.2.2 skrll /* Zero PBA, if it needs it */
1248 1.1.2.2 skrll if (net->partial_bytes_acked) {
1249 1.1.2.2 skrll net->partial_bytes_acked = 0;
1250 1.1.2.2 skrll }
1251 1.1.2.2 skrll }
1252 1.1.2.2 skrll TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1253 1.1.2.2 skrll if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
1254 1.1.2.2 skrll (net->dest_state & SCTP_ADDR_REACHABLE)) {
1255 1.1.2.2 skrll cnt_of_unconf++;
1256 1.1.2.2 skrll }
1257 1.1.2.2 skrll }
1258 1.1.2.2 skrll if ((stcb->asoc.total_output_queue_size > 0) &&
1259 1.1.2.2 skrll (TAILQ_EMPTY(&stcb->asoc.send_queue)) &&
1260 1.1.2.2 skrll (TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
1261 1.1.2.2 skrll sctp_audit_stream_queues_for_size(inp, stcb);
1262 1.1.2.2 skrll }
1263 1.1.2.2 skrll /* Send a new HB, this will do threshold managment, pick a new dest */
1264 1.1.2.2 skrll if (sctp_send_hb(stcb, 0, NULL) < 0) {
1265 1.1.2.2 skrll return (1);
1266 1.1.2.2 skrll }
1267 1.1.2.2 skrll if (cnt_of_unconf > 1) {
1268 1.1.2.2 skrll /*
1269 1.1.2.2 skrll * this will send out extra hb's up to maxburst if
1270 1.1.2.2 skrll * there are any unconfirmed addresses.
1271 1.1.2.2 skrll */
1272 1.1.2.2 skrll int cnt_sent = 1;
1273 1.1.2.2 skrll while ((cnt_sent < stcb->asoc.max_burst) && (cnt_of_unconf > 1)) {
1274 1.1.2.2 skrll if (sctp_send_hb(stcb, 0, NULL) == 0)
1275 1.1.2.2 skrll break;
1276 1.1.2.2 skrll cnt_of_unconf--;
1277 1.1.2.2 skrll cnt_sent++;
1278 1.1.2.2 skrll }
1279 1.1.2.2 skrll }
1280 1.1.2.2 skrll return (0);
1281 1.1.2.2 skrll }
1282 1.1.2.2 skrll
1283 1.1.2.2 skrll #define SCTP_NUMBER_OF_MTU_SIZES 18
1284 1.1.2.2 skrll static u_int32_t mtu_sizes[]={
1285 1.1.2.2 skrll 68,
1286 1.1.2.2 skrll 296,
1287 1.1.2.2 skrll 508,
1288 1.1.2.2 skrll 512,
1289 1.1.2.2 skrll 544,
1290 1.1.2.2 skrll 576,
1291 1.1.2.2 skrll 1006,
1292 1.1.2.2 skrll 1492,
1293 1.1.2.2 skrll 1500,
1294 1.1.2.2 skrll 1536,
1295 1.1.2.2 skrll 2002,
1296 1.1.2.2 skrll 2048,
1297 1.1.2.2 skrll 4352,
1298 1.1.2.2 skrll 4464,
1299 1.1.2.2 skrll 8166,
1300 1.1.2.2 skrll 17914,
1301 1.1.2.2 skrll 32000,
1302 1.1.2.2 skrll 65535
1303 1.1.2.2 skrll };
1304 1.1.2.2 skrll
1305 1.1.2.2 skrll
1306 1.1.2.2 skrll static u_int32_t
1307 1.1.2.2 skrll sctp_getnext_mtu(struct sctp_inpcb *inp, u_int32_t cur_mtu)
1308 1.1.2.2 skrll {
1309 1.1.2.2 skrll /* select another MTU that is just bigger than this one */
1310 1.1.2.2 skrll int i;
1311 1.1.2.2 skrll
1312 1.1.2.2 skrll for (i = 0; i < SCTP_NUMBER_OF_MTU_SIZES; i++) {
1313 1.1.2.2 skrll if (cur_mtu < mtu_sizes[i]) {
1314 1.1.2.2 skrll /* no max_mtu is bigger than this one */
1315 1.1.2.2 skrll return (mtu_sizes[i]);
1316 1.1.2.2 skrll }
1317 1.1.2.2 skrll }
1318 1.1.2.2 skrll /* here return the highest allowable */
1319 1.1.2.2 skrll return (cur_mtu);
1320 1.1.2.2 skrll }
1321 1.1.2.2 skrll
1322 1.1.2.2 skrll
1323 1.1.2.2 skrll void sctp_pathmtu_timer(struct sctp_inpcb *inp,
1324 1.1.2.2 skrll struct sctp_tcb *stcb,
1325 1.1.2.2 skrll struct sctp_nets *net)
1326 1.1.2.2 skrll {
1327 1.1.2.2 skrll u_int32_t next_mtu;
1328 1.1.2.2 skrll struct rtentry *rt;
1329 1.1.2.2 skrll
1330 1.1.2.2 skrll /* restart the timer in any case */
1331 1.1.2.2 skrll next_mtu = sctp_getnext_mtu(inp, net->mtu);
1332 1.1.2.2 skrll if (next_mtu <= net->mtu) {
1333 1.1.2.2 skrll /* nothing to do */
1334 1.1.2.2 skrll return;
1335 1.1.2.2 skrll }
1336 1.1.2.2 skrll rt = rtcache_validate(&net->ro);
1337 1.1.2.2 skrll if (rt != NULL) {
1338 1.1.2.2 skrll /* only if we have a route and interface do we
1339 1.1.2.2 skrll * set anything. Note we always restart
1340 1.1.2.2 skrll * the timer though just in case it is updated
1341 1.1.2.2 skrll * (i.e. the ifp) or route/ifp is populated.
1342 1.1.2.2 skrll */
1343 1.1.2.2 skrll if (rt->rt_ifp != NULL) {
1344 1.1.2.2 skrll if (rt->rt_ifp->if_mtu > next_mtu) {
1345 1.1.2.2 skrll /* ok it will fit out the door */
1346 1.1.2.2 skrll net->mtu = next_mtu;
1347 1.1.2.2 skrll }
1348 1.1.2.2 skrll }
1349 1.1.2.2 skrll }
1350 1.1.2.2 skrll /* restart the timer */
1351 1.1.2.2 skrll sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
1352 1.1.2.2 skrll }
1353 1.1.2.2 skrll
1354 1.1.2.2 skrll void sctp_autoclose_timer(struct sctp_inpcb *inp,
1355 1.1.2.2 skrll struct sctp_tcb *stcb,
1356 1.1.2.2 skrll struct sctp_nets *net)
1357 1.1.2.2 skrll {
1358 1.1.2.2 skrll struct timeval tn, *tim_touse;
1359 1.1.2.2 skrll struct sctp_association *asoc;
1360 1.1.2.2 skrll int ticks_gone_by;
1361 1.1.2.2 skrll
1362 1.1.2.2 skrll SCTP_GETTIME_TIMEVAL(&tn);
1363 1.1.2.2 skrll if (stcb->asoc.sctp_autoclose_ticks &&
1364 1.1.2.2 skrll (inp->sctp_flags & SCTP_PCB_FLAGS_AUTOCLOSE)) {
1365 1.1.2.2 skrll /* Auto close is on */
1366 1.1.2.2 skrll asoc = &stcb->asoc;
1367 1.1.2.2 skrll /* pick the time to use */
1368 1.1.2.2 skrll if (asoc->time_last_rcvd.tv_sec >
1369 1.1.2.2 skrll asoc->time_last_sent.tv_sec) {
1370 1.1.2.2 skrll tim_touse = &asoc->time_last_rcvd;
1371 1.1.2.2 skrll } else {
1372 1.1.2.2 skrll tim_touse = &asoc->time_last_sent;
1373 1.1.2.2 skrll }
1374 1.1.2.2 skrll /* Now has long enough transpired to autoclose? */
1375 1.1.2.2 skrll ticks_gone_by = ((tn.tv_sec - tim_touse->tv_sec) * hz);
1376 1.1.2.2 skrll if ((ticks_gone_by > 0) &&
1377 1.1.2.2 skrll (ticks_gone_by >= (int)asoc->sctp_autoclose_ticks)) {
1378 1.1.2.2 skrll /*
1379 1.1.2.2 skrll * autoclose time has hit, call the output routine,
1380 1.1.2.2 skrll * which should do nothing just to be SURE we don't
1381 1.1.2.2 skrll * have hanging data. We can then safely check the
1382 1.1.2.2 skrll * queues and know that we are clear to send shutdown
1383 1.1.2.2 skrll */
1384 1.1.2.2 skrll sctp_chunk_output(inp, stcb, 9);
1385 1.1.2.2 skrll /* Are we clean? */
1386 1.1.2.2 skrll if (TAILQ_EMPTY(&asoc->send_queue) &&
1387 1.1.2.2 skrll TAILQ_EMPTY(&asoc->sent_queue)) {
1388 1.1.2.2 skrll /*
1389 1.1.2.2 skrll * there is nothing queued to send,
1390 1.1.2.2 skrll * so I'm done...
1391 1.1.2.2 skrll */
1392 1.1.2.2 skrll if (SCTP_GET_STATE(asoc) !=
1393 1.1.2.2 skrll SCTP_STATE_SHUTDOWN_SENT) {
1394 1.1.2.2 skrll /* only send SHUTDOWN 1st time thru */
1395 1.1.2.2 skrll #ifdef SCTP_DEBUG
1396 1.1.2.2 skrll if (sctp_debug_on & SCTP_DEBUG_OUTPUT4) {
1397 1.1.2.2 skrll printf("%s:%d sends a shutdown\n",
1398 1.1.2.2 skrll __FILE__,
1399 1.1.2.2 skrll __LINE__
1400 1.1.2.2 skrll );
1401 1.1.2.2 skrll }
1402 1.1.2.2 skrll #endif
1403 1.1.2.2 skrll sctp_send_shutdown(stcb, stcb->asoc.primary_destination);
1404 1.1.2.2 skrll asoc->state = SCTP_STATE_SHUTDOWN_SENT;
1405 1.1.2.2 skrll sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
1406 1.1.2.2 skrll stcb->sctp_ep, stcb,
1407 1.1.2.2 skrll asoc->primary_destination);
1408 1.1.2.2 skrll sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
1409 1.1.2.2 skrll stcb->sctp_ep, stcb,
1410 1.1.2.2 skrll asoc->primary_destination);
1411 1.1.2.2 skrll }
1412 1.1.2.2 skrll }
1413 1.1.2.2 skrll } else {
1414 1.1.2.2 skrll /*
1415 1.1.2.2 skrll * No auto close at this time, reset t-o to
1416 1.1.2.2 skrll * check later
1417 1.1.2.2 skrll */
1418 1.1.2.2 skrll int tmp;
1419 1.1.2.2 skrll /* fool the timer startup to use the time left */
1420 1.1.2.2 skrll tmp = asoc->sctp_autoclose_ticks;
1421 1.1.2.2 skrll asoc->sctp_autoclose_ticks -= ticks_gone_by;
1422 1.1.2.2 skrll sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb,
1423 1.1.2.2 skrll net);
1424 1.1.2.2 skrll /* restore the real tick value */
1425 1.1.2.2 skrll asoc->sctp_autoclose_ticks = tmp;
1426 1.1.2.2 skrll }
1427 1.1.2.2 skrll }
1428 1.1.2.2 skrll }
1429 1.1.2.2 skrll
1430 1.1.2.2 skrll void
1431 1.1.2.2 skrll sctp_iterator_timer(struct sctp_iterator *it)
1432 1.1.2.2 skrll {
1433 1.1.2.2 skrll int cnt= 0;
1434 1.1.2.2 skrll /* only one iterator can run at a
1435 1.1.2.2 skrll * time. This is the only way we
1436 1.1.2.2 skrll * can cleanly pull ep's from underneath
1437 1.1.2.2 skrll * all the running interators when a
1438 1.1.2.2 skrll * ep is freed.
1439 1.1.2.2 skrll */
1440 1.1.2.2 skrll SCTP_ITERATOR_LOCK();
1441 1.1.2.2 skrll if (it->inp == NULL) {
1442 1.1.2.2 skrll /* iterator is complete */
1443 1.1.2.2 skrll done_with_iterator:
1444 1.1.2.2 skrll SCTP_ITERATOR_UNLOCK();
1445 1.1.2.2 skrll SCTP_INP_INFO_WLOCK();
1446 1.1.2.2 skrll LIST_REMOVE(it, sctp_nxt_itr);
1447 1.1.2.2 skrll /* stopping the callout is not needed, in theory,
1448 1.1.2.2 skrll * but I am paranoid.
1449 1.1.2.2 skrll */
1450 1.1.2.2 skrll SCTP_INP_INFO_WUNLOCK();
1451 1.1.2.2 skrll callout_stop(&it->tmr.timer);
1452 1.1.2.2 skrll if (it->function_atend != NULL) {
1453 1.1.2.2 skrll (*it->function_atend)(it->pointer, it->val);
1454 1.1.2.2 skrll }
1455 1.1.2.2 skrll callout_destroy(&it->tmr.timer);
1456 1.1.2.2 skrll free(it, M_PCB);
1457 1.1.2.2 skrll return;
1458 1.1.2.2 skrll }
1459 1.1.2.2 skrll select_a_new_ep:
1460 1.1.2.2 skrll SCTP_INP_WLOCK(it->inp);
1461 1.1.2.2 skrll while ((it->pcb_flags) && ((it->inp->sctp_flags & it->pcb_flags) != it->pcb_flags)) {
1462 1.1.2.2 skrll /* we do not like this ep */
1463 1.1.2.2 skrll if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
1464 1.1.2.2 skrll SCTP_INP_WUNLOCK(it->inp);
1465 1.1.2.2 skrll goto done_with_iterator;
1466 1.1.2.2 skrll }
1467 1.1.2.2 skrll SCTP_INP_WUNLOCK(it->inp);
1468 1.1.2.2 skrll it->inp = LIST_NEXT(it->inp, sctp_list);
1469 1.1.2.2 skrll if (it->inp == NULL) {
1470 1.1.2.2 skrll goto done_with_iterator;
1471 1.1.2.2 skrll }
1472 1.1.2.2 skrll SCTP_INP_WLOCK(it->inp);
1473 1.1.2.2 skrll }
1474 1.1.2.2 skrll if ((it->inp->inp_starting_point_for_iterator != NULL) &&
1475 1.1.2.2 skrll (it->inp->inp_starting_point_for_iterator != it)) {
1476 1.1.2.2 skrll printf("Iterator collision, we must wait for other iterator at %p\n",
1477 1.1.2.2 skrll it->inp);
1478 1.1.2.2 skrll SCTP_INP_WUNLOCK(it->inp);
1479 1.1.2.2 skrll goto start_timer_return;
1480 1.1.2.2 skrll }
1481 1.1.2.2 skrll /* now we do the actual write to this guy */
1482 1.1.2.2 skrll it->inp->inp_starting_point_for_iterator = it;
1483 1.1.2.2 skrll SCTP_INP_WUNLOCK(it->inp);
1484 1.1.2.2 skrll SCTP_INP_RLOCK(it->inp);
1485 1.1.2.2 skrll /* if we reach here we found a inp acceptable, now through each
1486 1.1.2.2 skrll * one that has the association in the right state
1487 1.1.2.2 skrll */
1488 1.1.2.2 skrll if (it->stcb == NULL) {
1489 1.1.2.2 skrll it->stcb = LIST_FIRST(&it->inp->sctp_asoc_list);
1490 1.1.2.2 skrll }
1491 1.1.2.2 skrll if (it->stcb->asoc.stcb_starting_point_for_iterator == it) {
1492 1.1.2.2 skrll it->stcb->asoc.stcb_starting_point_for_iterator = NULL;
1493 1.1.2.2 skrll }
1494 1.1.2.2 skrll while (it->stcb) {
1495 1.1.2.2 skrll SCTP_TCB_LOCK(it->stcb);
1496 1.1.2.2 skrll if (it->asoc_state && ((it->stcb->asoc.state & it->asoc_state) != it->asoc_state)) {
1497 1.1.2.2 skrll SCTP_TCB_UNLOCK(it->stcb);
1498 1.1.2.2 skrll it->stcb = LIST_NEXT(it->stcb, sctp_tcblist);
1499 1.1.2.2 skrll continue;
1500 1.1.2.2 skrll }
1501 1.1.2.2 skrll cnt++;
1502 1.1.2.2 skrll /* run function on this one */
1503 1.1.2.2 skrll SCTP_INP_RUNLOCK(it->inp);
1504 1.1.2.2 skrll (*it->function_toapply)(it->inp, it->stcb, it->pointer, it->val);
1505 1.1.2.2 skrll sctp_chunk_output(it->inp, it->stcb, 1);
1506 1.1.2.2 skrll SCTP_TCB_UNLOCK(it->stcb);
1507 1.1.2.2 skrll /* see if we have limited out */
1508 1.1.2.2 skrll if (cnt > SCTP_MAX_ITERATOR_AT_ONCE) {
1509 1.1.2.2 skrll it->stcb->asoc.stcb_starting_point_for_iterator = it;
1510 1.1.2.2 skrll start_timer_return:
1511 1.1.2.2 skrll SCTP_ITERATOR_UNLOCK();
1512 1.1.2.2 skrll sctp_timer_start(SCTP_TIMER_TYPE_ITERATOR, (struct sctp_inpcb *)it, NULL, NULL);
1513 1.1.2.2 skrll return;
1514 1.1.2.2 skrll }
1515 1.1.2.2 skrll SCTP_INP_RLOCK(it->inp);
1516 1.1.2.2 skrll it->stcb = LIST_NEXT(it->stcb, sctp_tcblist);
1517 1.1.2.2 skrll }
1518 1.1.2.2 skrll /* if we reach here, we ran out of stcb's in the inp we are looking at */
1519 1.1.2.2 skrll SCTP_INP_RUNLOCK(it->inp);
1520 1.1.2.2 skrll SCTP_INP_WLOCK(it->inp);
1521 1.1.2.2 skrll it->inp->inp_starting_point_for_iterator = NULL;
1522 1.1.2.2 skrll SCTP_INP_WUNLOCK(it->inp);
1523 1.1.2.2 skrll if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
1524 1.1.2.2 skrll it->inp = NULL;
1525 1.1.2.2 skrll } else {
1526 1.1.2.2 skrll SCTP_INP_INFO_RLOCK();
1527 1.1.2.2 skrll it->inp = LIST_NEXT(it->inp, sctp_list);
1528 1.1.2.2 skrll SCTP_INP_INFO_RUNLOCK();
1529 1.1.2.2 skrll }
1530 1.1.2.2 skrll if (it->inp == NULL) {
1531 1.1.2.2 skrll goto done_with_iterator;
1532 1.1.2.2 skrll }
1533 1.1.2.2 skrll goto select_a_new_ep;
1534 1.1.2.2 skrll }
1535