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