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