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