LCOV - code coverage report
Current view: top level - netwerk/sctp/src/netinet - sctp_timer.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 688 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-
       2             :  * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
       3             :  * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
       4             :  * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions are met:
       8             :  *
       9             :  * a) Redistributions of source code must retain the above copyright notice,
      10             :  *    this list of conditions and the following disclaimer.
      11             :  *
      12             :  * b) Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in
      14             :  *    the documentation and/or other materials provided with the distribution.
      15             :  *
      16             :  * c) Neither the name of Cisco Systems, Inc. nor the names of its
      17             :  *    contributors may be used to endorse or promote products derived
      18             :  *    from this software without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
      22             :  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      23             :  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
      24             :  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      25             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      26             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      27             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      28             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      29             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
      30             :  * THE POSSIBILITY OF SUCH DAMAGE.
      31             :  */
      32             : 
      33             : #ifdef __FreeBSD__
      34             : #include <sys/cdefs.h>
      35             : __FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 279841 2015-03-10 09:16:31Z tuexen $");
      36             : #endif
      37             : 
      38             : #define _IP_VHL
      39             : #include <netinet/sctp_os.h>
      40             : #include <netinet/sctp_pcb.h>
      41             : #ifdef INET6
      42             : #if defined(__Userspace_os_FreeBSD)
      43             : #include <netinet6/sctp6_var.h>
      44             : #endif
      45             : #endif
      46             : #include <netinet/sctp_var.h>
      47             : #include <netinet/sctp_sysctl.h>
      48             : #include <netinet/sctp_timer.h>
      49             : #include <netinet/sctputil.h>
      50             : #include <netinet/sctp_output.h>
      51             : #include <netinet/sctp_header.h>
      52             : #include <netinet/sctp_indata.h>
      53             : #include <netinet/sctp_asconf.h>
      54             : #include <netinet/sctp_input.h>
      55             : #include <netinet/sctp.h>
      56             : #include <netinet/sctp_uio.h>
      57             : #if defined(INET) || defined(INET6)
      58             : #if !defined(__Userspace_os_Windows)
      59             : #include <netinet/udp.h>
      60             : #endif
      61             : #endif
      62             : 
      63             : #if defined(__APPLE__)
      64             : #define APPLE_FILE_NO 6
      65             : #endif
      66             : 
      67             : void
      68           0 : sctp_audit_retranmission_queue(struct sctp_association *asoc)
      69             : {
      70             :         struct sctp_tmit_chunk *chk;
      71             : 
      72           0 :         SCTPDBG(SCTP_DEBUG_TIMER4, "Audit invoked on send queue cnt:%d onqueue:%d\n",
      73             :                         asoc->sent_queue_retran_cnt,
      74             :                         asoc->sent_queue_cnt);
      75           0 :         asoc->sent_queue_retran_cnt = 0;
      76           0 :         asoc->sent_queue_cnt = 0;
      77           0 :         TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
      78           0 :                 if (chk->sent == SCTP_DATAGRAM_RESEND) {
      79           0 :                         sctp_ucount_incr(asoc->sent_queue_retran_cnt);
      80             :                 }
      81           0 :                 asoc->sent_queue_cnt++;
      82             :         }
      83           0 :         TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
      84           0 :                 if (chk->sent == SCTP_DATAGRAM_RESEND) {
      85           0 :                         sctp_ucount_incr(asoc->sent_queue_retran_cnt);
      86             :                 }
      87             :         }
      88           0 :         TAILQ_FOREACH(chk, &asoc->asconf_send_queue, sctp_next) {
      89           0 :                 if (chk->sent == SCTP_DATAGRAM_RESEND) {
      90           0 :                         sctp_ucount_incr(asoc->sent_queue_retran_cnt);
      91             :                 }
      92             :         }
      93           0 :         SCTPDBG(SCTP_DEBUG_TIMER4, "Audit completes retran:%d onqueue:%d\n",
      94             :                 asoc->sent_queue_retran_cnt,
      95             :                 asoc->sent_queue_cnt);
      96           0 : }
      97             : 
      98             : int
      99           0 : sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
     100             :     struct sctp_nets *net, uint16_t threshold)
     101             : {
     102           0 :         if (net) {
     103           0 :                 net->error_count++;
     104           0 :                 SCTPDBG(SCTP_DEBUG_TIMER4, "Error count for %p now %d thresh:%d\n",
     105             :                         (void *)net, net->error_count,
     106             :                         net->failure_threshold);
     107           0 :                 if (net->error_count > net->failure_threshold) {
     108             :                         /* We had a threshold failure */
     109           0 :                         if (net->dest_state & SCTP_ADDR_REACHABLE) {
     110           0 :                                 net->dest_state &= ~SCTP_ADDR_REACHABLE;
     111           0 :                                 net->dest_state &= ~SCTP_ADDR_REQ_PRIMARY;
     112           0 :                                 net->dest_state &= ~SCTP_ADDR_PF;
     113           0 :                                 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
     114             :                                     stcb, 0,
     115             :                                     (void *)net, SCTP_SO_NOT_LOCKED);
     116             :                         }
     117           0 :                 } else if ((net->pf_threshold < net->failure_threshold) &&
     118           0 :                            (net->error_count > net->pf_threshold)) {
     119           0 :                         if (!(net->dest_state & SCTP_ADDR_PF)) {
     120           0 :                                 net->dest_state |= SCTP_ADDR_PF;
     121           0 :                                 net->last_active = sctp_get_tick_count();
     122           0 :                                 sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
     123           0 :                                 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3);
     124           0 :                                 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
     125             :                         }
     126             :                 }
     127             :         }
     128           0 :         if (stcb == NULL)
     129           0 :                 return (0);
     130             : 
     131           0 :         if (net) {
     132           0 :                 if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) {
     133           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
     134           0 :                                 sctp_misc_ints(SCTP_THRESHOLD_INCR,
     135             :                                                stcb->asoc.overall_error_count,
     136           0 :                                                (stcb->asoc.overall_error_count+1),
     137             :                                                SCTP_FROM_SCTP_TIMER,
     138             :                                                __LINE__);
     139             :                         }
     140           0 :                         stcb->asoc.overall_error_count++;
     141             :                 }
     142             :         } else {
     143           0 :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
     144           0 :                         sctp_misc_ints(SCTP_THRESHOLD_INCR,
     145             :                                        stcb->asoc.overall_error_count,
     146           0 :                                        (stcb->asoc.overall_error_count+1),
     147             :                                        SCTP_FROM_SCTP_TIMER,
     148             :                                        __LINE__);
     149             :                 }
     150           0 :                 stcb->asoc.overall_error_count++;
     151             :         }
     152           0 :         SCTPDBG(SCTP_DEBUG_TIMER4, "Overall error count for %p now %d thresh:%u state:%x\n",
     153             :                 (void *)&stcb->asoc, stcb->asoc.overall_error_count,
     154             :                 (uint32_t)threshold,
     155             :                 ((net == NULL) ? (uint32_t) 0 : (uint32_t) net->dest_state));
     156             :         /*
     157             :          * We specifically do not do >= to give the assoc one more change
     158             :          * before we fail it.
     159             :          */
     160           0 :         if (stcb->asoc.overall_error_count > threshold) {
     161             :                 /* Abort notification sends a ULP notify */
     162             :                 struct mbuf *op_err;
     163             : 
     164           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION,
     165             :                                              "Association error counter exceeded");
     166           0 :                 inp->last_abort_code = SCTP_FROM_SCTP_TIMER+SCTP_LOC_1;
     167           0 :                 sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
     168           0 :                 return (1);
     169             :         }
     170           0 :         return (0);
     171             : }
     172             : 
     173             : /*
     174             :  * sctp_find_alternate_net() returns a non-NULL pointer as long
     175             :  * the argument net is non-NULL.
     176             :  */
     177             : struct sctp_nets *
     178           0 : sctp_find_alternate_net(struct sctp_tcb *stcb,
     179             :     struct sctp_nets *net,
     180             :     int mode)
     181             : {
     182             :         /* Find and return an alternate network if possible */
     183           0 :         struct sctp_nets *alt, *mnet, *min_errors_net = NULL , *max_cwnd_net = NULL;
     184             :         int once;
     185             :         /* JRS 5/14/07 - Initialize min_errors to an impossible value. */
     186           0 :         int min_errors = -1;
     187           0 :         uint32_t max_cwnd = 0;
     188             : 
     189           0 :         if (stcb->asoc.numnets == 1) {
     190             :                 /* No others but net */
     191           0 :                 return (TAILQ_FIRST(&stcb->asoc.nets));
     192             :         }
     193             :         /*
     194             :          * JRS 5/14/07 - If mode is set to 2, use the CMT PF find alternate net algorithm.
     195             :          * This algorithm chooses the active destination (not in PF state) with the largest
     196             :          * cwnd value. If all destinations are in PF state, unreachable, or unconfirmed, choose
     197             :          * the desination that is in PF state with the lowest error count. In case of a tie,
     198             :          * choose the destination that was most recently active.
     199             :          */
     200           0 :         if (mode == 2) {
     201           0 :                 TAILQ_FOREACH(mnet, &stcb->asoc.nets, sctp_next) {
     202             :                         /* JRS 5/14/07 - If the destination is unreachable or unconfirmed, skip it. */
     203           0 :                         if (((mnet->dest_state & SCTP_ADDR_REACHABLE) != SCTP_ADDR_REACHABLE) ||
     204           0 :                             (mnet->dest_state & SCTP_ADDR_UNCONFIRMED)) {
     205           0 :                                 continue;
     206             :                         }
     207             :                         /*
     208             :                          * JRS 5/14/07 -  If the destination is reachable but in PF state, compare
     209             :                          *  the error count of the destination to the minimum error count seen thus far.
     210             :                          *  Store the destination with the lower error count.  If the error counts are
     211             :                          *  equal, store the destination that was most recently active.
     212             :                          */
     213           0 :                         if (mnet->dest_state & SCTP_ADDR_PF) {
     214             :                                 /*
     215             :                                  * JRS 5/14/07 - If the destination under consideration is the current
     216             :                                  *  destination, work as if the error count is one higher.  The
     217             :                                  *  actual error count will not be incremented until later in the
     218             :                                  *  t3 handler.
     219             :                                  */
     220           0 :                                 if (mnet == net) {
     221           0 :                                         if (min_errors == -1) {
     222           0 :                                                 min_errors = mnet->error_count + 1;
     223           0 :                                                 min_errors_net = mnet;
     224           0 :                                         } else if (mnet->error_count + 1 < min_errors) {
     225           0 :                                                 min_errors = mnet->error_count + 1;
     226           0 :                                                 min_errors_net = mnet;
     227           0 :                                         } else if (mnet->error_count + 1 == min_errors
     228           0 :                                                                 && mnet->last_active > min_errors_net->last_active) {
     229           0 :                                                 min_errors_net = mnet;
     230           0 :                                                 min_errors = mnet->error_count + 1;
     231             :                                         }
     232           0 :                                         continue;
     233             :                                 } else {
     234           0 :                                         if (min_errors == -1) {
     235           0 :                                                 min_errors = mnet->error_count;
     236           0 :                                                 min_errors_net = mnet;
     237           0 :                                         } else if (mnet->error_count < min_errors) {
     238           0 :                                                 min_errors = mnet->error_count;
     239           0 :                                                 min_errors_net = mnet;
     240           0 :                                         } else if (mnet->error_count == min_errors
     241           0 :                                                                 && mnet->last_active > min_errors_net->last_active) {
     242           0 :                                                 min_errors_net = mnet;
     243           0 :                                                 min_errors = mnet->error_count;
     244             :                                         }
     245           0 :                                         continue;
     246             :                                 }
     247             :                         }
     248             :                         /*
     249             :                          * JRS 5/14/07 - If the destination is reachable and not in PF state, compare the
     250             :                          *  cwnd of the destination to the highest cwnd seen thus far.  Store the
     251             :                          *  destination with the higher cwnd value.  If the cwnd values are equal,
     252             :                          *  randomly choose one of the two destinations.
     253             :                          */
     254           0 :                         if (max_cwnd < mnet->cwnd) {
     255           0 :                                 max_cwnd_net = mnet;
     256           0 :                                 max_cwnd = mnet->cwnd;
     257           0 :                         } else if (max_cwnd == mnet->cwnd) {
     258             :                                 uint32_t rndval;
     259             :                                 uint8_t this_random;
     260             : 
     261           0 :                                 if (stcb->asoc.hb_random_idx > 3) {
     262           0 :                                         rndval = sctp_select_initial_TSN(&stcb->sctp_ep->sctp_ep);
     263           0 :                                         memcpy(stcb->asoc.hb_random_values, &rndval, sizeof(stcb->asoc.hb_random_values));
     264           0 :                                         this_random = stcb->asoc.hb_random_values[0];
     265           0 :                                         stcb->asoc.hb_random_idx++;
     266           0 :                                         stcb->asoc.hb_ect_randombit = 0;
     267             :                                 } else {
     268           0 :                                         this_random = stcb->asoc.hb_random_values[stcb->asoc.hb_random_idx];
     269           0 :                                         stcb->asoc.hb_random_idx++;
     270           0 :                                         stcb->asoc.hb_ect_randombit = 0;
     271             :                                 }
     272           0 :                                 if (this_random % 2 == 1) {
     273           0 :                                         max_cwnd_net = mnet;
     274           0 :                                         max_cwnd = mnet->cwnd; /* Useless? */
     275             :                                 }
     276             :                         }
     277             :                 }
     278           0 :                 if (max_cwnd_net == NULL) {
     279           0 :                         if (min_errors_net == NULL) {
     280           0 :                                 return (net);
     281             :                         }
     282           0 :                         return (min_errors_net);
     283             :                 } else {
     284           0 :                         return (max_cwnd_net);
     285             :                 }
     286             :         } /* JRS 5/14/07 - If mode is set to 1, use the CMT policy for choosing an alternate net. */
     287           0 :         else if (mode == 1) {
     288           0 :                 TAILQ_FOREACH(mnet, &stcb->asoc.nets, sctp_next) {
     289           0 :                         if (((mnet->dest_state & SCTP_ADDR_REACHABLE) != SCTP_ADDR_REACHABLE) ||
     290           0 :                             (mnet->dest_state & SCTP_ADDR_UNCONFIRMED)) {
     291             :                                 /*
     292             :                                  * will skip ones that are not-reachable or
     293             :                                  * unconfirmed
     294             :                                  */
     295           0 :                                 continue;
     296             :                         }
     297           0 :                         if (max_cwnd < mnet->cwnd) {
     298           0 :                                 max_cwnd_net = mnet;
     299           0 :                                 max_cwnd = mnet->cwnd;
     300           0 :                         } else if (max_cwnd == mnet->cwnd) {
     301             :                                 uint32_t rndval;
     302             :                                 uint8_t this_random;
     303             : 
     304           0 :                                 if (stcb->asoc.hb_random_idx > 3) {
     305           0 :                                         rndval = sctp_select_initial_TSN(&stcb->sctp_ep->sctp_ep);
     306           0 :                                         memcpy(stcb->asoc.hb_random_values, &rndval,
     307             :                                             sizeof(stcb->asoc.hb_random_values));
     308           0 :                                         this_random = stcb->asoc.hb_random_values[0];
     309           0 :                                         stcb->asoc.hb_random_idx = 0;
     310           0 :                                         stcb->asoc.hb_ect_randombit = 0;
     311             :                                 } else {
     312           0 :                                         this_random = stcb->asoc.hb_random_values[stcb->asoc.hb_random_idx];
     313           0 :                                         stcb->asoc.hb_random_idx++;
     314           0 :                                         stcb->asoc.hb_ect_randombit = 0;
     315             :                                 }
     316           0 :                                 if (this_random % 2) {
     317           0 :                                         max_cwnd_net = mnet;
     318           0 :                                         max_cwnd = mnet->cwnd;
     319             :                                 }
     320             :                         }
     321             :                 }
     322           0 :                 if (max_cwnd_net) {
     323           0 :                         return (max_cwnd_net);
     324             :                 }
     325             :         }
     326           0 :         mnet = net;
     327           0 :         once = 0;
     328             : 
     329           0 :         if (mnet == NULL) {
     330           0 :                 mnet = TAILQ_FIRST(&stcb->asoc.nets);
     331           0 :                 if (mnet == NULL) {
     332           0 :                         return (NULL);
     333             :                 }
     334             :         }
     335             :         for (;;) {
     336           0 :                 alt = TAILQ_NEXT(mnet, sctp_next);
     337           0 :                 if (alt == NULL) {
     338           0 :                         once++;
     339           0 :                         if (once > 1) {
     340           0 :                                 break;
     341             :                         }
     342           0 :                         alt = TAILQ_FIRST(&stcb->asoc.nets);
     343           0 :                         if (alt == NULL) {
     344           0 :                                 return (NULL);
     345             :                         }
     346             :                 }
     347           0 :                 if (alt->ro.ro_rt == NULL) {
     348           0 :                         if (alt->ro._s_addr) {
     349           0 :                                 sctp_free_ifa(alt->ro._s_addr);
     350           0 :                                 alt->ro._s_addr = NULL;
     351             :                         }
     352           0 :                         alt->src_addr_selected = 0;
     353             :                 }
     354           0 :                 if (((alt->dest_state & SCTP_ADDR_REACHABLE) == SCTP_ADDR_REACHABLE) &&
     355           0 :                     (alt->ro.ro_rt != NULL) &&
     356           0 :                     (!(alt->dest_state & SCTP_ADDR_UNCONFIRMED))) {
     357             :                         /* Found a reachable address */
     358           0 :                         break;
     359             :                 }
     360           0 :                 mnet = alt;
     361             :         }
     362             : 
     363           0 :         if (alt == NULL) {
     364             :                 /* Case where NO insv network exists (dormant state) */
     365             :                 /* we rotate destinations */
     366           0 :                 once = 0;
     367           0 :                 mnet = net;
     368             :                 for (;;) {
     369           0 :                         if (mnet == NULL) {
     370           0 :                                 return (TAILQ_FIRST(&stcb->asoc.nets));
     371             :                         }
     372           0 :                         alt = TAILQ_NEXT(mnet, sctp_next);
     373           0 :                         if (alt == NULL) {
     374           0 :                                 once++;
     375           0 :                                 if (once > 1) {
     376           0 :                                         break;
     377             :                                 }
     378           0 :                                 alt = TAILQ_FIRST(&stcb->asoc.nets);
     379           0 :                                 if (alt == NULL) {
     380           0 :                                         break;
     381             :                                 }
     382             :                         }
     383           0 :                         if ((!(alt->dest_state & SCTP_ADDR_UNCONFIRMED)) &&
     384             :                             (alt != net)) {
     385             :                                 /* Found an alternate address */
     386           0 :                                 break;
     387             :                         }
     388           0 :                         mnet = alt;
     389             :                 }
     390             :         }
     391           0 :         if (alt == NULL) {
     392           0 :                 return (net);
     393             :         }
     394           0 :         return (alt);
     395             : }
     396             : 
     397             : static void
     398           0 : sctp_backoff_on_timeout(struct sctp_tcb *stcb,
     399             :     struct sctp_nets *net,
     400             :     int win_probe,
     401             :     int num_marked, int num_abandoned)
     402             : {
     403           0 :         if (net->RTO == 0) {
     404           0 :                 net->RTO = stcb->asoc.minrto;
     405             :         }
     406           0 :         net->RTO <<= 1;
     407           0 :         if (net->RTO > stcb->asoc.maxrto) {
     408           0 :                 net->RTO = stcb->asoc.maxrto;
     409             :         }
     410           0 :         if ((win_probe == 0) && (num_marked || num_abandoned)) {
     411             :                 /* We don't apply penalty to window probe scenarios */
     412             :                 /* JRS - Use the congestion control given in the CC module */
     413           0 :                 stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout(stcb, net);
     414             :         }
     415           0 : }
     416             : 
     417             : #ifndef INVARIANTS
     418             : static void
     419           0 : sctp_recover_sent_list(struct sctp_tcb *stcb)
     420             : {
     421             :         struct sctp_tmit_chunk *chk, *nchk;
     422             :         struct sctp_association *asoc;
     423             : 
     424           0 :         asoc = &stcb->asoc;
     425           0 :         TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
     426           0 :                 if (SCTP_TSN_GE(asoc->last_acked_seq, chk->rec.data.TSN_seq)) {
     427           0 :                         SCTP_PRINTF("Found chk:%p tsn:%x <= last_acked_seq:%x\n",
     428             :                                     (void *)chk, chk->rec.data.TSN_seq, asoc->last_acked_seq);
     429           0 :                         if (chk->sent != SCTP_DATAGRAM_NR_ACKED) {
     430           0 :                                 if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
     431           0 :                                         asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
     432             :                                 }
     433             :                         }
     434           0 :                         TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
     435           0 :                         if (PR_SCTP_ENABLED(chk->flags)) {
     436           0 :                                 if (asoc->pr_sctp_cnt != 0)
     437           0 :                                         asoc->pr_sctp_cnt--;
     438             :                         }
     439           0 :                         if (chk->data) {
     440             :                                 /*sa_ignore NO_NULL_CHK*/
     441           0 :                                 sctp_free_bufspace(stcb, asoc, chk, 1);
     442           0 :                                 sctp_m_freem(chk->data);
     443           0 :                                 chk->data = NULL;
     444           0 :                                 if (asoc->prsctp_supported && PR_SCTP_BUF_ENABLED(chk->flags)) {
     445           0 :                                         asoc->sent_queue_cnt_removeable--;
     446             :                                 }
     447             :                         }
     448           0 :                         asoc->sent_queue_cnt--;
     449           0 :                         sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
     450             :                 }
     451             :         }
     452           0 :         SCTP_PRINTF("after recover order is as follows\n");
     453           0 :         TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
     454           0 :                 SCTP_PRINTF("chk:%p TSN:%x\n", (void *)chk, chk->rec.data.TSN_seq);
     455             :         }
     456           0 : }
     457             : #endif
     458             : 
     459             : static int
     460           0 : sctp_mark_all_for_resend(struct sctp_tcb *stcb,
     461             :     struct sctp_nets *net,
     462             :     struct sctp_nets *alt,
     463             :     int window_probe,
     464             :     int *num_marked,
     465             :     int *num_abandoned)
     466             : {
     467             : 
     468             :         /*
     469             :          * Mark all chunks (well not all) that were sent to *net for
     470             :          * retransmission. Move them to alt for there destination as well...
     471             :          * We only mark chunks that have been outstanding long enough to
     472             :          * have received feed-back.
     473             :          */
     474             :         struct sctp_tmit_chunk *chk, *nchk;
     475             :         struct sctp_nets *lnets;
     476             :         struct timeval now, min_wait, tv;
     477             :         int cur_rto;
     478             :         int cnt_abandoned;
     479             :         int audit_tf, num_mk, fir;
     480             :         unsigned int cnt_mk;
     481             :         uint32_t orig_flight, orig_tf;
     482             :         uint32_t tsnlast, tsnfirst;
     483           0 :         int recovery_cnt = 0;
     484             : 
     485             : 
     486             :         /* none in flight now */
     487           0 :         audit_tf = 0;
     488           0 :         fir = 0;
     489             :         /*
     490             :          * figure out how long a data chunk must be pending before we can
     491             :          * mark it ..
     492             :          */
     493           0 :         (void)SCTP_GETTIME_TIMEVAL(&now);
     494             :         /* get cur rto in micro-seconds */
     495           0 :         cur_rto = (net->lastsa >> SCTP_RTT_SHIFT) + net->lastsv;
     496           0 :         cur_rto *= 1000;
     497           0 :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
     498           0 :                 sctp_log_fr(cur_rto,
     499             :                             stcb->asoc.peers_rwnd,
     500             :                             window_probe,
     501             :                             SCTP_FR_T3_MARK_TIME);
     502           0 :                 sctp_log_fr(net->flight_size, 0, 0, SCTP_FR_CWND_REPORT);
     503           0 :                 sctp_log_fr(net->flight_size, net->cwnd, stcb->asoc.total_flight, SCTP_FR_CWND_REPORT);
     504             :         }
     505           0 :         tv.tv_sec = cur_rto / 1000000;
     506           0 :         tv.tv_usec = cur_rto % 1000000;
     507             : #ifndef __FreeBSD__
     508           0 :         timersub(&now, &tv, &min_wait);
     509             : #else
     510             :         min_wait = now;
     511             :         timevalsub(&min_wait, &tv);
     512             : #endif
     513           0 :         if (min_wait.tv_sec < 0 || min_wait.tv_usec < 0) {
     514             :                 /*
     515             :                  * if we hit here, we don't have enough seconds on the clock
     516             :                  * to account for the RTO. We just let the lower seconds be
     517             :                  * the bounds and don't worry about it. This may mean we
     518             :                  * will mark a lot more than we should.
     519             :                  */
     520           0 :                 min_wait.tv_sec = min_wait.tv_usec = 0;
     521             :         }
     522           0 :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
     523           0 :                 sctp_log_fr(cur_rto, now.tv_sec, now.tv_usec, SCTP_FR_T3_MARK_TIME);
     524           0 :                 sctp_log_fr(0, min_wait.tv_sec, min_wait.tv_usec, SCTP_FR_T3_MARK_TIME);
     525             :         }
     526             :         /*
     527             :          * Our rwnd will be incorrect here since we are not adding back the
     528             :          * cnt * mbuf but we will fix that down below.
     529             :          */
     530           0 :         orig_flight = net->flight_size;
     531           0 :         orig_tf = stcb->asoc.total_flight;
     532             : 
     533           0 :         net->fast_retran_ip = 0;
     534             :         /* Now on to each chunk */
     535           0 :         cnt_abandoned = 0;
     536           0 :         num_mk = cnt_mk = 0;
     537           0 :         tsnfirst = tsnlast = 0;
     538             : #ifndef INVARIANTS
     539             :  start_again:
     540             : #endif
     541           0 :         TAILQ_FOREACH_SAFE(chk, &stcb->asoc.sent_queue, sctp_next, nchk) {
     542           0 :                 if (SCTP_TSN_GE(stcb->asoc.last_acked_seq, chk->rec.data.TSN_seq)) {
     543             :                         /* Strange case our list got out of order? */
     544           0 :                         SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x\n",
     545             :                                     (unsigned int)stcb->asoc.last_acked_seq, (unsigned int)chk->rec.data.TSN_seq);
     546           0 :                         recovery_cnt++;
     547             : #ifdef INVARIANTS
     548             :                         panic("last acked >= chk on sent-Q");
     549             : #else
     550           0 :                         SCTP_PRINTF("Recover attempts a restart cnt:%d\n", recovery_cnt);
     551           0 :                         sctp_recover_sent_list(stcb);
     552           0 :                         if (recovery_cnt < 10) {
     553           0 :                                 goto start_again;
     554             :                         } else {
     555           0 :                                 SCTP_PRINTF("Recovery fails %d times??\n", recovery_cnt);
     556             :                         }
     557             : #endif
     558             :                 }
     559           0 :                 if ((chk->whoTo == net) && (chk->sent < SCTP_DATAGRAM_ACKED)) {
     560             :                         /*
     561             :                          * found one to mark: If it is less than
     562             :                          * DATAGRAM_ACKED it MUST not be a skipped or marked
     563             :                          * TSN but instead one that is either already set
     564             :                          * for retransmission OR one that needs
     565             :                          * retransmission.
     566             :                          */
     567             : 
     568             :                         /* validate its been outstanding long enough */
     569           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
     570           0 :                                 sctp_log_fr(chk->rec.data.TSN_seq,
     571           0 :                                             chk->sent_rcv_time.tv_sec,
     572           0 :                                             chk->sent_rcv_time.tv_usec,
     573             :                                             SCTP_FR_T3_MARK_TIME);
     574             :                         }
     575           0 :                         if ((chk->sent_rcv_time.tv_sec > min_wait.tv_sec) && (window_probe == 0)) {
     576             :                                 /*
     577             :                                  * we have reached a chunk that was sent
     578             :                                  * some seconds past our min.. forget it we
     579             :                                  * will find no more to send.
     580             :                                  */
     581           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
     582           0 :                                         sctp_log_fr(0,
     583           0 :                                                     chk->sent_rcv_time.tv_sec,
     584           0 :                                                     chk->sent_rcv_time.tv_usec,
     585             :                                                     SCTP_FR_T3_STOPPED);
     586             :                                 }
     587           0 :                                 continue;
     588           0 :                         } else if ((chk->sent_rcv_time.tv_sec == min_wait.tv_sec) &&
     589             :                                    (window_probe == 0)) {
     590             :                                 /*
     591             :                                  * we must look at the micro seconds to
     592             :                                  * know.
     593             :                                  */
     594           0 :                                 if (chk->sent_rcv_time.tv_usec >= min_wait.tv_usec) {
     595             :                                         /*
     596             :                                          * ok it was sent after our boundary
     597             :                                          * time.
     598             :                                          */
     599           0 :                                         continue;
     600             :                                 }
     601             :                         }
     602           0 :                         if (stcb->asoc.prsctp_supported && PR_SCTP_TTL_ENABLED(chk->flags)) {
     603             :                                 /* Is it expired? */
     604             : #ifndef __FreeBSD__
     605           0 :                                 if (timercmp(&now, &chk->rec.data.timetodrop, >)) {
     606             : #else
     607             :                                 if (timevalcmp(&now, &chk->rec.data.timetodrop, >)) {
     608             : #endif
     609             :                                         /* Yes so drop it */
     610           0 :                                         if (chk->data) {
     611           0 :                                                 (void)sctp_release_pr_sctp_chunk(stcb,
     612             :                                                                                  chk,
     613             :                                                                                  1,
     614             :                                                                                  SCTP_SO_NOT_LOCKED);
     615           0 :                                                 cnt_abandoned++;
     616             :                                         }
     617           0 :                                         continue;
     618             :                                 }
     619             :                         }
     620           0 :                         if (stcb->asoc.prsctp_supported && PR_SCTP_RTX_ENABLED(chk->flags)) {
     621             :                                 /* Has it been retransmitted tv_sec times? */
     622           0 :                                 if (chk->snd_count > chk->rec.data.timetodrop.tv_sec) {
     623           0 :                                         if (chk->data) {
     624           0 :                                                 (void)sctp_release_pr_sctp_chunk(stcb,
     625             :                                                                                  chk,
     626             :                                                                                  1,
     627             :                                                                                  SCTP_SO_NOT_LOCKED);
     628           0 :                                                 cnt_abandoned++;
     629             :                                         }
     630           0 :                                         continue;
     631             :                                 }
     632             :                         }
     633           0 :                         if (chk->sent < SCTP_DATAGRAM_RESEND) {
     634           0 :                                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
     635           0 :                                 num_mk++;
     636           0 :                                 if (fir == 0) {
     637           0 :                                         fir = 1;
     638           0 :                                         tsnfirst = chk->rec.data.TSN_seq;
     639             :                                 }
     640           0 :                                 tsnlast = chk->rec.data.TSN_seq;
     641           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
     642           0 :                                         sctp_log_fr(chk->rec.data.TSN_seq, chk->snd_count,
     643             :                                                     0, SCTP_FR_T3_MARKED);
     644             :                                 }
     645             : 
     646           0 :                                 if (chk->rec.data.chunk_was_revoked) {
     647             :                                         /* deflate the cwnd */
     648           0 :                                         chk->whoTo->cwnd -= chk->book_size;
     649           0 :                                         chk->rec.data.chunk_was_revoked = 0;
     650             :                                 }
     651           0 :                                 net->marked_retrans++;
     652           0 :                                 stcb->asoc.marked_retrans++;
     653           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
     654           0 :                                         sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_RSND_TO,
     655           0 :                                                        chk->whoTo->flight_size,
     656           0 :                                                        chk->book_size,
     657           0 :                                                        (uintptr_t)chk->whoTo,
     658             :                                                        chk->rec.data.TSN_seq);
     659             :                                 }
     660           0 :                                 sctp_flight_size_decrease(chk);
     661           0 :                                 sctp_total_flight_decrease(stcb, chk);
     662           0 :                                 stcb->asoc.peers_rwnd += chk->send_size;
     663           0 :                                 stcb->asoc.peers_rwnd += SCTP_BASE_SYSCTL(sctp_peer_chunk_oh);
     664             :                         }
     665           0 :                         chk->sent = SCTP_DATAGRAM_RESEND;
     666           0 :                         SCTP_STAT_INCR(sctps_markedretrans);
     667             : 
     668             :                         /* reset the TSN for striking and other FR stuff */
     669           0 :                         chk->rec.data.doing_fast_retransmit = 0;
     670             :                         /* Clear any time so NO RTT is being done */
     671             : 
     672           0 :                         if (chk->do_rtt) {
     673           0 :                                 if (chk->whoTo->rto_needed == 0) {
     674           0 :                                         chk->whoTo->rto_needed = 1;
     675             :                                 }
     676             :                         }
     677           0 :                         chk->do_rtt = 0;
     678           0 :                         if (alt != net) {
     679           0 :                                 sctp_free_remote_addr(chk->whoTo);
     680           0 :                                 chk->no_fr_allowed = 1;
     681           0 :                                 chk->whoTo = alt;
     682           0 :                                 atomic_add_int(&alt->ref_count, 1);
     683             :                         } else {
     684           0 :                                 chk->no_fr_allowed = 0;
     685           0 :                                 if (TAILQ_EMPTY(&stcb->asoc.send_queue)) {
     686           0 :                                         chk->rec.data.fast_retran_tsn = stcb->asoc.sending_seq;
     687             :                                 } else {
     688           0 :                                         chk->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.TSN_seq;
     689             :                                 }
     690             :                         }
     691             :                         /* CMT: Do not allow FRs on retransmitted TSNs.
     692             :                          */
     693           0 :                         if (stcb->asoc.sctp_cmt_on_off > 0) {
     694           0 :                                 chk->no_fr_allowed = 1;
     695             :                         }
     696             : #ifdef THIS_SHOULD_NOT_BE_DONE
     697             :                 } else if (chk->sent == SCTP_DATAGRAM_ACKED) {
     698             :                         /* remember highest acked one */
     699             :                         could_be_sent = chk;
     700             : #endif
     701             :                 }
     702           0 :                 if (chk->sent == SCTP_DATAGRAM_RESEND) {
     703           0 :                         cnt_mk++;
     704             :                 }
     705             :         }
     706           0 :         if ((orig_flight - net->flight_size) != (orig_tf - stcb->asoc.total_flight)) {
     707             :                 /* we did not subtract the same things? */
     708           0 :                 audit_tf = 1;
     709             :         }
     710             : 
     711           0 :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
     712           0 :                 sctp_log_fr(tsnfirst, tsnlast, num_mk, SCTP_FR_T3_TIMEOUT);
     713             :         }
     714             : #ifdef SCTP_DEBUG
     715           0 :         if (num_mk) {
     716           0 :                 SCTPDBG(SCTP_DEBUG_TIMER1, "LAST TSN marked was %x\n",
     717             :                         tsnlast);
     718           0 :                 SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%ld\n",
     719             :                         num_mk, (u_long)stcb->asoc.peers_rwnd);
     720           0 :                 SCTPDBG(SCTP_DEBUG_TIMER1, "LAST TSN marked was %x\n",
     721             :                         tsnlast);
     722           0 :                 SCTPDBG(SCTP_DEBUG_TIMER1, "Num marked for retransmission was %d peer-rwd:%d\n",
     723             :                         num_mk,
     724             :                         (int)stcb->asoc.peers_rwnd);
     725             :         }
     726             : #endif
     727           0 :         *num_marked = num_mk;
     728           0 :         *num_abandoned = cnt_abandoned;
     729             :         /* Now check for a ECN Echo that may be stranded And
     730             :          * include the cnt_mk'd to have all resends in the
     731             :          * control queue.
     732             :          */
     733           0 :         TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
     734           0 :                 if (chk->sent == SCTP_DATAGRAM_RESEND) {
     735           0 :                         cnt_mk++;
     736             :                 }
     737           0 :                 if ((chk->whoTo == net) &&
     738           0 :                     (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) {
     739           0 :                         sctp_free_remote_addr(chk->whoTo);
     740           0 :                         chk->whoTo = alt;
     741           0 :                         if (chk->sent != SCTP_DATAGRAM_RESEND) {
     742           0 :                                 chk->sent = SCTP_DATAGRAM_RESEND;
     743           0 :                                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
     744           0 :                                 cnt_mk++;
     745             :                         }
     746           0 :                         atomic_add_int(&alt->ref_count, 1);
     747             :                 }
     748             :         }
     749             : #ifdef THIS_SHOULD_NOT_BE_DONE
     750             :         if ((stcb->asoc.sent_queue_retran_cnt == 0) && (could_be_sent)) {
     751             :                 /* fix it so we retransmit the highest acked anyway */
     752             :                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
     753             :                 cnt_mk++;
     754             :                 could_be_sent->sent = SCTP_DATAGRAM_RESEND;
     755             :         }
     756             : #endif
     757           0 :         if (stcb->asoc.sent_queue_retran_cnt != cnt_mk) {
     758             : #ifdef INVARIANTS
     759             :                 SCTP_PRINTF("Local Audit says there are %d for retran asoc cnt:%d we marked:%d this time\n",
     760             :                             cnt_mk, stcb->asoc.sent_queue_retran_cnt, num_mk);
     761             : #endif
     762             : #ifndef SCTP_AUDITING_ENABLED
     763           0 :                 stcb->asoc.sent_queue_retran_cnt = cnt_mk;
     764             : #endif
     765             :         }
     766           0 :         if (audit_tf) {
     767           0 :                 SCTPDBG(SCTP_DEBUG_TIMER4,
     768             :                         "Audit total flight due to negative value net:%p\n",
     769             :                         (void *)net);
     770           0 :                 stcb->asoc.total_flight = 0;
     771           0 :                 stcb->asoc.total_flight_count = 0;
     772             :                 /* Clear all networks flight size */
     773           0 :                 TAILQ_FOREACH(lnets, &stcb->asoc.nets, sctp_next) {
     774           0 :                         lnets->flight_size = 0;
     775           0 :                         SCTPDBG(SCTP_DEBUG_TIMER4,
     776             :                                 "Net:%p c-f cwnd:%d ssthresh:%d\n",
     777             :                                 (void *)lnets, lnets->cwnd, lnets->ssthresh);
     778             :                 }
     779           0 :                 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
     780           0 :                         if (chk->sent < SCTP_DATAGRAM_RESEND) {
     781           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
     782           0 :                                         sctp_misc_ints(SCTP_FLIGHT_LOG_UP,
     783           0 :                                                        chk->whoTo->flight_size,
     784           0 :                                                        chk->book_size,
     785           0 :                                                        (uintptr_t)chk->whoTo,
     786             :                                                        chk->rec.data.TSN_seq);
     787             :                                 }
     788             : 
     789           0 :                                 sctp_flight_size_increase(chk);
     790           0 :                                 sctp_total_flight_increase(stcb, chk);
     791             :                         }
     792             :                 }
     793             :         }
     794             :         /* We return 1 if we only have a window probe outstanding */
     795           0 :         return (0);
     796             : }
     797             : 
     798             : 
     799             : int
     800           0 : sctp_t3rxt_timer(struct sctp_inpcb *inp,
     801             :     struct sctp_tcb *stcb,
     802             :     struct sctp_nets *net)
     803             : {
     804             :         struct sctp_nets *alt;
     805             :         int win_probe, num_mk, num_abandoned;
     806             : 
     807           0 :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FR_LOGGING_ENABLE) {
     808           0 :                 sctp_log_fr(0, 0, 0, SCTP_FR_T3_TIMEOUT);
     809             :         }
     810           0 :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
     811             :                 struct sctp_nets *lnet;
     812             : 
     813           0 :                 TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
     814           0 :                         if (net == lnet) {
     815           0 :                                 sctp_log_cwnd(stcb, lnet, 1, SCTP_CWND_LOG_FROM_T3);
     816             :                         } else {
     817           0 :                                 sctp_log_cwnd(stcb, lnet, 0, SCTP_CWND_LOG_FROM_T3);
     818             :                         }
     819             :                 }
     820             :         }
     821             :         /* Find an alternate and mark those for retransmission */
     822           0 :         if ((stcb->asoc.peers_rwnd == 0) &&
     823           0 :             (stcb->asoc.total_flight < net->mtu)) {
     824           0 :                 SCTP_STAT_INCR(sctps_timowindowprobe);
     825           0 :                 win_probe = 1;
     826             :         } else {
     827           0 :                 win_probe = 0;
     828             :         }
     829             : 
     830           0 :         if (win_probe == 0) {
     831             :                 /* We don't do normal threshold management on window probes */
     832           0 :                 if (sctp_threshold_management(inp, stcb, net,
     833           0 :                     stcb->asoc.max_send_times)) {
     834             :                         /* Association was destroyed */
     835           0 :                         return (1);
     836             :                 } else {
     837           0 :                         if (net != stcb->asoc.primary_destination) {
     838             :                                 /* send a immediate HB if our RTO is stale */
     839             :                                 struct timeval now;
     840             :                                 unsigned int ms_goneby;
     841             : 
     842           0 :                                 (void)SCTP_GETTIME_TIMEVAL(&now);
     843           0 :                                 if (net->last_sent_time.tv_sec) {
     844           0 :                                         ms_goneby = (now.tv_sec - net->last_sent_time.tv_sec) * 1000;
     845             :                                 } else {
     846           0 :                                         ms_goneby = 0;
     847             :                                 }
     848           0 :                                 if ((net->dest_state & SCTP_ADDR_PF) == 0) {
     849           0 :                                         if ((ms_goneby > net->RTO) || (net->RTO == 0)) {
     850             :                                                 /*
     851             :                                                  * no recent feed back in an RTO or
     852             :                                                  * more, request a RTT update
     853             :                                                  */
     854           0 :                                                 sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
     855             :                                         }
     856             :                                 }
     857             :                         }
     858             :                 }
     859             :         } else {
     860             :                 /*
     861             :                  * For a window probe we don't penalize the net's but only
     862             :                  * the association. This may fail it if SACKs are not coming
     863             :                  * back. If sack's are coming with rwnd locked at 0, we will
     864             :                  * continue to hold things waiting for rwnd to raise
     865             :                  */
     866           0 :                 if (sctp_threshold_management(inp, stcb, NULL,
     867           0 :                     stcb->asoc.max_send_times)) {
     868             :                         /* Association was destroyed */
     869           0 :                         return (1);
     870             :                 }
     871             :         }
     872           0 :         if (stcb->asoc.sctp_cmt_on_off > 0) {
     873           0 :                 if (net->pf_threshold < net->failure_threshold) {
     874           0 :                         alt = sctp_find_alternate_net(stcb, net, 2);
     875             :                 } else {
     876             :                         /*
     877             :                          * CMT: Using RTX_SSTHRESH policy for CMT.
     878             :                          * If CMT is being used, then pick dest with
     879             :                          * largest ssthresh for any retransmission.
     880             :                          */
     881           0 :                         alt = sctp_find_alternate_net(stcb, net, 1);
     882             :                         /*
     883             :                          * CUCv2: If a different dest is picked for
     884             :                          * the retransmission, then new
     885             :                          * (rtx-)pseudo_cumack needs to be tracked
     886             :                          * for orig dest. Let CUCv2 track new (rtx-)
     887             :                          * pseudo-cumack always.
     888             :                          */
     889           0 :                         net->find_pseudo_cumack = 1;
     890           0 :                         net->find_rtx_pseudo_cumack = 1;
     891             :                 }
     892             :         } else {
     893           0 :                 alt = sctp_find_alternate_net(stcb, net, 0);
     894             :         }
     895             : 
     896           0 :         num_mk = 0;
     897           0 :         num_abandoned = 0;
     898           0 :         (void)sctp_mark_all_for_resend(stcb, net, alt, win_probe,
     899             :                                       &num_mk, &num_abandoned);
     900             :         /* FR Loss recovery just ended with the T3. */
     901           0 :         stcb->asoc.fast_retran_loss_recovery = 0;
     902             : 
     903             :         /* CMT FR loss recovery ended with the T3 */
     904           0 :         net->fast_retran_loss_recovery = 0;
     905           0 :         if ((stcb->asoc.cc_functions.sctp_cwnd_new_transmission_begins) &&
     906           0 :             (net->flight_size == 0)) {
     907           0 :                 (*stcb->asoc.cc_functions.sctp_cwnd_new_transmission_begins)(stcb, net);
     908             :         }
     909             : 
     910             :         /*
     911             :          * setup the sat loss recovery that prevents satellite cwnd advance.
     912             :          */
     913           0 :         stcb->asoc.sat_t3_loss_recovery = 1;
     914           0 :         stcb->asoc.sat_t3_recovery_tsn = stcb->asoc.sending_seq;
     915             : 
     916             :         /* Backoff the timer and cwnd */
     917           0 :         sctp_backoff_on_timeout(stcb, net, win_probe, num_mk, num_abandoned);
     918           0 :         if ((!(net->dest_state & SCTP_ADDR_REACHABLE)) ||
     919           0 :             (net->dest_state & SCTP_ADDR_PF)) {
     920             :                 /* Move all pending over too */
     921           0 :                 sctp_move_chunks_from_net(stcb, net);
     922             : 
     923             :                 /* Get the address that failed, to
     924             :                  * force a new src address selecton and
     925             :                  * a route allocation.
     926             :                  */
     927           0 :                 if (net->ro._s_addr) {
     928           0 :                         sctp_free_ifa(net->ro._s_addr);
     929           0 :                         net->ro._s_addr = NULL;
     930             :                 }
     931           0 :                 net->src_addr_selected = 0;
     932             : 
     933             :                 /* Force a route allocation too */
     934           0 :                 if (net->ro.ro_rt) {
     935           0 :                         RTFREE(net->ro.ro_rt);
     936           0 :                         net->ro.ro_rt = NULL;
     937             :                 }
     938             : 
     939             :                 /* Was it our primary? */
     940           0 :                 if ((stcb->asoc.primary_destination == net) && (alt != net)) {
     941             :                         /*
     942             :                          * Yes, note it as such and find an alternate note:
     943             :                          * this means HB code must use this to resent the
     944             :                          * primary if it goes active AND if someone does a
     945             :                          * change-primary then this flag must be cleared
     946             :                          * from any net structures.
     947             :                          */
     948           0 :                         if (stcb->asoc.alternate) {
     949           0 :                                 sctp_free_remote_addr(stcb->asoc.alternate);
     950             :                         }
     951           0 :                         stcb->asoc.alternate = alt;
     952           0 :                         atomic_add_int(&stcb->asoc.alternate->ref_count, 1);
     953             :                 }
     954             :         }
     955             :         /*
     956             :          * Special case for cookie-echo'ed case, we don't do output but must
     957             :          * await the COOKIE-ACK before retransmission
     958             :          */
     959           0 :         if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
     960             :                 /*
     961             :                  * Here we just reset the timer and start again since we
     962             :                  * have not established the asoc
     963             :                  */
     964           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
     965           0 :                 return (0);
     966             :         }
     967           0 :         if (stcb->asoc.prsctp_supported) {
     968             :                 struct sctp_tmit_chunk *lchk;
     969             : 
     970           0 :                 lchk = sctp_try_advance_peer_ack_point(stcb, &stcb->asoc);
     971             :                 /* C3. See if we need to send a Fwd-TSN */
     972           0 :                 if (SCTP_TSN_GT(stcb->asoc.advanced_peer_ack_point, stcb->asoc.last_acked_seq)) {
     973           0 :                         send_forward_tsn(stcb, &stcb->asoc);
     974           0 :                         if (lchk) {
     975             :                                 /* Assure a timer is up */
     976           0 :                                 sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, lchk->whoTo);
     977             :                         }
     978             :                 }
     979             :         }
     980           0 :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
     981           0 :                 sctp_log_cwnd(stcb, net, net->cwnd, SCTP_CWND_LOG_FROM_RTX);
     982             :         }
     983           0 :         return (0);
     984             : }
     985             : 
     986             : int
     987           0 : sctp_t1init_timer(struct sctp_inpcb *inp,
     988             :     struct sctp_tcb *stcb,
     989             :     struct sctp_nets *net)
     990             : {
     991             :         /* bump the thresholds */
     992           0 :         if (stcb->asoc.delayed_connection) {
     993             :                 /*
     994             :                  * special hook for delayed connection. The library did NOT
     995             :                  * complete the rest of its sends.
     996             :                  */
     997           0 :                 stcb->asoc.delayed_connection = 0;
     998           0 :                 sctp_send_initiate(inp, stcb, SCTP_SO_NOT_LOCKED);
     999           0 :                 return (0);
    1000             :         }
    1001           0 :         if (SCTP_GET_STATE((&stcb->asoc)) != SCTP_STATE_COOKIE_WAIT) {
    1002           0 :                 return (0);
    1003             :         }
    1004           0 :         if (sctp_threshold_management(inp, stcb, net,
    1005           0 :             stcb->asoc.max_init_times)) {
    1006             :                 /* Association was destroyed */
    1007           0 :                 return (1);
    1008             :         }
    1009           0 :         stcb->asoc.dropped_special_cnt = 0;
    1010           0 :         sctp_backoff_on_timeout(stcb, stcb->asoc.primary_destination, 1, 0, 0);
    1011           0 :         if (stcb->asoc.initial_init_rto_max < net->RTO) {
    1012           0 :                 net->RTO = stcb->asoc.initial_init_rto_max;
    1013             :         }
    1014           0 :         if (stcb->asoc.numnets > 1) {
    1015             :                 /* If we have more than one addr use it */
    1016             :                 struct sctp_nets *alt;
    1017             : 
    1018           0 :                 alt = sctp_find_alternate_net(stcb, stcb->asoc.primary_destination, 0);
    1019           0 :                 if (alt != stcb->asoc.primary_destination) {
    1020           0 :                         sctp_move_chunks_from_net(stcb, stcb->asoc.primary_destination);
    1021           0 :                         stcb->asoc.primary_destination = alt;
    1022             :                 }
    1023             :         }
    1024             :         /* Send out a new init */
    1025           0 :         sctp_send_initiate(inp, stcb, SCTP_SO_NOT_LOCKED);
    1026           0 :         return (0);
    1027             : }
    1028             : 
    1029             : /*
    1030             :  * For cookie and asconf we actually need to find and mark for resend, then
    1031             :  * increment the resend counter (after all the threshold management stuff of
    1032             :  * course).
    1033             :  */
    1034             : int
    1035           0 : sctp_cookie_timer(struct sctp_inpcb *inp,
    1036             :     struct sctp_tcb *stcb,
    1037             :     struct sctp_nets *net SCTP_UNUSED)
    1038             : {
    1039             :         struct sctp_nets *alt;
    1040             :         struct sctp_tmit_chunk *cookie;
    1041             : 
    1042             :         /* first before all else we must find the cookie */
    1043           0 :         TAILQ_FOREACH(cookie, &stcb->asoc.control_send_queue, sctp_next) {
    1044           0 :                 if (cookie->rec.chunk_id.id == SCTP_COOKIE_ECHO) {
    1045           0 :                         break;
    1046             :                 }
    1047             :         }
    1048           0 :         if (cookie == NULL) {
    1049           0 :                 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
    1050             :                         /* FOOBAR! */
    1051             :                         struct mbuf *op_err;
    1052             : 
    1053           0 :                         op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION,
    1054             :                                                      "Cookie timer expired, but no cookie");
    1055           0 :                         inp->last_abort_code = SCTP_FROM_SCTP_TIMER+SCTP_LOC_4;
    1056           0 :                         sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
    1057             :                 } else {
    1058             : #ifdef INVARIANTS
    1059             :                         panic("Cookie timer expires in wrong state?");
    1060             : #else
    1061           0 :                         SCTP_PRINTF("Strange in state %d not cookie-echoed yet c-e timer expires?\n", SCTP_GET_STATE(&stcb->asoc));
    1062           0 :                         return (0);
    1063             : #endif
    1064             :                 }
    1065           0 :                 return (0);
    1066             :         }
    1067             :         /* Ok we found the cookie, threshold management next */
    1068           0 :         if (sctp_threshold_management(inp, stcb, cookie->whoTo,
    1069           0 :             stcb->asoc.max_init_times)) {
    1070             :                 /* Assoc is over */
    1071           0 :                 return (1);
    1072             :         }
    1073             :         /*
    1074             :          * cleared theshold management now lets backoff the address & select
    1075             :          * an alternate
    1076             :          */
    1077           0 :         stcb->asoc.dropped_special_cnt = 0;
    1078           0 :         sctp_backoff_on_timeout(stcb, cookie->whoTo, 1, 0, 0);
    1079           0 :         alt = sctp_find_alternate_net(stcb, cookie->whoTo, 0);
    1080           0 :         if (alt != cookie->whoTo) {
    1081           0 :                 sctp_free_remote_addr(cookie->whoTo);
    1082           0 :                 cookie->whoTo = alt;
    1083           0 :                 atomic_add_int(&alt->ref_count, 1);
    1084             :         }
    1085             :         /* Now mark the retran info */
    1086           0 :         if (cookie->sent != SCTP_DATAGRAM_RESEND) {
    1087           0 :                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
    1088             :         }
    1089           0 :         cookie->sent = SCTP_DATAGRAM_RESEND;
    1090             :         /*
    1091             :          * Now call the output routine to kick out the cookie again, Note we
    1092             :          * don't mark any chunks for retran so that FR will need to kick in
    1093             :          * to move these (or a send timer).
    1094             :          */
    1095           0 :         return (0);
    1096             : }
    1097             : 
    1098             : int
    1099           0 : sctp_strreset_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
    1100             :     struct sctp_nets *net)
    1101             : {
    1102             :         struct sctp_nets *alt;
    1103           0 :         struct sctp_tmit_chunk *strrst = NULL, *chk = NULL;
    1104             : 
    1105           0 :         if (stcb->asoc.stream_reset_outstanding == 0) {
    1106           0 :                 return (0);
    1107             :         }
    1108             :         /* find the existing STRRESET, we use the seq number we sent out on */
    1109           0 :         (void)sctp_find_stream_reset(stcb, stcb->asoc.str_reset_seq_out, &strrst);
    1110           0 :         if (strrst == NULL) {
    1111           0 :                 return (0);
    1112             :         }
    1113             :         /* do threshold management */
    1114           0 :         if (sctp_threshold_management(inp, stcb, strrst->whoTo,
    1115           0 :             stcb->asoc.max_send_times)) {
    1116             :                 /* Assoc is over */
    1117           0 :                 return (1);
    1118             :         }
    1119             :         /*
    1120             :          * cleared theshold management now lets backoff the address & select
    1121             :          * an alternate
    1122             :          */
    1123           0 :         sctp_backoff_on_timeout(stcb, strrst->whoTo, 1, 0, 0);
    1124           0 :         alt = sctp_find_alternate_net(stcb, strrst->whoTo, 0);
    1125           0 :         sctp_free_remote_addr(strrst->whoTo);
    1126           0 :         strrst->whoTo = alt;
    1127           0 :         atomic_add_int(&alt->ref_count, 1);
    1128             : 
    1129             :         /* See if a ECN Echo is also stranded */
    1130           0 :         TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
    1131           0 :                 if ((chk->whoTo == net) &&
    1132           0 :                     (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) {
    1133           0 :                         sctp_free_remote_addr(chk->whoTo);
    1134           0 :                         if (chk->sent != SCTP_DATAGRAM_RESEND) {
    1135           0 :                                 chk->sent = SCTP_DATAGRAM_RESEND;
    1136           0 :                                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
    1137             :                         }
    1138           0 :                         chk->whoTo = alt;
    1139           0 :                         atomic_add_int(&alt->ref_count, 1);
    1140             :                 }
    1141             :         }
    1142           0 :         if (!(net->dest_state & SCTP_ADDR_REACHABLE)) {
    1143             :                 /*
    1144             :                  * If the address went un-reachable, we need to move to
    1145             :                  * alternates for ALL chk's in queue
    1146             :                  */
    1147           0 :                 sctp_move_chunks_from_net(stcb, net);
    1148             :         }
    1149             :         /* mark the retran info */
    1150           0 :         if (strrst->sent != SCTP_DATAGRAM_RESEND)
    1151           0 :                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
    1152           0 :         strrst->sent = SCTP_DATAGRAM_RESEND;
    1153             : 
    1154             :         /* restart the timer */
    1155           0 :         sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, inp, stcb, strrst->whoTo);
    1156           0 :         return (0);
    1157             : }
    1158             : 
    1159             : int
    1160           0 : sctp_asconf_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
    1161             :                   struct sctp_nets *net)
    1162             : {
    1163             :         struct sctp_nets *alt;
    1164             :         struct sctp_tmit_chunk *asconf, *chk;
    1165             : 
    1166             :         /* is this a first send, or a retransmission? */
    1167           0 :         if (TAILQ_EMPTY(&stcb->asoc.asconf_send_queue)) {
    1168             :                 /* compose a new ASCONF chunk and send it */
    1169           0 :                 sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);
    1170             :         } else {
    1171             :                 /*
    1172             :                  * Retransmission of the existing ASCONF is needed
    1173             :                  */
    1174             : 
    1175             :                 /* find the existing ASCONF */
    1176           0 :                 asconf = TAILQ_FIRST(&stcb->asoc.asconf_send_queue);
    1177           0 :                 if (asconf == NULL) {
    1178           0 :                         return (0);
    1179             :                 }
    1180             :                 /* do threshold management */
    1181           0 :                 if (sctp_threshold_management(inp, stcb, asconf->whoTo,
    1182           0 :                     stcb->asoc.max_send_times)) {
    1183             :                         /* Assoc is over */
    1184           0 :                         return (1);
    1185             :                 }
    1186           0 :                 if (asconf->snd_count > stcb->asoc.max_send_times) {
    1187             :                         /*
    1188             :                          * Something is rotten: our peer is not responding to
    1189             :                          * ASCONFs but apparently is to other chunks.  i.e. it
    1190             :                          * is not properly handling the chunk type upper bits.
    1191             :                          * Mark this peer as ASCONF incapable and cleanup.
    1192             :                          */
    1193           0 :                         SCTPDBG(SCTP_DEBUG_TIMER1, "asconf_timer: Peer has not responded to our repeated ASCONFs\n");
    1194           0 :                         sctp_asconf_cleanup(stcb, net);
    1195           0 :                         return (0);
    1196             :                 }
    1197             :                 /*
    1198             :                  * cleared threshold management, so now backoff the net and
    1199             :                  * select an alternate
    1200             :                  */
    1201           0 :                 sctp_backoff_on_timeout(stcb, asconf->whoTo, 1, 0, 0);
    1202           0 :                 alt = sctp_find_alternate_net(stcb, asconf->whoTo, 0);
    1203           0 :                 if (asconf->whoTo != alt) {
    1204           0 :                         sctp_free_remote_addr(asconf->whoTo);
    1205           0 :                         asconf->whoTo = alt;
    1206           0 :                         atomic_add_int(&alt->ref_count, 1);
    1207             :                 }
    1208             : 
    1209             :                 /* See if an ECN Echo is also stranded */
    1210           0 :                 TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
    1211           0 :                         if ((chk->whoTo == net) &&
    1212           0 :                             (chk->rec.chunk_id.id == SCTP_ECN_ECHO)) {
    1213           0 :                                 sctp_free_remote_addr(chk->whoTo);
    1214           0 :                                 chk->whoTo = alt;
    1215           0 :                                 if (chk->sent != SCTP_DATAGRAM_RESEND) {
    1216           0 :                                         chk->sent = SCTP_DATAGRAM_RESEND;
    1217           0 :                                         sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
    1218             :                                 }
    1219           0 :                                 atomic_add_int(&alt->ref_count, 1);
    1220             :                         }
    1221             :                 }
    1222           0 :                 TAILQ_FOREACH(chk, &stcb->asoc.asconf_send_queue, sctp_next) {
    1223           0 :                         if (chk->whoTo != alt) {
    1224           0 :                                 sctp_free_remote_addr(chk->whoTo);
    1225           0 :                                 chk->whoTo = alt;
    1226           0 :                                 atomic_add_int(&alt->ref_count, 1);
    1227             :                         }
    1228           0 :                         if (asconf->sent != SCTP_DATAGRAM_RESEND && chk->sent != SCTP_DATAGRAM_UNSENT)
    1229           0 :                                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
    1230           0 :                         chk->sent = SCTP_DATAGRAM_RESEND;
    1231             :                 }
    1232           0 :                 if (!(net->dest_state & SCTP_ADDR_REACHABLE)) {
    1233             :                         /*
    1234             :                          * If the address went un-reachable, we need to move
    1235             :                          * to the alternate for ALL chunks in queue
    1236             :                          */
    1237           0 :                         sctp_move_chunks_from_net(stcb, net);
    1238             :                 }
    1239             :                 /* mark the retran info */
    1240           0 :                 if (asconf->sent != SCTP_DATAGRAM_RESEND)
    1241           0 :                         sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
    1242           0 :                 asconf->sent = SCTP_DATAGRAM_RESEND;
    1243             : 
    1244             :                 /* send another ASCONF if any and we can do */
    1245           0 :                 sctp_send_asconf(stcb, alt, SCTP_ADDR_NOT_LOCKED);
    1246             :         }
    1247           0 :         return (0);
    1248             : }
    1249             : 
    1250             : /* Mobility adaptation */
    1251             : void
    1252           0 : sctp_delete_prim_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
    1253             :                        struct sctp_nets *net SCTP_UNUSED)
    1254             : {
    1255           0 :         if (stcb->asoc.deleted_primary == NULL) {
    1256           0 :                 SCTPDBG(SCTP_DEBUG_ASCONF1, "delete_prim_timer: deleted_primary is not stored...\n");
    1257           0 :                 sctp_mobility_feature_off(inp, SCTP_MOBILITY_PRIM_DELETED);
    1258           0 :                 return;
    1259             :         }
    1260           0 :         SCTPDBG(SCTP_DEBUG_ASCONF1, "delete_prim_timer: finished to keep deleted primary ");
    1261           0 :         SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.deleted_primary->ro._l_addr.sa);
    1262           0 :         sctp_free_remote_addr(stcb->asoc.deleted_primary);
    1263           0 :         stcb->asoc.deleted_primary = NULL;
    1264           0 :         sctp_mobility_feature_off(inp, SCTP_MOBILITY_PRIM_DELETED);
    1265           0 :         return;
    1266             : }
    1267             : 
    1268             : /*
    1269             :  * For the shutdown and shutdown-ack, we do not keep one around on the
    1270             :  * control queue. This means we must generate a new one and call the general
    1271             :  * chunk output routine, AFTER having done threshold management.
    1272             :  * It is assumed that net is non-NULL.
    1273             :  */
    1274             : int
    1275           0 : sctp_shutdown_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
    1276             :     struct sctp_nets *net)
    1277             : {
    1278             :         struct sctp_nets *alt;
    1279             : 
    1280             :         /* first threshold managment */
    1281           0 :         if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
    1282             :                 /* Assoc is over */
    1283           0 :                 return (1);
    1284             :         }
    1285           0 :         sctp_backoff_on_timeout(stcb, net, 1, 0, 0);
    1286             :         /* second select an alternative */
    1287           0 :         alt = sctp_find_alternate_net(stcb, net, 0);
    1288             : 
    1289             :         /* third generate a shutdown into the queue for out net */
    1290           0 :         sctp_send_shutdown(stcb, alt);
    1291             : 
    1292             :         /* fourth restart timer */
    1293           0 :         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, inp, stcb, alt);
    1294           0 :         return (0);
    1295             : }
    1296             : 
    1297             : int
    1298           0 : sctp_shutdownack_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
    1299             :     struct sctp_nets *net)
    1300             : {
    1301             :         struct sctp_nets *alt;
    1302             : 
    1303             :         /* first threshold managment */
    1304           0 :         if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
    1305             :                 /* Assoc is over */
    1306           0 :                 return (1);
    1307             :         }
    1308           0 :         sctp_backoff_on_timeout(stcb, net, 1, 0, 0);
    1309             :         /* second select an alternative */
    1310           0 :         alt = sctp_find_alternate_net(stcb, net, 0);
    1311             : 
    1312             :         /* third generate a shutdown into the queue for out net */
    1313           0 :         sctp_send_shutdown_ack(stcb, alt);
    1314             : 
    1315             :         /* fourth restart timer */
    1316           0 :         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK, inp, stcb, alt);
    1317           0 :         return (0);
    1318             : }
    1319             : 
    1320             : static void
    1321           0 : sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp,
    1322             :     struct sctp_tcb *stcb)
    1323             : {
    1324             :         struct sctp_stream_queue_pending *sp;
    1325           0 :         unsigned int i, chks_in_queue = 0;
    1326           0 :         int being_filled = 0;
    1327             :         /*
    1328             :          * This function is ONLY called when the send/sent queues are empty.
    1329             :          */
    1330           0 :         if ((stcb == NULL) || (inp == NULL))
    1331           0 :                 return;
    1332             : 
    1333           0 :         if (stcb->asoc.sent_queue_retran_cnt) {
    1334           0 :                 SCTP_PRINTF("Hmm, sent_queue_retran_cnt is non-zero %d\n",
    1335             :                             stcb->asoc.sent_queue_retran_cnt);
    1336           0 :                 stcb->asoc.sent_queue_retran_cnt = 0;
    1337             :         }
    1338           0 :         if (stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, &stcb->asoc)) {
    1339             :                 /* No stream scheduler information, initialize scheduler */
    1340           0 :                 stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc, 0);
    1341           0 :                 if (!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, &stcb->asoc)) {
    1342             :                         /* yep, we lost a stream or two */
    1343           0 :                         SCTP_PRINTF("Found additional streams NOT managed by scheduler, corrected\n");
    1344             :                 } else {
    1345             :                         /* no streams lost */
    1346           0 :                         stcb->asoc.total_output_queue_size = 0;
    1347             :                 }
    1348             :         }
    1349             :         /* Check to see if some data queued, if so report it */
    1350           0 :         for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
    1351           0 :                 if (!TAILQ_EMPTY(&stcb->asoc.strmout[i].outqueue)) {
    1352           0 :                         TAILQ_FOREACH(sp, &stcb->asoc.strmout[i].outqueue, next) {
    1353           0 :                                 if (sp->msg_is_complete)
    1354           0 :                                         being_filled++;
    1355           0 :                                 chks_in_queue++;
    1356             :                         }
    1357             :                 }
    1358             :         }
    1359           0 :         if (chks_in_queue != stcb->asoc.stream_queue_cnt) {
    1360           0 :                 SCTP_PRINTF("Hmm, stream queue cnt at %d I counted %d in stream out wheel\n",
    1361             :                             stcb->asoc.stream_queue_cnt, chks_in_queue);
    1362             :         }
    1363           0 :         if (chks_in_queue) {
    1364             :                 /* call the output queue function */
    1365           0 :                 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
    1366           0 :                 if ((TAILQ_EMPTY(&stcb->asoc.send_queue)) &&
    1367           0 :                     (TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
    1368             :                         /*
    1369             :                          * Probably should go in and make it go back through
    1370             :                          * and add fragments allowed
    1371             :                          */
    1372           0 :                         if (being_filled == 0) {
    1373           0 :                                 SCTP_PRINTF("Still nothing moved %d chunks are stuck\n",
    1374             :                                             chks_in_queue);
    1375             :                         }
    1376             :                 }
    1377             :         } else {
    1378           0 :                 SCTP_PRINTF("Found no chunks on any queue tot:%lu\n",
    1379             :                             (u_long)stcb->asoc.total_output_queue_size);
    1380           0 :                 stcb->asoc.total_output_queue_size = 0;
    1381             :         }
    1382             : }
    1383             : 
    1384             : int
    1385           0 : sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
    1386             :     struct sctp_nets *net)
    1387             : {
    1388             :         uint8_t net_was_pf;
    1389             : 
    1390           0 :         if (net->dest_state & SCTP_ADDR_PF) {
    1391           0 :                 net_was_pf = 1;
    1392             :         } else {
    1393           0 :                 net_was_pf = 0;
    1394             :         }
    1395           0 :         if (net->hb_responded == 0) {
    1396           0 :                 if (net->ro._s_addr) {
    1397             :                         /* Invalidate the src address if we did not get
    1398             :                          * a response last time.
    1399             :                          */
    1400           0 :                         sctp_free_ifa(net->ro._s_addr);
    1401           0 :                         net->ro._s_addr = NULL;
    1402           0 :                         net->src_addr_selected = 0;
    1403             :                 }
    1404           0 :                 sctp_backoff_on_timeout(stcb, net, 1, 0, 0);
    1405           0 :                 if (sctp_threshold_management(inp, stcb, net, stcb->asoc.max_send_times)) {
    1406             :                         /* Assoc is over */
    1407           0 :                         return (1);
    1408             :                 }
    1409             :         }
    1410             :         /* Zero PBA, if it needs it */
    1411           0 :         if (net->partial_bytes_acked) {
    1412           0 :                 net->partial_bytes_acked = 0;
    1413             :         }
    1414           0 :         if ((stcb->asoc.total_output_queue_size > 0) &&
    1415           0 :             (TAILQ_EMPTY(&stcb->asoc.send_queue)) &&
    1416           0 :             (TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
    1417           0 :                 sctp_audit_stream_queues_for_size(inp, stcb);
    1418             :         }
    1419           0 :         if (!(net->dest_state & SCTP_ADDR_NOHB) &&
    1420           0 :             !((net_was_pf == 0) && (net->dest_state & SCTP_ADDR_PF))) {
    1421             :                 /* when move to PF during threshold mangement, a HB has been
    1422             :                    queued in that routine */
    1423             :                 uint32_t ms_gone_by;
    1424             : 
    1425           0 :                 if ((net->last_sent_time.tv_sec > 0) ||
    1426           0 :                     (net->last_sent_time.tv_usec > 0)) {
    1427             : #ifdef __FreeBSD__
    1428             :                         struct timeval diff;
    1429             : 
    1430             :                         SCTP_GETTIME_TIMEVAL(&diff);
    1431             :                         timevalsub(&diff, &net->last_sent_time);
    1432             : #else
    1433             :                         struct timeval diff, now;
    1434             : 
    1435           0 :                         SCTP_GETTIME_TIMEVAL(&now);
    1436           0 :                         timersub(&now, &net->last_sent_time, &diff);
    1437             : #endif
    1438           0 :                         ms_gone_by = (uint32_t)(diff.tv_sec * 1000) +
    1439           0 :                                      (uint32_t)(diff.tv_usec / 1000);
    1440             :                 } else {
    1441           0 :                         ms_gone_by = 0xffffffff;
    1442             :                 }
    1443           0 :                 if ((ms_gone_by >= net->heart_beat_delay) ||
    1444           0 :                     (net->dest_state & SCTP_ADDR_PF)) {
    1445           0 :                         sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
    1446             :                 }
    1447             :         }
    1448           0 :         return (0);
    1449             : }
    1450             : 
    1451             : void
    1452           0 : sctp_pathmtu_timer(struct sctp_inpcb *inp,
    1453             :     struct sctp_tcb *stcb,
    1454             :     struct sctp_nets *net)
    1455             : {
    1456             :         uint32_t next_mtu, mtu;
    1457             : 
    1458           0 :         next_mtu = sctp_get_next_mtu(net->mtu);
    1459             : 
    1460           0 :         if ((next_mtu > net->mtu) && (net->port == 0)) {
    1461           0 :                 if ((net->src_addr_selected == 0) ||
    1462           0 :                     (net->ro._s_addr == NULL) ||
    1463           0 :                     (net->ro._s_addr->localifa_flags & SCTP_BEING_DELETED)) {
    1464           0 :                         if ((net->ro._s_addr != NULL) && (net->ro._s_addr->localifa_flags & SCTP_BEING_DELETED)) {
    1465           0 :                                 sctp_free_ifa(net->ro._s_addr);
    1466           0 :                                 net->ro._s_addr = NULL;
    1467           0 :                                 net->src_addr_selected = 0;
    1468           0 :                         } else  if (net->ro._s_addr == NULL) {
    1469             : #if defined(INET6) && defined(SCTP_EMBEDDED_V6_SCOPE)
    1470             :                                 if (net->ro._l_addr.sa.sa_family == AF_INET6) {
    1471             :                                         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
    1472             :                                         /* KAME hack: embed scopeid */
    1473             : #if defined(__APPLE__)
    1474             : #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
    1475             :                                         (void)in6_embedscope(&sin6->sin6_addr, sin6, NULL, NULL);
    1476             : #else
    1477             :                                         (void)in6_embedscope(&sin6->sin6_addr, sin6, NULL, NULL, NULL);
    1478             : #endif
    1479             : #elif defined(SCTP_KAME)
    1480             :                                         (void)sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
    1481             : #else
    1482             :                                         (void)in6_embedscope(&sin6->sin6_addr, sin6);
    1483             : #endif
    1484             :                                 }
    1485             : #endif
    1486             : 
    1487           0 :                                 net->ro._s_addr = sctp_source_address_selection(inp,
    1488             :                                                                                 stcb,
    1489           0 :                                                                                 (sctp_route_t *)&net->ro,
    1490             :                                                                                 net, 0, stcb->asoc.vrf_id);
    1491             : #if defined(INET6) && defined(SCTP_EMBEDDED_V6_SCOPE)
    1492             :                                 if (net->ro._l_addr.sa.sa_family == AF_INET6) {
    1493             :                                         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
    1494             : #ifdef SCTP_KAME
    1495             :                                         (void)sa6_recoverscope(sin6);
    1496             : #else
    1497             :                                         (void)in6_recoverscope(sin6, &sin6->sin6_addr, NULL);
    1498             : #endif  /* SCTP_KAME */
    1499             :                                 }
    1500             : #endif  /* INET6 */
    1501             :                         }
    1502           0 :                         if (net->ro._s_addr)
    1503           0 :                                 net->src_addr_selected = 1;
    1504             :                 }
    1505           0 :                 if (net->ro._s_addr) {
    1506           0 :                         mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._s_addr.sa, net->ro.ro_rt);
    1507             : #if defined(INET) || defined(INET6)
    1508             :                         if (net->port) {
    1509             :                                 mtu -= sizeof(struct udphdr);
    1510             :                         }
    1511             : #endif
    1512           0 :                         if (mtu > next_mtu) {
    1513           0 :                                 net->mtu = next_mtu;
    1514             :                         }
    1515             :                 }
    1516             :         }
    1517             :         /* restart the timer */
    1518           0 :         sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
    1519           0 : }
    1520             : 
    1521             : void
    1522           0 : sctp_autoclose_timer(struct sctp_inpcb *inp,
    1523             :     struct sctp_tcb *stcb,
    1524             :     struct sctp_nets *net)
    1525             : {
    1526             :         struct timeval tn, *tim_touse;
    1527             :         struct sctp_association *asoc;
    1528             :         int ticks_gone_by;
    1529             : 
    1530           0 :         (void)SCTP_GETTIME_TIMEVAL(&tn);
    1531           0 :         if (stcb->asoc.sctp_autoclose_ticks &&
    1532           0 :             sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) {
    1533             :                 /* Auto close is on */
    1534           0 :                 asoc = &stcb->asoc;
    1535             :                 /* pick the time to use */
    1536           0 :                 if (asoc->time_last_rcvd.tv_sec >
    1537           0 :                     asoc->time_last_sent.tv_sec) {
    1538           0 :                         tim_touse = &asoc->time_last_rcvd;
    1539             :                 } else {
    1540           0 :                         tim_touse = &asoc->time_last_sent;
    1541             :                 }
    1542             :                 /* Now has long enough transpired to autoclose? */
    1543           0 :                 ticks_gone_by = SEC_TO_TICKS(tn.tv_sec - tim_touse->tv_sec);
    1544           0 :                 if ((ticks_gone_by > 0) &&
    1545           0 :                     (ticks_gone_by >= (int)asoc->sctp_autoclose_ticks)) {
    1546             :                         /*
    1547             :                          * autoclose time has hit, call the output routine,
    1548             :                          * which should do nothing just to be SURE we don't
    1549             :                          * have hanging data. We can then safely check the
    1550             :                          * queues and know that we are clear to send
    1551             :                          * shutdown
    1552             :                          */
    1553           0 :                         sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_AUTOCLOSE_TMR, SCTP_SO_NOT_LOCKED);
    1554             :                         /* Are we clean? */
    1555           0 :                         if (TAILQ_EMPTY(&asoc->send_queue) &&
    1556           0 :                             TAILQ_EMPTY(&asoc->sent_queue)) {
    1557             :                                 /*
    1558             :                                  * there is nothing queued to send, so I'm
    1559             :                                  * done...
    1560             :                                  */
    1561           0 :                                 if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) {
    1562             :                                         /* only send SHUTDOWN 1st time thru */
    1563             :                                         struct sctp_nets *netp;
    1564             : 
    1565           0 :                                         if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
    1566           0 :                                             (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
    1567           0 :                                                 SCTP_STAT_DECR_GAUGE32(sctps_currestab);
    1568             :                                         }
    1569           0 :                                         SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
    1570           0 :                                         SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
    1571           0 :                                         sctp_stop_timers_for_shutdown(stcb);
    1572           0 :                                         if (stcb->asoc.alternate) {
    1573           0 :                                                 netp = stcb->asoc.alternate;
    1574             :                                         } else {
    1575           0 :                                                 netp = stcb->asoc.primary_destination;
    1576             :                                         }
    1577           0 :                                         sctp_send_shutdown(stcb, netp);
    1578           0 :                                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
    1579             :                                                          stcb->sctp_ep, stcb,
    1580             :                                                          netp);
    1581           0 :                                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
    1582             :                                                          stcb->sctp_ep, stcb,
    1583             :                                                          netp);
    1584             :                                 }
    1585             :                         }
    1586             :                 } else {
    1587             :                         /*
    1588             :                          * No auto close at this time, reset t-o to check
    1589             :                          * later
    1590             :                          */
    1591             :                         int tmp;
    1592             : 
    1593             :                         /* fool the timer startup to use the time left */
    1594           0 :                         tmp = asoc->sctp_autoclose_ticks;
    1595           0 :                         asoc->sctp_autoclose_ticks -= ticks_gone_by;
    1596           0 :                         sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb,
    1597             :                             net);
    1598             :                         /* restore the real tick value */
    1599           0 :                         asoc->sctp_autoclose_ticks = tmp;
    1600             :                 }
    1601             :         }
    1602           0 : }
    1603             : 

Generated by: LCOV version 1.13