xref: /freebsd/sys/netinet/sctp_timer.c (revision c737bf586a50168f29b51e14e9712fe412f18f9b)
1 /*-
2  * Copyright (c) 2001-2007, 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 	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 #ifdef SCTP_DEBUG
175 	if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
176 		printf("Audit invoked on send queue cnt:%d onqueue:%d\n",
177 		    asoc->sent_queue_retran_cnt,
178 		    asoc->sent_queue_cnt);
179 	}
180 #endif				/* SCTP_DEBUG */
181 	asoc->sent_queue_retran_cnt = 0;
182 	asoc->sent_queue_cnt = 0;
183 	TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
184 		if (chk->sent == SCTP_DATAGRAM_RESEND) {
185 			sctp_ucount_incr(asoc->sent_queue_retran_cnt);
186 		}
187 		asoc->sent_queue_cnt++;
188 	}
189 	TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
190 		if (chk->sent == SCTP_DATAGRAM_RESEND) {
191 			sctp_ucount_incr(asoc->sent_queue_retran_cnt);
192 		}
193 	}
194 #ifdef SCTP_DEBUG
195 	if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
196 		printf("Audit completes retran:%d onqueue:%d\n",
197 		    asoc->sent_queue_retran_cnt,
198 		    asoc->sent_queue_cnt);
199 	}
200 #endif				/* SCTP_DEBUG */
201 }
202 
203 int
204 sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
205     struct sctp_nets *net, uint16_t threshold)
206 {
207 	if (net) {
208 		net->error_count++;
209 #ifdef SCTP_DEBUG
210 		if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
211 			printf("Error count for %p now %d thresh:%d\n",
212 			    net, net->error_count,
213 			    net->failure_threshold);
214 		}
215 #endif				/* SCTP_DEBUG */
216 		if (net->error_count > net->failure_threshold) {
217 			/* We had a threshold failure */
218 			if (net->dest_state & SCTP_ADDR_REACHABLE) {
219 				net->dest_state &= ~SCTP_ADDR_REACHABLE;
220 				net->dest_state |= SCTP_ADDR_NOT_REACHABLE;
221 				net->dest_state &= ~SCTP_ADDR_REQ_PRIMARY;
222 				if (net == stcb->asoc.primary_destination) {
223 					net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
224 				}
225 				sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
226 				    stcb,
227 				    SCTP_FAILED_THRESHOLD,
228 				    (void *)net);
229 			}
230 		}
231 		/*********HOLD THIS COMMENT FOR PATCH OF ALTERNATE
232 		 *********ROUTING CODE
233 		 */
234 		/*********HOLD THIS COMMENT FOR END OF PATCH OF ALTERNATE
235 		 *********ROUTING CODE
236 		 */
237 	}
238 	if (stcb == NULL)
239 		return (0);
240 
241 	if (net) {
242 		if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) {
243 			stcb->asoc.overall_error_count++;
244 		}
245 	} else {
246 		stcb->asoc.overall_error_count++;
247 	}
248 #ifdef SCTP_DEBUG
249 	if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
250 		printf("Overall error count for %p now %d thresh:%u state:%x\n",
251 		    &stcb->asoc,
252 		    stcb->asoc.overall_error_count,
253 		    (uint32_t) threshold,
254 		    ((net == NULL) ? (uint32_t) 0 : (uint32_t) net->dest_state));
255 	}
256 #endif				/* SCTP_DEBUG */
257 	/*
258 	 * We specifically do not do >= to give the assoc one more change
259 	 * before we fail it.
260 	 */
261 	if (stcb->asoc.overall_error_count > threshold) {
262 		/* Abort notification sends a ULP notify */
263 		struct mbuf *oper;
264 
265 		oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
266 		    0, M_DONTWAIT, 1, MT_DATA);
267 		if (oper) {
268 			struct sctp_paramhdr *ph;
269 			uint32_t *ippp;
270 
271 			SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
272 			    sizeof(uint32_t);
273 			ph = mtod(oper, struct sctp_paramhdr *);
274 			ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
275 			ph->param_length = htons(SCTP_BUF_LEN(oper));
276 			ippp = (uint32_t *) (ph + 1);
277 			*ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_1);
278 		}
279 		inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_1;
280 		sctp_abort_an_association(inp, stcb, SCTP_FAILED_THRESHOLD, oper);
281 		return (1);
282 	}
283 	return (0);
284 }
285 
286 struct sctp_nets *
287 sctp_find_alternate_net(struct sctp_tcb *stcb,
288     struct sctp_nets *net,
289     int highest_ssthresh)
290 {
291 	/* Find and return an alternate network if possible */
292 	struct sctp_nets *alt, *mnet, *hthresh = NULL;
293 	int once;
294 	uint32_t val = 0;
295 
296 	if (stcb->asoc.numnets == 1) {
297 		/* No others but net */
298 		return (TAILQ_FIRST(&stcb->asoc.nets));
299 	}
300 	if (highest_ssthresh) {
301 		TAILQ_FOREACH(mnet, &stcb->asoc.nets, sctp_next) {
302 			if (((mnet->dest_state & SCTP_ADDR_REACHABLE) != SCTP_ADDR_REACHABLE) ||
303 			    (mnet->dest_state & SCTP_ADDR_UNCONFIRMED)
304 			    ) {
305 				/*
306 				 * will skip ones that are not-reachable or
307 				 * unconfirmed
308 				 */
309 				continue;
310 			}
311 			if (val > mnet->ssthresh) {
312 				hthresh = mnet;
313 				val = mnet->ssthresh;
314 			} else if (val == mnet->ssthresh) {
315 				uint32_t rndval;
316 				uint8_t this_random;
317 
318 				if (stcb->asoc.hb_random_idx > 3) {
319 					rndval = sctp_select_initial_TSN(&stcb->sctp_ep->sctp_ep);
320 					memcpy(stcb->asoc.hb_random_values, &rndval,
321 					    sizeof(stcb->asoc.hb_random_values));
322 					this_random = stcb->asoc.hb_random_values[0];
323 					stcb->asoc.hb_random_idx = 0;
324 					stcb->asoc.hb_ect_randombit = 0;
325 				} else {
326 					this_random = stcb->asoc.hb_random_values[stcb->asoc.hb_random_idx];
327 					stcb->asoc.hb_random_idx++;
328 					stcb->asoc.hb_ect_randombit = 0;
329 				}
330 				if (this_random % 2) {
331 					hthresh = mnet;
332 					val = mnet->ssthresh;
333 				}
334 			}
335 		}
336 		if (hthresh) {
337 			return (hthresh);
338 		}
339 	}
340 	mnet = net;
341 	once = 0;
342 
343 	if (mnet == NULL) {
344 		mnet = TAILQ_FIRST(&stcb->asoc.nets);
345 	}
346 	do {
347 		alt = TAILQ_NEXT(mnet, sctp_next);
348 		if (alt == NULL) {
349 			once++;
350 			if (once > 1) {
351 				break;
352 			}
353 			alt = TAILQ_FIRST(&stcb->asoc.nets);
354 		}
355 		if (alt->ro.ro_rt == NULL) {
356 			struct sockaddr_in6 *sin6;
357 
358 			sin6 = (struct sockaddr_in6 *)&alt->ro._l_addr;
359 			if (sin6->sin6_family == AF_INET6) {
360 				(void)sa6_embedscope(sin6, ip6_use_defzone);
361 			}
362 			rtalloc_ign((struct route *)&alt->ro, 0UL);
363 			if (sin6->sin6_family == AF_INET6) {
364 				(void)sa6_recoverscope(sin6);
365 			}
366 			if (alt->ro._s_addr) {
367 				sctp_free_ifa(alt->ro._s_addr);
368 				alt->ro._s_addr = NULL;
369 			}
370 			alt->src_addr_selected = 0;
371 		}
372 		if (
373 		    ((alt->dest_state & SCTP_ADDR_REACHABLE) == SCTP_ADDR_REACHABLE) &&
374 		    (alt->ro.ro_rt != NULL) &&
375 		    (!(alt->dest_state & SCTP_ADDR_UNCONFIRMED))
376 		    ) {
377 			/* Found a reachable address */
378 			break;
379 		}
380 		mnet = alt;
381 	} while (alt != NULL);
382 
383 	if (alt == NULL) {
384 		/* Case where NO insv network exists (dormant state) */
385 		/* we rotate destinations */
386 		once = 0;
387 		mnet = net;
388 		do {
389 			alt = TAILQ_NEXT(mnet, sctp_next);
390 			if (alt == NULL) {
391 				once++;
392 				if (once > 1) {
393 					break;
394 				}
395 				alt = TAILQ_FIRST(&stcb->asoc.nets);
396 			}
397 			if ((!(alt->dest_state & SCTP_ADDR_UNCONFIRMED)) &&
398 			    (alt != net)) {
399 				/* Found an alternate address */
400 				break;
401 			}
402 			mnet = alt;
403 		} while (alt != NULL);
404 	}
405 	if (alt == NULL) {
406 		return (net);
407 	}
408 	return (alt);
409 }
410 
411 static void
412 sctp_backoff_on_timeout(struct sctp_tcb *stcb,
413     struct sctp_nets *net,
414     int win_probe,
415     int num_marked)
416 {
417 	net->RTO <<= 1;
418 	if (net->RTO > stcb->asoc.maxrto) {
419 		net->RTO = stcb->asoc.maxrto;
420 	}
421 	if ((win_probe == 0) && num_marked) {
422 		/* We don't apply penalty to window probe scenarios */
423 #ifdef SCTP_CWND_MONITOR
424 		int old_cwnd = net->cwnd;
425 
426 #endif
427 		net->ssthresh = net->cwnd >> 1;
428 		if (net->ssthresh < (net->mtu << 1)) {
429 			net->ssthresh = (net->mtu << 1);
430 		}
431 		net->cwnd = net->mtu;
432 		/* floor of 1 mtu */
433 		if (net->cwnd < net->mtu)
434 			net->cwnd = net->mtu;
435 #ifdef SCTP_CWND_MONITOR
436 		sctp_log_cwnd(stcb, net, net->cwnd - old_cwnd, SCTP_CWND_LOG_FROM_RTX);
437 #endif
438 
439 		net->partial_bytes_acked = 0;
440 	}
441 }
442 
443 static int
444 sctp_mark_all_for_resend(struct sctp_tcb *stcb,
445     struct sctp_nets *net,
446     struct sctp_nets *alt,
447     int window_probe,
448     int *num_marked)
449 {
450 
451 	/*
452 	 * Mark all chunks (well not all) that were sent to *net for
453 	 * retransmission. Move them to alt for there destination as well...
454 	 * We only mark chunks that have been outstanding long enough to
455 	 * have received feed-back.
456 	 */
457 	struct sctp_tmit_chunk *chk, *tp2, *could_be_sent = NULL;
458 	struct sctp_nets *lnets;
459 	struct timeval now, min_wait, tv;
460 	int cur_rtt;
461 	int orig_rwnd, audit_tf, num_mk, fir;
462 	unsigned int cnt_mk;
463 	uint32_t orig_flight;
464 	uint32_t tsnlast, tsnfirst;
465 
466 	/*
467 	 * CMT: Using RTX_SSTHRESH policy for CMT. If CMT is being used,
468 	 * then pick dest with largest ssthresh for any retransmission.
469 	 * (iyengar@cis.udel.edu, 2005/08/12)
470 	 */
471 	if (sctp_cmt_on_off) {
472 		alt = sctp_find_alternate_net(stcb, net, 1);
473 		/*
474 		 * CUCv2: If a different dest is picked for the
475 		 * retransmission, then new (rtx-)pseudo_cumack needs to be
476 		 * tracked for orig dest. Let CUCv2 track new (rtx-)
477 		 * pseudo-cumack always.
478 		 */
479 		net->find_pseudo_cumack = 1;
480 		net->find_rtx_pseudo_cumack = 1;
481 	}
482 	/* none in flight now */
483 	audit_tf = 0;
484 	fir = 0;
485 	/*
486 	 * figure out how long a data chunk must be pending before we can
487 	 * mark it ..
488 	 */
489 	SCTP_GETTIME_TIMEVAL(&now);
490 	/* get cur rto in micro-seconds */
491 	cur_rtt = (((net->lastsa >> 2) + net->lastsv) >> 1);
492 	cur_rtt *= 1000;
493 #if defined(SCTP_FR_LOGGING) || defined(SCTP_EARLYFR_LOGGING)
494 	sctp_log_fr(cur_rtt,
495 	    stcb->asoc.peers_rwnd,
496 	    window_probe,
497 	    SCTP_FR_T3_MARK_TIME);
498 	sctp_log_fr(net->flight_size,
499 	    SCTP_OS_TIMER_PENDING(&net->fr_timer.timer),
500 	    SCTP_OS_TIMER_ACTIVE(&net->fr_timer.timer),
501 	    SCTP_FR_CWND_REPORT);
502 	sctp_log_fr(net->flight_size, net->cwnd, stcb->asoc.total_flight, SCTP_FR_CWND_REPORT);
503 #endif
504 	tv.tv_sec = cur_rtt / 1000000;
505 	tv.tv_usec = cur_rtt % 1000000;
506 	min_wait = now;
507 	timevalsub(&min_wait, &tv);
508 	if (min_wait.tv_sec < 0 || min_wait.tv_usec < 0) {
509 		/*
510 		 * if we hit here, we don't have enough seconds on the clock
511 		 * to account for the RTO. We just let the lower seconds be
512 		 * the bounds and don't worry about it. This may mean we
513 		 * will mark a lot more than we should.
514 		 */
515 		min_wait.tv_sec = min_wait.tv_usec = 0;
516 	}
517 #if defined(SCTP_FR_LOGGING) || defined(SCTP_EARLYFR_LOGGING)
518 	sctp_log_fr(cur_rtt, now.tv_sec, now.tv_usec, SCTP_FR_T3_MARK_TIME);
519 	sctp_log_fr(0, min_wait.tv_sec, min_wait.tv_usec, SCTP_FR_T3_MARK_TIME);
520 #endif
521 	/*
522 	 * Our rwnd will be incorrect here since we are not adding back the
523 	 * cnt * mbuf but we will fix that down below.
524 	 */
525 	orig_rwnd = stcb->asoc.peers_rwnd;
526 	orig_flight = net->flight_size;
527 	net->fast_retran_ip = 0;
528 	/* Now on to each chunk */
529 	num_mk = cnt_mk = 0;
530 	tsnfirst = tsnlast = 0;
531 	chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
532 	for (; chk != NULL; chk = tp2) {
533 		tp2 = TAILQ_NEXT(chk, sctp_next);
534 		if ((compare_with_wrap(stcb->asoc.last_acked_seq,
535 		    chk->rec.data.TSN_seq,
536 		    MAX_TSN)) ||
537 		    (stcb->asoc.last_acked_seq == chk->rec.data.TSN_seq)) {
538 			/* Strange case our list got out of order? */
539 			printf("Our list is out of order?\n");
540 			panic("Out of order list");
541 		}
542 		if ((chk->whoTo == net) && (chk->sent < SCTP_DATAGRAM_ACKED)) {
543 			/*
544 			 * found one to mark: If it is less than
545 			 * DATAGRAM_ACKED it MUST not be a skipped or marked
546 			 * TSN but instead one that is either already set
547 			 * for retransmission OR one that needs
548 			 * retransmission.
549 			 */
550 
551 			/* validate its been outstanding long enough */
552 #if defined(SCTP_FR_LOGGING) || defined(SCTP_EARLYFR_LOGGING)
553 			sctp_log_fr(chk->rec.data.TSN_seq,
554 			    chk->sent_rcv_time.tv_sec,
555 			    chk->sent_rcv_time.tv_usec,
556 			    SCTP_FR_T3_MARK_TIME);
557 #endif
558 			if ((chk->sent_rcv_time.tv_sec > min_wait.tv_sec) && (window_probe == 0)) {
559 				/*
560 				 * we have reached a chunk that was sent
561 				 * some seconds past our min.. forget it we
562 				 * will find no more to send.
563 				 */
564 #if defined(SCTP_FR_LOGGING) || defined(SCTP_EARLYFR_LOGGING)
565 				sctp_log_fr(0,
566 				    chk->sent_rcv_time.tv_sec,
567 				    chk->sent_rcv_time.tv_usec,
568 				    SCTP_FR_T3_STOPPED);
569 #endif
570 				continue;
571 			} else if ((chk->sent_rcv_time.tv_sec == min_wait.tv_sec) &&
572 			    (window_probe == 0)) {
573 				/*
574 				 * we must look at the micro seconds to
575 				 * know.
576 				 */
577 				if (chk->sent_rcv_time.tv_usec >= min_wait.tv_usec) {
578 					/*
579 					 * ok it was sent after our boundary
580 					 * time.
581 					 */
582 #if defined(SCTP_FR_LOGGING) || defined(SCTP_EARLYFR_LOGGING)
583 					sctp_log_fr(0,
584 					    chk->sent_rcv_time.tv_sec,
585 					    chk->sent_rcv_time.tv_usec,
586 					    SCTP_FR_T3_STOPPED);
587 #endif
588 					continue;
589 				}
590 			}
591 			if (PR_SCTP_TTL_ENABLED(chk->flags)) {
592 				/* Is it expired? */
593 				if ((now.tv_sec > chk->rec.data.timetodrop.tv_sec) ||
594 				    ((chk->rec.data.timetodrop.tv_sec == now.tv_sec) &&
595 				    (now.tv_usec > chk->rec.data.timetodrop.tv_usec))) {
596 					/* Yes so drop it */
597 					if (chk->data) {
598 						sctp_release_pr_sctp_chunk(stcb,
599 						    chk,
600 						    (SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_SENT),
601 						    &stcb->asoc.sent_queue);
602 					}
603 				}
604 				continue;
605 			}
606 			if (PR_SCTP_RTX_ENABLED(chk->flags)) {
607 				/* Has it been retransmitted tv_sec times? */
608 				if (chk->snd_count > chk->rec.data.timetodrop.tv_sec) {
609 					if (chk->data) {
610 						sctp_release_pr_sctp_chunk(stcb,
611 						    chk,
612 						    (SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_SENT),
613 						    &stcb->asoc.sent_queue);
614 					}
615 				}
616 				continue;
617 			}
618 			if (chk->sent != SCTP_DATAGRAM_RESEND) {
619 				sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
620 				num_mk++;
621 				if (fir == 0) {
622 					fir = 1;
623 					tsnfirst = chk->rec.data.TSN_seq;
624 				}
625 				tsnlast = chk->rec.data.TSN_seq;
626 #if defined(SCTP_FR_LOGGING) || defined(SCTP_EARLYFR_LOGGING)
627 				sctp_log_fr(chk->rec.data.TSN_seq, chk->snd_count,
628 				    0, SCTP_FR_T3_MARKED);
629 
630 #endif
631 			}
632 			if (stcb->asoc.total_flight_count > 0)
633 				stcb->asoc.total_flight_count--;
634 			if (chk->rec.data.chunk_was_revoked) {
635 				/* deflate the cwnd */
636 				chk->whoTo->cwnd -= chk->book_size;
637 				chk->rec.data.chunk_was_revoked = 0;
638 			}
639 			chk->sent = SCTP_DATAGRAM_RESEND;
640 			SCTP_STAT_INCR(sctps_markedretrans);
641 			net->marked_retrans++;
642 			stcb->asoc.marked_retrans++;
643 #ifdef SCTP_FLIGHT_LOGGING
644 			sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN,
645 			    chk->whoTo->flight_size,
646 			    chk->book_size,
647 			    (uintptr_t) stcb,
648 			    chk->rec.data.TSN_seq);
649 #endif
650 
651 			if (net->flight_size >= chk->book_size)
652 				net->flight_size -= chk->book_size;
653 			else
654 				net->flight_size = 0;
655 
656 			stcb->asoc.peers_rwnd += chk->send_size;
657 			stcb->asoc.peers_rwnd += sctp_peer_chunk_oh;
658 
659 			/* reset the TSN for striking and other FR stuff */
660 			chk->rec.data.doing_fast_retransmit = 0;
661 			/* Clear any time so NO RTT is being done */
662 			chk->do_rtt = 0;
663 			if (alt != net) {
664 				sctp_free_remote_addr(chk->whoTo);
665 				chk->no_fr_allowed = 1;
666 				chk->whoTo = alt;
667 				atomic_add_int(&alt->ref_count, 1);
668 			} else {
669 				chk->no_fr_allowed = 0;
670 				if (TAILQ_EMPTY(&stcb->asoc.send_queue)) {
671 					chk->rec.data.fast_retran_tsn = stcb->asoc.sending_seq;
672 				} else {
673 					chk->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.TSN_seq;
674 				}
675 			}
676 			if (sctp_cmt_on_off == 1) {
677 				chk->no_fr_allowed = 1;
678 			}
679 		} else if (chk->sent == SCTP_DATAGRAM_ACKED) {
680 			/* remember highest acked one */
681 			could_be_sent = chk;
682 		}
683 		if (chk->sent == SCTP_DATAGRAM_RESEND) {
684 			cnt_mk++;
685 		}
686 	}
687 #if defined(SCTP_FR_LOGGING) || defined(SCTP_EARLYFR_LOGGING)
688 	sctp_log_fr(tsnfirst, tsnlast, num_mk, SCTP_FR_T3_TIMEOUT);
689 #endif
690 
691 	if (stcb->asoc.total_flight >= (orig_flight - net->flight_size)) {
692 		stcb->asoc.total_flight -= (orig_flight - net->flight_size);
693 	} else {
694 		stcb->asoc.total_flight = 0;
695 		stcb->asoc.total_flight_count = 0;
696 		audit_tf = 1;
697 	}
698 
699 #ifdef SCTP_DEBUG
700 	if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
701 		if (num_mk) {
702 			printf("LAST TSN marked was %x\n", tsnlast);
703 			printf("Num marked for retransmission was %d peer-rwd:%ld\n",
704 			    num_mk, (u_long)stcb->asoc.peers_rwnd);
705 			printf("LAST TSN marked was %x\n", tsnlast);
706 			printf("Num marked for retransmission was %d peer-rwd:%d\n",
707 			    num_mk,
708 			    (int)stcb->asoc.peers_rwnd
709 			    );
710 		}
711 	}
712 #endif
713 	*num_marked = num_mk;
714 	if ((stcb->asoc.sent_queue_retran_cnt == 0) && (could_be_sent)) {
715 		/* fix it so we retransmit the highest acked anyway */
716 		sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
717 		cnt_mk++;
718 		could_be_sent->sent = SCTP_DATAGRAM_RESEND;
719 	}
720 	if (stcb->asoc.sent_queue_retran_cnt != cnt_mk) {
721 #ifdef INVARIANTS
722 		printf("Local Audit says there are %d for retran asoc cnt:%d\n",
723 		    cnt_mk, stcb->asoc.sent_queue_retran_cnt);
724 #endif
725 #ifndef SCTP_AUDITING_ENABLED
726 		stcb->asoc.sent_queue_retran_cnt = cnt_mk;
727 #endif
728 	}
729 	/* Now check for a ECN Echo that may be stranded */
730 	TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
731 		if ((chk->whoTo == net) &&
732 		    (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) {
733 			sctp_free_remote_addr(chk->whoTo);
734 			chk->whoTo = alt;
735 			if (chk->sent != SCTP_DATAGRAM_RESEND) {
736 				chk->sent = SCTP_DATAGRAM_RESEND;
737 				sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
738 			}
739 			atomic_add_int(&alt->ref_count, 1);
740 		}
741 	}
742 	if (audit_tf) {
743 #ifdef SCTP_DEBUG
744 		if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
745 			printf("Audit total flight due to negative value net:%p\n",
746 			    net);
747 		}
748 #endif				/* SCTP_DEBUG */
749 		stcb->asoc.total_flight = 0;
750 		stcb->asoc.total_flight_count = 0;
751 		/* Clear all networks flight size */
752 		TAILQ_FOREACH(lnets, &stcb->asoc.nets, sctp_next) {
753 			lnets->flight_size = 0;
754 #ifdef SCTP_DEBUG
755 			if (sctp_debug_on & SCTP_DEBUG_TIMER4) {
756 				printf("Net:%p c-f cwnd:%d ssthresh:%d\n",
757 				    lnets, lnets->cwnd, lnets->ssthresh);
758 			}
759 #endif				/* SCTP_DEBUG */
760 		}
761 		TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
762 			if (chk->sent < SCTP_DATAGRAM_RESEND) {
763 #ifdef SCTP_FLIGHT_LOGGING
764 				sctp_misc_ints(SCTP_FLIGHT_LOG_UP,
765 				    chk->whoTo->flight_size,
766 				    chk->book_size,
767 				    (uintptr_t) stcb,
768 				    chk->rec.data.TSN_seq);
769 #endif
770 				stcb->asoc.total_flight += chk->book_size;
771 				chk->whoTo->flight_size += chk->book_size;
772 				stcb->asoc.total_flight_count++;
773 			}
774 		}
775 	}
776 	/*
777 	 * Setup the ecn nonce re-sync point. We do this since
778 	 * retranmissions are NOT setup for ECN. This means that do to
779 	 * Karn's rule, we don't know the total of the peers ecn bits.
780 	 */
781 	chk = TAILQ_FIRST(&stcb->asoc.send_queue);
782 	if (chk == NULL) {
783 		stcb->asoc.nonce_resync_tsn = stcb->asoc.sending_seq;
784 	} else {
785 		stcb->asoc.nonce_resync_tsn = chk->rec.data.TSN_seq;
786 	}
787 	stcb->asoc.nonce_wait_for_ecne = 0;
788 	stcb->asoc.nonce_sum_check = 0;
789 	/* We return 1 if we only have a window probe outstanding */
790 	return (0);
791 }
792 
793 static void
794 sctp_move_all_chunks_to_alt(struct sctp_tcb *stcb,
795     struct sctp_nets *net,
796     struct sctp_nets *alt)
797 {
798 	struct sctp_association *asoc;
799 	struct sctp_stream_out *outs;
800 	struct sctp_tmit_chunk *chk;
801 	struct sctp_stream_queue_pending *sp;
802 
803 	if (net == alt)
804 		/* nothing to do */
805 		return;
806 
807 	asoc = &stcb->asoc;
808 
809 	/*
810 	 * now through all the streams checking for chunks sent to our bad
811 	 * network.
812 	 */
813 	TAILQ_FOREACH(outs, &asoc->out_wheel, next_spoke) {
814 		/* now clean up any chunks here */
815 		TAILQ_FOREACH(sp, &outs->outqueue, next) {
816 			if (sp->net == net) {
817 				sctp_free_remote_addr(sp->net);
818 				sp->net = alt;
819 				atomic_add_int(&alt->ref_count, 1);
820 			}
821 		}
822 	}
823 	/* Now check the pending queue */
824 	TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
825 		if (chk->whoTo == net) {
826 			sctp_free_remote_addr(chk->whoTo);
827 			chk->whoTo = alt;
828 			atomic_add_int(&alt->ref_count, 1);
829 		}
830 	}
831 
832 }
833 
834 int
835 sctp_t3rxt_timer(struct sctp_inpcb *inp,
836     struct sctp_tcb *stcb,
837     struct sctp_nets *net)
838 {
839 	struct sctp_nets *alt;
840 	int win_probe, num_mk;
841 
842 #ifdef SCTP_FR_LOGGING
843 	sctp_log_fr(0, 0, 0, SCTP_FR_T3_TIMEOUT);
844 #ifdef SCTP_CWND_LOGGING
845 	{
846 		struct sctp_nets *lnet;
847 
848 		TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
849 			if (net == lnet) {
850 				sctp_log_cwnd(stcb, lnet, 1, SCTP_CWND_LOG_FROM_T3);
851 			} else {
852 				sctp_log_cwnd(stcb, lnet, 0, SCTP_CWND_LOG_FROM_T3);
853 			}
854 		}
855 	}
856 #endif
857 #endif
858 	/* Find an alternate and mark those for retransmission */
859 	if ((stcb->asoc.peers_rwnd == 0) &&
860 	    (stcb->asoc.total_flight < net->mtu)) {
861 		SCTP_STAT_INCR(sctps_timowindowprobe);
862 		win_probe = 1;
863 	} else {
864 		win_probe = 0;
865 	}
866 	alt = sctp_find_alternate_net(stcb, net, 0);
867 	sctp_mark_all_for_resend(stcb, net, alt, win_probe, &num_mk);
868 	/* FR Loss recovery just ended with the T3. */
869 	stcb->asoc.fast_retran_loss_recovery = 0;
870 
871 	/* CMT FR loss recovery ended with the T3 */
872 	net->fast_retran_loss_recovery = 0;
873 
874 	/*
875 	 * setup the sat loss recovery that prevents satellite cwnd advance.
876 	 */
877 	stcb->asoc.sat_t3_loss_recovery = 1;
878 	stcb->asoc.sat_t3_recovery_tsn = stcb->asoc.sending_seq;
879 
880 	/* Backoff the timer and cwnd */
881 	sctp_backoff_on_timeout(stcb, net, win_probe, num_mk);
882 	if (win_probe == 0) {
883 		/* We don't do normal threshold management on window probes */
884 		if (sctp_threshold_management(inp, stcb, net,
885 		    stcb->asoc.max_send_times)) {
886 			/* Association was destroyed */
887 			return (1);
888 		} else {
889 			if (net != stcb->asoc.primary_destination) {
890 				/* send a immediate HB if our RTO is stale */
891 				struct timeval now;
892 				unsigned int ms_goneby;
893 
894 				SCTP_GETTIME_TIMEVAL(&now);
895 				if (net->last_sent_time.tv_sec) {
896 					ms_goneby = (now.tv_sec - net->last_sent_time.tv_sec) * 1000;
897 				} else {
898 					ms_goneby = 0;
899 				}
900 				if ((ms_goneby > net->RTO) || (net->RTO == 0)) {
901 					/*
902 					 * no recent feed back in an RTO or
903 					 * more, request a RTT update
904 					 */
905 					sctp_send_hb(stcb, 1, net);
906 				}
907 			}
908 		}
909 	} else {
910 		/*
911 		 * For a window probe we don't penalize the net's but only
912 		 * the association. This may fail it if SACKs are not coming
913 		 * back. If sack's are coming with rwnd locked at 0, we will
914 		 * continue to hold things waiting for rwnd to raise
915 		 */
916 		if (sctp_threshold_management(inp, stcb, NULL,
917 		    stcb->asoc.max_send_times)) {
918 			/* Association was destroyed */
919 			return (1);
920 		}
921 	}
922 	if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) {
923 		/* Move all pending over too */
924 		sctp_move_all_chunks_to_alt(stcb, net, alt);
925 		/* Was it our primary? */
926 		if ((stcb->asoc.primary_destination == net) && (alt != net)) {
927 			/*
928 			 * Yes, note it as such and find an alternate note:
929 			 * this means HB code must use this to resent the
930 			 * primary if it goes active AND if someone does a
931 			 * change-primary then this flag must be cleared
932 			 * from any net structures.
933 			 */
934 			if (sctp_set_primary_addr(stcb,
935 			    (struct sockaddr *)NULL,
936 			    alt) == 0) {
937 				net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
938 				if (net->ro._s_addr) {
939 					sctp_free_ifa(net->ro._s_addr);
940 					net->ro._s_addr = NULL;
941 				}
942 				net->src_addr_selected = 0;
943 			}
944 		}
945 	}
946 	/*
947 	 * Special case for cookie-echo'ed case, we don't do output but must
948 	 * await the COOKIE-ACK before retransmission
949 	 */
950 	if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
951 		/*
952 		 * Here we just reset the timer and start again since we
953 		 * have not established the asoc
954 		 */
955 		sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
956 		return (0);
957 	}
958 	if (stcb->asoc.peer_supports_prsctp) {
959 		struct sctp_tmit_chunk *lchk;
960 
961 		lchk = sctp_try_advance_peer_ack_point(stcb, &stcb->asoc);
962 		/* C3. See if we need to send a Fwd-TSN */
963 		if (compare_with_wrap(stcb->asoc.advanced_peer_ack_point,
964 		    stcb->asoc.last_acked_seq, MAX_TSN)) {
965 			/*
966 			 * ISSUE with ECN, see FWD-TSN processing for notes
967 			 * on issues that will occur when the ECN NONCE
968 			 * stuff is put into SCTP for cross checking.
969 			 */
970 			send_forward_tsn(stcb, &stcb->asoc);
971 			if (lchk) {
972 				/* Assure a timer is up */
973 				sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, lchk->whoTo);
974 			}
975 		}
976 	}
977 #ifdef SCTP_CWND_MONITOR
978 	sctp_log_cwnd(stcb, net, net->cwnd, SCTP_CWND_LOG_FROM_RTX);
979 #endif
980 	return (0);
981 }
982 
983 int
984 sctp_t1init_timer(struct sctp_inpcb *inp,
985     struct sctp_tcb *stcb,
986     struct sctp_nets *net)
987 {
988 	/* bump the thresholds */
989 	if (stcb->asoc.delayed_connection) {
990 		/*
991 		 * special hook for delayed connection. The library did NOT
992 		 * complete the rest of its sends.
993 		 */
994 		stcb->asoc.delayed_connection = 0;
995 		sctp_send_initiate(inp, stcb);
996 		return (0);
997 	}
998 	if (SCTP_GET_STATE((&stcb->asoc)) != SCTP_STATE_COOKIE_WAIT) {
999 		return (0);
1000 	}
1001 	if (sctp_threshold_management(inp, stcb, net,
1002 	    stcb->asoc.max_init_times)) {
1003 		/* Association was destroyed */
1004 		return (1);
1005 	}
1006 	stcb->asoc.dropped_special_cnt = 0;
1007 	sctp_backoff_on_timeout(stcb, stcb->asoc.primary_destination, 1, 0);
1008 	if (stcb->asoc.initial_init_rto_max < net->RTO) {
1009 		net->RTO = stcb->asoc.initial_init_rto_max;
1010 	}
1011 	if (stcb->asoc.numnets > 1) {
1012 		/* If we have more than one addr use it */
1013 		struct sctp_nets *alt;
1014 
1015 		alt = sctp_find_alternate_net(stcb, stcb->asoc.primary_destination, 0);
1016 		if ((alt != NULL) && (alt != stcb->asoc.primary_destination)) {
1017 			sctp_move_all_chunks_to_alt(stcb, stcb->asoc.primary_destination, alt);
1018 			stcb->asoc.primary_destination = alt;
1019 		}
1020 	}
1021 	/* Send out a new init */
1022 	sctp_send_initiate(inp, stcb);
1023 	return (0);
1024 }
1025 
1026 /*
1027  * For cookie and asconf we actually need to find and mark for resend, then
1028  * increment the resend counter (after all the threshold management stuff of
1029  * course).
1030  */
1031 int
1032 sctp_cookie_timer(struct sctp_inpcb *inp,
1033     struct sctp_tcb *stcb,
1034     struct sctp_nets *net)
1035 {
1036 	struct sctp_nets *alt;
1037 	struct sctp_tmit_chunk *cookie;
1038 
1039 	/* first before all else we must find the cookie */
1040 	TAILQ_FOREACH(cookie, &stcb->asoc.control_send_queue, sctp_next) {
1041 		if (cookie->rec.chunk_id.id == SCTP_COOKIE_ECHO) {
1042 			break;
1043 		}
1044 	}
1045 	if (cookie == NULL) {
1046 		if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
1047 			/* FOOBAR! */
1048 			struct mbuf *oper;
1049 
1050 			oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
1051 			    0, M_DONTWAIT, 1, MT_DATA);
1052 			if (oper) {
1053 				struct sctp_paramhdr *ph;
1054 				uint32_t *ippp;
1055 
1056 				SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
1057 				    sizeof(uint32_t);
1058 				ph = mtod(oper, struct sctp_paramhdr *);
1059 				ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
1060 				ph->param_length = htons(SCTP_BUF_LEN(oper));
1061 				ippp = (uint32_t *) (ph + 1);
1062 				*ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_2);
1063 			}
1064 			inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_3;
1065 			sctp_abort_an_association(inp, stcb, SCTP_INTERNAL_ERROR,
1066 			    oper);
1067 		} else {
1068 #ifdef INVARIANTS
1069 			panic("Cookie timer expires in wrong state?");
1070 #else
1071 			printf("Strange in state %d not cookie-echoed yet c-e timer expires?\n", SCTP_GET_STATE(&stcb->asoc));
1072 			return (0);
1073 #endif
1074 		}
1075 		return (0);
1076 	}
1077 	/* Ok we found the cookie, threshold management next */
1078 	if (sctp_threshold_management(inp, stcb, cookie->whoTo,
1079 	    stcb->asoc.max_init_times)) {
1080 		/* Assoc is over */
1081 		return (1);
1082 	}
1083 	/*
1084 	 * cleared theshold management now lets backoff the address & select
1085 	 * an alternate
1086 	 */
1087 	stcb->asoc.dropped_special_cnt = 0;
1088 	sctp_backoff_on_timeout(stcb, cookie->whoTo, 1, 0);
1089 	alt = sctp_find_alternate_net(stcb, cookie->whoTo, 0);
1090 	if (alt != cookie->whoTo) {
1091 		sctp_free_remote_addr(cookie->whoTo);
1092 		cookie->whoTo = alt;
1093 		atomic_add_int(&alt->ref_count, 1);
1094 	}
1095 	/* Now mark the retran info */
1096 	if (cookie->sent != SCTP_DATAGRAM_RESEND) {
1097 		sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1098 	}
1099 	cookie->sent = SCTP_DATAGRAM_RESEND;
1100 	/*
1101 	 * Now call the output routine to kick out the cookie again, Note we
1102 	 * don't mark any chunks for retran so that FR will need to kick in
1103 	 * to move these (or a send timer).
1104 	 */
1105 	return (0);
1106 }
1107 
1108 int
1109 sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1110     struct sctp_nets *net)
1111 {
1112 	struct sctp_nets *alt;
1113 	struct sctp_tmit_chunk *strrst = NULL, *chk = NULL;
1114 
1115 	if (stcb->asoc.stream_reset_outstanding == 0) {
1116 		return (0);
1117 	}
1118 	/* find the existing STRRESET, we use the seq number we sent out on */
1119 	sctp_find_stream_reset(stcb, stcb->asoc.str_reset_seq_out, &strrst);
1120 	if (strrst == NULL) {
1121 		return (0);
1122 	}
1123 	/* do threshold management */
1124 	if (sctp_threshold_management(inp, stcb, strrst->whoTo,
1125 	    stcb->asoc.max_send_times)) {
1126 		/* Assoc is over */
1127 		return (1);
1128 	}
1129 	/*
1130 	 * cleared theshold management now lets backoff the address & select
1131 	 * an alternate
1132 	 */
1133 	sctp_backoff_on_timeout(stcb, strrst->whoTo, 1, 0);
1134 	alt = sctp_find_alternate_net(stcb, strrst->whoTo, 0);
1135 	sctp_free_remote_addr(strrst->whoTo);
1136 	strrst->whoTo = alt;
1137 	atomic_add_int(&alt->ref_count, 1);
1138 
1139 	/* See if a ECN Echo is also stranded */
1140 	TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
1141 		if ((chk->whoTo == net) &&
1142 		    (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) {
1143 			sctp_free_remote_addr(chk->whoTo);
1144 			if (chk->sent != SCTP_DATAGRAM_RESEND) {
1145 				chk->sent = SCTP_DATAGRAM_RESEND;
1146 				sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1147 			}
1148 			chk->whoTo = alt;
1149 			atomic_add_int(&alt->ref_count, 1);
1150 		}
1151 	}
1152 	if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) {
1153 		/*
1154 		 * If the address went un-reachable, we need to move to
1155 		 * alternates for ALL chk's in queue
1156 		 */
1157 		sctp_move_all_chunks_to_alt(stcb, net, alt);
1158 	}
1159 	/* mark the retran info */
1160 	if (strrst->sent != SCTP_DATAGRAM_RESEND)
1161 		sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1162 	strrst->sent = SCTP_DATAGRAM_RESEND;
1163 
1164 	/* restart the timer */
1165 	sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, inp, stcb, strrst->whoTo);
1166 	return (0);
1167 }
1168 
1169 int
1170 sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1171     struct sctp_nets *net)
1172 {
1173 	struct sctp_nets *alt;
1174 	struct sctp_tmit_chunk *asconf, *chk;
1175 
1176 	/* is this the first send, or a retransmission? */
1177 	if (stcb->asoc.asconf_sent == 0) {
1178 		/* compose a new ASCONF chunk and send it */
1179 		sctp_send_asconf(stcb, net);
1180 	} else {
1181 		/* Retransmission of the existing ASCONF needed... */
1182 
1183 		/* find the existing ASCONF */
1184 		TAILQ_FOREACH(asconf, &stcb->asoc.control_send_queue,
1185 		    sctp_next) {
1186 			if (asconf->rec.chunk_id.id == SCTP_ASCONF) {
1187 				break;
1188 			}
1189 		}
1190 		if (asconf == NULL) {
1191 			return (0);
1192 		}
1193 		/* do threshold management */
1194 		if (sctp_threshold_management(inp, stcb, asconf->whoTo,
1195 		    stcb->asoc.max_send_times)) {
1196 			/* Assoc is over */
1197 			return (1);
1198 		}
1199 		/*
1200 		 * PETER? FIX? How will the following code ever run? If the
1201 		 * max_send_times is hit, threshold managment will blow away
1202 		 * the association?
1203 		 */
1204 		if (asconf->snd_count > stcb->asoc.max_send_times) {
1205 			/*
1206 			 * Something is rotten, peer is not responding to
1207 			 * ASCONFs but maybe is to data etc.  e.g. it is not
1208 			 * properly handling the chunk type upper bits Mark
1209 			 * this peer as ASCONF incapable and cleanup
1210 			 */
1211 #ifdef SCTP_DEBUG
1212 			if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
1213 				printf("asconf_timer: Peer has not responded to our repeated ASCONFs\n");
1214 			}
1215 #endif				/* SCTP_DEBUG */
1216 			sctp_asconf_cleanup(stcb, net);
1217 			return (0);
1218 		}
1219 		/*
1220 		 * cleared theshold management now lets backoff the address
1221 		 * & select an alternate
1222 		 */
1223 		sctp_backoff_on_timeout(stcb, asconf->whoTo, 1, 0);
1224 		alt = sctp_find_alternate_net(stcb, asconf->whoTo, 0);
1225 		sctp_free_remote_addr(asconf->whoTo);
1226 		asconf->whoTo = alt;
1227 		atomic_add_int(&alt->ref_count, 1);
1228 
1229 		/* See if a ECN Echo is also stranded */
1230 		TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
1231 			if ((chk->whoTo == net) &&
1232 			    (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) {
1233 				sctp_free_remote_addr(chk->whoTo);
1234 				chk->whoTo = alt;
1235 				if (chk->sent != SCTP_DATAGRAM_RESEND) {
1236 					chk->sent = SCTP_DATAGRAM_RESEND;
1237 					sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1238 				}
1239 				atomic_add_int(&alt->ref_count, 1);
1240 			}
1241 		}
1242 		if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) {
1243 			/*
1244 			 * If the address went un-reachable, we need to move
1245 			 * to alternates for ALL chk's in queue
1246 			 */
1247 			sctp_move_all_chunks_to_alt(stcb, net, alt);
1248 		}
1249 		/* mark the retran info */
1250 		if (asconf->sent != SCTP_DATAGRAM_RESEND)
1251 			sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1252 		asconf->sent = SCTP_DATAGRAM_RESEND;
1253 	}
1254 	return (0);
1255 }
1256 
1257 /*
1258  * For the shutdown and shutdown-ack, we do not keep one around on the
1259  * control queue. This means we must generate a new one and call the general
1260  * chunk output routine, AFTER having done threshold management.
1261  */
1262 int
1263 sctp_shutdown_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1264     struct sctp_nets *net)
1265 {
1266 	struct sctp_nets *alt;
1267 
1268 	/* first threshold managment */
1269 	if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
1270 		/* Assoc is over */
1271 		return (1);
1272 	}
1273 	/* second select an alternative */
1274 	alt = sctp_find_alternate_net(stcb, net, 0);
1275 
1276 	/* third generate a shutdown into the queue for out net */
1277 	if (alt) {
1278 		sctp_send_shutdown(stcb, alt);
1279 	} else {
1280 		/*
1281 		 * if alt is NULL, there is no dest to send to??
1282 		 */
1283 		return (0);
1284 	}
1285 	/* fourth restart timer */
1286 	sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, inp, stcb, alt);
1287 	return (0);
1288 }
1289 
1290 int
1291 sctp_shutdownack_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1292     struct sctp_nets *net)
1293 {
1294 	struct sctp_nets *alt;
1295 
1296 	/* first threshold managment */
1297 	if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
1298 		/* Assoc is over */
1299 		return (1);
1300 	}
1301 	/* second select an alternative */
1302 	alt = sctp_find_alternate_net(stcb, net, 0);
1303 
1304 	/* third generate a shutdown into the queue for out net */
1305 	sctp_send_shutdown_ack(stcb, alt);
1306 
1307 	/* fourth restart timer */
1308 	sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK, inp, stcb, alt);
1309 	return (0);
1310 }
1311 
1312 static void
1313 sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp,
1314     struct sctp_tcb *stcb)
1315 {
1316 	struct sctp_stream_out *outs;
1317 	struct sctp_stream_queue_pending *sp;
1318 	unsigned int chks_in_queue = 0;
1319 	int being_filled = 0;
1320 
1321 	/*
1322 	 * This function is ONLY called when the send/sent queues are empty.
1323 	 */
1324 	if ((stcb == NULL) || (inp == NULL))
1325 		return;
1326 
1327 	if (stcb->asoc.sent_queue_retran_cnt) {
1328 		printf("Hmm, sent_queue_retran_cnt is non-zero %d\n",
1329 		    stcb->asoc.sent_queue_retran_cnt);
1330 		stcb->asoc.sent_queue_retran_cnt = 0;
1331 	}
1332 	SCTP_TCB_SEND_LOCK(stcb);
1333 	if (TAILQ_EMPTY(&stcb->asoc.out_wheel)) {
1334 		int i, cnt = 0;
1335 
1336 		/* Check to see if a spoke fell off the wheel */
1337 		for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
1338 			if (!TAILQ_EMPTY(&stcb->asoc.strmout[i].outqueue)) {
1339 				sctp_insert_on_wheel(stcb, &stcb->asoc, &stcb->asoc.strmout[i], 1);
1340 				cnt++;
1341 			}
1342 		}
1343 		if (cnt) {
1344 			/* yep, we lost a spoke or two */
1345 			printf("Found an additional %d streams NOT on outwheel, corrected\n", cnt);
1346 		} else {
1347 			/* no spokes lost, */
1348 			stcb->asoc.total_output_queue_size = 0;
1349 		}
1350 		SCTP_TCB_SEND_UNLOCK(stcb);
1351 		return;
1352 	}
1353 	SCTP_TCB_SEND_UNLOCK(stcb);
1354 	/* Check to see if some data queued, if so report it */
1355 	TAILQ_FOREACH(outs, &stcb->asoc.out_wheel, next_spoke) {
1356 		if (!TAILQ_EMPTY(&outs->outqueue)) {
1357 			TAILQ_FOREACH(sp, &outs->outqueue, next) {
1358 				if (sp->msg_is_complete)
1359 					being_filled++;
1360 				chks_in_queue++;
1361 			}
1362 		}
1363 	}
1364 	if (chks_in_queue != stcb->asoc.stream_queue_cnt) {
1365 		printf("Hmm, stream queue cnt at %d I counted %d in stream out wheel\n",
1366 		    stcb->asoc.stream_queue_cnt, chks_in_queue);
1367 	}
1368 	if (chks_in_queue) {
1369 		/* call the output queue function */
1370 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3);
1371 		if ((TAILQ_EMPTY(&stcb->asoc.send_queue)) &&
1372 		    (TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
1373 			/*
1374 			 * Probably should go in and make it go back through
1375 			 * and add fragments allowed
1376 			 */
1377 			if (being_filled == 0) {
1378 				printf("Still nothing moved %d chunks are stuck\n",
1379 				    chks_in_queue);
1380 			}
1381 		}
1382 	} else {
1383 		printf("Found no chunks on any queue tot:%lu\n",
1384 		    (u_long)stcb->asoc.total_output_queue_size);
1385 		stcb->asoc.total_output_queue_size = 0;
1386 	}
1387 }
1388 
1389 int
1390 sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1391     struct sctp_nets *net, int cnt_of_unconf)
1392 {
1393 	if (net) {
1394 		if (net->hb_responded == 0) {
1395 			if (net->ro._s_addr) {
1396 				/*
1397 				 * Invalidate the src address if we did not
1398 				 * get a response last time.
1399 				 */
1400 				sctp_free_ifa(net->ro._s_addr);
1401 				net->ro._s_addr = NULL;
1402 				net->src_addr_selected = 0;
1403 			}
1404 			sctp_backoff_on_timeout(stcb, net, 1, 0);
1405 		}
1406 		/* Zero PBA, if it needs it */
1407 		if (net->partial_bytes_acked) {
1408 			net->partial_bytes_acked = 0;
1409 		}
1410 	}
1411 	if ((stcb->asoc.total_output_queue_size > 0) &&
1412 	    (TAILQ_EMPTY(&stcb->asoc.send_queue)) &&
1413 	    (TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
1414 		sctp_audit_stream_queues_for_size(inp, stcb);
1415 	}
1416 	/* Send a new HB, this will do threshold managment, pick a new dest */
1417 	if (cnt_of_unconf == 0) {
1418 		if (sctp_send_hb(stcb, 0, NULL) < 0) {
1419 			return (1);
1420 		}
1421 	} else {
1422 		/*
1423 		 * this will send out extra hb's up to maxburst if there are
1424 		 * any unconfirmed addresses.
1425 		 */
1426 		int cnt_sent = 0;
1427 
1428 		TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1429 			if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
1430 			    (net->dest_state & SCTP_ADDR_REACHABLE)) {
1431 				cnt_sent++;
1432 				if (net->hb_responded == 0) {
1433 					/* Did we respond last time? */
1434 					if (net->ro._s_addr) {
1435 						sctp_free_ifa(net->ro._s_addr);
1436 						net->ro._s_addr = NULL;
1437 						net->src_addr_selected = 0;
1438 					}
1439 				}
1440 				if (sctp_send_hb(stcb, 1, net) == 0) {
1441 					break;
1442 				}
1443 				if (cnt_sent >= sctp_hb_maxburst)
1444 					break;
1445 			}
1446 		}
1447 	}
1448 	return (0);
1449 }
1450 
1451 int
1452 sctp_is_hb_timer_running(struct sctp_tcb *stcb)
1453 {
1454 	if (SCTP_OS_TIMER_PENDING(&stcb->asoc.hb_timer.timer)) {
1455 		/* its running */
1456 		return (1);
1457 	} else {
1458 		/* nope */
1459 		return (0);
1460 	}
1461 }
1462 
1463 int
1464 sctp_is_sack_timer_running(struct sctp_tcb *stcb)
1465 {
1466 	if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
1467 		/* its running */
1468 		return (1);
1469 	} else {
1470 		/* nope */
1471 		return (0);
1472 	}
1473 }
1474 
1475 #define SCTP_NUMBER_OF_MTU_SIZES 18
1476 static uint32_t mtu_sizes[] = {
1477 	68,
1478 	296,
1479 	508,
1480 	512,
1481 	544,
1482 	576,
1483 	1006,
1484 	1492,
1485 	1500,
1486 	1536,
1487 	2002,
1488 	2048,
1489 	4352,
1490 	4464,
1491 	8166,
1492 	17914,
1493 	32000,
1494 	65535
1495 };
1496 
1497 
1498 static uint32_t
1499 sctp_getnext_mtu(struct sctp_inpcb *inp, uint32_t cur_mtu)
1500 {
1501 	/* select another MTU that is just bigger than this one */
1502 	int i;
1503 
1504 	for (i = 0; i < SCTP_NUMBER_OF_MTU_SIZES; i++) {
1505 		if (cur_mtu < mtu_sizes[i]) {
1506 			/* no max_mtu is bigger than this one */
1507 			return (mtu_sizes[i]);
1508 		}
1509 	}
1510 	/* here return the highest allowable */
1511 	return (cur_mtu);
1512 }
1513 
1514 
1515 void
1516 sctp_pathmtu_timer(struct sctp_inpcb *inp,
1517     struct sctp_tcb *stcb,
1518     struct sctp_nets *net)
1519 {
1520 	uint32_t next_mtu;
1521 
1522 	/* restart the timer in any case */
1523 	next_mtu = sctp_getnext_mtu(inp, net->mtu);
1524 	if (next_mtu <= net->mtu) {
1525 		/* nothing to do */
1526 		return;
1527 	}
1528 	if (net->ro.ro_rt != NULL) {
1529 		/*
1530 		 * only if we have a route and interface do we set anything.
1531 		 * Note we always restart the timer though just in case it
1532 		 * is updated (i.e. the ifp) or route/ifp is populated.
1533 		 */
1534 		if (net->ro.ro_rt->rt_ifp != NULL) {
1535 			if (net->ro.ro_rt->rt_ifp->if_mtu > next_mtu) {
1536 				/* ok it will fit out the door */
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 	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 		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 		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