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