]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netinet/sctp_timer.c
This commit was generated by cvs2svn to compensate for changes in r169942,
[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                         if (sctp_cmt_on_off == 1) {
648                                 chk->no_fr_allowed = 1;
649                         }
650                 } else if (chk->sent == SCTP_DATAGRAM_ACKED) {
651                         /* remember highest acked one */
652                         could_be_sent = chk;
653                 }
654                 if (chk->sent == SCTP_DATAGRAM_RESEND) {
655                         cnt_mk++;
656                 }
657         }
658         if ((orig_flight - net->flight_size) != (orig_tf - stcb->asoc.total_flight)) {
659                 /* we did not subtract the same things? */
660                 audit_tf = 1;
661         }
662 #if defined(SCTP_FR_LOGGING) || defined(SCTP_EARLYFR_LOGGING)
663         sctp_log_fr(tsnfirst, tsnlast, num_mk, SCTP_FR_T3_TIMEOUT);
664 #endif
665 #ifdef SCTP_DEBUG
666         if (num_mk) {
667                 SCTPDBG(SCTP_DEBUG_TIMER1, "LAST TSN marked was %x\n",
668                     tsnlast);
669                 SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%ld\n",
670                     num_mk, (u_long)stcb->asoc.peers_rwnd);
671                 SCTPDBG(SCTP_DEBUG_TIMER1, "LAST TSN marked was %x\n",
672                     tsnlast);
673                 SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%d\n",
674                     num_mk,
675                     (int)stcb->asoc.peers_rwnd);
676         }
677 #endif
678         *num_marked = num_mk;
679         if ((stcb->asoc.sent_queue_retran_cnt == 0) && (could_be_sent)) {
680                 /* fix it so we retransmit the highest acked anyway */
681                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
682                 cnt_mk++;
683                 could_be_sent->sent = SCTP_DATAGRAM_RESEND;
684         }
685         if (stcb->asoc.sent_queue_retran_cnt != cnt_mk) {
686 #ifdef INVARIANTS
687                 SCTP_PRINTF("Local Audit says there are %d for retran asoc cnt:%d\n",
688                     cnt_mk, stcb->asoc.sent_queue_retran_cnt);
689 #endif
690 #ifndef SCTP_AUDITING_ENABLED
691                 stcb->asoc.sent_queue_retran_cnt = cnt_mk;
692 #endif
693         }
694         /* Now check for a ECN Echo that may be stranded */
695         TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
696                 if ((chk->whoTo == net) &&
697                     (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) {
698                         sctp_free_remote_addr(chk->whoTo);
699                         chk->whoTo = alt;
700                         if (chk->sent != SCTP_DATAGRAM_RESEND) {
701                                 chk->sent = SCTP_DATAGRAM_RESEND;
702                                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
703                         }
704                         atomic_add_int(&alt->ref_count, 1);
705                 }
706         }
707         if (audit_tf) {
708                 SCTPDBG(SCTP_DEBUG_TIMER4,
709                     "Audit total flight due to negative value net:%p\n",
710                     net);
711                 stcb->asoc.total_flight = 0;
712                 stcb->asoc.total_flight_count = 0;
713                 /* Clear all networks flight size */
714                 TAILQ_FOREACH(lnets, &stcb->asoc.nets, sctp_next) {
715                         lnets->flight_size = 0;
716                         SCTPDBG(SCTP_DEBUG_TIMER4,
717                             "Net:%p c-f cwnd:%d ssthresh:%d\n",
718                             lnets, lnets->cwnd, lnets->ssthresh);
719                 }
720                 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
721                         if (chk->sent < SCTP_DATAGRAM_RESEND) {
722 #ifdef SCTP_FLIGHT_LOGGING
723                                 sctp_misc_ints(SCTP_FLIGHT_LOG_UP,
724                                     chk->whoTo->flight_size,
725                                     chk->book_size,
726                                     (uintptr_t) chk->whoTo,
727                                     chk->rec.data.TSN_seq);
728 #endif
729
730                                 sctp_flight_size_increase(chk);
731                                 sctp_total_flight_increase(stcb, chk);
732                         }
733                 }
734         }
735         /*
736          * Setup the ecn nonce re-sync point. We do this since
737          * retranmissions are NOT setup for ECN. This means that do to
738          * Karn's rule, we don't know the total of the peers ecn bits.
739          */
740         chk = TAILQ_FIRST(&stcb->asoc.send_queue);
741         if (chk == NULL) {
742                 stcb->asoc.nonce_resync_tsn = stcb->asoc.sending_seq;
743         } else {
744                 stcb->asoc.nonce_resync_tsn = chk->rec.data.TSN_seq;
745         }
746         stcb->asoc.nonce_wait_for_ecne = 0;
747         stcb->asoc.nonce_sum_check = 0;
748         /* We return 1 if we only have a window probe outstanding */
749         return (0);
750 }
751
752 static void
753 sctp_move_all_chunks_to_alt(struct sctp_tcb *stcb,
754     struct sctp_nets *net,
755     struct sctp_nets *alt)
756 {
757         struct sctp_association *asoc;
758         struct sctp_stream_out *outs;
759         struct sctp_tmit_chunk *chk;
760         struct sctp_stream_queue_pending *sp;
761
762         if (net == alt)
763                 /* nothing to do */
764                 return;
765
766         asoc = &stcb->asoc;
767
768         /*
769          * now through all the streams checking for chunks sent to our bad
770          * network.
771          */
772         TAILQ_FOREACH(outs, &asoc->out_wheel, next_spoke) {
773                 /* now clean up any chunks here */
774                 TAILQ_FOREACH(sp, &outs->outqueue, next) {
775                         if (sp->net == net) {
776                                 sctp_free_remote_addr(sp->net);
777                                 sp->net = alt;
778                                 atomic_add_int(&alt->ref_count, 1);
779                         }
780                 }
781         }
782         /* Now check the pending queue */
783         TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
784                 if (chk->whoTo == net) {
785                         sctp_free_remote_addr(chk->whoTo);
786                         chk->whoTo = alt;
787                         atomic_add_int(&alt->ref_count, 1);
788                 }
789         }
790
791 }
792
793 int
794 sctp_t3rxt_timer(struct sctp_inpcb *inp,
795     struct sctp_tcb *stcb,
796     struct sctp_nets *net)
797 {
798         struct sctp_nets *alt;
799         int win_probe, num_mk;
800
801 #ifdef SCTP_FR_LOGGING
802         sctp_log_fr(0, 0, 0, SCTP_FR_T3_TIMEOUT);
803 #ifdef SCTP_CWND_LOGGING
804         {
805                 struct sctp_nets *lnet;
806
807                 TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
808                         if (net == lnet) {
809                                 sctp_log_cwnd(stcb, lnet, 1, SCTP_CWND_LOG_FROM_T3);
810                         } else {
811                                 sctp_log_cwnd(stcb, lnet, 0, SCTP_CWND_LOG_FROM_T3);
812                         }
813                 }
814         }
815 #endif
816 #endif
817         /* Find an alternate and mark those for retransmission */
818         if ((stcb->asoc.peers_rwnd == 0) &&
819             (stcb->asoc.total_flight < net->mtu)) {
820                 SCTP_STAT_INCR(sctps_timowindowprobe);
821                 win_probe = 1;
822         } else {
823                 win_probe = 0;
824         }
825
826         if (sctp_cmt_on_off) {
827                 /*
828                  * CMT: Using RTX_SSTHRESH policy for CMT. If CMT is being
829                  * used, then pick dest with largest ssthresh for any
830                  * retransmission.
831                  */
832                 alt = net;
833                 alt = sctp_find_alternate_net(stcb, alt, 1);
834                 /*
835                  * CUCv2: If a different dest is picked for the
836                  * retransmission, then new (rtx-)pseudo_cumack needs to be
837                  * tracked for orig dest. Let CUCv2 track new (rtx-)
838                  * pseudo-cumack always.
839                  */
840                 net->find_pseudo_cumack = 1;
841                 net->find_rtx_pseudo_cumack = 1;
842
843         } else {                /* CMT is OFF */
844
845                 alt = sctp_find_alternate_net(stcb, net, 0);
846         }
847
848         (void)sctp_mark_all_for_resend(stcb, net, alt, win_probe, &num_mk);
849         /* FR Loss recovery just ended with the T3. */
850         stcb->asoc.fast_retran_loss_recovery = 0;
851
852         /* CMT FR loss recovery ended with the T3 */
853         net->fast_retran_loss_recovery = 0;
854
855         /*
856          * setup the sat loss recovery that prevents satellite cwnd advance.
857          */
858         stcb->asoc.sat_t3_loss_recovery = 1;
859         stcb->asoc.sat_t3_recovery_tsn = stcb->asoc.sending_seq;
860
861         /* Backoff the timer and cwnd */
862         sctp_backoff_on_timeout(stcb, net, win_probe, num_mk);
863         if (win_probe == 0) {
864                 /* We don't do normal threshold management on window probes */
865                 if (sctp_threshold_management(inp, stcb, net,
866                     stcb->asoc.max_send_times)) {
867                         /* Association was destroyed */
868                         return (1);
869                 } else {
870                         if (net != stcb->asoc.primary_destination) {
871                                 /* send a immediate HB if our RTO is stale */
872                                 struct timeval now;
873                                 unsigned int ms_goneby;
874
875                                 (void)SCTP_GETTIME_TIMEVAL(&now);
876                                 if (net->last_sent_time.tv_sec) {
877                                         ms_goneby = (now.tv_sec - net->last_sent_time.tv_sec) * 1000;
878                                 } else {
879                                         ms_goneby = 0;
880                                 }
881                                 if ((ms_goneby > net->RTO) || (net->RTO == 0)) {
882                                         /*
883                                          * no recent feed back in an RTO or
884                                          * more, request a RTT update
885                                          */
886                                         (void)sctp_send_hb(stcb, 1, net);
887                                 }
888                         }
889                 }
890         } else {
891                 /*
892                  * For a window probe we don't penalize the net's but only
893                  * the association. This may fail it if SACKs are not coming
894                  * back. If sack's are coming with rwnd locked at 0, we will
895                  * continue to hold things waiting for rwnd to raise
896                  */
897                 if (sctp_threshold_management(inp, stcb, NULL,
898                     stcb->asoc.max_send_times)) {
899                         /* Association was destroyed */
900                         return (1);
901                 }
902         }
903         if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) {
904                 /* Move all pending over too */
905                 sctp_move_all_chunks_to_alt(stcb, net, alt);
906
907                 /*
908                  * Get the address that failed, to force a new src address
909                  * selecton and a route allocation.
910                  */
911                 if (net->ro._s_addr) {
912                         sctp_free_ifa(net->ro._s_addr);
913                         net->ro._s_addr = NULL;
914                 }
915                 net->src_addr_selected = 0;
916
917                 /* Force a route allocation too */
918                 if (net->ro.ro_rt) {
919                         RTFREE(net->ro.ro_rt);
920                         net->ro.ro_rt = NULL;
921                 }
922                 /* Was it our primary? */
923                 if ((stcb->asoc.primary_destination == net) && (alt != net)) {
924                         /*
925                          * Yes, note it as such and find an alternate note:
926                          * this means HB code must use this to resent the
927                          * primary if it goes active AND if someone does a
928                          * change-primary then this flag must be cleared
929                          * from any net structures.
930                          */
931                         if (sctp_set_primary_addr(stcb,
932                             (struct sockaddr *)NULL,
933                             alt) == 0) {
934                                 net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
935                         }
936                 }
937         }
938         /*
939          * Special case for cookie-echo'ed case, we don't do output but must
940          * await the COOKIE-ACK before retransmission
941          */
942         if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
943                 /*
944                  * Here we just reset the timer and start again since we
945                  * have not established the asoc
946                  */
947                 sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
948                 return (0);
949         }
950         if (stcb->asoc.peer_supports_prsctp) {
951                 struct sctp_tmit_chunk *lchk;
952
953                 lchk = sctp_try_advance_peer_ack_point(stcb, &stcb->asoc);
954                 /* C3. See if we need to send a Fwd-TSN */
955                 if (compare_with_wrap(stcb->asoc.advanced_peer_ack_point,
956                     stcb->asoc.last_acked_seq, MAX_TSN)) {
957                         /*
958                          * ISSUE with ECN, see FWD-TSN processing for notes
959                          * on issues that will occur when the ECN NONCE
960                          * stuff is put into SCTP for cross checking.
961                          */
962                         send_forward_tsn(stcb, &stcb->asoc);
963                         if (lchk) {
964                                 /* Assure a timer is up */
965                                 sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, lchk->whoTo);
966                         }
967                 }
968         }
969 #ifdef SCTP_CWND_MONITOR
970         sctp_log_cwnd(stcb, net, net->cwnd, SCTP_CWND_LOG_FROM_RTX);
971 #endif
972         return (0);
973 }
974
975 int
976 sctp_t1init_timer(struct sctp_inpcb *inp,
977     struct sctp_tcb *stcb,
978     struct sctp_nets *net)
979 {
980         /* bump the thresholds */
981         if (stcb->asoc.delayed_connection) {
982                 /*
983                  * special hook for delayed connection. The library did NOT
984                  * complete the rest of its sends.
985                  */
986                 stcb->asoc.delayed_connection = 0;
987                 sctp_send_initiate(inp, stcb);
988                 return (0);
989         }
990         if (SCTP_GET_STATE((&stcb->asoc)) != SCTP_STATE_COOKIE_WAIT) {
991                 return (0);
992         }
993         if (sctp_threshold_management(inp, stcb, net,
994             stcb->asoc.max_init_times)) {
995                 /* Association was destroyed */
996                 return (1);
997         }
998         stcb->asoc.dropped_special_cnt = 0;
999         sctp_backoff_on_timeout(stcb, stcb->asoc.primary_destination, 1, 0);
1000         if (stcb->asoc.initial_init_rto_max < net->RTO) {
1001                 net->RTO = stcb->asoc.initial_init_rto_max;
1002         }
1003         if (stcb->asoc.numnets > 1) {
1004                 /* If we have more than one addr use it */
1005                 struct sctp_nets *alt;
1006
1007                 alt = sctp_find_alternate_net(stcb, stcb->asoc.primary_destination, 0);
1008                 if ((alt != NULL) && (alt != stcb->asoc.primary_destination)) {
1009                         sctp_move_all_chunks_to_alt(stcb, stcb->asoc.primary_destination, alt);
1010                         stcb->asoc.primary_destination = alt;
1011                 }
1012         }
1013         /* Send out a new init */
1014         sctp_send_initiate(inp, stcb);
1015         return (0);
1016 }
1017
1018 /*
1019  * For cookie and asconf we actually need to find and mark for resend, then
1020  * increment the resend counter (after all the threshold management stuff of
1021  * course).
1022  */
1023 int
1024 sctp_cookie_timer(struct sctp_inpcb *inp,
1025     struct sctp_tcb *stcb,
1026     struct sctp_nets *net)
1027 {
1028         struct sctp_nets *alt;
1029         struct sctp_tmit_chunk *cookie;
1030
1031         /* first before all else we must find the cookie */
1032         TAILQ_FOREACH(cookie, &stcb->asoc.control_send_queue, sctp_next) {
1033                 if (cookie->rec.chunk_id.id == SCTP_COOKIE_ECHO) {
1034                         break;
1035                 }
1036         }
1037         if (cookie == NULL) {
1038                 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
1039                         /* FOOBAR! */
1040                         struct mbuf *oper;
1041
1042                         oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
1043                             0, M_DONTWAIT, 1, MT_DATA);
1044                         if (oper) {
1045                                 struct sctp_paramhdr *ph;
1046                                 uint32_t *ippp;
1047
1048                                 SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
1049                                     sizeof(uint32_t);
1050                                 ph = mtod(oper, struct sctp_paramhdr *);
1051                                 ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
1052                                 ph->param_length = htons(SCTP_BUF_LEN(oper));
1053                                 ippp = (uint32_t *) (ph + 1);
1054                                 *ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_2);
1055                         }
1056                         inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_3;
1057                         sctp_abort_an_association(inp, stcb, SCTP_INTERNAL_ERROR,
1058                             oper);
1059                 } else {
1060 #ifdef INVARIANTS
1061                         panic("Cookie timer expires in wrong state?");
1062 #else
1063                         SCTP_PRINTF("Strange in state %d not cookie-echoed yet c-e timer expires?\n", SCTP_GET_STATE(&stcb->asoc));
1064                         return (0);
1065 #endif
1066                 }
1067                 return (0);
1068         }
1069         /* Ok we found the cookie, threshold management next */
1070         if (sctp_threshold_management(inp, stcb, cookie->whoTo,
1071             stcb->asoc.max_init_times)) {
1072                 /* Assoc is over */
1073                 return (1);
1074         }
1075         /*
1076          * cleared theshold management now lets backoff the address & select
1077          * an alternate
1078          */
1079         stcb->asoc.dropped_special_cnt = 0;
1080         sctp_backoff_on_timeout(stcb, cookie->whoTo, 1, 0);
1081         alt = sctp_find_alternate_net(stcb, cookie->whoTo, 0);
1082         if (alt != cookie->whoTo) {
1083                 sctp_free_remote_addr(cookie->whoTo);
1084                 cookie->whoTo = alt;
1085                 atomic_add_int(&alt->ref_count, 1);
1086         }
1087         /* Now mark the retran info */
1088         if (cookie->sent != SCTP_DATAGRAM_RESEND) {
1089                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1090         }
1091         cookie->sent = SCTP_DATAGRAM_RESEND;
1092         /*
1093          * Now call the output routine to kick out the cookie again, Note we
1094          * don't mark any chunks for retran so that FR will need to kick in
1095          * to move these (or a send timer).
1096          */
1097         return (0);
1098 }
1099
1100 int
1101 sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1102     struct sctp_nets *net)
1103 {
1104         struct sctp_nets *alt;
1105         struct sctp_tmit_chunk *strrst = NULL, *chk = NULL;
1106
1107         if (stcb->asoc.stream_reset_outstanding == 0) {
1108                 return (0);
1109         }
1110         /* find the existing STRRESET, we use the seq number we sent out on */
1111         (void)sctp_find_stream_reset(stcb, stcb->asoc.str_reset_seq_out, &strrst);
1112         if (strrst == NULL) {
1113                 return (0);
1114         }
1115         /* do threshold management */
1116         if (sctp_threshold_management(inp, stcb, strrst->whoTo,
1117             stcb->asoc.max_send_times)) {
1118                 /* Assoc is over */
1119                 return (1);
1120         }
1121         /*
1122          * cleared theshold management now lets backoff the address & select
1123          * an alternate
1124          */
1125         sctp_backoff_on_timeout(stcb, strrst->whoTo, 1, 0);
1126         alt = sctp_find_alternate_net(stcb, strrst->whoTo, 0);
1127         sctp_free_remote_addr(strrst->whoTo);
1128         strrst->whoTo = alt;
1129         atomic_add_int(&alt->ref_count, 1);
1130
1131         /* See if a ECN Echo is also stranded */
1132         TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
1133                 if ((chk->whoTo == net) &&
1134                     (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) {
1135                         sctp_free_remote_addr(chk->whoTo);
1136                         if (chk->sent != SCTP_DATAGRAM_RESEND) {
1137                                 chk->sent = SCTP_DATAGRAM_RESEND;
1138                                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1139                         }
1140                         chk->whoTo = alt;
1141                         atomic_add_int(&alt->ref_count, 1);
1142                 }
1143         }
1144         if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) {
1145                 /*
1146                  * If the address went un-reachable, we need to move to
1147                  * alternates for ALL chk's in queue
1148                  */
1149                 sctp_move_all_chunks_to_alt(stcb, net, alt);
1150         }
1151         /* mark the retran info */
1152         if (strrst->sent != SCTP_DATAGRAM_RESEND)
1153                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1154         strrst->sent = SCTP_DATAGRAM_RESEND;
1155
1156         /* restart the timer */
1157         sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, inp, stcb, strrst->whoTo);
1158         return (0);
1159 }
1160
1161 int
1162 sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1163     struct sctp_nets *net)
1164 {
1165         struct sctp_nets *alt;
1166         struct sctp_tmit_chunk *asconf, *chk;
1167
1168         /* is this the first send, or a retransmission? */
1169         if (stcb->asoc.asconf_sent == 0) {
1170                 /* compose a new ASCONF chunk and send it */
1171                 sctp_send_asconf(stcb, net);
1172         } else {
1173                 /* Retransmission of the existing ASCONF needed... */
1174
1175                 /* find the existing ASCONF */
1176                 TAILQ_FOREACH(asconf, &stcb->asoc.control_send_queue,
1177                     sctp_next) {
1178                         if (asconf->rec.chunk_id.id == SCTP_ASCONF) {
1179                                 break;
1180                         }
1181                 }
1182                 if (asconf == NULL) {
1183                         return (0);
1184                 }
1185                 /* do threshold management */
1186                 if (sctp_threshold_management(inp, stcb, asconf->whoTo,
1187                     stcb->asoc.max_send_times)) {
1188                         /* Assoc is over */
1189                         return (1);
1190                 }
1191                 /*
1192                  * PETER? FIX? How will the following code ever run? If the
1193                  * max_send_times is hit, threshold managment will blow away
1194                  * the association?
1195                  */
1196                 if (asconf->snd_count > stcb->asoc.max_send_times) {
1197                         /*
1198                          * Something is rotten, peer is not responding to
1199                          * ASCONFs but maybe is to data etc.  e.g. it is not
1200                          * properly handling the chunk type upper bits Mark
1201                          * this peer as ASCONF incapable and cleanup
1202                          */
1203                         SCTPDBG(SCTP_DEBUG_TIMER1, "asconf_timer: Peer has not responded to our repeated ASCONFs\n");
1204                         sctp_asconf_cleanup(stcb, net);
1205                         return (0);
1206                 }
1207                 /*
1208                  * cleared theshold management now lets backoff the address
1209                  * & select an alternate
1210                  */
1211                 sctp_backoff_on_timeout(stcb, asconf->whoTo, 1, 0);
1212                 alt = sctp_find_alternate_net(stcb, asconf->whoTo, 0);
1213                 sctp_free_remote_addr(asconf->whoTo);
1214                 asconf->whoTo = alt;
1215                 atomic_add_int(&alt->ref_count, 1);
1216
1217                 /* See if a ECN Echo is also stranded */
1218                 TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
1219                         if ((chk->whoTo == net) &&
1220                             (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) {
1221                                 sctp_free_remote_addr(chk->whoTo);
1222                                 chk->whoTo = alt;
1223                                 if (chk->sent != SCTP_DATAGRAM_RESEND) {
1224                                         chk->sent = SCTP_DATAGRAM_RESEND;
1225                                         sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1226                                 }
1227                                 atomic_add_int(&alt->ref_count, 1);
1228                         }
1229                 }
1230                 if (net->dest_state & SCTP_ADDR_NOT_REACHABLE) {
1231                         /*
1232                          * If the address went un-reachable, we need to move
1233                          * to alternates for ALL chk's in queue
1234                          */
1235                         sctp_move_all_chunks_to_alt(stcb, net, alt);
1236                 }
1237                 /* mark the retran info */
1238                 if (asconf->sent != SCTP_DATAGRAM_RESEND)
1239                         sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1240                 asconf->sent = SCTP_DATAGRAM_RESEND;
1241         }
1242         return (0);
1243 }
1244
1245 /*
1246  * For the shutdown and shutdown-ack, we do not keep one around on the
1247  * control queue. This means we must generate a new one and call the general
1248  * chunk output routine, AFTER having done threshold management.
1249  */
1250 int
1251 sctp_shutdown_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1252     struct sctp_nets *net)
1253 {
1254         struct sctp_nets *alt;
1255
1256         /* first threshold managment */
1257         if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
1258                 /* Assoc is over */
1259                 return (1);
1260         }
1261         /* second select an alternative */
1262         alt = sctp_find_alternate_net(stcb, net, 0);
1263
1264         /* third generate a shutdown into the queue for out net */
1265         if (alt) {
1266                 sctp_send_shutdown(stcb, alt);
1267         } else {
1268                 /*
1269                  * if alt is NULL, there is no dest to send to??
1270                  */
1271                 return (0);
1272         }
1273         /* fourth restart timer */
1274         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, inp, stcb, alt);
1275         return (0);
1276 }
1277
1278 int
1279 sctp_shutdownack_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1280     struct sctp_nets *net)
1281 {
1282         struct sctp_nets *alt;
1283
1284         /* first threshold managment */
1285         if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
1286                 /* Assoc is over */
1287                 return (1);
1288         }
1289         /* second select an alternative */
1290         alt = sctp_find_alternate_net(stcb, net, 0);
1291
1292         /* third generate a shutdown into the queue for out net */
1293         sctp_send_shutdown_ack(stcb, alt);
1294
1295         /* fourth restart timer */
1296         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK, inp, stcb, alt);
1297         return (0);
1298 }
1299
1300 static void
1301 sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp,
1302     struct sctp_tcb *stcb)
1303 {
1304         struct sctp_stream_out *outs;
1305         struct sctp_stream_queue_pending *sp;
1306         unsigned int chks_in_queue = 0;
1307         int being_filled = 0;
1308
1309         /*
1310          * This function is ONLY called when the send/sent queues are empty.
1311          */
1312         if ((stcb == NULL) || (inp == NULL))
1313                 return;
1314
1315         if (stcb->asoc.sent_queue_retran_cnt) {
1316                 SCTP_PRINTF("Hmm, sent_queue_retran_cnt is non-zero %d\n",
1317                     stcb->asoc.sent_queue_retran_cnt);
1318                 stcb->asoc.sent_queue_retran_cnt = 0;
1319         }
1320         SCTP_TCB_SEND_LOCK(stcb);
1321         if (TAILQ_EMPTY(&stcb->asoc.out_wheel)) {
1322                 int i, cnt = 0;
1323
1324                 /* Check to see if a spoke fell off the wheel */
1325                 for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
1326                         if (!TAILQ_EMPTY(&stcb->asoc.strmout[i].outqueue)) {
1327                                 sctp_insert_on_wheel(stcb, &stcb->asoc, &stcb->asoc.strmout[i], 1);
1328                                 cnt++;
1329                         }
1330                 }
1331                 if (cnt) {
1332                         /* yep, we lost a spoke or two */
1333                         SCTP_PRINTF("Found an additional %d streams NOT on outwheel, corrected\n", cnt);
1334                 } else {
1335                         /* no spokes lost, */
1336                         stcb->asoc.total_output_queue_size = 0;
1337                 }
1338                 SCTP_TCB_SEND_UNLOCK(stcb);
1339                 return;
1340         }
1341         SCTP_TCB_SEND_UNLOCK(stcb);
1342         /* Check to see if some data queued, if so report it */
1343         TAILQ_FOREACH(outs, &stcb->asoc.out_wheel, next_spoke) {
1344                 if (!TAILQ_EMPTY(&outs->outqueue)) {
1345                         TAILQ_FOREACH(sp, &outs->outqueue, next) {
1346                                 if (sp->msg_is_complete)
1347                                         being_filled++;
1348                                 chks_in_queue++;
1349                         }
1350                 }
1351         }
1352         if (chks_in_queue != stcb->asoc.stream_queue_cnt) {
1353                 SCTP_PRINTF("Hmm, stream queue cnt at %d I counted %d in stream out wheel\n",
1354                     stcb->asoc.stream_queue_cnt, chks_in_queue);
1355         }
1356         if (chks_in_queue) {
1357                 /* call the output queue function */
1358                 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3);
1359                 if ((TAILQ_EMPTY(&stcb->asoc.send_queue)) &&
1360                     (TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
1361                         /*
1362                          * Probably should go in and make it go back through
1363                          * and add fragments allowed
1364                          */
1365                         if (being_filled == 0) {
1366                                 SCTP_PRINTF("Still nothing moved %d chunks are stuck\n",
1367                                     chks_in_queue);
1368                         }
1369                 }
1370         } else {
1371                 SCTP_PRINTF("Found no chunks on any queue tot:%lu\n",
1372                     (u_long)stcb->asoc.total_output_queue_size);
1373                 stcb->asoc.total_output_queue_size = 0;
1374         }
1375 }
1376
1377 int
1378 sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1379     struct sctp_nets *net, int cnt_of_unconf)
1380 {
1381         if (net) {
1382                 if (net->hb_responded == 0) {
1383                         if (net->ro._s_addr) {
1384                                 /*
1385                                  * Invalidate the src address if we did not
1386                                  * get a response last time.
1387                                  */
1388                                 sctp_free_ifa(net->ro._s_addr);
1389                                 net->ro._s_addr = NULL;
1390                                 net->src_addr_selected = 0;
1391                         }
1392                         sctp_backoff_on_timeout(stcb, net, 1, 0);
1393                 }
1394                 /* Zero PBA, if it needs it */
1395                 if (net->partial_bytes_acked) {
1396                         net->partial_bytes_acked = 0;
1397                 }
1398         }
1399         if ((stcb->asoc.total_output_queue_size > 0) &&
1400             (TAILQ_EMPTY(&stcb->asoc.send_queue)) &&
1401             (TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
1402                 sctp_audit_stream_queues_for_size(inp, stcb);
1403         }
1404         /* Send a new HB, this will do threshold managment, pick a new dest */
1405         if (cnt_of_unconf == 0) {
1406                 if (sctp_send_hb(stcb, 0, NULL) < 0) {
1407                         return (1);
1408                 }
1409         } else {
1410                 /*
1411                  * this will send out extra hb's up to maxburst if there are
1412                  * any unconfirmed addresses.
1413                  */
1414                 int cnt_sent = 0;
1415
1416                 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1417                         if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
1418                             (net->dest_state & SCTP_ADDR_REACHABLE)) {
1419                                 cnt_sent++;
1420                                 if (net->hb_responded == 0) {
1421                                         /* Did we respond last time? */
1422                                         if (net->ro._s_addr) {
1423                                                 sctp_free_ifa(net->ro._s_addr);
1424                                                 net->ro._s_addr = NULL;
1425                                                 net->src_addr_selected = 0;
1426                                         }
1427                                 }
1428                                 if (sctp_send_hb(stcb, 1, net) == 0) {
1429                                         break;
1430                                 }
1431                                 if (cnt_sent >= sctp_hb_maxburst)
1432                                         break;
1433                         }
1434                 }
1435         }
1436         return (0);
1437 }
1438
1439 int
1440 sctp_is_hb_timer_running(struct sctp_tcb *stcb)
1441 {
1442         if (SCTP_OS_TIMER_PENDING(&stcb->asoc.hb_timer.timer)) {
1443                 /* its running */
1444                 return (1);
1445         } else {
1446                 /* nope */
1447                 return (0);
1448         }
1449 }
1450
1451 int
1452 sctp_is_sack_timer_running(struct sctp_tcb *stcb)
1453 {
1454         if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
1455                 /* its running */
1456                 return (1);
1457         } else {
1458                 /* nope */
1459                 return (0);
1460         }
1461 }
1462
1463 #define SCTP_NUMBER_OF_MTU_SIZES 18
1464 static uint32_t mtu_sizes[] = {
1465         68,
1466         296,
1467         508,
1468         512,
1469         544,
1470         576,
1471         1006,
1472         1492,
1473         1500,
1474         1536,
1475         2002,
1476         2048,
1477         4352,
1478         4464,
1479         8166,
1480         17914,
1481         32000,
1482         65535
1483 };
1484
1485
1486 static uint32_t
1487 sctp_getnext_mtu(struct sctp_inpcb *inp, uint32_t cur_mtu)
1488 {
1489         /* select another MTU that is just bigger than this one */
1490         int i;
1491
1492         for (i = 0; i < SCTP_NUMBER_OF_MTU_SIZES; i++) {
1493                 if (cur_mtu < mtu_sizes[i]) {
1494                         /* no max_mtu is bigger than this one */
1495                         return (mtu_sizes[i]);
1496                 }
1497         }
1498         /* here return the highest allowable */
1499         return (cur_mtu);
1500 }
1501
1502
1503 void
1504 sctp_pathmtu_timer(struct sctp_inpcb *inp,
1505     struct sctp_tcb *stcb,
1506     struct sctp_nets *net)
1507 {
1508         uint32_t next_mtu;
1509
1510         /* restart the timer in any case */
1511         next_mtu = sctp_getnext_mtu(inp, net->mtu);
1512         if (next_mtu <= net->mtu) {
1513                 /* nothing to do */
1514                 return;
1515         } {
1516                 uint32_t mtu;
1517
1518                 if ((net->src_addr_selected == 0) ||
1519                     (net->ro._s_addr == NULL) ||
1520                     (net->ro._s_addr->localifa_flags & SCTP_BEING_DELETED)) {
1521                         if ((net->ro._s_addr != NULL) && (net->ro._s_addr->localifa_flags & SCTP_BEING_DELETED)) {
1522                                 sctp_free_ifa(net->ro._s_addr);
1523                                 net->ro._s_addr = NULL;
1524                                 net->src_addr_selected = 0;
1525                         } else if (net->ro._s_addr == NULL) {
1526                                 net->ro._s_addr = sctp_source_address_selection(inp,
1527                                     stcb,
1528                                     (sctp_route_t *) & net->ro,
1529                                     net, 0, stcb->asoc.vrf_id);
1530                         }
1531                         if (net->ro._s_addr)
1532                                 net->src_addr_selected = 1;
1533                 }
1534                 if (net->ro._s_addr) {
1535                         mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._s_addr.sa, net->ro.ro_rt);
1536                         if (mtu > next_mtu) {
1537                                 net->mtu = next_mtu;
1538                         }
1539                 }
1540         }
1541         /* restart the timer */
1542         sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
1543 }
1544
1545 void
1546 sctp_autoclose_timer(struct sctp_inpcb *inp,
1547     struct sctp_tcb *stcb,
1548     struct sctp_nets *net)
1549 {
1550         struct timeval tn, *tim_touse;
1551         struct sctp_association *asoc;
1552         int ticks_gone_by;
1553
1554         (void)SCTP_GETTIME_TIMEVAL(&tn);
1555         if (stcb->asoc.sctp_autoclose_ticks &&
1556             sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) {
1557                 /* Auto close is on */
1558                 asoc = &stcb->asoc;
1559                 /* pick the time to use */
1560                 if (asoc->time_last_rcvd.tv_sec >
1561                     asoc->time_last_sent.tv_sec) {
1562                         tim_touse = &asoc->time_last_rcvd;
1563                 } else {
1564                         tim_touse = &asoc->time_last_sent;
1565                 }
1566                 /* Now has long enough transpired to autoclose? */
1567                 ticks_gone_by = SEC_TO_TICKS(tn.tv_sec - tim_touse->tv_sec);
1568                 if ((ticks_gone_by > 0) &&
1569                     (ticks_gone_by >= (int)asoc->sctp_autoclose_ticks)) {
1570                         /*
1571                          * autoclose time has hit, call the output routine,
1572                          * which should do nothing just to be SURE we don't
1573                          * have hanging data. We can then safely check the
1574                          * queues and know that we are clear to send
1575                          * shutdown
1576                          */
1577                         sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_AUTOCLOSE_TMR);
1578                         /* Are we clean? */
1579                         if (TAILQ_EMPTY(&asoc->send_queue) &&
1580                             TAILQ_EMPTY(&asoc->sent_queue)) {
1581                                 /*
1582                                  * there is nothing queued to send, so I'm
1583                                  * done...
1584                                  */
1585                                 if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) {
1586                                         /* only send SHUTDOWN 1st time thru */
1587                                         sctp_send_shutdown(stcb, stcb->asoc.primary_destination);
1588                                         if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
1589                                             (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
1590                                                 SCTP_STAT_DECR_GAUGE32(sctps_currestab);
1591                                         }
1592                                         asoc->state = SCTP_STATE_SHUTDOWN_SENT;
1593                                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
1594                                             stcb->sctp_ep, stcb,
1595                                             asoc->primary_destination);
1596                                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
1597                                             stcb->sctp_ep, stcb,
1598                                             asoc->primary_destination);
1599                                 }
1600                         }
1601                 } else {
1602                         /*
1603                          * No auto close at this time, reset t-o to check
1604                          * later
1605                          */
1606                         int tmp;
1607
1608                         /* fool the timer startup to use the time left */
1609                         tmp = asoc->sctp_autoclose_ticks;
1610                         asoc->sctp_autoclose_ticks -= ticks_gone_by;
1611                         sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb,
1612                             net);
1613                         /* restore the real tick value */
1614                         asoc->sctp_autoclose_ticks = tmp;
1615                 }
1616         }
1617 }
1618
1619 void
1620 sctp_iterator_timer(struct sctp_iterator *it)
1621 {
1622         int iteration_count = 0;
1623         int inp_skip = 0;
1624
1625         /*
1626          * only one iterator can run at a time. This is the only way we can
1627          * cleanly pull ep's from underneath all the running interators when
1628          * a ep is freed.
1629          */
1630         SCTP_ITERATOR_LOCK();
1631         if (it->inp == NULL) {
1632                 /* iterator is complete */
1633 done_with_iterator:
1634                 SCTP_ITERATOR_UNLOCK();
1635                 SCTP_INP_INFO_WLOCK();
1636                 TAILQ_REMOVE(&sctppcbinfo.iteratorhead, it, sctp_nxt_itr);
1637                 /* stopping the callout is not needed, in theory */
1638                 SCTP_INP_INFO_WUNLOCK();
1639                 (void)SCTP_OS_TIMER_STOP(&it->tmr.timer);
1640                 if (it->function_atend != NULL) {
1641                         (*it->function_atend) (it->pointer, it->val);
1642                 }
1643                 SCTP_FREE(it);
1644                 return;
1645         }
1646 select_a_new_ep:
1647         SCTP_INP_WLOCK(it->inp);
1648         while (((it->pcb_flags) &&
1649             ((it->inp->sctp_flags & it->pcb_flags) != it->pcb_flags)) ||
1650             ((it->pcb_features) &&
1651             ((it->inp->sctp_features & it->pcb_features) != it->pcb_features))) {
1652                 /* endpoint flags or features don't match, so keep looking */
1653                 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
1654                         SCTP_INP_WUNLOCK(it->inp);
1655                         goto done_with_iterator;
1656                 }
1657                 SCTP_INP_WUNLOCK(it->inp);
1658                 it->inp = LIST_NEXT(it->inp, sctp_list);
1659                 if (it->inp == NULL) {
1660                         goto done_with_iterator;
1661                 }
1662                 SCTP_INP_WLOCK(it->inp);
1663         }
1664         if ((it->inp->inp_starting_point_for_iterator != NULL) &&
1665             (it->inp->inp_starting_point_for_iterator != it)) {
1666                 SCTP_PRINTF("Iterator collision, waiting for one at %p\n",
1667                     it->inp);
1668                 SCTP_INP_WUNLOCK(it->inp);
1669                 goto start_timer_return;
1670         }
1671         /* mark the current iterator on the endpoint */
1672         it->inp->inp_starting_point_for_iterator = it;
1673         SCTP_INP_WUNLOCK(it->inp);
1674         SCTP_INP_RLOCK(it->inp);
1675         /* now go through each assoc which is in the desired state */
1676         if (it->done_current_ep == 0) {
1677                 if (it->function_inp != NULL)
1678                         inp_skip = (*it->function_inp) (it->inp, it->pointer, it->val);
1679                 it->done_current_ep = 1;
1680         }
1681         if (it->stcb == NULL) {
1682                 /* run the per instance function */
1683                 it->stcb = LIST_FIRST(&it->inp->sctp_asoc_list);
1684         }
1685         SCTP_INP_RUNLOCK(it->inp);
1686         if ((inp_skip) || it->stcb == NULL) {
1687                 if (it->function_inp_end != NULL) {
1688                         inp_skip = (*it->function_inp_end) (it->inp,
1689                             it->pointer,
1690                             it->val);
1691                 }
1692                 goto no_stcb;
1693         }
1694         if ((it->stcb) &&
1695             (it->stcb->asoc.stcb_starting_point_for_iterator == it)) {
1696                 it->stcb->asoc.stcb_starting_point_for_iterator = NULL;
1697         }
1698         while (it->stcb) {
1699                 SCTP_TCB_LOCK(it->stcb);
1700                 if (it->asoc_state && ((it->stcb->asoc.state & it->asoc_state) != it->asoc_state)) {
1701                         /* not in the right state... keep looking */
1702                         SCTP_TCB_UNLOCK(it->stcb);
1703                         goto next_assoc;
1704                 }
1705                 /* mark the current iterator on the assoc */
1706                 it->stcb->asoc.stcb_starting_point_for_iterator = it;
1707                 /* see if we have limited out the iterator loop */
1708                 iteration_count++;
1709                 if (iteration_count > SCTP_ITERATOR_MAX_AT_ONCE) {
1710         start_timer_return:
1711                         /* set a timer to continue this later */
1712                         SCTP_TCB_UNLOCK(it->stcb);
1713                         sctp_timer_start(SCTP_TIMER_TYPE_ITERATOR,
1714                             (struct sctp_inpcb *)it, NULL, NULL);
1715                         SCTP_ITERATOR_UNLOCK();
1716                         return;
1717                 }
1718                 /* run function on this one */
1719                 (*it->function_assoc) (it->inp, it->stcb, it->pointer, it->val);
1720
1721                 /*
1722                  * we lie here, it really needs to have its own type but
1723                  * first I must verify that this won't effect things :-0
1724                  */
1725                 if (it->no_chunk_output == 0)
1726                         sctp_chunk_output(it->inp, it->stcb, SCTP_OUTPUT_FROM_T3);
1727
1728                 SCTP_TCB_UNLOCK(it->stcb);
1729 next_assoc:
1730                 it->stcb = LIST_NEXT(it->stcb, sctp_tcblist);
1731                 if (it->stcb == NULL) {
1732                         if (it->function_inp_end != NULL) {
1733                                 inp_skip = (*it->function_inp_end) (it->inp,
1734                                     it->pointer,
1735                                     it->val);
1736                         }
1737                 }
1738         }
1739 no_stcb:
1740         /* done with all assocs on this endpoint, move on to next endpoint */
1741         it->done_current_ep = 0;
1742         SCTP_INP_WLOCK(it->inp);
1743         it->inp->inp_starting_point_for_iterator = NULL;
1744         SCTP_INP_WUNLOCK(it->inp);
1745         if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
1746                 it->inp = NULL;
1747         } else {
1748                 SCTP_INP_INFO_RLOCK();
1749                 it->inp = LIST_NEXT(it->inp, sctp_list);
1750                 SCTP_INP_INFO_RUNLOCK();
1751         }
1752         if (it->inp == NULL) {
1753                 goto done_with_iterator;
1754         }
1755         goto select_a_new_ep;
1756 }