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

          Line data    Source code
       1             : /*-
       2             :  * Copyright (c) 2001-2008, 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_input.c 279859 2015-03-10 19:49:25Z tuexen $");
      36             : #endif
      37             : 
      38             : #include <netinet/sctp_os.h>
      39             : #include <netinet/sctp_var.h>
      40             : #include <netinet/sctp_sysctl.h>
      41             : #include <netinet/sctp_pcb.h>
      42             : #include <netinet/sctp_header.h>
      43             : #include <netinet/sctputil.h>
      44             : #include <netinet/sctp_output.h>
      45             : #include <netinet/sctp_input.h>
      46             : #include <netinet/sctp_auth.h>
      47             : #include <netinet/sctp_indata.h>
      48             : #include <netinet/sctp_asconf.h>
      49             : #include <netinet/sctp_bsd_addr.h>
      50             : #include <netinet/sctp_timer.h>
      51             : #include <netinet/sctp_crc32.h>
      52             : #if defined(INET) || defined(INET6)
      53             : #if !defined(__Userspace_os_Windows)
      54             : #include <netinet/udp.h>
      55             : #endif
      56             : #endif
      57             : #if defined(__FreeBSD__)
      58             : #include <sys/smp.h>
      59             : #endif
      60             : 
      61             : #if defined(__APPLE__)
      62             : #define APPLE_FILE_NO 2
      63             : #endif
      64             : 
      65             : 
      66             : static void
      67           0 : sctp_stop_all_cookie_timers(struct sctp_tcb *stcb)
      68             : {
      69             :         struct sctp_nets *net;
      70             : 
      71             :         /* This now not only stops all cookie timers
      72             :          * it also stops any INIT timers as well. This
      73             :          * will make sure that the timers are stopped in
      74             :          * all collision cases.
      75             :          */
      76             :         SCTP_TCB_LOCK_ASSERT(stcb);
      77           0 :         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
      78           0 :                 if (net->rxt_timer.type == SCTP_TIMER_TYPE_COOKIE) {
      79           0 :                         sctp_timer_stop(SCTP_TIMER_TYPE_COOKIE,
      80             :                                         stcb->sctp_ep,
      81             :                                         stcb,
      82             :                                         net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_1);
      83           0 :                 } else if (net->rxt_timer.type == SCTP_TIMER_TYPE_INIT) {
      84           0 :                         sctp_timer_stop(SCTP_TIMER_TYPE_INIT,
      85             :                                         stcb->sctp_ep,
      86             :                                         stcb,
      87             :                                         net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_2);
      88             :                 }
      89             :         }
      90           0 : }
      91             : 
      92             : /* INIT handler */
      93             : static void
      94           0 : sctp_handle_init(struct mbuf *m, int iphlen, int offset,
      95             :                  struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh,
      96             :                  struct sctp_init_chunk *cp, struct sctp_inpcb *inp,
      97             :                  struct sctp_tcb *stcb, int *abort_no_unlock,
      98             : #if defined(__FreeBSD__)
      99             :                  uint8_t mflowtype, uint32_t mflowid,
     100             : #endif
     101             :                  uint32_t vrf_id, uint16_t port)
     102             : {
     103             :         struct sctp_init *init;
     104             :         struct mbuf *op_err;
     105             : 
     106           0 :         SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_init: handling INIT tcb:%p\n",
     107             :                 (void *)stcb);
     108           0 :         if (stcb == NULL) {
     109           0 :                 SCTP_INP_RLOCK(inp);
     110             :         }
     111             :         /* validate length */
     112           0 :         if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_chunk)) {
     113           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
     114           0 :                 sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
     115             : #if defined(__FreeBSD__)
     116             :                                        mflowtype, mflowid,
     117             : #endif
     118             :                                        vrf_id, port);
     119           0 :                 if (stcb)
     120           0 :                         *abort_no_unlock = 1;
     121           0 :                 goto outnow;
     122             :         }
     123             :         /* validate parameters */
     124           0 :         init = &cp->init;
     125           0 :         if (init->initiate_tag == 0) {
     126             :                 /* protocol error... send abort */
     127           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
     128           0 :                 sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
     129             : #if defined(__FreeBSD__)
     130             :                                        mflowtype, mflowid,
     131             : #endif
     132             :                                        vrf_id, port);
     133           0 :                 if (stcb)
     134           0 :                         *abort_no_unlock = 1;
     135           0 :                 goto outnow;
     136             :         }
     137           0 :         if (ntohl(init->a_rwnd) < SCTP_MIN_RWND) {
     138             :                 /* invalid parameter... send abort */
     139           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
     140           0 :                 sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
     141             : #if defined(__FreeBSD__)
     142             :                                        mflowtype, mflowid,
     143             : #endif
     144             :                                        vrf_id, port);
     145           0 :                 if (stcb)
     146           0 :                         *abort_no_unlock = 1;
     147           0 :                 goto outnow;
     148             :         }
     149           0 :         if (init->num_inbound_streams == 0) {
     150             :                 /* protocol error... send abort */
     151           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
     152           0 :                 sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
     153             : #if defined(__FreeBSD__)
     154             :                                        mflowtype, mflowid,
     155             : #endif
     156             :                                        vrf_id, port);
     157           0 :                 if (stcb)
     158           0 :                         *abort_no_unlock = 1;
     159           0 :                 goto outnow;
     160             :         }
     161           0 :         if (init->num_outbound_streams == 0) {
     162             :                 /* protocol error... send abort */
     163           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
     164           0 :                 sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
     165             : #if defined(__FreeBSD__)
     166             :                                        mflowtype, mflowid,
     167             : #endif
     168             :                                        vrf_id, port);
     169           0 :                 if (stcb)
     170           0 :                         *abort_no_unlock = 1;
     171           0 :                 goto outnow;
     172             :         }
     173           0 :         if (sctp_validate_init_auth_params(m, offset + sizeof(*cp),
     174           0 :                                            offset + ntohs(cp->ch.chunk_length))) {
     175             :                 /* auth parameter(s) error... send abort */
     176           0 :                 op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
     177             :                                              "Problem with AUTH parameters");
     178           0 :                 sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
     179             : #if defined(__FreeBSD__)
     180             :                                        mflowtype, mflowid,
     181             : #endif
     182             :                                        vrf_id, port);
     183           0 :                 if (stcb)
     184           0 :                         *abort_no_unlock = 1;
     185           0 :                 goto outnow;
     186             :         }
     187             :         /* We are only accepting if we have a socket with positive so_qlimit.*/
     188           0 :         if ((stcb == NULL) &&
     189           0 :             ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
     190           0 :              (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
     191           0 :              (inp->sctp_socket == NULL) ||
     192           0 :              (inp->sctp_socket->so_qlimit == 0))) {
     193             :                 /*
     194             :                  * FIX ME ?? What about TCP model and we have a
     195             :                  * match/restart case? Actually no fix is needed.
     196             :                  * the lookup will always find the existing assoc so stcb
     197             :                  * would not be NULL. It may be questionable to do this
     198             :                  * since we COULD just send back the INIT-ACK and hope that
     199             :                  * the app did accept()'s by the time the COOKIE was sent. But
     200             :                  * there is a price to pay for COOKIE generation and I don't
     201             :                  * want to pay it on the chance that the app will actually do
     202             :                  * some accepts(). The App just looses and should NOT be in
     203             :                  * this state :-)
     204             :                  */
     205           0 :                 if (SCTP_BASE_SYSCTL(sctp_blackhole) == 0) {
     206           0 :                         op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
     207             :                                                      "No listener");
     208           0 :                         sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err,
     209             : #if defined(__FreeBSD__)
     210             :                                         mflowtype, mflowid,
     211             : #endif
     212             :                                         vrf_id, port);
     213             :                 }
     214           0 :                 goto outnow;
     215             :         }
     216           0 :         if ((stcb != NULL) &&
     217           0 :             (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT)) {
     218           0 :                 SCTPDBG(SCTP_DEBUG_INPUT3, "sctp_handle_init: sending SHUTDOWN-ACK\n");
     219           0 :                 sctp_send_shutdown_ack(stcb, NULL);
     220           0 :                 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED);
     221             :         } else {
     222           0 :                 SCTPDBG(SCTP_DEBUG_INPUT3, "sctp_handle_init: sending INIT-ACK\n");
     223           0 :                 sctp_send_initiate_ack(inp, stcb, m, iphlen, offset, src, dst,
     224             :                                        sh, cp,
     225             : #if defined(__FreeBSD__)
     226             :                                        mflowtype, mflowid,
     227             : #endif
     228             :                                        vrf_id, port,
     229             :                                        ((stcb == NULL) ? SCTP_HOLDS_LOCK : SCTP_NOT_LOCKED));
     230             :         }
     231             :  outnow:
     232           0 :         if (stcb == NULL) {
     233           0 :                 SCTP_INP_RUNLOCK(inp);
     234             :         }
     235           0 : }
     236             : 
     237             : /*
     238             :  * process peer "INIT/INIT-ACK" chunk returns value < 0 on error
     239             :  */
     240             : 
     241             : int
     242           0 : sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked
     243             : #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
     244             :         SCTP_UNUSED
     245             : #endif
     246             : )
     247             : {
     248           0 :         int unsent_data = 0;
     249             :         unsigned int i;
     250             :         struct sctp_stream_queue_pending *sp;
     251             :         struct sctp_association *asoc;
     252             : 
     253             :         /* This function returns the number of streams that have
     254             :          * true unsent data on them. Note that as it looks through
     255             :          * it will clean up any places that have old data that
     256             :          * has been sent but left at top of stream queue.
     257             :          */
     258           0 :         asoc = &stcb->asoc;
     259           0 :         SCTP_TCB_SEND_LOCK(stcb);
     260           0 :         if (!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
     261             :                 /* Check to see if some data queued */
     262           0 :                 for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
     263             :                         /*sa_ignore FREED_MEMORY*/
     264           0 :                         sp = TAILQ_FIRST(&stcb->asoc.strmout[i].outqueue);
     265           0 :                         if (sp == NULL) {
     266           0 :                                 continue;
     267             :                         }
     268           0 :                         if ((sp->msg_is_complete) &&
     269           0 :                             (sp->length == 0)  &&
     270           0 :                             (sp->sender_all_done)) {
     271             :                                 /* We are doing differed cleanup. Last
     272             :                                  * time through when we took all the data
     273             :                                  * the sender_all_done was not set.
     274             :                                  */
     275           0 :                                 if (sp->put_last_out == 0) {
     276           0 :                                         SCTP_PRINTF("Gak, put out entire msg with NO end!-1\n");
     277           0 :                                         SCTP_PRINTF("sender_done:%d len:%d msg_comp:%d put_last_out:%d\n",
     278             :                                                     sp->sender_all_done,
     279             :                                                     sp->length,
     280             :                                                     sp->msg_is_complete,
     281             :                                                     sp->put_last_out);
     282             :                                 }
     283           0 :                                 atomic_subtract_int(&stcb->asoc.stream_queue_cnt, 1);
     284           0 :                                 TAILQ_REMOVE(&stcb->asoc.strmout[i].outqueue, sp, next);
     285           0 :                                 if (sp->net) {
     286           0 :                                         sctp_free_remote_addr(sp->net);
     287           0 :                                         sp->net = NULL;
     288             :                                 }
     289           0 :                                 if (sp->data) {
     290           0 :                                         sctp_m_freem(sp->data);
     291           0 :                                         sp->data = NULL;
     292             :                                 }
     293           0 :                                 sctp_free_a_strmoq(stcb, sp, so_locked);
     294             :                         } else {
     295           0 :                                 unsent_data++;
     296           0 :                                 break;
     297             :                         }
     298             :                 }
     299             :         }
     300           0 :         SCTP_TCB_SEND_UNLOCK(stcb);
     301           0 :         return (unsent_data);
     302             : }
     303             : 
     304             : static int
     305           0 : sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
     306             : {
     307             :         struct sctp_init *init;
     308             :         struct sctp_association *asoc;
     309             :         struct sctp_nets *lnet;
     310             :         unsigned int i;
     311             : 
     312           0 :         init = &cp->init;
     313           0 :         asoc = &stcb->asoc;
     314             :         /* save off parameters */
     315           0 :         asoc->peer_vtag = ntohl(init->initiate_tag);
     316           0 :         asoc->peers_rwnd = ntohl(init->a_rwnd);
     317             :         /* init tsn's */
     318           0 :         asoc->highest_tsn_inside_map = asoc->asconf_seq_in = ntohl(init->initial_tsn) - 1;
     319             : 
     320           0 :         if (!TAILQ_EMPTY(&asoc->nets)) {
     321             :                 /* update any ssthresh's that may have a default */
     322           0 :                 TAILQ_FOREACH(lnet, &asoc->nets, sctp_next) {
     323           0 :                         lnet->ssthresh = asoc->peers_rwnd;
     324           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & (SCTP_CWND_MONITOR_ENABLE|SCTP_CWND_LOGGING_ENABLE)) {
     325           0 :                                 sctp_log_cwnd(stcb, lnet, 0, SCTP_CWND_INITIALIZATION);
     326             :                         }
     327             : 
     328             :                 }
     329             :         }
     330           0 :         SCTP_TCB_SEND_LOCK(stcb);
     331           0 :         if (asoc->pre_open_streams > ntohs(init->num_inbound_streams)) {
     332             :                 unsigned int newcnt;
     333             :                 struct sctp_stream_out *outs;
     334             :                 struct sctp_stream_queue_pending *sp, *nsp;
     335             :                 struct sctp_tmit_chunk *chk, *nchk;
     336             : 
     337             :                 /* abandon the upper streams */
     338           0 :                 newcnt = ntohs(init->num_inbound_streams);
     339           0 :                 TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
     340           0 :                         if (chk->rec.data.stream_number >= newcnt) {
     341           0 :                                 TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
     342           0 :                                 asoc->send_queue_cnt--;
     343           0 :                                 if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
     344           0 :                                         asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
     345             : #ifdef INVARIANTS
     346             :                                 } else {
     347             :                                         panic("No chunks on the queues for sid %u.", chk->rec.data.stream_number);
     348             : #endif
     349             :                                 }
     350           0 :                                 if (chk->data != NULL) {
     351           0 :                                         sctp_free_bufspace(stcb, asoc, chk, 1);
     352           0 :                                         sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb,
     353             :                                                         0, chk, SCTP_SO_NOT_LOCKED);
     354           0 :                                         if (chk->data) {
     355           0 :                                                 sctp_m_freem(chk->data);
     356           0 :                                                 chk->data = NULL;
     357             :                                         }
     358             :                                 }
     359           0 :                                 sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
     360             :                                 /*sa_ignore FREED_MEMORY*/
     361             :                         }
     362             :                 }
     363           0 :                 if (asoc->strmout) {
     364           0 :                         for (i = newcnt; i < asoc->pre_open_streams; i++) {
     365           0 :                                 outs = &asoc->strmout[i];
     366           0 :                                 TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) {
     367           0 :                                         TAILQ_REMOVE(&outs->outqueue, sp, next);
     368           0 :                                         asoc->stream_queue_cnt--;
     369           0 :                                         sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL,
     370             :                                             stcb, 0, sp, SCTP_SO_NOT_LOCKED);
     371           0 :                                         if (sp->data) {
     372           0 :                                                 sctp_m_freem(sp->data);
     373           0 :                                                 sp->data = NULL;
     374             :                                         }
     375           0 :                                         if (sp->net) {
     376           0 :                                                 sctp_free_remote_addr(sp->net);
     377           0 :                                                 sp->net = NULL;
     378             :                                         }
     379             :                                         /* Free the chunk */
     380           0 :                                         sctp_free_a_strmoq(stcb, sp, SCTP_SO_NOT_LOCKED);
     381             :                                         /*sa_ignore FREED_MEMORY*/
     382             :                                 }
     383             :                         }
     384             :                 }
     385             :                 /* cut back the count */
     386           0 :                 asoc->pre_open_streams = newcnt;
     387             :         }
     388           0 :         SCTP_TCB_SEND_UNLOCK(stcb);
     389           0 :         asoc->strm_realoutsize = asoc->streamoutcnt = asoc->pre_open_streams;
     390             : 
     391             :         /* EY - nr_sack: initialize highest tsn in nr_mapping_array */
     392           0 :         asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map;
     393           0 :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
     394           0 :                 sctp_log_map(0, 5, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
     395             :         }
     396             :         /* This is the next one we expect */
     397           0 :         asoc->str_reset_seq_in = asoc->asconf_seq_in + 1;
     398             : 
     399           0 :         asoc->mapping_array_base_tsn = ntohl(init->initial_tsn);
     400           0 :         asoc->tsn_last_delivered = asoc->cumulative_tsn = asoc->asconf_seq_in;
     401             : 
     402           0 :         asoc->advanced_peer_ack_point = asoc->last_acked_seq;
     403             :         /* open the requested streams */
     404             : 
     405           0 :         if (asoc->strmin != NULL) {
     406             :                 /* Free the old ones */
     407             :                 struct sctp_queued_to_read *ctl, *nctl;
     408             : 
     409           0 :                 for (i = 0; i < asoc->streamincnt; i++) {
     410           0 :                         TAILQ_FOREACH_SAFE(ctl, &asoc->strmin[i].inqueue, next, nctl) {
     411           0 :                                 TAILQ_REMOVE(&asoc->strmin[i].inqueue, ctl, next);
     412           0 :                                 sctp_free_remote_addr(ctl->whoFrom);
     413           0 :                                 ctl->whoFrom = NULL;
     414           0 :                                 sctp_m_freem(ctl->data);
     415           0 :                                 ctl->data = NULL;
     416           0 :                                 sctp_free_a_readq(stcb, ctl);
     417             :                         }
     418             :                 }
     419           0 :                 SCTP_FREE(asoc->strmin, SCTP_M_STRMI);
     420             :         }
     421           0 :         if (asoc->max_inbound_streams > ntohs(init->num_outbound_streams)) {
     422           0 :                 asoc->streamincnt = ntohs(init->num_outbound_streams);
     423             :         } else {
     424           0 :                 asoc->streamincnt = asoc->max_inbound_streams;
     425             :         }
     426           0 :         SCTP_MALLOC(asoc->strmin, struct sctp_stream_in *, asoc->streamincnt *
     427             :                     sizeof(struct sctp_stream_in), SCTP_M_STRMI);
     428           0 :         if (asoc->strmin == NULL) {
     429             :                 /* we didn't get memory for the streams! */
     430           0 :                 SCTPDBG(SCTP_DEBUG_INPUT2, "process_init: couldn't get memory for the streams!\n");
     431           0 :                 return (-1);
     432             :         }
     433           0 :         for (i = 0; i < asoc->streamincnt; i++) {
     434           0 :                 asoc->strmin[i].stream_no = i;
     435           0 :                 asoc->strmin[i].last_sequence_delivered = 0xffff;
     436           0 :                 TAILQ_INIT(&asoc->strmin[i].inqueue);
     437           0 :                 asoc->strmin[i].delivery_started = 0;
     438             :         }
     439             :         /*
     440             :          * load_address_from_init will put the addresses into the
     441             :          * association when the COOKIE is processed or the INIT-ACK is
     442             :          * processed. Both types of COOKIE's existing and new call this
     443             :          * routine. It will remove addresses that are no longer in the
     444             :          * association (for the restarting case where addresses are
     445             :          * removed). Up front when the INIT arrives we will discard it if it
     446             :          * is a restart and new addresses have been added.
     447             :          */
     448             :         /* sa_ignore MEMLEAK */
     449           0 :         return (0);
     450             : }
     451             : 
     452             : /*
     453             :  * INIT-ACK message processing/consumption returns value < 0 on error
     454             :  */
     455             : static int
     456           0 : sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
     457             :                       struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh,
     458             :                       struct sctp_init_ack_chunk *cp, struct sctp_tcb *stcb,
     459             :                       struct sctp_nets *net, int *abort_no_unlock,
     460             : #if defined(__FreeBSD__)
     461             :                       uint8_t mflowtype, uint32_t mflowid,
     462             : #endif
     463             :                       uint32_t vrf_id)
     464             : {
     465             :         struct sctp_association *asoc;
     466             :         struct mbuf *op_err;
     467             :         int retval, abort_flag;
     468             :         uint32_t initack_limit;
     469           0 :         int nat_friendly = 0;
     470             : 
     471             :         /* First verify that we have no illegal param's */
     472           0 :         abort_flag = 0;
     473             : 
     474           0 :         op_err = sctp_arethere_unrecognized_parameters(m,
     475           0 :                                                        (offset + sizeof(struct sctp_init_chunk)),
     476             :                                                        &abort_flag, (struct sctp_chunkhdr *)cp, &nat_friendly);
     477           0 :         if (abort_flag) {
     478             :                 /* Send an abort and notify peer */
     479           0 :                 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
     480           0 :                 *abort_no_unlock = 1;
     481           0 :                 return (-1);
     482             :         }
     483           0 :         asoc = &stcb->asoc;
     484           0 :         asoc->peer_supports_nat = (uint8_t)nat_friendly;
     485             :         /* process the peer's parameters in the INIT-ACK */
     486           0 :         retval = sctp_process_init((struct sctp_init_chunk *)cp, stcb);
     487           0 :         if (retval < 0) {
     488           0 :                 return (retval);
     489             :         }
     490           0 :         initack_limit = offset + ntohs(cp->ch.chunk_length);
     491             :         /* load all addresses */
     492           0 :         if ((retval = sctp_load_addresses_from_init(stcb, m,
     493           0 :             (offset + sizeof(struct sctp_init_chunk)), initack_limit,
     494             :             src, dst, NULL))) {
     495           0 :                 op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
     496             :                                              "Problem with address parameters");
     497           0 :                 SCTPDBG(SCTP_DEBUG_INPUT1,
     498             :                         "Load addresses from INIT causes an abort %d\n",
     499             :                         retval);
     500           0 :                 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
     501             :                                        src, dst, sh, op_err,
     502             : #if defined(__FreeBSD__)
     503             :                                        mflowtype, mflowid,
     504             : #endif
     505           0 :                                        vrf_id, net->port);
     506           0 :                 *abort_no_unlock = 1;
     507           0 :                 return (-1);
     508             :         }
     509             :         /* if the peer doesn't support asconf, flush the asconf queue */
     510           0 :         if (asoc->asconf_supported == 0) {
     511             :                 struct sctp_asconf_addr *param, *nparam;
     512             : 
     513           0 :                 TAILQ_FOREACH_SAFE(param, &asoc->asconf_queue, next, nparam) {
     514           0 :                         TAILQ_REMOVE(&asoc->asconf_queue, param, next);
     515           0 :                         SCTP_FREE(param, SCTP_M_ASC_ADDR);
     516             :                 }
     517             :         }
     518             : 
     519           0 :         stcb->asoc.peer_hmac_id = sctp_negotiate_hmacid(stcb->asoc.peer_hmacs,
     520             :             stcb->asoc.local_hmacs);
     521           0 :         if (op_err) {
     522           0 :                 sctp_queue_op_err(stcb, op_err);
     523             :                 /* queuing will steal away the mbuf chain to the out queue */
     524           0 :                 op_err = NULL;
     525             :         }
     526             :         /* extract the cookie and queue it to "echo" it back... */
     527           0 :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
     528           0 :                 sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
     529             :                                stcb->asoc.overall_error_count,
     530             :                                0,
     531             :                                SCTP_FROM_SCTP_INPUT,
     532             :                                __LINE__);
     533             :         }
     534           0 :         stcb->asoc.overall_error_count = 0;
     535           0 :         net->error_count = 0;
     536             : 
     537             :         /*
     538             :          * Cancel the INIT timer, We do this first before queueing the
     539             :          * cookie. We always cancel at the primary to assue that we are
     540             :          * canceling the timer started by the INIT which always goes to the
     541             :          * primary.
     542             :          */
     543           0 :         sctp_timer_stop(SCTP_TIMER_TYPE_INIT, stcb->sctp_ep, stcb,
     544             :             asoc->primary_destination, SCTP_FROM_SCTP_INPUT+SCTP_LOC_4);
     545             : 
     546             :         /* calculate the RTO */
     547           0 :         net->RTO = sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered, sctp_align_safe_nocopy,
     548             :                                       SCTP_RTT_FROM_NON_DATA);
     549             : 
     550           0 :         retval = sctp_send_cookie_echo(m, offset, stcb, net);
     551           0 :         if (retval < 0) {
     552             :                 /*
     553             :                  * No cookie, we probably should send a op error. But in any
     554             :                  * case if there is no cookie in the INIT-ACK, we can
     555             :                  * abandon the peer, its broke.
     556             :                  */
     557           0 :                 if (retval == -3) {
     558             :                         /* We abort with an error of missing mandatory param */
     559           0 :                         op_err = sctp_generate_cause(SCTP_CAUSE_MISSING_PARAM, "");
     560           0 :                         if (op_err) {
     561             :                                 /*
     562             :                                  * Expand beyond to include the mandatory
     563             :                                  * param cookie
     564             :                                  */
     565             :                                 struct sctp_inv_mandatory_param *mp;
     566             : 
     567           0 :                                 SCTP_BUF_LEN(op_err) =
     568             :                                     sizeof(struct sctp_inv_mandatory_param);
     569           0 :                                 mp = mtod(op_err,
     570             :                                     struct sctp_inv_mandatory_param *);
     571             :                                 /* Subtract the reserved param */
     572           0 :                                 mp->length =
     573           0 :                                     htons(sizeof(struct sctp_inv_mandatory_param) - 2);
     574           0 :                                 mp->num_param = htonl(1);
     575           0 :                                 mp->param = htons(SCTP_STATE_COOKIE);
     576           0 :                                 mp->resv = 0;
     577             :                         }
     578           0 :                         sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
     579             :                                                src, dst, sh, op_err,
     580             : #if defined(__FreeBSD__)
     581             :                                                mflowtype, mflowid,
     582             : #endif
     583           0 :                                                vrf_id, net->port);
     584           0 :                         *abort_no_unlock = 1;
     585             :                 }
     586           0 :                 return (retval);
     587             :         }
     588             : 
     589           0 :         return (0);
     590             : }
     591             : 
     592             : static void
     593           0 : sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
     594             :     struct sctp_tcb *stcb, struct sctp_nets *net)
     595             : {
     596             :         union sctp_sockstore store;
     597             :         struct sctp_nets *r_net, *f_net;
     598             :         struct timeval tv;
     599           0 :         int req_prim = 0;
     600             :         uint16_t old_error_counter;
     601             : 
     602           0 :         if (ntohs(cp->ch.chunk_length) != sizeof(struct sctp_heartbeat_chunk)) {
     603             :                 /* Invalid length */
     604           0 :                 return;
     605             :         }
     606             : 
     607           0 :         memset(&store, 0, sizeof(store));
     608           0 :         switch (cp->heartbeat.hb_info.addr_family) {
     609             : #ifdef INET
     610             :         case AF_INET:
     611             :                 if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_in)) {
     612             :                         store.sin.sin_family = cp->heartbeat.hb_info.addr_family;
     613             : #ifdef HAVE_SIN_LEN
     614             :                         store.sin.sin_len = cp->heartbeat.hb_info.addr_len;
     615             : #endif
     616             :                         store.sin.sin_port = stcb->rport;
     617             :                         memcpy(&store.sin.sin_addr, cp->heartbeat.hb_info.address,
     618             :                                sizeof(store.sin.sin_addr));
     619             :                 } else {
     620             :                         return;
     621             :                 }
     622             :                 break;
     623             : #endif
     624             : #ifdef INET6
     625             :         case AF_INET6:
     626             :                 if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_in6)) {
     627             :                         store.sin6.sin6_family = cp->heartbeat.hb_info.addr_family;
     628             : #ifdef HAVE_SIN6_LEN
     629             :                         store.sin6.sin6_len = cp->heartbeat.hb_info.addr_len;
     630             : #endif
     631             :                         store.sin6.sin6_port = stcb->rport;
     632             :                         memcpy(&store.sin6.sin6_addr, cp->heartbeat.hb_info.address, sizeof(struct in6_addr));
     633             :                 } else {
     634             :                         return;
     635             :                 }
     636             :                 break;
     637             : #endif
     638             : #if defined(__Userspace__)
     639             :         case AF_CONN:
     640           0 :                 if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_conn)) {
     641           0 :                         store.sconn.sconn_family = cp->heartbeat.hb_info.addr_family;
     642             : #ifdef HAVE_SCONN_LEN
     643             :                         store.sconn.sconn_len = cp->heartbeat.hb_info.addr_len;
     644             : #endif
     645           0 :                         store.sconn.sconn_port = stcb->rport;
     646           0 :                         memcpy(&store.sconn.sconn_addr, cp->heartbeat.hb_info.address, sizeof(void *));
     647             :                 } else {
     648           0 :                         return;
     649             :                 }
     650           0 :                 break;
     651             : #endif
     652             :         default:
     653           0 :                 return;
     654             :         }
     655           0 :         r_net = sctp_findnet(stcb, &store.sa);
     656           0 :         if (r_net == NULL) {
     657           0 :                 SCTPDBG(SCTP_DEBUG_INPUT1, "Huh? I can't find the address I sent it to, discard\n");
     658           0 :                 return;
     659             :         }
     660           0 :         if ((r_net && (r_net->dest_state & SCTP_ADDR_UNCONFIRMED)) &&
     661           0 :             (r_net->heartbeat_random1 == cp->heartbeat.hb_info.random_value1) &&
     662           0 :             (r_net->heartbeat_random2 == cp->heartbeat.hb_info.random_value2)) {
     663             :                 /*
     664             :                  * If the its a HB and it's random value is correct when can
     665             :                  * confirm the destination.
     666             :                  */
     667           0 :                 r_net->dest_state &= ~SCTP_ADDR_UNCONFIRMED;
     668           0 :                 if (r_net->dest_state & SCTP_ADDR_REQ_PRIMARY) {
     669           0 :                         stcb->asoc.primary_destination = r_net;
     670           0 :                         r_net->dest_state &= ~SCTP_ADDR_REQ_PRIMARY;
     671           0 :                         f_net = TAILQ_FIRST(&stcb->asoc.nets);
     672           0 :                         if (f_net != r_net) {
     673             :                                 /* first one on the list is NOT the primary
     674             :                                  * sctp_cmpaddr() is much more efficent if
     675             :                                  * the primary is the first on the list, make it
     676             :                                  * so.
     677             :                                  */
     678           0 :                                 TAILQ_REMOVE(&stcb->asoc.nets, r_net, sctp_next);
     679           0 :                                 TAILQ_INSERT_HEAD(&stcb->asoc.nets, r_net, sctp_next);
     680             :                         }
     681           0 :                         req_prim = 1;
     682             :                 }
     683           0 :                 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
     684             :                     stcb, 0, (void *)r_net, SCTP_SO_NOT_LOCKED);
     685           0 :                 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3);
     686           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net);
     687             :         }
     688           0 :         old_error_counter = r_net->error_count;
     689           0 :         r_net->error_count = 0;
     690           0 :         r_net->hb_responded = 1;
     691           0 :         tv.tv_sec = cp->heartbeat.hb_info.time_value_1;
     692           0 :         tv.tv_usec = cp->heartbeat.hb_info.time_value_2;
     693             :         /* Now lets do a RTO with this */
     694           0 :         r_net->RTO = sctp_calculate_rto(stcb, &stcb->asoc, r_net, &tv, sctp_align_safe_nocopy,
     695             :                                         SCTP_RTT_FROM_NON_DATA);
     696           0 :         if (!(r_net->dest_state & SCTP_ADDR_REACHABLE)) {
     697           0 :                 r_net->dest_state |= SCTP_ADDR_REACHABLE;
     698           0 :                 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb,
     699             :                                 0, (void *)r_net, SCTP_SO_NOT_LOCKED);
     700             :         }
     701           0 :         if (r_net->dest_state & SCTP_ADDR_PF) {
     702           0 :                 r_net->dest_state &= ~SCTP_ADDR_PF;
     703           0 :                 stcb->asoc.cc_functions.sctp_cwnd_update_exit_pf(stcb, net);
     704             :         }
     705           0 :         if (old_error_counter > 0) {
     706           0 :                 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3);
     707           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net);
     708             :         }
     709           0 :         if (r_net == stcb->asoc.primary_destination) {
     710           0 :                 if (stcb->asoc.alternate) {
     711             :                         /* release the alternate, primary is good */
     712           0 :                         sctp_free_remote_addr(stcb->asoc.alternate);
     713           0 :                         stcb->asoc.alternate = NULL;
     714             :                 }
     715             :         }
     716             :         /* Mobility adaptation */
     717           0 :         if (req_prim) {
     718           0 :                 if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
     719           0 :                                                  SCTP_MOBILITY_BASE) ||
     720           0 :                     sctp_is_mobility_feature_on(stcb->sctp_ep,
     721           0 :                                                 SCTP_MOBILITY_FASTHANDOFF)) &&
     722           0 :                     sctp_is_mobility_feature_on(stcb->sctp_ep,
     723             :                                                 SCTP_MOBILITY_PRIM_DELETED)) {
     724             : 
     725           0 :                         sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_TIMER+SCTP_LOC_7);
     726           0 :                         if (sctp_is_mobility_feature_on(stcb->sctp_ep,
     727             :                                         SCTP_MOBILITY_FASTHANDOFF)) {
     728           0 :                                 sctp_assoc_immediate_retrans(stcb,
     729             :                                         stcb->asoc.primary_destination);
     730             :                         }
     731           0 :                         if (sctp_is_mobility_feature_on(stcb->sctp_ep,
     732             :                                         SCTP_MOBILITY_BASE)) {
     733           0 :                                 sctp_move_chunks_from_net(stcb,
     734             :                                         stcb->asoc.deleted_primary);
     735             :                         }
     736           0 :                         sctp_delete_prim_timer(stcb->sctp_ep, stcb,
     737             :                                         stcb->asoc.deleted_primary);
     738             :                 }
     739             :         }
     740             : }
     741             : 
     742             : static int
     743           0 : sctp_handle_nat_colliding_state(struct sctp_tcb *stcb)
     744             : {
     745             :         /* return 0 means we want you to proceed with the abort
     746             :          * non-zero means no abort processing
     747             :         */
     748             :         struct sctpasochead *head;
     749             : 
     750           0 :         if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) {
     751             :                 /* generate a new vtag and send init */
     752           0 :                 LIST_REMOVE(stcb, sctp_asocs);
     753           0 :                 stcb->asoc.my_vtag = sctp_select_a_tag(stcb->sctp_ep, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
     754           0 :                 head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
     755             :                 /* put it in the bucket in the vtag hash of assoc's for the system */
     756           0 :                 LIST_INSERT_HEAD(head, stcb, sctp_asocs);
     757           0 :                 sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
     758           0 :                 return (1);
     759             :         }
     760           0 :         if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
     761             :                 /* treat like a case where the cookie expired i.e.:
     762             :                 * - dump current cookie.
     763             :                 * - generate a new vtag.
     764             :                 * - resend init.
     765             :                 */
     766             :                 /* generate a new vtag and send init */
     767           0 :                 LIST_REMOVE(stcb, sctp_asocs);
     768           0 :                 stcb->asoc.state &= ~SCTP_STATE_COOKIE_ECHOED;
     769           0 :                 stcb->asoc.state |= SCTP_STATE_COOKIE_WAIT;
     770           0 :                 sctp_stop_all_cookie_timers(stcb);
     771           0 :                 sctp_toss_old_cookies(stcb, &stcb->asoc);
     772           0 :                 stcb->asoc.my_vtag = sctp_select_a_tag(stcb->sctp_ep, stcb->sctp_ep->sctp_lport, stcb->rport,  1);
     773           0 :                 head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
     774             :                 /* put it in the bucket in the vtag hash of assoc's for the system */
     775           0 :                 LIST_INSERT_HEAD(head, stcb, sctp_asocs);
     776           0 :                 sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
     777           0 :                 return (1);
     778             :         }
     779           0 :         return (0);
     780             : }
     781             : 
     782             : static int
     783           0 : sctp_handle_nat_missing_state(struct sctp_tcb *stcb,
     784             :                               struct sctp_nets *net)
     785             : {
     786             :         /* return 0 means we want you to proceed with the abort
     787             :          * non-zero means no abort processing
     788             :          */
     789           0 :         if (stcb->asoc.auth_supported == 0) {
     790           0 :                 SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_nat_missing_state: Peer does not support AUTH, cannot send an asconf\n");
     791           0 :                 return (0);
     792             :         }
     793           0 :         sctp_asconf_send_nat_state_update(stcb, net);
     794           0 :         return (1);
     795             : }
     796             : 
     797             : 
     798             : static void
     799           0 : sctp_handle_abort(struct sctp_abort_chunk *abort,
     800             :     struct sctp_tcb *stcb, struct sctp_nets *net)
     801             : {
     802             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
     803             :         struct socket *so;
     804             : #endif
     805             :         uint16_t len;
     806             :         uint16_t error;
     807             : 
     808           0 :         SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_abort: handling ABORT\n");
     809           0 :         if (stcb == NULL)
     810           0 :                 return;
     811             : 
     812           0 :         len = ntohs(abort->ch.chunk_length);
     813           0 :         if (len > sizeof (struct sctp_chunkhdr)) {
     814             :                 /* Need to check the cause codes for our
     815             :                  * two magic nat aborts which don't kill the assoc
     816             :                  * necessarily.
     817             :                  */
     818             :                 struct sctp_missing_nat_state *natc;
     819             : 
     820           0 :                 natc = (struct sctp_missing_nat_state *)(abort + 1);
     821           0 :                 error = ntohs(natc->cause);
     822           0 :                 if (error == SCTP_CAUSE_NAT_COLLIDING_STATE) {
     823           0 :                         SCTPDBG(SCTP_DEBUG_INPUT2, "Received Colliding state abort flags:%x\n",
     824             :                                                    abort->ch.chunk_flags);
     825           0 :                         if (sctp_handle_nat_colliding_state(stcb)) {
     826           0 :                                 return;
     827             :                         }
     828           0 :                 } else if (error == SCTP_CAUSE_NAT_MISSING_STATE) {
     829           0 :                         SCTPDBG(SCTP_DEBUG_INPUT2, "Received missing state abort flags:%x\n",
     830             :                                                    abort->ch.chunk_flags);
     831           0 :                         if (sctp_handle_nat_missing_state(stcb, net)) {
     832           0 :                                 return;
     833             :                         }
     834             :                 }
     835             :         } else {
     836           0 :                 error = 0;
     837             :         }
     838             :         /* stop any receive timers */
     839           0 :         sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_6);
     840             :         /* notify user of the abort and clean up... */
     841           0 :         sctp_abort_notification(stcb, 1, error, abort, SCTP_SO_NOT_LOCKED);
     842             :         /* free the tcb */
     843           0 :         SCTP_STAT_INCR_COUNTER32(sctps_aborted);
     844           0 :         if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
     845           0 :             (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
     846           0 :                 SCTP_STAT_DECR_GAUGE32(sctps_currestab);
     847             :         }
     848             : #ifdef SCTP_ASOCLOG_OF_TSNS
     849             :         sctp_print_out_track_log(stcb);
     850             : #endif
     851             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
     852             :         so = SCTP_INP_SO(stcb->sctp_ep);
     853             :         atomic_add_int(&stcb->asoc.refcnt, 1);
     854             :         SCTP_TCB_UNLOCK(stcb);
     855             :         SCTP_SOCKET_LOCK(so, 1);
     856             :         SCTP_TCB_LOCK(stcb);
     857             :         atomic_subtract_int(&stcb->asoc.refcnt, 1);
     858             : #endif
     859           0 :         stcb->asoc.state |= SCTP_STATE_WAS_ABORTED;
     860           0 :         (void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
     861             :                               SCTP_FROM_SCTP_INPUT+SCTP_LOC_6);
     862             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
     863             :         SCTP_SOCKET_UNLOCK(so, 1);
     864             : #endif
     865           0 :         SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_abort: finished\n");
     866             : }
     867             : 
     868             : static void
     869           0 : sctp_start_net_timers(struct sctp_tcb *stcb)
     870             : {
     871             :         uint32_t cnt_hb_sent;
     872             :         struct sctp_nets *net;
     873             : 
     874           0 :         cnt_hb_sent = 0;
     875           0 :         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
     876             :                 /* For each network start:
     877             :                  * 1) A pmtu timer.
     878             :                  * 2) A HB timer
     879             :                  * 3) If the dest in unconfirmed send
     880             :                  *    a hb as well if under max_hb_burst have
     881             :                  *    been sent.
     882             :                  */
     883           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net);
     884           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
     885           0 :                 if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
     886           0 :                     (cnt_hb_sent < SCTP_BASE_SYSCTL(sctp_hb_maxburst))) {
     887           0 :                         sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
     888           0 :                         cnt_hb_sent++;
     889             :                 }
     890             :         }
     891           0 :         if (cnt_hb_sent) {
     892           0 :                 sctp_chunk_output(stcb->sctp_ep, stcb,
     893             :                                   SCTP_OUTPUT_FROM_COOKIE_ACK,
     894             :                                   SCTP_SO_NOT_LOCKED);
     895             :         }
     896           0 : }
     897             : 
     898             : 
     899             : static void
     900           0 : sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
     901             :     struct sctp_tcb *stcb, struct sctp_nets *net, int *abort_flag)
     902             : {
     903             :         struct sctp_association *asoc;
     904             :         int some_on_streamwheel;
     905             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
     906             :         struct socket *so;
     907             : #endif
     908             : 
     909           0 :         SCTPDBG(SCTP_DEBUG_INPUT2,
     910             :                 "sctp_handle_shutdown: handling SHUTDOWN\n");
     911           0 :         if (stcb == NULL)
     912           0 :                 return;
     913           0 :         asoc = &stcb->asoc;
     914           0 :         if ((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT) ||
     915           0 :             (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)) {
     916           0 :                 return;
     917             :         }
     918           0 :         if (ntohs(cp->ch.chunk_length) != sizeof(struct sctp_shutdown_chunk)) {
     919             :                 /* Shutdown NOT the expected size */
     920           0 :                 return;
     921             :         } else {
     922           0 :                 sctp_update_acked(stcb, cp, abort_flag);
     923           0 :                 if (*abort_flag) {
     924           0 :                         return;
     925             :                 }
     926             :         }
     927           0 :         if (asoc->control_pdapi) {
     928             :                 /* With a normal shutdown
     929             :                  * we assume the end of last record.
     930             :                  */
     931           0 :                 SCTP_INP_READ_LOCK(stcb->sctp_ep);
     932           0 :                 asoc->control_pdapi->end_added = 1;
     933           0 :                 asoc->control_pdapi->pdapi_aborted = 1;
     934           0 :                 asoc->control_pdapi = NULL;
     935           0 :                 SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
     936             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
     937             :                 so = SCTP_INP_SO(stcb->sctp_ep);
     938             :                 atomic_add_int(&stcb->asoc.refcnt, 1);
     939             :                 SCTP_TCB_UNLOCK(stcb);
     940             :                 SCTP_SOCKET_LOCK(so, 1);
     941             :                 SCTP_TCB_LOCK(stcb);
     942             :                 atomic_subtract_int(&stcb->asoc.refcnt, 1);
     943             :                 if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
     944             :                         /* assoc was freed while we were unlocked */
     945             :                         SCTP_SOCKET_UNLOCK(so, 1);
     946             :                         return;
     947             :                 }
     948             : #endif
     949           0 :                 sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
     950             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
     951             :                 SCTP_SOCKET_UNLOCK(so, 1);
     952             : #endif
     953             :         }
     954             :         /* goto SHUTDOWN_RECEIVED state to block new requests */
     955           0 :         if (stcb->sctp_socket) {
     956           0 :                 if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
     957           0 :                     (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT) &&
     958           0 :                     (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT)) {
     959           0 :                         SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_RECEIVED);
     960           0 :                         SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
     961             :                         /* notify upper layer that peer has initiated a shutdown */
     962           0 :                         sctp_ulp_notify(SCTP_NOTIFY_PEER_SHUTDOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
     963             : 
     964             :                         /* reset time */
     965           0 :                         (void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered);
     966             :                 }
     967             :         }
     968           0 :         if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_SENT) {
     969             :                 /*
     970             :                  * stop the shutdown timer, since we WILL move to
     971             :                  * SHUTDOWN-ACK-SENT.
     972             :                  */
     973           0 :                 sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_8);
     974             :         }
     975             :         /* Now is there unsent data on a stream somewhere? */
     976           0 :         some_on_streamwheel = sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED);
     977             : 
     978           0 :         if (!TAILQ_EMPTY(&asoc->send_queue) ||
     979           0 :             !TAILQ_EMPTY(&asoc->sent_queue) ||
     980             :             some_on_streamwheel) {
     981             :                 /* By returning we will push more data out */
     982           0 :                 return;
     983             :         } else {
     984             :                 /* no outstanding data to send, so move on... */
     985             :                 /* send SHUTDOWN-ACK */
     986             :                 /* move to SHUTDOWN-ACK-SENT state */
     987           0 :                 if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
     988           0 :                     (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
     989           0 :                         SCTP_STAT_DECR_GAUGE32(sctps_currestab);
     990             :                 }
     991           0 :                 SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
     992           0 :                 SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
     993           0 :                 sctp_stop_timers_for_shutdown(stcb);
     994           0 :                 sctp_send_shutdown_ack(stcb, net);
     995           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep,
     996             :                                  stcb, net);
     997             :         }
     998             : }
     999             : 
    1000             : static void
    1001           0 : sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
    1002             :                          struct sctp_tcb *stcb,
    1003             :                          struct sctp_nets *net)
    1004             : {
    1005             :         struct sctp_association *asoc;
    1006             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1007             :         struct socket *so;
    1008             : 
    1009             :         so = SCTP_INP_SO(stcb->sctp_ep);
    1010             : #endif
    1011           0 :         SCTPDBG(SCTP_DEBUG_INPUT2,
    1012             :                 "sctp_handle_shutdown_ack: handling SHUTDOWN ACK\n");
    1013           0 :         if (stcb == NULL)
    1014           0 :                 return;
    1015             : 
    1016           0 :         asoc = &stcb->asoc;
    1017             :         /* process according to association state */
    1018           0 :         if ((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT) ||
    1019           0 :             (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)) {
    1020             :                 /* unexpected SHUTDOWN-ACK... do OOTB handling... */
    1021           0 :                 sctp_send_shutdown_complete(stcb, net, 1);
    1022           0 :                 SCTP_TCB_UNLOCK(stcb);
    1023           0 :                 return;
    1024             :         }
    1025           0 :         if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
    1026           0 :             (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
    1027             :                 /* unexpected SHUTDOWN-ACK... so ignore... */
    1028           0 :                 SCTP_TCB_UNLOCK(stcb);
    1029           0 :                 return;
    1030             :         }
    1031           0 :         if (asoc->control_pdapi) {
    1032             :                 /* With a normal shutdown
    1033             :                  * we assume the end of last record.
    1034             :                  */
    1035           0 :                 SCTP_INP_READ_LOCK(stcb->sctp_ep);
    1036           0 :                 asoc->control_pdapi->end_added = 1;
    1037           0 :                 asoc->control_pdapi->pdapi_aborted = 1;
    1038           0 :                 asoc->control_pdapi = NULL;
    1039           0 :                 SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
    1040             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1041             :                 atomic_add_int(&stcb->asoc.refcnt, 1);
    1042             :                 SCTP_TCB_UNLOCK(stcb);
    1043             :                 SCTP_SOCKET_LOCK(so, 1);
    1044             :                 SCTP_TCB_LOCK(stcb);
    1045             :                 atomic_subtract_int(&stcb->asoc.refcnt, 1);
    1046             :                 if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
    1047             :                         /* assoc was freed while we were unlocked */
    1048             :                         SCTP_SOCKET_UNLOCK(so, 1);
    1049             :                         return;
    1050             :                 }
    1051             : #endif
    1052           0 :                 sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
    1053             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1054             :                 SCTP_SOCKET_UNLOCK(so, 1);
    1055             : #endif
    1056             :         }
    1057             : #ifdef INVARIANTS
    1058             :         if (!TAILQ_EMPTY(&asoc->send_queue) ||
    1059             :             !TAILQ_EMPTY(&asoc->sent_queue) ||
    1060             :             !stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
    1061             :                 panic("Queues are not empty when handling SHUTDOWN-ACK");
    1062             :         }
    1063             : #endif
    1064             :         /* stop the timer */
    1065           0 :         sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_9);
    1066             :         /* send SHUTDOWN-COMPLETE */
    1067           0 :         sctp_send_shutdown_complete(stcb, net, 0);
    1068             :         /* notify upper layer protocol */
    1069           0 :         if (stcb->sctp_socket) {
    1070           0 :                 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
    1071           0 :                     (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
    1072           0 :                         stcb->sctp_socket->so_snd.sb_cc = 0;
    1073             :                 }
    1074           0 :                 sctp_ulp_notify(SCTP_NOTIFY_ASSOC_DOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
    1075             :         }
    1076           0 :         SCTP_STAT_INCR_COUNTER32(sctps_shutdown);
    1077             :         /* free the TCB but first save off the ep */
    1078             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1079             :         atomic_add_int(&stcb->asoc.refcnt, 1);
    1080             :         SCTP_TCB_UNLOCK(stcb);
    1081             :         SCTP_SOCKET_LOCK(so, 1);
    1082             :         SCTP_TCB_LOCK(stcb);
    1083             :         atomic_subtract_int(&stcb->asoc.refcnt, 1);
    1084             : #endif
    1085           0 :         (void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
    1086             :                               SCTP_FROM_SCTP_INPUT+SCTP_LOC_10);
    1087             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1088             :         SCTP_SOCKET_UNLOCK(so, 1);
    1089             : #endif
    1090             : }
    1091             : 
    1092             : /*
    1093             :  * Skip past the param header and then we will find the chunk that caused the
    1094             :  * problem. There are two possiblities ASCONF or FWD-TSN other than that and
    1095             :  * our peer must be broken.
    1096             :  */
    1097             : static void
    1098           0 : sctp_process_unrecog_chunk(struct sctp_tcb *stcb, struct sctp_paramhdr *phdr,
    1099             :     struct sctp_nets *net)
    1100             : {
    1101             :         struct sctp_chunkhdr *chk;
    1102             : 
    1103           0 :         chk = (struct sctp_chunkhdr *)((caddr_t)phdr + sizeof(*phdr));
    1104           0 :         switch (chk->chunk_type) {
    1105             :         case SCTP_ASCONF_ACK:
    1106             :         case SCTP_ASCONF:
    1107           0 :                 sctp_asconf_cleanup(stcb, net);
    1108           0 :                 break;
    1109             :         case SCTP_FORWARD_CUM_TSN:
    1110           0 :                 stcb->asoc.prsctp_supported = 0;
    1111           0 :                 break;
    1112             :         default:
    1113           0 :                 SCTPDBG(SCTP_DEBUG_INPUT2,
    1114             :                         "Peer does not support chunk type %d(%x)??\n",
    1115             :                         chk->chunk_type, (uint32_t) chk->chunk_type);
    1116           0 :                 break;
    1117             :         }
    1118           0 : }
    1119             : 
    1120             : /*
    1121             :  * Skip past the param header and then we will find the param that caused the
    1122             :  * problem.  There are a number of param's in a ASCONF OR the prsctp param
    1123             :  * these will turn of specific features.
    1124             :  * XXX: Is this the right thing to do?
    1125             :  */
    1126             : static void
    1127           0 : sctp_process_unrecog_param(struct sctp_tcb *stcb, struct sctp_paramhdr *phdr)
    1128             : {
    1129             :         struct sctp_paramhdr *pbad;
    1130             : 
    1131           0 :         pbad = phdr + 1;
    1132           0 :         switch (ntohs(pbad->param_type)) {
    1133             :                 /* pr-sctp draft */
    1134             :         case SCTP_PRSCTP_SUPPORTED:
    1135           0 :                 stcb->asoc.prsctp_supported = 0;
    1136           0 :                 break;
    1137             :         case SCTP_SUPPORTED_CHUNK_EXT:
    1138           0 :                 break;
    1139             :                 /* draft-ietf-tsvwg-addip-sctp */
    1140             :         case SCTP_HAS_NAT_SUPPORT:
    1141           0 :                 stcb->asoc.peer_supports_nat = 0;
    1142           0 :                 break;
    1143             :         case SCTP_ADD_IP_ADDRESS:
    1144             :         case SCTP_DEL_IP_ADDRESS:
    1145             :         case SCTP_SET_PRIM_ADDR:
    1146           0 :                 stcb->asoc.asconf_supported = 0;
    1147           0 :                 break;
    1148             :         case SCTP_SUCCESS_REPORT:
    1149             :         case SCTP_ERROR_CAUSE_IND:
    1150           0 :                 SCTPDBG(SCTP_DEBUG_INPUT2, "Huh, the peer does not support success? or error cause?\n");
    1151           0 :                 SCTPDBG(SCTP_DEBUG_INPUT2,
    1152             :                         "Turning off ASCONF to this strange peer\n");
    1153           0 :                 stcb->asoc.asconf_supported = 0;
    1154           0 :                 break;
    1155             :         default:
    1156           0 :                 SCTPDBG(SCTP_DEBUG_INPUT2,
    1157             :                         "Peer does not support param type %d(%x)??\n",
    1158             :                         pbad->param_type, (uint32_t) pbad->param_type);
    1159           0 :                 break;
    1160             :         }
    1161           0 : }
    1162             : 
    1163             : static int
    1164           0 : sctp_handle_error(struct sctp_chunkhdr *ch,
    1165             :     struct sctp_tcb *stcb, struct sctp_nets *net)
    1166             : {
    1167             :         int chklen;
    1168             :         struct sctp_paramhdr *phdr;
    1169             :         uint16_t error, error_type;
    1170             :         uint16_t error_len;
    1171             :         struct sctp_association *asoc;
    1172             :         int adjust;
    1173             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1174             :         struct socket *so;
    1175             : #endif
    1176             : 
    1177             :         /* parse through all of the errors and process */
    1178           0 :         asoc = &stcb->asoc;
    1179           0 :         phdr = (struct sctp_paramhdr *)((caddr_t)ch +
    1180             :             sizeof(struct sctp_chunkhdr));
    1181           0 :         chklen = ntohs(ch->chunk_length) - sizeof(struct sctp_chunkhdr);
    1182           0 :         error = 0;
    1183           0 :         while ((size_t)chklen >= sizeof(struct sctp_paramhdr)) {
    1184             :                 /* Process an Error Cause */
    1185           0 :                 error_type = ntohs(phdr->param_type);
    1186           0 :                 error_len = ntohs(phdr->param_length);
    1187           0 :                 if ((error_len > chklen) || (error_len == 0)) {
    1188             :                         /* invalid param length for this param */
    1189           0 :                         SCTPDBG(SCTP_DEBUG_INPUT1, "Bogus length in error param- chunk left:%d errorlen:%d\n",
    1190             :                                 chklen, error_len);
    1191           0 :                         return (0);
    1192             :                 }
    1193           0 :                 if (error == 0) {
    1194             :                         /* report the first error cause */
    1195           0 :                         error = error_type;
    1196             :                 }
    1197           0 :                 switch (error_type) {
    1198             :                 case SCTP_CAUSE_INVALID_STREAM:
    1199             :                 case SCTP_CAUSE_MISSING_PARAM:
    1200             :                 case SCTP_CAUSE_INVALID_PARAM:
    1201             :                 case SCTP_CAUSE_NO_USER_DATA:
    1202           0 :                         SCTPDBG(SCTP_DEBUG_INPUT1, "Software error we got a %d back? We have a bug :/ (or do they?)\n",
    1203             :                                 error_type);
    1204           0 :                         break;
    1205             :                 case SCTP_CAUSE_NAT_COLLIDING_STATE:
    1206           0 :                         SCTPDBG(SCTP_DEBUG_INPUT2, "Received Colliding state abort flags:%x\n",
    1207             :                                 ch->chunk_flags);
    1208           0 :                         if (sctp_handle_nat_colliding_state(stcb)) {
    1209           0 :                           return (0);
    1210             :                         }
    1211           0 :                         break;
    1212             :                 case SCTP_CAUSE_NAT_MISSING_STATE:
    1213           0 :                         SCTPDBG(SCTP_DEBUG_INPUT2, "Received missing state abort flags:%x\n",
    1214             :                                                    ch->chunk_flags);
    1215           0 :                         if (sctp_handle_nat_missing_state(stcb, net)) {
    1216           0 :                           return (0);
    1217             :                         }
    1218           0 :                         break;
    1219             :                 case SCTP_CAUSE_STALE_COOKIE:
    1220             :                         /*
    1221             :                          * We only act if we have echoed a cookie and are
    1222             :                          * waiting.
    1223             :                          */
    1224           0 :                         if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED) {
    1225             :                                 int *p;
    1226             : 
    1227           0 :                                 p = (int *)((caddr_t)phdr + sizeof(*phdr));
    1228             :                                 /* Save the time doubled */
    1229           0 :                                 asoc->cookie_preserve_req = ntohl(*p) << 1;
    1230           0 :                                 asoc->stale_cookie_count++;
    1231           0 :                                 if (asoc->stale_cookie_count >
    1232           0 :                                     asoc->max_init_times) {
    1233           0 :                                         sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED);
    1234             :                                         /* now free the asoc */
    1235             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1236             :                                         so = SCTP_INP_SO(stcb->sctp_ep);
    1237             :                                         atomic_add_int(&stcb->asoc.refcnt, 1);
    1238             :                                         SCTP_TCB_UNLOCK(stcb);
    1239             :                                         SCTP_SOCKET_LOCK(so, 1);
    1240             :                                         SCTP_TCB_LOCK(stcb);
    1241             :                                         atomic_subtract_int(&stcb->asoc.refcnt, 1);
    1242             : #endif
    1243           0 :                                         (void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
    1244             :                                                               SCTP_FROM_SCTP_INPUT+SCTP_LOC_11);
    1245             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1246             :                                         SCTP_SOCKET_UNLOCK(so, 1);
    1247             : #endif
    1248           0 :                                         return (-1);
    1249             :                                 }
    1250             :                                 /* blast back to INIT state */
    1251           0 :                                 sctp_toss_old_cookies(stcb, &stcb->asoc);
    1252           0 :                                 asoc->state &= ~SCTP_STATE_COOKIE_ECHOED;
    1253           0 :                                 asoc->state |= SCTP_STATE_COOKIE_WAIT;
    1254           0 :                                 sctp_stop_all_cookie_timers(stcb);
    1255           0 :                                 sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
    1256             :                         }
    1257           0 :                         break;
    1258             :                 case SCTP_CAUSE_UNRESOLVABLE_ADDR:
    1259             :                         /*
    1260             :                          * Nothing we can do here, we don't do hostname
    1261             :                          * addresses so if the peer does not like my IPv6
    1262             :                          * (or IPv4 for that matter) it does not matter. If
    1263             :                          * they don't support that type of address, they can
    1264             :                          * NOT possibly get that packet type... i.e. with no
    1265             :                          * IPv6 you can't recieve a IPv6 packet. so we can
    1266             :                          * safely ignore this one. If we ever added support
    1267             :                          * for HOSTNAME Addresses, then we would need to do
    1268             :                          * something here.
    1269             :                          */
    1270           0 :                         break;
    1271             :                 case SCTP_CAUSE_UNRECOG_CHUNK:
    1272           0 :                         sctp_process_unrecog_chunk(stcb, phdr, net);
    1273           0 :                         break;
    1274             :                 case SCTP_CAUSE_UNRECOG_PARAM:
    1275           0 :                         sctp_process_unrecog_param(stcb, phdr);
    1276           0 :                         break;
    1277             :                 case SCTP_CAUSE_COOKIE_IN_SHUTDOWN:
    1278             :                         /*
    1279             :                          * We ignore this since the timer will drive out a
    1280             :                          * new cookie anyway and there timer will drive us
    1281             :                          * to send a SHUTDOWN_COMPLETE. We can't send one
    1282             :                          * here since we don't have their tag.
    1283             :                          */
    1284           0 :                         break;
    1285             :                 case SCTP_CAUSE_DELETING_LAST_ADDR:
    1286             :                 case SCTP_CAUSE_RESOURCE_SHORTAGE:
    1287             :                 case SCTP_CAUSE_DELETING_SRC_ADDR:
    1288             :                         /*
    1289             :                          * We should NOT get these here, but in a
    1290             :                          * ASCONF-ACK.
    1291             :                          */
    1292           0 :                         SCTPDBG(SCTP_DEBUG_INPUT2, "Peer sends ASCONF errors in a Operational Error?<%d>?\n",
    1293             :                                 error_type);
    1294           0 :                         break;
    1295             :                 case SCTP_CAUSE_OUT_OF_RESC:
    1296             :                         /*
    1297             :                          * And what, pray tell do we do with the fact that
    1298             :                          * the peer is out of resources? Not really sure we
    1299             :                          * could do anything but abort. I suspect this
    1300             :                          * should have came WITH an abort instead of in a
    1301             :                          * OP-ERROR.
    1302             :                          */
    1303           0 :                         break;
    1304             :                 default:
    1305           0 :                         SCTPDBG(SCTP_DEBUG_INPUT1, "sctp_handle_error: unknown error type = 0x%xh\n",
    1306             :                                 error_type);
    1307           0 :                         break;
    1308             :                 }
    1309           0 :                 adjust = SCTP_SIZE32(error_len);
    1310           0 :                 chklen -= adjust;
    1311           0 :                 phdr = (struct sctp_paramhdr *)((caddr_t)phdr + adjust);
    1312             :         }
    1313           0 :         sctp_ulp_notify(SCTP_NOTIFY_REMOTE_ERROR, stcb, error, ch, SCTP_SO_NOT_LOCKED);
    1314           0 :         return (0);
    1315             : }
    1316             : 
    1317             : static int
    1318           0 : sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
    1319             :                      struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh,
    1320             :                      struct sctp_init_ack_chunk *cp, struct sctp_tcb *stcb,
    1321             :                      struct sctp_nets *net, int *abort_no_unlock,
    1322             : #if defined(__FreeBSD__)
    1323             :                      uint8_t mflowtype, uint32_t mflowid,
    1324             : #endif
    1325             :                      uint32_t vrf_id)
    1326             : {
    1327             :         struct sctp_init_ack *init_ack;
    1328             :         struct mbuf *op_err;
    1329             : 
    1330           0 :         SCTPDBG(SCTP_DEBUG_INPUT2,
    1331             :                 "sctp_handle_init_ack: handling INIT-ACK\n");
    1332             : 
    1333           0 :         if (stcb == NULL) {
    1334           0 :                 SCTPDBG(SCTP_DEBUG_INPUT2,
    1335             :                         "sctp_handle_init_ack: TCB is null\n");
    1336           0 :                 return (-1);
    1337             :         }
    1338           0 :         if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_ack_chunk)) {
    1339             :                 /* Invalid length */
    1340           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
    1341           0 :                 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
    1342             :                                        src, dst, sh, op_err,
    1343             : #if defined(__FreeBSD__)
    1344             :                                        mflowtype, mflowid,
    1345             : #endif
    1346           0 :                                        vrf_id, net->port);
    1347           0 :                 *abort_no_unlock = 1;
    1348           0 :                 return (-1);
    1349             :         }
    1350           0 :         init_ack = &cp->init;
    1351             :         /* validate parameters */
    1352           0 :         if (init_ack->initiate_tag == 0) {
    1353             :                 /* protocol error... send an abort */
    1354           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
    1355           0 :                 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
    1356             :                                        src, dst, sh, op_err,
    1357             : #if defined(__FreeBSD__)
    1358             :                                        mflowtype, mflowid,
    1359             : #endif
    1360           0 :                                        vrf_id, net->port);
    1361           0 :                 *abort_no_unlock = 1;
    1362           0 :                 return (-1);
    1363             :         }
    1364           0 :         if (ntohl(init_ack->a_rwnd) < SCTP_MIN_RWND) {
    1365             :                 /* protocol error... send an abort */
    1366           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
    1367           0 :                 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
    1368             :                                        src, dst, sh, op_err,
    1369             : #if defined(__FreeBSD__)
    1370             :                                        mflowtype, mflowid,
    1371             : #endif
    1372           0 :                                        vrf_id, net->port);
    1373           0 :                 *abort_no_unlock = 1;
    1374           0 :                 return (-1);
    1375             :         }
    1376           0 :         if (init_ack->num_inbound_streams == 0) {
    1377             :                 /* protocol error... send an abort */
    1378           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
    1379           0 :                 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
    1380             :                                        src, dst, sh, op_err,
    1381             : #if defined(__FreeBSD__)
    1382             :                                        mflowtype, mflowid,
    1383             : #endif
    1384           0 :                                        vrf_id, net->port);
    1385           0 :                 *abort_no_unlock = 1;
    1386           0 :                 return (-1);
    1387             :         }
    1388           0 :         if (init_ack->num_outbound_streams == 0) {
    1389             :                 /* protocol error... send an abort */
    1390           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
    1391           0 :                 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
    1392             :                                        src, dst, sh, op_err,
    1393             : #if defined(__FreeBSD__)
    1394             :                                        mflowtype, mflowid,
    1395             : #endif
    1396           0 :                                        vrf_id, net->port);
    1397           0 :                 *abort_no_unlock = 1;
    1398           0 :                 return (-1);
    1399             :         }
    1400             :         /* process according to association state... */
    1401           0 :         switch (stcb->asoc.state & SCTP_STATE_MASK) {
    1402             :         case SCTP_STATE_COOKIE_WAIT:
    1403             :                 /* this is the expected state for this chunk */
    1404             :                 /* process the INIT-ACK parameters */
    1405           0 :                 if (stcb->asoc.primary_destination->dest_state &
    1406             :                     SCTP_ADDR_UNCONFIRMED) {
    1407             :                         /*
    1408             :                          * The primary is where we sent the INIT, we can
    1409             :                          * always consider it confirmed when the INIT-ACK is
    1410             :                          * returned. Do this before we load addresses
    1411             :                          * though.
    1412             :                          */
    1413           0 :                         stcb->asoc.primary_destination->dest_state &=
    1414             :                             ~SCTP_ADDR_UNCONFIRMED;
    1415           0 :                         sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
    1416           0 :                             stcb, 0, (void *)stcb->asoc.primary_destination, SCTP_SO_NOT_LOCKED);
    1417             :                 }
    1418           0 :                 if (sctp_process_init_ack(m, iphlen, offset, src, dst, sh, cp, stcb,
    1419             :                                           net, abort_no_unlock,
    1420             : #if defined(__FreeBSD__)
    1421             :                                           mflowtype, mflowid,
    1422             : #endif
    1423             :                                           vrf_id) < 0) {
    1424             :                         /* error in parsing parameters */
    1425           0 :                         return (-1);
    1426             :                 }
    1427             :                 /* update our state */
    1428           0 :                 SCTPDBG(SCTP_DEBUG_INPUT2, "moving to COOKIE-ECHOED state\n");
    1429           0 :                 SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_ECHOED);
    1430             : 
    1431             :                 /* reset the RTO calc */
    1432           0 :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
    1433           0 :                         sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    1434             :                                        stcb->asoc.overall_error_count,
    1435             :                                        0,
    1436             :                                        SCTP_FROM_SCTP_INPUT,
    1437             :                                        __LINE__);
    1438             :                 }
    1439           0 :                 stcb->asoc.overall_error_count = 0;
    1440           0 :                 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
    1441             :                 /*
    1442             :                  * collapse the init timer back in case of a exponential
    1443             :                  * backoff
    1444             :                  */
    1445           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_COOKIE, stcb->sctp_ep,
    1446             :                     stcb, net);
    1447             :                 /*
    1448             :                  * the send at the end of the inbound data processing will
    1449             :                  * cause the cookie to be sent
    1450             :                  */
    1451           0 :                 break;
    1452             :         case SCTP_STATE_SHUTDOWN_SENT:
    1453             :                 /* incorrect state... discard */
    1454           0 :                 break;
    1455             :         case SCTP_STATE_COOKIE_ECHOED:
    1456             :                 /* incorrect state... discard */
    1457           0 :                 break;
    1458             :         case SCTP_STATE_OPEN:
    1459             :                 /* incorrect state... discard */
    1460           0 :                 break;
    1461             :         case SCTP_STATE_EMPTY:
    1462             :         case SCTP_STATE_INUSE:
    1463             :         default:
    1464             :                 /* incorrect state... discard */
    1465           0 :                 return (-1);
    1466             :                 break;
    1467             :         }
    1468           0 :         SCTPDBG(SCTP_DEBUG_INPUT1, "Leaving handle-init-ack end\n");
    1469           0 :         return (0);
    1470             : }
    1471             : 
    1472             : static struct sctp_tcb *
    1473             : sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
    1474             :     struct sockaddr *src, struct sockaddr *dst,
    1475             :     struct sctphdr *sh, struct sctp_state_cookie *cookie, int cookie_len,
    1476             :     struct sctp_inpcb *inp, struct sctp_nets **netp,
    1477             :     struct sockaddr *init_src, int *notification,
    1478             :     int auth_skipped, uint32_t auth_offset, uint32_t auth_len,
    1479             : #if defined(__FreeBSD__)
    1480             :     uint8_t mflowtype, uint32_t mflowid,
    1481             : #endif
    1482             :     uint32_t vrf_id, uint16_t port);
    1483             : 
    1484             : 
    1485             : /*
    1486             :  * handle a state cookie for an existing association m: input packet mbuf
    1487             :  * chain-- assumes a pullup on IP/SCTP/COOKIE-ECHO chunk note: this is a
    1488             :  * "split" mbuf and the cookie signature does not exist offset: offset into
    1489             :  * mbuf to the cookie-echo chunk
    1490             :  */
    1491             : static struct sctp_tcb *
    1492           0 : sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
    1493             :     struct sockaddr *src, struct sockaddr *dst,
    1494             :     struct sctphdr *sh, struct sctp_state_cookie *cookie, int cookie_len,
    1495             :     struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets **netp,
    1496             :     struct sockaddr *init_src, int *notification,
    1497             :     int auth_skipped, uint32_t auth_offset, uint32_t auth_len,
    1498             : #if defined(__FreeBSD__)
    1499             :     uint8_t mflowtype, uint32_t mflowid,
    1500             : #endif
    1501             :     uint32_t vrf_id, uint16_t port)
    1502             : {
    1503             :         struct sctp_association *asoc;
    1504             :         struct sctp_init_chunk *init_cp, init_buf;
    1505             :         struct sctp_init_ack_chunk *initack_cp, initack_buf;
    1506             :         struct sctp_nets *net;
    1507             :         struct mbuf *op_err;
    1508             :         int init_offset, initack_offset, i;
    1509             :         int retval;
    1510           0 :         int spec_flag = 0;
    1511             :         uint32_t how_indx;
    1512             : #if defined(SCTP_DETAILED_STR_STATS)
    1513             :         int j;
    1514             : #endif
    1515             : 
    1516           0 :         net = *netp;
    1517             :         /* I know that the TCB is non-NULL from the caller */
    1518           0 :         asoc = &stcb->asoc;
    1519           0 :         for (how_indx = 0; how_indx  < sizeof(asoc->cookie_how); how_indx++) {
    1520           0 :                 if (asoc->cookie_how[how_indx] == 0)
    1521           0 :                         break;
    1522             :         }
    1523           0 :         if (how_indx < sizeof(asoc->cookie_how)) {
    1524           0 :                 asoc->cookie_how[how_indx] = 1;
    1525             :         }
    1526           0 :         if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
    1527             :                 /* SHUTDOWN came in after sending INIT-ACK */
    1528           0 :                 sctp_send_shutdown_ack(stcb, stcb->asoc.primary_destination);
    1529           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_COOKIE_IN_SHUTDOWN, "");
    1530           0 :                 sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err,
    1531             : #if defined(__FreeBSD__)
    1532             :                                    mflowtype, mflowid,
    1533             : #endif
    1534           0 :                                    vrf_id, net->port);
    1535           0 :                 if (how_indx < sizeof(asoc->cookie_how))
    1536           0 :                         asoc->cookie_how[how_indx] = 2;
    1537           0 :                 return (NULL);
    1538             :         }
    1539             :         /*
    1540             :          * find and validate the INIT chunk in the cookie (peer's info) the
    1541             :          * INIT should start after the cookie-echo header struct (chunk
    1542             :          * header, state cookie header struct)
    1543             :          */
    1544           0 :         init_offset = offset += sizeof(struct sctp_cookie_echo_chunk);
    1545             : 
    1546           0 :         init_cp = (struct sctp_init_chunk *)
    1547             :                 sctp_m_getptr(m, init_offset, sizeof(struct sctp_init_chunk),
    1548             :                               (uint8_t *) & init_buf);
    1549           0 :         if (init_cp == NULL) {
    1550             :                 /* could not pull a INIT chunk in cookie */
    1551           0 :                 return (NULL);
    1552             :         }
    1553           0 :         if (init_cp->ch.chunk_type != SCTP_INITIATION) {
    1554           0 :                 return (NULL);
    1555             :         }
    1556             :         /*
    1557             :          * find and validate the INIT-ACK chunk in the cookie (my info) the
    1558             :          * INIT-ACK follows the INIT chunk
    1559             :          */
    1560           0 :         initack_offset = init_offset + SCTP_SIZE32(ntohs(init_cp->ch.chunk_length));
    1561           0 :         initack_cp = (struct sctp_init_ack_chunk *)
    1562             :                 sctp_m_getptr(m, initack_offset, sizeof(struct sctp_init_ack_chunk),
    1563             :                               (uint8_t *) & initack_buf);
    1564           0 :         if (initack_cp == NULL) {
    1565             :                 /* could not pull INIT-ACK chunk in cookie */
    1566           0 :                 return (NULL);
    1567             :         }
    1568           0 :         if (initack_cp->ch.chunk_type != SCTP_INITIATION_ACK) {
    1569           0 :                 return (NULL);
    1570             :         }
    1571           0 :         if ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) &&
    1572           0 :             (ntohl(init_cp->init.initiate_tag) == asoc->peer_vtag)) {
    1573             :                 /*
    1574             :                  * case D in Section 5.2.4 Table 2: MMAA process accordingly
    1575             :                  * to get into the OPEN state
    1576             :                  */
    1577           0 :                 if (ntohl(initack_cp->init.initial_tsn) != asoc->init_seq_number) {
    1578             :                         /*-
    1579             :                          * Opps, this means that we somehow generated two vtag's
    1580             :                          * the same. I.e. we did:
    1581             :                          *  Us               Peer
    1582             :                          *   <---INIT(tag=a)------
    1583             :                          *   ----INIT-ACK(tag=t)-->
    1584             :                          *   ----INIT(tag=t)------> *1
    1585             :                          *   <---INIT-ACK(tag=a)---
    1586             :                          *   <----CE(tag=t)------------- *2
    1587             :                          *
    1588             :                          * At point *1 we should be generating a different
    1589             :                          * tag t'. Which means we would throw away the CE and send
    1590             :                          * ours instead. Basically this is case C (throw away side).
    1591             :                          */
    1592           0 :                         if (how_indx < sizeof(asoc->cookie_how))
    1593           0 :                                 asoc->cookie_how[how_indx] = 17;
    1594           0 :                         return (NULL);
    1595             : 
    1596             :                 }
    1597           0 :                 switch (SCTP_GET_STATE(asoc)) {
    1598             :                         case SCTP_STATE_COOKIE_WAIT:
    1599             :                         case SCTP_STATE_COOKIE_ECHOED:
    1600             :                                 /*
    1601             :                                  * INIT was sent but got a COOKIE_ECHO with the
    1602             :                                  * correct tags... just accept it...but we must
    1603             :                                  * process the init so that we can make sure we
    1604             :                                  * have the right seq no's.
    1605             :                                  */
    1606             :                                 /* First we must process the INIT !! */
    1607           0 :                                 retval = sctp_process_init(init_cp, stcb);
    1608           0 :                                 if (retval < 0) {
    1609           0 :                                         if (how_indx < sizeof(asoc->cookie_how))
    1610           0 :                                                 asoc->cookie_how[how_indx] = 3;
    1611           0 :                                         return (NULL);
    1612             :                                 }
    1613             :                                 /* we have already processed the INIT so no problem */
    1614           0 :                                 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb,
    1615             :                                                 net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_12);
    1616           0 :                                 sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_13);
    1617             :                                 /* update current state */
    1618           0 :                                 if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)
    1619           0 :                                         SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
    1620             :                                 else
    1621           0 :                                         SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
    1622             : 
    1623           0 :                                 SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
    1624           0 :                                 if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
    1625           0 :                                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
    1626             :                                                          stcb->sctp_ep, stcb, asoc->primary_destination);
    1627             :                                 }
    1628           0 :                                 SCTP_STAT_INCR_GAUGE32(sctps_currestab);
    1629           0 :                                 sctp_stop_all_cookie_timers(stcb);
    1630           0 :                                 if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
    1631           0 :                                      (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
    1632           0 :                                     (inp->sctp_socket->so_qlimit == 0)
    1633             :                                         ) {
    1634             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1635             :                                         struct socket *so;
    1636             : #endif
    1637             :                                         /*
    1638             :                                          * Here is where collision would go if we
    1639             :                                          * did a connect() and instead got a
    1640             :                                          * init/init-ack/cookie done before the
    1641             :                                          * init-ack came back..
    1642             :                                          */
    1643           0 :                                         stcb->sctp_ep->sctp_flags |=
    1644             :                                                 SCTP_PCB_FLAGS_CONNECTED;
    1645             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1646             :                                         so = SCTP_INP_SO(stcb->sctp_ep);
    1647             :                                         atomic_add_int(&stcb->asoc.refcnt, 1);
    1648             :                                         SCTP_TCB_UNLOCK(stcb);
    1649             :                                         SCTP_SOCKET_LOCK(so, 1);
    1650             :                                         SCTP_TCB_LOCK(stcb);
    1651             :                                         atomic_add_int(&stcb->asoc.refcnt, -1);
    1652             :                                         if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
    1653             :                                                 SCTP_SOCKET_UNLOCK(so, 1);
    1654             :                                                 return (NULL);
    1655             :                                         }
    1656             : #endif
    1657           0 :                                         soisconnected(stcb->sctp_socket);
    1658             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1659             :                                         SCTP_SOCKET_UNLOCK(so, 1);
    1660             : #endif
    1661             :                                 }
    1662             :                                 /* notify upper layer */
    1663           0 :                                 *notification = SCTP_NOTIFY_ASSOC_UP;
    1664             :                                 /*
    1665             :                                  * since we did not send a HB make sure we
    1666             :                                  * don't double things
    1667             :                                  */
    1668           0 :                                 net->hb_responded = 1;
    1669           0 :                                 net->RTO = sctp_calculate_rto(stcb, asoc, net,
    1670             :                                                               &cookie->time_entered,
    1671             :                                                               sctp_align_unsafe_makecopy,
    1672             :                                                               SCTP_RTT_FROM_NON_DATA);
    1673             : 
    1674           0 :                                 if (stcb->asoc.sctp_autoclose_ticks &&
    1675           0 :                                     (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE))) {
    1676           0 :                                         sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE,
    1677             :                                                          inp, stcb, NULL);
    1678             :                                 }
    1679           0 :                                 break;
    1680             :                         default:
    1681             :                                 /*
    1682             :                                  * we're in the OPEN state (or beyond), so
    1683             :                                  * peer must have simply lost the COOKIE-ACK
    1684             :                                  */
    1685           0 :                                 break;
    1686             :                 }       /* end switch */
    1687           0 :                 sctp_stop_all_cookie_timers(stcb);
    1688             :                 /*
    1689             :                  * We ignore the return code here.. not sure if we should
    1690             :                  * somehow abort.. but we do have an existing asoc. This
    1691             :                  * really should not fail.
    1692             :                  */
    1693           0 :                 if (sctp_load_addresses_from_init(stcb, m,
    1694           0 :                                                   init_offset + sizeof(struct sctp_init_chunk),
    1695             :                                                   initack_offset, src, dst, init_src)) {
    1696           0 :                         if (how_indx < sizeof(asoc->cookie_how))
    1697           0 :                                 asoc->cookie_how[how_indx] = 4;
    1698           0 :                         return (NULL);
    1699             :                 }
    1700             :                 /* respond with a COOKIE-ACK */
    1701           0 :                 sctp_toss_old_cookies(stcb, asoc);
    1702           0 :                 sctp_send_cookie_ack(stcb);
    1703           0 :                 if (how_indx < sizeof(asoc->cookie_how))
    1704           0 :                         asoc->cookie_how[how_indx] = 5;
    1705           0 :                 return (stcb);
    1706             :         }
    1707             : 
    1708           0 :         if (ntohl(initack_cp->init.initiate_tag) != asoc->my_vtag &&
    1709           0 :             ntohl(init_cp->init.initiate_tag) == asoc->peer_vtag &&
    1710           0 :             cookie->tie_tag_my_vtag == 0 &&
    1711           0 :             cookie->tie_tag_peer_vtag == 0) {
    1712             :                 /*
    1713             :                  * case C in Section 5.2.4 Table 2: XMOO silently discard
    1714             :                  */
    1715           0 :                 if (how_indx < sizeof(asoc->cookie_how))
    1716           0 :                         asoc->cookie_how[how_indx] = 6;
    1717           0 :                 return (NULL);
    1718             :         }
    1719             :         /* If nat support, and the below and stcb is established,
    1720             :          * send back a ABORT(colliding state) if we are established.
    1721             :          */
    1722           0 :         if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN)  &&
    1723           0 :             (asoc->peer_supports_nat) &&
    1724           0 :             ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) &&
    1725           0 :             ((ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) ||
    1726           0 :              (asoc->peer_vtag == 0)))) {
    1727             :                 /* Special case - Peer's support nat. We may have
    1728             :                  * two init's that we gave out the same tag on since
    1729             :                  * one was not established.. i.e. we get INIT from host-1
    1730             :                  * behind the nat and we respond tag-a, we get a INIT from
    1731             :                  * host-2 behind the nat and we get tag-a again. Then we
    1732             :                  * bring up host-1 (or 2's) assoc, Then comes the cookie
    1733             :                  * from hsot-2 (or 1). Now we have colliding state. We must
    1734             :                  * send an abort here with colliding state indication.
    1735             :                  */
    1736           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_NAT_COLLIDING_STATE, "");
    1737           0 :                 sctp_send_abort(m, iphlen,  src, dst, sh, 0, op_err,
    1738             : #if defined(__FreeBSD__)
    1739             :                                 mflowtype, mflowid,
    1740             : #endif
    1741             :                                 vrf_id, port);
    1742           0 :                 return (NULL);
    1743             :         }
    1744           0 :         if ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) &&
    1745           0 :             ((ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) ||
    1746           0 :              (asoc->peer_vtag == 0))) {
    1747             :                 /*
    1748             :                  * case B in Section 5.2.4 Table 2: MXAA or MOAA my info
    1749             :                  * should be ok, re-accept peer info
    1750             :                  */
    1751           0 :                 if (ntohl(initack_cp->init.initial_tsn) != asoc->init_seq_number) {
    1752             :                         /* Extension of case C.
    1753             :                          * If we hit this, then the random number
    1754             :                          * generator returned the same vtag when we
    1755             :                          * first sent our INIT-ACK and when we later sent
    1756             :                          * our INIT. The side with the seq numbers that are
    1757             :                          * different will be the one that normnally would
    1758             :                          * have hit case C. This in effect "extends" our vtags
    1759             :                          * in this collision case to be 64 bits. The same collision
    1760             :                          * could occur aka you get both vtag and seq number the
    1761             :                          * same twice in a row.. but is much less likely. If it
    1762             :                          * did happen then we would proceed through and bring
    1763             :                          * up the assoc.. we may end up with the wrong stream
    1764             :                          * setup however.. which would be bad.. but there is
    1765             :                          * no way to tell.. until we send on a stream that does
    1766             :                          * not exist :-)
    1767             :                          */
    1768           0 :                         if (how_indx < sizeof(asoc->cookie_how))
    1769           0 :                                 asoc->cookie_how[how_indx] = 7;
    1770             : 
    1771           0 :                         return (NULL);
    1772             :                 }
    1773           0 :                 if (how_indx < sizeof(asoc->cookie_how))
    1774           0 :                         asoc->cookie_how[how_indx] = 8;
    1775           0 :                 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_14);
    1776           0 :                 sctp_stop_all_cookie_timers(stcb);
    1777             :                 /*
    1778             :                  * since we did not send a HB make sure we don't double
    1779             :                  * things
    1780             :                  */
    1781           0 :                 net->hb_responded = 1;
    1782           0 :                 if (stcb->asoc.sctp_autoclose_ticks &&
    1783           0 :                     sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) {
    1784           0 :                         sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb,
    1785             :                                          NULL);
    1786             :                 }
    1787           0 :                 asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
    1788           0 :                 asoc->pre_open_streams = ntohs(initack_cp->init.num_outbound_streams);
    1789             : 
    1790           0 :                 if (ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) {
    1791             :                         /* Ok the peer probably discarded our
    1792             :                          * data (if we echoed a cookie+data). So anything
    1793             :                          * on the sent_queue should be marked for
    1794             :                          * retransmit, we may not get something to
    1795             :                          * kick us so it COULD still take a timeout
    1796             :                          * to move these.. but it can't hurt to mark them.
    1797             :                          */
    1798             :                         struct sctp_tmit_chunk *chk;
    1799           0 :                         TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
    1800           0 :                                 if (chk->sent < SCTP_DATAGRAM_RESEND) {
    1801           0 :                                         chk->sent = SCTP_DATAGRAM_RESEND;
    1802           0 :                                         sctp_flight_size_decrease(chk);
    1803           0 :                                         sctp_total_flight_decrease(stcb, chk);
    1804           0 :                                         sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
    1805           0 :                                         spec_flag++;
    1806             :                                 }
    1807             :                         }
    1808             : 
    1809             :                 }
    1810             :                 /* process the INIT info (peer's info) */
    1811           0 :                 retval = sctp_process_init(init_cp, stcb);
    1812           0 :                 if (retval < 0) {
    1813           0 :                         if (how_indx < sizeof(asoc->cookie_how))
    1814           0 :                                 asoc->cookie_how[how_indx] = 9;
    1815           0 :                         return (NULL);
    1816             :                 }
    1817           0 :                 if (sctp_load_addresses_from_init(stcb, m,
    1818           0 :                                                   init_offset + sizeof(struct sctp_init_chunk),
    1819             :                                                   initack_offset, src, dst, init_src)) {
    1820           0 :                         if (how_indx < sizeof(asoc->cookie_how))
    1821           0 :                                 asoc->cookie_how[how_indx] = 10;
    1822           0 :                         return (NULL);
    1823             :                 }
    1824           0 :                 if ((asoc->state & SCTP_STATE_COOKIE_WAIT) ||
    1825           0 :                     (asoc->state & SCTP_STATE_COOKIE_ECHOED)) {
    1826           0 :                         *notification = SCTP_NOTIFY_ASSOC_UP;
    1827             : 
    1828           0 :                         if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
    1829           0 :                              (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
    1830           0 :                             (inp->sctp_socket->so_qlimit == 0)) {
    1831             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1832             :                                 struct socket *so;
    1833             : #endif
    1834           0 :                                 stcb->sctp_ep->sctp_flags |=
    1835             :                                         SCTP_PCB_FLAGS_CONNECTED;
    1836             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1837             :                                 so = SCTP_INP_SO(stcb->sctp_ep);
    1838             :                                 atomic_add_int(&stcb->asoc.refcnt, 1);
    1839             :                                 SCTP_TCB_UNLOCK(stcb);
    1840             :                                 SCTP_SOCKET_LOCK(so, 1);
    1841             :                                 SCTP_TCB_LOCK(stcb);
    1842             :                                 atomic_add_int(&stcb->asoc.refcnt, -1);
    1843             :                                 if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
    1844             :                                         SCTP_SOCKET_UNLOCK(so, 1);
    1845             :                                         return (NULL);
    1846             :                                 }
    1847             : #endif
    1848           0 :                                 soisconnected(stcb->sctp_socket);
    1849             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1850             :                                 SCTP_SOCKET_UNLOCK(so, 1);
    1851             : #endif
    1852             :                         }
    1853           0 :                         if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)
    1854           0 :                                 SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
    1855             :                         else
    1856           0 :                                 SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
    1857           0 :                         SCTP_STAT_INCR_GAUGE32(sctps_currestab);
    1858           0 :                 } else if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
    1859           0 :                         SCTP_STAT_INCR_COUNTER32(sctps_restartestab);
    1860             :                 } else {
    1861           0 :                         SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
    1862             :                 }
    1863           0 :                 SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
    1864           0 :                 if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
    1865           0 :                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
    1866             :                                          stcb->sctp_ep, stcb, asoc->primary_destination);
    1867             :                 }
    1868           0 :                 sctp_stop_all_cookie_timers(stcb);
    1869           0 :                 sctp_toss_old_cookies(stcb, asoc);
    1870           0 :                 sctp_send_cookie_ack(stcb);
    1871           0 :                 if (spec_flag) {
    1872             :                         /* only if we have retrans set do we do this. What
    1873             :                          * this call does is get only the COOKIE-ACK out
    1874             :                          * and then when we return the normal call to
    1875             :                          * sctp_chunk_output will get the retrans out
    1876             :                          * behind this.
    1877             :                          */
    1878           0 :                         sctp_chunk_output(inp,stcb, SCTP_OUTPUT_FROM_COOKIE_ACK, SCTP_SO_NOT_LOCKED);
    1879             :                 }
    1880           0 :                 if (how_indx < sizeof(asoc->cookie_how))
    1881           0 :                         asoc->cookie_how[how_indx] = 11;
    1882             : 
    1883           0 :                 return (stcb);
    1884             :         }
    1885           0 :         if ((ntohl(initack_cp->init.initiate_tag) != asoc->my_vtag &&
    1886           0 :              ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) &&
    1887           0 :             cookie->tie_tag_my_vtag == asoc->my_vtag_nonce &&
    1888           0 :             cookie->tie_tag_peer_vtag == asoc->peer_vtag_nonce &&
    1889           0 :             cookie->tie_tag_peer_vtag != 0) {
    1890             :                 struct sctpasochead *head;
    1891             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1892             :                 struct socket *so;
    1893             : #endif
    1894             : 
    1895           0 :                 if (asoc->peer_supports_nat) {
    1896             :                         /* This is a gross gross hack.
    1897             :                          * Just call the cookie_new code since we
    1898             :                          * are allowing a duplicate association.
    1899             :                          * I hope this works...
    1900             :                          */
    1901           0 :                         return (sctp_process_cookie_new(m, iphlen, offset, src, dst,
    1902             :                                                         sh, cookie, cookie_len,
    1903             :                                                         inp, netp, init_src,notification,
    1904             :                                                         auth_skipped, auth_offset, auth_len,
    1905             : #if defined(__FreeBSD__)
    1906             :                                                         mflowtype, mflowid,
    1907             : #endif
    1908             :                                                         vrf_id, port));
    1909             :                 }
    1910             :                 /*
    1911             :                  * case A in Section 5.2.4 Table 2: XXMM (peer restarted)
    1912             :                  */
    1913             :                 /* temp code */
    1914           0 :                 if (how_indx < sizeof(asoc->cookie_how))
    1915           0 :                         asoc->cookie_how[how_indx] = 12;
    1916           0 :                 sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_15);
    1917           0 :                 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_16);
    1918             : 
    1919             :                 /* notify upper layer */
    1920           0 :                 *notification = SCTP_NOTIFY_ASSOC_RESTART;
    1921           0 :                 atomic_add_int(&stcb->asoc.refcnt, 1);
    1922           0 :                 if ((SCTP_GET_STATE(asoc) != SCTP_STATE_OPEN) &&
    1923           0 :                     (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
    1924           0 :                     (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT)) {
    1925           0 :                         SCTP_STAT_INCR_GAUGE32(sctps_currestab);
    1926             :                 }
    1927           0 :                 if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
    1928           0 :                         SCTP_STAT_INCR_GAUGE32(sctps_restartestab);
    1929           0 :                 } else if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) {
    1930           0 :                         SCTP_STAT_INCR_GAUGE32(sctps_collisionestab);
    1931             :                 }
    1932           0 :                 if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
    1933           0 :                         SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
    1934           0 :                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
    1935             :                                          stcb->sctp_ep, stcb, asoc->primary_destination);
    1936             : 
    1937           0 :                 } else if (!(asoc->state & SCTP_STATE_SHUTDOWN_SENT)) {
    1938             :                         /* move to OPEN state, if not in SHUTDOWN_SENT */
    1939           0 :                         SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
    1940             :                 }
    1941           0 :                 asoc->pre_open_streams =
    1942           0 :                         ntohs(initack_cp->init.num_outbound_streams);
    1943           0 :                 asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
    1944           0 :                 asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
    1945           0 :                 asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
    1946             : 
    1947           0 :                 asoc->asconf_seq_in = asoc->last_acked_seq = asoc->init_seq_number - 1;
    1948             : 
    1949           0 :                 asoc->str_reset_seq_in = asoc->init_seq_number;
    1950             : 
    1951           0 :                 asoc->advanced_peer_ack_point = asoc->last_acked_seq;
    1952           0 :                 if (asoc->mapping_array) {
    1953           0 :                         memset(asoc->mapping_array, 0,
    1954           0 :                                asoc->mapping_array_size);
    1955             :                 }
    1956           0 :                 if (asoc->nr_mapping_array) {
    1957           0 :                         memset(asoc->nr_mapping_array, 0,
    1958           0 :                             asoc->mapping_array_size);
    1959             :                 }
    1960           0 :                 SCTP_TCB_UNLOCK(stcb);
    1961             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    1962             :                 so = SCTP_INP_SO(stcb->sctp_ep);
    1963             :                 SCTP_SOCKET_LOCK(so, 1);
    1964             : #endif
    1965           0 :                 SCTP_INP_INFO_WLOCK();
    1966           0 :                 SCTP_INP_WLOCK(stcb->sctp_ep);
    1967           0 :                 SCTP_TCB_LOCK(stcb);
    1968           0 :                 atomic_add_int(&stcb->asoc.refcnt, -1);
    1969             :                 /* send up all the data */
    1970           0 :                 SCTP_TCB_SEND_LOCK(stcb);
    1971             : 
    1972           0 :                 sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_LOCKED);
    1973           0 :                 for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
    1974           0 :                         stcb->asoc.strmout[i].chunks_on_queues = 0;
    1975             : #if defined(SCTP_DETAILED_STR_STATS)
    1976             :                         for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) {
    1977             :                                 asoc->strmout[i].abandoned_sent[j] = 0;
    1978             :                                 asoc->strmout[i].abandoned_unsent[j] = 0;
    1979             :                         }
    1980             : #else
    1981           0 :                         asoc->strmout[i].abandoned_sent[0] = 0;
    1982           0 :                         asoc->strmout[i].abandoned_unsent[0] = 0;
    1983             : #endif
    1984           0 :                         stcb->asoc.strmout[i].stream_no = i;
    1985           0 :                         stcb->asoc.strmout[i].next_sequence_send = 0;
    1986           0 :                         stcb->asoc.strmout[i].last_msg_incomplete = 0;
    1987             :                 }
    1988             :                 /* process the INIT-ACK info (my info) */
    1989           0 :                 asoc->my_vtag = ntohl(initack_cp->init.initiate_tag);
    1990           0 :                 asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
    1991             : 
    1992             :                 /* pull from vtag hash */
    1993           0 :                 LIST_REMOVE(stcb, sctp_asocs);
    1994             :                 /* re-insert to new vtag position */
    1995           0 :                 head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag,
    1996             :                                                                     SCTP_BASE_INFO(hashasocmark))];
    1997             :                 /*
    1998             :                  * put it in the bucket in the vtag hash of assoc's for the
    1999             :                  * system
    2000             :                  */
    2001           0 :                 LIST_INSERT_HEAD(head, stcb, sctp_asocs);
    2002             : 
    2003           0 :                 SCTP_TCB_SEND_UNLOCK(stcb);
    2004           0 :                 SCTP_INP_WUNLOCK(stcb->sctp_ep);
    2005           0 :                 SCTP_INP_INFO_WUNLOCK();
    2006             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2007             :                 SCTP_SOCKET_UNLOCK(so, 1);
    2008             : #endif
    2009           0 :                 asoc->total_flight = 0;
    2010           0 :                 asoc->total_flight_count = 0;
    2011             :                 /* process the INIT info (peer's info) */
    2012           0 :                 retval = sctp_process_init(init_cp, stcb);
    2013           0 :                 if (retval < 0) {
    2014           0 :                         if (how_indx < sizeof(asoc->cookie_how))
    2015           0 :                                 asoc->cookie_how[how_indx] = 13;
    2016             : 
    2017           0 :                         return (NULL);
    2018             :                 }
    2019             :                 /*
    2020             :                  * since we did not send a HB make sure we don't double
    2021             :                  * things
    2022             :                  */
    2023           0 :                 net->hb_responded = 1;
    2024             : 
    2025           0 :                 if (sctp_load_addresses_from_init(stcb, m,
    2026           0 :                                                   init_offset + sizeof(struct sctp_init_chunk),
    2027             :                                                   initack_offset, src, dst, init_src)) {
    2028           0 :                         if (how_indx < sizeof(asoc->cookie_how))
    2029           0 :                                 asoc->cookie_how[how_indx] = 14;
    2030             : 
    2031           0 :                         return (NULL);
    2032             :                 }
    2033             :                 /* respond with a COOKIE-ACK */
    2034           0 :                 sctp_stop_all_cookie_timers(stcb);
    2035           0 :                 sctp_toss_old_cookies(stcb, asoc);
    2036           0 :                 sctp_send_cookie_ack(stcb);
    2037           0 :                 if (how_indx < sizeof(asoc->cookie_how))
    2038           0 :                         asoc->cookie_how[how_indx] = 15;
    2039             : 
    2040           0 :                 return (stcb);
    2041             :         }
    2042           0 :         if (how_indx < sizeof(asoc->cookie_how))
    2043           0 :                 asoc->cookie_how[how_indx] = 16;
    2044             :         /* all other cases... */
    2045           0 :         return (NULL);
    2046             : }
    2047             : 
    2048             : 
    2049             : /*
    2050             :  * handle a state cookie for a new association m: input packet mbuf chain--
    2051             :  * assumes a pullup on IP/SCTP/COOKIE-ECHO chunk note: this is a "split" mbuf
    2052             :  * and the cookie signature does not exist offset: offset into mbuf to the
    2053             :  * cookie-echo chunk length: length of the cookie chunk to: where the init
    2054             :  * was from returns a new TCB
    2055             :  */
    2056             : static struct sctp_tcb *
    2057           0 : sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
    2058             :     struct sockaddr *src, struct sockaddr *dst,
    2059             :     struct sctphdr *sh, struct sctp_state_cookie *cookie, int cookie_len,
    2060             :     struct sctp_inpcb *inp, struct sctp_nets **netp,
    2061             :     struct sockaddr *init_src, int *notification,
    2062             :     int auth_skipped, uint32_t auth_offset, uint32_t auth_len,
    2063             : #if defined(__FreeBSD__)
    2064             :     uint8_t mflowtype, uint32_t mflowid,
    2065             : #endif
    2066             :     uint32_t vrf_id, uint16_t port)
    2067             : {
    2068             :         struct sctp_tcb *stcb;
    2069             :         struct sctp_init_chunk *init_cp, init_buf;
    2070             :         struct sctp_init_ack_chunk *initack_cp, initack_buf;
    2071             :         union sctp_sockstore store;
    2072             :         struct sctp_association *asoc;
    2073             :         int init_offset, initack_offset, initack_limit;
    2074             :         int retval;
    2075           0 :         int error = 0;
    2076             :         uint8_t auth_chunk_buf[SCTP_PARAM_BUFFER_SIZE];
    2077             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2078             :         struct socket *so;
    2079             : 
    2080             :         so = SCTP_INP_SO(inp);
    2081             : #endif
    2082             : 
    2083             :         /*
    2084             :          * find and validate the INIT chunk in the cookie (peer's info) the
    2085             :          * INIT should start after the cookie-echo header struct (chunk
    2086             :          * header, state cookie header struct)
    2087             :          */
    2088           0 :         init_offset = offset + sizeof(struct sctp_cookie_echo_chunk);
    2089           0 :         init_cp = (struct sctp_init_chunk *)
    2090             :             sctp_m_getptr(m, init_offset, sizeof(struct sctp_init_chunk),
    2091             :             (uint8_t *) & init_buf);
    2092           0 :         if (init_cp == NULL) {
    2093             :                 /* could not pull a INIT chunk in cookie */
    2094           0 :                 SCTPDBG(SCTP_DEBUG_INPUT1,
    2095             :                         "process_cookie_new: could not pull INIT chunk hdr\n");
    2096           0 :                 return (NULL);
    2097             :         }
    2098           0 :         if (init_cp->ch.chunk_type != SCTP_INITIATION) {
    2099           0 :                 SCTPDBG(SCTP_DEBUG_INPUT1, "HUH? process_cookie_new: could not find INIT chunk!\n");
    2100           0 :                 return (NULL);
    2101             :         }
    2102           0 :         initack_offset = init_offset + SCTP_SIZE32(ntohs(init_cp->ch.chunk_length));
    2103             :         /*
    2104             :          * find and validate the INIT-ACK chunk in the cookie (my info) the
    2105             :          * INIT-ACK follows the INIT chunk
    2106             :          */
    2107           0 :         initack_cp = (struct sctp_init_ack_chunk *)
    2108             :             sctp_m_getptr(m, initack_offset, sizeof(struct sctp_init_ack_chunk),
    2109             :             (uint8_t *) & initack_buf);
    2110           0 :         if (initack_cp == NULL) {
    2111             :                 /* could not pull INIT-ACK chunk in cookie */
    2112           0 :                 SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: could not pull INIT-ACK chunk hdr\n");
    2113           0 :                 return (NULL);
    2114             :         }
    2115           0 :         if (initack_cp->ch.chunk_type != SCTP_INITIATION_ACK) {
    2116           0 :                 return (NULL);
    2117             :         }
    2118             :         /*
    2119             :          * NOTE: We can't use the INIT_ACK's chk_length to determine the
    2120             :          * "initack_limit" value.  This is because the chk_length field
    2121             :          * includes the length of the cookie, but the cookie is omitted when
    2122             :          * the INIT and INIT_ACK are tacked onto the cookie...
    2123             :          */
    2124           0 :         initack_limit = offset + cookie_len;
    2125             : 
    2126             :         /*
    2127             :          * now that we know the INIT/INIT-ACK are in place, create a new TCB
    2128             :          * and popluate
    2129             :          */
    2130             : 
    2131             :         /*
    2132             :          * Here we do a trick, we set in NULL for the proc/thread argument. We
    2133             :          * do this since in effect we only use the p argument when
    2134             :          * the socket is unbound and we must do an implicit bind.
    2135             :          * Since we are getting a cookie, we cannot be unbound.
    2136             :          */
    2137           0 :         stcb = sctp_aloc_assoc(inp, init_src, &error,
    2138             :                                ntohl(initack_cp->init.initiate_tag), vrf_id,
    2139             : #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
    2140             :                                (struct thread *)NULL
    2141             : #elif defined(__Windows__)
    2142             :                                (PKTHREAD)NULL
    2143             : #else
    2144             :                                (struct proc *)NULL
    2145             : #endif
    2146             :                                );
    2147           0 :         if (stcb == NULL) {
    2148             :                 struct mbuf *op_err;
    2149             : 
    2150             :                 /* memory problem? */
    2151           0 :                 SCTPDBG(SCTP_DEBUG_INPUT1,
    2152             :                         "process_cookie_new: no room for another TCB!\n");
    2153           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
    2154           0 :                 sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen,
    2155             :                                        src, dst, sh, op_err,
    2156             : #if defined(__FreeBSD__)
    2157             :                                        mflowtype, mflowid,
    2158             : #endif
    2159             :                                        vrf_id, port);
    2160           0 :                 return (NULL);
    2161             :         }
    2162             :         /* get the correct sctp_nets */
    2163           0 :         if (netp)
    2164           0 :                 *netp = sctp_findnet(stcb, init_src);
    2165             : 
    2166           0 :         asoc = &stcb->asoc;
    2167             :         /* get scope variables out of cookie */
    2168           0 :         asoc->scope.ipv4_local_scope = cookie->ipv4_scope;
    2169           0 :         asoc->scope.site_scope = cookie->site_scope;
    2170           0 :         asoc->scope.local_scope = cookie->local_scope;
    2171           0 :         asoc->scope.loopback_scope = cookie->loopback_scope;
    2172             : 
    2173             : #if defined(__Userspace__)
    2174           0 :         if ((asoc->scope.ipv4_addr_legal != cookie->ipv4_addr_legal) ||
    2175           0 :             (asoc->scope.ipv6_addr_legal != cookie->ipv6_addr_legal) ||
    2176           0 :             (asoc->scope.conn_addr_legal != cookie->conn_addr_legal)) {
    2177             : #else
    2178             :         if ((asoc->scope.ipv4_addr_legal != cookie->ipv4_addr_legal) ||
    2179             :             (asoc->scope.ipv6_addr_legal != cookie->ipv6_addr_legal)) {
    2180             : #endif
    2181             :                 struct mbuf *op_err;
    2182             : 
    2183             :                 /*
    2184             :                  * Houston we have a problem. The EP changed while the
    2185             :                  * cookie was in flight. Only recourse is to abort the
    2186             :                  * association.
    2187             :                  */
    2188           0 :                 atomic_add_int(&stcb->asoc.refcnt, 1);
    2189           0 :                 op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
    2190           0 :                 sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen,
    2191             :                                        src, dst, sh, op_err,
    2192             : #if defined(__FreeBSD__)
    2193             :                                        mflowtype, mflowid,
    2194             : #endif
    2195             :                                        vrf_id, port);
    2196             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2197             :                 SCTP_TCB_UNLOCK(stcb);
    2198             :                 SCTP_SOCKET_LOCK(so, 1);
    2199             :                 SCTP_TCB_LOCK(stcb);
    2200             : #endif
    2201           0 :                 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
    2202             :                                       SCTP_FROM_SCTP_INPUT+SCTP_LOC_16);
    2203             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2204             :                 SCTP_SOCKET_UNLOCK(so, 1);
    2205             : #endif
    2206           0 :                 atomic_subtract_int(&stcb->asoc.refcnt, 1);
    2207           0 :                 return (NULL);
    2208             :         }
    2209             :         /* process the INIT-ACK info (my info) */
    2210           0 :         asoc->my_vtag = ntohl(initack_cp->init.initiate_tag);
    2211           0 :         asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
    2212           0 :         asoc->pre_open_streams = ntohs(initack_cp->init.num_outbound_streams);
    2213           0 :         asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
    2214           0 :         asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
    2215           0 :         asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
    2216           0 :         asoc->asconf_seq_in = asoc->last_acked_seq = asoc->init_seq_number - 1;
    2217           0 :         asoc->str_reset_seq_in = asoc->init_seq_number;
    2218             : 
    2219           0 :         asoc->advanced_peer_ack_point = asoc->last_acked_seq;
    2220             : 
    2221             :         /* process the INIT info (peer's info) */
    2222           0 :         if (netp)
    2223           0 :                 retval = sctp_process_init(init_cp, stcb);
    2224             :         else
    2225           0 :                 retval = 0;
    2226           0 :         if (retval < 0) {
    2227           0 :                 atomic_add_int(&stcb->asoc.refcnt, 1);
    2228             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2229             :                 SCTP_TCB_UNLOCK(stcb);
    2230             :                 SCTP_SOCKET_LOCK(so, 1);
    2231             :                 SCTP_TCB_LOCK(stcb);
    2232             : #endif
    2233           0 :                 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_16);
    2234             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2235             :                 SCTP_SOCKET_UNLOCK(so, 1);
    2236             : #endif
    2237           0 :                 atomic_subtract_int(&stcb->asoc.refcnt, 1);
    2238           0 :                 return (NULL);
    2239             :         }
    2240             :         /* load all addresses */
    2241           0 :         if (sctp_load_addresses_from_init(stcb, m,
    2242           0 :             init_offset + sizeof(struct sctp_init_chunk), initack_offset,
    2243             :             src, dst, init_src)) {
    2244           0 :                 atomic_add_int(&stcb->asoc.refcnt, 1);
    2245             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2246             :                 SCTP_TCB_UNLOCK(stcb);
    2247             :                 SCTP_SOCKET_LOCK(so, 1);
    2248             :                 SCTP_TCB_LOCK(stcb);
    2249             : #endif
    2250           0 :                 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_17);
    2251             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2252             :                 SCTP_SOCKET_UNLOCK(so, 1);
    2253             : #endif
    2254           0 :                 atomic_subtract_int(&stcb->asoc.refcnt, 1);
    2255           0 :                 return (NULL);
    2256             :         }
    2257             :         /*
    2258             :          * verify any preceding AUTH chunk that was skipped
    2259             :          */
    2260             :         /* pull the local authentication parameters from the cookie/init-ack */
    2261           0 :         sctp_auth_get_cookie_params(stcb, m,
    2262             :             initack_offset + sizeof(struct sctp_init_ack_chunk),
    2263           0 :             initack_limit - (initack_offset + sizeof(struct sctp_init_ack_chunk)));
    2264           0 :         if (auth_skipped) {
    2265             :                 struct sctp_auth_chunk *auth;
    2266             : 
    2267           0 :                 auth = (struct sctp_auth_chunk *)
    2268           0 :                     sctp_m_getptr(m, auth_offset, auth_len, auth_chunk_buf);
    2269           0 :                 if ((auth == NULL) || sctp_handle_auth(stcb, auth, m, auth_offset)) {
    2270             :                         /* auth HMAC failed, dump the assoc and packet */
    2271           0 :                         SCTPDBG(SCTP_DEBUG_AUTH1,
    2272             :                                 "COOKIE-ECHO: AUTH failed\n");
    2273           0 :                         atomic_add_int(&stcb->asoc.refcnt, 1);
    2274             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2275             :                         SCTP_TCB_UNLOCK(stcb);
    2276             :                         SCTP_SOCKET_LOCK(so, 1);
    2277             :                         SCTP_TCB_LOCK(stcb);
    2278             : #endif
    2279           0 :                         (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_18);
    2280             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2281             :                         SCTP_SOCKET_UNLOCK(so, 1);
    2282             : #endif
    2283           0 :                         atomic_subtract_int(&stcb->asoc.refcnt, 1);
    2284           0 :                         return (NULL);
    2285             :                 } else {
    2286             :                         /* remaining chunks checked... good to go */
    2287           0 :                         stcb->asoc.authenticated = 1;
    2288             :                 }
    2289             :         }
    2290             :         /* update current state */
    2291           0 :         SCTPDBG(SCTP_DEBUG_INPUT2, "moving to OPEN state\n");
    2292           0 :         SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
    2293           0 :         if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
    2294           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
    2295             :                                  stcb->sctp_ep, stcb, asoc->primary_destination);
    2296             :         }
    2297           0 :         sctp_stop_all_cookie_timers(stcb);
    2298           0 :         SCTP_STAT_INCR_COUNTER32(sctps_passiveestab);
    2299           0 :         SCTP_STAT_INCR_GAUGE32(sctps_currestab);
    2300             : 
    2301             :         /*
    2302             :          * if we're doing ASCONFs, check to see if we have any new local
    2303             :          * addresses that need to get added to the peer (eg. addresses
    2304             :          * changed while cookie echo in flight).  This needs to be done
    2305             :          * after we go to the OPEN state to do the correct asconf
    2306             :          * processing. else, make sure we have the correct addresses in our
    2307             :          * lists
    2308             :          */
    2309             : 
    2310             :         /* warning, we re-use sin, sin6, sa_store here! */
    2311             :         /* pull in local_address (our "from" address) */
    2312           0 :         switch (cookie->laddr_type) {
    2313             : #ifdef INET
    2314             :         case SCTP_IPV4_ADDRESS:
    2315             :                 /* source addr is IPv4 */
    2316             :                 memset(&store.sin, 0, sizeof(struct sockaddr_in));
    2317             :                 store.sin.sin_family = AF_INET;
    2318             : #ifdef HAVE_SIN_LEN
    2319             :                 store.sin.sin_len = sizeof(struct sockaddr_in);
    2320             : #endif
    2321             :                 store.sin.sin_addr.s_addr = cookie->laddress[0];
    2322             :                 break;
    2323             : #endif
    2324             : #ifdef INET6
    2325             :         case SCTP_IPV6_ADDRESS:
    2326             :                 /* source addr is IPv6 */
    2327             :                 memset(&store.sin6, 0, sizeof(struct sockaddr_in6));
    2328             :                 store.sin6.sin6_family = AF_INET6;
    2329             : #ifdef HAVE_SIN6_LEN
    2330             :                 store.sin6.sin6_len = sizeof(struct sockaddr_in6);
    2331             : #endif
    2332             :                 store.sin6.sin6_scope_id = cookie->scope_id;
    2333             :                 memcpy(&store.sin6.sin6_addr, cookie->laddress, sizeof(struct in6_addr));
    2334             :                 break;
    2335             : #endif
    2336             : #if defined(__Userspace__)
    2337             :         case SCTP_CONN_ADDRESS:
    2338             :                 /* source addr is conn */
    2339           0 :                 memset(&store.sconn, 0, sizeof(struct sockaddr_conn));
    2340           0 :                 store.sconn.sconn_family = AF_CONN;
    2341             : #ifdef HAVE_SCONN_LEN
    2342             :                 store.sconn.sconn_len = sizeof(struct sockaddr_conn);
    2343             : #endif
    2344           0 :                 memcpy(&store.sconn.sconn_addr, cookie->laddress, sizeof(void *));
    2345           0 :                 break;
    2346             : #endif
    2347             :         default:
    2348           0 :                 atomic_add_int(&stcb->asoc.refcnt, 1);
    2349             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2350             :                 SCTP_TCB_UNLOCK(stcb);
    2351             :                 SCTP_SOCKET_LOCK(so, 1);
    2352             :                 SCTP_TCB_LOCK(stcb);
    2353             : #endif
    2354           0 :                 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_19);
    2355             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2356             :                 SCTP_SOCKET_UNLOCK(so, 1);
    2357             : #endif
    2358           0 :                 atomic_subtract_int(&stcb->asoc.refcnt, 1);
    2359           0 :                 return (NULL);
    2360             :         }
    2361             : 
    2362             :         /* set up to notify upper layer */
    2363           0 :         *notification = SCTP_NOTIFY_ASSOC_UP;
    2364           0 :         if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
    2365           0 :             (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
    2366           0 :             (inp->sctp_socket->so_qlimit == 0)) {
    2367             :                 /*
    2368             :                  * This is an endpoint that called connect() how it got a
    2369             :                  * cookie that is NEW is a bit of a mystery. It must be that
    2370             :                  * the INIT was sent, but before it got there.. a complete
    2371             :                  * INIT/INIT-ACK/COOKIE arrived. But of course then it
    2372             :                  * should have went to the other code.. not here.. oh well..
    2373             :                  * a bit of protection is worth having..
    2374             :                  */
    2375           0 :                 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
    2376             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2377             :                 atomic_add_int(&stcb->asoc.refcnt, 1);
    2378             :                 SCTP_TCB_UNLOCK(stcb);
    2379             :                 SCTP_SOCKET_LOCK(so, 1);
    2380             :                 SCTP_TCB_LOCK(stcb);
    2381             :                 atomic_subtract_int(&stcb->asoc.refcnt, 1);
    2382             :                 if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
    2383             :                         SCTP_SOCKET_UNLOCK(so, 1);
    2384             :                         return (NULL);
    2385             :                 }
    2386             : #endif
    2387           0 :                 soisconnected(stcb->sctp_socket);
    2388             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2389             :                 SCTP_SOCKET_UNLOCK(so, 1);
    2390             : #endif
    2391           0 :         } else if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
    2392           0 :             (inp->sctp_socket->so_qlimit)) {
    2393             :                 /*
    2394             :                  * We don't want to do anything with this one. Since it is
    2395             :                  * the listening guy. The timer will get started for
    2396             :                  * accepted connections in the caller.
    2397             :                  */
    2398             :                 ;
    2399             :         }
    2400             :         /* since we did not send a HB make sure we don't double things */
    2401           0 :         if ((netp) && (*netp))
    2402           0 :                 (*netp)->hb_responded = 1;
    2403             : 
    2404           0 :         if (stcb->asoc.sctp_autoclose_ticks &&
    2405           0 :             sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) {
    2406           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL);
    2407             :         }
    2408             :         /* calculate the RTT */
    2409           0 :         (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
    2410           0 :         if ((netp) && (*netp)) {
    2411           0 :                 (*netp)->RTO = sctp_calculate_rto(stcb, asoc, *netp,
    2412             :                                                   &cookie->time_entered, sctp_align_unsafe_makecopy,
    2413             :                                                   SCTP_RTT_FROM_NON_DATA);
    2414             :         }
    2415             :         /* respond with a COOKIE-ACK */
    2416           0 :         sctp_send_cookie_ack(stcb);
    2417             : 
    2418             :         /*
    2419             :          * check the address lists for any ASCONFs that need to be sent
    2420             :          * AFTER the cookie-ack is sent
    2421             :          */
    2422           0 :         sctp_check_address_list(stcb, m,
    2423           0 :             initack_offset + sizeof(struct sctp_init_ack_chunk),
    2424           0 :             initack_limit - (initack_offset + sizeof(struct sctp_init_ack_chunk)),
    2425           0 :             &store.sa, cookie->local_scope, cookie->site_scope,
    2426           0 :             cookie->ipv4_scope, cookie->loopback_scope);
    2427             : 
    2428             : 
    2429           0 :         return (stcb);
    2430             : }
    2431             : 
    2432             : /*
    2433             :  * CODE LIKE THIS NEEDS TO RUN IF the peer supports the NAT extension, i.e
    2434             :  * we NEED to make sure we are not already using the vtag. If so we
    2435             :  * need to send back an ABORT-TRY-AGAIN-WITH-NEW-TAG No middle box bit!
    2436             :         head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(tag,
    2437             :                                                             SCTP_BASE_INFO(hashasocmark))];
    2438             :         LIST_FOREACH(stcb, head, sctp_asocs) {
    2439             :                 if ((stcb->asoc.my_vtag == tag) && (stcb->rport == rport) && (inp == stcb->sctp_ep))  {
    2440             :                        -- SEND ABORT - TRY AGAIN --
    2441             :                 }
    2442             :         }
    2443             : */
    2444             : 
    2445             : /*
    2446             :  * handles a COOKIE-ECHO message stcb: modified to either a new or left as
    2447             :  * existing (non-NULL) TCB
    2448             :  */
    2449             : static struct mbuf *
    2450           0 : sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
    2451             :     struct sockaddr *src, struct sockaddr *dst,
    2452             :     struct sctphdr *sh, struct sctp_cookie_echo_chunk *cp,
    2453             :     struct sctp_inpcb **inp_p, struct sctp_tcb **stcb, struct sctp_nets **netp,
    2454             :     int auth_skipped, uint32_t auth_offset, uint32_t auth_len,
    2455             :     struct sctp_tcb **locked_tcb,
    2456             : #if defined(__FreeBSD__)
    2457             :     uint8_t mflowtype, uint32_t mflowid,
    2458             : #endif
    2459             :     uint32_t vrf_id, uint16_t port)
    2460             : {
    2461             :         struct sctp_state_cookie *cookie;
    2462           0 :         struct sctp_tcb *l_stcb = *stcb;
    2463             :         struct sctp_inpcb *l_inp;
    2464             :         struct sockaddr *to;
    2465             :         struct sctp_pcb *ep;
    2466             :         struct mbuf *m_sig;
    2467             :         uint8_t calc_sig[SCTP_SIGNATURE_SIZE], tmp_sig[SCTP_SIGNATURE_SIZE];
    2468             :         uint8_t *sig;
    2469           0 :         uint8_t cookie_ok = 0;
    2470             :         unsigned int sig_offset, cookie_offset;
    2471             :         unsigned int cookie_len;
    2472             :         struct timeval now;
    2473             :         struct timeval time_expires;
    2474           0 :         int notification = 0;
    2475             :         struct sctp_nets *netl;
    2476           0 :         int had_a_existing_tcb = 0;
    2477           0 :         int send_int_conf = 0;
    2478             : #ifdef INET
    2479             :         struct sockaddr_in sin;
    2480             : #endif
    2481             : #ifdef INET6
    2482             :         struct sockaddr_in6 sin6;
    2483             : #endif
    2484             : #if defined(__Userspace__)
    2485             :         struct sockaddr_conn sconn;
    2486             : #endif
    2487             : 
    2488           0 :         SCTPDBG(SCTP_DEBUG_INPUT2,
    2489             :                 "sctp_handle_cookie: handling COOKIE-ECHO\n");
    2490             : 
    2491           0 :         if (inp_p == NULL) {
    2492           0 :                 return (NULL);
    2493             :         }
    2494           0 :         cookie = &cp->cookie;
    2495           0 :         cookie_offset = offset + sizeof(struct sctp_chunkhdr);
    2496           0 :         cookie_len = ntohs(cp->ch.chunk_length);
    2497             : 
    2498           0 :         if ((cookie->peerport != sh->src_port) &&
    2499           0 :             (cookie->myport != sh->dest_port) &&
    2500           0 :             (cookie->my_vtag != sh->v_tag)) {
    2501             :                 /*
    2502             :                  * invalid ports or bad tag.  Note that we always leave the
    2503             :                  * v_tag in the header in network order and when we stored
    2504             :                  * it in the my_vtag slot we also left it in network order.
    2505             :                  * This maintains the match even though it may be in the
    2506             :                  * opposite byte order of the machine :->
    2507             :                  */
    2508           0 :                 return (NULL);
    2509             :         }
    2510           0 :         if (cookie_len < sizeof(struct sctp_cookie_echo_chunk) +
    2511             :             sizeof(struct sctp_init_chunk) +
    2512             :             sizeof(struct sctp_init_ack_chunk) + SCTP_SIGNATURE_SIZE) {
    2513             :                 /* cookie too small */
    2514           0 :                 return (NULL);
    2515             :         }
    2516             :         /*
    2517             :          * split off the signature into its own mbuf (since it should not be
    2518             :          * calculated in the sctp_hmac_m() call).
    2519             :          */
    2520           0 :         sig_offset = offset + cookie_len - SCTP_SIGNATURE_SIZE;
    2521           0 :         m_sig = m_split(m, sig_offset, M_NOWAIT);
    2522           0 :         if (m_sig == NULL) {
    2523             :                 /* out of memory or ?? */
    2524           0 :                 return (NULL);
    2525             :         }
    2526             : #ifdef SCTP_MBUF_LOGGING
    2527             :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
    2528             :                 sctp_log_mbc(m_sig, SCTP_MBUF_SPLIT);
    2529             :         }
    2530             : #endif
    2531             : 
    2532             :         /*
    2533             :          * compute the signature/digest for the cookie
    2534             :          */
    2535           0 :         ep = &(*inp_p)->sctp_ep;
    2536           0 :         l_inp = *inp_p;
    2537           0 :         if (l_stcb) {
    2538           0 :                 SCTP_TCB_UNLOCK(l_stcb);
    2539             :         }
    2540           0 :         SCTP_INP_RLOCK(l_inp);
    2541           0 :         if (l_stcb) {
    2542           0 :                 SCTP_TCB_LOCK(l_stcb);
    2543             :         }
    2544             :         /* which cookie is it? */
    2545           0 :         if ((cookie->time_entered.tv_sec < (long)ep->time_of_secret_change) &&
    2546           0 :             (ep->current_secret_number != ep->last_secret_number)) {
    2547             :                 /* it's the old cookie */
    2548           0 :                 (void)sctp_hmac_m(SCTP_HMAC,
    2549           0 :                     (uint8_t *)ep->secret_key[(int)ep->last_secret_number],
    2550             :                     SCTP_SECRET_SIZE, m, cookie_offset, calc_sig, 0);
    2551             :         } else {
    2552             :                 /* it's the current cookie */
    2553           0 :                 (void)sctp_hmac_m(SCTP_HMAC,
    2554           0 :                     (uint8_t *)ep->secret_key[(int)ep->current_secret_number],
    2555             :                     SCTP_SECRET_SIZE, m, cookie_offset, calc_sig, 0);
    2556             :         }
    2557             :         /* get the signature */
    2558           0 :         SCTP_INP_RUNLOCK(l_inp);
    2559           0 :         sig = (uint8_t *) sctp_m_getptr(m_sig, 0, SCTP_SIGNATURE_SIZE, (uint8_t *) & tmp_sig);
    2560           0 :         if (sig == NULL) {
    2561             :                 /* couldn't find signature */
    2562           0 :                 sctp_m_freem(m_sig);
    2563           0 :                 return (NULL);
    2564             :         }
    2565             :         /* compare the received digest with the computed digest */
    2566           0 :         if (memcmp(calc_sig, sig, SCTP_SIGNATURE_SIZE) != 0) {
    2567             :                 /* try the old cookie? */
    2568           0 :                 if ((cookie->time_entered.tv_sec == (long)ep->time_of_secret_change) &&
    2569           0 :                     (ep->current_secret_number != ep->last_secret_number)) {
    2570             :                         /* compute digest with old */
    2571           0 :                         (void)sctp_hmac_m(SCTP_HMAC,
    2572           0 :                             (uint8_t *)ep->secret_key[(int)ep->last_secret_number],
    2573             :                             SCTP_SECRET_SIZE, m, cookie_offset, calc_sig, 0);
    2574             :                         /* compare */
    2575           0 :                         if (memcmp(calc_sig, sig, SCTP_SIGNATURE_SIZE) == 0)
    2576           0 :                                 cookie_ok = 1;
    2577             :                 }
    2578             :         } else {
    2579           0 :                 cookie_ok = 1;
    2580             :         }
    2581             : 
    2582             :         /*
    2583             :          * Now before we continue we must reconstruct our mbuf so that
    2584             :          * normal processing of any other chunks will work.
    2585             :          */
    2586             :         {
    2587             :                 struct mbuf *m_at;
    2588             : 
    2589           0 :                 m_at = m;
    2590           0 :                 while (SCTP_BUF_NEXT(m_at) != NULL) {
    2591           0 :                         m_at = SCTP_BUF_NEXT(m_at);
    2592             :                 }
    2593           0 :                 SCTP_BUF_NEXT(m_at) = m_sig;
    2594             :         }
    2595             : 
    2596           0 :         if (cookie_ok == 0) {
    2597           0 :                 SCTPDBG(SCTP_DEBUG_INPUT2, "handle_cookie_echo: cookie signature validation failed!\n");
    2598           0 :                 SCTPDBG(SCTP_DEBUG_INPUT2,
    2599             :                         "offset = %u, cookie_offset = %u, sig_offset = %u\n",
    2600             :                         (uint32_t) offset, cookie_offset, sig_offset);
    2601           0 :                 return (NULL);
    2602             :         }
    2603             : 
    2604             :         /*
    2605             :          * check the cookie timestamps to be sure it's not stale
    2606             :          */
    2607           0 :         (void)SCTP_GETTIME_TIMEVAL(&now);
    2608             :         /* Expire time is in Ticks, so we convert to seconds */
    2609           0 :         time_expires.tv_sec = cookie->time_entered.tv_sec + TICKS_TO_SEC(cookie->cookie_life);
    2610           0 :         time_expires.tv_usec = cookie->time_entered.tv_usec;
    2611             :         /* TODO sctp_constants.h needs alternative time macros when
    2612             :          *  _KERNEL is undefined.
    2613             :          */
    2614             : #ifndef __FreeBSD__
    2615           0 :         if (timercmp(&now, &time_expires, >))
    2616             : #else
    2617             :         if (timevalcmp(&now, &time_expires, >))
    2618             : #endif
    2619             :         {
    2620             :                 /* cookie is stale! */
    2621             :                 struct mbuf *op_err;
    2622             :                 struct sctp_stale_cookie_msg *scm;
    2623             :                 uint32_t tim;
    2624           0 :                 op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_stale_cookie_msg),
    2625             :                                                0, M_NOWAIT, 1, MT_DATA);
    2626           0 :                 if (op_err == NULL) {
    2627             :                         /* FOOBAR */
    2628           0 :                         return (NULL);
    2629             :                 }
    2630             :                 /* Set the len */
    2631           0 :                 SCTP_BUF_LEN(op_err) = sizeof(struct sctp_stale_cookie_msg);
    2632           0 :                 scm = mtod(op_err, struct sctp_stale_cookie_msg *);
    2633           0 :                 scm->ph.param_type = htons(SCTP_CAUSE_STALE_COOKIE);
    2634           0 :                 scm->ph.param_length = htons((sizeof(struct sctp_paramhdr) +
    2635             :                     (sizeof(uint32_t))));
    2636             :                 /* seconds to usec */
    2637           0 :                 tim = (now.tv_sec - time_expires.tv_sec) * 1000000;
    2638             :                 /* add in usec */
    2639           0 :                 if (tim == 0)
    2640           0 :                         tim = now.tv_usec - cookie->time_entered.tv_usec;
    2641           0 :                 scm->time_usec = htonl(tim);
    2642           0 :                 sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err,
    2643             : #if defined(__FreeBSD__)
    2644             :                                    mflowtype, mflowid,
    2645             : #endif
    2646             :                                    vrf_id, port);
    2647           0 :                 return (NULL);
    2648             :         }
    2649             :         /*
    2650             :          * Now we must see with the lookup address if we have an existing
    2651             :          * asoc. This will only happen if we were in the COOKIE-WAIT state
    2652             :          * and a INIT collided with us and somewhere the peer sent the
    2653             :          * cookie on another address besides the single address our assoc
    2654             :          * had for him. In this case we will have one of the tie-tags set at
    2655             :          * least AND the address field in the cookie can be used to look it
    2656             :          * up.
    2657             :          */
    2658           0 :         to = NULL;
    2659           0 :         switch (cookie->addr_type) {
    2660             : #ifdef INET6
    2661             :         case SCTP_IPV6_ADDRESS:
    2662             :                 memset(&sin6, 0, sizeof(sin6));
    2663             :                 sin6.sin6_family = AF_INET6;
    2664             : #ifdef HAVE_SIN6_LEN
    2665             :                 sin6.sin6_len = sizeof(sin6);
    2666             : #endif
    2667             :                 sin6.sin6_port = sh->src_port;
    2668             :                 sin6.sin6_scope_id = cookie->scope_id;
    2669             :                 memcpy(&sin6.sin6_addr.s6_addr, cookie->address,
    2670             :                     sizeof(sin6.sin6_addr.s6_addr));
    2671             :                 to = (struct sockaddr *)&sin6;
    2672             :                 break;
    2673             : #endif
    2674             : #ifdef INET
    2675             :         case SCTP_IPV4_ADDRESS:
    2676             :                 memset(&sin, 0, sizeof(sin));
    2677             :                 sin.sin_family = AF_INET;
    2678             : #ifdef HAVE_SIN_LEN
    2679             :                 sin.sin_len = sizeof(sin);
    2680             : #endif
    2681             :                 sin.sin_port = sh->src_port;
    2682             :                 sin.sin_addr.s_addr = cookie->address[0];
    2683             :                 to = (struct sockaddr *)&sin;
    2684             :                 break;
    2685             : #endif
    2686             : #if defined(__Userspace__)
    2687             :         case SCTP_CONN_ADDRESS:
    2688           0 :                 memset(&sconn, 0, sizeof(struct sockaddr_conn));
    2689           0 :                 sconn.sconn_family = AF_CONN;
    2690             : #ifdef HAVE_SCONN_LEN
    2691             :                 sconn.sconn_len = sizeof(struct sockaddr_conn);
    2692             : #endif
    2693           0 :                 sconn.sconn_port = sh->src_port;
    2694           0 :                 memcpy(&sconn.sconn_addr, cookie->address, sizeof(void *));
    2695           0 :                 to = (struct sockaddr *)&sconn;
    2696           0 :                 break;
    2697             : #endif
    2698             :         default:
    2699             :                 /* This should not happen */
    2700           0 :                 return (NULL);
    2701             :         }
    2702           0 :         if (*stcb == NULL) {
    2703             :                 /* Yep, lets check */
    2704           0 :                 *stcb = sctp_findassociation_ep_addr(inp_p, to, netp, dst, NULL);
    2705           0 :                 if (*stcb == NULL) {
    2706             :                         /*
    2707             :                          * We should have only got back the same inp. If we
    2708             :                          * got back a different ep we have a problem. The
    2709             :                          * original findep got back l_inp and now
    2710             :                          */
    2711           0 :                         if (l_inp != *inp_p) {
    2712           0 :                                 SCTP_PRINTF("Bad problem find_ep got a diff inp then special_locate?\n");
    2713             :                         }
    2714             :                 } else {
    2715           0 :                         if (*locked_tcb == NULL) {
    2716             :                                 /* In this case we found the assoc only
    2717             :                                  * after we locked the create lock. This means
    2718             :                                  * we are in a colliding case and we must make
    2719             :                                  * sure that we unlock the tcb if its one of the
    2720             :                                  * cases where we throw away the incoming packets.
    2721             :                                  */
    2722           0 :                                 *locked_tcb = *stcb;
    2723             : 
    2724             :                                 /* We must also increment the inp ref count
    2725             :                                  * since the ref_count flags was set when we
    2726             :                                  * did not find the TCB, now we found it which
    2727             :                                  * reduces the refcount.. we must raise it back
    2728             :                                  * out to balance it all :-)
    2729             :                                  */
    2730           0 :                                 SCTP_INP_INCR_REF((*stcb)->sctp_ep);
    2731           0 :                                 if ((*stcb)->sctp_ep != l_inp) {
    2732           0 :                                         SCTP_PRINTF("Huh? ep:%p diff then l_inp:%p?\n",
    2733             :                                                     (void *)(*stcb)->sctp_ep, (void *)l_inp);
    2734             :                                 }
    2735             :                         }
    2736             :                 }
    2737             :         }
    2738             : 
    2739           0 :         cookie_len -= SCTP_SIGNATURE_SIZE;
    2740           0 :         if (*stcb == NULL) {
    2741             :                 /* this is the "normal" case... get a new TCB */
    2742           0 :                 *stcb = sctp_process_cookie_new(m, iphlen, offset, src, dst, sh,
    2743             :                                                 cookie, cookie_len, *inp_p,
    2744             :                                                 netp, to, &notification,
    2745             :                                                 auth_skipped, auth_offset, auth_len,
    2746             : #if defined(__FreeBSD__)
    2747             :                                                 mflowtype, mflowid,
    2748             : #endif
    2749             :                                                 vrf_id, port);
    2750             :         } else {
    2751             :                 /* this is abnormal... cookie-echo on existing TCB */
    2752           0 :                 had_a_existing_tcb = 1;
    2753           0 :                 *stcb = sctp_process_cookie_existing(m, iphlen, offset,
    2754             :                                                      src, dst, sh,
    2755             :                                                      cookie, cookie_len, *inp_p, *stcb, netp, to,
    2756             :                                                      &notification, auth_skipped, auth_offset, auth_len,
    2757             : #if defined(__FreeBSD__)
    2758             :                                                      mflowtype, mflowid,
    2759             : #endif
    2760             :                                                      vrf_id, port);
    2761             :         }
    2762             : 
    2763           0 :         if (*stcb == NULL) {
    2764             :                 /* still no TCB... must be bad cookie-echo */
    2765           0 :                 return (NULL);
    2766             :         }
    2767             : #if defined(__FreeBSD__)
    2768             :         if ((*netp != NULL) && (mflowtype != M_HASHTYPE_NONE)) {
    2769             :                 (*netp)->flowtype = mflowtype;
    2770             :         }
    2771             : #endif
    2772             :         /*
    2773             :          * Ok, we built an association so confirm the address we sent the
    2774             :          * INIT-ACK to.
    2775             :          */
    2776           0 :         netl = sctp_findnet(*stcb, to);
    2777             :         /*
    2778             :          * This code should in theory NOT run but
    2779             :          */
    2780           0 :         if (netl == NULL) {
    2781             :                 /* TSNH! Huh, why do I need to add this address here? */
    2782           0 :                 if (sctp_add_remote_addr(*stcb, to, NULL, SCTP_DONOT_SETSCOPE, SCTP_IN_COOKIE_PROC)) {
    2783           0 :                         return (NULL);
    2784             :                 }
    2785           0 :                 netl = sctp_findnet(*stcb, to);
    2786             :         }
    2787           0 :         if (netl) {
    2788           0 :                 if (netl->dest_state & SCTP_ADDR_UNCONFIRMED) {
    2789           0 :                         netl->dest_state &= ~SCTP_ADDR_UNCONFIRMED;
    2790           0 :                         (void)sctp_set_primary_addr((*stcb), (struct sockaddr *)NULL,
    2791             :                             netl);
    2792           0 :                         send_int_conf = 1;
    2793             :                 }
    2794             :         }
    2795           0 :         sctp_start_net_timers(*stcb);
    2796           0 :         if ((*inp_p)->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
    2797           0 :                 if (!had_a_existing_tcb ||
    2798           0 :                     (((*inp_p)->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
    2799             :                         /*
    2800             :                          * If we have a NEW cookie or the connect never
    2801             :                          * reached the connected state during collision we
    2802             :                          * must do the TCP accept thing.
    2803             :                          */
    2804             :                         struct socket *so, *oso;
    2805             :                         struct sctp_inpcb *inp;
    2806             : 
    2807           0 :                         if (notification == SCTP_NOTIFY_ASSOC_RESTART) {
    2808             :                                 /*
    2809             :                                  * For a restart we will keep the same
    2810             :                                  * socket, no need to do anything. I THINK!!
    2811             :                                  */
    2812           0 :                                 sctp_ulp_notify(notification, *stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
    2813           0 :                                 if (send_int_conf) {
    2814           0 :                                         sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
    2815             :                                                         (*stcb), 0, (void *)netl, SCTP_SO_NOT_LOCKED);
    2816             :                                 }
    2817           0 :                                 return (m);
    2818             :                         }
    2819           0 :                         oso = (*inp_p)->sctp_socket;
    2820             : #if (defined(__FreeBSD__) && __FreeBSD_version < 700000)
    2821             :                         /*
    2822             :                          * We do this to keep the sockets side happy during
    2823             :                          * the sonewcon ONLY.
    2824             :                          */
    2825             :                         NET_LOCK_GIANT();
    2826             : #endif
    2827           0 :                         atomic_add_int(&(*stcb)->asoc.refcnt, 1);
    2828           0 :                         SCTP_TCB_UNLOCK((*stcb));
    2829             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
    2830             :                         CURVNET_SET(oso->so_vnet);
    2831             : #endif
    2832             : #if defined(__APPLE__)
    2833             :                         SCTP_SOCKET_LOCK(oso, 1);
    2834             : #endif
    2835           0 :                         so = sonewconn(oso, 0
    2836             : #if defined(__APPLE__)
    2837             :                             ,NULL
    2838             : #endif
    2839             : #ifdef __Panda__
    2840             :                              ,NULL , (*inp_p)->def_vrf_id
    2841             : #endif
    2842             :                             );
    2843             : #if (defined(__FreeBSD__) && __FreeBSD_version < 700000)
    2844             :                         NET_UNLOCK_GIANT();
    2845             : #endif
    2846             : #if defined(__APPLE__)
    2847             :                         SCTP_SOCKET_UNLOCK(oso, 1);
    2848             : #endif
    2849             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
    2850             :                         CURVNET_RESTORE();
    2851             : #endif
    2852           0 :                         SCTP_TCB_LOCK((*stcb));
    2853           0 :                         atomic_subtract_int(&(*stcb)->asoc.refcnt, 1);
    2854             : 
    2855           0 :                         if (so == NULL) {
    2856             :                                 struct mbuf *op_err;
    2857             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2858             :                                 struct socket *pcb_so;
    2859             : #endif
    2860             :                                 /* Too many sockets */
    2861           0 :                                 SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: no room for another socket!\n");
    2862           0 :                                 op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
    2863           0 :                                 sctp_abort_association(*inp_p, NULL, m, iphlen,
    2864             :                                                        src, dst, sh, op_err,
    2865             : #if defined(__FreeBSD__)
    2866             :                                                        mflowtype, mflowid,
    2867             : #endif
    2868             :                                                        vrf_id, port);
    2869             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2870             :                                 pcb_so = SCTP_INP_SO(*inp_p);
    2871             :                                 atomic_add_int(&(*stcb)->asoc.refcnt, 1);
    2872             :                                 SCTP_TCB_UNLOCK((*stcb));
    2873             :                                 SCTP_SOCKET_LOCK(pcb_so, 1);
    2874             :                                 SCTP_TCB_LOCK((*stcb));
    2875             :                                 atomic_subtract_int(&(*stcb)->asoc.refcnt, 1);
    2876             : #endif
    2877           0 :                                 (void)sctp_free_assoc(*inp_p, *stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_20);
    2878             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2879             :                                 SCTP_SOCKET_UNLOCK(pcb_so, 1);
    2880             : #endif
    2881           0 :                                 return (NULL);
    2882             :                         }
    2883           0 :                         inp = (struct sctp_inpcb *)so->so_pcb;
    2884           0 :                         SCTP_INP_INCR_REF(inp);
    2885             :                         /*
    2886             :                          * We add the unbound flag here so that
    2887             :                          * if we get an soabort() before we get the
    2888             :                          * move_pcb done, we will properly cleanup.
    2889             :                          */
    2890           0 :                         inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE |
    2891             :                             SCTP_PCB_FLAGS_CONNECTED |
    2892             :                             SCTP_PCB_FLAGS_IN_TCPPOOL |
    2893             :                             SCTP_PCB_FLAGS_UNBOUND |
    2894           0 :                             (SCTP_PCB_COPY_FLAGS & (*inp_p)->sctp_flags) |
    2895             :                             SCTP_PCB_FLAGS_DONT_WAKE);
    2896           0 :                         inp->sctp_features = (*inp_p)->sctp_features;
    2897           0 :                         inp->sctp_mobility_features = (*inp_p)->sctp_mobility_features;
    2898           0 :                         inp->sctp_socket = so;
    2899           0 :                         inp->sctp_frag_point = (*inp_p)->sctp_frag_point;
    2900           0 :                         inp->max_cwnd = (*inp_p)->max_cwnd;
    2901           0 :                         inp->sctp_cmt_on_off = (*inp_p)->sctp_cmt_on_off;
    2902           0 :                         inp->ecn_supported = (*inp_p)->ecn_supported;
    2903           0 :                         inp->prsctp_supported = (*inp_p)->prsctp_supported;
    2904           0 :                         inp->auth_supported = (*inp_p)->auth_supported;
    2905           0 :                         inp->asconf_supported = (*inp_p)->asconf_supported;
    2906           0 :                         inp->reconfig_supported = (*inp_p)->reconfig_supported;
    2907           0 :                         inp->nrsack_supported = (*inp_p)->nrsack_supported;
    2908           0 :                         inp->pktdrop_supported = (*inp_p)->pktdrop_supported;
    2909           0 :                         inp->partial_delivery_point = (*inp_p)->partial_delivery_point;
    2910           0 :                         inp->sctp_context = (*inp_p)->sctp_context;
    2911           0 :                         inp->local_strreset_support = (*inp_p)->local_strreset_support;
    2912           0 :                         inp->inp_starting_point_for_iterator = NULL;
    2913             : #if defined(__Userspace__)
    2914           0 :                         inp->ulp_info = (*inp_p)->ulp_info;
    2915           0 :                         inp->recv_callback = (*inp_p)->recv_callback;
    2916           0 :                         inp->send_callback = (*inp_p)->send_callback;
    2917           0 :                         inp->send_sb_threshold = (*inp_p)->send_sb_threshold;
    2918             : #endif
    2919             :                         /*
    2920             :                          * copy in the authentication parameters from the
    2921             :                          * original endpoint
    2922             :                          */
    2923           0 :                         if (inp->sctp_ep.local_hmacs)
    2924           0 :                                 sctp_free_hmaclist(inp->sctp_ep.local_hmacs);
    2925           0 :                         inp->sctp_ep.local_hmacs =
    2926           0 :                             sctp_copy_hmaclist((*inp_p)->sctp_ep.local_hmacs);
    2927           0 :                         if (inp->sctp_ep.local_auth_chunks)
    2928           0 :                                 sctp_free_chunklist(inp->sctp_ep.local_auth_chunks);
    2929           0 :                         inp->sctp_ep.local_auth_chunks =
    2930           0 :                             sctp_copy_chunklist((*inp_p)->sctp_ep.local_auth_chunks);
    2931             : 
    2932             :                         /*
    2933             :                          * Now we must move it from one hash table to
    2934             :                          * another and get the tcb in the right place.
    2935             :                          */
    2936             : 
    2937             :                         /* This is where the one-2-one socket is put into
    2938             :                          * the accept state waiting for the accept!
    2939             :                          */
    2940           0 :                         if (*stcb) {
    2941           0 :                                 (*stcb)->asoc.state |= SCTP_STATE_IN_ACCEPT_QUEUE;
    2942             :                         }
    2943           0 :                         sctp_move_pcb_and_assoc(*inp_p, inp, *stcb);
    2944             : 
    2945           0 :                         atomic_add_int(&(*stcb)->asoc.refcnt, 1);
    2946           0 :                         SCTP_TCB_UNLOCK((*stcb));
    2947             : 
    2948             : #if defined(__FreeBSD__)
    2949             :                         sctp_pull_off_control_to_new_inp((*inp_p), inp, *stcb,
    2950             :                             0);
    2951             : #else
    2952           0 :                         sctp_pull_off_control_to_new_inp((*inp_p), inp, *stcb, M_NOWAIT);
    2953             : #endif
    2954           0 :                         SCTP_TCB_LOCK((*stcb));
    2955           0 :                         atomic_subtract_int(&(*stcb)->asoc.refcnt, 1);
    2956             : 
    2957             : 
    2958             :                         /* now we must check to see if we were aborted while
    2959             :                          * the move was going on and the lock/unlock happened.
    2960             :                          */
    2961           0 :                         if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
    2962             :                                 /* yep it was, we leave the
    2963             :                                  * assoc attached to the socket since
    2964             :                                  * the sctp_inpcb_free() call will send
    2965             :                                  * an abort for us.
    2966             :                                  */
    2967           0 :                                 SCTP_INP_DECR_REF(inp);
    2968           0 :                                 return (NULL);
    2969             :                         }
    2970           0 :                         SCTP_INP_DECR_REF(inp);
    2971             :                         /* Switch over to the new guy */
    2972           0 :                         *inp_p = inp;
    2973           0 :                         sctp_ulp_notify(notification, *stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
    2974           0 :                         if (send_int_conf) {
    2975           0 :                                 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
    2976             :                                                 (*stcb), 0, (void *)netl, SCTP_SO_NOT_LOCKED);
    2977             :                         }
    2978             : 
    2979             :                         /* Pull it from the incomplete queue and wake the guy */
    2980             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2981             :                         atomic_add_int(&(*stcb)->asoc.refcnt, 1);
    2982             :                         SCTP_TCB_UNLOCK((*stcb));
    2983             :                         SCTP_SOCKET_LOCK(so, 1);
    2984             : #endif
    2985           0 :                         soisconnected(so);
    2986             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    2987             :                         SCTP_TCB_LOCK((*stcb));
    2988             :                         atomic_subtract_int(&(*stcb)->asoc.refcnt, 1);
    2989             :                         SCTP_SOCKET_UNLOCK(so, 1);
    2990             : #endif
    2991           0 :                         return (m);
    2992             :                 }
    2993             :         }
    2994           0 :         if (notification) {
    2995           0 :                 sctp_ulp_notify(notification, *stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
    2996             :         }
    2997           0 :         if (send_int_conf) {
    2998           0 :                 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
    2999             :                                 (*stcb), 0, (void *)netl, SCTP_SO_NOT_LOCKED);
    3000             :         }
    3001           0 :         return (m);
    3002             : }
    3003             : 
    3004             : static void
    3005           0 : sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
    3006             :     struct sctp_tcb *stcb, struct sctp_nets *net)
    3007             : {
    3008             :         /* cp must not be used, others call this without a c-ack :-) */
    3009             :         struct sctp_association *asoc;
    3010             : 
    3011           0 :         SCTPDBG(SCTP_DEBUG_INPUT2,
    3012             :                 "sctp_handle_cookie_ack: handling COOKIE-ACK\n");
    3013           0 :         if ((stcb == NULL) || (net == NULL)) {
    3014           0 :                 return;
    3015             :         }
    3016             : 
    3017           0 :         asoc = &stcb->asoc;
    3018             : 
    3019           0 :         sctp_stop_all_cookie_timers(stcb);
    3020             :         /* process according to association state */
    3021           0 :         if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED) {
    3022             :                 /* state change only needed when I am in right state */
    3023           0 :                 SCTPDBG(SCTP_DEBUG_INPUT2, "moving to OPEN state\n");
    3024           0 :                 SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
    3025           0 :                 sctp_start_net_timers(stcb);
    3026           0 :                 if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
    3027           0 :                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
    3028             :                                          stcb->sctp_ep, stcb, asoc->primary_destination);
    3029             : 
    3030             :                 }
    3031             :                 /* update RTO */
    3032           0 :                 SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
    3033           0 :                 SCTP_STAT_INCR_GAUGE32(sctps_currestab);
    3034           0 :                 if (asoc->overall_error_count == 0) {
    3035           0 :                         net->RTO = sctp_calculate_rto(stcb, asoc, net,
    3036             :                                                      &asoc->time_entered, sctp_align_safe_nocopy,
    3037             :                                                       SCTP_RTT_FROM_NON_DATA);
    3038             :                 }
    3039           0 :                 (void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered);
    3040           0 :                 sctp_ulp_notify(SCTP_NOTIFY_ASSOC_UP, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
    3041           0 :                 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
    3042           0 :                     (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
    3043             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    3044             :                         struct socket *so;
    3045             : 
    3046             : #endif
    3047           0 :                         stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
    3048             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    3049             :                         so = SCTP_INP_SO(stcb->sctp_ep);
    3050             :                         atomic_add_int(&stcb->asoc.refcnt, 1);
    3051             :                         SCTP_TCB_UNLOCK(stcb);
    3052             :                         SCTP_SOCKET_LOCK(so, 1);
    3053             :                         SCTP_TCB_LOCK(stcb);
    3054             :                         atomic_subtract_int(&stcb->asoc.refcnt, 1);
    3055             : #endif
    3056           0 :                         if ((stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) == 0) {
    3057           0 :                                 soisconnected(stcb->sctp_socket);
    3058             :                         }
    3059             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    3060             :                         SCTP_SOCKET_UNLOCK(so, 1);
    3061             : #endif
    3062             :                 }
    3063             :                 /*
    3064             :                  * since we did not send a HB make sure we don't double
    3065             :                  * things
    3066             :                  */
    3067           0 :                 net->hb_responded = 1;
    3068             : 
    3069           0 :                 if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
    3070             :                         /* We don't need to do the asconf thing,
    3071             :                          * nor hb or autoclose if the socket is closed.
    3072             :                          */
    3073           0 :                         goto closed_socket;
    3074             :                 }
    3075             : 
    3076           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
    3077             :                     stcb, net);
    3078             : 
    3079             : 
    3080           0 :                 if (stcb->asoc.sctp_autoclose_ticks &&
    3081           0 :                     sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_AUTOCLOSE)) {
    3082           0 :                         sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE,
    3083             :                             stcb->sctp_ep, stcb, NULL);
    3084             :                 }
    3085             :                 /*
    3086             :                  * send ASCONF if parameters are pending and ASCONFs are
    3087             :                  * allowed (eg. addresses changed when init/cookie echo were
    3088             :                  * in flight)
    3089             :                  */
    3090           0 :                 if ((sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_DO_ASCONF)) &&
    3091           0 :                     (stcb->asoc.asconf_supported == 1) &&
    3092           0 :                     (!TAILQ_EMPTY(&stcb->asoc.asconf_queue))) {
    3093             : #ifdef SCTP_TIMER_BASED_ASCONF
    3094             :                         sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
    3095             :                                          stcb->sctp_ep, stcb,
    3096             :                                          stcb->asoc.primary_destination);
    3097             : #else
    3098           0 :                         sctp_send_asconf(stcb, stcb->asoc.primary_destination,
    3099             :                                          SCTP_ADDR_NOT_LOCKED);
    3100             : #endif
    3101             :                 }
    3102             :         }
    3103             : closed_socket:
    3104             :         /* Toss the cookie if I can */
    3105           0 :         sctp_toss_old_cookies(stcb, asoc);
    3106           0 :         if (!TAILQ_EMPTY(&asoc->sent_queue)) {
    3107             :                 /* Restart the timer if we have pending data */
    3108             :                 struct sctp_tmit_chunk *chk;
    3109             : 
    3110           0 :                 chk = TAILQ_FIRST(&asoc->sent_queue);
    3111           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo);
    3112             :         }
    3113             : }
    3114             : 
    3115             : static void
    3116           0 : sctp_handle_ecn_echo(struct sctp_ecne_chunk *cp,
    3117             :                      struct sctp_tcb *stcb)
    3118             : {
    3119             :         struct sctp_nets *net;
    3120             :         struct sctp_tmit_chunk *lchk;
    3121             :         struct sctp_ecne_chunk bkup;
    3122             :         uint8_t override_bit;
    3123             :         uint32_t tsn, window_data_tsn;
    3124             :         int len;
    3125             :         unsigned int pkt_cnt;
    3126             : 
    3127           0 :         len = ntohs(cp->ch.chunk_length);
    3128           0 :         if ((len != sizeof(struct sctp_ecne_chunk)) &&
    3129             :             (len != sizeof(struct old_sctp_ecne_chunk))) {
    3130           0 :                 return;
    3131             :         }
    3132           0 :         if (len == sizeof(struct old_sctp_ecne_chunk)) {
    3133             :                 /* Its the old format */
    3134           0 :                 memcpy(&bkup, cp, sizeof(struct old_sctp_ecne_chunk));
    3135           0 :                 bkup.num_pkts_since_cwr = htonl(1);
    3136           0 :                 cp = &bkup;
    3137             :         }
    3138           0 :         SCTP_STAT_INCR(sctps_recvecne);
    3139           0 :         tsn = ntohl(cp->tsn);
    3140           0 :         pkt_cnt = ntohl(cp->num_pkts_since_cwr);
    3141           0 :         lchk = TAILQ_LAST(&stcb->asoc.send_queue, sctpchunk_listhead);
    3142           0 :         if (lchk == NULL) {
    3143           0 :                 window_data_tsn = stcb->asoc.sending_seq - 1;
    3144             :         } else {
    3145           0 :                 window_data_tsn = lchk->rec.data.TSN_seq;
    3146             :         }
    3147             : 
    3148             :         /* Find where it was sent to if possible. */
    3149           0 :         net = NULL;
    3150           0 :         TAILQ_FOREACH(lchk, &stcb->asoc.sent_queue, sctp_next) {
    3151           0 :                 if (lchk->rec.data.TSN_seq == tsn) {
    3152           0 :                         net = lchk->whoTo;
    3153           0 :                         net->ecn_prev_cwnd = lchk->rec.data.cwnd_at_send;
    3154           0 :                         break;
    3155             :                 }
    3156           0 :                 if (SCTP_TSN_GT(lchk->rec.data.TSN_seq, tsn)) {
    3157             :                         break;
    3158             :                 }
    3159             :         }
    3160           0 :         if (net == NULL) {
    3161             :                 /*
    3162             :                  * What to do. A previous send of a
    3163             :                  * CWR was possibly lost. See how old it is, we
    3164             :                  * may have it marked on the actual net.
    3165             :                  */
    3166           0 :                 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
    3167           0 :                         if (tsn == net->last_cwr_tsn) {
    3168             :                                 /* Found him, send it off */
    3169           0 :                                 break;
    3170             :                         }
    3171             :                 }
    3172           0 :                 if (net == NULL) {
    3173             :                         /*
    3174             :                          * If we reach here, we need to send a special
    3175             :                          * CWR that says hey, we did this a long time
    3176             :                          * ago and you lost the response.
    3177             :                          */
    3178           0 :                         net = TAILQ_FIRST(&stcb->asoc.nets);
    3179           0 :                         if (net == NULL) {
    3180             :                                 /* TSNH */
    3181           0 :                                 return;
    3182             :                         }
    3183           0 :                         override_bit = SCTP_CWR_REDUCE_OVERRIDE;
    3184             :                 } else {
    3185           0 :                         override_bit = 0;
    3186             :                 }
    3187             :         } else {
    3188           0 :                 override_bit = 0;
    3189             :         }
    3190           0 :         if (SCTP_TSN_GT(tsn, net->cwr_window_tsn) &&
    3191           0 :             ((override_bit&SCTP_CWR_REDUCE_OVERRIDE) == 0)) {
    3192             :                 /* JRS - Use the congestion control given in the pluggable CC module */
    3193           0 :                 stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo(stcb, net, 0, pkt_cnt);
    3194             :                 /*
    3195             :                  * We reduce once every RTT. So we will only lower cwnd at
    3196             :                  * the next sending seq i.e. the window_data_tsn
    3197             :                  */
    3198           0 :                 net->cwr_window_tsn = window_data_tsn;
    3199           0 :                 net->ecn_ce_pkt_cnt += pkt_cnt;
    3200           0 :                 net->lost_cnt = pkt_cnt;
    3201           0 :                 net->last_cwr_tsn = tsn;
    3202             :         } else {
    3203           0 :                 override_bit |= SCTP_CWR_IN_SAME_WINDOW;
    3204           0 :                 if (SCTP_TSN_GT(tsn, net->last_cwr_tsn) &&
    3205           0 :                     ((override_bit&SCTP_CWR_REDUCE_OVERRIDE) == 0)) {
    3206             :                         /*
    3207             :                          * Another loss in the same window update how
    3208             :                          * many marks/packets lost we have had.
    3209             :                          */
    3210           0 :                         int cnt = 1;
    3211           0 :                         if (pkt_cnt > net->lost_cnt) {
    3212             :                                 /* Should be the case */
    3213           0 :                                 cnt = (pkt_cnt - net->lost_cnt);
    3214           0 :                                 net->ecn_ce_pkt_cnt += cnt;
    3215             :                         }
    3216           0 :                         net->lost_cnt = pkt_cnt;
    3217           0 :                         net->last_cwr_tsn = tsn;
    3218             :                         /*
    3219             :                          * Most CC functions will ignore this call, since we are in-window
    3220             :                          * yet of the initial CE the peer saw.
    3221             :                          */
    3222           0 :                         stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo(stcb, net, 1, cnt);
    3223             :                 }
    3224             :         }
    3225             :         /*
    3226             :          * We always send a CWR this way if our previous one was lost our
    3227             :          * peer will get an update, or if it is not time again to reduce we
    3228             :          * still get the cwr to the peer. Note we set the override when we
    3229             :          * could not find the TSN on the chunk or the destination network.
    3230             :          */
    3231           0 :         sctp_send_cwr(stcb, net, net->last_cwr_tsn, override_bit);
    3232             : }
    3233             : 
    3234             : static void
    3235           0 : sctp_handle_ecn_cwr(struct sctp_cwr_chunk *cp, struct sctp_tcb *stcb, struct sctp_nets *net)
    3236             : {
    3237             :         /*
    3238             :          * Here we get a CWR from the peer. We must look in the outqueue and
    3239             :          * make sure that we have a covered ECNE in the control chunk part.
    3240             :          * If so remove it.
    3241             :          */
    3242             :         struct sctp_tmit_chunk *chk;
    3243             :         struct sctp_ecne_chunk *ecne;
    3244             :         int override;
    3245             :         uint32_t cwr_tsn;
    3246             : 
    3247           0 :         cwr_tsn = ntohl(cp->tsn);
    3248           0 :         override = cp->ch.chunk_flags & SCTP_CWR_REDUCE_OVERRIDE;
    3249           0 :         TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
    3250           0 :                 if (chk->rec.chunk_id.id != SCTP_ECN_ECHO) {
    3251           0 :                         continue;
    3252             :                 }
    3253           0 :                 if ((override == 0) && (chk->whoTo != net)) {
    3254             :                         /* Must be from the right src unless override is set */
    3255           0 :                         continue;
    3256             :                 }
    3257           0 :                 ecne = mtod(chk->data, struct sctp_ecne_chunk *);
    3258           0 :                 if (SCTP_TSN_GE(cwr_tsn, ntohl(ecne->tsn))) {
    3259             :                         /* this covers this ECNE, we can remove it */
    3260           0 :                         stcb->asoc.ecn_echo_cnt_onq--;
    3261           0 :                         TAILQ_REMOVE(&stcb->asoc.control_send_queue, chk,
    3262             :                             sctp_next);
    3263           0 :                         sctp_m_freem(chk->data);
    3264           0 :                         chk->data = NULL;
    3265           0 :                         stcb->asoc.ctrl_queue_cnt--;
    3266           0 :                         sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
    3267           0 :                         if (override == 0) {
    3268           0 :                                 break;
    3269             :                         }
    3270             :                 }
    3271             :         }
    3272           0 : }
    3273             : 
    3274             : static void
    3275           0 : sctp_handle_shutdown_complete(struct sctp_shutdown_complete_chunk *cp SCTP_UNUSED,
    3276             :     struct sctp_tcb *stcb, struct sctp_nets *net)
    3277             : {
    3278             :         struct sctp_association *asoc;
    3279             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    3280             :         struct socket *so;
    3281             : #endif
    3282             : 
    3283           0 :         SCTPDBG(SCTP_DEBUG_INPUT2,
    3284             :                 "sctp_handle_shutdown_complete: handling SHUTDOWN-COMPLETE\n");
    3285           0 :         if (stcb == NULL)
    3286           0 :                 return;
    3287             : 
    3288           0 :         asoc = &stcb->asoc;
    3289             :         /* process according to association state */
    3290           0 :         if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT) {
    3291             :                 /* unexpected SHUTDOWN-COMPLETE... so ignore... */
    3292           0 :                 SCTPDBG(SCTP_DEBUG_INPUT2,
    3293             :                         "sctp_handle_shutdown_complete: not in SCTP_STATE_SHUTDOWN_ACK_SENT --- ignore\n");
    3294           0 :                 SCTP_TCB_UNLOCK(stcb);
    3295           0 :                 return;
    3296             :         }
    3297             :         /* notify upper layer protocol */
    3298           0 :         if (stcb->sctp_socket) {
    3299           0 :                 sctp_ulp_notify(SCTP_NOTIFY_ASSOC_DOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
    3300             :         }
    3301             : #ifdef INVARIANTS
    3302             :         if (!TAILQ_EMPTY(&asoc->send_queue) ||
    3303             :             !TAILQ_EMPTY(&asoc->sent_queue) ||
    3304             :             !stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
    3305             :                 panic("Queues are not empty when handling SHUTDOWN-COMPLETE");
    3306             :         }
    3307             : #endif
    3308             :         /* stop the timer */
    3309           0 :         sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_22);
    3310           0 :         SCTP_STAT_INCR_COUNTER32(sctps_shutdown);
    3311             :         /* free the TCB */
    3312           0 :         SCTPDBG(SCTP_DEBUG_INPUT2,
    3313             :                 "sctp_handle_shutdown_complete: calls free-asoc\n");
    3314             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    3315             :         so = SCTP_INP_SO(stcb->sctp_ep);
    3316             :         atomic_add_int(&stcb->asoc.refcnt, 1);
    3317             :         SCTP_TCB_UNLOCK(stcb);
    3318             :         SCTP_SOCKET_LOCK(so, 1);
    3319             :         SCTP_TCB_LOCK(stcb);
    3320             :         atomic_subtract_int(&stcb->asoc.refcnt, 1);
    3321             : #endif
    3322           0 :         (void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_23);
    3323             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    3324             :         SCTP_SOCKET_UNLOCK(so, 1);
    3325             : #endif
    3326           0 :         return;
    3327             : }
    3328             : 
    3329             : static int
    3330           0 : process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
    3331             :     struct sctp_nets *net, uint8_t flg)
    3332             : {
    3333           0 :         switch (desc->chunk_type) {
    3334             :         case SCTP_DATA:
    3335             :                 /* find the tsn to resend (possibly */
    3336             :         {
    3337             :                 uint32_t tsn;
    3338             :                 struct sctp_tmit_chunk *tp1;
    3339             : 
    3340           0 :                 tsn = ntohl(desc->tsn_ifany);
    3341           0 :                 TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) {
    3342           0 :                         if (tp1->rec.data.TSN_seq == tsn) {
    3343             :                                 /* found it */
    3344           0 :                                 break;
    3345             :                         }
    3346           0 :                         if (SCTP_TSN_GT(tp1->rec.data.TSN_seq, tsn)) {
    3347             :                                 /* not found */
    3348           0 :                                 tp1 = NULL;
    3349           0 :                                 break;
    3350             :                         }
    3351             :                 }
    3352           0 :                 if (tp1 == NULL) {
    3353             :                         /*
    3354             :                          * Do it the other way , aka without paying
    3355             :                          * attention to queue seq order.
    3356             :                          */
    3357           0 :                         SCTP_STAT_INCR(sctps_pdrpdnfnd);
    3358           0 :                         TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) {
    3359           0 :                                 if (tp1->rec.data.TSN_seq == tsn) {
    3360             :                                         /* found it */
    3361           0 :                                         break;
    3362             :                                 }
    3363             :                         }
    3364             :                 }
    3365           0 :                 if (tp1 == NULL) {
    3366           0 :                         SCTP_STAT_INCR(sctps_pdrptsnnf);
    3367             :                 }
    3368           0 :                 if ((tp1) && (tp1->sent < SCTP_DATAGRAM_ACKED)) {
    3369             :                         uint8_t *ddp;
    3370             : 
    3371           0 :                         if (((flg & SCTP_BADCRC) == 0) &&
    3372           0 :                             ((flg & SCTP_FROM_MIDDLE_BOX) == 0)) {
    3373           0 :                                 return (0);
    3374             :                         }
    3375           0 :                         if ((stcb->asoc.peers_rwnd == 0) &&
    3376           0 :                             ((flg & SCTP_FROM_MIDDLE_BOX) == 0)) {
    3377           0 :                                 SCTP_STAT_INCR(sctps_pdrpdiwnp);
    3378           0 :                                 return (0);
    3379             :                         }
    3380           0 :                         if (stcb->asoc.peers_rwnd == 0 &&
    3381           0 :                             (flg & SCTP_FROM_MIDDLE_BOX)) {
    3382           0 :                                 SCTP_STAT_INCR(sctps_pdrpdizrw);
    3383           0 :                                 return (0);
    3384             :                         }
    3385           0 :                         ddp = (uint8_t *) (mtod(tp1->data, caddr_t) +
    3386             :                                            sizeof(struct sctp_data_chunk));
    3387             :                         {
    3388             :                                 unsigned int iii;
    3389             : 
    3390           0 :                                 for (iii = 0; iii < sizeof(desc->data_bytes);
    3391           0 :                                      iii++) {
    3392           0 :                                         if (ddp[iii] != desc->data_bytes[iii]) {
    3393           0 :                                                 SCTP_STAT_INCR(sctps_pdrpbadd);
    3394           0 :                                                 return (-1);
    3395             :                                         }
    3396             :                                 }
    3397             :                         }
    3398             : 
    3399           0 :                         if (tp1->do_rtt) {
    3400             :                                 /*
    3401             :                                  * this guy had a RTO calculation
    3402             :                                  * pending on it, cancel it
    3403             :                                  */
    3404           0 :                                 if (tp1->whoTo->rto_needed == 0) {
    3405           0 :                                         tp1->whoTo->rto_needed = 1;
    3406             :                                 }
    3407           0 :                                 tp1->do_rtt = 0;
    3408             :                         }
    3409           0 :                         SCTP_STAT_INCR(sctps_pdrpmark);
    3410           0 :                         if (tp1->sent != SCTP_DATAGRAM_RESEND)
    3411           0 :                                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
    3412             :                         /*
    3413             :                          * mark it as if we were doing a FR, since
    3414             :                          * we will be getting gap ack reports behind
    3415             :                          * the info from the router.
    3416             :                          */
    3417           0 :                         tp1->rec.data.doing_fast_retransmit = 1;
    3418             :                         /*
    3419             :                          * mark the tsn with what sequences can
    3420             :                          * cause a new FR.
    3421             :                          */
    3422           0 :                         if (TAILQ_EMPTY(&stcb->asoc.send_queue)) {
    3423           0 :                                 tp1->rec.data.fast_retran_tsn = stcb->asoc.sending_seq;
    3424             :                         } else {
    3425           0 :                                 tp1->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.TSN_seq;
    3426             :                         }
    3427             : 
    3428             :                         /* restart the timer */
    3429           0 :                         sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
    3430             :                                         stcb, tp1->whoTo, SCTP_FROM_SCTP_INPUT+SCTP_LOC_24);
    3431           0 :                         sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
    3432             :                                          stcb, tp1->whoTo);
    3433             : 
    3434             :                         /* fix counts and things */
    3435           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
    3436           0 :                                 sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_PDRP,
    3437           0 :                                                tp1->whoTo->flight_size,
    3438           0 :                                                tp1->book_size,
    3439             :                                                (uintptr_t)stcb,
    3440             :                                                tp1->rec.data.TSN_seq);
    3441             :                         }
    3442           0 :                         if (tp1->sent < SCTP_DATAGRAM_RESEND) {
    3443           0 :                                 sctp_flight_size_decrease(tp1);
    3444           0 :                                 sctp_total_flight_decrease(stcb, tp1);
    3445             :                         }
    3446           0 :                         tp1->sent = SCTP_DATAGRAM_RESEND;
    3447             :                 } {
    3448             :                         /* audit code */
    3449             :                         unsigned int audit;
    3450             : 
    3451           0 :                         audit = 0;
    3452           0 :                         TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) {
    3453           0 :                                 if (tp1->sent == SCTP_DATAGRAM_RESEND)
    3454           0 :                                         audit++;
    3455             :                         }
    3456           0 :                         TAILQ_FOREACH(tp1, &stcb->asoc.control_send_queue,
    3457             :                                       sctp_next) {
    3458           0 :                                 if (tp1->sent == SCTP_DATAGRAM_RESEND)
    3459           0 :                                         audit++;
    3460             :                         }
    3461           0 :                         if (audit != stcb->asoc.sent_queue_retran_cnt) {
    3462           0 :                                 SCTP_PRINTF("**Local Audit finds cnt:%d asoc cnt:%d\n",
    3463             :                                             audit, stcb->asoc.sent_queue_retran_cnt);
    3464             : #ifndef SCTP_AUDITING_ENABLED
    3465           0 :                                 stcb->asoc.sent_queue_retran_cnt = audit;
    3466             : #endif
    3467             :                         }
    3468             :                 }
    3469             :         }
    3470           0 :         break;
    3471             :         case SCTP_ASCONF:
    3472             :         {
    3473             :                 struct sctp_tmit_chunk *asconf;
    3474             : 
    3475           0 :                 TAILQ_FOREACH(asconf, &stcb->asoc.control_send_queue,
    3476             :                               sctp_next) {
    3477           0 :                         if (asconf->rec.chunk_id.id == SCTP_ASCONF) {
    3478           0 :                                 break;
    3479             :                         }
    3480             :                 }
    3481           0 :                 if (asconf) {
    3482           0 :                         if (asconf->sent != SCTP_DATAGRAM_RESEND)
    3483           0 :                                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
    3484           0 :                         asconf->sent = SCTP_DATAGRAM_RESEND;
    3485           0 :                         asconf->snd_count--;
    3486             :                 }
    3487             :         }
    3488           0 :         break;
    3489             :         case SCTP_INITIATION:
    3490             :                 /* resend the INIT */
    3491           0 :                 stcb->asoc.dropped_special_cnt++;
    3492           0 :                 if (stcb->asoc.dropped_special_cnt < SCTP_RETRY_DROPPED_THRESH) {
    3493             :                         /*
    3494             :                          * If we can get it in, in a few attempts we do
    3495             :                          * this, otherwise we let the timer fire.
    3496             :                          */
    3497           0 :                         sctp_timer_stop(SCTP_TIMER_TYPE_INIT, stcb->sctp_ep,
    3498             :                                         stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_25);
    3499           0 :                         sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
    3500             :                 }
    3501           0 :                 break;
    3502             :         case SCTP_SELECTIVE_ACK:
    3503             :         case SCTP_NR_SELECTIVE_ACK:
    3504             :                 /* resend the sack */
    3505           0 :                 sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
    3506           0 :                 break;
    3507             :         case SCTP_HEARTBEAT_REQUEST:
    3508             :                 /* resend a demand HB */
    3509           0 :                 if ((stcb->asoc.overall_error_count + 3) < stcb->asoc.max_send_times) {
    3510             :                         /* Only retransmit if we KNOW we wont destroy the tcb */
    3511           0 :                         sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
    3512             :                 }
    3513           0 :                 break;
    3514             :         case SCTP_SHUTDOWN:
    3515           0 :                 sctp_send_shutdown(stcb, net);
    3516           0 :                 break;
    3517             :         case SCTP_SHUTDOWN_ACK:
    3518           0 :                 sctp_send_shutdown_ack(stcb, net);
    3519           0 :                 break;
    3520             :         case SCTP_COOKIE_ECHO:
    3521             :         {
    3522             :                 struct sctp_tmit_chunk *cookie;
    3523             : 
    3524           0 :                 cookie = NULL;
    3525           0 :                 TAILQ_FOREACH(cookie, &stcb->asoc.control_send_queue,
    3526             :                               sctp_next) {
    3527           0 :                         if (cookie->rec.chunk_id.id == SCTP_COOKIE_ECHO) {
    3528           0 :                                 break;
    3529             :                         }
    3530             :                 }
    3531           0 :                 if (cookie) {
    3532           0 :                         if (cookie->sent != SCTP_DATAGRAM_RESEND)
    3533           0 :                                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
    3534           0 :                         cookie->sent = SCTP_DATAGRAM_RESEND;
    3535           0 :                         sctp_stop_all_cookie_timers(stcb);
    3536             :                 }
    3537             :         }
    3538           0 :         break;
    3539             :         case SCTP_COOKIE_ACK:
    3540           0 :                 sctp_send_cookie_ack(stcb);
    3541           0 :                 break;
    3542             :         case SCTP_ASCONF_ACK:
    3543             :                 /* resend last asconf ack */
    3544           0 :                 sctp_send_asconf_ack(stcb);
    3545           0 :                 break;
    3546             :         case SCTP_FORWARD_CUM_TSN:
    3547           0 :                 send_forward_tsn(stcb, &stcb->asoc);
    3548           0 :                 break;
    3549             :                 /* can't do anything with these */
    3550             :         case SCTP_PACKET_DROPPED:
    3551             :         case SCTP_INITIATION_ACK:       /* this should not happen */
    3552             :         case SCTP_HEARTBEAT_ACK:
    3553             :         case SCTP_ABORT_ASSOCIATION:
    3554             :         case SCTP_OPERATION_ERROR:
    3555             :         case SCTP_SHUTDOWN_COMPLETE:
    3556             :         case SCTP_ECN_ECHO:
    3557             :         case SCTP_ECN_CWR:
    3558             :         default:
    3559           0 :                 break;
    3560             :         }
    3561           0 :         return (0);
    3562             : }
    3563             : 
    3564             : void
    3565           0 : sctp_reset_in_stream(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t *list)
    3566             : {
    3567             :         uint32_t i;
    3568             :         uint16_t temp;
    3569             : 
    3570             :         /*
    3571             :          * We set things to 0xffff since this is the last delivered sequence
    3572             :          * and we will be sending in 0 after the reset.
    3573             :          */
    3574             : 
    3575           0 :         if (number_entries) {
    3576           0 :                 for (i = 0; i < number_entries; i++) {
    3577           0 :                         temp = ntohs(list[i]);
    3578           0 :                         if (temp >= stcb->asoc.streamincnt) {
    3579           0 :                                 continue;
    3580             :                         }
    3581           0 :                         stcb->asoc.strmin[temp].last_sequence_delivered = 0xffff;
    3582             :                 }
    3583             :         } else {
    3584           0 :                 list = NULL;
    3585           0 :                 for (i = 0; i < stcb->asoc.streamincnt; i++) {
    3586           0 :                         stcb->asoc.strmin[i].last_sequence_delivered = 0xffff;
    3587             :                 }
    3588             :         }
    3589           0 :         sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_RECV, stcb, number_entries, (void *)list, SCTP_SO_NOT_LOCKED);
    3590           0 : }
    3591             : 
    3592             : static void
    3593           0 : sctp_reset_out_streams(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t *list)
    3594             : {
    3595             :         uint32_t i;
    3596             :         uint16_t temp;
    3597             : 
    3598           0 :         if (number_entries > 0) {
    3599           0 :                 for (i = 0; i < number_entries; i++) {
    3600           0 :                         temp = ntohs(list[i]);
    3601           0 :                         if (temp >= stcb->asoc.streamoutcnt) {
    3602             :                                 /* no such stream */
    3603           0 :                                 continue;
    3604             :                         }
    3605           0 :                         stcb->asoc.strmout[temp].next_sequence_send = 0;
    3606             :                 }
    3607             :         } else {
    3608           0 :                 for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
    3609           0 :                         stcb->asoc.strmout[i].next_sequence_send = 0;
    3610             :                 }
    3611             :         }
    3612           0 :         sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_SEND, stcb, number_entries, (void *)list, SCTP_SO_NOT_LOCKED);
    3613           0 : }
    3614             : 
    3615             : 
    3616             : struct sctp_stream_reset_request *
    3617           0 : sctp_find_stream_reset(struct sctp_tcb *stcb, uint32_t seq, struct sctp_tmit_chunk **bchk)
    3618             : {
    3619             :         struct sctp_association *asoc;
    3620             :         struct sctp_chunkhdr *ch;
    3621             :         struct sctp_stream_reset_request *r;
    3622             :         struct sctp_tmit_chunk *chk;
    3623             :         int len, clen;
    3624             : 
    3625           0 :         asoc = &stcb->asoc;
    3626           0 :         if (TAILQ_EMPTY(&stcb->asoc.control_send_queue)) {
    3627           0 :                 asoc->stream_reset_outstanding = 0;
    3628           0 :                 return (NULL);
    3629             :         }
    3630           0 :         if (stcb->asoc.str_reset == NULL) {
    3631           0 :                 asoc->stream_reset_outstanding = 0;
    3632           0 :                 return (NULL);
    3633             :         }
    3634           0 :         chk = stcb->asoc.str_reset;
    3635           0 :         if (chk->data == NULL) {
    3636           0 :                 return (NULL);
    3637             :         }
    3638           0 :         if (bchk) {
    3639             :                 /* he wants a copy of the chk pointer */
    3640           0 :                 *bchk = chk;
    3641             :         }
    3642           0 :         clen = chk->send_size;
    3643           0 :         ch = mtod(chk->data, struct sctp_chunkhdr *);
    3644           0 :         r = (struct sctp_stream_reset_request *)(ch + 1);
    3645           0 :         if (ntohl(r->request_seq) == seq) {
    3646             :                 /* found it */
    3647           0 :                 return (r);
    3648             :         }
    3649           0 :         len = SCTP_SIZE32(ntohs(r->ph.param_length));
    3650           0 :         if (clen > (len + (int)sizeof(struct sctp_chunkhdr))) {
    3651             :                 /* move to the next one, there can only be a max of two */
    3652           0 :                 r = (struct sctp_stream_reset_request *)((caddr_t)r + len);
    3653           0 :                 if (ntohl(r->request_seq) == seq) {
    3654           0 :                         return (r);
    3655             :                 }
    3656             :         }
    3657             :         /* that seq is not here */
    3658           0 :         return (NULL);
    3659             : }
    3660             : 
    3661             : static void
    3662           0 : sctp_clean_up_stream_reset(struct sctp_tcb *stcb)
    3663             : {
    3664             :         struct sctp_association *asoc;
    3665           0 :         struct sctp_tmit_chunk *chk = stcb->asoc.str_reset;
    3666             : 
    3667           0 :         if (stcb->asoc.str_reset == NULL) {
    3668           0 :                 return;
    3669             :         }
    3670           0 :         asoc = &stcb->asoc;
    3671             : 
    3672           0 :         sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, stcb->sctp_ep, stcb, chk->whoTo, SCTP_FROM_SCTP_INPUT+SCTP_LOC_26);
    3673           0 :         TAILQ_REMOVE(&asoc->control_send_queue,
    3674             :             chk,
    3675             :             sctp_next);
    3676           0 :         if (chk->data) {
    3677           0 :                 sctp_m_freem(chk->data);
    3678           0 :                 chk->data = NULL;
    3679             :         }
    3680           0 :         asoc->ctrl_queue_cnt--;
    3681           0 :         sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
    3682             :         /*sa_ignore NO_NULL_CHK*/
    3683           0 :         stcb->asoc.str_reset = NULL;
    3684             : }
    3685             : 
    3686             : 
    3687             : static int
    3688           0 : sctp_handle_stream_reset_response(struct sctp_tcb *stcb,
    3689             :                                   uint32_t seq, uint32_t action,
    3690             :                                   struct sctp_stream_reset_response *respin)
    3691             : {
    3692             :         uint16_t type;
    3693             :         int lparm_len;
    3694           0 :         struct sctp_association *asoc = &stcb->asoc;
    3695             :         struct sctp_tmit_chunk *chk;
    3696             :         struct sctp_stream_reset_request *req_param;
    3697             :         struct sctp_stream_reset_out_request *req_out_param;
    3698             :         struct sctp_stream_reset_in_request *req_in_param;
    3699             :         uint32_t number_entries;
    3700             : 
    3701           0 :         if (asoc->stream_reset_outstanding == 0) {
    3702             :                 /* duplicate */
    3703           0 :                 return (0);
    3704             :         }
    3705           0 :         if (seq == stcb->asoc.str_reset_seq_out) {
    3706           0 :                 req_param = sctp_find_stream_reset(stcb, seq, &chk);
    3707           0 :                 if (req_param != NULL) {
    3708           0 :                         stcb->asoc.str_reset_seq_out++;
    3709           0 :                         type = ntohs(req_param->ph.param_type);
    3710           0 :                         lparm_len = ntohs(req_param->ph.param_length);
    3711           0 :                         if (type == SCTP_STR_RESET_OUT_REQUEST) {
    3712           0 :                                 req_out_param = (struct sctp_stream_reset_out_request *)req_param;
    3713           0 :                                 number_entries = (lparm_len - sizeof(struct sctp_stream_reset_out_request)) / sizeof(uint16_t);
    3714           0 :                                 asoc->stream_reset_out_is_outstanding = 0;
    3715           0 :                                 if (asoc->stream_reset_outstanding)
    3716           0 :                                         asoc->stream_reset_outstanding--;
    3717           0 :                                 if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) {
    3718             :                                         /* do it */
    3719           0 :                                         sctp_reset_out_streams(stcb, number_entries, req_out_param->list_of_streams);
    3720           0 :                                 } else if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
    3721           0 :                                         sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_DENIED_OUT, stcb, number_entries, req_out_param->list_of_streams, SCTP_SO_NOT_LOCKED);
    3722             :                                 } else {
    3723           0 :                                         sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_OUT, stcb, number_entries, req_out_param->list_of_streams, SCTP_SO_NOT_LOCKED);
    3724             :                                 }
    3725           0 :                         } else if (type == SCTP_STR_RESET_IN_REQUEST) {
    3726           0 :                                 req_in_param = (struct sctp_stream_reset_in_request *)req_param;
    3727           0 :                                 number_entries = (lparm_len - sizeof(struct sctp_stream_reset_in_request)) / sizeof(uint16_t);
    3728           0 :                                 if (asoc->stream_reset_outstanding)
    3729           0 :                                         asoc->stream_reset_outstanding--;
    3730           0 :                                 if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
    3731           0 :                                         sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_DENIED_IN, stcb,
    3732           0 :                                                         number_entries, req_in_param->list_of_streams, SCTP_SO_NOT_LOCKED);
    3733           0 :                                 } else if (action != SCTP_STREAM_RESET_RESULT_PERFORMED) {
    3734           0 :                                         sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_IN, stcb,
    3735           0 :                                                         number_entries, req_in_param->list_of_streams, SCTP_SO_NOT_LOCKED);
    3736             :                                 }
    3737           0 :                         } else if (type == SCTP_STR_RESET_ADD_OUT_STREAMS) {
    3738             :                                 /* Ok we now may have more streams */
    3739             :                                 int num_stream;
    3740             : 
    3741           0 :                                 num_stream = stcb->asoc.strm_pending_add_size;
    3742           0 :                                 if (num_stream > (stcb->asoc.strm_realoutsize - stcb->asoc.streamoutcnt)) {
    3743             :                                         /* TSNH */
    3744           0 :                                         num_stream = stcb->asoc.strm_realoutsize - stcb->asoc.streamoutcnt;
    3745             :                                 }
    3746           0 :                                 stcb->asoc.strm_pending_add_size = 0;
    3747           0 :                                 if (asoc->stream_reset_outstanding)
    3748           0 :                                         asoc->stream_reset_outstanding--;
    3749           0 :                                 if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) {
    3750             :                                         /* Put the new streams into effect */
    3751           0 :                                         stcb->asoc.streamoutcnt += num_stream;
    3752           0 :                                         sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt, 0);
    3753           0 :                                 } else if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
    3754           0 :                                         sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
    3755             :                                                                      SCTP_STREAM_CHANGE_DENIED);
    3756             :                                 } else {
    3757           0 :                                         sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
    3758             :                                                                      SCTP_STREAM_CHANGE_FAILED);
    3759             :                                 }
    3760           0 :                         } else if (type == SCTP_STR_RESET_ADD_IN_STREAMS) {
    3761           0 :                                 if (asoc->stream_reset_outstanding)
    3762           0 :                                         asoc->stream_reset_outstanding--;
    3763           0 :                                 if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
    3764           0 :                                         sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
    3765             :                                                                      SCTP_STREAM_CHANGE_DENIED);
    3766           0 :                                 } else if (action != SCTP_STREAM_RESET_RESULT_PERFORMED) {
    3767           0 :                                         sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
    3768             :                                                                      SCTP_STREAM_CHANGE_FAILED);
    3769             :                                 }
    3770           0 :                         } else if (type == SCTP_STR_RESET_TSN_REQUEST) {
    3771             :                                 /**
    3772             :                                  * a) Adopt the new in tsn.
    3773             :                                  * b) reset the map
    3774             :                                  * c) Adopt the new out-tsn
    3775             :                                  */
    3776             :                                 struct sctp_stream_reset_response_tsn *resp;
    3777             :                                 struct sctp_forward_tsn_chunk fwdtsn;
    3778           0 :                                 int abort_flag = 0;
    3779           0 :                                 if (respin == NULL) {
    3780             :                                         /* huh ? */
    3781           0 :                                         return (0);
    3782             :                                 }
    3783           0 :                                 if (ntohs(respin->ph.param_length) < sizeof(struct sctp_stream_reset_response_tsn)) {
    3784           0 :                                         return (0);
    3785             :                                 }
    3786           0 :                                 if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) {
    3787           0 :                                         resp = (struct sctp_stream_reset_response_tsn *)respin;
    3788           0 :                                         asoc->stream_reset_outstanding--;
    3789           0 :                                         fwdtsn.ch.chunk_length = htons(sizeof(struct sctp_forward_tsn_chunk));
    3790           0 :                                         fwdtsn.ch.chunk_type = SCTP_FORWARD_CUM_TSN;
    3791           0 :                                         fwdtsn.new_cumulative_tsn = htonl(ntohl(resp->senders_next_tsn) - 1);
    3792           0 :                                         sctp_handle_forward_tsn(stcb, &fwdtsn, &abort_flag, NULL, 0);
    3793           0 :                                         if (abort_flag) {
    3794           0 :                                                 return (1);
    3795             :                                         }
    3796           0 :                                         stcb->asoc.highest_tsn_inside_map = (ntohl(resp->senders_next_tsn) - 1);
    3797           0 :                                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
    3798           0 :                                                 sctp_log_map(0, 7, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
    3799             :                                         }
    3800             : 
    3801           0 :                                         stcb->asoc.tsn_last_delivered = stcb->asoc.cumulative_tsn = stcb->asoc.highest_tsn_inside_map;
    3802           0 :                                         stcb->asoc.mapping_array_base_tsn = ntohl(resp->senders_next_tsn);
    3803           0 :                                         memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size);
    3804             : 
    3805           0 :                                         stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
    3806           0 :                                         memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.mapping_array_size);
    3807             : 
    3808           0 :                                         stcb->asoc.sending_seq = ntohl(resp->receivers_next_tsn);
    3809           0 :                                         stcb->asoc.last_acked_seq = stcb->asoc.cumulative_tsn;
    3810             : 
    3811           0 :                                         sctp_reset_out_streams(stcb, 0, (uint16_t *) NULL);
    3812           0 :                                         sctp_reset_in_stream(stcb, 0, (uint16_t *) NULL);
    3813           0 :                                         sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1), 0);
    3814           0 :                                 } else if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
    3815           0 :                                         sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1),
    3816             :                                                                      SCTP_ASSOC_RESET_DENIED);
    3817             :                                 } else {
    3818           0 :                                         sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1),
    3819             :                                                                      SCTP_ASSOC_RESET_FAILED);
    3820             :                                 }
    3821             :                         }
    3822             :                         /* get rid of the request and get the request flags */
    3823           0 :                         if (asoc->stream_reset_outstanding == 0) {
    3824           0 :                                 sctp_clean_up_stream_reset(stcb);
    3825             :                         }
    3826             :                 }
    3827             :         }
    3828           0 :         return (0);
    3829             : }
    3830             : 
    3831             : static void
    3832           0 : sctp_handle_str_reset_request_in(struct sctp_tcb *stcb,
    3833             :     struct sctp_tmit_chunk *chk,
    3834             :     struct sctp_stream_reset_in_request *req, int trunc)
    3835             : {
    3836             :         uint32_t seq;
    3837             :         int len, i;
    3838             :         int number_entries;
    3839             :         uint16_t temp;
    3840             : 
    3841             :         /*
    3842             :          * peer wants me to send a str-reset to him for my outgoing seq's if
    3843             :          * seq_in is right.
    3844             :          */
    3845           0 :         struct sctp_association *asoc = &stcb->asoc;
    3846             : 
    3847           0 :         seq = ntohl(req->request_seq);
    3848           0 :         if (asoc->str_reset_seq_in == seq) {
    3849           0 :                 asoc->last_reset_action[1] = asoc->last_reset_action[0];
    3850           0 :                 if (!(asoc->local_strreset_support & SCTP_ENABLE_RESET_STREAM_REQ)) {
    3851           0 :                         asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
    3852           0 :                 } else if (trunc) {
    3853             :                         /* Can't do it, since they exceeded our buffer size  */
    3854           0 :                         asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
    3855           0 :                 } else if (stcb->asoc.stream_reset_out_is_outstanding == 0) {
    3856           0 :                         len = ntohs(req->ph.param_length);
    3857           0 :                         number_entries = ((len - sizeof(struct sctp_stream_reset_in_request)) / sizeof(uint16_t));
    3858           0 :                         for (i = 0; i < number_entries; i++) {
    3859           0 :                                 temp = ntohs(req->list_of_streams[i]);
    3860           0 :                                 req->list_of_streams[i] = temp;
    3861             :                         }
    3862           0 :                         asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
    3863           0 :                         sctp_add_stream_reset_out(chk, number_entries, req->list_of_streams,
    3864             :                             asoc->str_reset_seq_out,
    3865           0 :                             seq, (asoc->sending_seq - 1));
    3866           0 :                         asoc->stream_reset_out_is_outstanding = 1;
    3867           0 :                         asoc->str_reset = chk;
    3868           0 :                         sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, stcb->sctp_ep, stcb, chk->whoTo);
    3869           0 :                         stcb->asoc.stream_reset_outstanding++;
    3870             :                 } else {
    3871             :                         /* Can't do it, since we have sent one out */
    3872           0 :                         asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_ERR_IN_PROGRESS;
    3873             :                 }
    3874           0 :                 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
    3875           0 :                 asoc->str_reset_seq_in++;
    3876           0 :         } else if (asoc->str_reset_seq_in - 1 == seq) {
    3877           0 :                 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
    3878           0 :         } else if (asoc->str_reset_seq_in - 2 == seq) {
    3879           0 :                 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
    3880             :         } else {
    3881           0 :                 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
    3882             :         }
    3883           0 : }
    3884             : 
    3885             : static int
    3886           0 : sctp_handle_str_reset_request_tsn(struct sctp_tcb *stcb,
    3887             :     struct sctp_tmit_chunk *chk,
    3888             :     struct sctp_stream_reset_tsn_request *req)
    3889             : {
    3890             :         /* reset all in and out and update the tsn */
    3891             :         /*
    3892             :          * A) reset my str-seq's on in and out. B) Select a receive next,
    3893             :          * and set cum-ack to it. Also process this selected number as a
    3894             :          * fwd-tsn as well. C) set in the response my next sending seq.
    3895             :          */
    3896             :         struct sctp_forward_tsn_chunk fwdtsn;
    3897           0 :         struct sctp_association *asoc = &stcb->asoc;
    3898           0 :         int abort_flag = 0;
    3899             :         uint32_t seq;
    3900             : 
    3901           0 :         seq = ntohl(req->request_seq);
    3902           0 :         if (asoc->str_reset_seq_in == seq) {
    3903           0 :                 asoc->last_reset_action[1] = stcb->asoc.last_reset_action[0];
    3904           0 :                 if (!(asoc->local_strreset_support & SCTP_ENABLE_CHANGE_ASSOC_REQ)) {
    3905           0 :                         asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
    3906             :                 } else {
    3907           0 :                         fwdtsn.ch.chunk_length = htons(sizeof(struct sctp_forward_tsn_chunk));
    3908           0 :                         fwdtsn.ch.chunk_type = SCTP_FORWARD_CUM_TSN;
    3909           0 :                         fwdtsn.ch.chunk_flags = 0;
    3910           0 :                         fwdtsn.new_cumulative_tsn = htonl(stcb->asoc.highest_tsn_inside_map + 1);
    3911           0 :                         sctp_handle_forward_tsn(stcb, &fwdtsn, &abort_flag, NULL, 0);
    3912           0 :                         if (abort_flag) {
    3913           0 :                                 return (1);
    3914             :                         }
    3915           0 :                         asoc->highest_tsn_inside_map += SCTP_STREAM_RESET_TSN_DELTA;
    3916           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
    3917           0 :                                 sctp_log_map(0, 10, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
    3918             :                         }
    3919           0 :                         asoc->tsn_last_delivered = asoc->cumulative_tsn = asoc->highest_tsn_inside_map;
    3920           0 :                         asoc->mapping_array_base_tsn = asoc->highest_tsn_inside_map + 1;
    3921           0 :                         memset(asoc->mapping_array, 0, asoc->mapping_array_size);
    3922           0 :                         asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map;
    3923           0 :                         memset(asoc->nr_mapping_array, 0, asoc->mapping_array_size);
    3924           0 :                         atomic_add_int(&asoc->sending_seq, 1);
    3925             :                         /* save off historical data for retrans */
    3926           0 :                         asoc->last_sending_seq[1] = asoc->last_sending_seq[0];
    3927           0 :                         asoc->last_sending_seq[0] = asoc->sending_seq;
    3928           0 :                         asoc->last_base_tsnsent[1] = asoc->last_base_tsnsent[0];
    3929           0 :                         asoc->last_base_tsnsent[0] = asoc->mapping_array_base_tsn;
    3930           0 :                         sctp_reset_out_streams(stcb, 0, (uint16_t *) NULL);
    3931           0 :                         sctp_reset_in_stream(stcb, 0, (uint16_t *) NULL);
    3932           0 :                         asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
    3933           0 :                         sctp_notify_stream_reset_tsn(stcb, asoc->sending_seq, (asoc->mapping_array_base_tsn + 1), 0);
    3934             :                 }
    3935           0 :                 sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[0],
    3936             :                                                  asoc->last_sending_seq[0], asoc->last_base_tsnsent[0]);
    3937           0 :                 asoc->str_reset_seq_in++;
    3938           0 :         } else if (asoc->str_reset_seq_in - 1 == seq) {
    3939           0 :                 sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[0],
    3940             :                                                  asoc->last_sending_seq[0], asoc->last_base_tsnsent[0]);
    3941           0 :         } else if (asoc->str_reset_seq_in - 2 == seq) {
    3942           0 :                 sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[1],
    3943             :                                                  asoc->last_sending_seq[1], asoc->last_base_tsnsent[1]);
    3944             :         } else {
    3945           0 :                 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
    3946             :         }
    3947           0 :         return (0);
    3948             : }
    3949             : 
    3950             : static void
    3951           0 : sctp_handle_str_reset_request_out(struct sctp_tcb *stcb,
    3952             :     struct sctp_tmit_chunk *chk,
    3953             :     struct sctp_stream_reset_out_request *req, int trunc)
    3954             : {
    3955             :         uint32_t seq, tsn;
    3956             :         int number_entries, len;
    3957           0 :         struct sctp_association *asoc = &stcb->asoc;
    3958             : 
    3959           0 :         seq = ntohl(req->request_seq);
    3960             : 
    3961             :         /* now if its not a duplicate we process it */
    3962           0 :         if (asoc->str_reset_seq_in == seq) {
    3963           0 :                 len = ntohs(req->ph.param_length);
    3964           0 :                 number_entries = ((len - sizeof(struct sctp_stream_reset_out_request)) / sizeof(uint16_t));
    3965             :                 /*
    3966             :                  * the sender is resetting, handle the list issue.. we must
    3967             :                  * a) verify if we can do the reset, if so no problem b) If
    3968             :                  * we can't do the reset we must copy the request. c) queue
    3969             :                  * it, and setup the data in processor to trigger it off
    3970             :                  * when needed and dequeue all the queued data.
    3971             :                  */
    3972           0 :                 tsn = ntohl(req->send_reset_at_tsn);
    3973             : 
    3974             :                 /* move the reset action back one */
    3975           0 :                 asoc->last_reset_action[1] = asoc->last_reset_action[0];
    3976           0 :                 if (!(asoc->local_strreset_support & SCTP_ENABLE_RESET_STREAM_REQ)) {
    3977           0 :                         asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
    3978           0 :                 } else if (trunc) {
    3979           0 :                         asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
    3980           0 :                 } else if (SCTP_TSN_GE(asoc->cumulative_tsn, tsn)) {
    3981             :                         /* we can do it now */
    3982           0 :                         sctp_reset_in_stream(stcb, number_entries, req->list_of_streams);
    3983           0 :                         asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
    3984             :                 } else {
    3985             :                         /*
    3986             :                          * we must queue it up and thus wait for the TSN's
    3987             :                          * to arrive that are at or before tsn
    3988             :                          */
    3989             :                         struct sctp_stream_reset_list *liste;
    3990             :                         int siz;
    3991             : 
    3992           0 :                         siz = sizeof(struct sctp_stream_reset_list) + (number_entries * sizeof(uint16_t));
    3993           0 :                         SCTP_MALLOC(liste, struct sctp_stream_reset_list *,
    3994             :                                     siz, SCTP_M_STRESET);
    3995           0 :                         if (liste == NULL) {
    3996             :                                 /* gak out of memory */
    3997           0 :                                 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
    3998           0 :                                 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
    3999           0 :                                 return;
    4000             :                         }
    4001           0 :                         liste->tsn = tsn;
    4002           0 :                         liste->number_entries = number_entries;
    4003           0 :                         memcpy(&liste->list_of_streams, req->list_of_streams, number_entries * sizeof(uint16_t));
    4004           0 :                         TAILQ_INSERT_TAIL(&asoc->resetHead, liste, next_resp);
    4005           0 :                         asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
    4006             :                 }
    4007           0 :                 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
    4008           0 :                 asoc->str_reset_seq_in++;
    4009           0 :         } else if ((asoc->str_reset_seq_in - 1) == seq) {
    4010             :                 /*
    4011             :                  * one seq back, just echo back last action since my
    4012             :                  * response was lost.
    4013             :                  */
    4014           0 :                 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
    4015           0 :         } else if ((asoc->str_reset_seq_in - 2) == seq) {
    4016             :                 /*
    4017             :                  * two seq back, just echo back last action since my
    4018             :                  * response was lost.
    4019             :                  */
    4020           0 :                 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
    4021             :         } else {
    4022           0 :                 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
    4023             :         }
    4024             : }
    4025             : 
    4026             : static void
    4027           0 : sctp_handle_str_reset_add_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *chk,
    4028             :                                struct sctp_stream_reset_add_strm  *str_add)
    4029             : {
    4030             :         /*
    4031             :          * Peer is requesting to add more streams.
    4032             :          * If its within our max-streams we will
    4033             :          * allow it.
    4034             :          */
    4035             :         uint32_t num_stream, i;
    4036             :         uint32_t seq;
    4037           0 :         struct sctp_association *asoc = &stcb->asoc;
    4038             :         struct sctp_queued_to_read *ctl, *nctl;
    4039             : 
    4040             :         /* Get the number. */
    4041           0 :         seq = ntohl(str_add->request_seq);
    4042           0 :         num_stream = ntohs(str_add->number_of_streams);
    4043             :         /* Now what would be the new total? */
    4044           0 :         if (asoc->str_reset_seq_in == seq) {
    4045           0 :                 num_stream += stcb->asoc.streamincnt;
    4046           0 :                 stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
    4047           0 :                 if (!(asoc->local_strreset_support & SCTP_ENABLE_CHANGE_ASSOC_REQ)) {
    4048           0 :                         asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
    4049           0 :                 } else if ((num_stream > stcb->asoc.max_inbound_streams) ||
    4050             :                            (num_stream > 0xffff)) {
    4051             :                         /* We must reject it they ask for to many */
    4052             :   denied:
    4053           0 :                         stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
    4054             :                 } else {
    4055             :                         /* Ok, we can do that :-) */
    4056             :                         struct sctp_stream_in *oldstrm;
    4057             : 
    4058             :                         /* save off the old */
    4059           0 :                         oldstrm = stcb->asoc.strmin;
    4060           0 :                         SCTP_MALLOC(stcb->asoc.strmin, struct sctp_stream_in *,
    4061             :                                     (num_stream * sizeof(struct sctp_stream_in)),
    4062             :                                     SCTP_M_STRMI);
    4063           0 :                         if (stcb->asoc.strmin == NULL) {
    4064           0 :                                 stcb->asoc.strmin = oldstrm;
    4065           0 :                                 goto denied;
    4066             :                         }
    4067             :                         /* copy off the old data */
    4068           0 :                         for (i = 0; i < stcb->asoc.streamincnt; i++) {
    4069           0 :                                 TAILQ_INIT(&stcb->asoc.strmin[i].inqueue);
    4070           0 :                                 stcb->asoc.strmin[i].stream_no = i;
    4071           0 :                                 stcb->asoc.strmin[i].last_sequence_delivered = oldstrm[i].last_sequence_delivered;
    4072           0 :                                 stcb->asoc.strmin[i].delivery_started = oldstrm[i].delivery_started;
    4073             :                                 /* now anything on those queues? */
    4074           0 :                                 TAILQ_FOREACH_SAFE(ctl, &oldstrm[i].inqueue, next, nctl) {
    4075           0 :                                         TAILQ_REMOVE(&oldstrm[i].inqueue, ctl, next);
    4076           0 :                                         TAILQ_INSERT_TAIL(&stcb->asoc.strmin[i].inqueue, ctl, next);
    4077             :                                 }
    4078             :                         }
    4079             :                         /* Init the new streams */
    4080           0 :                         for (i = stcb->asoc.streamincnt; i < num_stream; i++) {
    4081           0 :                                 TAILQ_INIT(&stcb->asoc.strmin[i].inqueue);
    4082           0 :                                 stcb->asoc.strmin[i].stream_no = i;
    4083           0 :                                 stcb->asoc.strmin[i].last_sequence_delivered = 0xffff;
    4084           0 :                                 stcb->asoc.strmin[i].delivery_started = 0;
    4085             :                         }
    4086           0 :                         SCTP_FREE(oldstrm, SCTP_M_STRMI);
    4087             :                         /* update the size */
    4088           0 :                         stcb->asoc.streamincnt = num_stream;
    4089           0 :                         stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
    4090           0 :                         sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt, 0);
    4091             :                 }
    4092           0 :                 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
    4093           0 :                 asoc->str_reset_seq_in++;
    4094           0 :         } else if ((asoc->str_reset_seq_in - 1) == seq) {
    4095             :                 /*
    4096             :                  * one seq back, just echo back last action since my
    4097             :                  * response was lost.
    4098             :                  */
    4099           0 :                 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
    4100           0 :         } else if ((asoc->str_reset_seq_in - 2) == seq) {
    4101             :                 /*
    4102             :                  * two seq back, just echo back last action since my
    4103             :                  * response was lost.
    4104             :                  */
    4105           0 :                 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
    4106             :         } else {
    4107           0 :                 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
    4108             : 
    4109             :         }
    4110           0 : }
    4111             : 
    4112             : static void
    4113           0 : sctp_handle_str_reset_add_out_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *chk,
    4114             :                                    struct sctp_stream_reset_add_strm  *str_add)
    4115             : {
    4116             :         /*
    4117             :          * Peer is requesting to add more streams.
    4118             :          * If its within our max-streams we will
    4119             :          * allow it.
    4120             :          */
    4121             :         uint16_t num_stream;
    4122             :         uint32_t seq;
    4123           0 :         struct sctp_association *asoc = &stcb->asoc;
    4124             : 
    4125             :         /* Get the number. */
    4126           0 :         seq = ntohl(str_add->request_seq);
    4127           0 :         num_stream = ntohs(str_add->number_of_streams);
    4128             :         /* Now what would be the new total? */
    4129           0 :         if (asoc->str_reset_seq_in == seq) {
    4130           0 :                 stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
    4131           0 :                 if (!(asoc->local_strreset_support & SCTP_ENABLE_CHANGE_ASSOC_REQ)) {
    4132           0 :                         asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
    4133           0 :                 } else if (stcb->asoc.stream_reset_outstanding) {
    4134             :                         /* We must reject it we have something pending */
    4135           0 :                         stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_ERR_IN_PROGRESS;
    4136             :                 } else {
    4137             :                         /* Ok, we can do that :-) */
    4138             :                         int mychk;
    4139           0 :                         mychk = stcb->asoc.streamoutcnt;
    4140           0 :                         mychk += num_stream;
    4141           0 :                         if (mychk < 0x10000) {
    4142           0 :                                 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
    4143           0 :                                 if (sctp_send_str_reset_req(stcb, 0, NULL, 0, 0, 0, 1, num_stream, 0, 1)) {
    4144           0 :                                         stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
    4145             :                                 }
    4146             :                         } else {
    4147           0 :                                 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
    4148             :                         }
    4149             :                 }
    4150           0 :                 sctp_add_stream_reset_result(chk, seq, stcb->asoc.last_reset_action[0]);
    4151           0 :                 asoc->str_reset_seq_in++;
    4152           0 :         } else if ((asoc->str_reset_seq_in - 1) == seq) {
    4153             :                 /*
    4154             :                  * one seq back, just echo back last action since my
    4155             :                  * response was lost.
    4156             :                  */
    4157           0 :                 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
    4158           0 :         } else if ((asoc->str_reset_seq_in - 2) == seq) {
    4159             :                 /*
    4160             :                  * two seq back, just echo back last action since my
    4161             :                  * response was lost.
    4162             :                  */
    4163           0 :                 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
    4164             :         } else {
    4165           0 :                 sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
    4166             :         }
    4167           0 : }
    4168             : 
    4169             : #if !defined(__Panda__)
    4170             : #ifdef __GNUC__
    4171             : __attribute__ ((noinline))
    4172             : #endif
    4173             : #endif
    4174             : static int
    4175           0 : sctp_handle_stream_reset(struct sctp_tcb *stcb, struct mbuf *m, int offset,
    4176             :                          struct sctp_chunkhdr *ch_req)
    4177             : {
    4178             :         uint16_t remaining_length, param_len, ptype;
    4179             :         struct sctp_paramhdr pstore;
    4180             :         uint8_t cstore[SCTP_CHUNK_BUFFER_SIZE];
    4181           0 :         uint32_t seq = 0;
    4182           0 :         int num_req = 0;
    4183           0 :         int trunc = 0;
    4184             :         struct sctp_tmit_chunk *chk;
    4185             :         struct sctp_chunkhdr *ch;
    4186             :         struct sctp_paramhdr *ph;
    4187           0 :         int ret_code = 0;
    4188           0 :         int num_param = 0;
    4189             : 
    4190             :         /* now it may be a reset or a reset-response */
    4191           0 :         remaining_length = ntohs(ch_req->chunk_length) - sizeof(struct sctp_chunkhdr);
    4192             : 
    4193             :         /* setup for adding the response */
    4194           0 :         sctp_alloc_a_chunk(stcb, chk);
    4195           0 :         if (chk == NULL) {
    4196           0 :                 return (ret_code);
    4197             :         }
    4198           0 :         chk->copy_by_ref = 0;
    4199           0 :         chk->rec.chunk_id.id = SCTP_STREAM_RESET;
    4200           0 :         chk->rec.chunk_id.can_take_data = 0;
    4201           0 :         chk->flags = 0;
    4202           0 :         chk->asoc = &stcb->asoc;
    4203           0 :         chk->no_fr_allowed = 0;
    4204           0 :         chk->book_size = chk->send_size = sizeof(struct sctp_chunkhdr);
    4205           0 :         chk->book_size_scale = 0;
    4206           0 :         chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
    4207           0 :         if (chk->data == NULL) {
    4208             :         strres_nochunk:
    4209           0 :                 if (chk->data) {
    4210           0 :                         sctp_m_freem(chk->data);
    4211           0 :                         chk->data = NULL;
    4212             :                 }
    4213           0 :                 sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
    4214           0 :                 return (ret_code);
    4215             :         }
    4216           0 :         SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
    4217             : 
    4218             :         /* setup chunk parameters */
    4219           0 :         chk->sent = SCTP_DATAGRAM_UNSENT;
    4220           0 :         chk->snd_count = 0;
    4221           0 :         chk->whoTo = NULL;
    4222             : 
    4223           0 :         ch = mtod(chk->data, struct sctp_chunkhdr *);
    4224           0 :         ch->chunk_type = SCTP_STREAM_RESET;
    4225           0 :         ch->chunk_flags = 0;
    4226           0 :         ch->chunk_length = htons(chk->send_size);
    4227           0 :         SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size);
    4228           0 :         offset += sizeof(struct sctp_chunkhdr);
    4229           0 :         while (remaining_length >= sizeof(struct sctp_paramhdr)) {
    4230           0 :                 ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, sizeof(pstore), (uint8_t *)&pstore);
    4231           0 :                 if (ph == NULL) {
    4232             :                         /* TSNH */
    4233           0 :                         break;
    4234             :                 }
    4235           0 :                 param_len = ntohs(ph->param_length);
    4236           0 :                 if ((param_len > remaining_length) ||
    4237             :                     (param_len < (sizeof(struct sctp_paramhdr) + sizeof(uint32_t)))) {
    4238             :                         /* bad parameter length */
    4239             :                         break;
    4240             :                 }
    4241           0 :                 ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, min(param_len, sizeof(cstore)),
    4242             :                                                            (uint8_t *)&cstore);
    4243           0 :                 if (ph == NULL) {
    4244             :                         /* TSNH */
    4245           0 :                         break;
    4246             :                 }
    4247           0 :                 ptype = ntohs(ph->param_type);
    4248           0 :                 num_param++;
    4249           0 :                 if (param_len > sizeof(cstore)) {
    4250           0 :                         trunc = 1;
    4251             :                 } else {
    4252           0 :                         trunc = 0;
    4253             :                 }
    4254           0 :                 if (num_param > SCTP_MAX_RESET_PARAMS) {
    4255             :                         /* hit the max of parameters already sorry.. */
    4256           0 :                         break;
    4257             :                 }
    4258           0 :                 if (ptype == SCTP_STR_RESET_OUT_REQUEST) {
    4259             :                         struct sctp_stream_reset_out_request *req_out;
    4260             : 
    4261           0 :                         if (param_len < sizeof(struct sctp_stream_reset_out_request)) {
    4262           0 :                                 break;
    4263             :                         }
    4264           0 :                         req_out = (struct sctp_stream_reset_out_request *)ph;
    4265           0 :                         num_req++;
    4266           0 :                         if (stcb->asoc.stream_reset_outstanding) {
    4267           0 :                                 seq = ntohl(req_out->response_seq);
    4268           0 :                                 if (seq == stcb->asoc.str_reset_seq_out) {
    4269             :                                         /* implicit ack */
    4270           0 :                                         (void)sctp_handle_stream_reset_response(stcb, seq, SCTP_STREAM_RESET_RESULT_PERFORMED, NULL);
    4271             :                                 }
    4272             :                         }
    4273           0 :                         sctp_handle_str_reset_request_out(stcb, chk, req_out, trunc);
    4274           0 :                 } else if (ptype == SCTP_STR_RESET_ADD_OUT_STREAMS) {
    4275             :                         struct sctp_stream_reset_add_strm  *str_add;
    4276             : 
    4277           0 :                         if (param_len < sizeof(struct sctp_stream_reset_add_strm)) {
    4278           0 :                                 break;
    4279             :                         }
    4280           0 :                         str_add = (struct sctp_stream_reset_add_strm  *)ph;
    4281           0 :                         num_req++;
    4282           0 :                         sctp_handle_str_reset_add_strm(stcb, chk, str_add);
    4283           0 :                 } else if (ptype == SCTP_STR_RESET_ADD_IN_STREAMS) {
    4284             :                         struct sctp_stream_reset_add_strm  *str_add;
    4285             : 
    4286           0 :                         if (param_len < sizeof(struct sctp_stream_reset_add_strm)) {
    4287           0 :                                 break;
    4288             :                         }
    4289           0 :                         str_add = (struct sctp_stream_reset_add_strm  *)ph;
    4290           0 :                         num_req++;
    4291           0 :                         sctp_handle_str_reset_add_out_strm(stcb, chk, str_add);
    4292           0 :                 } else if (ptype == SCTP_STR_RESET_IN_REQUEST) {
    4293             :                         struct sctp_stream_reset_in_request *req_in;
    4294             : 
    4295           0 :                         num_req++;
    4296           0 :                         req_in = (struct sctp_stream_reset_in_request *)ph;
    4297           0 :                         sctp_handle_str_reset_request_in(stcb, chk, req_in, trunc);
    4298           0 :                 } else if (ptype == SCTP_STR_RESET_TSN_REQUEST) {
    4299             :                         struct sctp_stream_reset_tsn_request *req_tsn;
    4300             : 
    4301           0 :                         num_req++;
    4302           0 :                         req_tsn = (struct sctp_stream_reset_tsn_request *)ph;
    4303           0 :                         if (sctp_handle_str_reset_request_tsn(stcb, chk, req_tsn)) {
    4304           0 :                                 ret_code = 1;
    4305           0 :                                 goto strres_nochunk;
    4306             :                         }
    4307             :                         /* no more */
    4308           0 :                         break;
    4309           0 :                 } else if (ptype == SCTP_STR_RESET_RESPONSE) {
    4310             :                         struct sctp_stream_reset_response *resp;
    4311             :                         uint32_t result;
    4312             : 
    4313           0 :                         if (param_len < sizeof(struct sctp_stream_reset_response)) {
    4314           0 :                                 break;
    4315             :                         }
    4316           0 :                         resp = (struct sctp_stream_reset_response *)ph;
    4317           0 :                         seq = ntohl(resp->response_seq);
    4318           0 :                         result = ntohl(resp->result);
    4319           0 :                         if (sctp_handle_stream_reset_response(stcb, seq, result, resp)) {
    4320           0 :                                 ret_code = 1;
    4321           0 :                                 goto strres_nochunk;
    4322             :                         }
    4323             :                 } else {
    4324           0 :                         break;
    4325             :                 }
    4326           0 :                 offset += SCTP_SIZE32(param_len);
    4327           0 :                 if (remaining_length >= SCTP_SIZE32(param_len)) {
    4328           0 :                         remaining_length -= SCTP_SIZE32(param_len);
    4329             :                 } else {
    4330           0 :                         remaining_length = 0;
    4331             :                 }
    4332             :         }
    4333           0 :         if (num_req == 0) {
    4334             :                 /* we have no response free the stuff */
    4335           0 :                 goto strres_nochunk;
    4336             :         }
    4337             :         /* ok we have a chunk to link in */
    4338           0 :         TAILQ_INSERT_TAIL(&stcb->asoc.control_send_queue,
    4339             :                           chk,
    4340             :                           sctp_next);
    4341           0 :         stcb->asoc.ctrl_queue_cnt++;
    4342           0 :         return (ret_code);
    4343             : }
    4344             : 
    4345             : /*
    4346             :  * Handle a router or endpoints report of a packet loss, there are two ways
    4347             :  * to handle this, either we get the whole packet and must disect it
    4348             :  * ourselves (possibly with truncation and or corruption) or it is a summary
    4349             :  * from a middle box that did the disectting for us.
    4350             :  */
    4351             : static void
    4352           0 : sctp_handle_packet_dropped(struct sctp_pktdrop_chunk *cp,
    4353             :     struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t limit)
    4354             : {
    4355             :         uint32_t bottle_bw, on_queue;
    4356             :         uint16_t trunc_len;
    4357             :         unsigned int chlen;
    4358             :         unsigned int at;
    4359             :         struct sctp_chunk_desc desc;
    4360             :         struct sctp_chunkhdr *ch;
    4361             : 
    4362           0 :         chlen = ntohs(cp->ch.chunk_length);
    4363           0 :         chlen -= sizeof(struct sctp_pktdrop_chunk);
    4364             :         /* XXX possible chlen underflow */
    4365           0 :         if (chlen == 0) {
    4366           0 :                 ch = NULL;
    4367           0 :                 if (cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX)
    4368           0 :                         SCTP_STAT_INCR(sctps_pdrpbwrpt);
    4369             :         } else {
    4370           0 :                 ch = (struct sctp_chunkhdr *)(cp->data + sizeof(struct sctphdr));
    4371           0 :                 chlen -= sizeof(struct sctphdr);
    4372             :                 /* XXX possible chlen underflow */
    4373           0 :                 memset(&desc, 0, sizeof(desc));
    4374             :         }
    4375           0 :         trunc_len = (uint16_t) ntohs(cp->trunc_len);
    4376           0 :         if (trunc_len > limit) {
    4377           0 :                 trunc_len = limit;
    4378             :         }
    4379             : 
    4380             :         /* now the chunks themselves */
    4381           0 :         while ((ch != NULL) && (chlen >= sizeof(struct sctp_chunkhdr))) {
    4382           0 :                 desc.chunk_type = ch->chunk_type;
    4383             :                 /* get amount we need to move */
    4384           0 :                 at = ntohs(ch->chunk_length);
    4385           0 :                 if (at < sizeof(struct sctp_chunkhdr)) {
    4386             :                         /* corrupt chunk, maybe at the end? */
    4387           0 :                         SCTP_STAT_INCR(sctps_pdrpcrupt);
    4388           0 :                         break;
    4389             :                 }
    4390           0 :                 if (trunc_len == 0) {
    4391             :                         /* we are supposed to have all of it */
    4392           0 :                         if (at > chlen) {
    4393             :                                 /* corrupt skip it */
    4394           0 :                                 SCTP_STAT_INCR(sctps_pdrpcrupt);
    4395           0 :                                 break;
    4396             :                         }
    4397             :                 } else {
    4398             :                         /* is there enough of it left ? */
    4399           0 :                         if (desc.chunk_type == SCTP_DATA) {
    4400           0 :                                 if (chlen < (sizeof(struct sctp_data_chunk) +
    4401             :                                     sizeof(desc.data_bytes))) {
    4402           0 :                                         break;
    4403             :                                 }
    4404             :                         } else {
    4405           0 :                                 if (chlen < sizeof(struct sctp_chunkhdr)) {
    4406           0 :                                         break;
    4407             :                                 }
    4408             :                         }
    4409             :                 }
    4410           0 :                 if (desc.chunk_type == SCTP_DATA) {
    4411             :                         /* can we get out the tsn? */
    4412           0 :                         if ((cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX))
    4413           0 :                                 SCTP_STAT_INCR(sctps_pdrpmbda);
    4414             : 
    4415           0 :                         if (chlen >= (sizeof(struct sctp_data_chunk) + sizeof(uint32_t))) {
    4416             :                                 /* yep */
    4417             :                                 struct sctp_data_chunk *dcp;
    4418             :                                 uint8_t *ddp;
    4419             :                                 unsigned int iii;
    4420             : 
    4421           0 :                                 dcp = (struct sctp_data_chunk *)ch;
    4422           0 :                                 ddp = (uint8_t *) (dcp + 1);
    4423           0 :                                 for (iii = 0; iii < sizeof(desc.data_bytes); iii++) {
    4424           0 :                                         desc.data_bytes[iii] = ddp[iii];
    4425             :                                 }
    4426           0 :                                 desc.tsn_ifany = dcp->dp.tsn;
    4427             :                         } else {
    4428             :                                 /* nope we are done. */
    4429           0 :                                 SCTP_STAT_INCR(sctps_pdrpnedat);
    4430           0 :                                 break;
    4431             :                         }
    4432             :                 } else {
    4433           0 :                         if ((cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX))
    4434           0 :                                 SCTP_STAT_INCR(sctps_pdrpmbct);
    4435             :                 }
    4436             : 
    4437           0 :                 if (process_chunk_drop(stcb, &desc, net, cp->ch.chunk_flags)) {
    4438           0 :                         SCTP_STAT_INCR(sctps_pdrppdbrk);
    4439           0 :                         break;
    4440             :                 }
    4441           0 :                 if (SCTP_SIZE32(at) > chlen) {
    4442           0 :                         break;
    4443             :                 }
    4444           0 :                 chlen -= SCTP_SIZE32(at);
    4445           0 :                 if (chlen < sizeof(struct sctp_chunkhdr)) {
    4446             :                         /* done, none left */
    4447           0 :                         break;
    4448             :                 }
    4449           0 :                 ch = (struct sctp_chunkhdr *)((caddr_t)ch + SCTP_SIZE32(at));
    4450             :         }
    4451             :         /* Now update any rwnd --- possibly */
    4452           0 :         if ((cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX) == 0) {
    4453             :                 /* From a peer, we get a rwnd report */
    4454             :                 uint32_t a_rwnd;
    4455             : 
    4456           0 :                 SCTP_STAT_INCR(sctps_pdrpfehos);
    4457             : 
    4458           0 :                 bottle_bw = ntohl(cp->bottle_bw);
    4459           0 :                 on_queue = ntohl(cp->current_onq);
    4460           0 :                 if (bottle_bw && on_queue) {
    4461             :                         /* a rwnd report is in here */
    4462           0 :                         if (bottle_bw > on_queue)
    4463           0 :                                 a_rwnd = bottle_bw - on_queue;
    4464             :                         else
    4465           0 :                                 a_rwnd = 0;
    4466             : 
    4467           0 :                         if (a_rwnd == 0)
    4468           0 :                                 stcb->asoc.peers_rwnd = 0;
    4469             :                         else {
    4470           0 :                                 if (a_rwnd > stcb->asoc.total_flight) {
    4471           0 :                                         stcb->asoc.peers_rwnd =
    4472           0 :                                             a_rwnd - stcb->asoc.total_flight;
    4473             :                                 } else {
    4474           0 :                                         stcb->asoc.peers_rwnd = 0;
    4475             :                                 }
    4476           0 :                                 if (stcb->asoc.peers_rwnd <
    4477           0 :                                     stcb->sctp_ep->sctp_ep.sctp_sws_sender) {
    4478             :                                         /* SWS sender side engages */
    4479           0 :                                         stcb->asoc.peers_rwnd = 0;
    4480             :                                 }
    4481             :                         }
    4482             :                 }
    4483             :         } else {
    4484           0 :                 SCTP_STAT_INCR(sctps_pdrpfmbox);
    4485             :         }
    4486             : 
    4487             :         /* now middle boxes in sat networks get a cwnd bump */
    4488           0 :         if ((cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX) &&
    4489           0 :             (stcb->asoc.sat_t3_loss_recovery == 0) &&
    4490           0 :             (stcb->asoc.sat_network)) {
    4491             :                 /*
    4492             :                  * This is debateable but for sat networks it makes sense
    4493             :                  * Note if a T3 timer has went off, we will prohibit any
    4494             :                  * changes to cwnd until we exit the t3 loss recovery.
    4495             :                  */
    4496           0 :                 stcb->asoc.cc_functions.sctp_cwnd_update_after_packet_dropped(stcb,
    4497             :                         net, cp, &bottle_bw, &on_queue);
    4498             :         }
    4499           0 : }
    4500             : 
    4501             : /*
    4502             :  * handles all control chunks in a packet inputs: - m: mbuf chain, assumed to
    4503             :  * still contain IP/SCTP header - stcb: is the tcb found for this packet -
    4504             :  * offset: offset into the mbuf chain to first chunkhdr - length: is the
    4505             :  * length of the complete packet outputs: - length: modified to remaining
    4506             :  * length after control processing - netp: modified to new sctp_nets after
    4507             :  * cookie-echo processing - return NULL to discard the packet (ie. no asoc,
    4508             :  * bad packet,...) otherwise return the tcb for this packet
    4509             :  */
    4510             : #if !defined(__Panda__)
    4511             : #ifdef __GNUC__
    4512             : __attribute__ ((noinline))
    4513             : #endif
    4514             : #endif
    4515             : static struct sctp_tcb *
    4516           0 : sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
    4517             :     struct sockaddr *src, struct sockaddr *dst,
    4518             :     struct sctphdr *sh, struct sctp_chunkhdr *ch, struct sctp_inpcb *inp,
    4519             :     struct sctp_tcb *stcb, struct sctp_nets **netp, int *fwd_tsn_seen,
    4520             : #if defined(__FreeBSD__)
    4521             :     uint8_t mflowtype, uint32_t mflowid,
    4522             : #endif
    4523             :     uint32_t vrf_id, uint16_t port)
    4524             : {
    4525             :         struct sctp_association *asoc;
    4526             :         struct mbuf *op_err;
    4527             :         char msg[SCTP_DIAG_INFO_LEN];
    4528             :         uint32_t vtag_in;
    4529           0 :         int num_chunks = 0;     /* number of control chunks processed */
    4530             :         uint32_t chk_length;
    4531             :         int ret;
    4532           0 :         int abort_no_unlock = 0;
    4533           0 :         int ecne_seen = 0;
    4534             :         /*
    4535             :          * How big should this be, and should it be alloc'd? Lets try the
    4536             :          * d-mtu-ceiling for now (2k) and that should hopefully work ...
    4537             :          * until we get into jumbo grams and such..
    4538             :          */
    4539             :         uint8_t chunk_buf[SCTP_CHUNK_BUFFER_SIZE];
    4540           0 :         struct sctp_tcb *locked_tcb = stcb;
    4541           0 :         int got_auth = 0;
    4542           0 :         uint32_t auth_offset = 0, auth_len = 0;
    4543           0 :         int auth_skipped = 0;
    4544           0 :         int asconf_cnt = 0;
    4545             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    4546             :         struct socket *so;
    4547             : #endif
    4548             : 
    4549           0 :         SCTPDBG(SCTP_DEBUG_INPUT1, "sctp_process_control: iphlen=%u, offset=%u, length=%u stcb:%p\n",
    4550             :                 iphlen, *offset, length, (void *)stcb);
    4551             : 
    4552             :         /* validate chunk header length... */
    4553           0 :         if (ntohs(ch->chunk_length) < sizeof(*ch)) {
    4554           0 :                 SCTPDBG(SCTP_DEBUG_INPUT1, "Invalid header length %d\n",
    4555             :                         ntohs(ch->chunk_length));
    4556           0 :                 if (locked_tcb) {
    4557           0 :                         SCTP_TCB_UNLOCK(locked_tcb);
    4558             :                 }
    4559           0 :                 return (NULL);
    4560             :         }
    4561             :         /*
    4562             :          * validate the verification tag
    4563             :          */
    4564           0 :         vtag_in = ntohl(sh->v_tag);
    4565             : 
    4566           0 :         if (locked_tcb) {
    4567             :                 SCTP_TCB_LOCK_ASSERT(locked_tcb);
    4568             :         }
    4569           0 :         if (ch->chunk_type == SCTP_INITIATION) {
    4570           0 :                 SCTPDBG(SCTP_DEBUG_INPUT1, "Its an INIT of len:%d vtag:%x\n",
    4571             :                         ntohs(ch->chunk_length), vtag_in);
    4572           0 :                 if (vtag_in != 0) {
    4573             :                         /* protocol error- silently discard... */
    4574           0 :                         SCTP_STAT_INCR(sctps_badvtag);
    4575           0 :                         if (locked_tcb) {
    4576           0 :                                 SCTP_TCB_UNLOCK(locked_tcb);
    4577             :                         }
    4578           0 :                         return (NULL);
    4579             :                 }
    4580           0 :         } else if (ch->chunk_type != SCTP_COOKIE_ECHO) {
    4581             :                 /*
    4582             :                  * If there is no stcb, skip the AUTH chunk and process
    4583             :                  * later after a stcb is found (to validate the lookup was
    4584             :                  * valid.
    4585             :                  */
    4586           0 :                 if ((ch->chunk_type == SCTP_AUTHENTICATION) &&
    4587           0 :                     (stcb == NULL) &&
    4588           0 :                     (inp->auth_supported == 1)) {
    4589             :                         /* save this chunk for later processing */
    4590           0 :                         auth_skipped = 1;
    4591           0 :                         auth_offset = *offset;
    4592           0 :                         auth_len = ntohs(ch->chunk_length);
    4593             : 
    4594             :                         /* (temporarily) move past this chunk */
    4595           0 :                         *offset += SCTP_SIZE32(auth_len);
    4596           0 :                         if (*offset >= length) {
    4597             :                                 /* no more data left in the mbuf chain */
    4598           0 :                                 *offset = length;
    4599           0 :                                 if (locked_tcb) {
    4600           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    4601             :                                 }
    4602           0 :                                 return (NULL);
    4603             :                         }
    4604           0 :                         ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
    4605             :                                                                    sizeof(struct sctp_chunkhdr), chunk_buf);
    4606             :                 }
    4607           0 :                 if (ch == NULL) {
    4608             :                         /* Help */
    4609           0 :                         *offset = length;
    4610           0 :                         if (locked_tcb) {
    4611           0 :                                 SCTP_TCB_UNLOCK(locked_tcb);
    4612             :                         }
    4613           0 :                         return (NULL);
    4614             :                 }
    4615           0 :                 if (ch->chunk_type == SCTP_COOKIE_ECHO) {
    4616           0 :                         goto process_control_chunks;
    4617             :                 }
    4618             :                 /*
    4619             :                  * first check if it's an ASCONF with an unknown src addr we
    4620             :                  * need to look inside to find the association
    4621             :                  */
    4622           0 :                 if (ch->chunk_type == SCTP_ASCONF && stcb == NULL) {
    4623           0 :                         struct sctp_chunkhdr *asconf_ch = ch;
    4624           0 :                         uint32_t asconf_offset = 0, asconf_len = 0;
    4625             : 
    4626             :                         /* inp's refcount may be reduced */
    4627           0 :                         SCTP_INP_INCR_REF(inp);
    4628             : 
    4629           0 :                         asconf_offset = *offset;
    4630             :                         do {
    4631           0 :                                 asconf_len = ntohs(asconf_ch->chunk_length);
    4632           0 :                                 if (asconf_len < sizeof(struct sctp_asconf_paramhdr))
    4633           0 :                                         break;
    4634           0 :                                 stcb = sctp_findassociation_ep_asconf(m,
    4635             :                                                                       *offset,
    4636             :                                                                       dst,
    4637             :                                                                       sh, &inp, netp, vrf_id);
    4638           0 :                                 if (stcb != NULL)
    4639           0 :                                         break;
    4640           0 :                                 asconf_offset += SCTP_SIZE32(asconf_len);
    4641           0 :                                 asconf_ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, asconf_offset,
    4642             :                                                                                   sizeof(struct sctp_chunkhdr), chunk_buf);
    4643           0 :                         } while (asconf_ch != NULL && asconf_ch->chunk_type == SCTP_ASCONF);
    4644           0 :                         if (stcb == NULL) {
    4645             :                                 /*
    4646             :                                  * reduce inp's refcount if not reduced in
    4647             :                                  * sctp_findassociation_ep_asconf().
    4648             :                                  */
    4649           0 :                                 SCTP_INP_DECR_REF(inp);
    4650             :                         } else {
    4651           0 :                                 locked_tcb = stcb;
    4652             :                         }
    4653             : 
    4654             :                         /* now go back and verify any auth chunk to be sure */
    4655           0 :                         if (auth_skipped && (stcb != NULL)) {
    4656             :                                 struct sctp_auth_chunk *auth;
    4657             : 
    4658           0 :                                 auth = (struct sctp_auth_chunk *)
    4659           0 :                                         sctp_m_getptr(m, auth_offset,
    4660             :                                                       auth_len, chunk_buf);
    4661           0 :                                 got_auth = 1;
    4662           0 :                                 auth_skipped = 0;
    4663           0 :                                 if ((auth == NULL) || sctp_handle_auth(stcb, auth, m,
    4664             :                                                                        auth_offset)) {
    4665             :                                         /* auth HMAC failed so dump it */
    4666           0 :                                         *offset = length;
    4667           0 :                                         if (locked_tcb) {
    4668           0 :                                                 SCTP_TCB_UNLOCK(locked_tcb);
    4669             :                                         }
    4670           0 :                                         return (NULL);
    4671             :                                 } else {
    4672             :                                         /* remaining chunks are HMAC checked */
    4673           0 :                                         stcb->asoc.authenticated = 1;
    4674             :                                 }
    4675             :                         }
    4676             :                 }
    4677           0 :                 if (stcb == NULL) {
    4678           0 :                         snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
    4679           0 :                         op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
    4680             :                                                      msg);
    4681             :                         /* no association, so it's out of the blue... */
    4682           0 :                         sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp, op_err,
    4683             : #if defined(__FreeBSD__)
    4684             :                                          mflowtype, mflowid,
    4685             : #endif
    4686             :                                          vrf_id, port);
    4687           0 :                         *offset = length;
    4688           0 :                         if (locked_tcb) {
    4689           0 :                                 SCTP_TCB_UNLOCK(locked_tcb);
    4690             :                         }
    4691           0 :                         return (NULL);
    4692             :                 }
    4693           0 :                 asoc = &stcb->asoc;
    4694             :                 /* ABORT and SHUTDOWN can use either v_tag... */
    4695           0 :                 if ((ch->chunk_type == SCTP_ABORT_ASSOCIATION) ||
    4696           0 :                     (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) ||
    4697           0 :                     (ch->chunk_type == SCTP_PACKET_DROPPED)) {
    4698             :                         /* Take the T-bit always into account. */
    4699           0 :                         if ((((ch->chunk_flags & SCTP_HAD_NO_TCB) == 0) &&
    4700           0 :                              (vtag_in == asoc->my_vtag)) ||
    4701           0 :                             (((ch->chunk_flags & SCTP_HAD_NO_TCB) == SCTP_HAD_NO_TCB) &&
    4702           0 :                              (vtag_in == asoc->peer_vtag))) {
    4703             :                                 /* this is valid */
    4704             :                         } else {
    4705             :                                 /* drop this packet... */
    4706           0 :                                 SCTP_STAT_INCR(sctps_badvtag);
    4707           0 :                                 if (locked_tcb) {
    4708           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    4709             :                                 }
    4710           0 :                                 return (NULL);
    4711             :                         }
    4712           0 :                 } else if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
    4713           0 :                         if (vtag_in != asoc->my_vtag) {
    4714             :                                 /*
    4715             :                                  * this could be a stale SHUTDOWN-ACK or the
    4716             :                                  * peer never got the SHUTDOWN-COMPLETE and
    4717             :                                  * is still hung; we have started a new asoc
    4718             :                                  * but it won't complete until the shutdown
    4719             :                                  * is completed
    4720             :                                  */
    4721           0 :                                 if (locked_tcb) {
    4722           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    4723             :                                 }
    4724           0 :                                 snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
    4725           0 :                                 op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
    4726             :                                                              msg);
    4727           0 :                                 sctp_handle_ootb(m, iphlen, *offset, src, dst,
    4728             :                                                  sh, inp, op_err,
    4729             : #if defined(__FreeBSD__)
    4730             :                                                  mflowtype, mflowid,
    4731             : #endif
    4732             :                                                  vrf_id, port);
    4733           0 :                                 return (NULL);
    4734             :                         }
    4735             :                 } else {
    4736             :                         /* for all other chunks, vtag must match */
    4737           0 :                         if (vtag_in != asoc->my_vtag) {
    4738             :                                 /* invalid vtag... */
    4739           0 :                                 SCTPDBG(SCTP_DEBUG_INPUT3,
    4740             :                                         "invalid vtag: %xh, expect %xh\n",
    4741             :                                         vtag_in, asoc->my_vtag);
    4742           0 :                                 SCTP_STAT_INCR(sctps_badvtag);
    4743           0 :                                 if (locked_tcb) {
    4744           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    4745             :                                 }
    4746           0 :                                 *offset = length;
    4747           0 :                                 return (NULL);
    4748             :                         }
    4749             :                 }
    4750             :         }                       /* end if !SCTP_COOKIE_ECHO */
    4751             :         /*
    4752             :          * process all control chunks...
    4753             :          */
    4754           0 :         if (((ch->chunk_type == SCTP_SELECTIVE_ACK) ||
    4755           0 :              (ch->chunk_type == SCTP_NR_SELECTIVE_ACK) ||
    4756           0 :              (ch->chunk_type == SCTP_HEARTBEAT_REQUEST)) &&
    4757           0 :             (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED)) {
    4758             :                 /* implied cookie-ack.. we must have lost the ack */
    4759           0 :                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
    4760           0 :                         sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    4761           0 :                                        stcb->asoc.overall_error_count,
    4762             :                                        0,
    4763             :                                        SCTP_FROM_SCTP_INPUT,
    4764             :                                        __LINE__);
    4765             :                 }
    4766           0 :                 stcb->asoc.overall_error_count = 0;
    4767           0 :                 sctp_handle_cookie_ack((struct sctp_cookie_ack_chunk *)ch, stcb,
    4768             :                                        *netp);
    4769             :         }
    4770             : 
    4771             :  process_control_chunks:
    4772           0 :         while (IS_SCTP_CONTROL(ch)) {
    4773             :                 /* validate chunk length */
    4774           0 :                 chk_length = ntohs(ch->chunk_length);
    4775           0 :                 SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_process_control: processing a chunk type=%u, len=%u\n",
    4776             :                         ch->chunk_type, chk_length);
    4777             :                 SCTP_LTRACE_CHK(inp, stcb, ch->chunk_type, chk_length);
    4778           0 :                 if (chk_length < sizeof(*ch) ||
    4779           0 :                     (*offset + (int)chk_length) > length) {
    4780           0 :                         *offset = length;
    4781           0 :                         if (locked_tcb) {
    4782           0 :                                 SCTP_TCB_UNLOCK(locked_tcb);
    4783             :                         }
    4784           0 :                         return (NULL);
    4785             :                 }
    4786           0 :                 SCTP_STAT_INCR_COUNTER64(sctps_incontrolchunks);
    4787             :                 /*
    4788             :                  * INIT-ACK only gets the init ack "header" portion only
    4789             :                  * because we don't have to process the peer's COOKIE. All
    4790             :                  * others get a complete chunk.
    4791             :                  */
    4792           0 :                 if ((ch->chunk_type == SCTP_INITIATION_ACK) ||
    4793           0 :                     (ch->chunk_type == SCTP_INITIATION)) {
    4794             :                         /* get an init-ack chunk */
    4795           0 :                         ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
    4796             :                                                                    sizeof(struct sctp_init_ack_chunk), chunk_buf);
    4797           0 :                         if (ch == NULL) {
    4798           0 :                                 *offset = length;
    4799           0 :                                 if (locked_tcb) {
    4800           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    4801             :                                 }
    4802           0 :                                 return (NULL);
    4803             :                         }
    4804             :                 } else {
    4805             :                         /* For cookies and all other chunks. */
    4806           0 :                         if (chk_length > sizeof(chunk_buf)) {
    4807             :                                 /*
    4808             :                                  * use just the size of the chunk buffer
    4809             :                                  * so the front part of our chunks fit in
    4810             :                                  * contiguous space up to the chunk buffer
    4811             :                                  * size (508 bytes).
    4812             :                                  * For chunks that need to get more than that
    4813             :                                  * they must use the sctp_m_getptr() function
    4814             :                                  * or other means (e.g. know how to parse mbuf
    4815             :                                  * chains). Cookies do this already.
    4816             :                                  */
    4817           0 :                                 ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
    4818             :                                                                            (sizeof(chunk_buf) - 4),
    4819             :                                                                            chunk_buf);
    4820           0 :                                 if (ch == NULL) {
    4821           0 :                                         *offset = length;
    4822           0 :                                         if (locked_tcb) {
    4823           0 :                                                 SCTP_TCB_UNLOCK(locked_tcb);
    4824             :                                         }
    4825           0 :                                         return (NULL);
    4826             :                                 }
    4827             :                         } else {
    4828             :                                 /* We can fit it all */
    4829           0 :                                 ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
    4830             :                                                                    chk_length, chunk_buf);
    4831           0 :                                 if (ch == NULL) {
    4832           0 :                                         SCTP_PRINTF("sctp_process_control: Can't get the all data....\n");
    4833           0 :                                         *offset = length;
    4834           0 :                                         if (locked_tcb) {
    4835           0 :                                                 SCTP_TCB_UNLOCK(locked_tcb);
    4836             :                                         }
    4837           0 :                                         return (NULL);
    4838             :                                 }
    4839             :                         }
    4840             :                 }
    4841           0 :                 num_chunks++;
    4842             :                 /* Save off the last place we got a control from */
    4843           0 :                 if (stcb != NULL) {
    4844           0 :                         if (((netp != NULL) && (*netp != NULL)) || (ch->chunk_type == SCTP_ASCONF)) {
    4845             :                                 /*
    4846             :                                  * allow last_control to be NULL if
    4847             :                                  * ASCONF... ASCONF processing will find the
    4848             :                                  * right net later
    4849             :                                  */
    4850           0 :                                 if ((netp != NULL) && (*netp != NULL))
    4851           0 :                                         stcb->asoc.last_control_chunk_from = *netp;
    4852             :                         }
    4853             :                 }
    4854             : #ifdef SCTP_AUDITING_ENABLED
    4855             :                 sctp_audit_log(0xB0, ch->chunk_type);
    4856             : #endif
    4857             : 
    4858             :                 /* check to see if this chunk required auth, but isn't */
    4859           0 :                 if ((stcb != NULL) &&
    4860           0 :                     (stcb->asoc.auth_supported == 1) &&
    4861           0 :                     sctp_auth_is_required_chunk(ch->chunk_type, stcb->asoc.local_auth_chunks) &&
    4862           0 :                     !stcb->asoc.authenticated) {
    4863             :                         /* "silently" ignore */
    4864           0 :                         SCTP_STAT_INCR(sctps_recvauthmissing);
    4865           0 :                         goto next_chunk;
    4866             :                 }
    4867           0 :                 switch (ch->chunk_type) {
    4868             :                 case SCTP_INITIATION:
    4869           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_INIT\n");
    4870             :                         /* The INIT chunk must be the only chunk. */
    4871           0 :                         if ((num_chunks > 1) ||
    4872           0 :                             (length - *offset > (int)SCTP_SIZE32(chk_length))) {
    4873           0 :                                 op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
    4874             :                                                              "INIT not the only chunk");
    4875           0 :                                 sctp_abort_association(inp, stcb, m, iphlen,
    4876             :                                                        src, dst, sh, op_err,
    4877             : #if defined(__FreeBSD__)
    4878             :                                                        mflowtype, mflowid,
    4879             : #endif
    4880             :                                                        vrf_id, port);
    4881           0 :                                 *offset = length;
    4882           0 :                                 return (NULL);
    4883             :                         }
    4884             :                         /* Honor our resource limit. */
    4885           0 :                         if (chk_length > SCTP_LARGEST_INIT_ACCEPTED) {
    4886           0 :                                 op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
    4887           0 :                                 sctp_abort_association(inp, stcb, m, iphlen,
    4888             :                                                        src, dst, sh, op_err,
    4889             : #if defined(__FreeBSD__)
    4890             :                                                        mflowtype, mflowid,
    4891             : #endif
    4892             :                                                        vrf_id, port);
    4893           0 :                                 *offset = length;
    4894           0 :                                 return (NULL);
    4895             :                         }
    4896           0 :                         sctp_handle_init(m, iphlen, *offset, src, dst, sh,
    4897             :                                          (struct sctp_init_chunk *)ch, inp,
    4898             :                                          stcb, &abort_no_unlock,
    4899             : #if defined(__FreeBSD__)
    4900             :                                          mflowtype, mflowid,
    4901             : #endif
    4902             :                                          vrf_id, port);
    4903           0 :                         *offset = length;
    4904           0 :                         if ((!abort_no_unlock) && (locked_tcb)) {
    4905           0 :                                 SCTP_TCB_UNLOCK(locked_tcb);
    4906             :                         }
    4907           0 :                         return (NULL);
    4908             :                         break;
    4909             :                 case SCTP_PAD_CHUNK:
    4910           0 :                         break;
    4911             :                 case SCTP_INITIATION_ACK:
    4912           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_INIT-ACK\n");
    4913           0 :                         if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
    4914             :                                 /* We are not interested anymore */
    4915           0 :                                 if ((stcb) && (stcb->asoc.total_output_queue_size)) {
    4916             :                                         ;
    4917             :                                 } else {
    4918           0 :                                         if (locked_tcb != stcb) {
    4919             :                                                 /* Very unlikely */
    4920           0 :                                                 SCTP_TCB_UNLOCK(locked_tcb);
    4921             :                                         }
    4922           0 :                                         *offset = length;
    4923           0 :                                         if (stcb) {
    4924             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    4925             :                                                 so = SCTP_INP_SO(inp);
    4926             :                                                 atomic_add_int(&stcb->asoc.refcnt, 1);
    4927             :                                                 SCTP_TCB_UNLOCK(stcb);
    4928             :                                                 SCTP_SOCKET_LOCK(so, 1);
    4929             :                                                 SCTP_TCB_LOCK(stcb);
    4930             :                                                 atomic_subtract_int(&stcb->asoc.refcnt, 1);
    4931             : #endif
    4932           0 :                                                 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_27);
    4933             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    4934             :                                                 SCTP_SOCKET_UNLOCK(so, 1);
    4935             : #endif
    4936             :                                         }
    4937           0 :                                         return (NULL);
    4938             :                                 }
    4939             :                         }
    4940             :                         /* The INIT-ACK chunk must be the only chunk. */
    4941           0 :                         if ((num_chunks > 1) ||
    4942           0 :                             (length - *offset > (int)SCTP_SIZE32(chk_length))) {
    4943           0 :                                 *offset = length;
    4944           0 :                                 if (locked_tcb) {
    4945           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    4946             :                                 }
    4947           0 :                                 return (NULL);
    4948             :                         }
    4949           0 :                         if ((netp) && (*netp)) {
    4950           0 :                                 ret = sctp_handle_init_ack(m, iphlen, *offset,
    4951             :                                                            src, dst, sh,
    4952             :                                                            (struct sctp_init_ack_chunk *)ch,
    4953             :                                                            stcb, *netp,
    4954             :                                                            &abort_no_unlock,
    4955             : #if defined(__FreeBSD__)
    4956             :                                                            mflowtype, mflowid,
    4957             : #endif
    4958             :                                                            vrf_id);
    4959             :                         } else {
    4960           0 :                                 ret = -1;
    4961             :                         }
    4962           0 :                         *offset = length;
    4963           0 :                         if (abort_no_unlock) {
    4964           0 :                                 return (NULL);
    4965             :                         }
    4966             :                         /*
    4967             :                          * Special case, I must call the output routine to
    4968             :                          * get the cookie echoed
    4969             :                          */
    4970           0 :                         if ((stcb != NULL) && (ret == 0)) {
    4971           0 :                                 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED);
    4972             :                         }
    4973           0 :                         if (locked_tcb) {
    4974           0 :                                 SCTP_TCB_UNLOCK(locked_tcb);
    4975             :                         }
    4976           0 :                         return (NULL);
    4977             :                         break;
    4978             :                 case SCTP_SELECTIVE_ACK:
    4979             :                         {
    4980             :                                 struct sctp_sack_chunk *sack;
    4981           0 :                                 int abort_now = 0;
    4982             :                                 uint32_t a_rwnd, cum_ack;
    4983             :                                 uint16_t num_seg, num_dup;
    4984             :                                 uint8_t flags;
    4985             :                                 int offset_seg, offset_dup;
    4986             : 
    4987           0 :                                 SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SACK\n");
    4988           0 :                                 SCTP_STAT_INCR(sctps_recvsacks);
    4989           0 :                                 if (stcb == NULL) {
    4990           0 :                                         SCTPDBG(SCTP_DEBUG_INDATA1, "No stcb when processing SACK chunk\n");
    4991           0 :                                         break;
    4992             :                                 }
    4993           0 :                                 if (chk_length < sizeof(struct sctp_sack_chunk)) {
    4994           0 :                                         SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on SACK chunk, too small\n");
    4995           0 :                                         break;
    4996             :                                 }
    4997           0 :                                 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
    4998             :                                         /*-
    4999             :                                          * If we have sent a shutdown-ack, we will pay no
    5000             :                                          * attention to a sack sent in to us since
    5001             :                                          * we don't care anymore.
    5002             :                                          */
    5003           0 :                                         break;
    5004             :                                 }
    5005           0 :                                 sack = (struct sctp_sack_chunk *)ch;
    5006           0 :                                 flags = ch->chunk_flags;
    5007           0 :                                 cum_ack = ntohl(sack->sack.cum_tsn_ack);
    5008           0 :                                 num_seg = ntohs(sack->sack.num_gap_ack_blks);
    5009           0 :                                 num_dup = ntohs(sack->sack.num_dup_tsns);
    5010           0 :                                 a_rwnd = (uint32_t) ntohl(sack->sack.a_rwnd);
    5011           0 :                                 if (sizeof(struct sctp_sack_chunk) +
    5012           0 :                                     num_seg * sizeof(struct sctp_gap_ack_block) +
    5013           0 :                                     num_dup * sizeof(uint32_t) != chk_length) {
    5014           0 :                                         SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size of SACK chunk\n");
    5015           0 :                                         break;
    5016             :                                 }
    5017           0 :                                 offset_seg = *offset + sizeof(struct sctp_sack_chunk);
    5018           0 :                                 offset_dup = offset_seg + num_seg * sizeof(struct sctp_gap_ack_block);
    5019           0 :                                 SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SACK process cum_ack:%x num_seg:%d a_rwnd:%d\n",
    5020             :                                         cum_ack, num_seg, a_rwnd);
    5021           0 :                                 stcb->asoc.seen_a_sack_this_pkt = 1;
    5022           0 :                                 if ((stcb->asoc.pr_sctp_cnt == 0) &&
    5023           0 :                                     (num_seg == 0) &&
    5024           0 :                                     SCTP_TSN_GE(cum_ack, stcb->asoc.last_acked_seq) &&
    5025           0 :                                     (stcb->asoc.saw_sack_with_frags == 0) &&
    5026           0 :                                     (stcb->asoc.saw_sack_with_nr_frags == 0) &&
    5027           0 :                                     (!TAILQ_EMPTY(&stcb->asoc.sent_queue))
    5028             :                                         ) {
    5029             :                                         /* We have a SIMPLE sack having no prior segments and
    5030             :                                          * data on sent queue to be acked.. Use the faster
    5031             :                                          * path sack processing. We also allow window update
    5032             :                                          * sacks with no missing segments to go this way too.
    5033             :                                          */
    5034           0 :                                         sctp_express_handle_sack(stcb, cum_ack, a_rwnd, &abort_now, ecne_seen);
    5035             :                                 } else {
    5036           0 :                                         if (netp && *netp)
    5037           0 :                                                 sctp_handle_sack(m, offset_seg, offset_dup, stcb,
    5038             :                                                                  num_seg, 0, num_dup, &abort_now, flags,
    5039             :                                                                  cum_ack, a_rwnd, ecne_seen);
    5040             :                                 }
    5041           0 :                                 if (abort_now) {
    5042             :                                         /* ABORT signal from sack processing */
    5043           0 :                                         *offset = length;
    5044           0 :                                         return (NULL);
    5045             :                                 }
    5046           0 :                                 if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
    5047           0 :                                     TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
    5048           0 :                                     (stcb->asoc.stream_queue_cnt == 0)) {
    5049           0 :                                         sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb,  0, NULL, SCTP_SO_NOT_LOCKED);
    5050             :                                 }
    5051             :                         }
    5052           0 :                         break;
    5053             :                 /* EY - nr_sack:  If the received chunk is an nr_sack chunk */
    5054             :                 case SCTP_NR_SELECTIVE_ACK:
    5055             :                         {
    5056             :                                 struct sctp_nr_sack_chunk *nr_sack;
    5057           0 :                                 int abort_now = 0;
    5058             :                                 uint32_t a_rwnd, cum_ack;
    5059             :                                 uint16_t num_seg, num_nr_seg, num_dup;
    5060             :                                 uint8_t flags;
    5061             :                                 int offset_seg, offset_dup;
    5062             : 
    5063           0 :                                 SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_NR_SACK\n");
    5064           0 :                                 SCTP_STAT_INCR(sctps_recvsacks);
    5065           0 :                                 if (stcb == NULL) {
    5066           0 :                                         SCTPDBG(SCTP_DEBUG_INDATA1, "No stcb when processing NR-SACK chunk\n");
    5067           0 :                                         break;
    5068             :                                 }
    5069           0 :                                 if (stcb->asoc.nrsack_supported == 0) {
    5070           0 :                                         goto unknown_chunk;
    5071             :                                 }
    5072           0 :                                 if (chk_length < sizeof(struct sctp_nr_sack_chunk)) {
    5073           0 :                                         SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on NR-SACK chunk, too small\n");
    5074           0 :                                         break;
    5075             :                                 }
    5076           0 :                                 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
    5077             :                                         /*-
    5078             :                                          * If we have sent a shutdown-ack, we will pay no
    5079             :                                          * attention to a sack sent in to us since
    5080             :                                          * we don't care anymore.
    5081             :                                          */
    5082           0 :                                         break;
    5083             :                                 }
    5084           0 :                                 nr_sack = (struct sctp_nr_sack_chunk *)ch;
    5085           0 :                                 flags = ch->chunk_flags;
    5086           0 :                                 cum_ack = ntohl(nr_sack->nr_sack.cum_tsn_ack);
    5087           0 :                                 num_seg = ntohs(nr_sack->nr_sack.num_gap_ack_blks);
    5088           0 :                                 num_nr_seg = ntohs(nr_sack->nr_sack.num_nr_gap_ack_blks);
    5089           0 :                                 num_dup = ntohs(nr_sack->nr_sack.num_dup_tsns);
    5090           0 :                                 a_rwnd = (uint32_t) ntohl(nr_sack->nr_sack.a_rwnd);
    5091           0 :                                 if (sizeof(struct sctp_nr_sack_chunk) +
    5092           0 :                                     (num_seg + num_nr_seg) * sizeof(struct sctp_gap_ack_block) +
    5093           0 :                                     num_dup * sizeof(uint32_t) != chk_length) {
    5094           0 :                                         SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size of NR_SACK chunk\n");
    5095           0 :                                         break;
    5096             :                                 }
    5097           0 :                                 offset_seg = *offset + sizeof(struct sctp_nr_sack_chunk);
    5098           0 :                                 offset_dup = offset_seg + num_seg * sizeof(struct sctp_gap_ack_block);
    5099           0 :                                 SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_NR_SACK process cum_ack:%x num_seg:%d a_rwnd:%d\n",
    5100             :                                         cum_ack, num_seg, a_rwnd);
    5101           0 :                                 stcb->asoc.seen_a_sack_this_pkt = 1;
    5102           0 :                                 if ((stcb->asoc.pr_sctp_cnt == 0) &&
    5103           0 :                                     (num_seg == 0) && (num_nr_seg == 0) &&
    5104           0 :                                     SCTP_TSN_GE(cum_ack, stcb->asoc.last_acked_seq) &&
    5105           0 :                                     (stcb->asoc.saw_sack_with_frags == 0) &&
    5106           0 :                                     (stcb->asoc.saw_sack_with_nr_frags == 0) &&
    5107           0 :                                     (!TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
    5108             :                                         /*
    5109             :                                          * We have a SIMPLE sack having no
    5110             :                                          * prior segments and data on sent
    5111             :                                          * queue to be acked. Use the
    5112             :                                          * faster path sack processing. We
    5113             :                                          * also allow window update sacks
    5114             :                                          * with no missing segments to go
    5115             :                                          * this way too.
    5116             :                                          */
    5117           0 :                                         sctp_express_handle_sack(stcb, cum_ack, a_rwnd,
    5118             :                                                                  &abort_now, ecne_seen);
    5119             :                                 } else {
    5120           0 :                                         if (netp && *netp)
    5121           0 :                                                 sctp_handle_sack(m, offset_seg, offset_dup, stcb,
    5122             :                                                                  num_seg, num_nr_seg, num_dup, &abort_now, flags,
    5123             :                                                                  cum_ack, a_rwnd, ecne_seen);
    5124             :                                 }
    5125           0 :                                 if (abort_now) {
    5126             :                                         /* ABORT signal from sack processing */
    5127           0 :                                         *offset = length;
    5128           0 :                                         return (NULL);
    5129             :                                 }
    5130           0 :                                 if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
    5131           0 :                                     TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
    5132           0 :                                     (stcb->asoc.stream_queue_cnt == 0)) {
    5133           0 :                                         sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb,  0, NULL, SCTP_SO_NOT_LOCKED);
    5134             :                                 }
    5135             :                         }
    5136           0 :                         break;
    5137             : 
    5138             :                 case SCTP_HEARTBEAT_REQUEST:
    5139           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_HEARTBEAT\n");
    5140           0 :                         if ((stcb) && netp && *netp) {
    5141           0 :                                 SCTP_STAT_INCR(sctps_recvheartbeat);
    5142           0 :                                 sctp_send_heartbeat_ack(stcb, m, *offset,
    5143             :                                                         chk_length, *netp);
    5144             : 
    5145             :                                 /* He's alive so give him credit */
    5146           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
    5147           0 :                                         sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    5148           0 :                                                        stcb->asoc.overall_error_count,
    5149             :                                                        0,
    5150             :                                                        SCTP_FROM_SCTP_INPUT,
    5151             :                                                        __LINE__);
    5152             :                                 }
    5153           0 :                                 stcb->asoc.overall_error_count = 0;
    5154             :                         }
    5155           0 :                         break;
    5156             :                 case SCTP_HEARTBEAT_ACK:
    5157           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_HEARTBEAT-ACK\n");
    5158           0 :                         if ((stcb == NULL) || (chk_length != sizeof(struct sctp_heartbeat_chunk))) {
    5159             :                                 /* Its not ours */
    5160           0 :                                 *offset = length;
    5161           0 :                                 if (locked_tcb) {
    5162           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    5163             :                                 }
    5164           0 :                                 return (NULL);
    5165             :                         }
    5166             :                         /* He's alive so give him credit */
    5167           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
    5168           0 :                                 sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    5169           0 :                                                stcb->asoc.overall_error_count,
    5170             :                                                0,
    5171             :                                                SCTP_FROM_SCTP_INPUT,
    5172             :                                                __LINE__);
    5173             :                         }
    5174           0 :                         stcb->asoc.overall_error_count = 0;
    5175           0 :                         SCTP_STAT_INCR(sctps_recvheartbeatack);
    5176           0 :                         if (netp && *netp)
    5177           0 :                                 sctp_handle_heartbeat_ack((struct sctp_heartbeat_chunk *)ch,
    5178             :                                                           stcb, *netp);
    5179           0 :                         break;
    5180             :                 case SCTP_ABORT_ASSOCIATION:
    5181           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ABORT, stcb %p\n",
    5182             :                                 (void *)stcb);
    5183           0 :                         if ((stcb) && netp && *netp)
    5184           0 :                                 sctp_handle_abort((struct sctp_abort_chunk *)ch,
    5185             :                                                   stcb, *netp);
    5186           0 :                         *offset = length;
    5187           0 :                         return (NULL);
    5188             :                         break;
    5189             :                 case SCTP_SHUTDOWN:
    5190           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN, stcb %p\n",
    5191             :                                 (void *)stcb);
    5192           0 :                         if ((stcb == NULL) || (chk_length != sizeof(struct sctp_shutdown_chunk))) {
    5193           0 :                                 *offset = length;
    5194           0 :                                 if (locked_tcb) {
    5195           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    5196             :                                 }
    5197           0 :                                 return (NULL);
    5198             :                         }
    5199           0 :                         if (netp && *netp) {
    5200           0 :                                 int abort_flag = 0;
    5201             : 
    5202           0 :                                 sctp_handle_shutdown((struct sctp_shutdown_chunk *)ch,
    5203             :                                                      stcb, *netp, &abort_flag);
    5204           0 :                                 if (abort_flag) {
    5205           0 :                                         *offset = length;
    5206           0 :                                         return (NULL);
    5207             :                                 }
    5208             :                         }
    5209           0 :                         break;
    5210             :                 case SCTP_SHUTDOWN_ACK:
    5211           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN-ACK, stcb %p\n", (void *)stcb);
    5212           0 :                         if ((stcb) && (netp) && (*netp))
    5213           0 :                                 sctp_handle_shutdown_ack((struct sctp_shutdown_ack_chunk *)ch, stcb, *netp);
    5214           0 :                         *offset = length;
    5215           0 :                         return (NULL);
    5216             :                         break;
    5217             : 
    5218             :                 case SCTP_OPERATION_ERROR:
    5219           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_OP-ERR\n");
    5220           0 :                         if ((stcb) && netp && *netp && sctp_handle_error(ch, stcb, *netp) < 0) {
    5221           0 :                                 *offset = length;
    5222           0 :                                 return (NULL);
    5223             :                         }
    5224           0 :                         break;
    5225             :                 case SCTP_COOKIE_ECHO:
    5226           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3,
    5227             :                                 "SCTP_COOKIE-ECHO, stcb %p\n", (void *)stcb);
    5228           0 :                         if ((stcb) && (stcb->asoc.total_output_queue_size)) {
    5229             :                                 ;
    5230             :                         } else {
    5231           0 :                                 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
    5232             :                                         /* We are not interested anymore */
    5233             :                                 abend:
    5234           0 :                                         if (stcb) {
    5235           0 :                                                 SCTP_TCB_UNLOCK(stcb);
    5236             :                                         }
    5237           0 :                                         *offset = length;
    5238           0 :                                         return (NULL);
    5239             :                                 }
    5240             :                         }
    5241             :                         /*
    5242             :                          * First are we accepting? We do this again here
    5243             :                          * since it is possible that a previous endpoint WAS
    5244             :                          * listening responded to a INIT-ACK and then
    5245             :                          * closed. We opened and bound.. and are now no
    5246             :                          * longer listening.
    5247             :                          */
    5248             : 
    5249           0 :                         if ((stcb == NULL) && (inp->sctp_socket->so_qlen >= inp->sctp_socket->so_qlimit)) {
    5250           0 :                                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
    5251           0 :                                     (SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit))) {
    5252           0 :                                         op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
    5253           0 :                                         sctp_abort_association(inp, stcb, m, iphlen,
    5254             :                                                                src, dst, sh, op_err,
    5255             : #if defined(__FreeBSD__)
    5256             :                                                                mflowtype, mflowid,
    5257             : #endif
    5258             :                                                                vrf_id, port);
    5259             :                                 }
    5260           0 :                                 *offset = length;
    5261           0 :                                 return (NULL);
    5262             :                         } else {
    5263             :                                 struct mbuf *ret_buf;
    5264             :                                 struct sctp_inpcb *linp;
    5265           0 :                                 if (stcb) {
    5266           0 :                                         linp = NULL;
    5267             :                                 } else {
    5268           0 :                                         linp = inp;
    5269             :                                 }
    5270             : 
    5271           0 :                                 if (linp) {
    5272           0 :                                         SCTP_ASOC_CREATE_LOCK(linp);
    5273           0 :                                         if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
    5274           0 :                                             (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
    5275           0 :                                                 SCTP_ASOC_CREATE_UNLOCK(linp);
    5276           0 :                                                 goto abend;
    5277             :                                         }
    5278             :                                 }
    5279             : 
    5280           0 :                                 if (netp) {
    5281           0 :                                         ret_buf =
    5282           0 :                                                 sctp_handle_cookie_echo(m, iphlen,
    5283             :                                                                         *offset,
    5284             :                                                                         src, dst,
    5285             :                                                                         sh,
    5286             :                                                                         (struct sctp_cookie_echo_chunk *)ch,
    5287             :                                                                         &inp, &stcb, netp,
    5288             :                                                                         auth_skipped,
    5289             :                                                                         auth_offset,
    5290             :                                                                         auth_len,
    5291             :                                                                         &locked_tcb,
    5292             : #if defined(__FreeBSD__)
    5293             :                                                                         mflowtype,
    5294             :                                                                         mflowid,
    5295             : #endif
    5296             :                                                                         vrf_id,
    5297             :                                                                         port);
    5298             :                                 } else {
    5299           0 :                                         ret_buf = NULL;
    5300             :                                 }
    5301           0 :                                 if (linp) {
    5302           0 :                                         SCTP_ASOC_CREATE_UNLOCK(linp);
    5303             :                                 }
    5304           0 :                                 if (ret_buf == NULL) {
    5305           0 :                                         if (locked_tcb) {
    5306           0 :                                                 SCTP_TCB_UNLOCK(locked_tcb);
    5307             :                                         }
    5308           0 :                                         SCTPDBG(SCTP_DEBUG_INPUT3,
    5309             :                                                 "GAK, null buffer\n");
    5310           0 :                                         *offset = length;
    5311           0 :                                         return (NULL);
    5312             :                                 }
    5313             :                                 /* if AUTH skipped, see if it verified... */
    5314           0 :                                 if (auth_skipped) {
    5315           0 :                                         got_auth = 1;
    5316           0 :                                         auth_skipped = 0;
    5317             :                                 }
    5318           0 :                                 if (!TAILQ_EMPTY(&stcb->asoc.sent_queue)) {
    5319             :                                         /*
    5320             :                                          * Restart the timer if we have
    5321             :                                          * pending data
    5322             :                                          */
    5323             :                                         struct sctp_tmit_chunk *chk;
    5324             : 
    5325           0 :                                         chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
    5326           0 :                                         sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo);
    5327             :                                 }
    5328             :                         }
    5329           0 :                         break;
    5330             :                 case SCTP_COOKIE_ACK:
    5331           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_COOKIE-ACK, stcb %p\n", (void *)stcb);
    5332           0 :                         if ((stcb == NULL) || chk_length != sizeof(struct sctp_cookie_ack_chunk)) {
    5333           0 :                                 if (locked_tcb) {
    5334           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    5335             :                                 }
    5336           0 :                                 return (NULL);
    5337             :                         }
    5338           0 :                         if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
    5339             :                                 /* We are not interested anymore */
    5340           0 :                                 if ((stcb) && (stcb->asoc.total_output_queue_size)) {
    5341             :                                         ;
    5342           0 :                                 } else if (stcb) {
    5343             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    5344             :                                         so = SCTP_INP_SO(inp);
    5345             :                                         atomic_add_int(&stcb->asoc.refcnt, 1);
    5346             :                                         SCTP_TCB_UNLOCK(stcb);
    5347             :                                         SCTP_SOCKET_LOCK(so, 1);
    5348             :                                         SCTP_TCB_LOCK(stcb);
    5349             :                                         atomic_subtract_int(&stcb->asoc.refcnt, 1);
    5350             : #endif
    5351           0 :                                         (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_27);
    5352             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    5353             :                                         SCTP_SOCKET_UNLOCK(so, 1);
    5354             : #endif
    5355           0 :                                         *offset = length;
    5356           0 :                                         return (NULL);
    5357             :                                 }
    5358             :                         }
    5359             :                         /* He's alive so give him credit */
    5360           0 :                         if ((stcb) && netp && *netp) {
    5361           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
    5362           0 :                                         sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    5363           0 :                                                        stcb->asoc.overall_error_count,
    5364             :                                                        0,
    5365             :                                                        SCTP_FROM_SCTP_INPUT,
    5366             :                                                        __LINE__);
    5367             :                                 }
    5368           0 :                                 stcb->asoc.overall_error_count = 0;
    5369           0 :                                 sctp_handle_cookie_ack((struct sctp_cookie_ack_chunk *)ch,stcb, *netp);
    5370             :                         }
    5371           0 :                         break;
    5372             :                 case SCTP_ECN_ECHO:
    5373           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ECN-ECHO\n");
    5374             :                         /* He's alive so give him credit */
    5375           0 :                         if ((stcb == NULL) || (chk_length != sizeof(struct sctp_ecne_chunk))) {
    5376             :                                 /* Its not ours */
    5377           0 :                                 if (locked_tcb) {
    5378           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    5379             :                                 }
    5380           0 :                                 *offset = length;
    5381           0 :                                 return (NULL);
    5382             :                         }
    5383           0 :                         if (stcb) {
    5384           0 :                                 if (stcb->asoc.ecn_supported == 0) {
    5385           0 :                                         goto unknown_chunk;
    5386             :                                 }
    5387           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
    5388           0 :                                         sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    5389           0 :                                                        stcb->asoc.overall_error_count,
    5390             :                                                        0,
    5391             :                                                        SCTP_FROM_SCTP_INPUT,
    5392             :                                                        __LINE__);
    5393             :                                 }
    5394           0 :                                 stcb->asoc.overall_error_count = 0;
    5395           0 :                                 sctp_handle_ecn_echo((struct sctp_ecne_chunk *)ch,
    5396             :                                                      stcb);
    5397           0 :                                 ecne_seen = 1;
    5398             :                         }
    5399           0 :                         break;
    5400             :                 case SCTP_ECN_CWR:
    5401           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ECN-CWR\n");
    5402             :                         /* He's alive so give him credit */
    5403           0 :                         if ((stcb == NULL) || (chk_length != sizeof(struct sctp_cwr_chunk))) {
    5404             :                                 /* Its not ours */
    5405           0 :                                 if (locked_tcb) {
    5406           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    5407             :                                 }
    5408           0 :                                 *offset = length;
    5409           0 :                                 return (NULL);
    5410             :                         }
    5411           0 :                         if (stcb) {
    5412           0 :                                 if (stcb->asoc.ecn_supported == 0) {
    5413           0 :                                         goto unknown_chunk;
    5414             :                                 }
    5415           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
    5416           0 :                                         sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    5417           0 :                                                        stcb->asoc.overall_error_count,
    5418             :                                                        0,
    5419             :                                                        SCTP_FROM_SCTP_INPUT,
    5420             :                                                        __LINE__);
    5421             :                                 }
    5422           0 :                                 stcb->asoc.overall_error_count = 0;
    5423           0 :                                 sctp_handle_ecn_cwr((struct sctp_cwr_chunk *)ch, stcb, *netp);
    5424             :                         }
    5425           0 :                         break;
    5426             :                 case SCTP_SHUTDOWN_COMPLETE:
    5427           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN-COMPLETE, stcb %p\n", (void *)stcb);
    5428             :                         /* must be first and only chunk */
    5429           0 :                         if ((num_chunks > 1) ||
    5430           0 :                             (length - *offset > (int)SCTP_SIZE32(chk_length))) {
    5431           0 :                                 *offset = length;
    5432           0 :                                 if (locked_tcb) {
    5433           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    5434             :                                 }
    5435           0 :                                 return (NULL);
    5436             :                         }
    5437           0 :                         if ((stcb) && netp && *netp) {
    5438           0 :                                 sctp_handle_shutdown_complete((struct sctp_shutdown_complete_chunk *)ch,
    5439             :                                                               stcb, *netp);
    5440             :                         }
    5441           0 :                         *offset = length;
    5442           0 :                         return (NULL);
    5443             :                         break;
    5444             :                 case SCTP_ASCONF:
    5445           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ASCONF\n");
    5446             :                         /* He's alive so give him credit */
    5447           0 :                         if (stcb) {
    5448           0 :                                 if (stcb->asoc.asconf_supported == 0) {
    5449           0 :                                         goto unknown_chunk;
    5450             :                                 }
    5451           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
    5452           0 :                                         sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    5453           0 :                                                        stcb->asoc.overall_error_count,
    5454             :                                                        0,
    5455             :                                                        SCTP_FROM_SCTP_INPUT,
    5456             :                                                        __LINE__);
    5457             :                                 }
    5458           0 :                                 stcb->asoc.overall_error_count = 0;
    5459           0 :                                 sctp_handle_asconf(m, *offset, src,
    5460             :                                                    (struct sctp_asconf_chunk *)ch, stcb, asconf_cnt == 0);
    5461           0 :                                 asconf_cnt++;
    5462             :                         }
    5463           0 :                         break;
    5464             :                 case SCTP_ASCONF_ACK:
    5465           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ASCONF-ACK\n");
    5466           0 :                         if (chk_length < sizeof(struct sctp_asconf_ack_chunk)) {
    5467             :                                 /* Its not ours */
    5468           0 :                                 if (locked_tcb) {
    5469           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    5470             :                                 }
    5471           0 :                                 *offset = length;
    5472           0 :                                 return (NULL);
    5473             :                         }
    5474           0 :                         if ((stcb) && netp && *netp) {
    5475           0 :                                 if (stcb->asoc.asconf_supported == 0) {
    5476           0 :                                         goto unknown_chunk;
    5477             :                                 }
    5478             :                                 /* He's alive so give him credit */
    5479           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
    5480           0 :                                         sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    5481           0 :                                                        stcb->asoc.overall_error_count,
    5482             :                                                        0,
    5483             :                                                        SCTP_FROM_SCTP_INPUT,
    5484             :                                                        __LINE__);
    5485             :                                 }
    5486           0 :                                 stcb->asoc.overall_error_count = 0;
    5487           0 :                                 sctp_handle_asconf_ack(m, *offset,
    5488             :                                                        (struct sctp_asconf_ack_chunk *)ch, stcb, *netp, &abort_no_unlock);
    5489           0 :                                 if (abort_no_unlock)
    5490           0 :                                         return (NULL);
    5491             :                         }
    5492           0 :                         break;
    5493             :                 case SCTP_FORWARD_CUM_TSN:
    5494           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_FWD-TSN\n");
    5495           0 :                         if (chk_length < sizeof(struct sctp_forward_tsn_chunk)) {
    5496             :                                 /* Its not ours */
    5497           0 :                                 if (locked_tcb) {
    5498           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    5499             :                                 }
    5500           0 :                                 *offset = length;
    5501           0 :                                 return (NULL);
    5502             :                         }
    5503             : 
    5504             :                         /* He's alive so give him credit */
    5505           0 :                         if (stcb) {
    5506           0 :                                 int abort_flag = 0;
    5507             : 
    5508           0 :                                 if (stcb->asoc.prsctp_supported == 0) {
    5509           0 :                                         goto unknown_chunk;
    5510             :                                 }
    5511           0 :                                 stcb->asoc.overall_error_count = 0;
    5512           0 :                                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
    5513           0 :                                         sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    5514           0 :                                                        stcb->asoc.overall_error_count,
    5515             :                                                        0,
    5516             :                                                        SCTP_FROM_SCTP_INPUT,
    5517             :                                                        __LINE__);
    5518             :                                 }
    5519           0 :                                 *fwd_tsn_seen = 1;
    5520           0 :                                 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
    5521             :                                         /* We are not interested anymore */
    5522             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    5523             :                                         so = SCTP_INP_SO(inp);
    5524             :                                         atomic_add_int(&stcb->asoc.refcnt, 1);
    5525             :                                         SCTP_TCB_UNLOCK(stcb);
    5526             :                                         SCTP_SOCKET_LOCK(so, 1);
    5527             :                                         SCTP_TCB_LOCK(stcb);
    5528             :                                         atomic_subtract_int(&stcb->asoc.refcnt, 1);
    5529             : #endif
    5530           0 :                                         (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_29);
    5531             : #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
    5532             :                                         SCTP_SOCKET_UNLOCK(so, 1);
    5533             : #endif
    5534           0 :                                         *offset = length;
    5535           0 :                                         return (NULL);
    5536             :                                 }
    5537           0 :                                 sctp_handle_forward_tsn(stcb,
    5538             :                                                         (struct sctp_forward_tsn_chunk *)ch, &abort_flag, m, *offset);
    5539           0 :                                 if (abort_flag) {
    5540           0 :                                         *offset = length;
    5541           0 :                                         return (NULL);
    5542             :                                 } else {
    5543           0 :                                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
    5544           0 :                                                 sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    5545           0 :                                                                stcb->asoc.overall_error_count,
    5546             :                                                                0,
    5547             :                                                                SCTP_FROM_SCTP_INPUT,
    5548             :                                                                __LINE__);
    5549             :                                         }
    5550           0 :                                         stcb->asoc.overall_error_count = 0;
    5551             :                                 }
    5552             : 
    5553             :                         }
    5554           0 :                         break;
    5555             :                 case SCTP_STREAM_RESET:
    5556           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_STREAM_RESET\n");
    5557           0 :                         if (((stcb == NULL) || (ch == NULL) || (chk_length < sizeof(struct sctp_stream_reset_tsn_req)))) {
    5558             :                                 /* Its not ours */
    5559           0 :                                 if (locked_tcb) {
    5560           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    5561             :                                 }
    5562           0 :                                 *offset = length;
    5563           0 :                                 return (NULL);
    5564             :                         }
    5565           0 :                         if (stcb->asoc.reconfig_supported == 0) {
    5566           0 :                                 goto unknown_chunk;
    5567             :                         }
    5568           0 :                         if (sctp_handle_stream_reset(stcb, m, *offset, ch)) {
    5569             :                                 /* stop processing */
    5570           0 :                                 *offset = length;
    5571           0 :                                 return (NULL);
    5572             :                         }
    5573           0 :                         break;
    5574             :                 case SCTP_PACKET_DROPPED:
    5575           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_PACKET_DROPPED\n");
    5576             :                         /* re-get it all please */
    5577           0 :                         if (chk_length < sizeof(struct sctp_pktdrop_chunk)) {
    5578             :                                 /* Its not ours */
    5579           0 :                                 if (locked_tcb) {
    5580           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    5581             :                                 }
    5582           0 :                                 *offset = length;
    5583           0 :                                 return (NULL);
    5584             :                         }
    5585             : 
    5586             : 
    5587           0 :                         if (ch && (stcb) && netp && (*netp)) {
    5588           0 :                                 if (stcb->asoc.pktdrop_supported == 0) {
    5589           0 :                                         goto unknown_chunk;
    5590             :                                 }
    5591           0 :                                 sctp_handle_packet_dropped((struct sctp_pktdrop_chunk *)ch,
    5592             :                                                            stcb, *netp,
    5593             :                                                            min(chk_length, (sizeof(chunk_buf) - 4)));
    5594             : 
    5595             :                         }
    5596             : 
    5597           0 :                         break;
    5598             :                 case SCTP_AUTHENTICATION:
    5599           0 :                         SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_AUTHENTICATION\n");
    5600           0 :                         if (stcb == NULL) {
    5601             :                                 /* save the first AUTH for later processing */
    5602           0 :                                 if (auth_skipped == 0) {
    5603           0 :                                         auth_offset = *offset;
    5604           0 :                                         auth_len = chk_length;
    5605           0 :                                         auth_skipped = 1;
    5606             :                                 }
    5607             :                                 /* skip this chunk (temporarily) */
    5608           0 :                                 goto next_chunk;
    5609             :                         }
    5610           0 :                         if (stcb->asoc.auth_supported == 0) {
    5611           0 :                                 goto unknown_chunk;
    5612             :                         }
    5613           0 :                         if ((chk_length < (sizeof(struct sctp_auth_chunk))) ||
    5614             :                             (chk_length > (sizeof(struct sctp_auth_chunk) +
    5615             :                                            SCTP_AUTH_DIGEST_LEN_MAX))) {
    5616             :                                 /* Its not ours */
    5617           0 :                                 if (locked_tcb) {
    5618           0 :                                         SCTP_TCB_UNLOCK(locked_tcb);
    5619             :                                 }
    5620           0 :                                 *offset = length;
    5621           0 :                                 return (NULL);
    5622             :                         }
    5623           0 :                         if (got_auth == 1) {
    5624             :                                 /* skip this chunk... it's already auth'd */
    5625           0 :                                 goto next_chunk;
    5626             :                         }
    5627           0 :                         got_auth = 1;
    5628           0 :                         if ((ch == NULL) || sctp_handle_auth(stcb, (struct sctp_auth_chunk *)ch,
    5629           0 :                                                              m, *offset)) {
    5630             :                                 /* auth HMAC failed so dump the packet */
    5631           0 :                                 *offset = length;
    5632           0 :                                 return (stcb);
    5633             :                         } else {
    5634             :                                 /* remaining chunks are HMAC checked */
    5635           0 :                                 stcb->asoc.authenticated = 1;
    5636             :                         }
    5637           0 :                         break;
    5638             : 
    5639             :                 default:
    5640             :                 unknown_chunk:
    5641             :                         /* it's an unknown chunk! */
    5642           0 :                         if ((ch->chunk_type & 0x40) && (stcb != NULL)) {
    5643             :                                 struct mbuf *mm;
    5644             :                                 struct sctp_paramhdr *phd;
    5645             :                                 int len;
    5646             : 
    5647           0 :                                 mm = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
    5648             :                                                            0, M_NOWAIT, 1, MT_DATA);
    5649           0 :                                 if (mm) {
    5650           0 :                                         len = min(SCTP_SIZE32(chk_length), (uint32_t)(length - *offset));
    5651           0 :                                         phd = mtod(mm, struct sctp_paramhdr *);
    5652             :                                         /*
    5653             :                                          * We cheat and use param type since
    5654             :                                          * we did not bother to define a
    5655             :                                          * error cause struct. They are the
    5656             :                                          * same basic format with different
    5657             :                                          * names.
    5658             :                                          */
    5659           0 :                                         phd->param_type =  htons(SCTP_CAUSE_UNRECOG_CHUNK);
    5660           0 :                                         phd->param_length = htons(len + sizeof(*phd));
    5661           0 :                                         SCTP_BUF_LEN(mm) = sizeof(*phd);
    5662           0 :                                         SCTP_BUF_NEXT(mm) = SCTP_M_COPYM(m, *offset, len, M_NOWAIT);
    5663           0 :                                         if (SCTP_BUF_NEXT(mm)) {
    5664           0 :                                                 if (sctp_pad_lastmbuf(SCTP_BUF_NEXT(mm), SCTP_SIZE32(len) - len, NULL) == NULL) {
    5665           0 :                                                         sctp_m_freem(mm);
    5666             :                                                 } else {
    5667             : #ifdef SCTP_MBUF_LOGGING
    5668             :                                                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
    5669             :                                                                 sctp_log_mbc(SCTP_BUF_NEXT(mm), SCTP_MBUF_ICOPY);
    5670             :                                                         }
    5671             : #endif
    5672           0 :                                                         sctp_queue_op_err(stcb, mm);
    5673             :                                                 }
    5674             :                                         } else {
    5675           0 :                                                 sctp_m_freem(mm);
    5676             :                                         }
    5677             :                                 }
    5678             :                         }
    5679           0 :                         if ((ch->chunk_type & 0x80) == 0) {
    5680             :                                 /* discard this packet */
    5681           0 :                                 *offset = length;
    5682           0 :                                 return (stcb);
    5683             :                         }       /* else skip this bad chunk and continue... */
    5684           0 :                         break;
    5685             :                 }               /* switch (ch->chunk_type) */
    5686             : 
    5687             : 
    5688             :         next_chunk:
    5689             :                 /* get the next chunk */
    5690           0 :                 *offset += SCTP_SIZE32(chk_length);
    5691           0 :                 if (*offset >= length) {
    5692             :                         /* no more data left in the mbuf chain */
    5693           0 :                         break;
    5694             :                 }
    5695           0 :                 ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
    5696             :                                                            sizeof(struct sctp_chunkhdr), chunk_buf);
    5697           0 :                 if (ch == NULL) {
    5698           0 :                         if (locked_tcb) {
    5699           0 :                                 SCTP_TCB_UNLOCK(locked_tcb);
    5700             :                         }
    5701           0 :                         *offset = length;
    5702           0 :                         return (NULL);
    5703             :                 }
    5704             :         }                       /* while */
    5705             : 
    5706           0 :         if (asconf_cnt > 0 && stcb != NULL) {
    5707           0 :                 sctp_send_asconf_ack(stcb);
    5708             :         }
    5709           0 :         return (stcb);
    5710             : }
    5711             : 
    5712             : 
    5713             : #ifdef INVARIANTS
    5714             : #ifdef __GNUC__
    5715             : __attribute__((noinline))
    5716             : #endif
    5717             : void
    5718             : sctp_validate_no_locks(struct sctp_inpcb *inp)
    5719             : {
    5720             : #ifndef __APPLE__
    5721             :         struct sctp_tcb *lstcb;
    5722             : 
    5723             :         LIST_FOREACH(lstcb, &inp->sctp_asoc_list, sctp_tcblist) {
    5724             :                 if (mtx_owned(&lstcb->tcb_mtx)) {
    5725             :                         panic("Own lock on stcb at return from input");
    5726             :                 }
    5727             :         }
    5728             :         if (mtx_owned(&inp->inp_create_mtx)) {
    5729             :                 panic("Own create lock on inp");
    5730             :         }
    5731             :         if (mtx_owned(&inp->inp_mtx)) {
    5732             :                 panic("Own inp lock on inp");
    5733             :         }
    5734             : #endif
    5735             : }
    5736             : #endif
    5737             : 
    5738             : /*
    5739             :  * common input chunk processing (v4 and v6)
    5740             :  */
    5741             : void
    5742           0 : sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int length,
    5743             :                              struct sockaddr *src, struct sockaddr *dst,
    5744             :                              struct sctphdr *sh, struct sctp_chunkhdr *ch,
    5745             : #if !defined(SCTP_WITH_NO_CSUM)
    5746             :                              uint8_t compute_crc,
    5747             : #endif
    5748             :                              uint8_t ecn_bits,
    5749             : #if defined(__FreeBSD__)
    5750             :                              uint8_t mflowtype, uint32_t mflowid,
    5751             : #endif
    5752             :                              uint32_t vrf_id, uint16_t port)
    5753             : {
    5754             :         uint32_t high_tsn;
    5755           0 :         int fwd_tsn_seen = 0, data_processed = 0;
    5756           0 :         struct mbuf *m = *mm, *op_err;
    5757             :         char msg[SCTP_DIAG_INFO_LEN];
    5758             :         int un_sent;
    5759           0 :         int cnt_ctrl_ready = 0;
    5760           0 :         struct sctp_inpcb *inp = NULL, *inp_decr = NULL;
    5761           0 :         struct sctp_tcb *stcb = NULL;
    5762           0 :         struct sctp_nets *net = NULL;
    5763             : 
    5764           0 :         SCTP_STAT_INCR(sctps_recvdatagrams);
    5765             : #ifdef SCTP_AUDITING_ENABLED
    5766             :         sctp_audit_log(0xE0, 1);
    5767             :         sctp_auditing(0, inp, stcb, net);
    5768             : #endif
    5769             : #if !defined(SCTP_WITH_NO_CSUM)
    5770           0 :         if (compute_crc != 0) {
    5771             :                 uint32_t check, calc_check;
    5772             : 
    5773           0 :                 check = sh->checksum;
    5774           0 :                 sh->checksum = 0;
    5775           0 :                 calc_check = sctp_calculate_cksum(m, iphlen);
    5776           0 :                 sh->checksum = check;
    5777           0 :                 if (calc_check != check) {
    5778           0 :                         SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x  m:%p mlen:%d iphlen:%d\n",
    5779             :                                 calc_check, check, (void *)m, length, iphlen);
    5780           0 :                         stcb = sctp_findassociation_addr(m, offset, src, dst,
    5781             :                                                          sh, ch, &inp, &net, vrf_id);
    5782             : #if defined(INET) || defined(INET6)
    5783             :                         if ((net != NULL) && (port != 0)) {
    5784             :                                 if (net->port == 0) {
    5785             :                                         sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
    5786             :                                 }
    5787             :                                 net->port = port;
    5788             :                         }
    5789             : #endif
    5790             : #if defined(__FreeBSD__)
    5791             :                         if ((net != NULL) && (mflowtype != M_HASHTYPE_NONE)) {
    5792             :                                 net->flowtype = mflowtype;
    5793             :                         }
    5794             : #endif
    5795           0 :                         if ((inp != NULL) && (stcb != NULL)) {
    5796           0 :                                 sctp_send_packet_dropped(stcb, net, m, length, iphlen, 1);
    5797           0 :                                 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED);
    5798           0 :                         } else if ((inp != NULL) && (stcb == NULL)) {
    5799           0 :                                 inp_decr = inp;
    5800             :                         }
    5801           0 :                         SCTP_STAT_INCR(sctps_badsum);
    5802           0 :                         SCTP_STAT_INCR_COUNTER32(sctps_checksumerrors);
    5803           0 :                         goto out;
    5804             :                 }
    5805             :         }
    5806             : #endif
    5807             :         /* Destination port of 0 is illegal, based on RFC4960. */
    5808           0 :         if (sh->dest_port == 0) {
    5809           0 :                 SCTP_STAT_INCR(sctps_hdrops);
    5810           0 :                 goto out;
    5811             :         }
    5812           0 :         stcb = sctp_findassociation_addr(m, offset, src, dst,
    5813             :                                          sh, ch, &inp, &net, vrf_id);
    5814             : #if defined(INET) || defined(INET6)
    5815             :         if ((net != NULL) && (port != 0)) {
    5816             :                 if (net->port == 0) {
    5817             :                         sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
    5818             :                 }
    5819             :                 net->port = port;
    5820             :         }
    5821             : #endif
    5822             : #if defined(__FreeBSD__)
    5823             :         if ((net != NULL) && (mflowtype != M_HASHTYPE_NONE)) {
    5824             :                 net->flowtype = mflowtype;
    5825             :         }
    5826             : #endif
    5827           0 :         if (inp == NULL) {
    5828           0 :                 SCTP_STAT_INCR(sctps_noport);
    5829             : #if defined(__FreeBSD__) && (((__FreeBSD_version < 900000) && (__FreeBSD_version >= 804000)) || (__FreeBSD_version > 900000))
    5830             :                 if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0) {
    5831             :                         goto out;
    5832             :                 }
    5833             : #endif
    5834           0 :                 if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
    5835           0 :                         sctp_send_shutdown_complete2(src, dst, sh,
    5836             : #if defined(__FreeBSD__)
    5837             :                                                      mflowtype, mflowid,
    5838             : #endif
    5839             :                                                      vrf_id, port);
    5840           0 :                         goto out;
    5841             :                 }
    5842           0 :                 if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) {
    5843           0 :                         goto out;
    5844             :                 }
    5845           0 :                 if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) {
    5846           0 :                         if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
    5847           0 :                             ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
    5848           0 :                              (ch->chunk_type != SCTP_INIT))) {
    5849           0 :                                 op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
    5850             :                                                              "Out of the blue");
    5851           0 :                                 sctp_send_abort(m, iphlen, src, dst,
    5852             :                                                 sh, 0, op_err,
    5853             : #if defined(__FreeBSD__)
    5854             :                                                 mflowtype, mflowid,
    5855             : #endif
    5856             :                                                 vrf_id, port);
    5857             :                         }
    5858             :                 }
    5859           0 :                 goto out;
    5860           0 :         } else if (stcb == NULL) {
    5861           0 :                 inp_decr = inp;
    5862             :         }
    5863             : #ifdef IPSEC
    5864             :         /*-
    5865             :          * I very much doubt any of the IPSEC stuff will work but I have no
    5866             :          * idea, so I will leave it in place.
    5867             :          */
    5868             :         if (inp != NULL) {
    5869             :                 switch (dst->sa_family) {
    5870             : #ifdef INET
    5871             :                 case AF_INET:
    5872             :                         if (ipsec4_in_reject(m, &inp->ip_inp.inp)) {
    5873             :                                 SCTP_STAT_INCR(sctps_hdrops);
    5874             :                                 goto out;
    5875             :                         }
    5876             :                         break;
    5877             : #endif
    5878             : #ifdef INET6
    5879             :                 case AF_INET6:
    5880             :                         if (ipsec6_in_reject(m, &inp->ip_inp.inp)) {
    5881             :                                 SCTP_STAT_INCR(sctps_hdrops);
    5882             :                                 goto out;
    5883             :                         }
    5884             :                         break;
    5885             : #endif
    5886             :                 default:
    5887             :                         break;
    5888             :                 }
    5889             :         }
    5890             : #endif
    5891           0 :         SCTPDBG(SCTP_DEBUG_INPUT1, "Ok, Common input processing called, m:%p iphlen:%d offset:%d length:%d stcb:%p\n",
    5892             :                 (void *)m, iphlen, offset, length, (void *)stcb);
    5893           0 :         if (stcb) {
    5894             :                 /* always clear this before beginning a packet */
    5895           0 :                 stcb->asoc.authenticated = 0;
    5896           0 :                 stcb->asoc.seen_a_sack_this_pkt = 0;
    5897           0 :                 SCTPDBG(SCTP_DEBUG_INPUT1, "stcb:%p state:%x\n",
    5898             :                         (void *)stcb, stcb->asoc.state);
    5899             : 
    5900           0 :                 if ((stcb->asoc.state & SCTP_STATE_WAS_ABORTED) ||
    5901           0 :                     (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED)) {
    5902             :                         /*-
    5903             :                          * If we hit here, we had a ref count
    5904             :                          * up when the assoc was aborted and the
    5905             :                          * timer is clearing out the assoc, we should
    5906             :                          * NOT respond to any packet.. its OOTB.
    5907             :                          */
    5908           0 :                         SCTP_TCB_UNLOCK(stcb);
    5909           0 :                         stcb = NULL;
    5910           0 :                         snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
    5911           0 :                         op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
    5912             :                                                      msg);
    5913           0 :                         sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
    5914             : #if defined(__FreeBSD__)
    5915             :                                          mflowtype, mflowid,
    5916             : #endif
    5917             :                                          vrf_id, port);
    5918           0 :                         goto out;
    5919             :                 }
    5920             : 
    5921             :         }
    5922           0 :         if (IS_SCTP_CONTROL(ch)) {
    5923             :                 /* process the control portion of the SCTP packet */
    5924             :                 /* sa_ignore NO_NULL_CHK */
    5925           0 :                 stcb = sctp_process_control(m, iphlen, &offset, length,
    5926             :                                             src, dst, sh, ch,
    5927             :                                             inp, stcb, &net, &fwd_tsn_seen,
    5928             : #if defined(__FreeBSD__)
    5929             :                                             mflowtype, mflowid,
    5930             : #endif
    5931             :                                             vrf_id, port);
    5932           0 :                 if (stcb) {
    5933             :                         /* This covers us if the cookie-echo was there
    5934             :                          * and it changes our INP.
    5935             :                          */
    5936           0 :                         inp = stcb->sctp_ep;
    5937             : #if defined(INET) || defined(INET6)
    5938             :                         if ((net) && (port)) {
    5939             :                                 if (net->port == 0) {
    5940             :                                         sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
    5941             :                                 }
    5942             :                                 net->port = port;
    5943             :                         }
    5944             : #endif
    5945             :                 }
    5946             :         } else {
    5947             :                 /*
    5948             :                  * no control chunks, so pre-process DATA chunks (these
    5949             :                  * checks are taken care of by control processing)
    5950             :                  */
    5951             : 
    5952             :                 /*
    5953             :                  * if DATA only packet, and auth is required, then punt...
    5954             :                  * can't have authenticated without any AUTH (control)
    5955             :                  * chunks
    5956             :                  */
    5957           0 :                 if ((stcb != NULL) &&
    5958           0 :                     (stcb->asoc.auth_supported == 1) &&
    5959           0 :                     sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks)) {
    5960             :                         /* "silently" ignore */
    5961           0 :                         SCTP_STAT_INCR(sctps_recvauthmissing);
    5962           0 :                         goto out;
    5963             :                 }
    5964           0 :                 if (stcb == NULL) {
    5965             :                         /* out of the blue DATA chunk */
    5966           0 :                         snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
    5967           0 :                         op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
    5968             :                                                      msg);
    5969           0 :                         sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
    5970             : #if defined(__FreeBSD__)
    5971             :                                          mflowtype, mflowid,
    5972             : #endif
    5973             :                                          vrf_id, port);
    5974           0 :                         goto out;
    5975             :                 }
    5976           0 :                 if (stcb->asoc.my_vtag != ntohl(sh->v_tag)) {
    5977             :                         /* v_tag mismatch! */
    5978           0 :                         SCTP_STAT_INCR(sctps_badvtag);
    5979           0 :                         goto out;
    5980             :                 }
    5981             :         }
    5982             : 
    5983           0 :         if (stcb == NULL) {
    5984             :                 /*
    5985             :                  * no valid TCB for this packet, or we found it's a bad
    5986             :                  * packet while processing control, or we're done with this
    5987             :                  * packet (done or skip rest of data), so we drop it...
    5988             :                  */
    5989           0 :                 goto out;
    5990             :         }
    5991             : 
    5992             :         /*
    5993             :          * DATA chunk processing
    5994             :          */
    5995             :         /* plow through the data chunks while length > offset */
    5996             : 
    5997             :         /*
    5998             :          * Rest should be DATA only.  Check authentication state if AUTH for
    5999             :          * DATA is required.
    6000             :          */
    6001           0 :         if ((length > offset) &&
    6002           0 :             (stcb != NULL) &&
    6003           0 :             (stcb->asoc.auth_supported == 1) &&
    6004           0 :             sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks) &&
    6005           0 :             !stcb->asoc.authenticated) {
    6006             :                 /* "silently" ignore */
    6007           0 :                 SCTP_STAT_INCR(sctps_recvauthmissing);
    6008           0 :                 SCTPDBG(SCTP_DEBUG_AUTH1,
    6009             :                         "Data chunk requires AUTH, skipped\n");
    6010           0 :                 goto trigger_send;
    6011             :         }
    6012           0 :         if (length > offset) {
    6013             :                 int retval;
    6014             : 
    6015             :                 /*
    6016             :                  * First check to make sure our state is correct. We would
    6017             :                  * not get here unless we really did have a tag, so we don't
    6018             :                  * abort if this happens, just dump the chunk silently.
    6019             :                  */
    6020           0 :                 switch (SCTP_GET_STATE(&stcb->asoc)) {
    6021             :                 case SCTP_STATE_COOKIE_ECHOED:
    6022             :                         /*
    6023             :                          * we consider data with valid tags in this state
    6024             :                          * shows us the cookie-ack was lost. Imply it was
    6025             :                          * there.
    6026             :                          */
    6027           0 :                         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
    6028           0 :                                 sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
    6029             :                                                stcb->asoc.overall_error_count,
    6030             :                                                0,
    6031             :                                                SCTP_FROM_SCTP_INPUT,
    6032             :                                                __LINE__);
    6033             :                         }
    6034           0 :                         stcb->asoc.overall_error_count = 0;
    6035           0 :                         sctp_handle_cookie_ack((struct sctp_cookie_ack_chunk *)ch, stcb, net);
    6036           0 :                         break;
    6037             :                 case SCTP_STATE_COOKIE_WAIT:
    6038             :                         /*
    6039             :                          * We consider OOTB any data sent during asoc setup.
    6040             :                          */
    6041           0 :                         snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
    6042           0 :                         op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
    6043             :                                                      msg);
    6044           0 :                         sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
    6045             : #if defined(__FreeBSD__)
    6046             :                                          mflowtype, mflowid,
    6047             : #endif
    6048             :                                          vrf_id, port);
    6049           0 :                         goto out;
    6050             :                         /*sa_ignore NOTREACHED*/
    6051             :                         break;
    6052             :                 case SCTP_STATE_EMPTY:  /* should not happen */
    6053             :                 case SCTP_STATE_INUSE:  /* should not happen */
    6054             :                 case SCTP_STATE_SHUTDOWN_RECEIVED:      /* This is a peer error */
    6055             :                 case SCTP_STATE_SHUTDOWN_ACK_SENT:
    6056             :                 default:
    6057           0 :                         goto out;
    6058             :                         /*sa_ignore NOTREACHED*/
    6059             :                         break;
    6060             :                 case SCTP_STATE_OPEN:
    6061             :                 case SCTP_STATE_SHUTDOWN_SENT:
    6062           0 :                         break;
    6063             :                 }
    6064             :                 /* plow through the data chunks while length > offset */
    6065           0 :                 retval = sctp_process_data(mm, iphlen, &offset, length,
    6066             :                                            src, dst, sh,
    6067             :                                            inp, stcb, net, &high_tsn,
    6068             : #if defined(__FreeBSD__)
    6069             :                                            mflowtype, mflowid,
    6070             : #endif
    6071             :                                            vrf_id, port);
    6072           0 :                 if (retval == 2) {
    6073             :                         /*
    6074             :                          * The association aborted, NO UNLOCK needed since
    6075             :                          * the association is destroyed.
    6076             :                          */
    6077           0 :                         stcb = NULL;
    6078           0 :                         goto out;
    6079             :                 }
    6080           0 :                 data_processed = 1;
    6081             :                 /*
    6082             :                  * Anything important needs to have been m_copy'ed in
    6083             :                  * process_data
    6084             :                  */
    6085             :         }
    6086             : 
    6087             :         /* take care of ecn */
    6088           0 :         if ((data_processed == 1) &&
    6089           0 :             (stcb->asoc.ecn_supported == 1) &&
    6090           0 :             ((ecn_bits & SCTP_CE_BITS) == SCTP_CE_BITS)) {
    6091             :                 /* Yep, we need to add a ECNE */
    6092           0 :                 sctp_send_ecn_echo(stcb, net, high_tsn);
    6093             :         }
    6094             : 
    6095           0 :         if ((data_processed == 0) && (fwd_tsn_seen)) {
    6096             :                 int was_a_gap;
    6097             :                 uint32_t highest_tsn;
    6098             : 
    6099           0 :                 if (SCTP_TSN_GT(stcb->asoc.highest_tsn_inside_nr_map, stcb->asoc.highest_tsn_inside_map)) {
    6100           0 :                         highest_tsn = stcb->asoc.highest_tsn_inside_nr_map;
    6101             :                 } else {
    6102           0 :                         highest_tsn = stcb->asoc.highest_tsn_inside_map;
    6103             :                 }
    6104           0 :                 was_a_gap = SCTP_TSN_GT(highest_tsn, stcb->asoc.cumulative_tsn);
    6105           0 :                 stcb->asoc.send_sack = 1;
    6106           0 :                 sctp_sack_check(stcb, was_a_gap);
    6107           0 :         } else if (fwd_tsn_seen) {
    6108           0 :                 stcb->asoc.send_sack = 1;
    6109             :         }
    6110             :         /* trigger send of any chunks in queue... */
    6111             : trigger_send:
    6112             : #ifdef SCTP_AUDITING_ENABLED
    6113             :         sctp_audit_log(0xE0, 2);
    6114             :         sctp_auditing(1, inp, stcb, net);
    6115             : #endif
    6116           0 :         SCTPDBG(SCTP_DEBUG_INPUT1,
    6117             :                 "Check for chunk output prw:%d tqe:%d tf=%d\n",
    6118             :                 stcb->asoc.peers_rwnd,
    6119             :                 TAILQ_EMPTY(&stcb->asoc.control_send_queue),
    6120             :                 stcb->asoc.total_flight);
    6121           0 :         un_sent = (stcb->asoc.total_output_queue_size - stcb->asoc.total_flight);
    6122           0 :         if (!TAILQ_EMPTY(&stcb->asoc.control_send_queue)) {
    6123           0 :                 cnt_ctrl_ready = stcb->asoc.ctrl_queue_cnt - stcb->asoc.ecn_echo_cnt_onq;
    6124             :         }
    6125           0 :         if (cnt_ctrl_ready ||
    6126           0 :             ((un_sent) &&
    6127           0 :              (stcb->asoc.peers_rwnd > 0 ||
    6128           0 :               (stcb->asoc.peers_rwnd <= 0 && stcb->asoc.total_flight == 0)))) {
    6129           0 :                 SCTPDBG(SCTP_DEBUG_INPUT3, "Calling chunk OUTPUT\n");
    6130           0 :                 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED);
    6131           0 :                 SCTPDBG(SCTP_DEBUG_INPUT3, "chunk OUTPUT returns\n");
    6132             :         }
    6133             : #ifdef SCTP_AUDITING_ENABLED
    6134             :         sctp_audit_log(0xE0, 3);
    6135             :         sctp_auditing(2, inp, stcb, net);
    6136             : #endif
    6137             :  out:
    6138           0 :         if (stcb != NULL) {
    6139           0 :                 SCTP_TCB_UNLOCK(stcb);
    6140             :         }
    6141           0 :         if (inp_decr != NULL) {
    6142             :                 /* reduce ref-count */
    6143           0 :                 SCTP_INP_WLOCK(inp_decr);
    6144           0 :                 SCTP_INP_DECR_REF(inp_decr);
    6145           0 :                 SCTP_INP_WUNLOCK(inp_decr);
    6146             :         }
    6147             : #ifdef INVARIANTS
    6148             :         if (inp != NULL) {
    6149             :                 sctp_validate_no_locks(inp);
    6150             :         }
    6151             : #endif
    6152           0 :         return;
    6153             : }
    6154             : 
    6155             : #ifdef INET
    6156             : #if !defined(__Userspace__)
    6157             : #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
    6158             : void
    6159             : sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
    6160             : #elif defined(__Panda__)
    6161             : void
    6162             : sctp_input(pakhandle_type i_pak)
    6163             : #else
    6164             : void
    6165             : #if __STDC__
    6166             : sctp_input(struct mbuf *i_pak,...)
    6167             : #else
    6168             : sctp_input(i_pak, va_alist)
    6169             :         struct mbuf *i_pak;
    6170             : #endif
    6171             : #endif
    6172             : {
    6173             :         struct mbuf *m;
    6174             :         int iphlen;
    6175             :         uint32_t vrf_id = 0;
    6176             :         uint8_t ecn_bits;
    6177             :         struct sockaddr_in src, dst;
    6178             :         struct ip *ip;
    6179             :         struct sctphdr *sh;
    6180             :         struct sctp_chunkhdr *ch;
    6181             :         int length, offset;
    6182             : #if !defined(SCTP_WITH_NO_CSUM)
    6183             :         uint8_t compute_crc;
    6184             : #endif
    6185             : #if defined(__FreeBSD__)
    6186             :         uint32_t mflowid;
    6187             :         uint8_t mflowtype;
    6188             : #endif
    6189             : #if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__))
    6190             :         uint16_t port = 0;
    6191             : #endif
    6192             : 
    6193             : #if defined(__Panda__)
    6194             :         /* This is Evil, but its the only way to make panda work right. */
    6195             :         iphlen = sizeof(struct ip);
    6196             : #else
    6197             :         iphlen = off;
    6198             : #endif
    6199             :         if (SCTP_GET_PKT_VRFID(i_pak, vrf_id)) {
    6200             :                 SCTP_RELEASE_PKT(i_pak);
    6201             :                 return;
    6202             :         }
    6203             :         m = SCTP_HEADER_TO_CHAIN(i_pak);
    6204             : #ifdef __Panda__
    6205             :         SCTP_DETACH_HEADER_FROM_CHAIN(i_pak);
    6206             :         (void)SCTP_RELEASE_HEADER(i_pak);
    6207             : #endif
    6208             : #ifdef SCTP_MBUF_LOGGING
    6209             :         /* Log in any input mbufs */
    6210             :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
    6211             :                 sctp_log_mbc(m, SCTP_MBUF_INPUT);
    6212             :         }
    6213             : #endif
    6214             : #ifdef SCTP_PACKET_LOGGING
    6215             :         if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) {
    6216             :                 sctp_packet_log(m);
    6217             :         }
    6218             : #endif
    6219             : #if defined(__FreeBSD__)
    6220             : #if __FreeBSD_version > 1000049
    6221             :         SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
    6222             :                 "sctp_input(): Packet of length %d received on %s with csum_flags 0x%b.\n",
    6223             :                 m->m_pkthdr.len,
    6224             :                 if_name(m->m_pkthdr.rcvif),
    6225             :                 (int)m->m_pkthdr.csum_flags, CSUM_BITS);
    6226             : #elif __FreeBSD_version >= 800000
    6227             :         SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
    6228             :                 "sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
    6229             :                 m->m_pkthdr.len,
    6230             :                 if_name(m->m_pkthdr.rcvif),
    6231             :                 m->m_pkthdr.csum_flags);
    6232             : #else
    6233             :         SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
    6234             :                 "sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
    6235             :                 m->m_pkthdr.len,
    6236             :                 m->m_pkthdr.rcvif->if_xname,
    6237             :                 m->m_pkthdr.csum_flags);
    6238             : #endif
    6239             : #endif
    6240             : #if defined(__APPLE__)
    6241             :         SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
    6242             :                 "sctp_input(): Packet of length %d received on %s%d with csum_flags 0x%x.\n",
    6243             :                 m->m_pkthdr.len,
    6244             :                 m->m_pkthdr.rcvif->if_name,
    6245             :                 m->m_pkthdr.rcvif->if_unit,
    6246             :                 m->m_pkthdr.csum_flags);
    6247             : #endif
    6248             : #if defined(__Windows__)
    6249             :         SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
    6250             :                 "sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
    6251             :                 m->m_pkthdr.len,
    6252             :                 m->m_pkthdr.rcvif->if_xname,
    6253             :                 m->m_pkthdr.csum_flags);
    6254             : #endif
    6255             : #if defined(__FreeBSD__)
    6256             :         mflowid = m->m_pkthdr.flowid;
    6257             :         mflowtype = M_HASHTYPE_GET(m);
    6258             : #endif
    6259             :         SCTP_STAT_INCR(sctps_recvpackets);
    6260             :         SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
    6261             :         /* Get IP, SCTP, and first chunk header together in the first mbuf. */
    6262             :         offset = iphlen + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
    6263             :         if (SCTP_BUF_LEN(m) < offset) {
    6264             :                 if ((m = m_pullup(m, offset)) == NULL) {
    6265             :                         SCTP_STAT_INCR(sctps_hdrops);
    6266             :                         return;
    6267             :                 }
    6268             :         }
    6269             :         ip = mtod(m, struct ip *);
    6270             :         sh = (struct sctphdr *)((caddr_t)ip + iphlen);
    6271             :         ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
    6272             :         offset -= sizeof(struct sctp_chunkhdr);
    6273             :         memset(&src, 0, sizeof(struct sockaddr_in));
    6274             :         src.sin_family = AF_INET;
    6275             : #ifdef HAVE_SIN_LEN
    6276             :         src.sin_len = sizeof(struct sockaddr_in);
    6277             : #endif
    6278             :         src.sin_port = sh->src_port;
    6279             :         src.sin_addr = ip->ip_src;
    6280             :         memset(&dst, 0, sizeof(struct sockaddr_in));
    6281             :         dst.sin_family = AF_INET;
    6282             : #ifdef HAVE_SIN_LEN
    6283             :         dst.sin_len = sizeof(struct sockaddr_in);
    6284             : #endif
    6285             :         dst.sin_port = sh->dest_port;
    6286             :         dst.sin_addr = ip->ip_dst;
    6287             : #if defined(__Windows__)
    6288             :         NTOHS(ip->ip_len);
    6289             : #endif
    6290             : #if defined(__Userspace_os_Linux) || defined(__Userspace_os_Windows)
    6291             :         ip->ip_len = ntohs(ip->ip_len);
    6292             : #endif
    6293             : #if defined(__FreeBSD__)
    6294             : #if __FreeBSD_version >= 1000000
    6295             :         length = ntohs(ip->ip_len);
    6296             : #else
    6297             :         length = ip->ip_len + iphlen;
    6298             : #endif
    6299             : #elif defined(__APPLE__)
    6300             :         length = ip->ip_len + iphlen;
    6301             : #elif defined(__Userspace__)
    6302             : #if defined(__Userspace_os_Linux) || defined(__Userspace_os_Windows)
    6303             :         length = ip->ip_len;
    6304             : #else
    6305             :         length = ip->ip_len + iphlen;
    6306             : #endif
    6307             : #else
    6308             :         length = ip->ip_len;
    6309             : #endif
    6310             :         /* Validate mbuf chain length with IP payload length. */
    6311             :         if (SCTP_HEADER_LEN(m) != length) {
    6312             :                 SCTPDBG(SCTP_DEBUG_INPUT1,
    6313             :                         "sctp_input() length:%d reported length:%d\n", length, SCTP_HEADER_LEN(m));
    6314             :                 SCTP_STAT_INCR(sctps_hdrops);
    6315             :                 goto out;
    6316             :         }
    6317             :         /* SCTP does not allow broadcasts or multicasts */
    6318             :         if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
    6319             :                 goto out;
    6320             :         }
    6321             :         if (SCTP_IS_IT_BROADCAST(dst.sin_addr, m)) {
    6322             :                 goto out;
    6323             :         }
    6324             :         ecn_bits = ip->ip_tos;
    6325             : #if defined(SCTP_WITH_NO_CSUM)
    6326             :         SCTP_STAT_INCR(sctps_recvnocrc);
    6327             : #else
    6328             : #if defined(__FreeBSD__) && __FreeBSD_version >= 800000
    6329             :         if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
    6330             :                 SCTP_STAT_INCR(sctps_recvhwcrc);
    6331             :                 compute_crc = 0;
    6332             :         } else {
    6333             : #else
    6334             :         if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
    6335             :             ((src.sin_addr.s_addr == dst.sin_addr.s_addr) ||
    6336             :              (SCTP_IS_IT_LOOPBACK(m)))) {
    6337             :                 SCTP_STAT_INCR(sctps_recvnocrc);
    6338             :                 compute_crc = 0;
    6339             :         } else {
    6340             : #endif
    6341             :                 SCTP_STAT_INCR(sctps_recvswcrc);
    6342             :                 compute_crc = 1;
    6343             :         }
    6344             : #endif
    6345             :         sctp_common_input_processing(&m, iphlen, offset, length,
    6346             :                                      (struct sockaddr *)&src,
    6347             :                                      (struct sockaddr *)&dst,
    6348             :                                      sh, ch,
    6349             : #if !defined(SCTP_WITH_NO_CSUM)
    6350             :                                      compute_crc,
    6351             : #endif
    6352             :                                      ecn_bits,
    6353             : #if defined(__FreeBSD__)
    6354             :                                      mflowtype, mflowid,
    6355             : #endif
    6356             :                                      vrf_id, port);
    6357             :  out:
    6358             :         if (m) {
    6359             :                 sctp_m_freem(m);
    6360             :         }
    6361             :         return;
    6362             : }
    6363             : 
    6364             : #if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP)
    6365             : extern int *sctp_cpuarry;
    6366             : #endif
    6367             : 
    6368             : #if defined(__FreeBSD__) && __FreeBSD_version >= 1100020  
    6369             : int
    6370             : sctp_input(struct mbuf **mp, int *offp, int proto SCTP_UNUSED)
    6371             : {
    6372             :         struct mbuf *m;
    6373             :         int off;
    6374             : 
    6375             :         m = *mp;
    6376             :         off = *offp;
    6377             : #else
    6378             : void
    6379             : sctp_input(struct mbuf *m, int off)
    6380             : {
    6381             : #endif
    6382             : #if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP)
    6383             :         if (mp_ncpus > 1) {
    6384             :                 struct ip *ip;
    6385             :                 struct sctphdr *sh;
    6386             :                 int offset;
    6387             :                 int cpu_to_use;
    6388             :                 uint32_t flowid, tag;
    6389             : 
    6390             :                 if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) {
    6391             :                         flowid = m->m_pkthdr.flowid;
    6392             :                 } else {
    6393             :                         /* No flow id built by lower layers
    6394             :                          * fix it so we create one.
    6395             :                          */
    6396             :                         offset = off + sizeof(struct sctphdr);
    6397             :                         if (SCTP_BUF_LEN(m) < offset) {
    6398             :                                 if ((m = m_pullup(m, offset)) == NULL) {
    6399             :                                         SCTP_STAT_INCR(sctps_hdrops);
    6400             : #if defined(__FreeBSD__) && __FreeBSD_version >= 1100020  
    6401             :                                         return (IPPROTO_DONE);
    6402             : #else
    6403             :                                         return;
    6404             : #endif
    6405             :                                 }
    6406             :                         }
    6407             :                         ip = mtod(m, struct ip *);
    6408             :                         sh = (struct sctphdr *)((caddr_t)ip + off);
    6409             :                         tag = htonl(sh->v_tag);
    6410             :                         flowid = tag ^ ntohs(sh->dest_port) ^ ntohs(sh->src_port);
    6411             :                         m->m_pkthdr.flowid = flowid;
    6412             :                         M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE);
    6413             :                 }
    6414             :                 cpu_to_use = sctp_cpuarry[flowid % mp_ncpus];
    6415             :                 sctp_queue_to_mcore(m, off, cpu_to_use);
    6416             : #if defined(__FreeBSD__) && __FreeBSD_version >= 1100020  
    6417             :                 return (IPPROTO_DONE);
    6418             : #else
    6419             :                 return;
    6420             : #endif
    6421             :         }
    6422             : #endif
    6423             :         sctp_input_with_port(m, off, 0);
    6424             : #if defined(__FreeBSD__) && __FreeBSD_version >= 1100020  
    6425             :         return (IPPROTO_DONE);
    6426             : #endif
    6427             : }
    6428             : #endif
    6429             : #endif

Generated by: LCOV version 1.13