[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/sctp_timer.c

Version: -  FREEBSD  -  FREEBSD10  -  FREEBSD9  -  FREEBSD92  -  FREEBSD91  -  FREEBSD90  -  FREEBSD8  -  FREEBSD82  -  FREEBSD81  -  FREEBSD80  -  FREEBSD7  -  FREEBSD74  -  FREEBSD73  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  cheribsd  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1  -  FREEBSD-LIBC  -  FREEBSD8-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  3  -  10 

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

Cache object: 50dafd352904c9d1e9635d1e025cbb69


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.