The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


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

Cache object: 0a19f2c8d4476a7ccdd0a762f96cbc39


[ 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.