LCOV - code coverage report
Current view: top level - netwerk/sctp/src/netinet - sctp_pcb.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 2652 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 62 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_pcb.c 280459 2015-03-24 21:12:45Z tuexen $");
      36             : #endif
      37             : 
      38             : #include <netinet/sctp_os.h>
      39             : #ifdef __FreeBSD__
      40             : #include <sys/proc.h>
      41             : #endif
      42             : #include <netinet/sctp_var.h>
      43             : #include <netinet/sctp_sysctl.h>
      44             : #include <netinet/sctp_pcb.h>
      45             : #include <netinet/sctputil.h>
      46             : #include <netinet/sctp.h>
      47             : #include <netinet/sctp_header.h>
      48             : #include <netinet/sctp_asconf.h>
      49             : #include <netinet/sctp_output.h>
      50             : #include <netinet/sctp_timer.h>
      51             : #include <netinet/sctp_bsd_addr.h>
      52             : #if defined(__FreeBSD__) && __FreeBSD_version >= 803000
      53             : #include <netinet/sctp_dtrace_define.h>
      54             : #endif
      55             : #if defined(INET) || defined(INET6)
      56             : #if !defined(__Userspace_os_Windows)
      57             : #include <netinet/udp.h>
      58             : #endif
      59             : #endif
      60             : #ifdef INET6
      61             : #if defined(__Userspace__)
      62             : #include "user_ip6_var.h"
      63             : #else
      64             : #include <netinet6/ip6_var.h>
      65             : #endif
      66             : #endif
      67             : #if defined(__FreeBSD__)
      68             : #include <sys/sched.h>
      69             : #include <sys/smp.h>
      70             : #include <sys/unistd.h>
      71             : #endif
      72             : #if defined(__Userspace__)
      73             : #include <user_socketvar.h>
      74             : #if !defined(__Userspace_os_Windows)
      75             : #include <netdb.h>
      76             : #endif
      77             : #endif
      78             : 
      79             : #if defined(__APPLE__)
      80             : #define APPLE_FILE_NO 4
      81             : #endif
      82             : 
      83             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
      84             : VNET_DEFINE(struct sctp_base_info, system_base_info);
      85             : #else
      86             : struct sctp_base_info system_base_info;
      87             : #endif
      88             : 
      89             : #if defined(__Userspace__)
      90             : #if defined(INET) || defined(INET6)
      91             : struct ifaddrs *g_interfaces;
      92             : #endif
      93             : #endif
      94             : /* FIX: we don't handle multiple link local scopes */
      95             : /* "scopeless" replacement IN6_ARE_ADDR_EQUAL */
      96             : #ifdef INET6
      97             : int
      98             : SCTP6_ARE_ADDR_EQUAL(struct sockaddr_in6 *a, struct sockaddr_in6 *b)
      99             : {
     100             : #ifdef SCTP_EMBEDDED_V6_SCOPE
     101             : #if defined(__APPLE__)
     102             :         struct in6_addr tmp_a, tmp_b;
     103             : 
     104             :         tmp_a = a->sin6_addr;
     105             : #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
     106             :         if (in6_embedscope(&tmp_a, a, NULL, NULL) != 0) {
     107             : #else
     108             :         if (in6_embedscope(&tmp_a, a, NULL, NULL, NULL) != 0) {
     109             : #endif
     110             :                 return (0);
     111             :         }
     112             :         tmp_b = b->sin6_addr;
     113             : #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
     114             :         if (in6_embedscope(&tmp_b, b, NULL, NULL) != 0) {
     115             : #else
     116             :         if (in6_embedscope(&tmp_b, b, NULL, NULL, NULL) != 0) {
     117             : #endif
     118             :                 return (0);
     119             :         }
     120             :         return (IN6_ARE_ADDR_EQUAL(&tmp_a, &tmp_b));
     121             : #elif defined(SCTP_KAME)
     122             :         struct sockaddr_in6 tmp_a, tmp_b;
     123             : 
     124             :         memcpy(&tmp_a, a, sizeof(struct sockaddr_in6));
     125             :         if (sa6_embedscope(&tmp_a, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
     126             :                 return (0);
     127             :         }
     128             :         memcpy(&tmp_b, b, sizeof(struct sockaddr_in6));
     129             :         if (sa6_embedscope(&tmp_b, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
     130             :                 return (0);
     131             :         }
     132             :         return (IN6_ARE_ADDR_EQUAL(&tmp_a.sin6_addr, &tmp_b.sin6_addr));
     133             : #else
     134             :         struct in6_addr tmp_a, tmp_b;
     135             : 
     136             :         tmp_a = a->sin6_addr;
     137             :         if (in6_embedscope(&tmp_a, a) != 0) {
     138             :                 return (0);
     139             :         }
     140             :         tmp_b = b->sin6_addr;
     141             :         if (in6_embedscope(&tmp_b, b) != 0) {
     142             :                 return (0);
     143             :         }
     144             :         return (IN6_ARE_ADDR_EQUAL(&tmp_a, &tmp_b));
     145             : #endif
     146             : #else
     147             :         return (IN6_ARE_ADDR_EQUAL(&(a->sin6_addr), &(b->sin6_addr)));
     148             : #endif /* SCTP_EMBEDDED_V6_SCOPE */
     149             : }
     150             : #endif
     151             : 
     152             : void
     153           0 : sctp_fill_pcbinfo(struct sctp_pcbinfo *spcb)
     154             : {
     155             :         /*
     156             :          * We really don't need to lock this, but I will just because it
     157             :          * does not hurt.
     158             :          */
     159           0 :         SCTP_INP_INFO_RLOCK();
     160           0 :         spcb->ep_count = SCTP_BASE_INFO(ipi_count_ep);
     161           0 :         spcb->asoc_count = SCTP_BASE_INFO(ipi_count_asoc);
     162           0 :         spcb->laddr_count = SCTP_BASE_INFO(ipi_count_laddr);
     163           0 :         spcb->raddr_count = SCTP_BASE_INFO(ipi_count_raddr);
     164           0 :         spcb->chk_count = SCTP_BASE_INFO(ipi_count_chunk);
     165           0 :         spcb->readq_count = SCTP_BASE_INFO(ipi_count_readq);
     166           0 :         spcb->stream_oque = SCTP_BASE_INFO(ipi_count_strmoq);
     167           0 :         spcb->free_chunks = SCTP_BASE_INFO(ipi_free_chunks);
     168           0 :         SCTP_INP_INFO_RUNLOCK();
     169           0 : }
     170             : 
     171             : /*-
     172             :  * Addresses are added to VRF's (Virtual Router's). For BSD we
     173             :  * have only the default VRF 0. We maintain a hash list of
     174             :  * VRF's. Each VRF has its own list of sctp_ifn's. Each of
     175             :  * these has a list of addresses. When we add a new address
     176             :  * to a VRF we lookup the ifn/ifn_index, if the ifn does
     177             :  * not exist we create it and add it to the list of IFN's
     178             :  * within the VRF. Once we have the sctp_ifn, we add the
     179             :  * address to the list. So we look something like:
     180             :  *
     181             :  * hash-vrf-table
     182             :  *   vrf-> ifn-> ifn -> ifn
     183             :  *   vrf    |
     184             :  *    ...   +--ifa-> ifa -> ifa
     185             :  *   vrf
     186             :  *
     187             :  * We keep these separate lists since the SCTP subsystem will
     188             :  * point to these from its source address selection nets structure.
     189             :  * When an address is deleted it does not happen right away on
     190             :  * the SCTP side, it gets scheduled. What we do when a
     191             :  * delete happens is immediately remove the address from
     192             :  * the master list and decrement the refcount. As our
     193             :  * addip iterator works through and frees the src address
     194             :  * selection pointing to the sctp_ifa, eventually the refcount
     195             :  * will reach 0 and we will delete it. Note that it is assumed
     196             :  * that any locking on system level ifn/ifa is done at the
     197             :  * caller of these functions and these routines will only
     198             :  * lock the SCTP structures as they add or delete things.
     199             :  *
     200             :  * Other notes on VRF concepts.
     201             :  *  - An endpoint can be in multiple VRF's
     202             :  *  - An association lives within a VRF and only one VRF.
     203             :  *  - Any incoming packet we can deduce the VRF for by
     204             :  *    looking at the mbuf/pak inbound (for BSD its VRF=0 :D)
     205             :  *  - Any downward send call or connect call must supply the
     206             :  *    VRF via ancillary data or via some sort of set default
     207             :  *    VRF socket option call (again for BSD no brainer since
     208             :  *    the VRF is always 0).
     209             :  *  - An endpoint may add multiple VRF's to it.
     210             :  *  - Listening sockets can accept associations in any
     211             :  *    of the VRF's they are in but the assoc will end up
     212             :  *    in only one VRF (gotten from the packet or connect/send).
     213             :  *
     214             :  */
     215             : 
     216             : struct sctp_vrf *
     217           0 : sctp_allocate_vrf(int vrf_id)
     218             : {
     219           0 :         struct sctp_vrf *vrf = NULL;
     220             :         struct sctp_vrflist *bucket;
     221             : 
     222             :         /* First allocate the VRF structure */
     223           0 :         vrf = sctp_find_vrf(vrf_id);
     224           0 :         if (vrf) {
     225             :                 /* Already allocated */
     226           0 :                 return (vrf);
     227             :         }
     228           0 :         SCTP_MALLOC(vrf, struct sctp_vrf *, sizeof(struct sctp_vrf),
     229             :                     SCTP_M_VRF);
     230           0 :         if (vrf == NULL) {
     231             :                 /* No memory */
     232             : #ifdef INVARIANTS
     233             :                 panic("No memory for VRF:%d", vrf_id);
     234             : #endif
     235           0 :                 return (NULL);
     236             :         }
     237             :         /* setup the VRF */
     238           0 :         memset(vrf, 0, sizeof(struct sctp_vrf));
     239           0 :         vrf->vrf_id = vrf_id;
     240           0 :         LIST_INIT(&vrf->ifnlist);
     241           0 :         vrf->total_ifa_count = 0;
     242           0 :         vrf->refcount = 0;
     243             :         /* now also setup table ids */
     244             :         SCTP_INIT_VRF_TABLEID(vrf);
     245             :         /* Init the HASH of addresses */
     246           0 :         vrf->vrf_addr_hash = SCTP_HASH_INIT(SCTP_VRF_ADDR_HASH_SIZE,
     247             :                                             &vrf->vrf_addr_hashmark);
     248           0 :         if (vrf->vrf_addr_hash == NULL) {
     249             :                 /* No memory */
     250             : #ifdef INVARIANTS
     251             :                 panic("No memory for VRF:%d", vrf_id);
     252             : #endif
     253           0 :                 SCTP_FREE(vrf, SCTP_M_VRF);
     254           0 :                 return (NULL);
     255             :         }
     256             : 
     257             :         /* Add it to the hash table */
     258           0 :         bucket = &SCTP_BASE_INFO(sctp_vrfhash)[(vrf_id & SCTP_BASE_INFO(hashvrfmark))];
     259           0 :         LIST_INSERT_HEAD(bucket, vrf, next_vrf);
     260           0 :         atomic_add_int(&SCTP_BASE_INFO(ipi_count_vrfs), 1);
     261           0 :         return (vrf);
     262             : }
     263             : 
     264             : 
     265             : struct sctp_ifn *
     266           0 : sctp_find_ifn(void *ifn, uint32_t ifn_index)
     267             : {
     268             :         struct sctp_ifn *sctp_ifnp;
     269             :         struct sctp_ifnlist *hash_ifn_head;
     270             : 
     271             :         /* We assume the lock is held for the addresses
     272             :          * if that's wrong problems could occur :-)
     273             :          */
     274           0 :         hash_ifn_head = &SCTP_BASE_INFO(vrf_ifn_hash)[(ifn_index & SCTP_BASE_INFO(vrf_ifn_hashmark))];
     275           0 :         LIST_FOREACH(sctp_ifnp, hash_ifn_head, next_bucket) {
     276           0 :                 if (sctp_ifnp->ifn_index == ifn_index) {
     277           0 :                         return (sctp_ifnp);
     278             :                 }
     279           0 :                 if (sctp_ifnp->ifn_p && ifn && (sctp_ifnp->ifn_p == ifn)) {
     280           0 :                         return (sctp_ifnp);
     281             :                 }
     282             :         }
     283           0 :         return (NULL);
     284             : }
     285             : 
     286             : 
     287             : struct sctp_vrf *
     288           0 : sctp_find_vrf(uint32_t vrf_id)
     289             : {
     290             :         struct sctp_vrflist *bucket;
     291             :         struct sctp_vrf *liste;
     292             : 
     293           0 :         bucket = &SCTP_BASE_INFO(sctp_vrfhash)[(vrf_id & SCTP_BASE_INFO(hashvrfmark))];
     294           0 :         LIST_FOREACH(liste, bucket, next_vrf) {
     295           0 :                 if (vrf_id == liste->vrf_id) {
     296           0 :                         return (liste);
     297             :                 }
     298             :         }
     299           0 :         return (NULL);
     300             : }
     301             : 
     302             : 
     303             : void
     304           0 : sctp_free_vrf(struct sctp_vrf *vrf)
     305             : {
     306           0 :         if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&vrf->refcount)) {
     307           0 :                 if (vrf->vrf_addr_hash) {
     308           0 :                     SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark);
     309           0 :                     vrf->vrf_addr_hash = NULL;
     310             :                 }
     311             :                 /* We zero'd the count */
     312           0 :                 LIST_REMOVE(vrf, next_vrf);
     313           0 :                 SCTP_FREE(vrf, SCTP_M_VRF);
     314           0 :                 atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_vrfs), 1);
     315             :         }
     316           0 : }
     317             : 
     318             : 
     319             : void
     320           0 : sctp_free_ifn(struct sctp_ifn *sctp_ifnp)
     321             : {
     322           0 :         if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&sctp_ifnp->refcount)) {
     323             :                 /* We zero'd the count */
     324           0 :                 if (sctp_ifnp->vrf) {
     325           0 :                         sctp_free_vrf(sctp_ifnp->vrf);
     326             :                 }
     327           0 :                 SCTP_FREE(sctp_ifnp, SCTP_M_IFN);
     328           0 :                 atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ifns), 1);
     329             :         }
     330           0 : }
     331             : 
     332             : 
     333             : void
     334           0 : sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu)
     335             : {
     336             :         struct sctp_ifn *sctp_ifnp;
     337             : 
     338           0 :         sctp_ifnp = sctp_find_ifn((void *)NULL, ifn_index);
     339           0 :         if (sctp_ifnp != NULL) {
     340           0 :                 sctp_ifnp->ifn_mtu = mtu;
     341             :         }
     342           0 : }
     343             : 
     344             : 
     345             : void
     346           0 : sctp_free_ifa(struct sctp_ifa *sctp_ifap)
     347             : {
     348           0 :         if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&sctp_ifap->refcount)) {
     349             :                 /* We zero'd the count */
     350           0 :                 if (sctp_ifap->ifn_p) {
     351           0 :                         sctp_free_ifn(sctp_ifap->ifn_p);
     352             :                 }
     353           0 :                 SCTP_FREE(sctp_ifap, SCTP_M_IFA);
     354           0 :                 atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ifas), 1);
     355             :         }
     356           0 : }
     357             : 
     358             : 
     359             : static void
     360           0 : sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock)
     361             : {
     362             :         struct sctp_ifn *found;
     363             : 
     364           0 :         found = sctp_find_ifn(sctp_ifnp->ifn_p, sctp_ifnp->ifn_index);
     365           0 :         if (found == NULL) {
     366             :                 /* Not in the list.. sorry */
     367           0 :                 return;
     368             :         }
     369           0 :         if (hold_addr_lock == 0)
     370           0 :                 SCTP_IPI_ADDR_WLOCK();
     371           0 :         LIST_REMOVE(sctp_ifnp, next_bucket);
     372           0 :         LIST_REMOVE(sctp_ifnp, next_ifn);
     373             :         SCTP_DEREGISTER_INTERFACE(sctp_ifnp->ifn_index,
     374             :                                   sctp_ifnp->registered_af);
     375           0 :         if (hold_addr_lock == 0)
     376           0 :                 SCTP_IPI_ADDR_WUNLOCK();
     377             :         /* Take away the reference, and possibly free it */
     378           0 :         sctp_free_ifn(sctp_ifnp);
     379             : }
     380             : 
     381             : 
     382             : void
     383           0 : sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr,
     384             :                         const char *if_name, uint32_t ifn_index)
     385             : {
     386             :         struct sctp_vrf *vrf;
     387             :         struct sctp_ifa *sctp_ifap;
     388             : 
     389           0 :         SCTP_IPI_ADDR_RLOCK();
     390           0 :         vrf = sctp_find_vrf(vrf_id);
     391           0 :         if (vrf == NULL) {
     392           0 :                 SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id);
     393           0 :                 goto out;
     394             : 
     395             :         }
     396           0 :         sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
     397           0 :         if (sctp_ifap == NULL) {
     398           0 :                 SCTPDBG(SCTP_DEBUG_PCB4, "Can't find sctp_ifap for address\n");
     399           0 :                 goto out;
     400             :         }
     401           0 :         if (sctp_ifap->ifn_p == NULL) {
     402           0 :                 SCTPDBG(SCTP_DEBUG_PCB4, "IFA has no IFN - can't mark unuseable\n");
     403           0 :                 goto out;
     404             :         }
     405           0 :         if (if_name) {
     406           0 :                 if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) != 0) {
     407           0 :                         SCTPDBG(SCTP_DEBUG_PCB4, "IFN %s of IFA not the same as %s\n",
     408             :                                 sctp_ifap->ifn_p->ifn_name, if_name);
     409           0 :                         goto out;
     410             :                 }
     411             :         } else {
     412           0 :                 if (sctp_ifap->ifn_p->ifn_index != ifn_index) {
     413           0 :                         SCTPDBG(SCTP_DEBUG_PCB4, "IFA owned by ifn_index:%d down command for ifn_index:%d - ignored\n",
     414             :                                 sctp_ifap->ifn_p->ifn_index, ifn_index);
     415           0 :                         goto out;
     416             :                 }
     417             :         }
     418             : 
     419           0 :         sctp_ifap->localifa_flags &= (~SCTP_ADDR_VALID);
     420           0 :         sctp_ifap->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE;
     421             :  out:
     422           0 :         SCTP_IPI_ADDR_RUNLOCK();
     423           0 : }
     424             : 
     425             : 
     426             : void
     427           0 : sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr,
     428             :                       const char *if_name, uint32_t ifn_index)
     429             : {
     430             :         struct sctp_vrf *vrf;
     431             :         struct sctp_ifa *sctp_ifap;
     432             : 
     433           0 :         SCTP_IPI_ADDR_RLOCK();
     434           0 :         vrf = sctp_find_vrf(vrf_id);
     435           0 :         if (vrf == NULL) {
     436           0 :                 SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id);
     437           0 :                 goto out;
     438             : 
     439             :         }
     440           0 :         sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
     441           0 :         if (sctp_ifap == NULL) {
     442           0 :                 SCTPDBG(SCTP_DEBUG_PCB4, "Can't find sctp_ifap for address\n");
     443           0 :                 goto out;
     444             :         }
     445           0 :         if (sctp_ifap->ifn_p == NULL) {
     446           0 :                 SCTPDBG(SCTP_DEBUG_PCB4, "IFA has no IFN - can't mark unuseable\n");
     447           0 :                 goto out;
     448             :         }
     449           0 :         if (if_name) {
     450           0 :                 if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) != 0) {
     451           0 :                         SCTPDBG(SCTP_DEBUG_PCB4, "IFN %s of IFA not the same as %s\n",
     452             :                                 sctp_ifap->ifn_p->ifn_name, if_name);
     453           0 :                         goto out;
     454             :                 }
     455             :         } else {
     456           0 :                 if (sctp_ifap->ifn_p->ifn_index != ifn_index) {
     457           0 :                         SCTPDBG(SCTP_DEBUG_PCB4, "IFA owned by ifn_index:%d down command for ifn_index:%d - ignored\n",
     458             :                                 sctp_ifap->ifn_p->ifn_index, ifn_index);
     459           0 :                         goto out;
     460             :                 }
     461             :         }
     462             : 
     463           0 :         sctp_ifap->localifa_flags &= (~SCTP_ADDR_IFA_UNUSEABLE);
     464           0 :         sctp_ifap->localifa_flags |= SCTP_ADDR_VALID;
     465             :  out:
     466           0 :         SCTP_IPI_ADDR_RUNLOCK();
     467           0 : }
     468             : 
     469             : 
     470             : /*-
     471             :  * Add an ifa to an ifn.
     472             :  * Register the interface as necessary.
     473             :  * NOTE: ADDR write lock MUST be held.
     474             :  */
     475             : static void
     476           0 : sctp_add_ifa_to_ifn(struct sctp_ifn *sctp_ifnp, struct sctp_ifa *sctp_ifap)
     477             : {
     478             :         int ifa_af;
     479             : 
     480           0 :         LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa);
     481           0 :         sctp_ifap->ifn_p = sctp_ifnp;
     482           0 :         atomic_add_int(&sctp_ifap->ifn_p->refcount, 1);
     483             :         /* update address counts */
     484           0 :         sctp_ifnp->ifa_count++;
     485           0 :         ifa_af = sctp_ifap->address.sa.sa_family;
     486             :         switch (ifa_af) {
     487             : #ifdef INET
     488             :         case AF_INET:
     489             :                 sctp_ifnp->num_v4++;
     490             :                 break;
     491             : #endif
     492             : #ifdef INET6
     493             :         case AF_INET6:
     494             :                 sctp_ifnp->num_v6++;
     495             :                 break;
     496             : #endif
     497             :         default:
     498           0 :                 break;
     499             :         }
     500           0 :         if (sctp_ifnp->ifa_count == 1) {
     501             :                 /* register the new interface */
     502             :                 SCTP_REGISTER_INTERFACE(sctp_ifnp->ifn_index, ifa_af);
     503           0 :                 sctp_ifnp->registered_af = ifa_af;
     504             :         }
     505           0 : }
     506             : 
     507             : 
     508             : /*-
     509             :  * Remove an ifa from its ifn.
     510             :  * If no more addresses exist, remove the ifn too. Otherwise, re-register
     511             :  * the interface based on the remaining address families left.
     512             :  * NOTE: ADDR write lock MUST be held.
     513             :  */
     514             : static void
     515           0 : sctp_remove_ifa_from_ifn(struct sctp_ifa *sctp_ifap)
     516             : {
     517           0 :         LIST_REMOVE(sctp_ifap, next_ifa);
     518           0 :         if (sctp_ifap->ifn_p) {
     519             :                 /* update address counts */
     520           0 :                 sctp_ifap->ifn_p->ifa_count--;
     521           0 :                 switch (sctp_ifap->address.sa.sa_family) {
     522             : #ifdef INET
     523             :                 case AF_INET:
     524             :                         sctp_ifap->ifn_p->num_v4--;
     525             :                         break;
     526             : #endif
     527             : #ifdef INET6
     528             :                 case AF_INET6:
     529             :                         sctp_ifap->ifn_p->num_v6--;
     530             :                         break;
     531             : #endif
     532             :                 default:
     533           0 :                         break;
     534             :                 }
     535             : 
     536           0 :                 if (LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) {
     537             :                         /* remove the ifn, possibly freeing it */
     538           0 :                         sctp_delete_ifn(sctp_ifap->ifn_p, SCTP_ADDR_LOCKED);
     539             :                 } else {
     540             :                         /* re-register address family type, if needed */
     541           0 :                         if ((sctp_ifap->ifn_p->num_v6 == 0) &&
     542           0 :                             (sctp_ifap->ifn_p->registered_af == AF_INET6)) {
     543             :                                 SCTP_DEREGISTER_INTERFACE(sctp_ifap->ifn_p->ifn_index, AF_INET6);
     544             :                                 SCTP_REGISTER_INTERFACE(sctp_ifap->ifn_p->ifn_index, AF_INET);
     545           0 :                                 sctp_ifap->ifn_p->registered_af = AF_INET;
     546           0 :                         } else if ((sctp_ifap->ifn_p->num_v4 == 0) &&
     547           0 :                                    (sctp_ifap->ifn_p->registered_af == AF_INET)) {
     548             :                                 SCTP_DEREGISTER_INTERFACE(sctp_ifap->ifn_p->ifn_index, AF_INET);
     549             :                                 SCTP_REGISTER_INTERFACE(sctp_ifap->ifn_p->ifn_index, AF_INET6);
     550           0 :                                 sctp_ifap->ifn_p->registered_af = AF_INET6;
     551             :                         }
     552             :                         /* free the ifn refcount */
     553           0 :                         sctp_free_ifn(sctp_ifap->ifn_p);
     554             :                 }
     555           0 :                 sctp_ifap->ifn_p = NULL;
     556             :         }
     557           0 : }
     558             : 
     559             : 
     560             : struct sctp_ifa *
     561           0 : sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
     562             :                      uint32_t ifn_type, const char *if_name, void *ifa,
     563             :                      struct sockaddr *addr, uint32_t ifa_flags,
     564             :                      int dynamic_add)
     565             : {
     566             :         struct sctp_vrf *vrf;
     567           0 :         struct sctp_ifn *sctp_ifnp = NULL;
     568           0 :         struct sctp_ifa *sctp_ifap = NULL;
     569             :         struct sctp_ifalist *hash_addr_head;
     570             :         struct sctp_ifnlist *hash_ifn_head;
     571             :         uint32_t hash_of_addr;
     572           0 :         int new_ifn_af = 0;
     573             : 
     574             : #ifdef SCTP_DEBUG
     575           0 :         SCTPDBG(SCTP_DEBUG_PCB4, "vrf_id 0x%x: adding address: ", vrf_id);
     576           0 :         SCTPDBG_ADDR(SCTP_DEBUG_PCB4, addr);
     577             : #endif
     578           0 :         SCTP_IPI_ADDR_WLOCK();
     579           0 :         sctp_ifnp = sctp_find_ifn(ifn, ifn_index);
     580           0 :         if (sctp_ifnp) {
     581           0 :                 vrf = sctp_ifnp->vrf;
     582             :         } else {
     583           0 :                 vrf = sctp_find_vrf(vrf_id);
     584           0 :                 if (vrf == NULL) {
     585           0 :                         vrf = sctp_allocate_vrf(vrf_id);
     586           0 :                         if (vrf == NULL) {
     587           0 :                                 SCTP_IPI_ADDR_WUNLOCK();
     588           0 :                                 return (NULL);
     589             :                         }
     590             :                 }
     591             :         }
     592           0 :         if (sctp_ifnp == NULL) {
     593             :                 /* build one and add it, can't hold lock
     594             :                  * until after malloc done though.
     595             :                  */
     596           0 :                 SCTP_IPI_ADDR_WUNLOCK();
     597           0 :                 SCTP_MALLOC(sctp_ifnp, struct sctp_ifn *,
     598             :                             sizeof(struct sctp_ifn), SCTP_M_IFN);
     599           0 :                 if (sctp_ifnp == NULL) {
     600             : #ifdef INVARIANTS
     601             :                         panic("No memory for IFN");
     602             : #endif
     603           0 :                         return (NULL);
     604             :                 }
     605           0 :                 memset(sctp_ifnp, 0, sizeof(struct sctp_ifn));
     606           0 :                 sctp_ifnp->ifn_index = ifn_index;
     607           0 :                 sctp_ifnp->ifn_p = ifn;
     608           0 :                 sctp_ifnp->ifn_type = ifn_type;
     609           0 :                 sctp_ifnp->refcount = 0;
     610           0 :                 sctp_ifnp->vrf = vrf;
     611           0 :                 atomic_add_int(&vrf->refcount, 1);
     612           0 :                 sctp_ifnp->ifn_mtu = SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index, addr->sa_family);
     613           0 :                 if (if_name != NULL) {
     614           0 :                         snprintf(sctp_ifnp->ifn_name, SCTP_IFNAMSIZ, "%s", if_name);
     615             :                 } else {
     616           0 :                         snprintf(sctp_ifnp->ifn_name, SCTP_IFNAMSIZ, "%s", "unknown");
     617             :                 }
     618           0 :                 hash_ifn_head = &SCTP_BASE_INFO(vrf_ifn_hash)[(ifn_index & SCTP_BASE_INFO(vrf_ifn_hashmark))];
     619           0 :                 LIST_INIT(&sctp_ifnp->ifalist);
     620           0 :                 SCTP_IPI_ADDR_WLOCK();
     621           0 :                 LIST_INSERT_HEAD(hash_ifn_head, sctp_ifnp, next_bucket);
     622           0 :                 LIST_INSERT_HEAD(&vrf->ifnlist, sctp_ifnp, next_ifn);
     623           0 :                 atomic_add_int(&SCTP_BASE_INFO(ipi_count_ifns), 1);
     624           0 :                 new_ifn_af = 1;
     625             :         }
     626           0 :         sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
     627           0 :         if (sctp_ifap) {
     628             :                 /* Hmm, it already exists? */
     629           0 :                 if ((sctp_ifap->ifn_p) &&
     630           0 :                     (sctp_ifap->ifn_p->ifn_index == ifn_index)) {
     631           0 :                         SCTPDBG(SCTP_DEBUG_PCB4, "Using existing ifn %s (0x%x) for ifa %p\n",
     632             :                                 sctp_ifap->ifn_p->ifn_name, ifn_index,
     633             :                                 (void *)sctp_ifap);
     634           0 :                         if (new_ifn_af) {
     635             :                                 /* Remove the created one that we don't want */
     636           0 :                                 sctp_delete_ifn(sctp_ifnp, SCTP_ADDR_LOCKED);
     637             :                         }
     638           0 :                         if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) {
     639             :                                 /* easy to solve, just switch back to active */
     640           0 :                                 SCTPDBG(SCTP_DEBUG_PCB4, "Clearing deleted ifa flag\n");
     641           0 :                                 sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
     642           0 :                                 sctp_ifap->ifn_p = sctp_ifnp;
     643           0 :                                 atomic_add_int(&sctp_ifap->ifn_p->refcount, 1);
     644             :                         }
     645             :                 exit_stage_left:
     646           0 :                         SCTP_IPI_ADDR_WUNLOCK();
     647           0 :                         return (sctp_ifap);
     648             :                 } else {
     649           0 :                         if (sctp_ifap->ifn_p) {
     650             :                                 /*
     651             :                                  * The last IFN gets the address, remove the
     652             :                                  * old one
     653             :                                  */
     654           0 :                                 SCTPDBG(SCTP_DEBUG_PCB4, "Moving ifa %p from %s (0x%x) to %s (0x%x)\n",
     655             :                                         (void *)sctp_ifap, sctp_ifap->ifn_p->ifn_name,
     656             :                                         sctp_ifap->ifn_p->ifn_index, if_name,
     657             :                                         ifn_index);
     658             :                                 /* remove the address from the old ifn */
     659           0 :                                 sctp_remove_ifa_from_ifn(sctp_ifap);
     660             :                                 /* move the address over to the new ifn */
     661           0 :                                 sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap);
     662           0 :                                 goto exit_stage_left;
     663             :                         } else {
     664             :                                 /* repair ifnp which was NULL ? */
     665           0 :                                 sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
     666           0 :                                 SCTPDBG(SCTP_DEBUG_PCB4, "Repairing ifn %p for ifa %p\n",
     667             :                                         (void *)sctp_ifnp, (void *)sctp_ifap);
     668           0 :                                 sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap);
     669             :                         }
     670           0 :                         goto exit_stage_left;
     671             :                 }
     672             :         }
     673           0 :         SCTP_IPI_ADDR_WUNLOCK();
     674           0 :         SCTP_MALLOC(sctp_ifap, struct sctp_ifa *, sizeof(struct sctp_ifa), SCTP_M_IFA);
     675           0 :         if (sctp_ifap == NULL) {
     676             : #ifdef INVARIANTS
     677             :                 panic("No memory for IFA");
     678             : #endif
     679           0 :                 return (NULL);
     680             :         }
     681           0 :         memset(sctp_ifap, 0, sizeof(struct sctp_ifa));
     682           0 :         sctp_ifap->ifn_p = sctp_ifnp;
     683           0 :         atomic_add_int(&sctp_ifnp->refcount, 1);
     684           0 :         sctp_ifap->vrf_id = vrf_id;
     685           0 :         sctp_ifap->ifa = ifa;
     686             : #ifdef HAVE_SA_LEN
     687             :         memcpy(&sctp_ifap->address, addr, addr->sa_len);
     688             : #else
     689           0 :         switch (addr->sa_family) {
     690             : #ifdef INET
     691             :         case AF_INET:
     692             :                 memcpy(&sctp_ifap->address, addr, sizeof(struct sockaddr_in));
     693             :                 break;
     694             : #endif
     695             : #ifdef INET6
     696             :         case AF_INET6:
     697             :                 memcpy(&sctp_ifap->address, addr, sizeof(struct sockaddr_in6));
     698             :                 break;
     699             : #endif
     700             : #if defined(__Userspace__)
     701             :         case AF_CONN:
     702           0 :                 memcpy(&sctp_ifap->address, addr, sizeof(struct sockaddr_conn));
     703           0 :                 break;
     704             : #endif
     705             :         default:
     706             :                 /* TSNH */
     707           0 :                 break;
     708             :         }
     709             : #endif
     710           0 :         sctp_ifap->localifa_flags = SCTP_ADDR_VALID | SCTP_ADDR_DEFER_USE;
     711           0 :         sctp_ifap->flags = ifa_flags;
     712             :         /* Set scope */
     713           0 :         switch (sctp_ifap->address.sa.sa_family) {
     714             : #ifdef INET
     715             :         case AF_INET:
     716             :         {
     717             :                 struct sockaddr_in *sin;
     718             : 
     719             :                 sin = &sctp_ifap->address.sin;
     720             :                 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
     721             :                     (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) {
     722             :                         sctp_ifap->src_is_loop = 1;
     723             :                 }
     724             :                 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
     725             :                         sctp_ifap->src_is_priv = 1;
     726             :                 }
     727             :                 sctp_ifnp->num_v4++;
     728             :                 if (new_ifn_af)
     729             :                     new_ifn_af = AF_INET;
     730             :                 break;
     731             :         }
     732             : #endif
     733             : #ifdef INET6
     734             :         case AF_INET6:
     735             :         {
     736             :                 /* ok to use deprecated addresses? */
     737             :                 struct sockaddr_in6 *sin6;
     738             : 
     739             :                 sin6 = &sctp_ifap->address.sin6;
     740             :                 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
     741             :                     (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) {
     742             :                         sctp_ifap->src_is_loop = 1;
     743             :                 }
     744             :                 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
     745             :                         sctp_ifap->src_is_priv = 1;
     746             :                 }
     747             :                 sctp_ifnp->num_v6++;
     748             :                 if (new_ifn_af)
     749             :                         new_ifn_af = AF_INET6;
     750             :                 break;
     751             :         }
     752             : #endif
     753             : #if defined(__Userspace__)
     754             :         case AF_CONN:
     755           0 :                 if (new_ifn_af)
     756           0 :                         new_ifn_af = AF_CONN;
     757           0 :                 break;
     758             : #endif
     759             :         default:
     760           0 :                 new_ifn_af = 0;
     761           0 :                 break;
     762             :         }
     763           0 :         hash_of_addr = sctp_get_ifa_hash_val(&sctp_ifap->address.sa);
     764             : 
     765           0 :         if ((sctp_ifap->src_is_priv == 0) &&
     766           0 :             (sctp_ifap->src_is_loop == 0)) {
     767           0 :                 sctp_ifap->src_is_glob = 1;
     768             :         }
     769           0 :         SCTP_IPI_ADDR_WLOCK();
     770           0 :         hash_addr_head = &vrf->vrf_addr_hash[(hash_of_addr & vrf->vrf_addr_hashmark)];
     771           0 :         LIST_INSERT_HEAD(hash_addr_head, sctp_ifap, next_bucket);
     772           0 :         sctp_ifap->refcount = 1;
     773           0 :         LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa);
     774           0 :         sctp_ifnp->ifa_count++;
     775           0 :         vrf->total_ifa_count++;
     776           0 :         atomic_add_int(&SCTP_BASE_INFO(ipi_count_ifas), 1);
     777           0 :         if (new_ifn_af) {
     778             :                 SCTP_REGISTER_INTERFACE(ifn_index, new_ifn_af);
     779           0 :                 sctp_ifnp->registered_af = new_ifn_af;
     780             :         }
     781           0 :         SCTP_IPI_ADDR_WUNLOCK();
     782           0 :         if (dynamic_add) {
     783             :                 /* Bump up the refcount so that when the timer
     784             :                  * completes it will drop back down.
     785             :                  */
     786             :                 struct sctp_laddr *wi;
     787             : 
     788           0 :                 atomic_add_int(&sctp_ifap->refcount, 1);
     789           0 :                 wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
     790           0 :                 if (wi == NULL) {
     791             :                         /*
     792             :                          * Gak, what can we do? We have lost an address
     793             :                          * change can you say HOSED?
     794             :                          */
     795           0 :                         SCTPDBG(SCTP_DEBUG_PCB4, "Lost an address change?\n");
     796             :                         /* Opps, must decrement the count */
     797           0 :                         sctp_del_addr_from_vrf(vrf_id, addr, ifn_index,
     798             :                                                if_name);
     799           0 :                         return (NULL);
     800             :                 }
     801           0 :                 SCTP_INCR_LADDR_COUNT();
     802           0 :                 bzero(wi, sizeof(*wi));
     803           0 :                 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time);
     804           0 :                 wi->ifa = sctp_ifap;
     805           0 :                 wi->action = SCTP_ADD_IP_ADDRESS;
     806             : 
     807           0 :                 SCTP_WQ_ADDR_LOCK();
     808           0 :                 LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr);
     809           0 :                 SCTP_WQ_ADDR_UNLOCK();
     810             : 
     811           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
     812             :                                  (struct sctp_inpcb *)NULL,
     813             :                                  (struct sctp_tcb *)NULL,
     814             :                                  (struct sctp_nets *)NULL);
     815             :         } else {
     816             :                 /* it's ready for use */
     817           0 :                 sctp_ifap->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
     818             :         }
     819           0 :         return (sctp_ifap);
     820             : }
     821             : 
     822             : void
     823           0 : sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr,
     824             :                        uint32_t ifn_index, const char *if_name)
     825             : {
     826             :         struct sctp_vrf *vrf;
     827           0 :         struct sctp_ifa *sctp_ifap = NULL;
     828             : 
     829           0 :         SCTP_IPI_ADDR_WLOCK();
     830           0 :         vrf = sctp_find_vrf(vrf_id);
     831           0 :         if (vrf == NULL) {
     832           0 :                 SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id);
     833           0 :                 goto out_now;
     834             :         }
     835             : 
     836             : #ifdef SCTP_DEBUG
     837           0 :         SCTPDBG(SCTP_DEBUG_PCB4, "vrf_id 0x%x: deleting address:", vrf_id);
     838           0 :         SCTPDBG_ADDR(SCTP_DEBUG_PCB4, addr);
     839             : #endif
     840           0 :         sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
     841           0 :         if (sctp_ifap) {
     842             :                 /* Validate the delete */
     843           0 :                 if (sctp_ifap->ifn_p) {
     844           0 :                         int valid = 0;
     845             :                         /*-
     846             :                          * The name has priority over the ifn_index
     847             :                          * if its given. We do this especially for
     848             :                          * panda who might recycle indexes fast.
     849             :                          */
     850           0 :                         if (if_name) {
     851           0 :                                 if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) == 0) {
     852             :                                         /* They match its a correct delete */
     853           0 :                                         valid = 1;
     854             :                                 }
     855             :                         }
     856           0 :                         if (!valid) {
     857             :                                 /* last ditch check ifn_index */
     858           0 :                                 if (ifn_index == sctp_ifap->ifn_p->ifn_index) {
     859           0 :                                         valid = 1;
     860             :                                 }
     861             :                         }
     862           0 :                         if (!valid) {
     863           0 :                                 SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d ifname:%s does not match addresses\n",
     864             :                                         ifn_index, ((if_name == NULL) ? "NULL" : if_name));
     865           0 :                                 SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d ifname:%s - ignoring delete\n",
     866             :                                         sctp_ifap->ifn_p->ifn_index, sctp_ifap->ifn_p->ifn_name);
     867           0 :                                 SCTP_IPI_ADDR_WUNLOCK();
     868           0 :                                 return;
     869             :                         }
     870             :                 }
     871           0 :                 SCTPDBG(SCTP_DEBUG_PCB4, "Deleting ifa %p\n", (void *)sctp_ifap);
     872           0 :                 sctp_ifap->localifa_flags &= SCTP_ADDR_VALID;
     873             :                 /*
     874             :                  * We don't set the flag. This means that the structure will
     875             :                  * hang around in EP's that have bound specific to it until
     876             :                  * they close. This gives us TCP like behavior if someone
     877             :                  * removes an address (or for that matter adds it right back).
     878             :                  */
     879             :                 /* sctp_ifap->localifa_flags |= SCTP_BEING_DELETED; */
     880           0 :                 vrf->total_ifa_count--;
     881           0 :                 LIST_REMOVE(sctp_ifap, next_bucket);
     882           0 :                 sctp_remove_ifa_from_ifn(sctp_ifap);
     883             :         }
     884             : #ifdef SCTP_DEBUG
     885             :         else {
     886           0 :                 SCTPDBG(SCTP_DEBUG_PCB4, "Del Addr-ifn:%d Could not find address:",
     887             :                         ifn_index);
     888           0 :                 SCTPDBG_ADDR(SCTP_DEBUG_PCB1, addr);
     889             :         }
     890             : #endif
     891             : 
     892             :  out_now:
     893           0 :         SCTP_IPI_ADDR_WUNLOCK();
     894           0 :         if (sctp_ifap) {
     895             :                 struct sctp_laddr *wi;
     896             : 
     897           0 :                 wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
     898           0 :                 if (wi == NULL) {
     899             :                         /*
     900             :                          * Gak, what can we do? We have lost an address
     901             :                          * change can you say HOSED?
     902             :                          */
     903           0 :                         SCTPDBG(SCTP_DEBUG_PCB4, "Lost an address change?\n");
     904             : 
     905             :                         /* Oops, must decrement the count */
     906           0 :                         sctp_free_ifa(sctp_ifap);
     907           0 :                         return;
     908             :                 }
     909           0 :                 SCTP_INCR_LADDR_COUNT();
     910           0 :                 bzero(wi, sizeof(*wi));
     911           0 :                 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time);
     912           0 :                 wi->ifa = sctp_ifap;
     913           0 :                 wi->action = SCTP_DEL_IP_ADDRESS;
     914           0 :                 SCTP_WQ_ADDR_LOCK();
     915             :                 /*
     916             :                  * Should this really be a tailq? As it is we will process the
     917             :                  * newest first :-0
     918             :                  */
     919           0 :                 LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr);
     920           0 :                 SCTP_WQ_ADDR_UNLOCK();
     921             : 
     922           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
     923             :                                  (struct sctp_inpcb *)NULL,
     924             :                                  (struct sctp_tcb *)NULL,
     925             :                                  (struct sctp_nets *)NULL);
     926             :         }
     927           0 :         return;
     928             : }
     929             : 
     930             : 
     931             : static int
     932           0 : sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
     933             : {
     934             :         int loopback_scope;
     935             : #if defined(INET)
     936             :         int ipv4_local_scope, ipv4_addr_legal;
     937             : #endif
     938             : #if defined(INET6)
     939             :         int local_scope, site_scope, ipv6_addr_legal;
     940             : #endif
     941             : #if defined(__Userspace__)
     942             :         int conn_addr_legal;
     943             : #endif
     944             :         struct sctp_vrf *vrf;
     945             :         struct sctp_ifn *sctp_ifn;
     946             :         struct sctp_ifa *sctp_ifa;
     947             : 
     948           0 :         loopback_scope = stcb->asoc.scope.loopback_scope;
     949             : #if defined(INET)
     950             :         ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
     951             :         ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
     952             : #endif
     953             : #if defined(INET6)
     954             :         local_scope = stcb->asoc.scope.local_scope;
     955             :         site_scope = stcb->asoc.scope.site_scope;
     956             :         ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
     957             : #endif
     958             : #if defined(__Userspace__)
     959           0 :         conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
     960             : #endif
     961             : 
     962           0 :         SCTP_IPI_ADDR_RLOCK();
     963           0 :         vrf = sctp_find_vrf(stcb->asoc.vrf_id);
     964           0 :         if (vrf == NULL) {
     965             :                 /* no vrf, no addresses */
     966           0 :                 SCTP_IPI_ADDR_RUNLOCK();
     967           0 :                 return (0);
     968             :         }
     969             : 
     970           0 :         if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
     971           0 :                 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
     972           0 :                         if ((loopback_scope == 0) &&
     973           0 :                             SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
     974           0 :                                 continue;
     975             :                         }
     976           0 :                         LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
     977           0 :                                 if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
     978           0 :                                     (!sctp_is_addr_pending(stcb, sctp_ifa))) {
     979             :                                         /* We allow pending addresses, where we
     980             :                                          * have sent an asconf-add to be considered
     981             :                                          * valid.
     982             :                                          */
     983           0 :                                         continue;
     984             :                                 }
     985           0 :                                 if (sctp_ifa->address.sa.sa_family != to->sa_family) {
     986           0 :                                         continue;
     987             :                                 }
     988           0 :                                 switch (sctp_ifa->address.sa.sa_family) {
     989             : #ifdef INET
     990             :                                 case AF_INET:
     991             :                                         if (ipv4_addr_legal) {
     992             :                                                 struct sockaddr_in *sin, *rsin;
     993             : 
     994             :                                                 sin = &sctp_ifa->address.sin;
     995             :                                                 rsin = (struct sockaddr_in *)to;
     996             :                                                 if ((ipv4_local_scope == 0) &&
     997             :                                                     IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
     998             :                                                         continue;
     999             :                                                 }
    1000             : #if defined(__FreeBSD__)
    1001             :                                                 if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
    1002             :                                                                      &sin->sin_addr) != 0) {
    1003             :                                                         continue;
    1004             :                                                 }
    1005             : #endif
    1006             :                                                 if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) {
    1007             :                                                         SCTP_IPI_ADDR_RUNLOCK();
    1008             :                                                         return (1);
    1009             :                                                 }
    1010             :                                         }
    1011             :                                         break;
    1012             : #endif
    1013             : #ifdef INET6
    1014             :                                 case AF_INET6:
    1015             :                                         if (ipv6_addr_legal) {
    1016             :                                                 struct sockaddr_in6 *sin6, *rsin6;
    1017             : #if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME)
    1018             :                                                 struct sockaddr_in6 lsa6;
    1019             : #endif
    1020             :                                                 sin6 = &sctp_ifa->address.sin6;
    1021             :                                                 rsin6 = (struct sockaddr_in6 *)to;
    1022             : #if defined(__FreeBSD__)
    1023             :                                                 if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
    1024             :                                                                      &sin6->sin6_addr) != 0) {
    1025             :                                                         continue;
    1026             :                                                 }
    1027             : #endif
    1028             :                                                 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
    1029             :                                                         if (local_scope == 0)
    1030             :                                                                 continue;
    1031             : #if defined(SCTP_EMBEDDED_V6_SCOPE)
    1032             :                                                         if (sin6->sin6_scope_id == 0) {
    1033             : #ifdef SCTP_KAME
    1034             :                                                                 if (sa6_recoverscope(sin6) != 0)
    1035             :                                                                         continue;
    1036             : #else
    1037             :                                                                 lsa6 = *sin6;
    1038             :                                                                 if (in6_recoverscope(&lsa6,
    1039             :                                                                                      &lsa6.sin6_addr,
    1040             :                                                                                      NULL))
    1041             :                                                                         continue;
    1042             :                                                                 sin6 = &lsa6;
    1043             : #endif /* SCTP_KAME */
    1044             :                                                         }
    1045             : #endif /* SCTP_EMBEDDED_V6_SCOPE */
    1046             :                                                 }
    1047             :                                                 if ((site_scope == 0) &&
    1048             :                                                     (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
    1049             :                                                         continue;
    1050             :                                                 }
    1051             :                                                 if (SCTP6_ARE_ADDR_EQUAL(sin6, rsin6)) {
    1052             :                                                         SCTP_IPI_ADDR_RUNLOCK();
    1053             :                                                         return (1);
    1054             :                                                 }
    1055             :                                         }
    1056             :                                         break;
    1057             : #endif
    1058             : #if defined(__Userspace__)
    1059             :                                 case AF_CONN:
    1060           0 :                                         if (conn_addr_legal) {
    1061             :                                                 struct sockaddr_conn *sconn, *rsconn;
    1062             : 
    1063           0 :                                                 sconn = &sctp_ifa->address.sconn;
    1064           0 :                                                 rsconn = (struct sockaddr_conn *)to;
    1065           0 :                                                 if (sconn->sconn_addr == rsconn->sconn_addr) {
    1066           0 :                                                         SCTP_IPI_ADDR_RUNLOCK();
    1067           0 :                                                         return (1);
    1068             :                                                 }
    1069             :                                         }
    1070           0 :                                         break;
    1071             : #endif
    1072             :                                 default:
    1073             :                                         /* TSNH */
    1074           0 :                                         break;
    1075             :                                 }
    1076             :                         }
    1077             :                 }
    1078             :         } else {
    1079             :                 struct sctp_laddr *laddr;
    1080             : 
    1081           0 :                 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
    1082           0 :                         if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
    1083           0 :                                 SCTPDBG(SCTP_DEBUG_PCB1, "ifa being deleted\n");
    1084           0 :                                 continue;
    1085             :                         }
    1086           0 :                         if (sctp_is_addr_restricted(stcb, laddr->ifa) &&
    1087           0 :                             (!sctp_is_addr_pending(stcb, laddr->ifa))) {
    1088             :                                 /* We allow pending addresses, where we
    1089             :                                  * have sent an asconf-add to be considered
    1090             :                                  * valid.
    1091             :                                  */
    1092           0 :                                 continue;
    1093             :                         }
    1094           0 :                         if (laddr->ifa->address.sa.sa_family != to->sa_family) {
    1095           0 :                                 continue;
    1096             :                         }
    1097           0 :                         switch (to->sa_family) {
    1098             : #ifdef INET
    1099             :                         case AF_INET:
    1100             :                         {
    1101             :                                 struct sockaddr_in *sin, *rsin;
    1102             : 
    1103             :                                 sin = &laddr->ifa->address.sin;
    1104             :                                 rsin = (struct sockaddr_in *)to;
    1105             :                                 if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) {
    1106             :                                         SCTP_IPI_ADDR_RUNLOCK();
    1107             :                                         return (1);
    1108             :                                 }
    1109             :                                 break;
    1110             :                         }
    1111             : #endif
    1112             : #ifdef INET6
    1113             :                         case AF_INET6:
    1114             :                         {
    1115             :                                 struct sockaddr_in6 *sin6, *rsin6;
    1116             : 
    1117             :                                 sin6 = &laddr->ifa->address.sin6;
    1118             :                                 rsin6 = (struct sockaddr_in6 *)to;
    1119             :                                 if (SCTP6_ARE_ADDR_EQUAL(sin6, rsin6)) {
    1120             :                                         SCTP_IPI_ADDR_RUNLOCK();
    1121             :                                         return (1);
    1122             :                                 }
    1123             :                                 break;
    1124             :                         }
    1125             : 
    1126             : #endif
    1127             : #if defined(__Userspace__)
    1128             :                         case AF_CONN:
    1129             :                         {
    1130             :                                 struct sockaddr_conn *sconn, *rsconn;
    1131             : 
    1132           0 :                                 sconn = &laddr->ifa->address.sconn;
    1133           0 :                                 rsconn = (struct sockaddr_conn *)to;
    1134           0 :                                 if (sconn->sconn_addr == rsconn->sconn_addr) {
    1135           0 :                                         SCTP_IPI_ADDR_RUNLOCK();
    1136           0 :                                         return (1);
    1137             :                                 }
    1138           0 :                                 break;
    1139             :                         }
    1140             : #endif
    1141             :                         default:
    1142             :                                 /* TSNH */
    1143           0 :                                 break;
    1144             :                         }
    1145             : 
    1146             :                 }
    1147             :         }
    1148           0 :         SCTP_IPI_ADDR_RUNLOCK();
    1149           0 :         return (0);
    1150             : }
    1151             : 
    1152             : 
    1153             : static struct sctp_tcb *
    1154           0 : sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
    1155             :     struct sockaddr *to, struct sctp_nets **netp, uint32_t vrf_id)
    1156             : {
    1157             :         /**** ASSUMES THE CALLER holds the INP_INFO_RLOCK */
    1158             :         /*
    1159             :          * If we support the TCP model, then we must now dig through to see
    1160             :          * if we can find our endpoint in the list of tcp ep's.
    1161             :          */
    1162             :         uint16_t lport, rport;
    1163             :         struct sctppcbhead *ephead;
    1164             :         struct sctp_inpcb *inp;
    1165             :         struct sctp_laddr *laddr;
    1166             :         struct sctp_tcb *stcb;
    1167             :         struct sctp_nets *net;
    1168             : #ifdef SCTP_MVRF
    1169             :         int fnd, i;
    1170             : #endif
    1171             : 
    1172           0 :         if ((to == NULL) || (from == NULL)) {
    1173           0 :                 return (NULL);
    1174             :         }
    1175             : 
    1176           0 :         switch (to->sa_family) {
    1177             : #ifdef INET
    1178             :         case AF_INET:
    1179             :                 if (from->sa_family == AF_INET) {
    1180             :                         lport = ((struct sockaddr_in *)to)->sin_port;
    1181             :                         rport = ((struct sockaddr_in *)from)->sin_port;
    1182             :                 } else {
    1183             :                         return (NULL);
    1184             :                 }
    1185             :                 break;
    1186             : #endif
    1187             : #ifdef INET6
    1188             :         case AF_INET6:
    1189             :                 if (from->sa_family == AF_INET6) {
    1190             :                         lport = ((struct sockaddr_in6 *)to)->sin6_port;
    1191             :                         rport = ((struct sockaddr_in6 *)from)->sin6_port;
    1192             :                 } else {
    1193             :                         return (NULL);
    1194             :                 }
    1195             :                 break;
    1196             : #endif
    1197             : #if defined(__Userspace__)
    1198             :         case AF_CONN:
    1199           0 :                 if (from->sa_family == AF_CONN) {
    1200           0 :                         lport = ((struct sockaddr_conn *)to)->sconn_port;
    1201           0 :                         rport = ((struct sockaddr_conn *)from)->sconn_port;
    1202             :                 } else {
    1203           0 :                         return (NULL);
    1204             :                 }
    1205           0 :                 break;
    1206             : #endif
    1207             :         default:
    1208           0 :                 return (NULL);
    1209             :         }
    1210           0 :         ephead = &SCTP_BASE_INFO(sctp_tcpephash)[SCTP_PCBHASH_ALLADDR((lport | rport), SCTP_BASE_INFO(hashtcpmark))];
    1211             :         /*
    1212             :          * Ok now for each of the guys in this bucket we must look and see:
    1213             :          * - Does the remote port match. - Does there single association's
    1214             :          * addresses match this address (to). If so we update p_ep to point
    1215             :          * to this ep and return the tcb from it.
    1216             :          */
    1217           0 :         LIST_FOREACH(inp, ephead, sctp_hash) {
    1218           0 :                 SCTP_INP_RLOCK(inp);
    1219           0 :                 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
    1220           0 :                         SCTP_INP_RUNLOCK(inp);
    1221           0 :                         continue;
    1222             :                 }
    1223           0 :                 if (lport != inp->sctp_lport) {
    1224           0 :                         SCTP_INP_RUNLOCK(inp);
    1225           0 :                         continue;
    1226             :                 }
    1227             : #if defined(__FreeBSD__)
    1228             :                 switch (to->sa_family) {
    1229             : #ifdef INET
    1230             :                 case AF_INET:
    1231             :                 {
    1232             :                         struct sockaddr_in *sin;
    1233             : 
    1234             :                         sin = (struct sockaddr_in *)to;
    1235             :                         if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
    1236             :                                              &sin->sin_addr) != 0) {
    1237             :                                 SCTP_INP_RUNLOCK(inp);
    1238             :                                 continue;
    1239             :                         }
    1240             :                         break;
    1241             :                 }
    1242             : #endif
    1243             : #ifdef INET6
    1244             :                 case AF_INET6:
    1245             :                 {
    1246             :                         struct sockaddr_in6 *sin6;
    1247             : 
    1248             :                         sin6 = (struct sockaddr_in6 *)to;
    1249             :                         if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
    1250             :                                              &sin6->sin6_addr) != 0) {
    1251             :                                 SCTP_INP_RUNLOCK(inp);
    1252             :                                 continue;
    1253             :                         }
    1254             :                         break;
    1255             :                 }
    1256             : #endif
    1257             :                 default:
    1258             :                         SCTP_INP_RUNLOCK(inp);
    1259             :                         continue;
    1260             :                 }
    1261             : #endif
    1262             : #ifdef SCTP_MVRF
    1263             :                 fnd = 0;
    1264             :                 for (i = 0; i < inp->num_vrfs; i++) {
    1265             :                         if (inp->m_vrf_ids[i] == vrf_id) {
    1266             :                                 fnd = 1;
    1267             :                                 break;
    1268             :                         }
    1269             :                 }
    1270             :                 if (fnd == 0) {
    1271             :                         SCTP_INP_RUNLOCK(inp);
    1272             :                         continue;
    1273             :                 }
    1274             : #else
    1275           0 :                 if (inp->def_vrf_id != vrf_id) {
    1276           0 :                         SCTP_INP_RUNLOCK(inp);
    1277           0 :                         continue;
    1278             :                 }
    1279             : #endif
    1280             :                 /* check to see if the ep has one of the addresses */
    1281           0 :                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
    1282             :                         /* We are NOT bound all, so look further */
    1283           0 :                         int match = 0;
    1284             : 
    1285           0 :                         LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
    1286             : 
    1287           0 :                                 if (laddr->ifa == NULL) {
    1288           0 :                                         SCTPDBG(SCTP_DEBUG_PCB1, "%s: NULL ifa\n", __FUNCTION__);
    1289           0 :                                         continue;
    1290             :                                 }
    1291           0 :                                 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
    1292           0 :                                         SCTPDBG(SCTP_DEBUG_PCB1, "ifa being deleted\n");
    1293           0 :                                         continue;
    1294             :                                 }
    1295           0 :                                 if (laddr->ifa->address.sa.sa_family ==
    1296           0 :                                     to->sa_family) {
    1297             :                                         /* see if it matches */
    1298             : #ifdef INET
    1299             :                                         if (from->sa_family == AF_INET) {
    1300             :                                                 struct sockaddr_in *intf_addr, *sin;
    1301             : 
    1302             :                                                 intf_addr = &laddr->ifa->address.sin;
    1303             :                                                 sin = (struct sockaddr_in *)to;
    1304             :                                                 if (sin->sin_addr.s_addr ==
    1305             :                                                     intf_addr->sin_addr.s_addr) {
    1306             :                                                         match = 1;
    1307             :                                                         break;
    1308             :                                                 }
    1309             :                                         }
    1310             : #endif
    1311             : #ifdef INET6
    1312             :                                         if (from->sa_family == AF_INET6) {
    1313             :                                                 struct sockaddr_in6 *intf_addr6;
    1314             :                                                 struct sockaddr_in6 *sin6;
    1315             : 
    1316             :                                                 sin6 = (struct sockaddr_in6 *)
    1317             :                                                     to;
    1318             :                                                 intf_addr6 = &laddr->ifa->address.sin6;
    1319             : 
    1320             :                                                 if (SCTP6_ARE_ADDR_EQUAL(sin6,
    1321             :                                                     intf_addr6)) {
    1322             :                                                         match = 1;
    1323             :                                                         break;
    1324             :                                                 }
    1325             :                                         }
    1326             : #endif
    1327             : #if defined(__Userspace__)
    1328           0 :                                         if (from->sa_family == AF_CONN) {
    1329             :                                                 struct sockaddr_conn *intf_addr, *sconn;
    1330             : 
    1331           0 :                                                 intf_addr = &laddr->ifa->address.sconn;
    1332           0 :                                                 sconn = (struct sockaddr_conn *)to;
    1333           0 :                                                 if (sconn->sconn_addr ==
    1334           0 :                                                     intf_addr->sconn_addr) {
    1335           0 :                                                         match = 1;
    1336           0 :                                                         break;
    1337             :                                                 }
    1338             :                                         }
    1339             : #endif
    1340             :                                 }
    1341             :                         }
    1342           0 :                         if (match == 0) {
    1343             :                                 /* This endpoint does not have this address */
    1344           0 :                                 SCTP_INP_RUNLOCK(inp);
    1345           0 :                                 continue;
    1346             :                         }
    1347             :                 }
    1348             :                 /*
    1349             :                  * Ok if we hit here the ep has the address, does it hold
    1350             :                  * the tcb?
    1351             :                  */
    1352             :                 /* XXX: Why don't we TAILQ_FOREACH through sctp_asoc_list? */
    1353           0 :                 stcb = LIST_FIRST(&inp->sctp_asoc_list);
    1354           0 :                 if (stcb == NULL) {
    1355           0 :                         SCTP_INP_RUNLOCK(inp);
    1356           0 :                         continue;
    1357             :                 }
    1358           0 :                 SCTP_TCB_LOCK(stcb);
    1359           0 :                 if (!sctp_does_stcb_own_this_addr(stcb, to)) {
    1360           0 :                         SCTP_TCB_UNLOCK(stcb);
    1361           0 :                         SCTP_INP_RUNLOCK(inp);
    1362           0 :                         continue;
    1363             :                 }
    1364           0 :                 if (stcb->rport != rport) {
    1365             :                         /* remote port does not match. */
    1366           0 :                         SCTP_TCB_UNLOCK(stcb);
    1367           0 :                         SCTP_INP_RUNLOCK(inp);
    1368           0 :                         continue;
    1369             :                 }
    1370           0 :                 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
    1371           0 :                         SCTP_TCB_UNLOCK(stcb);
    1372           0 :                         SCTP_INP_RUNLOCK(inp);
    1373           0 :                         continue;
    1374             :                 }
    1375           0 :                 if (!sctp_does_stcb_own_this_addr(stcb, to)) {
    1376           0 :                         SCTP_TCB_UNLOCK(stcb);
    1377           0 :                         SCTP_INP_RUNLOCK(inp);
    1378           0 :                         continue;
    1379             :                 }
    1380             :                 /* Does this TCB have a matching address? */
    1381           0 :                 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
    1382             : 
    1383           0 :                         if (net->ro._l_addr.sa.sa_family != from->sa_family) {
    1384             :                                 /* not the same family, can't be a match */
    1385           0 :                                 continue;
    1386             :                         }
    1387           0 :                         switch (from->sa_family) {
    1388             : #ifdef INET
    1389             :                         case AF_INET:
    1390             :                         {
    1391             :                                 struct sockaddr_in *sin, *rsin;
    1392             : 
    1393             :                                 sin = (struct sockaddr_in *)&net->ro._l_addr;
    1394             :                                 rsin = (struct sockaddr_in *)from;
    1395             :                                 if (sin->sin_addr.s_addr ==
    1396             :                                     rsin->sin_addr.s_addr) {
    1397             :                                         /* found it */
    1398             :                                         if (netp != NULL) {
    1399             :                                                 *netp = net;
    1400             :                                         }
    1401             :                                         /* Update the endpoint pointer */
    1402             :                                         *inp_p = inp;
    1403             :                                         SCTP_INP_RUNLOCK(inp);
    1404             :                                         return (stcb);
    1405             :                                 }
    1406             :                                 break;
    1407             :                         }
    1408             : #endif
    1409             : #ifdef INET6
    1410             :                         case AF_INET6:
    1411             :                         {
    1412             :                                 struct sockaddr_in6 *sin6, *rsin6;
    1413             : 
    1414             :                                 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
    1415             :                                 rsin6 = (struct sockaddr_in6 *)from;
    1416             :                                 if (SCTP6_ARE_ADDR_EQUAL(sin6,
    1417             :                                     rsin6)) {
    1418             :                                         /* found it */
    1419             :                                         if (netp != NULL) {
    1420             :                                                 *netp = net;
    1421             :                                         }
    1422             :                                         /* Update the endpoint pointer */
    1423             :                                         *inp_p = inp;
    1424             :                                         SCTP_INP_RUNLOCK(inp);
    1425             :                                         return (stcb);
    1426             :                                 }
    1427             :                                 break;
    1428             :                         }
    1429             : #endif
    1430             : #if defined(__Userspace__)
    1431             :                         case AF_CONN:
    1432             :                         {
    1433             :                                 struct sockaddr_conn *sconn, *rsconn;
    1434             : 
    1435           0 :                                 sconn = (struct sockaddr_conn *)&net->ro._l_addr;
    1436           0 :                                 rsconn = (struct sockaddr_conn *)from;
    1437           0 :                                 if (sconn->sconn_addr == rsconn->sconn_addr) {
    1438             :                                         /* found it */
    1439           0 :                                         if (netp != NULL) {
    1440           0 :                                                 *netp = net;
    1441             :                                         }
    1442             :                                         /* Update the endpoint pointer */
    1443           0 :                                         *inp_p = inp;
    1444           0 :                                         SCTP_INP_RUNLOCK(inp);
    1445           0 :                                         return (stcb);
    1446             :                                 }
    1447           0 :                                 break;
    1448             :                         }
    1449             : #endif
    1450             :                         default:
    1451             :                                 /* TSNH */
    1452           0 :                                 break;
    1453             :                         }
    1454             :                 }
    1455           0 :                 SCTP_TCB_UNLOCK(stcb);
    1456           0 :                 SCTP_INP_RUNLOCK(inp);
    1457             :         }
    1458           0 :         return (NULL);
    1459             : }
    1460             : 
    1461             : 
    1462             : /*
    1463             :  * rules for use
    1464             :  *
    1465             :  * 1) If I return a NULL you must decrement any INP ref cnt. 2) If I find an
    1466             :  * stcb, both will be locked (locked_tcb and stcb) but decrement will be done
    1467             :  * (if locked == NULL). 3) Decrement happens on return ONLY if locked ==
    1468             :  * NULL.
    1469             :  */
    1470             : 
    1471             : struct sctp_tcb *
    1472           0 : sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
    1473             :     struct sctp_nets **netp, struct sockaddr *local, struct sctp_tcb *locked_tcb)
    1474             : {
    1475             :         struct sctpasochead *head;
    1476             :         struct sctp_inpcb *inp;
    1477           0 :         struct sctp_tcb *stcb = NULL;
    1478             :         struct sctp_nets *net;
    1479             :         uint16_t rport;
    1480             : 
    1481           0 :         inp = *inp_p;
    1482           0 :         switch (remote->sa_family) {
    1483             : #ifdef INET
    1484             :         case AF_INET:
    1485             :                 rport = (((struct sockaddr_in *)remote)->sin_port);
    1486             :                 break;
    1487             : #endif
    1488             : #ifdef INET6
    1489             :         case AF_INET6:
    1490             :                 rport = (((struct sockaddr_in6 *)remote)->sin6_port);
    1491             :                 break;
    1492             : #endif
    1493             : #if defined(__Userspace__)
    1494             :         case AF_CONN:
    1495           0 :                 rport = (((struct sockaddr_in6 *)remote)->sin6_port);
    1496           0 :                 break;
    1497             : #endif
    1498             :         default:
    1499           0 :                 return (NULL);
    1500             :         }
    1501           0 :         if (locked_tcb) {
    1502             :                 /*
    1503             :                  * UN-lock so we can do proper locking here this occurs when
    1504             :                  * called from load_addresses_from_init.
    1505             :                  */
    1506           0 :                 atomic_add_int(&locked_tcb->asoc.refcnt, 1);
    1507           0 :                 SCTP_TCB_UNLOCK(locked_tcb);
    1508             :         }
    1509           0 :         SCTP_INP_INFO_RLOCK();
    1510           0 :         if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
    1511           0 :             (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
    1512             :                 /*-
    1513             :                  * Now either this guy is our listener or it's the
    1514             :                  * connector. If it is the one that issued the connect, then
    1515             :                  * it's only chance is to be the first TCB in the list. If
    1516             :                  * it is the acceptor, then do the special_lookup to hash
    1517             :                  * and find the real inp.
    1518             :                  */
    1519           0 :                 if ((inp->sctp_socket) && (inp->sctp_socket->so_qlimit)) {
    1520             :                         /* to is peer addr, from is my addr */
    1521             : #ifndef SCTP_MVRF
    1522           0 :                         stcb = sctp_tcb_special_locate(inp_p, remote, local,
    1523             :                             netp, inp->def_vrf_id);
    1524           0 :                         if ((stcb != NULL) && (locked_tcb == NULL)) {
    1525             :                                 /* we have a locked tcb, lower refcount */
    1526           0 :                                 SCTP_INP_DECR_REF(inp);
    1527             :                         }
    1528           0 :                         if ((locked_tcb != NULL) && (locked_tcb != stcb)) {
    1529           0 :                                 SCTP_INP_RLOCK(locked_tcb->sctp_ep);
    1530           0 :                                 SCTP_TCB_LOCK(locked_tcb);
    1531           0 :                                 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
    1532           0 :                                 SCTP_INP_RUNLOCK(locked_tcb->sctp_ep);
    1533             :                         }
    1534             : #else
    1535             :                         /*-
    1536             :                          * MVRF is tricky, we must look in every VRF
    1537             :                          * the endpoint has.
    1538             :                          */
    1539             :                         int i;
    1540             : 
    1541             :                         for (i = 0; i < inp->num_vrfs; i++) {
    1542             :                                 stcb = sctp_tcb_special_locate(inp_p, remote, local,
    1543             :                                                                netp, inp->m_vrf_ids[i]);
    1544             :                                 if ((stcb != NULL) && (locked_tcb == NULL)) {
    1545             :                                         /* we have a locked tcb, lower refcount */
    1546             :                                         SCTP_INP_DECR_REF(inp);
    1547             :                                         break;
    1548             :                                 }
    1549             :                                 if ((locked_tcb != NULL) && (locked_tcb != stcb)) {
    1550             :                                         SCTP_INP_RLOCK(locked_tcb->sctp_ep);
    1551             :                                         SCTP_TCB_LOCK(locked_tcb);
    1552             :                                         atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
    1553             :                                         SCTP_INP_RUNLOCK(locked_tcb->sctp_ep);
    1554             :                                         break;
    1555             :                                 }
    1556             :                         }
    1557             : #endif
    1558           0 :                         SCTP_INP_INFO_RUNLOCK();
    1559           0 :                         return (stcb);
    1560             :                 } else {
    1561           0 :                         SCTP_INP_WLOCK(inp);
    1562           0 :                         if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
    1563           0 :                                 goto null_return;
    1564             :                         }
    1565           0 :                         stcb = LIST_FIRST(&inp->sctp_asoc_list);
    1566           0 :                         if (stcb == NULL) {
    1567           0 :                                 goto null_return;
    1568             :                         }
    1569           0 :                         SCTP_TCB_LOCK(stcb);
    1570             : 
    1571           0 :                         if (stcb->rport != rport) {
    1572             :                                 /* remote port does not match. */
    1573           0 :                                 SCTP_TCB_UNLOCK(stcb);
    1574           0 :                                 goto null_return;
    1575             :                         }
    1576           0 :                         if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
    1577           0 :                                 SCTP_TCB_UNLOCK(stcb);
    1578           0 :                                 goto null_return;
    1579             :                         }
    1580           0 :                         if (local && !sctp_does_stcb_own_this_addr(stcb, local)) {
    1581           0 :                                 SCTP_TCB_UNLOCK(stcb);
    1582           0 :                                 goto null_return;
    1583             :                         }
    1584             :                         /* now look at the list of remote addresses */
    1585           0 :                         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
    1586             : #ifdef INVARIANTS
    1587             :                                 if (net == (TAILQ_NEXT(net, sctp_next))) {
    1588             :                                         panic("Corrupt net list");
    1589             :                                 }
    1590             : #endif
    1591           0 :                                 if (net->ro._l_addr.sa.sa_family !=
    1592           0 :                                     remote->sa_family) {
    1593             :                                         /* not the same family */
    1594           0 :                                         continue;
    1595             :                                 }
    1596           0 :                                 switch (remote->sa_family) {
    1597             : #ifdef INET
    1598             :                                 case AF_INET:
    1599             :                                 {
    1600             :                                         struct sockaddr_in *sin, *rsin;
    1601             : 
    1602             :                                         sin = (struct sockaddr_in *)
    1603             :                                             &net->ro._l_addr;
    1604             :                                         rsin = (struct sockaddr_in *)remote;
    1605             :                                         if (sin->sin_addr.s_addr ==
    1606             :                                             rsin->sin_addr.s_addr) {
    1607             :                                                 /* found it */
    1608             :                                                 if (netp != NULL) {
    1609             :                                                         *netp = net;
    1610             :                                                 }
    1611             :                                                 if (locked_tcb == NULL) {
    1612             :                                                         SCTP_INP_DECR_REF(inp);
    1613             :                                                 } else if (locked_tcb != stcb) {
    1614             :                                                         SCTP_TCB_LOCK(locked_tcb);
    1615             :                                                 }
    1616             :                                                 if (locked_tcb) {
    1617             :                                                         atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
    1618             :                                                 }
    1619             : 
    1620             :                                                 SCTP_INP_WUNLOCK(inp);
    1621             :                                                 SCTP_INP_INFO_RUNLOCK();
    1622             :                                                 return (stcb);
    1623             :                                         }
    1624             :                                         break;
    1625             :                                 }
    1626             : #endif
    1627             : #ifdef INET6
    1628             :                                 case AF_INET6:
    1629             :                                 {
    1630             :                                         struct sockaddr_in6 *sin6, *rsin6;
    1631             : 
    1632             :                                         sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
    1633             :                                         rsin6 = (struct sockaddr_in6 *)remote;
    1634             :                                         if (SCTP6_ARE_ADDR_EQUAL(sin6,
    1635             :                                             rsin6)) {
    1636             :                                                 /* found it */
    1637             :                                                 if (netp != NULL) {
    1638             :                                                         *netp = net;
    1639             :                                                 }
    1640             :                                                 if (locked_tcb == NULL) {
    1641             :                                                         SCTP_INP_DECR_REF(inp);
    1642             :                                                 } else if (locked_tcb != stcb) {
    1643             :                                                         SCTP_TCB_LOCK(locked_tcb);
    1644             :                                                 }
    1645             :                                                 if (locked_tcb) {
    1646             :                                                         atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
    1647             :                                                 }
    1648             :                                                 SCTP_INP_WUNLOCK(inp);
    1649             :                                                 SCTP_INP_INFO_RUNLOCK();
    1650             :                                                 return (stcb);
    1651             :                                         }
    1652             :                                         break;
    1653             :                                 }
    1654             : #endif
    1655             : #if defined(__Userspace__)
    1656             :                                 case AF_CONN:
    1657             :                                 {
    1658             :                                         struct sockaddr_conn *sconn, *rsconn;
    1659             : 
    1660           0 :                                         sconn = (struct sockaddr_conn *)&net->ro._l_addr;
    1661           0 :                                         rsconn = (struct sockaddr_conn *)remote;
    1662           0 :                                         if (sconn->sconn_addr == rsconn->sconn_addr) {
    1663             :                                                 /* found it */
    1664           0 :                                                 if (netp != NULL) {
    1665           0 :                                                         *netp = net;
    1666             :                                                 }
    1667           0 :                                                 if (locked_tcb == NULL) {
    1668           0 :                                                         SCTP_INP_DECR_REF(inp);
    1669           0 :                                                 } else if (locked_tcb != stcb) {
    1670           0 :                                                         SCTP_TCB_LOCK(locked_tcb);
    1671             :                                                 }
    1672           0 :                                                 if (locked_tcb) {
    1673           0 :                                                         atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
    1674             :                                                 }
    1675           0 :                                                 SCTP_INP_WUNLOCK(inp);
    1676           0 :                                                 SCTP_INP_INFO_RUNLOCK();
    1677           0 :                                                 return (stcb);
    1678             :                                         }
    1679           0 :                                         break;
    1680             :                                 }
    1681             : #endif
    1682             :                                 default:
    1683             :                                         /* TSNH */
    1684           0 :                                         break;
    1685             :                                 }
    1686             :                         }
    1687           0 :                         SCTP_TCB_UNLOCK(stcb);
    1688             :                 }
    1689             :         } else {
    1690           0 :                 SCTP_INP_WLOCK(inp);
    1691           0 :                 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
    1692           0 :                         goto null_return;
    1693             :                 }
    1694           0 :                 head = &inp->sctp_tcbhash[SCTP_PCBHASH_ALLADDR(rport,
    1695             :                                                                inp->sctp_hashmark)];
    1696           0 :                 LIST_FOREACH(stcb, head, sctp_tcbhash) {
    1697           0 :                         if (stcb->rport != rport) {
    1698             :                                 /* remote port does not match */
    1699           0 :                                 continue;
    1700             :                         }
    1701           0 :                         SCTP_TCB_LOCK(stcb);
    1702           0 :                         if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
    1703           0 :                                 SCTP_TCB_UNLOCK(stcb);
    1704           0 :                                 continue;
    1705             :                         }
    1706           0 :                         if (local && !sctp_does_stcb_own_this_addr(stcb, local)) {
    1707           0 :                                 SCTP_TCB_UNLOCK(stcb);
    1708           0 :                                 continue;
    1709             :                         }
    1710             :                         /* now look at the list of remote addresses */
    1711           0 :                         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
    1712             : #ifdef INVARIANTS
    1713             :                                 if (net == (TAILQ_NEXT(net, sctp_next))) {
    1714             :                                         panic("Corrupt net list");
    1715             :                                 }
    1716             : #endif
    1717           0 :                                 if (net->ro._l_addr.sa.sa_family !=
    1718           0 :                                     remote->sa_family) {
    1719             :                                         /* not the same family */
    1720           0 :                                         continue;
    1721             :                                 }
    1722           0 :                                 switch (remote->sa_family) {
    1723             : #ifdef INET
    1724             :                                 case AF_INET:
    1725             :                                 {
    1726             :                                         struct sockaddr_in *sin, *rsin;
    1727             : 
    1728             :                                         sin = (struct sockaddr_in *)
    1729             :                                             &net->ro._l_addr;
    1730             :                                         rsin = (struct sockaddr_in *)remote;
    1731             :                                         if (sin->sin_addr.s_addr ==
    1732             :                                             rsin->sin_addr.s_addr) {
    1733             :                                                 /* found it */
    1734             :                                                 if (netp != NULL) {
    1735             :                                                         *netp = net;
    1736             :                                                 }
    1737             :                                                 if (locked_tcb == NULL) {
    1738             :                                                         SCTP_INP_DECR_REF(inp);
    1739             :                                                 } else if (locked_tcb != stcb) {
    1740             :                                                         SCTP_TCB_LOCK(locked_tcb);
    1741             :                                                 }
    1742             :                                                 if (locked_tcb) {
    1743             :                                                         atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
    1744             :                                                 }
    1745             :                                                 SCTP_INP_WUNLOCK(inp);
    1746             :                                                 SCTP_INP_INFO_RUNLOCK();
    1747             :                                                 return (stcb);
    1748             :                                         }
    1749             :                                         break;
    1750             :                                 }
    1751             : #endif
    1752             : #ifdef INET6
    1753             :                                 case AF_INET6:
    1754             :                                 {
    1755             :                                         struct sockaddr_in6 *sin6, *rsin6;
    1756             : 
    1757             :                                         sin6 = (struct sockaddr_in6 *)
    1758             :                                             &net->ro._l_addr;
    1759             :                                         rsin6 = (struct sockaddr_in6 *)remote;
    1760             :                                         if (SCTP6_ARE_ADDR_EQUAL(sin6,
    1761             :                                             rsin6)) {
    1762             :                                                 /* found it */
    1763             :                                                 if (netp != NULL) {
    1764             :                                                         *netp = net;
    1765             :                                                 }
    1766             :                                                 if (locked_tcb == NULL) {
    1767             :                                                         SCTP_INP_DECR_REF(inp);
    1768             :                                                 } else if (locked_tcb != stcb) {
    1769             :                                                         SCTP_TCB_LOCK(locked_tcb);
    1770             :                                                 }
    1771             :                                                 if (locked_tcb) {
    1772             :                                                         atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
    1773             :                                                 }
    1774             :                                                 SCTP_INP_WUNLOCK(inp);
    1775             :                                                 SCTP_INP_INFO_RUNLOCK();
    1776             :                                                 return (stcb);
    1777             :                                         }
    1778             :                                         break;
    1779             :                                 }
    1780             : #endif
    1781             : #if defined(__Userspace__)
    1782             :                                 case AF_CONN:
    1783             :                                 {
    1784             :                                         struct sockaddr_conn *sconn, *rsconn;
    1785             : 
    1786           0 :                                         sconn = (struct sockaddr_conn *)&net->ro._l_addr;
    1787           0 :                                         rsconn = (struct sockaddr_conn *)remote;
    1788           0 :                                         if (sconn->sconn_addr == rsconn->sconn_addr) {
    1789             :                                                 /* found it */
    1790           0 :                                                 if (netp != NULL) {
    1791           0 :                                                         *netp = net;
    1792             :                                                 }
    1793           0 :                                                 if (locked_tcb == NULL) {
    1794           0 :                                                         SCTP_INP_DECR_REF(inp);
    1795           0 :                                                 } else if (locked_tcb != stcb) {
    1796           0 :                                                         SCTP_TCB_LOCK(locked_tcb);
    1797             :                                                 }
    1798           0 :                                                 if (locked_tcb) {
    1799           0 :                                                         atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
    1800             :                                                 }
    1801           0 :                                                 SCTP_INP_WUNLOCK(inp);
    1802           0 :                                                 SCTP_INP_INFO_RUNLOCK();
    1803           0 :                                                 return (stcb);
    1804             :                                         }
    1805           0 :                                         break;
    1806             :                                 }
    1807             : #endif
    1808             :                                 default:
    1809             :                                         /* TSNH */
    1810           0 :                                         break;
    1811             :                                 }
    1812             :                         }
    1813           0 :                         SCTP_TCB_UNLOCK(stcb);
    1814             :                 }
    1815             :         }
    1816             : null_return:
    1817             :         /* clean up for returning null */
    1818           0 :         if (locked_tcb) {
    1819           0 :                 SCTP_TCB_LOCK(locked_tcb);
    1820           0 :                 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
    1821             :         }
    1822           0 :         SCTP_INP_WUNLOCK(inp);
    1823           0 :         SCTP_INP_INFO_RUNLOCK();
    1824             :         /* not found */
    1825           0 :         return (NULL);
    1826             : }
    1827             : 
    1828             : 
    1829             : /*
    1830             :  * Find an association for a specific endpoint using the association id given
    1831             :  * out in the COMM_UP notification
    1832             :  */
    1833             : struct sctp_tcb *
    1834           0 : sctp_findasoc_ep_asocid_locked(struct sctp_inpcb *inp, sctp_assoc_t asoc_id, int want_lock)
    1835             : {
    1836             :         /*
    1837             :          * Use my the assoc_id to find a endpoint
    1838             :          */
    1839             :         struct sctpasochead *head;
    1840             :         struct sctp_tcb *stcb;
    1841             :         uint32_t id;
    1842             : 
    1843           0 :         if (inp == NULL) {
    1844           0 :                 SCTP_PRINTF("TSNH ep_associd\n");
    1845           0 :                 return (NULL);
    1846             :         }
    1847           0 :         if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
    1848           0 :                 SCTP_PRINTF("TSNH ep_associd0\n");
    1849           0 :                 return (NULL);
    1850             :         }
    1851           0 :         id = (uint32_t)asoc_id;
    1852           0 :         head = &inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(id, inp->hashasocidmark)];
    1853           0 :         if (head == NULL) {
    1854             :                 /* invalid id TSNH */
    1855           0 :                 SCTP_PRINTF("TSNH ep_associd1\n");
    1856           0 :                 return (NULL);
    1857             :         }
    1858           0 :         LIST_FOREACH(stcb, head, sctp_tcbasocidhash) {
    1859           0 :                 if (stcb->asoc.assoc_id == id) {
    1860           0 :                         if (inp != stcb->sctp_ep) {
    1861             :                                 /*
    1862             :                                  * some other guy has the same id active (id
    1863             :                                  * collision ??).
    1864             :                                  */
    1865           0 :                                 SCTP_PRINTF("TSNH ep_associd2\n");
    1866           0 :                                 continue;
    1867             :                         }
    1868           0 :                         if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
    1869           0 :                                 continue;
    1870             :                         }
    1871           0 :                         if (want_lock) {
    1872           0 :                                 SCTP_TCB_LOCK(stcb);
    1873             :                         }
    1874           0 :                         return (stcb);
    1875             :                 }
    1876             :         }
    1877           0 :         return (NULL);
    1878             : }
    1879             : 
    1880             : 
    1881             : struct sctp_tcb *
    1882           0 : sctp_findassociation_ep_asocid(struct sctp_inpcb *inp, sctp_assoc_t asoc_id, int want_lock)
    1883             : {
    1884             :         struct sctp_tcb *stcb;
    1885             : 
    1886           0 :         SCTP_INP_RLOCK(inp);
    1887           0 :         stcb = sctp_findasoc_ep_asocid_locked(inp, asoc_id, want_lock);
    1888           0 :         SCTP_INP_RUNLOCK(inp);
    1889           0 :         return (stcb);
    1890             : }
    1891             : 
    1892             : 
    1893             : /*
    1894             :  * Endpoint probe expects that the INP_INFO is locked.
    1895             :  */
    1896             : static struct sctp_inpcb *
    1897           0 : sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
    1898             :                     uint16_t lport, uint32_t vrf_id)
    1899             : {
    1900             :         struct sctp_inpcb *inp;
    1901             :         struct sctp_laddr *laddr;
    1902             : #ifdef INET
    1903             :         struct sockaddr_in *sin;
    1904             : #endif
    1905             : #ifdef INET6
    1906             :         struct sockaddr_in6 *sin6;
    1907             :         struct sockaddr_in6 *intf_addr6;
    1908             : #endif
    1909             : #if defined(__Userspace__)
    1910             :         struct sockaddr_conn *sconn;
    1911             : #endif
    1912             : #ifdef SCTP_MVRF
    1913             :         int i;
    1914             : #endif
    1915             :         int  fnd;
    1916             : 
    1917             : #ifdef INET
    1918             :         sin = NULL;
    1919             : #endif
    1920             : #ifdef INET6
    1921             :         sin6 = NULL;
    1922             : #endif
    1923             : #if defined(__Userspace__)
    1924           0 :         sconn = NULL;
    1925             : #endif
    1926           0 :         switch (nam->sa_family) {
    1927             : #ifdef INET
    1928             :         case AF_INET:
    1929             :                 sin = (struct sockaddr_in *)nam;
    1930             :                 break;
    1931             : #endif
    1932             : #ifdef INET6
    1933             :         case AF_INET6:
    1934             :                 sin6 = (struct sockaddr_in6 *)nam;
    1935             :                 break;
    1936             : #endif
    1937             : #if defined(__Userspace__)
    1938             :         case AF_CONN:
    1939           0 :                 sconn = (struct sockaddr_conn *)nam;
    1940           0 :                 break;
    1941             : #endif
    1942             :         default:
    1943             :                 /* unsupported family */
    1944           0 :                 return (NULL);
    1945             :         }
    1946             : 
    1947           0 :         if (head == NULL)
    1948           0 :                 return (NULL);
    1949             : 
    1950           0 :         LIST_FOREACH(inp, head, sctp_hash) {
    1951           0 :                 SCTP_INP_RLOCK(inp);
    1952           0 :                 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
    1953           0 :                         SCTP_INP_RUNLOCK(inp);
    1954           0 :                         continue;
    1955             :                 }
    1956           0 :                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) &&
    1957           0 :                     (inp->sctp_lport == lport)) {
    1958             :                         /* got it */
    1959           0 :                         switch (nam->sa_family) {
    1960             : #ifdef INET
    1961             :                         case AF_INET:
    1962             :                                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
    1963             :                                     SCTP_IPV6_V6ONLY(inp)) {
    1964             :                                         /* IPv4 on a IPv6 socket with ONLY IPv6 set */
    1965             :                                         SCTP_INP_RUNLOCK(inp);
    1966             :                                         continue;
    1967             :                                 }
    1968             : #if defined(__FreeBSD__)
    1969             :                                 if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
    1970             :                                                      &sin->sin_addr) != 0) {
    1971             :                                         SCTP_INP_RUNLOCK(inp);
    1972             :                                         continue;
    1973             :                                 }
    1974             : #endif
    1975             :                                 break;
    1976             : #endif
    1977             : #ifdef INET6
    1978             :                         case AF_INET6:
    1979             :                                 /* A V6 address and the endpoint is NOT bound V6 */
    1980             :                                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
    1981             :                                         SCTP_INP_RUNLOCK(inp);
    1982             :                                         continue;
    1983             :                                 }
    1984             : #if defined(__FreeBSD__)
    1985             :                                 if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
    1986             :                                                      &sin6->sin6_addr) != 0) {
    1987             :                                         SCTP_INP_RUNLOCK(inp);
    1988             :                                         continue;
    1989             :                                 }
    1990             : #endif
    1991             :                                 break;
    1992             : #endif
    1993             :                         default:
    1994           0 :                                 break;
    1995             :                         }
    1996             :                         /* does a VRF id match? */
    1997           0 :                         fnd = 0;
    1998             : #ifdef SCTP_MVRF
    1999             :                         for (i = 0; i < inp->num_vrfs; i++) {
    2000             :                                 if (inp->m_vrf_ids[i] == vrf_id) {
    2001             :                                         fnd = 1;
    2002             :                                         break;
    2003             :                                 }
    2004             :                         }
    2005             : #else
    2006           0 :                         if (inp->def_vrf_id == vrf_id)
    2007           0 :                                 fnd = 1;
    2008             : #endif
    2009             : 
    2010           0 :                         SCTP_INP_RUNLOCK(inp);
    2011           0 :                         if (!fnd)
    2012           0 :                                 continue;
    2013           0 :                         return (inp);
    2014             :                 }
    2015           0 :                 SCTP_INP_RUNLOCK(inp);
    2016             :         }
    2017           0 :         switch (nam->sa_family) {
    2018             : #ifdef INET
    2019             :         case AF_INET:
    2020             :                 if (sin->sin_addr.s_addr == INADDR_ANY) {
    2021             :                         /* Can't hunt for one that has no address specified */
    2022             :                         return (NULL);
    2023             :                 }
    2024             :                 break;
    2025             : #endif
    2026             : #ifdef INET6
    2027             :         case AF_INET6:
    2028             :                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
    2029             :                         /* Can't hunt for one that has no address specified */
    2030             :                         return (NULL);
    2031             :                 }
    2032             :                 break;
    2033             : #endif
    2034             : #if defined(__Userspace__)
    2035             :         case AF_CONN:
    2036           0 :                 if (sconn->sconn_addr == NULL) {
    2037           0 :                         return (NULL);
    2038             :                 }
    2039           0 :                 break;
    2040             : #endif
    2041             :         default:
    2042           0 :                 break;
    2043             :         }
    2044             :         /*
    2045             :          * ok, not bound to all so see if we can find a EP bound to this
    2046             :          * address.
    2047             :          */
    2048           0 :         LIST_FOREACH(inp, head, sctp_hash) {
    2049           0 :                 SCTP_INP_RLOCK(inp);
    2050           0 :                 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
    2051           0 :                         SCTP_INP_RUNLOCK(inp);
    2052           0 :                         continue;
    2053             :                 }
    2054           0 :                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL)) {
    2055           0 :                         SCTP_INP_RUNLOCK(inp);
    2056           0 :                         continue;
    2057             :                 }
    2058             :                 /*
    2059             :                  * Ok this could be a likely candidate, look at all of its
    2060             :                  * addresses
    2061             :                  */
    2062           0 :                 if (inp->sctp_lport != lport) {
    2063           0 :                         SCTP_INP_RUNLOCK(inp);
    2064           0 :                         continue;
    2065             :                 }
    2066             :                 /* does a VRF id match? */
    2067           0 :                 fnd = 0;
    2068             : #ifdef SCTP_MVRF
    2069             :                 for (i = 0; i < inp->num_vrfs; i++) {
    2070             :                         if (inp->m_vrf_ids[i] == vrf_id) {
    2071             :                                 fnd = 1;
    2072             :                                 break;
    2073             :                         }
    2074             :                 }
    2075             : #else
    2076           0 :                 if (inp->def_vrf_id == vrf_id)
    2077           0 :                         fnd = 1;
    2078             : 
    2079             : #endif
    2080           0 :                 if (!fnd) {
    2081           0 :                         SCTP_INP_RUNLOCK(inp);
    2082           0 :                         continue;
    2083             :                 }
    2084           0 :                 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
    2085           0 :                         if (laddr->ifa == NULL) {
    2086           0 :                                 SCTPDBG(SCTP_DEBUG_PCB1, "%s: NULL ifa\n",
    2087             :                                         __FUNCTION__);
    2088           0 :                                 continue;
    2089             :                         }
    2090           0 :                         SCTPDBG(SCTP_DEBUG_PCB1, "Ok laddr->ifa:%p is possible, ",
    2091             :                                 (void *)laddr->ifa);
    2092           0 :                         if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
    2093           0 :                                 SCTPDBG(SCTP_DEBUG_PCB1, "Huh IFA being deleted\n");
    2094           0 :                                 continue;
    2095             :                         }
    2096           0 :                         if (laddr->ifa->address.sa.sa_family == nam->sa_family) {
    2097             :                                 /* possible, see if it matches */
    2098           0 :                                 switch (nam->sa_family) {
    2099             : #ifdef INET
    2100             :                                 case AF_INET:
    2101             : #if defined(__APPLE__)
    2102             :                                         if (sin == NULL) {
    2103             :                                                 /* TSNH */
    2104             :                                                 break;
    2105             :                                         }
    2106             : #endif
    2107             :                                         if (sin->sin_addr.s_addr ==
    2108             :                                             laddr->ifa->address.sin.sin_addr.s_addr) {
    2109             :                                                 SCTP_INP_RUNLOCK(inp);
    2110             :                                                 return (inp);
    2111             :                                         }
    2112             :                                         break;
    2113             : #endif
    2114             : #ifdef INET6
    2115             :                                 case AF_INET6:
    2116             :                                         intf_addr6 = &laddr->ifa->address.sin6;
    2117             :                                         if (SCTP6_ARE_ADDR_EQUAL(sin6,
    2118             :                                             intf_addr6)) {
    2119             :                                                 SCTP_INP_RUNLOCK(inp);
    2120             :                                                 return (inp);
    2121             :                                         }
    2122             :                                         break;
    2123             : #endif
    2124             : #if defined(__Userspace__)
    2125             :                                 case AF_CONN:
    2126           0 :                                         if (sconn->sconn_addr == laddr->ifa->address.sconn.sconn_addr) {
    2127           0 :                                                 SCTP_INP_RUNLOCK(inp);
    2128           0 :                                                 return (inp);
    2129             :                                         }
    2130           0 :                                         break;
    2131             : #endif
    2132             :                                 }
    2133             :                         }
    2134             :                 }
    2135           0 :                 SCTP_INP_RUNLOCK(inp);
    2136             :         }
    2137           0 :         return (NULL);
    2138             : }
    2139             : 
    2140             : 
    2141             : static struct sctp_inpcb *
    2142           0 : sctp_isport_inuse(struct sctp_inpcb *inp, uint16_t lport, uint32_t vrf_id)
    2143             : {
    2144             :         struct sctppcbhead *head;
    2145             :         struct sctp_inpcb *t_inp;
    2146             : #ifdef SCTP_MVRF
    2147             :         int i;
    2148             : #endif
    2149             :         int fnd;
    2150             : 
    2151           0 :         head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(lport,
    2152             :             SCTP_BASE_INFO(hashmark))];
    2153           0 :         LIST_FOREACH(t_inp, head, sctp_hash) {
    2154           0 :                 if (t_inp->sctp_lport != lport) {
    2155           0 :                         continue;
    2156             :                 }
    2157             :                 /* is it in the VRF in question */
    2158           0 :                 fnd = 0;
    2159             : #ifdef SCTP_MVRF
    2160             :                 for (i = 0; i < inp->num_vrfs; i++) {
    2161             :                         if (t_inp->m_vrf_ids[i] == vrf_id) {
    2162             :                                 fnd = 1;
    2163             :                                 break;
    2164             :                         }
    2165             :                 }
    2166             : #else
    2167           0 :                 if (t_inp->def_vrf_id == vrf_id)
    2168           0 :                         fnd = 1;
    2169             : #endif
    2170           0 :                 if (!fnd)
    2171           0 :                         continue;
    2172             : 
    2173             :                 /* This one is in use. */
    2174             :                 /* check the v6/v4 binding issue */
    2175           0 :                 if ((t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
    2176           0 :                     SCTP_IPV6_V6ONLY(t_inp)) {
    2177           0 :                         if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
    2178             :                                 /* collision in V6 space */
    2179           0 :                                 return (t_inp);
    2180             :                         } else {
    2181             :                                 /* inp is BOUND_V4 no conflict */
    2182           0 :                                 continue;
    2183             :                         }
    2184           0 :                 } else if (t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
    2185             :                         /* t_inp is bound v4 and v6, conflict always */
    2186           0 :                         return (t_inp);
    2187             :                 } else {
    2188             :                         /* t_inp is bound only V4 */
    2189           0 :                         if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
    2190           0 :                             SCTP_IPV6_V6ONLY(inp)) {
    2191             :                                 /* no conflict */
    2192           0 :                                 continue;
    2193             :                         }
    2194             :                         /* else fall through to conflict */
    2195             :                 }
    2196           0 :                 return (t_inp);
    2197             :         }
    2198           0 :         return (NULL);
    2199             : }
    2200             : 
    2201             : 
    2202             : int
    2203           0 : sctp_swap_inpcb_for_listen(struct sctp_inpcb *inp)
    2204             : {
    2205             :         /* For 1-2-1 with port reuse */
    2206             :         struct sctppcbhead *head;
    2207             :         struct sctp_inpcb *tinp, *ninp;
    2208             : 
    2209           0 :         if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE)) {
    2210             :                 /* only works with port reuse on */
    2211           0 :                 return (-1);
    2212             :         }
    2213           0 :         if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) {
    2214           0 :                 return (0);
    2215             :         }
    2216           0 :         SCTP_INP_RUNLOCK(inp);
    2217           0 :         SCTP_INP_INFO_WLOCK();
    2218           0 :         head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(inp->sctp_lport,
    2219             :                                             SCTP_BASE_INFO(hashmark))];
    2220             :         /* Kick out all non-listeners to the TCP hash */
    2221           0 :         LIST_FOREACH_SAFE(tinp, head, sctp_hash, ninp) {
    2222           0 :                 if (tinp->sctp_lport != inp->sctp_lport) {
    2223           0 :                         continue;
    2224             :                 }
    2225           0 :                 if (tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
    2226           0 :                         continue;
    2227             :                 }
    2228           0 :                 if (tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
    2229           0 :                         continue;
    2230             :                 }
    2231           0 :                 if (tinp->sctp_socket->so_qlimit) {
    2232           0 :                         continue;
    2233             :                 }
    2234           0 :                 SCTP_INP_WLOCK(tinp);
    2235           0 :                 LIST_REMOVE(tinp, sctp_hash);
    2236           0 :                 head = &SCTP_BASE_INFO(sctp_tcpephash)[SCTP_PCBHASH_ALLADDR(tinp->sctp_lport, SCTP_BASE_INFO(hashtcpmark))];
    2237           0 :                 tinp->sctp_flags |= SCTP_PCB_FLAGS_IN_TCPPOOL;
    2238           0 :                 LIST_INSERT_HEAD(head, tinp, sctp_hash);
    2239           0 :                 SCTP_INP_WUNLOCK(tinp);
    2240             :         }
    2241           0 :         SCTP_INP_WLOCK(inp);
    2242             :         /* Pull from where he was */
    2243           0 :         LIST_REMOVE(inp, sctp_hash);
    2244           0 :         inp->sctp_flags &= ~SCTP_PCB_FLAGS_IN_TCPPOOL;
    2245           0 :         head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(inp->sctp_lport, SCTP_BASE_INFO(hashmark))];
    2246           0 :         LIST_INSERT_HEAD(head, inp, sctp_hash);
    2247           0 :         SCTP_INP_WUNLOCK(inp);
    2248           0 :         SCTP_INP_RLOCK(inp);
    2249           0 :         SCTP_INP_INFO_WUNLOCK();
    2250           0 :         return (0);
    2251             : }
    2252             : 
    2253             : 
    2254             : struct sctp_inpcb *
    2255           0 : sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock,
    2256             :                 uint32_t vrf_id)
    2257             : {
    2258             :         /*
    2259             :          * First we check the hash table to see if someone has this port
    2260             :          * bound with just the port.
    2261             :          */
    2262             :         struct sctp_inpcb *inp;
    2263             :         struct sctppcbhead *head;
    2264             :         int lport;
    2265             :         unsigned int i;
    2266             : #ifdef INET
    2267             :         struct sockaddr_in *sin;
    2268             : #endif
    2269             : #ifdef INET6
    2270             :         struct sockaddr_in6 *sin6;
    2271             : #endif
    2272             : #if defined(__Userspace__)
    2273             :         struct sockaddr_conn *sconn;
    2274             : #endif
    2275             : 
    2276           0 :         switch (nam->sa_family) {
    2277             : #ifdef INET
    2278             :         case AF_INET:
    2279             :                 sin = (struct sockaddr_in *)nam;
    2280             :                 lport = sin->sin_port;
    2281             :                 break;
    2282             : #endif
    2283             : #ifdef INET6
    2284             :         case AF_INET6:
    2285             :                 sin6 = (struct sockaddr_in6 *)nam;
    2286             :                 lport = sin6->sin6_port;
    2287             :                 break;
    2288             : #endif
    2289             : #if defined(__Userspace__)
    2290             :         case AF_CONN:
    2291           0 :                 sconn = (struct sockaddr_conn *)nam;
    2292           0 :                 lport = sconn->sconn_port;
    2293           0 :                 break;
    2294             : #endif
    2295             :         default:
    2296           0 :                 return (NULL);
    2297             :         }
    2298             :         /*
    2299             :          * I could cheat here and just cast to one of the types but we will
    2300             :          * do it right. It also provides the check against an Unsupported
    2301             :          * type too.
    2302             :          */
    2303             :         /* Find the head of the ALLADDR chain */
    2304           0 :         if (have_lock == 0) {
    2305           0 :                 SCTP_INP_INFO_RLOCK();
    2306             :         }
    2307           0 :         head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(lport,
    2308             :             SCTP_BASE_INFO(hashmark))];
    2309           0 :         inp = sctp_endpoint_probe(nam, head, lport, vrf_id);
    2310             : 
    2311             :         /*
    2312             :          * If the TCP model exists it could be that the main listening
    2313             :          * endpoint is gone but there still exists a connected socket for this
    2314             :          * guy. If so we can return the first one that we find. This may NOT
    2315             :          * be the correct one so the caller should be wary on the returned INP.
    2316             :          * Currently the only caller that sets find_tcp_pool is in bindx where
    2317             :          * we are verifying that a user CAN bind the address. He either
    2318             :          * has bound it already, or someone else has, or its open to bind,
    2319             :          * so this is good enough.
    2320             :          */
    2321           0 :         if (inp == NULL && find_tcp_pool) {
    2322           0 :                 for (i = 0; i < SCTP_BASE_INFO(hashtcpmark) + 1; i++) {
    2323           0 :                         head = &SCTP_BASE_INFO(sctp_tcpephash)[i];
    2324           0 :                         inp = sctp_endpoint_probe(nam, head, lport, vrf_id);
    2325           0 :                         if (inp) {
    2326           0 :                                 break;
    2327             :                         }
    2328             :                 }
    2329             :         }
    2330           0 :         if (inp) {
    2331           0 :                 SCTP_INP_INCR_REF(inp);
    2332             :         }
    2333           0 :         if (have_lock == 0) {
    2334           0 :                 SCTP_INP_INFO_RUNLOCK();
    2335             :         }
    2336           0 :         return (inp);
    2337             : }
    2338             : 
    2339             : 
    2340             : /*
    2341             :  * Find an association for an endpoint with the pointer to whom you want to
    2342             :  * send to and the endpoint pointer. The address can be IPv4 or IPv6. We may
    2343             :  * need to change the *to to some other struct like a mbuf...
    2344             :  */
    2345             : struct sctp_tcb *
    2346           0 : sctp_findassociation_addr_sa(struct sockaddr *from, struct sockaddr *to,
    2347             :     struct sctp_inpcb **inp_p, struct sctp_nets **netp, int find_tcp_pool,
    2348             :     uint32_t vrf_id)
    2349             : {
    2350           0 :         struct sctp_inpcb *inp = NULL;
    2351             :         struct sctp_tcb *stcb;
    2352             : 
    2353           0 :         SCTP_INP_INFO_RLOCK();
    2354           0 :         if (find_tcp_pool) {
    2355           0 :                 if (inp_p != NULL) {
    2356           0 :                         stcb = sctp_tcb_special_locate(inp_p, from, to, netp,
    2357             :                                                        vrf_id);
    2358             :                 } else {
    2359           0 :                         stcb = sctp_tcb_special_locate(&inp, from, to, netp,
    2360             :                                                        vrf_id);
    2361             :                 }
    2362           0 :                 if (stcb != NULL) {
    2363           0 :                         SCTP_INP_INFO_RUNLOCK();
    2364           0 :                         return (stcb);
    2365             :                 }
    2366             :         }
    2367           0 :         inp = sctp_pcb_findep(to, 0, 1, vrf_id);
    2368           0 :         if (inp_p != NULL) {
    2369           0 :                 *inp_p = inp;
    2370             :         }
    2371           0 :         SCTP_INP_INFO_RUNLOCK();
    2372           0 :         if (inp == NULL) {
    2373           0 :                 return (NULL);
    2374             :         }
    2375             :         /*
    2376             :          * ok, we have an endpoint, now lets find the assoc for it (if any)
    2377             :          * we now place the source address or from in the to of the find
    2378             :          * endpoint call. Since in reality this chain is used from the
    2379             :          * inbound packet side.
    2380             :          */
    2381           0 :         if (inp_p != NULL) {
    2382           0 :                 stcb = sctp_findassociation_ep_addr(inp_p, from, netp, to,
    2383             :                                                     NULL);
    2384             :         } else {
    2385           0 :                 stcb = sctp_findassociation_ep_addr(&inp, from, netp, to,
    2386             :                                                     NULL);
    2387             :         }
    2388           0 :         return (stcb);
    2389             : }
    2390             : 
    2391             : 
    2392             : /*
    2393             :  * This routine will grub through the mbuf that is a INIT or INIT-ACK and
    2394             :  * find all addresses that the sender has specified in any address list. Each
    2395             :  * address will be used to lookup the TCB and see if one exits.
    2396             :  */
    2397             : static struct sctp_tcb *
    2398           0 : sctp_findassociation_special_addr(struct mbuf *m, int offset,
    2399             :     struct sctphdr *sh, struct sctp_inpcb **inp_p, struct sctp_nets **netp,
    2400             :     struct sockaddr *dst)
    2401             : {
    2402             :         struct sctp_paramhdr *phdr, parm_buf;
    2403             : #if defined(INET) || defined(INET6)
    2404             :         struct sctp_tcb *stcb;
    2405             :         uint16_t ptype;
    2406             : #endif
    2407             :         uint16_t plen;
    2408             : #ifdef INET
    2409             :         struct sockaddr_in sin4;
    2410             : #endif
    2411             : #ifdef INET6
    2412             :         struct sockaddr_in6 sin6;
    2413             : #endif
    2414             : 
    2415             : #ifdef INET
    2416             :         memset(&sin4, 0, sizeof(sin4));
    2417             : #ifdef HAVE_SIN_LEN
    2418             :         sin4.sin_len = sizeof(sin4);
    2419             : #endif
    2420             :         sin4.sin_family = AF_INET;
    2421             :         sin4.sin_port = sh->src_port;
    2422             : #endif
    2423             : #ifdef INET6
    2424             :         memset(&sin6, 0, sizeof(sin6));
    2425             : #ifdef HAVE_SIN6_LEN
    2426             :         sin6.sin6_len = sizeof(sin6);
    2427             : #endif
    2428             :         sin6.sin6_family = AF_INET6;
    2429             :         sin6.sin6_port = sh->src_port;
    2430             : #endif
    2431             : 
    2432           0 :         offset += sizeof(struct sctp_init_chunk);
    2433             : 
    2434           0 :         phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
    2435           0 :         while (phdr != NULL) {
    2436             :                 /* now we must see if we want the parameter */
    2437             : #if defined(INET) || defined(INET6)
    2438             :                 ptype = ntohs(phdr->param_type);
    2439             : #endif
    2440           0 :                 plen = ntohs(phdr->param_length);
    2441           0 :                 if (plen == 0) {
    2442           0 :                         break;
    2443             :                 }
    2444             : #ifdef INET
    2445             :                 if (ptype == SCTP_IPV4_ADDRESS &&
    2446             :                     plen == sizeof(struct sctp_ipv4addr_param)) {
    2447             :                         /* Get the rest of the address */
    2448             :                         struct sctp_ipv4addr_param ip4_parm, *p4;
    2449             : 
    2450             :                         phdr = sctp_get_next_param(m, offset,
    2451             :                             (struct sctp_paramhdr *)&ip4_parm, min(plen, sizeof(ip4_parm)));
    2452             :                         if (phdr == NULL) {
    2453             :                                 return (NULL);
    2454             :                         }
    2455             :                         p4 = (struct sctp_ipv4addr_param *)phdr;
    2456             :                         memcpy(&sin4.sin_addr, &p4->addr, sizeof(p4->addr));
    2457             :                         /* look it up */
    2458             :                         stcb = sctp_findassociation_ep_addr(inp_p,
    2459             :                             (struct sockaddr *)&sin4, netp, dst, NULL);
    2460             :                         if (stcb != NULL) {
    2461             :                                 return (stcb);
    2462             :                         }
    2463             :                 }
    2464             : #endif
    2465             : #ifdef INET6
    2466             :                 if (ptype == SCTP_IPV6_ADDRESS &&
    2467             :                     plen == sizeof(struct sctp_ipv6addr_param)) {
    2468             :                         /* Get the rest of the address */
    2469             :                         struct sctp_ipv6addr_param ip6_parm, *p6;
    2470             : 
    2471             :                         phdr = sctp_get_next_param(m, offset,
    2472             :                             (struct sctp_paramhdr *)&ip6_parm, min(plen,sizeof(ip6_parm)));
    2473             :                         if (phdr == NULL) {
    2474             :                                 return (NULL);
    2475             :                         }
    2476             :                         p6 = (struct sctp_ipv6addr_param *)phdr;
    2477             :                         memcpy(&sin6.sin6_addr, &p6->addr, sizeof(p6->addr));
    2478             :                         /* look it up */
    2479             :                         stcb = sctp_findassociation_ep_addr(inp_p,
    2480             :                             (struct sockaddr *)&sin6, netp, dst, NULL);
    2481             :                         if (stcb != NULL) {
    2482             :                                 return (stcb);
    2483             :                         }
    2484             :                 }
    2485             : #endif
    2486           0 :                 offset += SCTP_SIZE32(plen);
    2487           0 :                 phdr = sctp_get_next_param(m, offset, &parm_buf,
    2488             :                                            sizeof(parm_buf));
    2489             :         }
    2490           0 :         return (NULL);
    2491             : }
    2492             : 
    2493             : static struct sctp_tcb *
    2494           0 : sctp_findassoc_by_vtag(struct sockaddr *from, struct sockaddr *to, uint32_t vtag,
    2495             :                        struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint16_t rport,
    2496             :                        uint16_t lport, int skip_src_check, uint32_t vrf_id, uint32_t remote_tag)
    2497             : {
    2498             :         /*
    2499             :          * Use my vtag to hash. If we find it we then verify the source addr
    2500             :          * is in the assoc. If all goes well we save a bit on rec of a
    2501             :          * packet.
    2502             :          */
    2503             :         struct sctpasochead *head;
    2504             :         struct sctp_nets *net;
    2505             :         struct sctp_tcb *stcb;
    2506             : #ifdef SCTP_MVRF
    2507             :         unsigned int i;
    2508             : #endif
    2509             : 
    2510           0 :         SCTP_INP_INFO_RLOCK();
    2511           0 :         head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(vtag,
    2512             :                                                                 SCTP_BASE_INFO(hashasocmark))];
    2513           0 :         LIST_FOREACH(stcb, head, sctp_asocs) {
    2514           0 :                 SCTP_INP_RLOCK(stcb->sctp_ep);
    2515           0 :                 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
    2516           0 :                         SCTP_INP_RUNLOCK(stcb->sctp_ep);
    2517           0 :                         continue;
    2518             :                 }
    2519             : #ifdef SCTP_MVRF
    2520             :                 for (i = 0; i < stcb->sctp_ep->num_vrfs; i++) {
    2521             :                         if (stcb->sctp_ep->m_vrf_ids[i] == vrf_id) {
    2522             :                                 break;
    2523             :                         }
    2524             :                 }
    2525             :                 if (i == stcb->sctp_ep->num_vrfs) {
    2526             :                         SCTP_INP_RUNLOCK(inp);
    2527             :                         continue;
    2528             :                 }
    2529             : #else
    2530           0 :                 if (stcb->sctp_ep->def_vrf_id != vrf_id) {
    2531           0 :                         SCTP_INP_RUNLOCK(stcb->sctp_ep);
    2532           0 :                         continue;
    2533             :                 }
    2534             : #endif
    2535           0 :                 SCTP_TCB_LOCK(stcb);
    2536           0 :                 SCTP_INP_RUNLOCK(stcb->sctp_ep);
    2537           0 :                 if (stcb->asoc.my_vtag == vtag) {
    2538             :                         /* candidate */
    2539           0 :                         if (stcb->rport != rport) {
    2540           0 :                                 SCTP_TCB_UNLOCK(stcb);
    2541           0 :                                 continue;
    2542             :                         }
    2543           0 :                         if (stcb->sctp_ep->sctp_lport != lport) {
    2544           0 :                                 SCTP_TCB_UNLOCK(stcb);
    2545           0 :                                 continue;
    2546             :                         }
    2547           0 :                         if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
    2548           0 :                                 SCTP_TCB_UNLOCK(stcb);
    2549           0 :                                 continue;
    2550             :                         }
    2551             :                         /* RRS:Need toaddr check here */
    2552           0 :                         if (sctp_does_stcb_own_this_addr(stcb, to) == 0) {
    2553             :                                 /* Endpoint does not own this address */
    2554           0 :                                 SCTP_TCB_UNLOCK(stcb);
    2555           0 :                                 continue;
    2556             :                         }
    2557           0 :                         if (remote_tag) {
    2558             :                                 /* If we have both vtags that's all we match on */
    2559           0 :                                 if (stcb->asoc.peer_vtag == remote_tag) {
    2560             :                                         /* If both tags match we consider it conclusive
    2561             :                                          * and check NO source/destination addresses
    2562             :                                          */
    2563           0 :                                         goto conclusive;
    2564             :                                 }
    2565             :                         }
    2566           0 :                         if (skip_src_check) {
    2567             :                         conclusive:
    2568           0 :                                 if (from) {
    2569           0 :                                         *netp = sctp_findnet(stcb, from);
    2570             :                                 } else {
    2571           0 :                                         *netp = NULL;   /* unknown */
    2572             :                                 }
    2573           0 :                                 if (inp_p)
    2574           0 :                                         *inp_p = stcb->sctp_ep;
    2575           0 :                                 SCTP_INP_INFO_RUNLOCK();
    2576           0 :                                 return (stcb);
    2577             :                         }
    2578           0 :                         net = sctp_findnet(stcb, from);
    2579           0 :                         if (net) {
    2580             :                                 /* yep its him. */
    2581           0 :                                 *netp = net;
    2582           0 :                                 SCTP_STAT_INCR(sctps_vtagexpress);
    2583           0 :                                 *inp_p = stcb->sctp_ep;
    2584           0 :                                 SCTP_INP_INFO_RUNLOCK();
    2585           0 :                                 return (stcb);
    2586             :                         } else {
    2587             :                                 /*
    2588             :                                  * not him, this should only happen in rare
    2589             :                                  * cases so I peg it.
    2590             :                                  */
    2591           0 :                                 SCTP_STAT_INCR(sctps_vtagbogus);
    2592             :                         }
    2593             :                 }
    2594           0 :                 SCTP_TCB_UNLOCK(stcb);
    2595             :         }
    2596           0 :         SCTP_INP_INFO_RUNLOCK();
    2597           0 :         return (NULL);
    2598             : }
    2599             : 
    2600             : 
    2601             : /*
    2602             :  * Find an association with the pointer to the inbound IP packet. This can be
    2603             :  * a IPv4 or IPv6 packet.
    2604             :  */
    2605             : struct sctp_tcb *
    2606           0 : sctp_findassociation_addr(struct mbuf *m, int offset,
    2607             :     struct sockaddr *src, struct sockaddr *dst,
    2608             :     struct sctphdr *sh, struct sctp_chunkhdr *ch,
    2609             :     struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id)
    2610             : {
    2611             :         int find_tcp_pool;
    2612             :         struct sctp_tcb *stcb;
    2613             :         struct sctp_inpcb *inp;
    2614             : 
    2615           0 :         if (sh->v_tag) {
    2616             :                 /* we only go down this path if vtag is non-zero */
    2617           0 :                 stcb = sctp_findassoc_by_vtag(src, dst, ntohl(sh->v_tag),
    2618           0 :                                               inp_p, netp, sh->src_port, sh->dest_port, 0, vrf_id, 0);
    2619           0 :                 if (stcb) {
    2620           0 :                         return (stcb);
    2621             :                 }
    2622             :         }
    2623             : 
    2624           0 :         find_tcp_pool = 0;
    2625           0 :         if ((ch->chunk_type != SCTP_INITIATION) &&
    2626           0 :             (ch->chunk_type != SCTP_INITIATION_ACK) &&
    2627           0 :             (ch->chunk_type != SCTP_COOKIE_ACK) &&
    2628           0 :             (ch->chunk_type != SCTP_COOKIE_ECHO)) {
    2629             :                 /* Other chunk types go to the tcp pool. */
    2630           0 :                 find_tcp_pool = 1;
    2631             :         }
    2632           0 :         if (inp_p) {
    2633           0 :                 stcb = sctp_findassociation_addr_sa(src, dst, inp_p, netp,
    2634             :                                                     find_tcp_pool, vrf_id);
    2635           0 :                 inp = *inp_p;
    2636             :         } else {
    2637           0 :                 stcb = sctp_findassociation_addr_sa(src, dst, &inp, netp,
    2638             :                                                     find_tcp_pool, vrf_id);
    2639             :         }
    2640           0 :         SCTPDBG(SCTP_DEBUG_PCB1, "stcb:%p inp:%p\n", (void *)stcb, (void *)inp);
    2641           0 :         if (stcb == NULL && inp) {
    2642             :                 /* Found a EP but not this address */
    2643           0 :                 if ((ch->chunk_type == SCTP_INITIATION) ||
    2644           0 :                     (ch->chunk_type == SCTP_INITIATION_ACK)) {
    2645             :                         /*-
    2646             :                          * special hook, we do NOT return linp or an
    2647             :                          * association that is linked to an existing
    2648             :                          * association that is under the TCP pool (i.e. no
    2649             :                          * listener exists). The endpoint finding routine
    2650             :                          * will always find a listener before examining the
    2651             :                          * TCP pool.
    2652             :                          */
    2653           0 :                         if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) {
    2654           0 :                                 if (inp_p) {
    2655           0 :                                         *inp_p = NULL;
    2656             :                                 }
    2657           0 :                                 return (NULL);
    2658             :                         }
    2659           0 :                         stcb = sctp_findassociation_special_addr(m,
    2660             :                             offset, sh, &inp, netp, dst);
    2661           0 :                         if (inp_p != NULL) {
    2662           0 :                                 *inp_p = inp;
    2663             :                         }
    2664             :                 }
    2665             :         }
    2666           0 :         SCTPDBG(SCTP_DEBUG_PCB1, "stcb is %p\n", (void *)stcb);
    2667           0 :         return (stcb);
    2668             : }
    2669             : 
    2670             : /*
    2671             :  * lookup an association by an ASCONF lookup address.
    2672             :  * if the lookup address is 0.0.0.0 or ::0, use the vtag to do the lookup
    2673             :  */
    2674             : struct sctp_tcb *
    2675           0 : sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
    2676             :                                struct sockaddr *dst, struct sctphdr *sh,
    2677             :                                struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id)
    2678             : {
    2679             :         struct sctp_tcb *stcb;
    2680             :         union sctp_sockstore remote_store;
    2681             :         struct sctp_paramhdr parm_buf, *phdr;
    2682             :         int ptype;
    2683           0 :         int zero_address = 0;
    2684             : #ifdef INET
    2685             :         struct sockaddr_in *sin;
    2686             : #endif
    2687             : #ifdef INET6
    2688             :         struct sockaddr_in6 *sin6;
    2689             : #endif
    2690             : 
    2691           0 :         memset(&remote_store, 0, sizeof(remote_store));
    2692           0 :         phdr = sctp_get_next_param(m, offset + sizeof(struct sctp_asconf_chunk),
    2693             :                                    &parm_buf, sizeof(struct sctp_paramhdr));
    2694           0 :         if (phdr == NULL) {
    2695           0 :                 SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf lookup addr\n",
    2696             :                         __FUNCTION__);
    2697           0 :                 return NULL;
    2698             :         }
    2699           0 :         ptype = (int)((uint32_t) ntohs(phdr->param_type));
    2700             :         /* get the correlation address */
    2701             :         switch (ptype) {
    2702             : #ifdef INET6
    2703             :         case SCTP_IPV6_ADDRESS:
    2704             :         {
    2705             :                 /* ipv6 address param */
    2706             :                 struct sctp_ipv6addr_param *p6, p6_buf;
    2707             : 
    2708             :                 if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv6addr_param)) {
    2709             :                         return NULL;
    2710             :                 }
    2711             :                 p6 = (struct sctp_ipv6addr_param *)sctp_get_next_param(m,
    2712             :                                                                        offset + sizeof(struct sctp_asconf_chunk),
    2713             :                                                                        &p6_buf.ph, sizeof(*p6));
    2714             :                 if (p6 == NULL) {
    2715             :                         SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf v6 lookup addr\n",
    2716             :                                 __FUNCTION__);
    2717             :                         return (NULL);
    2718             :                 }
    2719             :                 sin6 = &remote_store.sin6;
    2720             :                 sin6->sin6_family = AF_INET6;
    2721             : #ifdef HAVE_SIN6_LEN
    2722             :                 sin6->sin6_len = sizeof(*sin6);
    2723             : #endif
    2724             :                 sin6->sin6_port = sh->src_port;
    2725             :                 memcpy(&sin6->sin6_addr, &p6->addr, sizeof(struct in6_addr));
    2726             :                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
    2727             :                         zero_address = 1;
    2728             :                 break;
    2729             :         }
    2730             : #endif
    2731             : #ifdef INET
    2732             :         case SCTP_IPV4_ADDRESS:
    2733             :         {
    2734             :                 /* ipv4 address param */
    2735             :                 struct sctp_ipv4addr_param *p4, p4_buf;
    2736             : 
    2737             :                 if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv4addr_param)) {
    2738             :                         return NULL;
    2739             :                 }
    2740             :                 p4 = (struct sctp_ipv4addr_param *)sctp_get_next_param(m,
    2741             :                                                                        offset + sizeof(struct sctp_asconf_chunk),
    2742             :                                                                        &p4_buf.ph, sizeof(*p4));
    2743             :                 if (p4 == NULL) {
    2744             :                         SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf v4 lookup addr\n",
    2745             :                                 __FUNCTION__);
    2746             :                         return (NULL);
    2747             :                 }
    2748             :                 sin = &remote_store.sin;
    2749             :                 sin->sin_family = AF_INET;
    2750             : #ifdef HAVE_SIN_LEN
    2751             :                 sin->sin_len = sizeof(*sin);
    2752             : #endif
    2753             :                 sin->sin_port = sh->src_port;
    2754             :                 memcpy(&sin->sin_addr, &p4->addr, sizeof(struct in_addr));
    2755             :                 if (sin->sin_addr.s_addr == INADDR_ANY)
    2756             :                         zero_address = 1;
    2757             :                 break;
    2758             :         }
    2759             : #endif
    2760             :         default:
    2761             :                 /* invalid address param type */
    2762           0 :                 return NULL;
    2763             :         }
    2764             : 
    2765             :         if (zero_address) {
    2766             :                 stcb = sctp_findassoc_by_vtag(NULL, dst, ntohl(sh->v_tag), inp_p,
    2767             :                                               netp, sh->src_port, sh->dest_port, 1, vrf_id, 0);
    2768             :                 if (stcb != NULL) {
    2769             :                         SCTP_INP_DECR_REF(*inp_p);
    2770             :                 }
    2771             :         } else {
    2772             :                 stcb = sctp_findassociation_ep_addr(inp_p,
    2773             :                     &remote_store.sa, netp,
    2774             :                     dst, NULL);
    2775             :         }
    2776             :         return (stcb);
    2777             : }
    2778             : 
    2779             : 
    2780             : /*
    2781             :  * allocate a sctp_inpcb and setup a temporary binding to a port/all
    2782             :  * addresses. This way if we don't get a bind we by default pick a ephemeral
    2783             :  * port with all addresses bound.
    2784             :  */
    2785             : int
    2786           0 : sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
    2787             : {
    2788             :         /*
    2789             :          * we get called when a new endpoint starts up. We need to allocate
    2790             :          * the sctp_inpcb structure from the zone and init it. Mark it as
    2791             :          * unbound and find a port that we can use as an ephemeral with
    2792             :          * INADDR_ANY. If the user binds later no problem we can then add in
    2793             :          * the specific addresses. And setup the default parameters for the
    2794             :          * EP.
    2795             :          */
    2796             :         int i, error;
    2797             :         struct sctp_inpcb *inp;
    2798             :         struct sctp_pcb *m;
    2799             :         struct timeval time;
    2800             :         sctp_sharedkey_t *null_key;
    2801             : 
    2802           0 :         error = 0;
    2803             : 
    2804           0 :         SCTP_INP_INFO_WLOCK();
    2805           0 :         inp = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_ep), struct sctp_inpcb);
    2806           0 :         if (inp == NULL) {
    2807           0 :                 SCTP_PRINTF("Out of SCTP-INPCB structures - no resources\n");
    2808           0 :                 SCTP_INP_INFO_WUNLOCK();
    2809             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
    2810           0 :                 return (ENOBUFS);
    2811             :         }
    2812             :         /* zap it */
    2813           0 :         bzero(inp, sizeof(*inp));
    2814             : 
    2815             :         /* bump generations */
    2816             : #if defined(__APPLE__)
    2817             :         inp->ip_inp.inp.inp_state = INPCB_STATE_INUSE;
    2818             : #endif
    2819             :         /* setup socket pointers */
    2820           0 :         inp->sctp_socket = so;
    2821           0 :         inp->ip_inp.inp.inp_socket = so;
    2822             : #if defined(__FreeBSD__)
    2823             :         inp->ip_inp.inp.inp_cred = crhold(so->so_cred);
    2824             : #endif
    2825             : #ifdef INET6
    2826             : #if !defined(__Userspace__) && !defined(__Windows__)
    2827             :         if (INP_SOCKAF(so) == AF_INET6) {
    2828             :                 if (MODULE_GLOBAL(ip6_auto_flowlabel)) {
    2829             :                         inp->ip_inp.inp.inp_flags |= IN6P_AUTOFLOWLABEL;
    2830             :                 }
    2831             :                 if (MODULE_GLOBAL(ip6_v6only)) {
    2832             :                         inp->ip_inp.inp.inp_flags |= IN6P_IPV6_V6ONLY;
    2833             :                 }
    2834             :         }
    2835             : #endif
    2836             : #endif
    2837           0 :         inp->sctp_associd_counter = 1;
    2838           0 :         inp->partial_delivery_point = SCTP_SB_LIMIT_RCV(so) >> SCTP_PARTIAL_DELIVERY_SHIFT;
    2839           0 :         inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT;
    2840           0 :         inp->max_cwnd = 0;
    2841           0 :         inp->sctp_cmt_on_off = SCTP_BASE_SYSCTL(sctp_cmt_on_off);
    2842           0 :         inp->ecn_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_ecn_enable);
    2843           0 :         inp->prsctp_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pr_enable);
    2844           0 :         inp->auth_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_auth_enable);
    2845           0 :         inp->asconf_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_asconf_enable);
    2846           0 :         inp->reconfig_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_reconfig_enable);
    2847           0 :         inp->nrsack_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_nrsack_enable);
    2848           0 :         inp->pktdrop_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pktdrop_enable);
    2849             : #if defined(__Userspace__)
    2850           0 :         inp->ulp_info = NULL;
    2851           0 :         inp->recv_callback = NULL;
    2852           0 :         inp->send_callback = NULL;
    2853           0 :         inp->send_sb_threshold = 0;
    2854             : #endif
    2855             :         /* init the small hash table we use to track asocid <-> tcb */
    2856           0 :         inp->sctp_asocidhash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, &inp->hashasocidmark);
    2857           0 :         if (inp->sctp_asocidhash == NULL) {
    2858             : #if defined(__FreeBSD__)
    2859             :                 crfree(inp->ip_inp.inp.inp_cred);
    2860             : #endif
    2861           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
    2862           0 :                 SCTP_INP_INFO_WUNLOCK();
    2863           0 :                 return (ENOBUFS);
    2864             :         }
    2865             : #ifdef IPSEC
    2866             : #if !(defined(__APPLE__))
    2867             :         {
    2868             :                 struct inpcbpolicy *pcb_sp = NULL;
    2869             : 
    2870             :                 error = ipsec_init_policy(so, &pcb_sp);
    2871             :                 /* Arrange to share the policy */
    2872             :                 inp->ip_inp.inp.inp_sp = pcb_sp;
    2873             :                 ((struct in6pcb *)(&inp->ip_inp.inp))->in6p_sp = pcb_sp;
    2874             :         }
    2875             : #else
    2876             :         /* not sure what to do for openbsd here */
    2877             :         error = 0;
    2878             : #endif
    2879             :         if (error != 0) {
    2880             : #if defined(__FreeBSD__)
    2881             :                 crfree(inp->ip_inp.inp.inp_cred);
    2882             : #endif
    2883             :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
    2884             :                 SCTP_INP_INFO_WUNLOCK();
    2885             :                 return error;
    2886             :         }
    2887             : #endif                          /* IPSEC */
    2888           0 :         SCTP_INCR_EP_COUNT();
    2889           0 :         inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
    2890           0 :         SCTP_INP_INFO_WUNLOCK();
    2891             : 
    2892           0 :         so->so_pcb = (caddr_t)inp;
    2893             : 
    2894             : #if defined(__FreeBSD__) && __FreeBSD_version < 803000
    2895             :         if ((SCTP_SO_TYPE(so) == SOCK_DGRAM) ||
    2896             :             (SCTP_SO_TYPE(so) == SOCK_SEQPACKET)) {
    2897             : #else
    2898           0 :         if (SCTP_SO_TYPE(so) == SOCK_SEQPACKET) {
    2899             : #endif
    2900             :                 /* UDP style socket */
    2901           0 :                 inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |
    2902             :                     SCTP_PCB_FLAGS_UNBOUND);
    2903             :                 /* Be sure it is NON-BLOCKING IO for UDP */
    2904             :                 /* SCTP_SET_SO_NBIO(so); */
    2905           0 :         } else if (SCTP_SO_TYPE(so) == SOCK_STREAM) {
    2906             :                 /* TCP style socket */
    2907           0 :                 inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE |
    2908             :                     SCTP_PCB_FLAGS_UNBOUND);
    2909             :                 /* Be sure we have blocking IO by default */
    2910           0 :                 SCTP_CLEAR_SO_NBIO(so);
    2911             : #if defined(__Panda__)
    2912             :         } else if (SCTP_SO_TYPE(so) == SOCK_FASTSEQPACKET) {
    2913             :                 inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |
    2914             :                     SCTP_PCB_FLAGS_UNBOUND);
    2915             :                 sctp_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE);
    2916             :         } else if (SCTP_SO_TYPE(so) == SOCK_FASTSTREAM) {
    2917             :                 inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE |
    2918             :                     SCTP_PCB_FLAGS_UNBOUND);
    2919             :                 sctp_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE);
    2920             : #endif
    2921             :         } else {
    2922             :                 /*
    2923             :                  * unsupported socket type (RAW, etc)- in case we missed it
    2924             :                  * in protosw
    2925             :                  */
    2926             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EOPNOTSUPP);
    2927           0 :                 so->so_pcb = NULL;
    2928             : #if defined(__FreeBSD__)
    2929             :                 crfree(inp->ip_inp.inp.inp_cred);
    2930             : #endif
    2931           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
    2932           0 :                 return (EOPNOTSUPP);
    2933             :         }
    2934           0 :         if (SCTP_BASE_SYSCTL(sctp_default_frag_interleave) == SCTP_FRAG_LEVEL_1) {
    2935           0 :                 sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
    2936           0 :                 sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
    2937           0 :         } else if (SCTP_BASE_SYSCTL(sctp_default_frag_interleave) == SCTP_FRAG_LEVEL_2) {
    2938           0 :                 sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
    2939           0 :                 sctp_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
    2940           0 :         } else if (SCTP_BASE_SYSCTL(sctp_default_frag_interleave) == SCTP_FRAG_LEVEL_0) {
    2941           0 :                 sctp_feature_off(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
    2942           0 :                 sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
    2943             :         }
    2944           0 :         inp->sctp_tcbhash = SCTP_HASH_INIT(SCTP_BASE_SYSCTL(sctp_pcbtblsize),
    2945             :                                            &inp->sctp_hashmark);
    2946           0 :         if (inp->sctp_tcbhash == NULL) {
    2947           0 :                 SCTP_PRINTF("Out of SCTP-INPCB->hashinit - no resources\n");
    2948             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
    2949           0 :                 so->so_pcb = NULL;
    2950             : #if defined(__FreeBSD__)
    2951             :                 crfree(inp->ip_inp.inp.inp_cred);
    2952             : #endif
    2953           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
    2954           0 :                 return (ENOBUFS);
    2955             :         }
    2956             : #ifdef SCTP_MVRF
    2957             :         inp->vrf_size = SCTP_DEFAULT_VRF_SIZE;
    2958             :         SCTP_MALLOC(inp->m_vrf_ids, uint32_t *,
    2959             :                     (sizeof(uint32_t) * inp->vrf_size), SCTP_M_MVRF);
    2960             :         if (inp->m_vrf_ids == NULL) {
    2961             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
    2962             :                 so->so_pcb = NULL;
    2963             :                 SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark);
    2964             : #if defined(__FreeBSD__)
    2965             :                 crfree(inp->ip_inp.inp.inp_cred);
    2966             : #endif
    2967             :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
    2968             :                 return (ENOBUFS);
    2969             :         }
    2970             :         inp->m_vrf_ids[0] = vrf_id;
    2971             :         inp->num_vrfs = 1;
    2972             : #endif
    2973           0 :         inp->def_vrf_id = vrf_id;
    2974             : 
    2975             : #if defined(__APPLE__)
    2976             : #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
    2977             :         inp->ip_inp.inp.inpcb_mtx = lck_mtx_alloc_init(SCTP_BASE_INFO(sctbinfo).mtx_grp, SCTP_BASE_INFO(sctbinfo).mtx_attr);
    2978             :         if (inp->ip_inp.inp.inpcb_mtx == NULL) {
    2979             :                 SCTP_PRINTF("in_pcballoc: can't alloc mutex! so=%p\n", (void *)so);
    2980             : #ifdef SCTP_MVRF
    2981             :                 SCTP_FREE(inp->m_vrf_ids, SCTP_M_MVRF);
    2982             : #endif
    2983             :                 SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark);
    2984             :                 so->so_pcb = NULL;
    2985             : #if defined(__FreeBSD__)
    2986             :                 crfree(inp->ip_inp.inp.inp_cred);
    2987             : #endif
    2988             :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
    2989             :                 SCTP_UNLOCK_EXC(SCTP_BASE_INFO(sctbinfo).ipi_lock);
    2990             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOMEM);
    2991             :                 return (ENOMEM);
    2992             :         }
    2993             : #elif defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
    2994             :         lck_mtx_init(&inp->ip_inp.inp.inpcb_mtx, SCTP_BASE_INFO(sctbinfo).mtx_grp, SCTP_BASE_INFO(sctbinfo).mtx_attr);
    2995             : #else
    2996             :         lck_mtx_init(&inp->ip_inp.inp.inpcb_mtx, SCTP_BASE_INFO(sctbinfo).ipi_lock_grp, SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
    2997             : #endif
    2998             : #endif
    2999           0 :         SCTP_INP_INFO_WLOCK();
    3000           0 :         SCTP_INP_LOCK_INIT(inp);
    3001             : #if defined(__FreeBSD__)
    3002             :         INP_LOCK_INIT(&inp->ip_inp.inp, "inp", "sctpinp");
    3003             : #endif
    3004           0 :         SCTP_INP_READ_INIT(inp);
    3005           0 :         SCTP_ASOC_CREATE_LOCK_INIT(inp);
    3006             :         /* lock the new ep */
    3007           0 :         SCTP_INP_WLOCK(inp);
    3008             : 
    3009             :         /* add it to the info area */
    3010           0 :         LIST_INSERT_HEAD(&SCTP_BASE_INFO(listhead), inp, sctp_list);
    3011             : #if defined(__APPLE__)
    3012             :         inp->ip_inp.inp.inp_pcbinfo = &SCTP_BASE_INFO(sctbinfo);
    3013             : #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
    3014             :         LIST_INSERT_HEAD(SCTP_BASE_INFO(sctbinfo).listhead, &inp->ip_inp.inp, inp_list);
    3015             : #else
    3016             :         LIST_INSERT_HEAD(SCTP_BASE_INFO(sctbinfo).ipi_listhead, &inp->ip_inp.inp, inp_list);
    3017             : #endif
    3018             : #endif
    3019           0 :         SCTP_INP_INFO_WUNLOCK();
    3020             : 
    3021           0 :         TAILQ_INIT(&inp->read_queue);
    3022           0 :         LIST_INIT(&inp->sctp_addr_list);
    3023             : 
    3024           0 :         LIST_INIT(&inp->sctp_asoc_list);
    3025             : 
    3026             : #ifdef SCTP_TRACK_FREED_ASOCS
    3027             :         /* TEMP CODE */
    3028             :         LIST_INIT(&inp->sctp_asoc_free_list);
    3029             : #endif
    3030             :         /* Init the timer structure for signature change */
    3031           0 :         SCTP_OS_TIMER_INIT(&inp->sctp_ep.signature_change.timer);
    3032           0 :         inp->sctp_ep.signature_change.type = SCTP_TIMER_TYPE_NEWCOOKIE;
    3033             : 
    3034             :         /* now init the actual endpoint default data */
    3035           0 :         m = &inp->sctp_ep;
    3036             : 
    3037             :         /* setup the base timeout information */
    3038           0 :         m->sctp_timeoutticks[SCTP_TIMER_SEND] = SEC_TO_TICKS(SCTP_SEND_SEC); /* needed ? */
    3039           0 :         m->sctp_timeoutticks[SCTP_TIMER_INIT] = SEC_TO_TICKS(SCTP_INIT_SEC); /* needed ? */
    3040           0 :         m->sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_delayed_sack_time_default));
    3041           0 :         m->sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_heartbeat_interval_default));
    3042           0 :         m->sctp_timeoutticks[SCTP_TIMER_PMTU] = SEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_pmtu_raise_time_default));
    3043           0 :         m->sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] = SEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_shutdown_guard_time_default));
    3044           0 :         m->sctp_timeoutticks[SCTP_TIMER_SIGNATURE] = SEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_secret_lifetime_default));
    3045             :         /* all max/min max are in ms */
    3046           0 :         m->sctp_maxrto = SCTP_BASE_SYSCTL(sctp_rto_max_default);
    3047           0 :         m->sctp_minrto = SCTP_BASE_SYSCTL(sctp_rto_min_default);
    3048           0 :         m->initial_rto = SCTP_BASE_SYSCTL(sctp_rto_initial_default);
    3049           0 :         m->initial_init_rto_max = SCTP_BASE_SYSCTL(sctp_init_rto_max_default);
    3050           0 :         m->sctp_sack_freq = SCTP_BASE_SYSCTL(sctp_sack_freq_default);
    3051           0 :         m->max_init_times = SCTP_BASE_SYSCTL(sctp_init_rtx_max_default);
    3052           0 :         m->max_send_times = SCTP_BASE_SYSCTL(sctp_assoc_rtx_max_default);
    3053           0 :         m->def_net_failure = SCTP_BASE_SYSCTL(sctp_path_rtx_max_default);
    3054           0 :         m->def_net_pf_threshold = SCTP_BASE_SYSCTL(sctp_path_pf_threshold);
    3055           0 :         m->sctp_sws_sender = SCTP_SWS_SENDER_DEF;
    3056           0 :         m->sctp_sws_receiver = SCTP_SWS_RECEIVER_DEF;
    3057           0 :         m->max_burst = SCTP_BASE_SYSCTL(sctp_max_burst_default);
    3058           0 :         m->fr_max_burst = SCTP_BASE_SYSCTL(sctp_fr_max_burst_default);
    3059             : 
    3060           0 :         m->sctp_default_cc_module = SCTP_BASE_SYSCTL(sctp_default_cc_module);
    3061           0 :         m->sctp_default_ss_module = SCTP_BASE_SYSCTL(sctp_default_ss_module);
    3062           0 :         m->max_open_streams_intome = SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default);
    3063             :         /* number of streams to pre-open on a association */
    3064           0 :         m->pre_open_stream_count = SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default);
    3065             : 
    3066             :         /* Add adaptation cookie */
    3067           0 :         m->adaptation_layer_indicator = 0;
    3068           0 :         m->adaptation_layer_indicator_provided = 0;
    3069             : 
    3070             :         /* seed random number generator */
    3071           0 :         m->random_counter = 1;
    3072           0 :         m->store_at = SCTP_SIGNATURE_SIZE;
    3073           0 :         SCTP_READ_RANDOM(m->random_numbers, sizeof(m->random_numbers));
    3074           0 :         sctp_fill_random_store(m);
    3075             : 
    3076             :         /* Minimum cookie size */
    3077           0 :         m->size_of_a_cookie = (sizeof(struct sctp_init_msg) * 2) +
    3078             :             sizeof(struct sctp_state_cookie);
    3079           0 :         m->size_of_a_cookie += SCTP_SIGNATURE_SIZE;
    3080             : 
    3081             :         /* Setup the initial secret */
    3082           0 :         (void)SCTP_GETTIME_TIMEVAL(&time);
    3083           0 :         m->time_of_secret_change = time.tv_sec;
    3084             : 
    3085           0 :         for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) {
    3086           0 :                 m->secret_key[0][i] = sctp_select_initial_TSN(m);
    3087             :         }
    3088           0 :         sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL);
    3089             : 
    3090             :         /* How long is a cookie good for ? */
    3091           0 :         m->def_cookie_life = MSEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_valid_cookie_life_default));
    3092             :         /*
    3093             :          * Initialize authentication parameters
    3094             :          */
    3095           0 :         m->local_hmacs = sctp_default_supported_hmaclist();
    3096           0 :         m->local_auth_chunks = sctp_alloc_chunklist();
    3097           0 :         if (inp->asconf_supported) {
    3098           0 :                 sctp_auth_add_chunk(SCTP_ASCONF, m->local_auth_chunks);
    3099           0 :                 sctp_auth_add_chunk(SCTP_ASCONF_ACK, m->local_auth_chunks);
    3100             :         }
    3101           0 :         m->default_dscp = 0;
    3102             : #ifdef INET6
    3103             :         m->default_flowlabel = 0;
    3104             : #endif
    3105           0 :         m->port = 0; /* encapsulation disabled by default */
    3106           0 :         LIST_INIT(&m->shared_keys);
    3107             :         /* add default NULL key as key id 0 */
    3108           0 :         null_key = sctp_alloc_sharedkey();
    3109           0 :         sctp_insert_sharedkey(&m->shared_keys, null_key);
    3110           0 :         SCTP_INP_WUNLOCK(inp);
    3111             : #ifdef SCTP_LOG_CLOSING
    3112             :         sctp_log_closing(inp, NULL, 12);
    3113             : #endif
    3114           0 :         return (error);
    3115             : }
    3116             : 
    3117             : 
    3118             : void
    3119           0 : sctp_move_pcb_and_assoc(struct sctp_inpcb *old_inp, struct sctp_inpcb *new_inp,
    3120             :     struct sctp_tcb *stcb)
    3121             : {
    3122             :         struct sctp_nets *net;
    3123             :         uint16_t lport, rport;
    3124             :         struct sctppcbhead *head;
    3125             :         struct sctp_laddr *laddr, *oladdr;
    3126             : 
    3127           0 :         atomic_add_int(&stcb->asoc.refcnt, 1);
    3128           0 :         SCTP_TCB_UNLOCK(stcb);
    3129           0 :         SCTP_INP_INFO_WLOCK();
    3130           0 :         SCTP_INP_WLOCK(old_inp);
    3131           0 :         SCTP_INP_WLOCK(new_inp);
    3132           0 :         SCTP_TCB_LOCK(stcb);
    3133           0 :         atomic_subtract_int(&stcb->asoc.refcnt, 1);
    3134             : 
    3135           0 :         new_inp->sctp_ep.time_of_secret_change =
    3136           0 :             old_inp->sctp_ep.time_of_secret_change;
    3137           0 :         memcpy(new_inp->sctp_ep.secret_key, old_inp->sctp_ep.secret_key,
    3138             :             sizeof(old_inp->sctp_ep.secret_key));
    3139           0 :         new_inp->sctp_ep.current_secret_number =
    3140           0 :             old_inp->sctp_ep.current_secret_number;
    3141           0 :         new_inp->sctp_ep.last_secret_number =
    3142           0 :             old_inp->sctp_ep.last_secret_number;
    3143           0 :         new_inp->sctp_ep.size_of_a_cookie = old_inp->sctp_ep.size_of_a_cookie;
    3144             : 
    3145             :         /* make it so new data pours into the new socket */
    3146           0 :         stcb->sctp_socket = new_inp->sctp_socket;
    3147           0 :         stcb->sctp_ep = new_inp;
    3148             : 
    3149             :         /* Copy the port across */
    3150           0 :         lport = new_inp->sctp_lport = old_inp->sctp_lport;
    3151           0 :         rport = stcb->rport;
    3152             :         /* Pull the tcb from the old association */
    3153           0 :         LIST_REMOVE(stcb, sctp_tcbhash);
    3154           0 :         LIST_REMOVE(stcb, sctp_tcblist);
    3155           0 :         if (stcb->asoc.in_asocid_hash) {
    3156           0 :                 LIST_REMOVE(stcb, sctp_tcbasocidhash);
    3157             :         }
    3158             :         /* Now insert the new_inp into the TCP connected hash */
    3159           0 :         head = &SCTP_BASE_INFO(sctp_tcpephash)[SCTP_PCBHASH_ALLADDR((lport | rport), SCTP_BASE_INFO(hashtcpmark))];
    3160             : 
    3161           0 :         LIST_INSERT_HEAD(head, new_inp, sctp_hash);
    3162             :         /* Its safe to access */
    3163           0 :         new_inp->sctp_flags &= ~SCTP_PCB_FLAGS_UNBOUND;
    3164             : 
    3165             :         /* Now move the tcb into the endpoint list */
    3166           0 :         LIST_INSERT_HEAD(&new_inp->sctp_asoc_list, stcb, sctp_tcblist);
    3167             :         /*
    3168             :          * Question, do we even need to worry about the ep-hash since we
    3169             :          * only have one connection? Probably not :> so lets get rid of it
    3170             :          * and not suck up any kernel memory in that.
    3171             :          */
    3172           0 :         if (stcb->asoc.in_asocid_hash) {
    3173             :                 struct sctpasochead *lhd;
    3174           0 :                 lhd = &new_inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(stcb->asoc.assoc_id,
    3175             :                         new_inp->hashasocidmark)];
    3176           0 :                 LIST_INSERT_HEAD(lhd, stcb, sctp_tcbasocidhash);
    3177             :         }
    3178             :         /* Ok. Let's restart timer. */
    3179           0 :         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
    3180           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, new_inp,
    3181             :                     stcb, net);
    3182             :         }
    3183             : 
    3184           0 :         SCTP_INP_INFO_WUNLOCK();
    3185           0 :         if (new_inp->sctp_tcbhash != NULL) {
    3186           0 :                 SCTP_HASH_FREE(new_inp->sctp_tcbhash, new_inp->sctp_hashmark);
    3187           0 :                 new_inp->sctp_tcbhash = NULL;
    3188             :         }
    3189           0 :         if ((new_inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
    3190             :                 /* Subset bound, so copy in the laddr list from the old_inp */
    3191           0 :                 LIST_FOREACH(oladdr, &old_inp->sctp_addr_list, sctp_nxt_addr) {
    3192           0 :                         laddr = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
    3193           0 :                         if (laddr == NULL) {
    3194             :                                 /*
    3195             :                                  * Gak, what can we do? This assoc is really
    3196             :                                  * HOSED. We probably should send an abort
    3197             :                                  * here.
    3198             :                                  */
    3199           0 :                                 SCTPDBG(SCTP_DEBUG_PCB1, "Association hosed in TCP model, out of laddr memory\n");
    3200           0 :                                 continue;
    3201             :                         }
    3202           0 :                         SCTP_INCR_LADDR_COUNT();
    3203           0 :                         bzero(laddr, sizeof(*laddr));
    3204           0 :                         (void)SCTP_GETTIME_TIMEVAL(&laddr->start_time);
    3205           0 :                         laddr->ifa = oladdr->ifa;
    3206           0 :                         atomic_add_int(&laddr->ifa->refcount, 1);
    3207           0 :                         LIST_INSERT_HEAD(&new_inp->sctp_addr_list, laddr,
    3208             :                             sctp_nxt_addr);
    3209           0 :                         new_inp->laddr_count++;
    3210           0 :                         if (oladdr == stcb->asoc.last_used_address) {
    3211           0 :                                 stcb->asoc.last_used_address = laddr;
    3212             :                         }
    3213             :                 }
    3214             :         }
    3215             :         /* Now any running timers need to be adjusted
    3216             :          * since we really don't care if they are running
    3217             :          * or not just blast in the new_inp into all of
    3218             :          * them.
    3219             :          */
    3220             : 
    3221           0 :         stcb->asoc.dack_timer.ep = (void *)new_inp;
    3222           0 :         stcb->asoc.asconf_timer.ep = (void *)new_inp;
    3223           0 :         stcb->asoc.strreset_timer.ep = (void *)new_inp;
    3224           0 :         stcb->asoc.shut_guard_timer.ep = (void *)new_inp;
    3225           0 :         stcb->asoc.autoclose_timer.ep = (void *)new_inp;
    3226           0 :         stcb->asoc.delayed_event_timer.ep = (void *)new_inp;
    3227           0 :         stcb->asoc.delete_prim_timer.ep = (void *)new_inp;
    3228             :         /* now what about the nets? */
    3229           0 :         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
    3230           0 :                 net->pmtu_timer.ep = (void *)new_inp;
    3231           0 :                 net->hb_timer.ep = (void *)new_inp;
    3232           0 :                 net->rxt_timer.ep = (void *)new_inp;
    3233             :         }
    3234           0 :         SCTP_INP_WUNLOCK(new_inp);
    3235           0 :         SCTP_INP_WUNLOCK(old_inp);
    3236           0 : }
    3237             : 
    3238             : 
    3239             : #if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__))
    3240             : /*
    3241             :  * Don't know why, but without this there is an unknown reference when
    3242             :  * compiling NetBSD... hmm
    3243             :  */
    3244             : extern void in6_sin6_2_sin(struct sockaddr_in *, struct sockaddr_in6 *sin6);
    3245             : #endif
    3246             : 
    3247             : 
    3248             : /* sctp_ifap is used to bypass normal local address validation checks */
    3249             : int
    3250             : #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
    3251             : sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
    3252             :                 struct sctp_ifa *sctp_ifap, struct thread *p)
    3253             : #elif defined(__Windows__)
    3254             : sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
    3255             :                 struct sctp_ifa *sctp_ifap, PKTHREAD p)
    3256             : #else
    3257           0 : sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
    3258             :                 struct sctp_ifa *sctp_ifap, struct proc *p)
    3259             : #endif
    3260             : {
    3261             :         /* bind a ep to a socket address */
    3262             :         struct sctppcbhead *head;
    3263             :         struct sctp_inpcb *inp, *inp_tmp;
    3264             : #if defined(INET) || (defined(INET6) && defined(__APPLE__)) || defined(__FreeBSD__) || defined(__APPLE__)
    3265             :         struct inpcb *ip_inp;
    3266             : #endif
    3267           0 :         int port_reuse_active = 0;
    3268             :         int bindall;
    3269             : #ifdef SCTP_MVRF
    3270             :         int i;
    3271             : #endif
    3272             :         uint16_t lport;
    3273             :         int error;
    3274             :         uint32_t vrf_id;
    3275             : 
    3276           0 :         lport = 0;
    3277           0 :         bindall = 1;
    3278           0 :         inp = (struct sctp_inpcb *)so->so_pcb;
    3279             : #if defined(INET) || (defined(INET6) && defined(__APPLE__)) || defined(__FreeBSD__) || defined(__APPLE__)
    3280             :         ip_inp = (struct inpcb *)so->so_pcb;
    3281             : #endif
    3282             : #ifdef SCTP_DEBUG
    3283           0 :         if (addr) {
    3284           0 :                 SCTPDBG(SCTP_DEBUG_PCB1, "Bind called port: %d\n",
    3285             :                         ntohs(((struct sockaddr_in *)addr)->sin_port));
    3286           0 :                 SCTPDBG(SCTP_DEBUG_PCB1, "Addr: ");
    3287           0 :                 SCTPDBG_ADDR(SCTP_DEBUG_PCB1, addr);
    3288             :         }
    3289             : #endif
    3290           0 :         if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) {
    3291             :                 /* already did a bind, subsequent binds NOT allowed ! */
    3292             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    3293           0 :                 return (EINVAL);
    3294             :         }
    3295             : #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
    3296             : #ifdef INVARIANTS
    3297             :         if (p == NULL)
    3298             :                 panic("null proc/thread");
    3299             : #endif
    3300             : #endif
    3301           0 :         if (addr != NULL) {
    3302           0 :                 switch (addr->sa_family) {
    3303             : #ifdef INET
    3304             :                 case AF_INET:
    3305             :                 {
    3306             :                         struct sockaddr_in *sin;
    3307             : 
    3308             :                         /* IPV6_V6ONLY socket? */
    3309             :                         if (SCTP_IPV6_V6ONLY(ip_inp)) {
    3310             :                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    3311             :                                 return (EINVAL);
    3312             :                         }
    3313             : #ifdef HAVE_SA_LEN
    3314             :                         if (addr->sa_len != sizeof(*sin)) {
    3315             :                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    3316             :                                 return (EINVAL);
    3317             :                         }
    3318             : #endif
    3319             : 
    3320             :                         sin = (struct sockaddr_in *)addr;
    3321             :                         lport = sin->sin_port;
    3322             : #if defined(__FreeBSD__) && __FreeBSD_version >= 800000
    3323             :                         /*
    3324             :                          * For LOOPBACK the prison_local_ip4() call will transmute the ip address
    3325             :                          * to the proper value.
    3326             :                          */
    3327             :                         if (p && (error = prison_local_ip4(p->td_ucred, &sin->sin_addr)) != 0) {
    3328             :                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
    3329             :                                 return (error);
    3330             :                         }
    3331             : #endif
    3332             :                         if (sin->sin_addr.s_addr != INADDR_ANY) {
    3333             :                                 bindall = 0;
    3334             :                         }
    3335             :                         break;
    3336             :                 }
    3337             : #endif
    3338             : #ifdef INET6
    3339             :                 case AF_INET6:
    3340             :                 {
    3341             :                         /* Only for pure IPv6 Address. (No IPv4 Mapped!) */
    3342             :                         struct sockaddr_in6 *sin6;
    3343             : 
    3344             :                         sin6 = (struct sockaddr_in6 *)addr;
    3345             : 
    3346             : #ifdef HAVE_SA_LEN
    3347             :                         if (addr->sa_len != sizeof(*sin6)) {
    3348             :                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    3349             :                                 return (EINVAL);
    3350             :                         }
    3351             : #endif
    3352             :                         lport = sin6->sin6_port;
    3353             : #if defined(__FreeBSD__) && __FreeBSD_version >= 800000
    3354             :                         /*
    3355             :                          * For LOOPBACK the prison_local_ip6() call will transmute the ipv6 address
    3356             :                          * to the proper value.
    3357             :                          */
    3358             :                         if (p && (error = prison_local_ip6(p->td_ucred, &sin6->sin6_addr,
    3359             :                             (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
    3360             :                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
    3361             :                                 return (error);
    3362             :                         }
    3363             : #endif
    3364             :                         if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
    3365             :                                 bindall = 0;
    3366             : #ifdef SCTP_EMBEDDED_V6_SCOPE
    3367             :                                 /* KAME hack: embed scopeid */
    3368             : #if defined(SCTP_KAME)
    3369             :                                 if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
    3370             :                                         SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    3371             :                                         return (EINVAL);
    3372             :                                 }
    3373             : #elif defined(__APPLE__)
    3374             : #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
    3375             :                                 if (in6_embedscope(&sin6->sin6_addr, sin6, ip_inp, NULL) != 0) {
    3376             : #else
    3377             :                                 if (in6_embedscope(&sin6->sin6_addr, sin6, ip_inp, NULL, NULL) != 0) {
    3378             : #endif
    3379             :                                         SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    3380             :                                         return (EINVAL);
    3381             :                                 }
    3382             : #elif defined(__FreeBSD__)
    3383             :                                 error = scope6_check_id(sin6, MODULE_GLOBAL(ip6_use_defzone));
    3384             :                                 if (error != 0) {
    3385             :                                         SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
    3386             :                                         return (error);
    3387             :                                 }
    3388             : #else
    3389             :                                 if (in6_embedscope(&sin6->sin6_addr, sin6) != 0) {
    3390             :                                         SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    3391             :                                         return (EINVAL);
    3392             :                                 }
    3393             : #endif
    3394             : #endif /* SCTP_EMBEDDED_V6_SCOPE */
    3395             :                         }
    3396             : #ifndef SCOPEDROUTING
    3397             :                         /* this must be cleared for ifa_ifwithaddr() */
    3398             :                         sin6->sin6_scope_id = 0;
    3399             : #endif /* SCOPEDROUTING */
    3400             :                         break;
    3401             :                 }
    3402             : #endif
    3403             : #if defined(__Userspace__)
    3404             :                 case AF_CONN:
    3405             :                 {
    3406             :                         struct sockaddr_conn *sconn;
    3407             : 
    3408             : #ifdef HAVE_SA_LEN
    3409             :                         if (addr->sa_len != sizeof(struct sockaddr_conn)) {
    3410             :                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    3411             :                                 return (EINVAL);
    3412             :                         }
    3413             : #endif
    3414           0 :                         sconn = (struct sockaddr_conn *)addr;
    3415           0 :                         lport = sconn->sconn_port;
    3416           0 :                         if (sconn->sconn_addr != NULL) {
    3417           0 :                                 bindall = 0;
    3418             :                         }
    3419           0 :                         break;
    3420             :                 }
    3421             : #endif
    3422             :                 default:
    3423             :                         SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EAFNOSUPPORT);
    3424           0 :                         return (EAFNOSUPPORT);
    3425             :                 }
    3426             :         }
    3427           0 :         SCTP_INP_INFO_WLOCK();
    3428           0 :         SCTP_INP_WLOCK(inp);
    3429             :         /* Setup a vrf_id to be the default for the non-bind-all case. */
    3430           0 :         vrf_id = inp->def_vrf_id;
    3431             : 
    3432             :         /* increase our count due to the unlock we do */
    3433           0 :         SCTP_INP_INCR_REF(inp);
    3434           0 :         if (lport) {
    3435             :                 /*
    3436             :                  * Did the caller specify a port? if so we must see if an ep
    3437             :                  * already has this one bound.
    3438             :                  */
    3439             :                 /* got to be root to get at low ports */
    3440             : #if !defined(__Windows__)
    3441           0 :                 if (ntohs(lport) < IPPORT_RESERVED) {
    3442           0 :                         if (p && (error =
    3443             : #ifdef __FreeBSD__
    3444             : #if __FreeBSD_version > 602000
    3445             :                                   priv_check(p, PRIV_NETINET_RESERVEDPORT)
    3446             : #elif __FreeBSD_version >= 500000
    3447             :                                   suser_cred(p->td_ucred, 0)
    3448             : #else
    3449             :                                   suser(p)
    3450             : #endif
    3451             : #elif defined(__APPLE__)
    3452             :                                   suser(p->p_ucred, &p->p_acflag)
    3453             : #elif defined(__Userspace__) /* must be true to use raw socket */
    3454             :                                   1
    3455             : #else
    3456             :                                   suser(p, 0)
    3457             : #endif
    3458             :                                     )) {
    3459           0 :                                 SCTP_INP_DECR_REF(inp);
    3460           0 :                                 SCTP_INP_WUNLOCK(inp);
    3461           0 :                                 SCTP_INP_INFO_WUNLOCK();
    3462           0 :                                 return (error);
    3463             :                         }
    3464             : #if defined(__Panda__)
    3465             :                         if (!SCTP_IS_PRIVILEDGED(so)) {
    3466             :                                 SCTP_INP_DECR_REF(inp);
    3467             :                                 SCTP_INP_WUNLOCK(inp);
    3468             :                                 SCTP_INP_INFO_WUNLOCK();
    3469             :                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EACCES);
    3470             :                                 return (EACCES);
    3471             :                         }
    3472             : #endif
    3473             :                 }
    3474             : #endif /* __Windows__ */
    3475           0 :                 SCTP_INP_WUNLOCK(inp);
    3476           0 :                 if (bindall) {
    3477             : #ifdef SCTP_MVRF
    3478             :                         for (i = 0; i < inp->num_vrfs; i++) {
    3479             :                                 vrf_id = inp->m_vrf_ids[i];
    3480             : #else
    3481           0 :                                 vrf_id = inp->def_vrf_id;
    3482             : #endif
    3483           0 :                                 inp_tmp = sctp_pcb_findep(addr, 0, 1, vrf_id);
    3484           0 :                                 if (inp_tmp != NULL) {
    3485             :                                         /*
    3486             :                                          * lock guy returned and lower count
    3487             :                                          * note that we are not bound so
    3488             :                                          * inp_tmp should NEVER be inp. And
    3489             :                                          * it is this inp (inp_tmp) that gets
    3490             :                                          * the reference bump, so we must
    3491             :                                          * lower it.
    3492             :                                          */
    3493           0 :                                         SCTP_INP_DECR_REF(inp_tmp);
    3494             :                                         /* unlock info */
    3495           0 :                                         if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) &&
    3496           0 :                                             (sctp_is_feature_on(inp_tmp, SCTP_PCB_FLAGS_PORTREUSE))) {
    3497             :                                                 /* Ok, must be one-2-one and allowing port re-use */
    3498           0 :                                                 port_reuse_active = 1;
    3499           0 :                                                 goto continue_anyway;
    3500             :                                         }
    3501           0 :                                         SCTP_INP_DECR_REF(inp);
    3502           0 :                                         SCTP_INP_INFO_WUNLOCK();
    3503             :                                         SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRINUSE);
    3504           0 :                                         return (EADDRINUSE);
    3505             :                                 }
    3506             : #ifdef SCTP_MVRF
    3507             :                         }
    3508             : #endif
    3509             :                 } else {
    3510           0 :                         inp_tmp = sctp_pcb_findep(addr, 0, 1, vrf_id);
    3511           0 :                         if (inp_tmp != NULL) {
    3512             :                                 /*
    3513             :                                  * lock guy returned and lower count note
    3514             :                                  * that we are not bound so inp_tmp should
    3515             :                                  * NEVER be inp. And it is this inp (inp_tmp)
    3516             :                                  * that gets the reference bump, so we must
    3517             :                                  * lower it.
    3518             :                                  */
    3519           0 :                                 SCTP_INP_DECR_REF(inp_tmp);
    3520             :                                 /* unlock info */
    3521           0 :                                 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) &&
    3522           0 :                                     (sctp_is_feature_on(inp_tmp, SCTP_PCB_FLAGS_PORTREUSE))) {
    3523             :                                         /* Ok, must be one-2-one and allowing port re-use */
    3524           0 :                                         port_reuse_active = 1;
    3525           0 :                                         goto continue_anyway;
    3526             :                                 }
    3527           0 :                                 SCTP_INP_DECR_REF(inp);
    3528           0 :                                 SCTP_INP_INFO_WUNLOCK();
    3529             :                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRINUSE);
    3530           0 :                                 return (EADDRINUSE);
    3531             :                         }
    3532             :                 }
    3533             :         continue_anyway:
    3534           0 :                 SCTP_INP_WLOCK(inp);
    3535           0 :                 if (bindall) {
    3536             :                         /* verify that no lport is not used by a singleton */
    3537           0 :                         if ((port_reuse_active == 0) &&
    3538           0 :                             (inp_tmp = sctp_isport_inuse(inp, lport, vrf_id))) {
    3539             :                                 /* Sorry someone already has this one bound */
    3540           0 :                                 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) &&
    3541           0 :                                     (sctp_is_feature_on(inp_tmp, SCTP_PCB_FLAGS_PORTREUSE))) {
    3542           0 :                                         port_reuse_active = 1;
    3543             :                                 } else {
    3544           0 :                                         SCTP_INP_DECR_REF(inp);
    3545           0 :                                         SCTP_INP_WUNLOCK(inp);
    3546           0 :                                         SCTP_INP_INFO_WUNLOCK();
    3547             :                                         SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRINUSE);
    3548           0 :                                         return (EADDRINUSE);
    3549             :                                 }
    3550             :                         }
    3551             :                 }
    3552             :         } else {
    3553             :                 uint16_t first, last, candidate;
    3554             :                 uint16_t count;
    3555             :                 int done;
    3556             : 
    3557             : #if defined(__Windows__)
    3558             :                 first = 1;
    3559             :                 last = 0xffff;
    3560             : #else
    3561             : #if defined(__Userspace__)
    3562             :                 /* TODO ensure uid is 0, etc... */
    3563             : #elif defined(__FreeBSD__) || defined(__APPLE__)
    3564             :                 if (ip_inp->inp_flags & INP_HIGHPORT) {
    3565             :                         first = MODULE_GLOBAL(ipport_hifirstauto);
    3566             :                         last = MODULE_GLOBAL(ipport_hilastauto);
    3567             :                 } else if (ip_inp->inp_flags & INP_LOWPORT) {
    3568             :                         if (p && (error =
    3569             : #ifdef __FreeBSD__
    3570             : #if __FreeBSD_version > 602000
    3571             :                                   priv_check(p, PRIV_NETINET_RESERVEDPORT)
    3572             : #elif __FreeBSD_version >= 500000
    3573             :                                   suser_cred(p->td_ucred, 0)
    3574             : #else
    3575             :                                   suser(p)
    3576             : #endif
    3577             : #elif defined(__APPLE__)
    3578             :                                   suser(p->p_ucred, &p->p_acflag)
    3579             : #else
    3580             :                                   suser(p, 0)
    3581             : #endif
    3582             :                                     )) {
    3583             :                                 SCTP_INP_DECR_REF(inp);
    3584             :                                 SCTP_INP_WUNLOCK(inp);
    3585             :                                 SCTP_INP_INFO_WUNLOCK();
    3586             :                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
    3587             :                                 return (error);
    3588             :                         }
    3589             :                         first = MODULE_GLOBAL(ipport_lowfirstauto);
    3590             :                         last = MODULE_GLOBAL(ipport_lowlastauto);
    3591             :                 } else {
    3592             : #endif
    3593           0 :                         first = MODULE_GLOBAL(ipport_firstauto);
    3594           0 :                         last = MODULE_GLOBAL(ipport_lastauto);
    3595             : #if defined(__FreeBSD__) || defined(__APPLE__)
    3596             :                 }
    3597             : #endif
    3598             : #endif /* __Windows__ */
    3599           0 :                 if (first > last) {
    3600             :                         uint16_t temp;
    3601             : 
    3602           0 :                         temp = first;
    3603           0 :                         first = last;
    3604           0 :                         last = temp;
    3605             :                 }
    3606           0 :                 count = last - first + 1; /* number of candidates */
    3607           0 :                 candidate = first + sctp_select_initial_TSN(&inp->sctp_ep) % (count);
    3608             : 
    3609           0 :                 done = 0;
    3610           0 :                 while (!done) {
    3611             : #ifdef SCTP_MVRF
    3612             :                         for (i = 0; i < inp->num_vrfs; i++) {
    3613             :                                 if (sctp_isport_inuse(inp, htons(candidate), inp->m_vrf_ids[i]) != NULL) {
    3614             :                                         break;
    3615             :                                 }
    3616             :                         }
    3617             :                         if (i == inp->num_vrfs) {
    3618             :                                 done = 1;
    3619             :                         }
    3620             : #else
    3621           0 :                         if (sctp_isport_inuse(inp, htons(candidate), inp->def_vrf_id) == NULL) {
    3622           0 :                                 done = 1;
    3623             :                         }
    3624             : #endif
    3625           0 :                         if (!done) {
    3626           0 :                                 if (--count == 0) {
    3627           0 :                                         SCTP_INP_DECR_REF(inp);
    3628           0 :                                         SCTP_INP_WUNLOCK(inp);
    3629           0 :                                         SCTP_INP_INFO_WUNLOCK();
    3630             :                                         SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRINUSE);
    3631           0 :                                         return (EADDRINUSE);
    3632             :                                 }
    3633           0 :                                 if (candidate == last)
    3634           0 :                                         candidate = first;
    3635             :                                 else
    3636           0 :                                         candidate = candidate + 1;
    3637             :                         }
    3638             :                 }
    3639           0 :                 lport = htons(candidate);
    3640             :         }
    3641           0 :         SCTP_INP_DECR_REF(inp);
    3642           0 :         if (inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE |
    3643             :                                SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
    3644             :                 /*
    3645             :                  * this really should not happen. The guy did a non-blocking
    3646             :                  * bind and then did a close at the same time.
    3647             :                  */
    3648           0 :                 SCTP_INP_WUNLOCK(inp);
    3649           0 :                 SCTP_INP_INFO_WUNLOCK();
    3650             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    3651           0 :                 return (EINVAL);
    3652             :         }
    3653             :         /* ok we look clear to give out this port, so lets setup the binding */
    3654           0 :         if (bindall) {
    3655             :                 /* binding to all addresses, so just set in the proper flags */
    3656           0 :                 inp->sctp_flags |= SCTP_PCB_FLAGS_BOUNDALL;
    3657             :                 /* set the automatic addr changes from kernel flag */
    3658           0 :                 if (SCTP_BASE_SYSCTL(sctp_auto_asconf) == 0) {
    3659           0 :                         sctp_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF);
    3660           0 :                         sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
    3661             :                 } else {
    3662           0 :                         sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF);
    3663           0 :                         sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
    3664             :                 }
    3665           0 :                 if (SCTP_BASE_SYSCTL(sctp_multiple_asconfs) == 0) {
    3666           0 :                         sctp_feature_off(inp, SCTP_PCB_FLAGS_MULTIPLE_ASCONFS);
    3667             :                 } else {
    3668           0 :                         sctp_feature_on(inp, SCTP_PCB_FLAGS_MULTIPLE_ASCONFS);
    3669             :                 }
    3670             :                 /* set the automatic mobility_base from kernel
    3671             :                    flag (by micchie)
    3672             :                 */
    3673           0 :                 if (SCTP_BASE_SYSCTL(sctp_mobility_base) == 0) {
    3674           0 :                         sctp_mobility_feature_off(inp, SCTP_MOBILITY_BASE);
    3675           0 :                         sctp_mobility_feature_off(inp, SCTP_MOBILITY_PRIM_DELETED);
    3676             :                 } else {
    3677           0 :                         sctp_mobility_feature_on(inp, SCTP_MOBILITY_BASE);
    3678           0 :                         sctp_mobility_feature_off(inp, SCTP_MOBILITY_PRIM_DELETED);
    3679             :                 }
    3680             :                 /* set the automatic mobility_fasthandoff from kernel
    3681             :                    flag (by micchie)
    3682             :                 */
    3683           0 :                 if (SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff) == 0) {
    3684           0 :                         sctp_mobility_feature_off(inp, SCTP_MOBILITY_FASTHANDOFF);
    3685           0 :                         sctp_mobility_feature_off(inp, SCTP_MOBILITY_PRIM_DELETED);
    3686             :                 } else {
    3687           0 :                         sctp_mobility_feature_on(inp, SCTP_MOBILITY_FASTHANDOFF);
    3688           0 :                         sctp_mobility_feature_off(inp, SCTP_MOBILITY_PRIM_DELETED);
    3689             :                 }
    3690             :         } else {
    3691             :                 /*
    3692             :                  * bind specific, make sure flags is off and add a new
    3693             :                  * address structure to the sctp_addr_list inside the ep
    3694             :                  * structure.
    3695             :                  *
    3696             :                  * We will need to allocate one and insert it at the head. The
    3697             :                  * socketopt call can just insert new addresses in there as
    3698             :                  * well. It will also have to do the embed scope kame hack
    3699             :                  * too (before adding).
    3700             :                  */
    3701             :                 struct sctp_ifa *ifa;
    3702             :                 union sctp_sockstore store;
    3703             : 
    3704           0 :                 memset(&store, 0, sizeof(store));
    3705           0 :                 switch (addr->sa_family) {
    3706             : #ifdef INET
    3707             :                 case AF_INET:
    3708             :                         memcpy(&store.sin, addr, sizeof(struct sockaddr_in));
    3709             :                         store.sin.sin_port = 0;
    3710             :                         break;
    3711             : #endif
    3712             : #ifdef INET6
    3713             :                 case AF_INET6:
    3714             :                         memcpy(&store.sin6, addr, sizeof(struct sockaddr_in6));
    3715             :                         store.sin6.sin6_port = 0;
    3716             :                         break;
    3717             : #endif
    3718             : #if defined(__Userspace__)
    3719             :                 case AF_CONN:
    3720           0 :                         memcpy(&store.sconn, addr, sizeof(struct sockaddr_conn));
    3721           0 :                         store.sconn.sconn_port = 0;
    3722           0 :                         break;
    3723             : #endif
    3724             :                 default:
    3725           0 :                         break;
    3726             :                 }
    3727             :                 /*
    3728             :                  * first find the interface with the bound address need to
    3729             :                  * zero out the port to find the address! yuck! can't do
    3730             :                  * this earlier since need port for sctp_pcb_findep()
    3731             :                  */
    3732           0 :                 if (sctp_ifap != NULL) {
    3733           0 :                         ifa = sctp_ifap;
    3734             :                 } else {
    3735             :                         /* Note for BSD we hit here always other
    3736             :                          * O/S's will pass things in via the
    3737             :                          * sctp_ifap argument (Panda).
    3738             :                          */
    3739           0 :                         ifa = sctp_find_ifa_by_addr(&store.sa,
    3740             :                                                     vrf_id, SCTP_ADDR_NOT_LOCKED);
    3741             :                 }
    3742           0 :                 if (ifa == NULL) {
    3743             :                         /* Can't find an interface with that address */
    3744           0 :                         SCTP_INP_WUNLOCK(inp);
    3745           0 :                         SCTP_INP_INFO_WUNLOCK();
    3746             :                         SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRNOTAVAIL);
    3747           0 :                         return (EADDRNOTAVAIL);
    3748             :                 }
    3749             : #ifdef INET6
    3750             :                 if (addr->sa_family == AF_INET6) {
    3751             :                         /* GAK, more FIXME IFA lock? */
    3752             :                         if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
    3753             :                                 /* Can't bind a non-existent addr. */
    3754             :                                 SCTP_INP_WUNLOCK(inp);
    3755             :                                 SCTP_INP_INFO_WUNLOCK();
    3756             :                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    3757             :                                 return (EINVAL);
    3758             :                         }
    3759             :                 }
    3760             : #endif
    3761             :                 /* we're not bound all */
    3762           0 :                 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUNDALL;
    3763             :                 /* allow bindx() to send ASCONF's for binding changes */
    3764           0 :                 sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF);
    3765             :                 /* clear automatic addr changes from kernel flag */
    3766           0 :                 sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
    3767             : 
    3768             :                 /* add this address to the endpoint list */
    3769           0 :                 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, 0);
    3770           0 :                 if (error != 0) {
    3771           0 :                         SCTP_INP_WUNLOCK(inp);
    3772           0 :                         SCTP_INP_INFO_WUNLOCK();
    3773           0 :                         return (error);
    3774             :                 }
    3775           0 :                 inp->laddr_count++;
    3776             :         }
    3777             :         /* find the bucket */
    3778           0 :         if (port_reuse_active) {
    3779             :                 /* Put it into tcp 1-2-1 hash */
    3780           0 :                 head = &SCTP_BASE_INFO(sctp_tcpephash)[SCTP_PCBHASH_ALLADDR(lport, SCTP_BASE_INFO(hashtcpmark))];
    3781           0 :                 inp->sctp_flags |= SCTP_PCB_FLAGS_IN_TCPPOOL;
    3782             :         } else {
    3783           0 :                 head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(lport, SCTP_BASE_INFO(hashmark))];
    3784             :         }
    3785             :         /* put it in the bucket */
    3786           0 :         LIST_INSERT_HEAD(head, inp, sctp_hash);
    3787           0 :         SCTPDBG(SCTP_DEBUG_PCB1, "Main hash to bind at head:%p, bound port:%d - in tcp_pool=%d\n",
    3788             :                 (void *)head, ntohs(lport), port_reuse_active);
    3789             :         /* set in the port */
    3790           0 :         inp->sctp_lport = lport;
    3791             : 
    3792             :         /* turn off just the unbound flag */
    3793           0 :         inp->sctp_flags &= ~SCTP_PCB_FLAGS_UNBOUND;
    3794           0 :         SCTP_INP_WUNLOCK(inp);
    3795           0 :         SCTP_INP_INFO_WUNLOCK();
    3796           0 :         return (0);
    3797             : }
    3798             : 
    3799             : 
    3800             : static void
    3801           0 : sctp_iterator_inp_being_freed(struct sctp_inpcb *inp)
    3802             : {
    3803             :         struct sctp_iterator *it, *nit;
    3804             : 
    3805             :         /*
    3806             :          * We enter with the only the ITERATOR_LOCK in place and a write
    3807             :          * lock on the inp_info stuff.
    3808             :          */
    3809           0 :         it = sctp_it_ctl.cur_it;
    3810             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
    3811             :         if (it && (it->vn != curvnet)) {
    3812             :                 /* Its not looking at our VNET */
    3813             :                 return;
    3814             :         }
    3815             : #endif
    3816           0 :         if (it && (it->inp == inp)) {
    3817             :                 /*
    3818             :                  * This is tricky and we hold the iterator lock,
    3819             :                  * but when it returns and gets the lock (when we
    3820             :                  * release it) the iterator will try to operate on
    3821             :                  * inp. We need to stop that from happening. But
    3822             :                  * of course the iterator has a reference on the
    3823             :                  * stcb and inp. We can mark it and it will stop.
    3824             :                  *
    3825             :                  * If its a single iterator situation, we
    3826             :                  * set the end iterator flag. Otherwise
    3827             :                  * we set the iterator to go to the next inp.
    3828             :                  *
    3829             :                  */
    3830           0 :                 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
    3831           0 :                         sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
    3832             :                 } else {
    3833           0 :                         sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_INP;
    3834             :                 }
    3835             :         }
    3836             :         /* Now go through and remove any single reference to
    3837             :          * our inp that may be still pending on the list
    3838             :          */
    3839           0 :         SCTP_IPI_ITERATOR_WQ_LOCK();
    3840           0 :         TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
    3841             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
    3842             :                 if (it->vn != curvnet) {
    3843             :                         continue;
    3844             :                 }
    3845             : #endif
    3846           0 :                 if (it->inp == inp) {
    3847             :                         /* This one points to me is it inp specific? */
    3848           0 :                         if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
    3849             :                                 /* Remove and free this one */
    3850           0 :                                 TAILQ_REMOVE(&sctp_it_ctl.iteratorhead,
    3851             :                                     it, sctp_nxt_itr);
    3852           0 :                                 if (it->function_atend != NULL) {
    3853           0 :                                         (*it->function_atend) (it->pointer, it->val);
    3854             :                                 }
    3855           0 :                                 SCTP_FREE(it, SCTP_M_ITER);
    3856             :                         } else {
    3857           0 :                                 it->inp = LIST_NEXT(it->inp, sctp_list);
    3858           0 :                                 if (it->inp) {
    3859           0 :                                         SCTP_INP_INCR_REF(it->inp);
    3860             :                                 }
    3861             :                         }
    3862             :                         /* When its put in the refcnt is incremented so decr it */
    3863           0 :                         SCTP_INP_DECR_REF(inp);
    3864             :                 }
    3865             :         }
    3866           0 :         SCTP_IPI_ITERATOR_WQ_UNLOCK();
    3867           0 : }
    3868             : 
    3869             : /* release sctp_inpcb unbind the port */
    3870             : void
    3871           0 : sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
    3872             : {
    3873             :         /*
    3874             :          * Here we free a endpoint. We must find it (if it is in the Hash
    3875             :          * table) and remove it from there. Then we must also find it in the
    3876             :          * overall list and remove it from there. After all removals are
    3877             :          * complete then any timer has to be stopped. Then start the actual
    3878             :          * freeing. a) Any local lists. b) Any associations. c) The hash of
    3879             :          * all associations. d) finally the ep itself.
    3880             :          */
    3881             :         struct sctp_tcb *asoc, *nasoc;
    3882             :         struct sctp_laddr *laddr, *nladdr;
    3883             :         struct inpcb *ip_pcb;
    3884             :         struct socket *so;
    3885           0 :         int being_refed = 0;
    3886             :         struct sctp_queued_to_read *sq, *nsq;
    3887             : #if !defined(__Panda__) && !defined(__Userspace__)
    3888             : #if !defined(__FreeBSD__) || __FreeBSD_version < 500000
    3889             :         sctp_rtentry_t *rt;
    3890             : #endif
    3891             : #endif
    3892             :         int cnt;
    3893             :         sctp_sharedkey_t *shared_key, *nshared_key;
    3894             : 
    3895             : 
    3896             : #if defined(__APPLE__)
    3897             :         sctp_lock_assert(SCTP_INP_SO(inp));
    3898             : #endif
    3899             : #ifdef SCTP_LOG_CLOSING
    3900             :         sctp_log_closing(inp, NULL, 0);
    3901             : #endif
    3902           0 :         SCTP_ITERATOR_LOCK();
    3903             :         /* mark any iterators on the list or being processed */
    3904           0 :         sctp_iterator_inp_being_freed(inp);
    3905           0 :         SCTP_ITERATOR_UNLOCK();
    3906           0 :         so = inp->sctp_socket;
    3907           0 :         if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
    3908             :                 /* been here before.. eeks.. get out of here */
    3909           0 :                 SCTP_PRINTF("This conflict in free SHOULD not be happening! from %d, imm %d\n", from, immediate);
    3910             : #ifdef SCTP_LOG_CLOSING
    3911             :                 sctp_log_closing(inp, NULL, 1);
    3912             : #endif
    3913           0 :                 return;
    3914             :         }
    3915           0 :         SCTP_ASOC_CREATE_LOCK(inp);
    3916           0 :         SCTP_INP_INFO_WLOCK();
    3917             : 
    3918           0 :         SCTP_INP_WLOCK(inp);
    3919           0 :         if (from == SCTP_CALLED_AFTER_CMPSET_OFCLOSE) {
    3920           0 :                 inp->sctp_flags &= ~SCTP_PCB_FLAGS_CLOSE_IP;
    3921             :                 /* socket is gone, so no more wakeups allowed */
    3922           0 :                 inp->sctp_flags |= SCTP_PCB_FLAGS_DONT_WAKE;
    3923           0 :                 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT;
    3924           0 :                 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT;
    3925             : 
    3926             :         }
    3927             :         /* First time through we have the socket lock, after that no more. */
    3928           0 :         sctp_timer_stop(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL,
    3929             :                         SCTP_FROM_SCTP_PCB+SCTP_LOC_1);
    3930             : 
    3931           0 :         if (inp->control) {
    3932           0 :                 sctp_m_freem(inp->control);
    3933           0 :                 inp->control = NULL;
    3934             :         }
    3935           0 :         if (inp->pkt) {
    3936           0 :                 sctp_m_freem(inp->pkt);
    3937           0 :                 inp->pkt = NULL;
    3938             :         }
    3939           0 :         ip_pcb = &inp->ip_inp.inp;       /* we could just cast the main pointer
    3940             :                                          * here but I will be nice :> (i.e.
    3941             :                                          * ip_pcb = ep;) */
    3942           0 :         if (immediate == SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE) {
    3943             :                 int cnt_in_sd;
    3944             : 
    3945           0 :                 cnt_in_sd = 0;
    3946           0 :                 LIST_FOREACH_SAFE(asoc, &inp->sctp_asoc_list, sctp_tcblist, nasoc) {
    3947           0 :                         SCTP_TCB_LOCK(asoc);
    3948           0 :                         if (asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
    3949             :                                 /* Skip guys being freed */
    3950           0 :                                 cnt_in_sd++;
    3951           0 :                                 if (asoc->asoc.state & SCTP_STATE_IN_ACCEPT_QUEUE) {
    3952             :                                         /*
    3953             :                                          * Special case - we did not start a kill
    3954             :                                          * timer on the asoc due to it was not
    3955             :                                          * closed. So go ahead and start it now.
    3956             :                                          */
    3957           0 :                                         asoc->asoc.state &= ~SCTP_STATE_IN_ACCEPT_QUEUE;
    3958           0 :                                         sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, asoc, NULL);
    3959             :                                 }
    3960           0 :                                 SCTP_TCB_UNLOCK(asoc);
    3961           0 :                                 continue;
    3962             :                         }
    3963           0 :                         if (((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_COOKIE_WAIT) ||
    3964           0 :                             (SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_COOKIE_ECHOED)) &&
    3965           0 :                             (asoc->asoc.total_output_queue_size == 0)) {
    3966             :                                 /* If we have data in queue, we don't want to just
    3967             :                                  * free since the app may have done, send()/close
    3968             :                                  * or connect/send/close. And it wants the data
    3969             :                                  * to get across first.
    3970             :                                  */
    3971             :                                 /* Just abandon things in the front states */
    3972           0 :                                 if (sctp_free_assoc(inp, asoc, SCTP_PCBFREE_NOFORCE,
    3973             :                                                    SCTP_FROM_SCTP_PCB+SCTP_LOC_2) == 0) {
    3974           0 :                                         cnt_in_sd++;
    3975             :                                 }
    3976           0 :                                 continue;
    3977             :                         }
    3978             :                         /* Disconnect the socket please */
    3979           0 :                         asoc->sctp_socket = NULL;
    3980           0 :                         asoc->asoc.state |= SCTP_STATE_CLOSED_SOCKET;
    3981           0 :                         if ((asoc->asoc.size_on_reasm_queue > 0) ||
    3982           0 :                             (asoc->asoc.control_pdapi) ||
    3983           0 :                             (asoc->asoc.size_on_all_streams > 0) ||
    3984           0 :                             (so && (so->so_rcv.sb_cc > 0))) {
    3985             :                                 /* Left with Data unread */
    3986             :                                 struct mbuf *op_err;
    3987             : 
    3988           0 :                                 op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
    3989           0 :                                 asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB+SCTP_LOC_3;
    3990           0 :                                 sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
    3991           0 :                                 SCTP_STAT_INCR_COUNTER32(sctps_aborted);
    3992           0 :                                 if ((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_OPEN) ||
    3993           0 :                                     (SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
    3994           0 :                                         SCTP_STAT_DECR_GAUGE32(sctps_currestab);
    3995             :                                 }
    3996           0 :                                 if (sctp_free_assoc(inp, asoc,
    3997             :                                                     SCTP_PCBFREE_NOFORCE, SCTP_FROM_SCTP_PCB+SCTP_LOC_4) == 0) {
    3998           0 :                                         cnt_in_sd++;
    3999             :                                 }
    4000           0 :                                 continue;
    4001           0 :                         } else if (TAILQ_EMPTY(&asoc->asoc.send_queue) &&
    4002           0 :                                    TAILQ_EMPTY(&asoc->asoc.sent_queue) &&
    4003           0 :                                    (asoc->asoc.stream_queue_cnt == 0)) {
    4004           0 :                                 if (asoc->asoc.locked_on_sending) {
    4005           0 :                                         goto abort_anyway;
    4006             :                                 }
    4007           0 :                                 if ((SCTP_GET_STATE(&asoc->asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
    4008           0 :                                     (SCTP_GET_STATE(&asoc->asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
    4009             :                                         struct sctp_nets *netp;
    4010             : 
    4011             :                                         /*
    4012             :                                          * there is nothing queued to send,
    4013             :                                          * so I send shutdown
    4014             :                                          */
    4015           0 :                                         if ((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_OPEN) ||
    4016           0 :                                             (SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
    4017           0 :                                                 SCTP_STAT_DECR_GAUGE32(sctps_currestab);
    4018             :                                         }
    4019           0 :                                         SCTP_SET_STATE(&asoc->asoc, SCTP_STATE_SHUTDOWN_SENT);
    4020           0 :                                         SCTP_CLEAR_SUBSTATE(&asoc->asoc, SCTP_STATE_SHUTDOWN_PENDING);
    4021           0 :                                         sctp_stop_timers_for_shutdown(asoc);
    4022           0 :                                         if (asoc->asoc.alternate) {
    4023           0 :                                                 netp = asoc->asoc.alternate;
    4024             :                                         } else {
    4025           0 :                                                 netp = asoc->asoc.primary_destination;
    4026             :                                         }
    4027           0 :                                         sctp_send_shutdown(asoc, netp);
    4028           0 :                                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, asoc->sctp_ep, asoc,
    4029             :                                             netp);
    4030           0 :                                         sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, asoc->sctp_ep, asoc,
    4031             :                                             asoc->asoc.primary_destination);
    4032           0 :                                         sctp_chunk_output(inp, asoc, SCTP_OUTPUT_FROM_SHUT_TMR, SCTP_SO_LOCKED);
    4033             :                                 }
    4034             :                         } else {
    4035             :                                 /* mark into shutdown pending */
    4036             :                                 struct sctp_stream_queue_pending *sp;
    4037             : 
    4038           0 :                                 asoc->asoc.state |= SCTP_STATE_SHUTDOWN_PENDING;
    4039           0 :                                 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, asoc->sctp_ep, asoc,
    4040             :                                                  asoc->asoc.primary_destination);
    4041           0 :                                 if (asoc->asoc.locked_on_sending) {
    4042           0 :                                         sp = TAILQ_LAST(&((asoc->asoc.locked_on_sending)->outqueue),
    4043             :                                                 sctp_streamhead);
    4044           0 :                                         if (sp == NULL) {
    4045           0 :                                                 SCTP_PRINTF("Error, sp is NULL, locked on sending is %p strm:%d\n",
    4046             :                                                        (void *)asoc->asoc.locked_on_sending,
    4047             :                                                        asoc->asoc.locked_on_sending->stream_no);
    4048             :                                         } else {
    4049           0 :                                                 if ((sp->length == 0) && (sp->msg_is_complete == 0))
    4050           0 :                                                         asoc->asoc.state |= SCTP_STATE_PARTIAL_MSG_LEFT;
    4051             :                                         }
    4052             :                                 }
    4053           0 :                                 if (TAILQ_EMPTY(&asoc->asoc.send_queue) &&
    4054           0 :                                     TAILQ_EMPTY(&asoc->asoc.sent_queue) &&
    4055           0 :                                     (asoc->asoc.state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
    4056             :                                         struct mbuf *op_err;
    4057             :                                 abort_anyway:
    4058           0 :                                         op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
    4059           0 :                                         asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB+SCTP_LOC_5;
    4060           0 :                                         sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
    4061           0 :                                         SCTP_STAT_INCR_COUNTER32(sctps_aborted);
    4062           0 :                                         if ((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_OPEN) ||
    4063           0 :                                             (SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
    4064           0 :                                                 SCTP_STAT_DECR_GAUGE32(sctps_currestab);
    4065             :                                         }
    4066           0 :                                         if (sctp_free_assoc(inp, asoc,
    4067             :                                                             SCTP_PCBFREE_NOFORCE,
    4068             :                                                             SCTP_FROM_SCTP_PCB+SCTP_LOC_6) == 0) {
    4069           0 :                                                 cnt_in_sd++;
    4070             :                                         }
    4071           0 :                                         continue;
    4072             :                                 } else {
    4073           0 :                                         sctp_chunk_output(inp, asoc, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
    4074             :                                 }
    4075             :                         }
    4076           0 :                         cnt_in_sd++;
    4077           0 :                         SCTP_TCB_UNLOCK(asoc);
    4078             :                 }
    4079             :                 /* now is there some left in our SHUTDOWN state? */
    4080           0 :                 if (cnt_in_sd) {
    4081             : #ifdef SCTP_LOG_CLOSING
    4082             :                         sctp_log_closing(inp, NULL, 2);
    4083             : #endif
    4084           0 :                         inp->sctp_socket = NULL;
    4085           0 :                         SCTP_INP_WUNLOCK(inp);
    4086           0 :                         SCTP_ASOC_CREATE_UNLOCK(inp);
    4087           0 :                         SCTP_INP_INFO_WUNLOCK();
    4088           0 :                         return;
    4089             :                 }
    4090             :         }
    4091           0 :         inp->sctp_socket = NULL;
    4092           0 :         if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) !=
    4093             :             SCTP_PCB_FLAGS_UNBOUND) {
    4094             :                 /*
    4095             :                  * ok, this guy has been bound. It's port is
    4096             :                  * somewhere in the SCTP_BASE_INFO(hash table). Remove
    4097             :                  * it!
    4098             :                  */
    4099           0 :                 LIST_REMOVE(inp, sctp_hash);
    4100           0 :                 inp->sctp_flags |= SCTP_PCB_FLAGS_UNBOUND;
    4101             :         }
    4102             : 
    4103             :         /* If there is a timer running to kill us,
    4104             :          * forget it, since it may have a contest
    4105             :          * on the INP lock.. which would cause us
    4106             :          * to die ...
    4107             :          */
    4108           0 :         cnt = 0;
    4109           0 :         LIST_FOREACH_SAFE(asoc, &inp->sctp_asoc_list, sctp_tcblist, nasoc) {
    4110           0 :                 SCTP_TCB_LOCK(asoc);
    4111           0 :                 if (asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
    4112           0 :                         if (asoc->asoc.state & SCTP_STATE_IN_ACCEPT_QUEUE) {
    4113           0 :                                 asoc->asoc.state &= ~SCTP_STATE_IN_ACCEPT_QUEUE;
    4114           0 :                                 sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, asoc, NULL);
    4115             :                         }
    4116           0 :                         cnt++;
    4117           0 :                         SCTP_TCB_UNLOCK(asoc);
    4118           0 :                         continue;
    4119             :                 }
    4120             :                 /* Free associations that are NOT killing us */
    4121           0 :                 if ((SCTP_GET_STATE(&asoc->asoc) != SCTP_STATE_COOKIE_WAIT) &&
    4122           0 :                     ((asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) {
    4123             :                         struct mbuf *op_err;
    4124             : 
    4125           0 :                         op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
    4126           0 :                         asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB+SCTP_LOC_7;
    4127           0 :                         sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
    4128           0 :                         SCTP_STAT_INCR_COUNTER32(sctps_aborted);
    4129           0 :                 } else if (asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
    4130           0 :                         cnt++;
    4131           0 :                         SCTP_TCB_UNLOCK(asoc);
    4132           0 :                         continue;
    4133             :                 }
    4134           0 :                 if ((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_OPEN) ||
    4135           0 :                     (SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
    4136           0 :                         SCTP_STAT_DECR_GAUGE32(sctps_currestab);
    4137             :                 }
    4138           0 :                 if (sctp_free_assoc(inp, asoc, SCTP_PCBFREE_FORCE, SCTP_FROM_SCTP_PCB+SCTP_LOC_8) == 0) {
    4139           0 :                         cnt++;
    4140             :                 }
    4141             :         }
    4142           0 :         if (cnt) {
    4143             :                 /* Ok we have someone out there that will kill us */
    4144           0 :                 (void)SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
    4145             : #ifdef SCTP_LOG_CLOSING
    4146             :                 sctp_log_closing(inp, NULL, 3);
    4147             : #endif
    4148           0 :                 SCTP_INP_WUNLOCK(inp);
    4149           0 :                 SCTP_ASOC_CREATE_UNLOCK(inp);
    4150           0 :                 SCTP_INP_INFO_WUNLOCK();
    4151           0 :                 return;
    4152             :         }
    4153             :         if (SCTP_INP_LOCK_CONTENDED(inp))
    4154             :                 being_refed++;
    4155             :         if (SCTP_INP_READ_CONTENDED(inp))
    4156             :                 being_refed++;
    4157             :         if (SCTP_ASOC_CREATE_LOCK_CONTENDED(inp))
    4158             :                 being_refed++;
    4159             : 
    4160           0 :         if ((inp->refcount) ||
    4161           0 :             (being_refed) ||
    4162           0 :             (inp->sctp_flags & SCTP_PCB_FLAGS_CLOSE_IP)) {
    4163           0 :                 (void)SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
    4164             : #ifdef SCTP_LOG_CLOSING
    4165             :                 sctp_log_closing(inp, NULL, 4);
    4166             : #endif
    4167           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL);
    4168           0 :                 SCTP_INP_WUNLOCK(inp);
    4169           0 :                 SCTP_ASOC_CREATE_UNLOCK(inp);
    4170           0 :                 SCTP_INP_INFO_WUNLOCK();
    4171           0 :                 return;
    4172             :         }
    4173           0 :         inp->sctp_ep.signature_change.type = 0;
    4174           0 :         inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_ALLGONE;
    4175             :         /* Remove it from the list .. last thing we need a
    4176             :          * lock for.
    4177             :          */
    4178           0 :         LIST_REMOVE(inp, sctp_list);
    4179           0 :         SCTP_INP_WUNLOCK(inp);
    4180           0 :         SCTP_ASOC_CREATE_UNLOCK(inp);
    4181           0 :         SCTP_INP_INFO_WUNLOCK();
    4182             :         /* Now we release all locks. Since this INP
    4183             :          * cannot be found anymore except possibly by the
    4184             :          * kill timer that might be running. We call
    4185             :          * the drain function here. It should hit the case
    4186             :          * were it sees the ACTIVE flag cleared and exit
    4187             :          * out freeing us to proceed and destroy everything.
    4188             :          */
    4189           0 :         if (from != SCTP_CALLED_FROM_INPKILL_TIMER) {
    4190           0 :                 (void)SCTP_OS_TIMER_STOP_DRAIN(&inp->sctp_ep.signature_change.timer);
    4191             :         } else {
    4192             :                 /* Probably un-needed */
    4193           0 :                 (void)SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
    4194             :         }
    4195             : 
    4196             : #ifdef SCTP_LOG_CLOSING
    4197             :         sctp_log_closing(inp, NULL, 5);
    4198             : #endif
    4199             : 
    4200             : #if !(defined(__Panda__) || defined(__Windows__) || defined(__Userspace__))
    4201             : #if !defined(__FreeBSD__) || __FreeBSD_version < 500000
    4202             :         rt = ip_pcb->inp_route.ro_rt;
    4203             : #endif
    4204             : #endif
    4205             : 
    4206             : #if defined(__Panda__)
    4207             :         if (inp->pak_to_read) {
    4208             :                 (void)SCTP_OS_TIMER_STOP(&inp->sctp_ep.zero_copy_timer.timer);
    4209             :                 SCTP_RELEASE_PKT(inp->pak_to_read);
    4210             :                 inp->pak_to_read = NULL;
    4211             :         }
    4212             :         if (inp->pak_to_read_sendq) {
    4213             :                 (void)SCTP_OS_TIMER_STOP(&inp->sctp_ep.zero_copy_sendq_timer.timer);
    4214             :                 SCTP_RELEASE_PKT(inp->pak_to_read_sendq);
    4215             :                 inp->pak_to_read_sendq = NULL;
    4216             :         }
    4217             : #endif
    4218           0 :         if ((inp->sctp_asocidhash) != NULL) {
    4219           0 :                 SCTP_HASH_FREE(inp->sctp_asocidhash, inp->hashasocidmark);
    4220           0 :                 inp->sctp_asocidhash = NULL;
    4221             :         }
    4222             :         /*sa_ignore FREED_MEMORY*/
    4223           0 :         TAILQ_FOREACH_SAFE(sq, &inp->read_queue, next, nsq) {
    4224             :                 /* Its only abandoned if it had data left */
    4225           0 :                 if (sq->length)
    4226           0 :                         SCTP_STAT_INCR(sctps_left_abandon);
    4227             : 
    4228           0 :                 TAILQ_REMOVE(&inp->read_queue, sq, next);
    4229           0 :                 sctp_free_remote_addr(sq->whoFrom);
    4230           0 :                 if (so)
    4231           0 :                         so->so_rcv.sb_cc -= sq->length;
    4232           0 :                 if (sq->data) {
    4233           0 :                         sctp_m_freem(sq->data);
    4234           0 :                         sq->data = NULL;
    4235             :                 }
    4236             :                 /*
    4237             :                  * no need to free the net count, since at this point all
    4238             :                  * assoc's are gone.
    4239             :                  */
    4240           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), sq);
    4241           0 :                 SCTP_DECR_READQ_COUNT();
    4242             :         }
    4243             :         /* Now the sctp_pcb things */
    4244             :         /*
    4245             :          * free each asoc if it is not already closed/free. we can't use the
    4246             :          * macro here since le_next will get freed as part of the
    4247             :          * sctp_free_assoc() call.
    4248             :          */
    4249             :         if (so) {
    4250             : #ifdef IPSEC
    4251             :                 ipsec_delete_pcbpolicy(ip_pcb);
    4252             : #endif                          /* IPSEC */
    4253             : 
    4254             :                 /* Unlocks not needed since the socket is gone now */
    4255             :         }
    4256             : #ifndef __Panda__
    4257           0 :         if (ip_pcb->inp_options) {
    4258           0 :                 (void)sctp_m_free(ip_pcb->inp_options);
    4259           0 :                 ip_pcb->inp_options = 0;
    4260             :         }
    4261             : #endif
    4262             : 
    4263             : #if !(defined(__Panda__) || defined(__Windows__) || defined(__Userspace__))
    4264             : #if !defined(__FreeBSD__) || __FreeBSD_version < 500000
    4265             :         if (rt) {
    4266             :                 RTFREE(rt);
    4267             :                 ip_pcb->inp_route.ro_rt = 0;
    4268             :         }
    4269             : #endif
    4270             : #if defined(__FreeBSD__) && __FreeBSD_version < 803000
    4271             : #ifdef INET
    4272             :         if (ip_pcb->inp_moptions) {
    4273             :                 inp_freemoptions(ip_pcb->inp_moptions);
    4274             :                 ip_pcb->inp_moptions = 0;
    4275             :         }
    4276             : #endif
    4277             : #endif
    4278             : #endif
    4279             : 
    4280             : #ifdef INET6
    4281             : #if !(defined(__Panda__) || defined(__Windows__) || defined(__Userspace__))
    4282             : #if defined(__FreeBSD__) || defined(__APPLE__)
    4283             :         if (ip_pcb->inp_vflag & INP_IPV6) {
    4284             : #else
    4285             :         if (inp->inp_vflag & INP_IPV6) {
    4286             : #endif
    4287             :                 struct in6pcb *in6p;
    4288             : 
    4289             :                 in6p = (struct in6pcb *)inp;
    4290             :                 ip6_freepcbopts(in6p->in6p_outputopts);
    4291             :         }
    4292             : #endif
    4293             : #endif                          /* INET6 */
    4294             : #if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
    4295             :         inp->inp_vflag = 0;
    4296             : #else
    4297           0 :         ip_pcb->inp_vflag = 0;
    4298             : #endif
    4299             :         /* free up authentication fields */
    4300           0 :         if (inp->sctp_ep.local_auth_chunks != NULL)
    4301           0 :                 sctp_free_chunklist(inp->sctp_ep.local_auth_chunks);
    4302           0 :         if (inp->sctp_ep.local_hmacs != NULL)
    4303           0 :                 sctp_free_hmaclist(inp->sctp_ep.local_hmacs);
    4304             : 
    4305           0 :         LIST_FOREACH_SAFE(shared_key, &inp->sctp_ep.shared_keys, next, nshared_key) {
    4306           0 :                 LIST_REMOVE(shared_key, next);
    4307           0 :                 sctp_free_sharedkey(shared_key);
    4308             :                 /*sa_ignore FREED_MEMORY*/
    4309             :         }
    4310             : 
    4311             : #if defined(__APPLE__)
    4312             :         inp->ip_inp.inp.inp_state = INPCB_STATE_DEAD;
    4313             :         if (in_pcb_checkstate(&inp->ip_inp.inp, WNT_STOPUSING, 1) != WNT_STOPUSING) {
    4314             : #ifdef INVARIANTS
    4315             :                 panic("sctp_inpcb_free inp = %p couldn't set to STOPUSING\n", (void *)inp);
    4316             : #else
    4317             :                 SCTP_PRINTF("sctp_inpcb_free inp = %p couldn't set to STOPUSING\n", (void *)inp);
    4318             : #endif
    4319             :         }
    4320             :         inp->ip_inp.inp.inp_socket->so_flags |= SOF_PCBCLEARING;
    4321             : #endif
    4322             :         /*
    4323             :          * if we have an address list the following will free the list of
    4324             :          * ifaddr's that are set into this ep. Again macro limitations here,
    4325             :          * since the LIST_FOREACH could be a bad idea.
    4326             :          */
    4327           0 :         LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
    4328           0 :                 sctp_remove_laddr(laddr);
    4329             :         }
    4330             : 
    4331             : #ifdef SCTP_TRACK_FREED_ASOCS
    4332             :         /* TEMP CODE */
    4333             :         LIST_FOREACH_SAFE(asoc, &inp->sctp_asoc_free_list, sctp_tcblist, nasoc) {
    4334             :                 LIST_REMOVE(asoc, sctp_tcblist);
    4335             :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), asoc);
    4336             :                 SCTP_DECR_ASOC_COUNT();
    4337             :         }
    4338             :         /* *** END TEMP CODE ****/
    4339             : #endif
    4340             : #ifdef SCTP_MVRF
    4341             :         SCTP_FREE(inp->m_vrf_ids, SCTP_M_MVRF);
    4342             : #endif
    4343             :         /* Now lets see about freeing the EP hash table. */
    4344           0 :         if (inp->sctp_tcbhash != NULL) {
    4345           0 :                 SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark);
    4346           0 :                 inp->sctp_tcbhash = NULL;
    4347             :         }
    4348             :         /* Now we must put the ep memory back into the zone pool */
    4349             : #if defined(__FreeBSD__)
    4350             :         crfree(inp->ip_inp.inp.inp_cred);
    4351             :         INP_LOCK_DESTROY(&inp->ip_inp.inp);
    4352             : #endif
    4353           0 :         SCTP_INP_LOCK_DESTROY(inp);
    4354           0 :         SCTP_INP_READ_DESTROY(inp);
    4355           0 :         SCTP_ASOC_CREATE_LOCK_DESTROY(inp);
    4356             : #if !defined(__APPLE__)
    4357           0 :         SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
    4358           0 :         SCTP_DECR_EP_COUNT();
    4359             : #else
    4360             :         /* For Tiger, we will do this later... */
    4361             : #endif
    4362             : }
    4363             : 
    4364             : 
    4365             : struct sctp_nets *
    4366           0 : sctp_findnet(struct sctp_tcb *stcb, struct sockaddr *addr)
    4367             : {
    4368             :         struct sctp_nets *net;
    4369             :         /* locate the address */
    4370           0 :         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
    4371           0 :                 if (sctp_cmpaddr(addr, (struct sockaddr *)&net->ro._l_addr))
    4372           0 :                         return (net);
    4373             :         }
    4374           0 :         return (NULL);
    4375             : }
    4376             : 
    4377             : 
    4378             : int
    4379           0 : sctp_is_address_on_local_host(struct sockaddr *addr, uint32_t vrf_id)
    4380             : {
    4381             : #ifdef __Panda__
    4382             :         return (0);
    4383             : #else
    4384             :         struct sctp_ifa *sctp_ifa;
    4385           0 :         sctp_ifa = sctp_find_ifa_by_addr(addr, vrf_id, SCTP_ADDR_NOT_LOCKED);
    4386           0 :         if (sctp_ifa) {
    4387           0 :                 return (1);
    4388             :         } else {
    4389           0 :                 return (0);
    4390             :         }
    4391             : #endif
    4392             : }
    4393             : 
    4394             : /*
    4395             :  * add's a remote endpoint address, done with the INIT/INIT-ACK as well as
    4396             :  * when a ASCONF arrives that adds it. It will also initialize all the cwnd
    4397             :  * stats of stuff.
    4398             :  */
    4399             : int
    4400           0 : sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
    4401             :     struct sctp_nets **netp, int set_scope, int from)
    4402             : {
    4403             :         /*
    4404             :          * The following is redundant to the same lines in the
    4405             :          * sctp_aloc_assoc() but is needed since others call the add
    4406             :          * address function
    4407             :          */
    4408             :         struct sctp_nets *net, *netfirst;
    4409             :         int addr_inscope;
    4410             : 
    4411           0 :         SCTPDBG(SCTP_DEBUG_PCB1, "Adding an address (from:%d) to the peer: ",
    4412             :                 from);
    4413           0 :         SCTPDBG_ADDR(SCTP_DEBUG_PCB1, newaddr);
    4414             : 
    4415           0 :         netfirst = sctp_findnet(stcb, newaddr);
    4416           0 :         if (netfirst) {
    4417             :                 /*
    4418             :                  * Lie and return ok, we don't want to make the association
    4419             :                  * go away for this behavior. It will happen in the TCP
    4420             :                  * model in a connected socket. It does not reach the hash
    4421             :                  * table until after the association is built so it can't be
    4422             :                  * found. Mark as reachable, since the initial creation will
    4423             :                  * have been cleared and the NOT_IN_ASSOC flag will have
    4424             :                  * been added... and we don't want to end up removing it
    4425             :                  * back out.
    4426             :                  */
    4427           0 :                 if (netfirst->dest_state & SCTP_ADDR_UNCONFIRMED) {
    4428           0 :                         netfirst->dest_state = (SCTP_ADDR_REACHABLE |
    4429             :                             SCTP_ADDR_UNCONFIRMED);
    4430             :                 } else {
    4431           0 :                         netfirst->dest_state = SCTP_ADDR_REACHABLE;
    4432             :                 }
    4433             : 
    4434           0 :                 return (0);
    4435             :         }
    4436           0 :         addr_inscope = 1;
    4437           0 :         switch (newaddr->sa_family) {
    4438             : #ifdef INET
    4439             :         case AF_INET:
    4440             :         {
    4441             :                 struct sockaddr_in *sin;
    4442             : 
    4443             :                 sin = (struct sockaddr_in *)newaddr;
    4444             :                 if (sin->sin_addr.s_addr == 0) {
    4445             :                         /* Invalid address */
    4446             :                         return (-1);
    4447             :                 }
    4448             :                 /* zero out the bzero area */
    4449             :                 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
    4450             : 
    4451             :                 /* assure len is set */
    4452             : #ifdef HAVE_SIN_LEN
    4453             :                 sin->sin_len = sizeof(struct sockaddr_in);
    4454             : #endif
    4455             :                 if (set_scope) {
    4456             : #ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
    4457             :                         stcb->asoc.scope.ipv4_local_scope = 1;
    4458             : #else
    4459             :                         if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
    4460             :                                 stcb->asoc.scope.ipv4_local_scope = 1;
    4461             :                         }
    4462             : #endif                          /* SCTP_DONT_DO_PRIVADDR_SCOPE */
    4463             :                 } else {
    4464             :                         /* Validate the address is in scope */
    4465             :                         if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) &&
    4466             :                             (stcb->asoc.scope.ipv4_local_scope == 0)) {
    4467             :                                 addr_inscope = 0;
    4468             :                         }
    4469             :                 }
    4470             :                 break;
    4471             :         }
    4472             : #endif
    4473             : #ifdef INET6
    4474             :         case AF_INET6:
    4475             :         {
    4476             :                 struct sockaddr_in6 *sin6;
    4477             : 
    4478             :                 sin6 = (struct sockaddr_in6 *)newaddr;
    4479             :                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
    4480             :                         /* Invalid address */
    4481             :                         return (-1);
    4482             :                 }
    4483             :                 /* assure len is set */
    4484             : #ifdef HAVE_SIN6_LEN
    4485             :                 sin6->sin6_len = sizeof(struct sockaddr_in6);
    4486             : #endif
    4487             :                 if (set_scope) {
    4488             :                         if (sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id)) {
    4489             :                                 stcb->asoc.scope.loopback_scope = 1;
    4490             :                                 stcb->asoc.scope.local_scope = 0;
    4491             :                                 stcb->asoc.scope.ipv4_local_scope = 1;
    4492             :                                 stcb->asoc.scope.site_scope = 1;
    4493             :                         } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
    4494             :                                 /*
    4495             :                                  * If the new destination is a LINK_LOCAL we
    4496             :                                  * must have common site scope. Don't set
    4497             :                                  * the local scope since we may not share
    4498             :                                  * all links, only loopback can do this.
    4499             :                                  * Links on the local network would also be
    4500             :                                  * on our private network for v4 too.
    4501             :                                  */
    4502             :                                 stcb->asoc.scope.ipv4_local_scope = 1;
    4503             :                                 stcb->asoc.scope.site_scope = 1;
    4504             :                         } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
    4505             :                                 /*
    4506             :                                  * If the new destination is SITE_LOCAL then
    4507             :                                  * we must have site scope in common.
    4508             :                                  */
    4509             :                                 stcb->asoc.scope.site_scope = 1;
    4510             :                         }
    4511             :                 } else {
    4512             :                         /* Validate the address is in scope */
    4513             :                         if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) &&
    4514             :                             (stcb->asoc.scope.loopback_scope == 0)) {
    4515             :                                 addr_inscope = 0;
    4516             :                         } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
    4517             :                             (stcb->asoc.scope.local_scope == 0)) {
    4518             :                                 addr_inscope = 0;
    4519             :                         } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&
    4520             :                             (stcb->asoc.scope.site_scope == 0)) {
    4521             :                                 addr_inscope = 0;
    4522             :                         }
    4523             :                 }
    4524             :                 break;
    4525             :         }
    4526             : #endif
    4527             : #if defined(__Userspace__)
    4528             :         case AF_CONN:
    4529             :         {
    4530             :                 struct sockaddr_conn *sconn;
    4531             : 
    4532           0 :                 sconn = (struct sockaddr_conn *)newaddr;
    4533           0 :                 if (sconn->sconn_addr == NULL) {
    4534             :                         /* Invalid address */
    4535           0 :                         return (-1);
    4536             :                 }
    4537             : #ifdef HAVE_SCONN_LEN
    4538             :                 sconn->sconn_len = sizeof(struct sockaddr_conn);
    4539             : #endif
    4540           0 :                 break;
    4541             :         }
    4542             : #endif
    4543             :         default:
    4544             :                 /* not supported family type */
    4545           0 :                 return (-1);
    4546             :         }
    4547           0 :         net = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_net), struct sctp_nets);
    4548           0 :         if (net == NULL) {
    4549           0 :                 return (-1);
    4550             :         }
    4551           0 :         SCTP_INCR_RADDR_COUNT();
    4552           0 :         bzero(net, sizeof(struct sctp_nets));
    4553           0 :         (void)SCTP_GETTIME_TIMEVAL(&net->start_time);
    4554             : #ifdef HAVE_SA_LEN
    4555             :         memcpy(&net->ro._l_addr, newaddr, newaddr->sa_len);
    4556             : #endif
    4557           0 :         switch (newaddr->sa_family) {
    4558             : #ifdef INET
    4559             :         case AF_INET:
    4560             : #ifndef HAVE_SA_LEN
    4561             :                 memcpy(&net->ro._l_addr, newaddr, sizeof(struct sockaddr_in));
    4562             : #endif
    4563             :                 ((struct sockaddr_in *)&net->ro._l_addr)->sin_port = stcb->rport;
    4564             :                 break;
    4565             : #endif
    4566             : #ifdef INET6
    4567             :         case AF_INET6:
    4568             : #ifndef HAVE_SA_LEN
    4569             :                 memcpy(&net->ro._l_addr, newaddr, sizeof(struct sockaddr_in6));
    4570             : #endif
    4571             :                 ((struct sockaddr_in6 *)&net->ro._l_addr)->sin6_port = stcb->rport;
    4572             :                 break;
    4573             : #endif
    4574             : #if defined(__Userspace__)
    4575             :         case AF_CONN:
    4576             : #ifndef HAVE_SA_LEN
    4577           0 :                 memcpy(&net->ro._l_addr, newaddr, sizeof(struct sockaddr_conn));
    4578             : #endif
    4579           0 :                 ((struct sockaddr_conn *)&net->ro._l_addr)->sconn_port = stcb->rport;
    4580           0 :                 break;
    4581             : #endif
    4582             :         default:
    4583           0 :                 break;
    4584             :         }
    4585           0 :         net->addr_is_local = sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id);
    4586           0 :         if (net->addr_is_local && ((set_scope || (from == SCTP_ADDR_IS_CONFIRMED)))) {
    4587           0 :                 stcb->asoc.scope.loopback_scope = 1;
    4588           0 :                 stcb->asoc.scope.ipv4_local_scope = 1;
    4589           0 :                 stcb->asoc.scope.local_scope = 0;
    4590           0 :                 stcb->asoc.scope.site_scope = 1;
    4591           0 :                 addr_inscope = 1;
    4592             :         }
    4593           0 :         net->failure_threshold = stcb->asoc.def_net_failure;
    4594           0 :         net->pf_threshold = stcb->asoc.def_net_pf_threshold;
    4595           0 :         if (addr_inscope == 0) {
    4596           0 :                 net->dest_state = (SCTP_ADDR_REACHABLE |
    4597             :                     SCTP_ADDR_OUT_OF_SCOPE);
    4598             :         } else {
    4599           0 :                 if (from == SCTP_ADDR_IS_CONFIRMED)
    4600             :                         /* SCTP_ADDR_IS_CONFIRMED is passed by connect_x */
    4601           0 :                         net->dest_state = SCTP_ADDR_REACHABLE;
    4602             :                 else
    4603           0 :                         net->dest_state = SCTP_ADDR_REACHABLE |
    4604             :                             SCTP_ADDR_UNCONFIRMED;
    4605             :         }
    4606             :         /* We set this to 0, the timer code knows that
    4607             :          * this means its an initial value
    4608             :          */
    4609           0 :         net->rto_needed = 1;
    4610           0 :         net->RTO = 0;
    4611           0 :         net->RTO_measured = 0;
    4612           0 :         stcb->asoc.numnets++;
    4613           0 :         net->ref_count = 1;
    4614           0 :         net->cwr_window_tsn = net->last_cwr_tsn = stcb->asoc.sending_seq - 1;
    4615           0 :         net->port = stcb->asoc.port;
    4616           0 :         net->dscp = stcb->asoc.default_dscp;
    4617             : #ifdef INET6
    4618             :         net->flowlabel = stcb->asoc.default_flowlabel;
    4619             : #endif
    4620           0 :         if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) {
    4621           0 :                 net->dest_state |= SCTP_ADDR_NOHB;
    4622             :         } else {
    4623           0 :                 net->dest_state &= ~SCTP_ADDR_NOHB;
    4624             :         }
    4625           0 :         if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) {
    4626           0 :                 net->dest_state |= SCTP_ADDR_NO_PMTUD;
    4627             :         } else {
    4628           0 :                 net->dest_state &= ~SCTP_ADDR_NO_PMTUD;
    4629             :         }
    4630           0 :         net->heart_beat_delay = stcb->asoc.heart_beat_delay;
    4631             :         /* Init the timer structure */
    4632           0 :         SCTP_OS_TIMER_INIT(&net->rxt_timer.timer);
    4633           0 :         SCTP_OS_TIMER_INIT(&net->pmtu_timer.timer);
    4634           0 :         SCTP_OS_TIMER_INIT(&net->hb_timer.timer);
    4635             : 
    4636             :         /* Now generate a route for this guy */
    4637             : #ifdef INET6
    4638             : #ifdef SCTP_EMBEDDED_V6_SCOPE
    4639             :         /* KAME hack: embed scopeid */
    4640             :         if (newaddr->sa_family == AF_INET6) {
    4641             :                 struct sockaddr_in6 *sin6;
    4642             : 
    4643             :                 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
    4644             : #if defined(__APPLE__)
    4645             : #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
    4646             :                 (void)in6_embedscope(&sin6->sin6_addr, sin6, &stcb->sctp_ep->ip_inp.inp, NULL);
    4647             : #else
    4648             :                 (void)in6_embedscope(&sin6->sin6_addr, sin6, &stcb->sctp_ep->ip_inp.inp, NULL, NULL);
    4649             : #endif
    4650             : #elif defined(SCTP_KAME)
    4651             :                 (void)sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
    4652             : #else
    4653             :                 (void)in6_embedscope(&sin6->sin6_addr, sin6);
    4654             : #endif
    4655             : #ifndef SCOPEDROUTING
    4656             :                 sin6->sin6_scope_id = 0;
    4657             : #endif
    4658             :         }
    4659             : #endif /* SCTP_EMBEDDED_V6_SCOPE */
    4660             : #endif
    4661           0 :         SCTP_RTALLOC((sctp_route_t *)&net->ro, stcb->asoc.vrf_id);
    4662             : 
    4663             : #if defined(__Userspace__)
    4664           0 :         net->src_addr_selected = 0;
    4665             : #else
    4666             :         if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) {
    4667             :                 /* Get source address */
    4668             :                 net->ro._s_addr = sctp_source_address_selection(stcb->sctp_ep,
    4669             :                                                                 stcb,
    4670             :                                                                 (sctp_route_t *)&net->ro,
    4671             :                                                                 net,
    4672             :                                                                 0,
    4673             :                                                                 stcb->asoc.vrf_id);
    4674             :                 if (net->ro._s_addr != NULL) {
    4675             :                         net->src_addr_selected = 1;
    4676             :                         /* Now get the interface MTU */
    4677             :                         if (net->ro._s_addr->ifn_p != NULL) {
    4678             :                                 net->mtu = SCTP_GATHER_MTU_FROM_INTFC(net->ro._s_addr->ifn_p);
    4679             :                         }
    4680             :                 } else {
    4681             :                         net->src_addr_selected = 0;
    4682             :                 }
    4683             :                 if (net->mtu > 0) {
    4684             :                         uint32_t rmtu;
    4685             : 
    4686             :                         rmtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, net->ro.ro_rt);
    4687             :                         if (rmtu == 0) {
    4688             :                                 /* Start things off to match mtu of interface please. */
    4689             :                                 SCTP_SET_MTU_OF_ROUTE(&net->ro._l_addr.sa,
    4690             :                                                       net->ro.ro_rt, net->mtu);
    4691             :                         } else {
    4692             :                                 /* we take the route mtu over the interface, since
    4693             :                                  * the route may be leading out the loopback, or
    4694             :                                  * a different interface.
    4695             :                                  */
    4696             :                                 net->mtu = rmtu;
    4697             :                         }
    4698             :                 }
    4699             :         } else {
    4700             :                 net->src_addr_selected = 0;
    4701             :         }
    4702             : #endif
    4703           0 :         if (net->mtu == 0) {
    4704           0 :                 switch (newaddr->sa_family) {
    4705             : #ifdef INET
    4706             :                 case AF_INET:
    4707             :                         net->mtu = SCTP_DEFAULT_MTU;
    4708             :                         break;
    4709             : #endif
    4710             : #ifdef INET6
    4711             :                 case AF_INET6:
    4712             :                         net->mtu = 1280;
    4713             :                         break;
    4714             : #endif
    4715             : #if defined(__Userspace__)
    4716             :                 case AF_CONN:
    4717           0 :                         net->mtu = 1280;
    4718           0 :                         break;
    4719             : #endif
    4720             :                 default:
    4721           0 :                         break;
    4722             :                 }
    4723             :         }
    4724             : #if defined(INET) || defined(INET6)
    4725             :         if (net->port) {
    4726             :                 net->mtu -= (uint32_t)sizeof(struct udphdr);
    4727             :         }
    4728             : #endif
    4729           0 :         if (from == SCTP_ALLOC_ASOC) {
    4730           0 :                 stcb->asoc.smallest_mtu = net->mtu;
    4731             :         }
    4732           0 :         if (stcb->asoc.smallest_mtu > net->mtu) {
    4733           0 :                 stcb->asoc.smallest_mtu = net->mtu;
    4734             :         }
    4735             : #ifdef INET6
    4736             : #ifdef SCTP_EMBEDDED_V6_SCOPE
    4737             :         if (newaddr->sa_family == AF_INET6) {
    4738             :                 struct sockaddr_in6 *sin6;
    4739             : 
    4740             :                 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
    4741             : #ifdef SCTP_KAME
    4742             :                 (void)sa6_recoverscope(sin6);
    4743             : #else
    4744             :                 (void)in6_recoverscope(sin6, &sin6->sin6_addr, NULL);
    4745             : #endif /* SCTP_KAME */
    4746             :         }
    4747             : #endif /* SCTP_EMBEDDED_V6_SCOPE */
    4748             : #endif
    4749             : 
    4750             :         /* JRS - Use the congestion control given in the CC module */
    4751           0 :         if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL)
    4752           0 :                 (*stcb->asoc.cc_functions.sctp_set_initial_cc_param)(stcb, net);
    4753             : 
    4754             :         /*
    4755             :          * CMT: CUC algo - set find_pseudo_cumack to TRUE (1) at beginning
    4756             :          * of assoc (2005/06/27, iyengar@cis.udel.edu)
    4757             :          */
    4758           0 :         net->find_pseudo_cumack = 1;
    4759           0 :         net->find_rtx_pseudo_cumack = 1;
    4760             : #if defined(__FreeBSD__)
    4761             :         /* Choose an initial flowid. */
    4762             :         net->flowid = stcb->asoc.my_vtag ^
    4763             :                       ntohs(stcb->rport) ^
    4764             :                       ntohs(stcb->sctp_ep->sctp_lport);
    4765             :         net->flowtype = M_HASHTYPE_OPAQUE;
    4766             : #endif
    4767           0 :         if (netp) {
    4768           0 :                 *netp = net;
    4769             :         }
    4770           0 :         netfirst = TAILQ_FIRST(&stcb->asoc.nets);
    4771           0 :         if (net->ro.ro_rt == NULL) {
    4772             :                 /* Since we have no route put it at the back */
    4773           0 :                 TAILQ_INSERT_TAIL(&stcb->asoc.nets, net, sctp_next);
    4774           0 :         } else if (netfirst == NULL) {
    4775             :                 /* We are the first one in the pool. */
    4776           0 :                 TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next);
    4777           0 :         } else if (netfirst->ro.ro_rt == NULL) {
    4778             :                 /*
    4779             :                  * First one has NO route. Place this one ahead of the first
    4780             :                  * one.
    4781             :                  */
    4782           0 :                 TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next);
    4783             : #ifndef __Panda__
    4784           0 :         } else if (net->ro.ro_rt->rt_ifp != netfirst->ro.ro_rt->rt_ifp) {
    4785             :                 /*
    4786             :                  * This one has a different interface than the one at the
    4787             :                  * top of the list. Place it ahead.
    4788             :                  */
    4789           0 :                 TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next);
    4790             : #endif
    4791             :         } else {
    4792             :                 /*
    4793             :                  * Ok we have the same interface as the first one. Move
    4794             :                  * forward until we find either a) one with a NULL route...
    4795             :                  * insert ahead of that b) one with a different ifp.. insert
    4796             :                  * after that. c) end of the list.. insert at the tail.
    4797             :                  */
    4798             :                 struct sctp_nets *netlook;
    4799             : 
    4800             :                 do {
    4801           0 :                         netlook = TAILQ_NEXT(netfirst, sctp_next);
    4802           0 :                         if (netlook == NULL) {
    4803             :                                 /* End of the list */
    4804           0 :                                 TAILQ_INSERT_TAIL(&stcb->asoc.nets, net, sctp_next);
    4805           0 :                                 break;
    4806           0 :                         } else if (netlook->ro.ro_rt == NULL) {
    4807             :                                 /* next one has NO route */
    4808           0 :                                 TAILQ_INSERT_BEFORE(netfirst, net, sctp_next);
    4809           0 :                                 break;
    4810             :                         }
    4811             : #ifndef __Panda__
    4812           0 :                         else if (netlook->ro.ro_rt->rt_ifp != net->ro.ro_rt->rt_ifp)
    4813             : #else
    4814             :                         else
    4815             : #endif
    4816             :                         {
    4817           0 :                                 TAILQ_INSERT_AFTER(&stcb->asoc.nets, netlook,
    4818             :                                                    net, sctp_next);
    4819           0 :                                 break;
    4820             :                         }
    4821             : #ifndef __Panda__
    4822             :                         /* Shift forward */
    4823           0 :                         netfirst = netlook;
    4824             : #endif
    4825           0 :                 } while (netlook != NULL);
    4826             :         }
    4827             : 
    4828             :         /* got to have a primary set */
    4829           0 :         if (stcb->asoc.primary_destination == 0) {
    4830           0 :                 stcb->asoc.primary_destination = net;
    4831           0 :         } else if ((stcb->asoc.primary_destination->ro.ro_rt == NULL) &&
    4832           0 :                     (net->ro.ro_rt) &&
    4833           0 :             ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0)) {
    4834             :                 /* No route to current primary adopt new primary */
    4835           0 :                 stcb->asoc.primary_destination = net;
    4836             :         }
    4837             :         /* Validate primary is first */
    4838           0 :         net = TAILQ_FIRST(&stcb->asoc.nets);
    4839           0 :         if ((net != stcb->asoc.primary_destination) &&
    4840           0 :             (stcb->asoc.primary_destination)) {
    4841             :                 /* first one on the list is NOT the primary
    4842             :                  * sctp_cmpaddr() is much more efficient if
    4843             :                  * the primary is the first on the list, make it
    4844             :                  * so.
    4845             :                  */
    4846           0 :                 TAILQ_REMOVE(&stcb->asoc.nets,
    4847             :                              stcb->asoc.primary_destination, sctp_next);
    4848           0 :                 TAILQ_INSERT_HEAD(&stcb->asoc.nets,
    4849             :                                   stcb->asoc.primary_destination, sctp_next);
    4850             :         }
    4851           0 :         return (0);
    4852             : }
    4853             : 
    4854             : 
    4855             : static uint32_t
    4856           0 : sctp_aloc_a_assoc_id(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
    4857             : {
    4858             :         uint32_t id;
    4859             :         struct sctpasochead *head;
    4860             :         struct sctp_tcb *lstcb;
    4861             : 
    4862           0 :         SCTP_INP_WLOCK(inp);
    4863             :  try_again:
    4864           0 :         if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
    4865             :                 /* TSNH */
    4866           0 :                 SCTP_INP_WUNLOCK(inp);
    4867           0 :                 return (0);
    4868             :         }
    4869             :         /*
    4870             :          * We don't allow assoc id to be one of SCTP_FUTURE_ASSOC,
    4871             :          * SCTP_CURRENT_ASSOC and SCTP_ALL_ASSOC.
    4872             :          */
    4873           0 :         if (inp->sctp_associd_counter <= SCTP_ALL_ASSOC) {
    4874           0 :                 inp->sctp_associd_counter = SCTP_ALL_ASSOC + 1;
    4875             :         }
    4876           0 :         id = inp->sctp_associd_counter;
    4877           0 :         inp->sctp_associd_counter++;
    4878           0 :         lstcb = sctp_findasoc_ep_asocid_locked(inp, (sctp_assoc_t)id, 0);
    4879           0 :         if (lstcb) {
    4880           0 :                 goto try_again;
    4881             :         }
    4882           0 :         head = &inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(id, inp->hashasocidmark)];
    4883           0 :         LIST_INSERT_HEAD(head, stcb, sctp_tcbasocidhash);
    4884           0 :         stcb->asoc.in_asocid_hash = 1;
    4885           0 :         SCTP_INP_WUNLOCK(inp);
    4886           0 :         return id;
    4887             : }
    4888             : 
    4889             : /*
    4890             :  * allocate an association and add it to the endpoint. The caller must be
    4891             :  * careful to add all additional addresses once they are know right away or
    4892             :  * else the assoc will be may experience a blackout scenario.
    4893             :  */
    4894             : struct sctp_tcb *
    4895           0 : sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
    4896             :                 int *error, uint32_t override_tag, uint32_t vrf_id,
    4897             : #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
    4898             :                 struct thread *p
    4899             : #elif defined(__Windows__)
    4900             :                 PKTHREAD p
    4901             : #else
    4902             : #if defined(__Userspace__)
    4903             :                 /*  __Userspace__ NULL proc is going to be passed here. See sctp_lower_sosend */
    4904             : #endif
    4905             :                 struct proc *p
    4906             : #endif
    4907             : )
    4908             : {
    4909             :         /* note the p argument is only valid in unbound sockets */
    4910             : 
    4911             :         struct sctp_tcb *stcb;
    4912             :         struct sctp_association *asoc;
    4913             :         struct sctpasochead *head;
    4914             :         uint16_t rport;
    4915             :         int err;
    4916             : 
    4917             :         /*
    4918             :          * Assumption made here: Caller has done a
    4919             :          * sctp_findassociation_ep_addr(ep, addr's); to make sure the
    4920             :          * address does not exist already.
    4921             :          */
    4922           0 :         if (SCTP_BASE_INFO(ipi_count_asoc) >= SCTP_MAX_NUM_OF_ASOC) {
    4923             :                 /* Hit max assoc, sorry no more */
    4924             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
    4925           0 :                 *error = ENOBUFS;
    4926           0 :                 return (NULL);
    4927             :         }
    4928           0 :         if (firstaddr == NULL) {
    4929             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    4930           0 :                 *error = EINVAL;
    4931           0 :                 return (NULL);
    4932             :         }
    4933           0 :         SCTP_INP_RLOCK(inp);
    4934           0 :         if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) &&
    4935           0 :             ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE)) ||
    4936           0 :              (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) {
    4937             :                 /*
    4938             :                  * If its in the TCP pool, its NOT allowed to create an
    4939             :                  * association. The parent listener needs to call
    4940             :                  * sctp_aloc_assoc.. or the one-2-many socket. If a peeled
    4941             :                  * off, or connected one does this.. its an error.
    4942             :                  */
    4943           0 :                 SCTP_INP_RUNLOCK(inp);
    4944             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    4945           0 :                 *error = EINVAL;
    4946           0 :                 return (NULL);
    4947             :         }
    4948           0 :         if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
    4949           0 :             (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)) {
    4950           0 :                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) ||
    4951           0 :                     (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED)) {
    4952           0 :                         SCTP_INP_RUNLOCK(inp);
    4953             :                         SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    4954           0 :                         *error = EINVAL;
    4955           0 :                         return (NULL);
    4956             :                 }
    4957             :         }
    4958           0 :         SCTPDBG(SCTP_DEBUG_PCB3, "Allocate an association for peer:");
    4959             : #ifdef SCTP_DEBUG
    4960           0 :         if (firstaddr) {
    4961           0 :                 SCTPDBG_ADDR(SCTP_DEBUG_PCB3, firstaddr);
    4962           0 :                 switch (firstaddr->sa_family) {
    4963             : #ifdef INET
    4964             :                 case AF_INET:
    4965             :                         SCTPDBG(SCTP_DEBUG_PCB3, "Port:%d\n",
    4966             :                                 ntohs(((struct sockaddr_in *)firstaddr)->sin_port));
    4967             :                         break;
    4968             : #endif
    4969             : #ifdef INET6
    4970             :                 case AF_INET6:
    4971             :                         SCTPDBG(SCTP_DEBUG_PCB3, "Port:%d\n",
    4972             :                                 ntohs(((struct sockaddr_in6 *)firstaddr)->sin6_port));
    4973             :                         break;
    4974             : #endif
    4975             : #if defined(__Userspace__)
    4976             :                 case AF_CONN:
    4977           0 :                         SCTPDBG(SCTP_DEBUG_PCB3, "Port:%d\n",
    4978             :                                 ntohs(((struct sockaddr_conn *)firstaddr)->sconn_port));
    4979           0 :                         break;
    4980             : #endif
    4981             :                 default:
    4982           0 :                         break;
    4983             :                 }
    4984             :         } else {
    4985           0 :                 SCTPDBG(SCTP_DEBUG_PCB3,"None\n");
    4986             :         }
    4987             : #endif                          /* SCTP_DEBUG */
    4988           0 :         switch (firstaddr->sa_family) {
    4989             : #ifdef INET
    4990             :         case AF_INET:
    4991             :         {
    4992             :                 struct sockaddr_in *sin;
    4993             : 
    4994             :                 sin = (struct sockaddr_in *)firstaddr;
    4995             :                 if ((ntohs(sin->sin_port) == 0) ||
    4996             :                     (sin->sin_addr.s_addr == INADDR_ANY) ||
    4997             :                     (sin->sin_addr.s_addr == INADDR_BROADCAST) ||
    4998             :                     IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
    4999             :                         /* Invalid address */
    5000             :                         SCTP_INP_RUNLOCK(inp);
    5001             :                         SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    5002             :                         *error = EINVAL;
    5003             :                         return (NULL);
    5004             :                 }
    5005             :                 rport = sin->sin_port;
    5006             :                 break;
    5007             :         }
    5008             : #endif
    5009             : #ifdef INET6
    5010             :         case AF_INET6:
    5011             :         {
    5012             :                 struct sockaddr_in6 *sin6;
    5013             : 
    5014             :                 sin6 = (struct sockaddr_in6 *)firstaddr;
    5015             :                 if ((ntohs(sin6->sin6_port) == 0) ||
    5016             :                     IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
    5017             :                     IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
    5018             :                         /* Invalid address */
    5019             :                         SCTP_INP_RUNLOCK(inp);
    5020             :                         SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    5021             :                         *error = EINVAL;
    5022             :                         return (NULL);
    5023             :                 }
    5024             :                 rport = sin6->sin6_port;
    5025             :                 break;
    5026             :         }
    5027             : #endif
    5028             : #if defined(__Userspace__)
    5029             :         case AF_CONN:
    5030             :         {
    5031             :                 struct sockaddr_conn *sconn;
    5032             : 
    5033           0 :                 sconn = (struct sockaddr_conn *)firstaddr;
    5034           0 :                 if ((ntohs(sconn->sconn_port) == 0) ||
    5035           0 :                     (sconn->sconn_addr == NULL)) {
    5036             :                         /* Invalid address */
    5037           0 :                         SCTP_INP_RUNLOCK(inp);
    5038             :                         SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    5039           0 :                         *error = EINVAL;
    5040           0 :                         return (NULL);
    5041             :                 }
    5042           0 :                 rport = sconn->sconn_port;
    5043           0 :                 break;
    5044             :         }
    5045             : #endif
    5046             :         default:
    5047             :                 /* not supported family type */
    5048           0 :                 SCTP_INP_RUNLOCK(inp);
    5049             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    5050           0 :                 *error = EINVAL;
    5051           0 :                 return (NULL);
    5052             :         }
    5053           0 :         SCTP_INP_RUNLOCK(inp);
    5054           0 :         if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
    5055             :                 /*
    5056             :                  * If you have not performed a bind, then we need to do the
    5057             :                  * ephemeral bind for you.
    5058             :                  */
    5059           0 :                 if ((err = sctp_inpcb_bind(inp->sctp_socket,
    5060             :                     (struct sockaddr *)NULL,
    5061             :                     (struct sctp_ifa *)NULL,
    5062             : #ifndef __Panda__
    5063             :                                            p
    5064             : #else
    5065             :                                            (struct proc *)NULL
    5066             : #endif
    5067             :                     ))) {
    5068             :                         /* bind error, probably perm */
    5069           0 :                         *error = err;
    5070           0 :                         return (NULL);
    5071             :                 }
    5072             :         }
    5073           0 :         stcb = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_asoc), struct sctp_tcb);
    5074           0 :         if (stcb == NULL) {
    5075             :                 /* out of memory? */
    5076             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOMEM);
    5077           0 :                 *error = ENOMEM;
    5078           0 :                 return (NULL);
    5079             :         }
    5080           0 :         SCTP_INCR_ASOC_COUNT();
    5081             : 
    5082           0 :         bzero(stcb, sizeof(*stcb));
    5083           0 :         asoc = &stcb->asoc;
    5084             : 
    5085           0 :         asoc->assoc_id = sctp_aloc_a_assoc_id(inp, stcb);
    5086           0 :         SCTP_TCB_LOCK_INIT(stcb);
    5087           0 :         SCTP_TCB_SEND_LOCK_INIT(stcb);
    5088           0 :         stcb->rport = rport;
    5089             :         /* setup back pointer's */
    5090           0 :         stcb->sctp_ep = inp;
    5091           0 :         stcb->sctp_socket = inp->sctp_socket;
    5092           0 :         if ((err = sctp_init_asoc(inp, stcb, override_tag, vrf_id))) {
    5093             :                 /* failed */
    5094           0 :                 SCTP_TCB_LOCK_DESTROY(stcb);
    5095           0 :                 SCTP_TCB_SEND_LOCK_DESTROY(stcb);
    5096           0 :                 LIST_REMOVE(stcb, sctp_tcbasocidhash);
    5097           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
    5098           0 :                 SCTP_DECR_ASOC_COUNT();
    5099           0 :                 *error = err;
    5100           0 :                 return (NULL);
    5101             :         }
    5102             :         /* and the port */
    5103           0 :         SCTP_INP_INFO_WLOCK();
    5104           0 :         SCTP_INP_WLOCK(inp);
    5105           0 :         if (inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
    5106             :                 /* inpcb freed while alloc going on */
    5107           0 :                 SCTP_TCB_LOCK_DESTROY(stcb);
    5108           0 :                 SCTP_TCB_SEND_LOCK_DESTROY(stcb);
    5109           0 :                 LIST_REMOVE(stcb, sctp_tcbasocidhash);
    5110           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
    5111           0 :                 SCTP_INP_WUNLOCK(inp);
    5112           0 :                 SCTP_INP_INFO_WUNLOCK();
    5113           0 :                 SCTP_DECR_ASOC_COUNT();
    5114             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    5115           0 :                 *error = EINVAL;
    5116           0 :                 return (NULL);
    5117             :         }
    5118           0 :         SCTP_TCB_LOCK(stcb);
    5119             : 
    5120             :         /* now that my_vtag is set, add it to the hash */
    5121           0 :         head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
    5122             :         /* put it in the bucket in the vtag hash of assoc's for the system */
    5123           0 :         LIST_INSERT_HEAD(head, stcb, sctp_asocs);
    5124           0 :         SCTP_INP_INFO_WUNLOCK();
    5125             : 
    5126           0 :         if ((err = sctp_add_remote_addr(stcb, firstaddr, NULL, SCTP_DO_SETSCOPE, SCTP_ALLOC_ASOC))) {
    5127             :                 /* failure.. memory error? */
    5128           0 :                 if (asoc->strmout) {
    5129           0 :                         SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
    5130           0 :                         asoc->strmout = NULL;
    5131             :                 }
    5132           0 :                 if (asoc->mapping_array) {
    5133           0 :                         SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
    5134           0 :                         asoc->mapping_array = NULL;
    5135             :                 }
    5136           0 :                 if (asoc->nr_mapping_array) {
    5137           0 :                         SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
    5138           0 :                         asoc->nr_mapping_array = NULL;
    5139             :                 }
    5140           0 :                 SCTP_DECR_ASOC_COUNT();
    5141           0 :                 SCTP_TCB_UNLOCK(stcb);
    5142           0 :                 SCTP_TCB_LOCK_DESTROY(stcb);
    5143           0 :                 SCTP_TCB_SEND_LOCK_DESTROY(stcb);
    5144           0 :                 LIST_REMOVE(stcb, sctp_tcbasocidhash);
    5145           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
    5146           0 :                 SCTP_INP_WUNLOCK(inp);
    5147             :                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
    5148           0 :                 *error = ENOBUFS;
    5149           0 :                 return (NULL);
    5150             :         }
    5151             :         /* Init all the timers */
    5152           0 :         SCTP_OS_TIMER_INIT(&asoc->dack_timer.timer);
    5153           0 :         SCTP_OS_TIMER_INIT(&asoc->strreset_timer.timer);
    5154           0 :         SCTP_OS_TIMER_INIT(&asoc->asconf_timer.timer);
    5155           0 :         SCTP_OS_TIMER_INIT(&asoc->shut_guard_timer.timer);
    5156           0 :         SCTP_OS_TIMER_INIT(&asoc->autoclose_timer.timer);
    5157           0 :         SCTP_OS_TIMER_INIT(&asoc->delayed_event_timer.timer);
    5158           0 :         SCTP_OS_TIMER_INIT(&asoc->delete_prim_timer.timer);
    5159             : 
    5160           0 :         LIST_INSERT_HEAD(&inp->sctp_asoc_list, stcb, sctp_tcblist);
    5161             :         /* now file the port under the hash as well */
    5162           0 :         if (inp->sctp_tcbhash != NULL) {
    5163           0 :                 head = &inp->sctp_tcbhash[SCTP_PCBHASH_ALLADDR(stcb->rport,
    5164             :                     inp->sctp_hashmark)];
    5165           0 :                 LIST_INSERT_HEAD(head, stcb, sctp_tcbhash);
    5166             :         }
    5167           0 :         SCTP_INP_WUNLOCK(inp);
    5168           0 :         SCTPDBG(SCTP_DEBUG_PCB1, "Association %p now allocated\n", (void *)stcb);
    5169           0 :         return (stcb);
    5170             : }
    5171             : 
    5172             : 
    5173             : void
    5174           0 : sctp_remove_net(struct sctp_tcb *stcb, struct sctp_nets *net)
    5175             : {
    5176             :         struct sctp_association *asoc;
    5177             : 
    5178           0 :         asoc = &stcb->asoc;
    5179           0 :         asoc->numnets--;
    5180           0 :         TAILQ_REMOVE(&asoc->nets, net, sctp_next);
    5181           0 :         if (net == asoc->primary_destination) {
    5182             :                 /* Reset primary */
    5183             :                 struct sctp_nets *lnet;
    5184             : 
    5185           0 :                 lnet = TAILQ_FIRST(&asoc->nets);
    5186             :                 /* Mobility adaptation
    5187             :                    Ideally, if deleted destination is the primary, it becomes
    5188             :                    a fast retransmission trigger by the subsequent SET PRIMARY.
    5189             :                    (by micchie)
    5190             :                  */
    5191           0 :                 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
    5192           0 :                                                 SCTP_MOBILITY_BASE) ||
    5193           0 :                     sctp_is_mobility_feature_on(stcb->sctp_ep,
    5194             :                                                 SCTP_MOBILITY_FASTHANDOFF)) {
    5195           0 :                         SCTPDBG(SCTP_DEBUG_ASCONF1, "remove_net: primary dst is deleting\n");
    5196           0 :                         if (asoc->deleted_primary != NULL) {
    5197           0 :                                 SCTPDBG(SCTP_DEBUG_ASCONF1, "remove_net: deleted primary may be already stored\n");
    5198           0 :                                 goto out;
    5199             :                         }
    5200           0 :                         asoc->deleted_primary = net;
    5201           0 :                         atomic_add_int(&net->ref_count, 1);
    5202           0 :                         memset(&net->lastsa, 0, sizeof(net->lastsa));
    5203           0 :                         memset(&net->lastsv, 0, sizeof(net->lastsv));
    5204           0 :                         sctp_mobility_feature_on(stcb->sctp_ep,
    5205             :                                                  SCTP_MOBILITY_PRIM_DELETED);
    5206           0 :                         sctp_timer_start(SCTP_TIMER_TYPE_PRIM_DELETED,
    5207             :                                          stcb->sctp_ep, stcb, NULL);
    5208             :                 }
    5209             : out:
    5210             :                 /* Try to find a confirmed primary */
    5211           0 :                 asoc->primary_destination = sctp_find_alternate_net(stcb, lnet, 0);
    5212             :         }
    5213           0 :         if (net == asoc->last_data_chunk_from) {
    5214             :                 /* Reset primary */
    5215           0 :                 asoc->last_data_chunk_from = TAILQ_FIRST(&asoc->nets);
    5216             :         }
    5217           0 :         if (net == asoc->last_control_chunk_from) {
    5218             :                 /* Clear net */
    5219           0 :                 asoc->last_control_chunk_from = NULL;
    5220             :         }
    5221           0 :         if (net == stcb->asoc.alternate) {
    5222           0 :                 sctp_free_remote_addr(stcb->asoc.alternate);
    5223           0 :                 stcb->asoc.alternate = NULL;
    5224             :         }
    5225           0 :         sctp_free_remote_addr(net);
    5226           0 : }
    5227             : 
    5228             : /*
    5229             :  * remove a remote endpoint address from an association, it will fail if the
    5230             :  * address does not exist.
    5231             :  */
    5232             : int
    5233           0 : sctp_del_remote_addr(struct sctp_tcb *stcb, struct sockaddr *remaddr)
    5234             : {
    5235             :         /*
    5236             :          * Here we need to remove a remote address. This is quite simple, we
    5237             :          * first find it in the list of address for the association
    5238             :          * (tasoc->asoc.nets) and then if it is there, we do a LIST_REMOVE
    5239             :          * on that item. Note we do not allow it to be removed if there are
    5240             :          * no other addresses.
    5241             :          */
    5242             :         struct sctp_association *asoc;
    5243             :         struct sctp_nets *net, *nnet;
    5244             : 
    5245           0 :         asoc = &stcb->asoc;
    5246             : 
    5247             :         /* locate the address */
    5248           0 :         TAILQ_FOREACH_SAFE(net, &asoc->nets, sctp_next, nnet) {
    5249           0 :                 if (net->ro._l_addr.sa.sa_family != remaddr->sa_family) {
    5250           0 :                         continue;
    5251             :                 }
    5252           0 :                 if (sctp_cmpaddr((struct sockaddr *)&net->ro._l_addr,
    5253             :                     remaddr)) {
    5254             :                         /* we found the guy */
    5255           0 :                         if (asoc->numnets < 2) {
    5256             :                                 /* Must have at LEAST two remote addresses */
    5257           0 :                                 return (-1);
    5258             :                         } else {
    5259           0 :                                 sctp_remove_net(stcb, net);
    5260           0 :                                 return (0);
    5261             :                         }
    5262             :                 }
    5263             :         }
    5264             :         /* not found. */
    5265           0 :         return (-2);
    5266             : }
    5267             : 
    5268             : void
    5269           0 : sctp_delete_from_timewait(uint32_t tag, uint16_t lport, uint16_t rport)
    5270             : {
    5271             :         struct sctpvtaghead *chain;
    5272             :         struct sctp_tagblock *twait_block;
    5273           0 :         int found = 0;
    5274             :         int i;
    5275             : 
    5276           0 :         chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
    5277           0 :         LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
    5278           0 :                 for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
    5279           0 :                   if ((twait_block->vtag_block[i].v_tag == tag) &&
    5280           0 :                       (twait_block->vtag_block[i].lport == lport) &&
    5281           0 :                       (twait_block->vtag_block[i].rport == rport)) {
    5282           0 :                                 twait_block->vtag_block[i].tv_sec_at_expire = 0;
    5283           0 :                                 twait_block->vtag_block[i].v_tag = 0;
    5284           0 :                                 twait_block->vtag_block[i].lport = 0;
    5285           0 :                                 twait_block->vtag_block[i].rport = 0;
    5286           0 :                                 found = 1;
    5287           0 :                                 break;
    5288             :                         }
    5289             :                 }
    5290           0 :                 if (found)
    5291           0 :                         break;
    5292             :         }
    5293           0 : }
    5294             : 
    5295             : int
    5296           0 : sctp_is_in_timewait(uint32_t tag, uint16_t lport, uint16_t rport)
    5297             : {
    5298             :         struct sctpvtaghead *chain;
    5299             :         struct sctp_tagblock *twait_block;
    5300           0 :         int found = 0;
    5301             :         int i;
    5302             : 
    5303           0 :         SCTP_INP_INFO_WLOCK();
    5304           0 :         chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
    5305           0 :         LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
    5306           0 :                 for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
    5307           0 :                         if ((twait_block->vtag_block[i].v_tag == tag)  &&
    5308           0 :                             (twait_block->vtag_block[i].lport == lport)  &&
    5309           0 :                             (twait_block->vtag_block[i].rport == rport)) {
    5310           0 :                                 found = 1;
    5311           0 :                                 break;
    5312             :                         }
    5313             :                 }
    5314           0 :                 if (found)
    5315           0 :                         break;
    5316             :         }
    5317           0 :         SCTP_INP_INFO_WUNLOCK();
    5318           0 :         return (found);
    5319             : }
    5320             : 
    5321             : 
    5322             : void
    5323           0 : sctp_add_vtag_to_timewait(uint32_t tag, uint32_t time, uint16_t lport, uint16_t rport)
    5324             : {
    5325             :         struct sctpvtaghead *chain;
    5326             :         struct sctp_tagblock *twait_block;
    5327             :         struct timeval now;
    5328             :         int set, i;
    5329             : 
    5330           0 :         if (time == 0) {
    5331             :                 /* Its disabled */
    5332           0 :                 return;
    5333             :         }
    5334           0 :         (void)SCTP_GETTIME_TIMEVAL(&now);
    5335           0 :         chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
    5336           0 :         set = 0;
    5337           0 :         LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
    5338             :                 /* Block(s) present, lets find space, and expire on the fly */
    5339           0 :                 for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
    5340           0 :                         if ((twait_block->vtag_block[i].v_tag == 0) &&
    5341             :                             !set) {
    5342           0 :                                 twait_block->vtag_block[i].tv_sec_at_expire =
    5343           0 :                                         now.tv_sec + time;
    5344           0 :                                 twait_block->vtag_block[i].v_tag = tag;
    5345           0 :                                 twait_block->vtag_block[i].lport = lport;
    5346           0 :                                 twait_block->vtag_block[i].rport = rport;
    5347           0 :                                 set = 1;
    5348           0 :                         } else if ((twait_block->vtag_block[i].v_tag) &&
    5349           0 :                                     ((long)twait_block->vtag_block[i].tv_sec_at_expire < now.tv_sec)) {
    5350             :                                 /* Audit expires this guy */
    5351           0 :                                 twait_block->vtag_block[i].tv_sec_at_expire = 0;
    5352           0 :                                 twait_block->vtag_block[i].v_tag = 0;
    5353           0 :                                 twait_block->vtag_block[i].lport = 0;
    5354           0 :                                 twait_block->vtag_block[i].rport = 0;
    5355           0 :                                 if (set == 0) {
    5356             :                                         /* Reuse it for my new tag */
    5357           0 :                                         twait_block->vtag_block[i].tv_sec_at_expire = now.tv_sec + time;
    5358           0 :                                         twait_block->vtag_block[i].v_tag = tag;
    5359           0 :                                         twait_block->vtag_block[i].lport = lport;
    5360           0 :                                         twait_block->vtag_block[i].rport = rport;
    5361           0 :                                         set = 1;
    5362             :                                 }
    5363             :                         }
    5364             :                 }
    5365           0 :                 if (set) {
    5366             :                         /*
    5367             :                          * We only do up to the block where we can
    5368             :                          * place our tag for audits
    5369             :                          */
    5370           0 :                         break;
    5371             :                 }
    5372             :         }
    5373             :         /* Need to add a new block to chain */
    5374           0 :         if (!set) {
    5375           0 :                 SCTP_MALLOC(twait_block, struct sctp_tagblock *,
    5376             :                     sizeof(struct sctp_tagblock), SCTP_M_TIMW);
    5377           0 :                 if (twait_block == NULL) {
    5378             : #ifdef INVARIANTS
    5379             :                         panic("Can not alloc tagblock");
    5380             : #endif
    5381           0 :                         return;
    5382             :                 }
    5383           0 :                 memset(twait_block, 0, sizeof(struct sctp_tagblock));
    5384           0 :                 LIST_INSERT_HEAD(chain, twait_block, sctp_nxt_tagblock);
    5385           0 :                 twait_block->vtag_block[0].tv_sec_at_expire = now.tv_sec + time;
    5386           0 :                 twait_block->vtag_block[0].v_tag = tag;
    5387           0 :                 twait_block->vtag_block[0].lport = lport;
    5388           0 :                 twait_block->vtag_block[0].rport = rport;
    5389             :         }
    5390             : }
    5391             : 
    5392             : 
    5393             : #ifdef __Panda__
    5394             : void panda_wakeup_socket(struct socket *so);
    5395             : #endif
    5396             : 
    5397             : /*-
    5398             :  * Free the association after un-hashing the remote port. This
    5399             :  * function ALWAYS returns holding NO LOCK on the stcb. It DOES
    5400             :  * expect that the input to this function IS a locked TCB.
    5401             :  * It will return 0, if it did NOT destroy the association (instead
    5402             :  * it unlocks it. It will return NON-zero if it either destroyed the
    5403             :  * association OR the association is already destroyed.
    5404             :  */
    5405             : int
    5406           0 : sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfree, int from_location)
    5407             : {
    5408             :         int i;
    5409             :         struct sctp_association *asoc;
    5410             :         struct sctp_nets *net, *nnet;
    5411             :         struct sctp_laddr *laddr, *naddr;
    5412             :         struct sctp_tmit_chunk *chk, *nchk;
    5413             :         struct sctp_asconf_addr *aparam, *naparam;
    5414             :         struct sctp_asconf_ack *aack, *naack;
    5415             :         struct sctp_stream_reset_list *strrst, *nstrrst;
    5416             :         struct sctp_queued_to_read *sq, *nsq;
    5417             :         struct sctp_stream_queue_pending *sp, *nsp;
    5418             :         sctp_sharedkey_t *shared_key, *nshared_key;
    5419             :         struct socket *so;
    5420             : 
    5421             :         /* first, lets purge the entry from the hash table. */
    5422             : #if defined(__APPLE__)
    5423             :         sctp_lock_assert(SCTP_INP_SO(inp));
    5424             : #endif
    5425             : 
    5426             : #ifdef SCTP_LOG_CLOSING
    5427             :         sctp_log_closing(inp, stcb, 6);
    5428             : #endif
    5429           0 :         if (stcb->asoc.state == 0) {
    5430             : #ifdef SCTP_LOG_CLOSING
    5431             :                 sctp_log_closing(inp, NULL, 7);
    5432             : #endif
    5433             :                 /* there is no asoc, really TSNH :-0 */
    5434           0 :                 return (1);
    5435             :         }
    5436           0 :         if (stcb->asoc.alternate) {
    5437           0 :                 sctp_free_remote_addr(stcb->asoc.alternate);
    5438           0 :                 stcb->asoc.alternate = NULL;
    5439             :         }
    5440             : #if !defined(__APPLE__) /* TEMP: moved to below */
    5441             :         /* TEMP CODE */
    5442           0 :         if (stcb->freed_from_where == 0) {
    5443             :                 /* Only record the first place free happened from */
    5444           0 :                 stcb->freed_from_where = from_location;
    5445             :         }
    5446             :         /* TEMP CODE */
    5447             : #endif
    5448             : 
    5449           0 :         asoc = &stcb->asoc;
    5450           0 :         if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
    5451           0 :             (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
    5452             :                 /* nothing around */
    5453           0 :                 so = NULL;
    5454             :         else
    5455           0 :                 so = inp->sctp_socket;
    5456             : 
    5457             :         /*
    5458             :          * We used timer based freeing if a reader or writer is in the way.
    5459             :          * So we first check if we are actually being called from a timer,
    5460             :          * if so we abort early if a reader or writer is still in the way.
    5461             :          */
    5462           0 :         if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) &&
    5463             :             (from_inpcbfree == SCTP_NORMAL_PROC)) {
    5464             :                 /*
    5465             :                  * is it the timer driving us? if so are the reader/writers
    5466             :                  * gone?
    5467             :                  */
    5468           0 :                 if (stcb->asoc.refcnt) {
    5469             :                         /* nope, reader or writer in the way */
    5470           0 :                         sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
    5471             :                         /* no asoc destroyed */
    5472           0 :                         SCTP_TCB_UNLOCK(stcb);
    5473             : #ifdef SCTP_LOG_CLOSING
    5474             :                         sctp_log_closing(inp, stcb, 8);
    5475             : #endif
    5476           0 :                         return (0);
    5477             :                 }
    5478             :         }
    5479             :         /* now clean up any other timers */
    5480           0 :         (void)SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
    5481           0 :         asoc->dack_timer.self = NULL;
    5482           0 :         (void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
    5483             :         /*-
    5484             :          * For stream reset we don't blast this unless
    5485             :          * it is a str-reset timer, it might be the
    5486             :          * free-asoc timer which we DON'T want to
    5487             :          * disturb.
    5488             :          */
    5489           0 :         if (asoc->strreset_timer.type == SCTP_TIMER_TYPE_STRRESET)
    5490           0 :                 asoc->strreset_timer.self = NULL;
    5491           0 :         (void)SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer);
    5492           0 :         asoc->asconf_timer.self = NULL;
    5493           0 :         (void)SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer);
    5494           0 :         asoc->autoclose_timer.self = NULL;
    5495           0 :         (void)SCTP_OS_TIMER_STOP(&asoc->shut_guard_timer.timer);
    5496           0 :         asoc->shut_guard_timer.self = NULL;
    5497           0 :         (void)SCTP_OS_TIMER_STOP(&asoc->delayed_event_timer.timer);
    5498           0 :         asoc->delayed_event_timer.self = NULL;
    5499             :         /* Mobility adaptation */
    5500           0 :         (void)SCTP_OS_TIMER_STOP(&asoc->delete_prim_timer.timer);
    5501           0 :         asoc->delete_prim_timer.self = NULL;
    5502           0 :         TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    5503           0 :                 (void)SCTP_OS_TIMER_STOP(&net->rxt_timer.timer);
    5504           0 :                 net->rxt_timer.self = NULL;
    5505           0 :                 (void)SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer);
    5506           0 :                 net->pmtu_timer.self = NULL;
    5507           0 :                 (void)SCTP_OS_TIMER_STOP(&net->hb_timer.timer);
    5508           0 :                 net->hb_timer.self = NULL;
    5509             :         }
    5510             :         /* Now the read queue needs to be cleaned up (only once) */
    5511           0 :         if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0) {
    5512           0 :                 stcb->asoc.state |= SCTP_STATE_ABOUT_TO_BE_FREED;
    5513           0 :                 SCTP_INP_READ_LOCK(inp);
    5514           0 :                 TAILQ_FOREACH(sq, &inp->read_queue, next) {
    5515           0 :                         if (sq->stcb == stcb) {
    5516           0 :                                 sq->do_not_ref_stcb = 1;
    5517           0 :                                 sq->sinfo_cumtsn = stcb->asoc.cumulative_tsn;
    5518             :                                 /* If there is no end, there never
    5519             :                                  * will be now.
    5520             :                                  */
    5521           0 :                                 if (sq->end_added == 0) {
    5522             :                                         /* Held for PD-API clear that. */
    5523           0 :                                         sq->pdapi_aborted = 1;
    5524           0 :                                         sq->held_length = 0;
    5525           0 :                                         if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_PDAPIEVNT) && (so != NULL)) {
    5526             :                                                 /*
    5527             :                                                  * Need to add a PD-API aborted indication.
    5528             :                                                  * Setting the control_pdapi assures that it will
    5529             :                                                  * be added right after this msg.
    5530             :                                                  */
    5531             :                                                 uint32_t strseq;
    5532           0 :                                                 stcb->asoc.control_pdapi = sq;
    5533           0 :                                                 strseq = (sq->sinfo_stream << 16) | sq->sinfo_ssn;
    5534           0 :                                                 sctp_ulp_notify(SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION,
    5535             :                                                                 stcb,
    5536             :                                                                 SCTP_PARTIAL_DELIVERY_ABORTED,
    5537             :                                                                 (void *)&strseq,
    5538             :                                                                 SCTP_SO_LOCKED);
    5539           0 :                                                 stcb->asoc.control_pdapi = NULL;
    5540             :                                         }
    5541             :                                 }
    5542             :                                 /* Add an end to wake them */
    5543           0 :                                 sq->end_added = 1;
    5544             :                         }
    5545             :                 }
    5546           0 :                 SCTP_INP_READ_UNLOCK(inp);
    5547           0 :                 if (stcb->block_entry) {
    5548             :                         SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_PCB, ECONNRESET);
    5549           0 :                         stcb->block_entry->error = ECONNRESET;
    5550           0 :                         stcb->block_entry = NULL;
    5551             :                 }
    5552             :         }
    5553           0 :         if ((stcb->asoc.refcnt) || (stcb->asoc.state & SCTP_STATE_IN_ACCEPT_QUEUE)) {
    5554             :                 /* Someone holds a reference OR the socket is unaccepted yet.
    5555             :                 */
    5556           0 :                 if ((stcb->asoc.refcnt)  ||
    5557           0 :                     (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
    5558           0 :                     (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
    5559           0 :                         stcb->asoc.state &= ~SCTP_STATE_IN_ACCEPT_QUEUE;
    5560           0 :                         sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
    5561             :                 }
    5562           0 :                 SCTP_TCB_UNLOCK(stcb);
    5563           0 :                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
    5564           0 :                     (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
    5565             :                         /* nothing around */
    5566           0 :                         so = NULL;
    5567           0 :                 if (so) {
    5568             :                         /* Wake any reader/writers */
    5569           0 :                         sctp_sorwakeup(inp, so);
    5570           0 :                         sctp_sowwakeup(inp, so);
    5571             :                 }
    5572             : 
    5573             : #ifdef SCTP_LOG_CLOSING
    5574             :                 sctp_log_closing(inp, stcb, 9);
    5575             : #endif
    5576             :                 /* no asoc destroyed */
    5577           0 :                 return (0);
    5578             :         }
    5579             : #ifdef SCTP_LOG_CLOSING
    5580             :         sctp_log_closing(inp, stcb, 10);
    5581             : #endif
    5582             :         /* When I reach here, no others want
    5583             :          * to kill the assoc yet.. and I own
    5584             :          * the lock. Now its possible an abort
    5585             :          * comes in when I do the lock exchange
    5586             :          * below to grab all the locks to do
    5587             :          * the final take out. to prevent this
    5588             :          * we increment the count, which will
    5589             :          * start a timer and blow out above thus
    5590             :          * assuring us that we hold exclusive
    5591             :          * killing of the asoc. Note that
    5592             :          * after getting back the TCB lock
    5593             :          * we will go ahead and increment the
    5594             :          * counter back up and stop any timer
    5595             :          * a passing stranger may have started :-S
    5596             :          */
    5597           0 :         if (from_inpcbfree == SCTP_NORMAL_PROC) {
    5598           0 :                 atomic_add_int(&stcb->asoc.refcnt, 1);
    5599             : 
    5600           0 :                 SCTP_TCB_UNLOCK(stcb);
    5601           0 :                 SCTP_INP_INFO_WLOCK();
    5602           0 :                 SCTP_INP_WLOCK(inp);
    5603           0 :                 SCTP_TCB_LOCK(stcb);
    5604             :         }
    5605             :         /* Double check the GONE flag */
    5606           0 :         if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
    5607           0 :             (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
    5608             :                 /* nothing around */
    5609           0 :                 so = NULL;
    5610             : 
    5611           0 :         if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
    5612           0 :             (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
    5613             :                 /*
    5614             :                  * For TCP type we need special handling when we are
    5615             :                  * connected. We also include the peel'ed off ones to.
    5616             :                  */
    5617           0 :                 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
    5618           0 :                         inp->sctp_flags &= ~SCTP_PCB_FLAGS_CONNECTED;
    5619           0 :                         inp->sctp_flags |= SCTP_PCB_FLAGS_WAS_CONNECTED;
    5620           0 :                         if (so) {
    5621           0 :                                 SOCK_LOCK(so);
    5622           0 :                                 if (so->so_rcv.sb_cc == 0) {
    5623           0 :                                         so->so_state &= ~(SS_ISCONNECTING |
    5624             :                                                           SS_ISDISCONNECTING |
    5625             :                                                           SS_ISCONFIRMING |
    5626             :                                                           SS_ISCONNECTED);
    5627             :                                 }
    5628             : #if defined(__APPLE__)
    5629             :                                 socantrcvmore(so);
    5630             : #else
    5631           0 :                                 socantrcvmore_locked(so);
    5632             : #endif
    5633           0 :                                 sctp_sowwakeup(inp, so);
    5634           0 :                                 sctp_sorwakeup(inp, so);
    5635           0 :                                 SCTP_SOWAKEUP(so);
    5636             :                         }
    5637             :                 }
    5638             :         }
    5639             : 
    5640             :         /* Make it invalid too, that way if its
    5641             :          * about to run it will abort and return.
    5642             :          */
    5643             :         /* re-increment the lock */
    5644           0 :         if (from_inpcbfree == SCTP_NORMAL_PROC) {
    5645           0 :                 atomic_add_int(&stcb->asoc.refcnt, -1);
    5646             :         }
    5647           0 :         if (stcb->asoc.refcnt) {
    5648           0 :                 stcb->asoc.state &= ~SCTP_STATE_IN_ACCEPT_QUEUE;
    5649           0 :                 sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
    5650           0 :                 if (from_inpcbfree == SCTP_NORMAL_PROC) {
    5651           0 :                         SCTP_INP_INFO_WUNLOCK();
    5652           0 :                         SCTP_INP_WUNLOCK(inp);
    5653             :                 }
    5654           0 :                 SCTP_TCB_UNLOCK(stcb);
    5655           0 :                 return (0);
    5656             :         }
    5657           0 :         asoc->state = 0;
    5658           0 :         if (inp->sctp_tcbhash) {
    5659           0 :                 LIST_REMOVE(stcb, sctp_tcbhash);
    5660             :         }
    5661           0 :         if (stcb->asoc.in_asocid_hash) {
    5662           0 :                 LIST_REMOVE(stcb, sctp_tcbasocidhash);
    5663             :         }
    5664             :         /* Now lets remove it from the list of ALL associations in the EP */
    5665           0 :         LIST_REMOVE(stcb, sctp_tcblist);
    5666           0 :         if (from_inpcbfree == SCTP_NORMAL_PROC) {
    5667           0 :                 SCTP_INP_INCR_REF(inp);
    5668           0 :                 SCTP_INP_WUNLOCK(inp);
    5669             :         }
    5670             :         /* pull from vtag hash */
    5671           0 :         LIST_REMOVE(stcb, sctp_asocs);
    5672           0 :         sctp_add_vtag_to_timewait(asoc->my_vtag, SCTP_BASE_SYSCTL(sctp_vtag_time_wait),
    5673           0 :                                   inp->sctp_lport, stcb->rport);
    5674             : 
    5675             :         /* Now restop the timers to be sure
    5676             :          * this is paranoia at is finest!
    5677             :          */
    5678           0 :         (void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
    5679           0 :         (void)SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
    5680           0 :         (void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
    5681           0 :         (void)SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer);
    5682           0 :         (void)SCTP_OS_TIMER_STOP(&asoc->shut_guard_timer.timer);
    5683           0 :         (void)SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer);
    5684           0 :         (void)SCTP_OS_TIMER_STOP(&asoc->delayed_event_timer.timer);
    5685           0 :         TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
    5686           0 :                 (void)SCTP_OS_TIMER_STOP(&net->rxt_timer.timer);
    5687           0 :                 (void)SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer);
    5688           0 :                 (void)SCTP_OS_TIMER_STOP(&net->hb_timer.timer);
    5689             :         }
    5690             : 
    5691           0 :         asoc->strreset_timer.type = SCTP_TIMER_TYPE_NONE;
    5692             :         /*
    5693             :          * The chunk lists and such SHOULD be empty but we check them just
    5694             :          * in case.
    5695             :          */
    5696             :         /* anything on the wheel needs to be removed */
    5697           0 :         for (i = 0; i < asoc->streamoutcnt; i++) {
    5698             :                 struct sctp_stream_out *outs;
    5699             : 
    5700           0 :                 outs = &asoc->strmout[i];
    5701             :                 /* now clean up any chunks here */
    5702           0 :                 TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) {
    5703           0 :                         TAILQ_REMOVE(&outs->outqueue, sp, next);
    5704           0 :                         sctp_free_spbufspace(stcb, asoc, sp);
    5705           0 :                         if (sp->data) {
    5706           0 :                                 if (so) {
    5707             :                                         /* Still an open socket - report */
    5708           0 :                                         sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb,
    5709             :                                                         0, (void *)sp, SCTP_SO_LOCKED);
    5710             :                                 }
    5711           0 :                                 if (sp->data) {
    5712           0 :                                         sctp_m_freem(sp->data);
    5713           0 :                                         sp->data = NULL;
    5714           0 :                                         sp->tail_mbuf = NULL;
    5715           0 :                                         sp->length = 0;
    5716             :                                 }
    5717             :                         }
    5718           0 :                         if (sp->net) {
    5719           0 :                                 sctp_free_remote_addr(sp->net);
    5720           0 :                                 sp->net = NULL;
    5721             :                         }
    5722           0 :                         sctp_free_a_strmoq(stcb, sp, SCTP_SO_LOCKED);
    5723             :                 }
    5724             :         }
    5725             :         /*sa_ignore FREED_MEMORY*/
    5726           0 :         TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) {
    5727           0 :                 TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp);
    5728           0 :                 SCTP_FREE(strrst, SCTP_M_STRESET);
    5729             :         }
    5730           0 :         TAILQ_FOREACH_SAFE(sq, &asoc->pending_reply_queue, next, nsq) {
    5731           0 :                 TAILQ_REMOVE(&asoc->pending_reply_queue, sq, next);
    5732           0 :                 if (sq->data) {
    5733           0 :                         sctp_m_freem(sq->data);
    5734           0 :                         sq->data = NULL;
    5735             :                 }
    5736           0 :                 sctp_free_remote_addr(sq->whoFrom);
    5737           0 :                 sq->whoFrom = NULL;
    5738           0 :                 sq->stcb = NULL;
    5739             :                 /* Free the ctl entry */
    5740           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), sq);
    5741           0 :                 SCTP_DECR_READQ_COUNT();
    5742             :                 /*sa_ignore FREED_MEMORY*/
    5743             :         }
    5744           0 :         TAILQ_FOREACH_SAFE(chk, &asoc->free_chunks, sctp_next, nchk) {
    5745           0 :                 TAILQ_REMOVE(&asoc->free_chunks, chk, sctp_next);
    5746           0 :                 if (chk->data) {
    5747           0 :                         sctp_m_freem(chk->data);
    5748           0 :                         chk->data = NULL;
    5749             :                 }
    5750           0 :                 if (chk->holds_key_ref)
    5751           0 :                         sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
    5752           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
    5753           0 :                 SCTP_DECR_CHK_COUNT();
    5754           0 :                 atomic_subtract_int(&SCTP_BASE_INFO(ipi_free_chunks), 1);
    5755           0 :                 asoc->free_chunk_cnt--;
    5756             :                 /*sa_ignore FREED_MEMORY*/
    5757             :         }
    5758             :         /* pending send queue SHOULD be empty */
    5759           0 :         TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
    5760           0 :                 if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
    5761           0 :                         asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
    5762             : #ifdef INVARIANTS
    5763             :                 } else {
    5764             :                         panic("No chunks on the queues for sid %u.", chk->rec.data.stream_number);
    5765             : #endif
    5766             :                 }
    5767           0 :                 TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
    5768           0 :                 if (chk->data) {
    5769           0 :                         if (so) {
    5770             :                                 /* Still a socket? */
    5771           0 :                                 sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb,
    5772             :                                                 0, chk, SCTP_SO_LOCKED);
    5773             :                         }
    5774           0 :                         if (chk->data) {
    5775           0 :                                 sctp_m_freem(chk->data);
    5776           0 :                                 chk->data = NULL;
    5777             :                         }
    5778             :                 }
    5779           0 :                 if (chk->holds_key_ref)
    5780           0 :                         sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
    5781           0 :                 if (chk->whoTo) {
    5782           0 :                         sctp_free_remote_addr(chk->whoTo);
    5783           0 :                         chk->whoTo = NULL;
    5784             :                 }
    5785           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
    5786           0 :                 SCTP_DECR_CHK_COUNT();
    5787             :                 /*sa_ignore FREED_MEMORY*/
    5788             :         }
    5789             :         /* sent queue SHOULD be empty */
    5790           0 :         TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
    5791           0 :                 if (chk->sent != SCTP_DATAGRAM_NR_ACKED) {
    5792           0 :                         if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
    5793           0 :                                 asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
    5794             : #ifdef INVARIANTS
    5795             :                         } else {
    5796             :                                 panic("No chunks on the queues for sid %u.", chk->rec.data.stream_number);
    5797             : #endif
    5798             :                         }
    5799             :                 }
    5800           0 :                 TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
    5801           0 :                 if (chk->data) {
    5802           0 :                         if (so) {
    5803             :                                 /* Still a socket? */
    5804           0 :                                 sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb,
    5805             :                                                 0, chk, SCTP_SO_LOCKED);
    5806             :                         }
    5807           0 :                         if (chk->data) {
    5808           0 :                                 sctp_m_freem(chk->data);
    5809           0 :                                 chk->data = NULL;
    5810             :                         }
    5811             :                 }
    5812           0 :                 if (chk->holds_key_ref)
    5813           0 :                         sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
    5814           0 :                 sctp_free_remote_addr(chk->whoTo);
    5815           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
    5816           0 :                 SCTP_DECR_CHK_COUNT();
    5817             :                 /*sa_ignore FREED_MEMORY*/
    5818             :         }
    5819             : #ifdef INVARIANTS
    5820             :         for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
    5821             :                 if (stcb->asoc.strmout[i].chunks_on_queues > 0) {
    5822             :                         panic("%u chunks left for stream %u.", stcb->asoc.strmout[i].chunks_on_queues, i);
    5823             :                 }
    5824             :         }
    5825             : #endif
    5826             :         /* control queue MAY not be empty */
    5827           0 :         TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) {
    5828           0 :                 TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
    5829           0 :                 if (chk->data) {
    5830           0 :                         sctp_m_freem(chk->data);
    5831           0 :                         chk->data = NULL;
    5832             :                 }
    5833           0 :                 if (chk->holds_key_ref)
    5834           0 :                         sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
    5835           0 :                 sctp_free_remote_addr(chk->whoTo);
    5836           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
    5837           0 :                 SCTP_DECR_CHK_COUNT();
    5838             :                 /*sa_ignore FREED_MEMORY*/
    5839             :         }
    5840             :         /* ASCONF queue MAY not be empty */
    5841           0 :         TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) {
    5842           0 :                 TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next);
    5843           0 :                 if (chk->data) {
    5844           0 :                         sctp_m_freem(chk->data);
    5845           0 :                         chk->data = NULL;
    5846             :                 }
    5847           0 :                 if (chk->holds_key_ref)
    5848           0 :                         sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
    5849           0 :                 sctp_free_remote_addr(chk->whoTo);
    5850           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
    5851           0 :                 SCTP_DECR_CHK_COUNT();
    5852             :                 /*sa_ignore FREED_MEMORY*/
    5853             :         }
    5854           0 :         TAILQ_FOREACH_SAFE(chk, &asoc->reasmqueue, sctp_next, nchk) {
    5855           0 :                 TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next);
    5856           0 :                 if (chk->data) {
    5857           0 :                         sctp_m_freem(chk->data);
    5858           0 :                         chk->data = NULL;
    5859             :                 }
    5860           0 :                 if (chk->holds_key_ref)
    5861           0 :                         sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
    5862           0 :                 sctp_free_remote_addr(chk->whoTo);
    5863           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
    5864           0 :                 SCTP_DECR_CHK_COUNT();
    5865             :                 /*sa_ignore FREED_MEMORY*/
    5866             :         }
    5867             : 
    5868           0 :         if (asoc->mapping_array) {
    5869           0 :                 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
    5870           0 :                 asoc->mapping_array = NULL;
    5871             :         }
    5872           0 :         if (asoc->nr_mapping_array) {
    5873           0 :                 SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
    5874           0 :                 asoc->nr_mapping_array = NULL;
    5875             :         }
    5876             :         /* the stream outs */
    5877           0 :         if (asoc->strmout) {
    5878           0 :                 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
    5879           0 :                 asoc->strmout = NULL;
    5880             :         }
    5881           0 :         asoc->strm_realoutsize = asoc->streamoutcnt = 0;
    5882           0 :         if (asoc->strmin) {
    5883             :                 struct sctp_queued_to_read *ctl, *nctl;
    5884             : 
    5885           0 :                 for (i = 0; i < asoc->streamincnt; i++) {
    5886           0 :                         TAILQ_FOREACH_SAFE(ctl, &asoc->strmin[i].inqueue, next, nctl) {
    5887           0 :                                 TAILQ_REMOVE(&asoc->strmin[i].inqueue, ctl, next);
    5888           0 :                                 sctp_free_remote_addr(ctl->whoFrom);
    5889           0 :                                 if (ctl->data) {
    5890           0 :                                         sctp_m_freem(ctl->data);
    5891           0 :                                         ctl->data = NULL;
    5892             :                                 }
    5893             :                                 /*
    5894             :                                  * We don't free the address here
    5895             :                                  * since all the net's were freed
    5896             :                                  * above.
    5897             :                                  */
    5898           0 :                                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), ctl);
    5899           0 :                                 SCTP_DECR_READQ_COUNT();
    5900             :                         }
    5901             :                 }
    5902           0 :                 SCTP_FREE(asoc->strmin, SCTP_M_STRMI);
    5903           0 :                 asoc->strmin = NULL;
    5904             :         }
    5905           0 :         asoc->streamincnt = 0;
    5906           0 :         TAILQ_FOREACH_SAFE(net, &asoc->nets, sctp_next, nnet) {
    5907             : #ifdef INVARIANTS
    5908             :                 if (SCTP_BASE_INFO(ipi_count_raddr) == 0) {
    5909             :                         panic("no net's left alloc'ed, or list points to itself");
    5910             :                 }
    5911             : #endif
    5912           0 :                 TAILQ_REMOVE(&asoc->nets, net, sctp_next);
    5913           0 :                 sctp_free_remote_addr(net);
    5914             :         }
    5915           0 :         LIST_FOREACH_SAFE(laddr, &asoc->sctp_restricted_addrs, sctp_nxt_addr, naddr) {
    5916             :                 /*sa_ignore FREED_MEMORY*/
    5917           0 :                 sctp_remove_laddr(laddr);
    5918             :         }
    5919             : 
    5920             :         /* pending asconf (address) parameters */
    5921           0 :         TAILQ_FOREACH_SAFE(aparam, &asoc->asconf_queue, next, naparam) {
    5922             :                 /*sa_ignore FREED_MEMORY*/
    5923           0 :                 TAILQ_REMOVE(&asoc->asconf_queue, aparam, next);
    5924           0 :                 SCTP_FREE(aparam,SCTP_M_ASC_ADDR);
    5925             :         }
    5926           0 :         TAILQ_FOREACH_SAFE(aack, &asoc->asconf_ack_sent, next, naack) {
    5927             :                 /*sa_ignore FREED_MEMORY*/
    5928           0 :                 TAILQ_REMOVE(&asoc->asconf_ack_sent, aack, next);
    5929           0 :                 if (aack->data != NULL) {
    5930           0 :                         sctp_m_freem(aack->data);
    5931             :                 }
    5932           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asconf_ack), aack);
    5933             :         }
    5934             :         /* clean up auth stuff */
    5935           0 :         if (asoc->local_hmacs)
    5936           0 :                 sctp_free_hmaclist(asoc->local_hmacs);
    5937           0 :         if (asoc->peer_hmacs)
    5938           0 :                 sctp_free_hmaclist(asoc->peer_hmacs);
    5939             : 
    5940           0 :         if (asoc->local_auth_chunks)
    5941           0 :                 sctp_free_chunklist(asoc->local_auth_chunks);
    5942           0 :         if (asoc->peer_auth_chunks)
    5943           0 :                 sctp_free_chunklist(asoc->peer_auth_chunks);
    5944             : 
    5945           0 :         sctp_free_authinfo(&asoc->authinfo);
    5946             : 
    5947           0 :         LIST_FOREACH_SAFE(shared_key, &asoc->shared_keys, next, nshared_key) {
    5948           0 :                 LIST_REMOVE(shared_key, next);
    5949           0 :                 sctp_free_sharedkey(shared_key);
    5950             :                 /*sa_ignore FREED_MEMORY*/
    5951             :         }
    5952             : 
    5953             :         /* Insert new items here :> */
    5954             : 
    5955             :         /* Get rid of LOCK */
    5956           0 :         SCTP_TCB_UNLOCK(stcb);
    5957           0 :         SCTP_TCB_LOCK_DESTROY(stcb);
    5958           0 :         SCTP_TCB_SEND_LOCK_DESTROY(stcb);
    5959           0 :         if (from_inpcbfree == SCTP_NORMAL_PROC) {
    5960           0 :                 SCTP_INP_INFO_WUNLOCK();
    5961           0 :                 SCTP_INP_RLOCK(inp);
    5962             :         }
    5963             : #if defined(__APPLE__) /* TEMP CODE */
    5964             :         stcb->freed_from_where = from_location;
    5965             : #endif
    5966             : #ifdef SCTP_TRACK_FREED_ASOCS
    5967             :         if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
    5968             :                 /* now clean up the tasoc itself */
    5969             :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
    5970             :                 SCTP_DECR_ASOC_COUNT();
    5971             :         } else {
    5972             :                 LIST_INSERT_HEAD(&inp->sctp_asoc_free_list, stcb, sctp_tcblist);
    5973             :         }
    5974             : #else
    5975           0 :         SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
    5976           0 :         SCTP_DECR_ASOC_COUNT();
    5977             : #endif
    5978           0 :         if (from_inpcbfree == SCTP_NORMAL_PROC) {
    5979           0 :                 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
    5980             :                         /* If its NOT the inp_free calling us AND
    5981             :                          * sctp_close as been called, we
    5982             :                          * call back...
    5983             :                          */
    5984           0 :                         SCTP_INP_RUNLOCK(inp);
    5985             :                         /* This will start the kill timer (if we are
    5986             :                          * the last one) since we hold an increment yet. But
    5987             :                          * this is the only safe way to do this
    5988             :                          * since otherwise if the socket closes
    5989             :                          * at the same time we are here we might
    5990             :                          * collide in the cleanup.
    5991             :                          */
    5992           0 :                         sctp_inpcb_free(inp,
    5993             :                                         SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE,
    5994             :                                         SCTP_CALLED_DIRECTLY_NOCMPSET);
    5995           0 :                         SCTP_INP_DECR_REF(inp);
    5996           0 :                         goto out_of;
    5997             :                 } else {
    5998             :                         /* The socket is still open. */
    5999           0 :                         SCTP_INP_DECR_REF(inp);
    6000             :                 }
    6001             :         }
    6002           0 :         if (from_inpcbfree == SCTP_NORMAL_PROC) {
    6003           0 :                 SCTP_INP_RUNLOCK(inp);
    6004             :         }
    6005             :  out_of:
    6006             :         /* destroyed the asoc */
    6007             : #ifdef SCTP_LOG_CLOSING
    6008             :         sctp_log_closing(inp, NULL, 11);
    6009             : #endif
    6010           0 :         return (1);
    6011             : }
    6012             : 
    6013             : 
    6014             : 
    6015             : /*
    6016             :  * determine if a destination is "reachable" based upon the addresses bound
    6017             :  * to the current endpoint (e.g. only v4 or v6 currently bound)
    6018             :  */
    6019             : /*
    6020             :  * FIX: if we allow assoc-level bindx(), then this needs to be fixed to use
    6021             :  * assoc level v4/v6 flags, as the assoc *may* not have the same address
    6022             :  * types bound as its endpoint
    6023             :  */
    6024             : int
    6025           0 : sctp_destination_is_reachable(struct sctp_tcb *stcb, struct sockaddr *destaddr)
    6026             : {
    6027             :         struct sctp_inpcb *inp;
    6028             :         int answer;
    6029             : 
    6030             :         /*
    6031             :          * No locks here, the TCB, in all cases is already locked and an
    6032             :          * assoc is up. There is either a INP lock by the caller applied (in
    6033             :          * asconf case when deleting an address) or NOT in the HB case,
    6034             :          * however if HB then the INP increment is up and the INP will not
    6035             :          * be removed (on top of the fact that we have a TCB lock). So we
    6036             :          * only want to read the sctp_flags, which is either bound-all or
    6037             :          * not.. no protection needed since once an assoc is up you can't be
    6038             :          * changing your binding.
    6039             :          */
    6040           0 :         inp = stcb->sctp_ep;
    6041           0 :         if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
    6042             :                 /* if bound all, destination is not restricted */
    6043             :                 /*
    6044             :                  * RRS: Question during lock work: Is this correct? If you
    6045             :                  * are bound-all you still might need to obey the V4--V6
    6046             :                  * flags??? IMO this bound-all stuff needs to be removed!
    6047             :                  */
    6048           0 :                 return (1);
    6049             :         }
    6050             :         /* NOTE: all "scope" checks are done when local addresses are added */
    6051           0 :         switch (destaddr->sa_family) {
    6052             : #ifdef INET6
    6053             :         case AF_INET6:
    6054             : #if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
    6055             :                 answer = inp->inp_vflag & INP_IPV6;
    6056             : #else
    6057             :                 answer = inp->ip_inp.inp.inp_vflag & INP_IPV6;
    6058             : #endif
    6059             :                 break;
    6060             : #endif
    6061             : #ifdef INET
    6062             :         case AF_INET:
    6063             : #if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
    6064             :                 answer = inp->inp_vflag & INP_IPV4;
    6065             : #else
    6066             :                 answer = inp->ip_inp.inp.inp_vflag & INP_IPV4;
    6067             : #endif
    6068             :                 break;
    6069             : #endif
    6070             : #if defined(__Userspace__)
    6071             :         case AF_CONN:
    6072           0 :                 answer = inp->ip_inp.inp.inp_vflag & INP_CONN;
    6073           0 :                 break;
    6074             : #endif
    6075             :         default:
    6076             :                 /* invalid family, so it's unreachable */
    6077           0 :                 answer = 0;
    6078           0 :                 break;
    6079             :         }
    6080           0 :         return (answer);
    6081             : }
    6082             : 
    6083             : /*
    6084             :  * update the inp_vflags on an endpoint
    6085             :  */
    6086             : static void
    6087           0 : sctp_update_ep_vflag(struct sctp_inpcb *inp)
    6088             : {
    6089             :         struct sctp_laddr *laddr;
    6090             : 
    6091             :         /* first clear the flag */
    6092             : #if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
    6093             :         inp->inp_vflag = 0;
    6094             : #else
    6095           0 :         inp->ip_inp.inp.inp_vflag = 0;
    6096             : #endif
    6097             :         /* set the flag based on addresses on the ep list */
    6098           0 :         LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
    6099           0 :                 if (laddr->ifa == NULL) {
    6100           0 :                         SCTPDBG(SCTP_DEBUG_PCB1, "%s: NULL ifa\n",
    6101             :                                 __FUNCTION__);
    6102           0 :                         continue;
    6103             :                 }
    6104             : 
    6105           0 :                 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
    6106           0 :                         continue;
    6107             :                 }
    6108           0 :                 switch (laddr->ifa->address.sa.sa_family) {
    6109             : #ifdef INET6
    6110             :                 case AF_INET6:
    6111             : #if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
    6112             :                         inp->inp_vflag |= INP_IPV6;
    6113             : #else
    6114             :                         inp->ip_inp.inp.inp_vflag |= INP_IPV6;
    6115             : #endif
    6116             :                         break;
    6117             : #endif
    6118             : #ifdef INET
    6119             :                 case AF_INET:
    6120             : #if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
    6121             :                         inp->inp_vflag |= INP_IPV4;
    6122             : #else
    6123             :                         inp->ip_inp.inp.inp_vflag |= INP_IPV4;
    6124             : #endif
    6125             :                         break;
    6126             : #endif
    6127             : #if defined(__Userspace__)
    6128             :                 case AF_CONN:
    6129           0 :                         inp->ip_inp.inp.inp_vflag |= INP_CONN;
    6130           0 :                         break;
    6131             : #endif
    6132             :                 default:
    6133           0 :                         break;
    6134             :                 }
    6135             :         }
    6136           0 : }
    6137             : 
    6138             : /*
    6139             :  * Add the address to the endpoint local address list There is nothing to be
    6140             :  * done if we are bound to all addresses
    6141             :  */
    6142             : void
    6143           0 : sctp_add_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa, uint32_t action)
    6144             : {
    6145             :         struct sctp_laddr *laddr;
    6146           0 :         int fnd, error = 0;
    6147             : 
    6148           0 :         fnd = 0;
    6149             : 
    6150           0 :         if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
    6151             :                 /* You are already bound to all. You have it already */
    6152           0 :                 return;
    6153             :         }
    6154             : #ifdef INET6
    6155             :         if (ifa->address.sa.sa_family == AF_INET6) {
    6156             :                 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
    6157             :                         /* Can't bind a non-useable addr. */
    6158             :                         return;
    6159             :                 }
    6160             :         }
    6161             : #endif
    6162             :         /* first, is it already present? */
    6163           0 :         LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
    6164           0 :                 if (laddr->ifa == ifa) {
    6165           0 :                         fnd = 1;
    6166           0 :                         break;
    6167             :                 }
    6168             :         }
    6169             : 
    6170           0 :         if (fnd == 0) {
    6171             :                 /* Not in the ep list */
    6172           0 :                 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, action);
    6173           0 :                 if (error != 0)
    6174           0 :                         return;
    6175           0 :                 inp->laddr_count++;
    6176             :                 /* update inp_vflag flags */
    6177           0 :                 switch (ifa->address.sa.sa_family) {
    6178             : #ifdef INET6
    6179             :                 case AF_INET6:
    6180             : #if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
    6181             :                         inp->inp_vflag |= INP_IPV6;
    6182             : #else
    6183             :                         inp->ip_inp.inp.inp_vflag |= INP_IPV6;
    6184             : #endif
    6185             :                         break;
    6186             : #endif
    6187             : #ifdef INET
    6188             :                 case AF_INET:
    6189             : #if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
    6190             :                         inp->inp_vflag |= INP_IPV4;
    6191             : #else
    6192             :                         inp->ip_inp.inp.inp_vflag |= INP_IPV4;
    6193             : #endif
    6194             :                         break;
    6195             : #endif
    6196             : #if defined(__Userspace__)
    6197             :                 case AF_CONN:
    6198           0 :                         inp->ip_inp.inp.inp_vflag |= INP_CONN;
    6199           0 :                         break;
    6200             : #endif
    6201             :                 default:
    6202           0 :                         break;
    6203             :                 }
    6204             :         }
    6205           0 :         return;
    6206             : }
    6207             : 
    6208             : 
    6209             : /*
    6210             :  * select a new (hopefully reachable) destination net (should only be used
    6211             :  * when we deleted an ep addr that is the only usable source address to reach
    6212             :  * the destination net)
    6213             :  */
    6214             : static void
    6215           0 : sctp_select_primary_destination(struct sctp_tcb *stcb)
    6216             : {
    6217             :         struct sctp_nets *net;
    6218             : 
    6219           0 :         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
    6220             :                 /* for now, we'll just pick the first reachable one we find */
    6221           0 :                 if (net->dest_state & SCTP_ADDR_UNCONFIRMED)
    6222           0 :                         continue;
    6223           0 :                 if (sctp_destination_is_reachable(stcb,
    6224           0 :                     (struct sockaddr *)&net->ro._l_addr)) {
    6225             :                         /* found a reachable destination */
    6226           0 :                         stcb->asoc.primary_destination = net;
    6227             :                 }
    6228             :         }
    6229             :         /* I can't there from here! ...we're gonna die shortly... */
    6230           0 : }
    6231             : 
    6232             : 
    6233             : /*
    6234             :  * Delete the address from the endpoint local address list There is nothing
    6235             :  * to be done if we are bound to all addresses
    6236             :  */
    6237             : void
    6238           0 : sctp_del_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa)
    6239             : {
    6240             :         struct sctp_laddr *laddr;
    6241             :         int fnd;
    6242             : 
    6243           0 :         fnd = 0;
    6244           0 :         if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
    6245             :                 /* You are already bound to all. You have it already */
    6246           0 :                 return;
    6247             :         }
    6248           0 :         LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
    6249           0 :                 if (laddr->ifa == ifa) {
    6250           0 :                         fnd = 1;
    6251           0 :                         break;
    6252             :                 }
    6253             :         }
    6254           0 :         if (fnd && (inp->laddr_count < 2)) {
    6255             :                 /* can't delete unless there are at LEAST 2 addresses */
    6256           0 :                 return;
    6257             :         }
    6258           0 :         if (fnd) {
    6259             :                 /*
    6260             :                  * clean up any use of this address go through our
    6261             :                  * associations and clear any last_used_address that match
    6262             :                  * this one for each assoc, see if a new primary_destination
    6263             :                  * is needed
    6264             :                  */
    6265             :                 struct sctp_tcb *stcb;
    6266             : 
    6267             :                 /* clean up "next_addr_touse" */
    6268           0 :                 if (inp->next_addr_touse == laddr)
    6269             :                         /* delete this address */
    6270           0 :                         inp->next_addr_touse = NULL;
    6271             : 
    6272             :                 /* clean up "last_used_address" */
    6273           0 :                 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
    6274             :                         struct sctp_nets *net;
    6275           0 :                         SCTP_TCB_LOCK(stcb);
    6276           0 :                         if (stcb->asoc.last_used_address == laddr)
    6277             :                                 /* delete this address */
    6278           0 :                                 stcb->asoc.last_used_address = NULL;
    6279             :                         /* Now spin through all the nets and purge any ref to laddr */
    6280           0 :                         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
    6281           0 :                                 if (net->ro._s_addr &&
    6282           0 :                                     (net->ro._s_addr->ifa == laddr->ifa)) {
    6283             :                                         /* Yep, purge src address selected */
    6284             :                                         sctp_rtentry_t *rt;
    6285             : 
    6286             :                                         /* delete this address if cached */
    6287           0 :                                         rt = net->ro.ro_rt;
    6288           0 :                                         if (rt != NULL) {
    6289           0 :                                                 RTFREE(rt);
    6290           0 :                                                 net->ro.ro_rt = NULL;
    6291             :                                         }
    6292           0 :                                         sctp_free_ifa(net->ro._s_addr);
    6293           0 :                                         net->ro._s_addr = NULL;
    6294           0 :                                         net->src_addr_selected = 0;
    6295             :                                 }
    6296             :                         }
    6297           0 :                         SCTP_TCB_UNLOCK(stcb);
    6298             :                 }               /* for each tcb */
    6299             :                 /* remove it from the ep list */
    6300           0 :                 sctp_remove_laddr(laddr);
    6301           0 :                 inp->laddr_count--;
    6302             :                 /* update inp_vflag flags */
    6303           0 :                 sctp_update_ep_vflag(inp);
    6304             :         }
    6305           0 :         return;
    6306             : }
    6307             : 
    6308             : /*
    6309             :  * Add the address to the TCB local address restricted list.
    6310             :  * This is a "pending" address list (eg. addresses waiting for an
    6311             :  * ASCONF-ACK response) and cannot be used as a valid source address.
    6312             :  */
    6313             : void
    6314           0 : sctp_add_local_addr_restricted(struct sctp_tcb *stcb, struct sctp_ifa *ifa)
    6315             : {
    6316             :         struct sctp_laddr *laddr;
    6317             :         struct sctpladdr *list;
    6318             : 
    6319             :         /*
    6320             :          * Assumes TCB is locked.. and possibly the INP. May need to
    6321             :          * confirm/fix that if we need it and is not the case.
    6322             :          */
    6323           0 :         list = &stcb->asoc.sctp_restricted_addrs;
    6324             : 
    6325             : #ifdef INET6
    6326             :         if (ifa->address.sa.sa_family == AF_INET6) {
    6327             :                 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
    6328             :                         /* Can't bind a non-existent addr. */
    6329             :                         return;
    6330             :                 }
    6331             :         }
    6332             : #endif
    6333             :         /* does the address already exist? */
    6334           0 :         LIST_FOREACH(laddr, list, sctp_nxt_addr) {
    6335           0 :                 if (laddr->ifa == ifa) {
    6336           0 :                         return;
    6337             :                 }
    6338             :         }
    6339             : 
    6340             :         /* add to the list */
    6341           0 :         (void)sctp_insert_laddr(list, ifa, 0);
    6342           0 :         return;
    6343             : }
    6344             : 
    6345             : /*
    6346             :  * insert an laddr entry with the given ifa for the desired list
    6347             :  */
    6348             : int
    6349           0 : sctp_insert_laddr(struct sctpladdr *list, struct sctp_ifa *ifa, uint32_t act)
    6350             : {
    6351             :         struct sctp_laddr *laddr;
    6352             : 
    6353           0 :         laddr = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
    6354           0 :         if (laddr == NULL) {
    6355             :                 /* out of memory? */
    6356             :                 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
    6357           0 :                 return (EINVAL);
    6358             :         }
    6359           0 :         SCTP_INCR_LADDR_COUNT();
    6360           0 :         bzero(laddr, sizeof(*laddr));
    6361           0 :         (void)SCTP_GETTIME_TIMEVAL(&laddr->start_time);
    6362           0 :         laddr->ifa = ifa;
    6363           0 :         laddr->action = act;
    6364           0 :         atomic_add_int(&ifa->refcount, 1);
    6365             :         /* insert it */
    6366           0 :         LIST_INSERT_HEAD(list, laddr, sctp_nxt_addr);
    6367             : 
    6368           0 :         return (0);
    6369             : }
    6370             : 
    6371             : /*
    6372             :  * Remove an laddr entry from the local address list (on an assoc)
    6373             :  */
    6374             : void
    6375           0 : sctp_remove_laddr(struct sctp_laddr *laddr)
    6376             : {
    6377             : 
    6378             :         /* remove from the list */
    6379           0 :         LIST_REMOVE(laddr, sctp_nxt_addr);
    6380           0 :         sctp_free_ifa(laddr->ifa);
    6381           0 :         SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), laddr);
    6382           0 :         SCTP_DECR_LADDR_COUNT();
    6383           0 : }
    6384             : 
    6385             : /*
    6386             :  * Remove a local address from the TCB local address restricted list
    6387             :  */
    6388             : void
    6389           0 : sctp_del_local_addr_restricted(struct sctp_tcb *stcb, struct sctp_ifa *ifa)
    6390             : {
    6391             :         struct sctp_inpcb *inp;
    6392             :         struct sctp_laddr *laddr;
    6393             : 
    6394             :         /*
    6395             :          * This is called by asconf work. It is assumed that a) The TCB is
    6396             :          * locked and b) The INP is locked. This is true in as much as I can
    6397             :          * trace through the entry asconf code where I did these locks.
    6398             :          * Again, the ASCONF code is a bit different in that it does lock
    6399             :          * the INP during its work often times. This must be since we don't
    6400             :          * want other proc's looking up things while what they are looking
    6401             :          * up is changing :-D
    6402             :          */
    6403             : 
    6404           0 :         inp = stcb->sctp_ep;
    6405             :         /* if subset bound and don't allow ASCONF's, can't delete last */
    6406           0 :         if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) &&
    6407           0 :             sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
    6408           0 :                 if (stcb->sctp_ep->laddr_count < 2) {
    6409             :                         /* can't delete last address */
    6410           0 :                         return;
    6411             :                 }
    6412             :         }
    6413           0 :         LIST_FOREACH(laddr, &stcb->asoc.sctp_restricted_addrs, sctp_nxt_addr) {
    6414             :                 /* remove the address if it exists */
    6415           0 :                 if (laddr->ifa == NULL)
    6416           0 :                         continue;
    6417           0 :                 if (laddr->ifa == ifa) {
    6418           0 :                         sctp_remove_laddr(laddr);
    6419           0 :                         return;
    6420             :                 }
    6421             :         }
    6422             : 
    6423             :         /* address not found! */
    6424           0 :         return;
    6425             : }
    6426             : 
    6427             : #if defined(__FreeBSD__)
    6428             : /*
    6429             :  * Temporarily remove for __APPLE__ until we use the Tiger equivalents
    6430             :  */
    6431             : /* sysctl */
    6432             : static int sctp_max_number_of_assoc = SCTP_MAX_NUM_OF_ASOC;
    6433             : static int sctp_scale_up_for_address = SCTP_SCALE_FOR_ADDR;
    6434             : #endif                          /* FreeBSD || APPLE */
    6435             : 
    6436             : 
    6437             : 
    6438             : #if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP)
    6439             : struct sctp_mcore_ctrl *sctp_mcore_workers = NULL;
    6440             : int *sctp_cpuarry = NULL;
    6441             : void
    6442             : sctp_queue_to_mcore(struct mbuf *m, int off, int cpu_to_use)
    6443             : {
    6444             :         /* Queue a packet to a processor for the specified core */
    6445             :         struct sctp_mcore_queue *qent;
    6446             :         struct sctp_mcore_ctrl *wkq;
    6447             :         int need_wake = 0;
    6448             :         if (sctp_mcore_workers == NULL) {
    6449             :                 /* Something went way bad during setup */
    6450             :                 sctp_input_with_port(m, off, 0);
    6451             :                 return;
    6452             :         }
    6453             :         SCTP_MALLOC(qent, struct sctp_mcore_queue *,
    6454             :                     (sizeof(struct sctp_mcore_queue)),
    6455             :                     SCTP_M_MCORE);
    6456             :         if (qent == NULL) {
    6457             :                 /* This is trouble  */
    6458             :                 sctp_input_with_port(m, off, 0);
    6459             :                 return;
    6460             :         }
    6461             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
    6462             :         qent->vn = curvnet;
    6463             : #endif
    6464             :         qent->m = m;
    6465             :         qent->off = off;
    6466             :         qent->v6 = 0;
    6467             :         wkq = &sctp_mcore_workers[cpu_to_use];
    6468             :         SCTP_MCORE_QLOCK(wkq);
    6469             : 
    6470             :         TAILQ_INSERT_TAIL(&wkq->que, qent, next);
    6471             :         if (wkq->running == 0) {
    6472             :                 need_wake = 1;
    6473             :         }
    6474             :         SCTP_MCORE_QUNLOCK(wkq);
    6475             :         if (need_wake) {
    6476             :                 wakeup(&wkq->running);
    6477             :         }
    6478             : }
    6479             : 
    6480             : static void
    6481             : sctp_mcore_thread(void *arg)
    6482             : {
    6483             : 
    6484             :         struct sctp_mcore_ctrl *wkq;
    6485             :         struct sctp_mcore_queue *qent;
    6486             : 
    6487             :         wkq = (struct sctp_mcore_ctrl *)arg;
    6488             :         struct mbuf *m;
    6489             :         int off, v6;
    6490             : 
    6491             :         /* Wait for first tickle */
    6492             :         SCTP_MCORE_LOCK(wkq);
    6493             :         wkq->running = 0;
    6494             :         msleep(&wkq->running,
    6495             :                &wkq->core_mtx,
    6496             :                0, "wait for pkt", 0);
    6497             :         SCTP_MCORE_UNLOCK(wkq);
    6498             : 
    6499             :         /* Bind to our cpu */
    6500             :         thread_lock(curthread);
    6501             :         sched_bind(curthread, wkq->cpuid);
    6502             :         thread_unlock(curthread);
    6503             : 
    6504             :         /* Now lets start working */
    6505             :         SCTP_MCORE_LOCK(wkq);
    6506             :         /* Now grab lock and go */
    6507             :         for (;;) {
    6508             :                 SCTP_MCORE_QLOCK(wkq);
    6509             :         skip_sleep:
    6510             :                 wkq->running = 1;
    6511             :                 qent = TAILQ_FIRST(&wkq->que);
    6512             :                 if (qent) {
    6513             :                         TAILQ_REMOVE(&wkq->que, qent, next);
    6514             :                         SCTP_MCORE_QUNLOCK(wkq);
    6515             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
    6516             :                         CURVNET_SET(qent->vn);
    6517             : #endif
    6518             :                         m = qent->m;
    6519             :                         off = qent->off;
    6520             :                         v6 = qent->v6;
    6521             :                         SCTP_FREE(qent, SCTP_M_MCORE);
    6522             :                         if (v6 == 0) {
    6523             :                                 sctp_input_with_port(m, off, 0);
    6524             :                         } else {
    6525             :                                 SCTP_PRINTF("V6 not yet supported\n");
    6526             :                                 sctp_m_freem(m);
    6527             :                         }
    6528             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
    6529             :                         CURVNET_RESTORE();
    6530             : #endif
    6531             :                         SCTP_MCORE_QLOCK(wkq);
    6532             :                 }
    6533             :                 wkq->running = 0;
    6534             :                 if (!TAILQ_EMPTY(&wkq->que)) {
    6535             :                         goto skip_sleep;
    6536             :                 }
    6537             :                 SCTP_MCORE_QUNLOCK(wkq);
    6538             :                 msleep(&wkq->running,
    6539             :                        &wkq->core_mtx,
    6540             :                        0, "wait for pkt", 0);
    6541             :         }
    6542             : }
    6543             : 
    6544             : static void
    6545             : sctp_startup_mcore_threads(void)
    6546             : {
    6547             :         int i, cpu;
    6548             : 
    6549             :         if (mp_ncpus == 1)
    6550             :                 return;
    6551             : 
    6552             :         if (sctp_mcore_workers != NULL) {
    6553             :                 /* Already been here in some previous
    6554             :                  * vnet?
    6555             :                  */
    6556             :                 return;
    6557             :         }
    6558             :         SCTP_MALLOC(sctp_mcore_workers, struct sctp_mcore_ctrl *,
    6559             :                     ((mp_maxid+1) * sizeof(struct sctp_mcore_ctrl)),
    6560             :                     SCTP_M_MCORE);
    6561             :         if (sctp_mcore_workers == NULL) {
    6562             :                 /* TSNH I hope */
    6563             :                 return;
    6564             :         }
    6565             :         memset(sctp_mcore_workers, 0 , ((mp_maxid+1) *
    6566             :                                         sizeof(struct sctp_mcore_ctrl)));
    6567             :         /* Init the structures */
    6568             :         for (i = 0; i<=mp_maxid; i++) {
    6569             :                 TAILQ_INIT(&sctp_mcore_workers[i].que);
    6570             :                 SCTP_MCORE_LOCK_INIT(&sctp_mcore_workers[i]);
    6571             :                 SCTP_MCORE_QLOCK_INIT(&sctp_mcore_workers[i]);
    6572             :                 sctp_mcore_workers[i].cpuid = i;
    6573             :         }
    6574             :         if (sctp_cpuarry == NULL) {
    6575             :                 SCTP_MALLOC(sctp_cpuarry, int *,
    6576             :                             (mp_ncpus * sizeof(int)),
    6577             :                             SCTP_M_MCORE);
    6578             :                 i = 0;
    6579             :                 CPU_FOREACH(cpu) {
    6580             :                         sctp_cpuarry[i] = cpu;
    6581             :                         i++;
    6582             :                 }
    6583             :         }
    6584             : 
    6585             :         /* Now start them all */
    6586             :         CPU_FOREACH(cpu) {
    6587             : #if __FreeBSD_version <= 701000
    6588             :                 (void)kthread_create(sctp_mcore_thread,
    6589             :                                      (void *)&sctp_mcore_workers[cpu],
    6590             :                                      &sctp_mcore_workers[cpu].thread_proc,
    6591             :                                      RFPROC,
    6592             :                                      SCTP_KTHREAD_PAGES,
    6593             :                                      SCTP_MCORE_NAME);
    6594             : 
    6595             : #else
    6596             :                 (void)kproc_create(sctp_mcore_thread,
    6597             :                                    (void *)&sctp_mcore_workers[cpu],
    6598             :                                    &sctp_mcore_workers[cpu].thread_proc,
    6599             :                                    RFPROC,
    6600             :                                    SCTP_KTHREAD_PAGES,
    6601             :                                    SCTP_MCORE_NAME);
    6602             : #endif
    6603             : 
    6604             :         }
    6605             : }
    6606             : #endif
    6607             : #if defined(__FreeBSD__) && __FreeBSD_cc_version >= 1200000
    6608             : static struct mbuf *
    6609             : sctp_netisr_hdlr(struct mbuf *m, uintptr_t source)
    6610             : {
    6611             :         struct ip *ip;
    6612             :         struct sctphdr *sh;
    6613             :         int offset;
    6614             :         uint32_t flowid, tag;
    6615             : 
    6616             :         /*
    6617             :          * No flow id built by lower layers fix it so we
    6618             :          * create one.
    6619             :          */
    6620             :         ip = mtod(m, struct ip *);
    6621             :         offset = (ip->ip_hl << 2) + sizeof(struct sctphdr);
    6622             :         if (SCTP_BUF_LEN(m) < offset) {
    6623             :                 if ((m = m_pullup(m, offset)) == NULL) {
    6624             :                         SCTP_STAT_INCR(sctps_hdrops);
    6625             :                         return (NULL);
    6626             :                 }
    6627             :                 ip = mtod(m, struct ip *);
    6628             :         }
    6629             :         sh = (struct sctphdr *)((caddr_t)ip + (ip->ip_hl << 2));
    6630             :         tag = htonl(sh->v_tag);
    6631             :         flowid = tag ^ ntohs(sh->dest_port) ^ ntohs(sh->src_port);
    6632             :         m->m_pkthdr.flowid = flowid;
    6633             :         m->m_flags |= M_FLOWID;
    6634             :         return (m);
    6635             : }
    6636             : #endif
    6637             : 
    6638             : void
    6639           0 : sctp_pcb_init()
    6640             : {
    6641             :         /*
    6642             :          * SCTP initialization for the PCB structures should be called by
    6643             :          * the sctp_init() funciton.
    6644             :          */
    6645             :         int i;
    6646             :         struct timeval tv;
    6647             : 
    6648           0 :         if (SCTP_BASE_VAR(sctp_pcb_initialized) != 0) {
    6649             :                 /* error I was called twice */
    6650           0 :                 return;
    6651             :         }
    6652           0 :         SCTP_BASE_VAR(sctp_pcb_initialized) = 1;
    6653             : 
    6654             : #if defined(SCTP_LOCAL_TRACE_BUF)
    6655             : #if defined(__Windows__)
    6656             :         if (SCTP_BASE_SYSCTL(sctp_log) != NULL) {
    6657             :                 bzero(SCTP_BASE_SYSCTL(sctp_log), sizeof(struct sctp_log));
    6658             :         }
    6659             : #else
    6660             :         bzero(&SCTP_BASE_SYSCTL(sctp_log), sizeof(struct sctp_log));
    6661             : #endif
    6662             : #endif
    6663             : #if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
    6664             :         SCTP_MALLOC(SCTP_BASE_STATS, struct sctpstat *,
    6665             :                     ((mp_maxid+1) * sizeof(struct sctpstat)),
    6666             :                     SCTP_M_MCORE);
    6667             : #endif
    6668           0 :         (void)SCTP_GETTIME_TIMEVAL(&tv);
    6669             : #if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
    6670             :         bzero(SCTP_BASE_STATS, (sizeof(struct sctpstat) * (mp_maxid+1)));
    6671             :         SCTP_BASE_STATS[PCPU_GET(cpuid)].sctps_discontinuitytime.tv_sec = (uint32_t)tv.tv_sec;
    6672             :         SCTP_BASE_STATS[PCPU_GET(cpuid)].sctps_discontinuitytime.tv_usec = (uint32_t)tv.tv_usec;
    6673             : #else
    6674           0 :         bzero(&SCTP_BASE_STATS, sizeof(struct sctpstat));
    6675           0 :         SCTP_BASE_STAT(sctps_discontinuitytime).tv_sec = (uint32_t)tv.tv_sec;
    6676           0 :         SCTP_BASE_STAT(sctps_discontinuitytime).tv_usec = (uint32_t)tv.tv_usec;
    6677             : #endif
    6678             :         /* init the empty list of (All) Endpoints */
    6679           0 :         LIST_INIT(&SCTP_BASE_INFO(listhead));
    6680             : #if defined(__APPLE__)
    6681             :         LIST_INIT(&SCTP_BASE_INFO(inplisthead));
    6682             : #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
    6683             :         SCTP_BASE_INFO(sctbinfo).listhead = &SCTP_BASE_INFO(inplisthead);
    6684             :         SCTP_BASE_INFO(sctbinfo).mtx_grp_attr = lck_grp_attr_alloc_init();
    6685             :         lck_grp_attr_setdefault(SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
    6686             :         SCTP_BASE_INFO(sctbinfo).mtx_grp = lck_grp_alloc_init("sctppcb", SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
    6687             :         SCTP_BASE_INFO(sctbinfo).mtx_attr = lck_attr_alloc_init();
    6688             :         lck_attr_setdefault(SCTP_BASE_INFO(sctbinfo).mtx_attr);
    6689             : #else
    6690             :         SCTP_BASE_INFO(sctbinfo).ipi_listhead = &SCTP_BASE_INFO(inplisthead);
    6691             :         SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr = lck_grp_attr_alloc_init();
    6692             :         lck_grp_attr_setdefault(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
    6693             :         SCTP_BASE_INFO(sctbinfo).ipi_lock_grp = lck_grp_alloc_init("sctppcb", SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
    6694             :         SCTP_BASE_INFO(sctbinfo).ipi_lock_attr = lck_attr_alloc_init();
    6695             :         lck_attr_setdefault(SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
    6696             : #endif
    6697             : #if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
    6698             :         SCTP_BASE_INFO(sctbinfo).ipi_gc = sctp_gc;
    6699             :         in_pcbinfo_attach(&SCTP_BASE_INFO(sctbinfo));
    6700             : #endif
    6701             : #endif
    6702             : 
    6703             : 
    6704             :         /* init the hash table of endpoints */
    6705             : #if defined(__FreeBSD__)
    6706             : #if defined(__FreeBSD_cc_version) && __FreeBSD_cc_version >= 440000
    6707             :         TUNABLE_INT_FETCH("net.inet.sctp.tcbhashsize", &SCTP_BASE_SYSCTL(sctp_hashtblsize));
    6708             :         TUNABLE_INT_FETCH("net.inet.sctp.pcbhashsize", &SCTP_BASE_SYSCTL(sctp_pcbtblsize));
    6709             :         TUNABLE_INT_FETCH("net.inet.sctp.chunkscale", &SCTP_BASE_SYSCTL(sctp_chunkscale));
    6710             : #else
    6711             :         TUNABLE_INT_FETCH("net.inet.sctp.tcbhashsize", SCTP_TCBHASHSIZE,
    6712             :                           SCTP_BASE_SYSCTL(sctp_hashtblsize));
    6713             :         TUNABLE_INT_FETCH("net.inet.sctp.pcbhashsize", SCTP_PCBHASHSIZE,
    6714             :                           SCTP_BASE_SYSCTL(sctp_pcbtblsize));
    6715             :         TUNABLE_INT_FETCH("net.inet.sctp.chunkscale", SCTP_CHUNKQUEUE_SCALE,
    6716             :                           SCTP_BASE_SYSCTL(sctp_chunkscale));
    6717             : #endif
    6718             : #endif
    6719           0 :         SCTP_BASE_INFO(sctp_asochash) = SCTP_HASH_INIT((SCTP_BASE_SYSCTL(sctp_hashtblsize) * 31),
    6720             :                                                        &SCTP_BASE_INFO(hashasocmark));
    6721           0 :         SCTP_BASE_INFO(sctp_ephash) = SCTP_HASH_INIT(SCTP_BASE_SYSCTL(sctp_hashtblsize),
    6722             :                                                      &SCTP_BASE_INFO(hashmark));
    6723           0 :         SCTP_BASE_INFO(sctp_tcpephash) = SCTP_HASH_INIT(SCTP_BASE_SYSCTL(sctp_hashtblsize),
    6724             :                                                         &SCTP_BASE_INFO(hashtcpmark));
    6725           0 :         SCTP_BASE_INFO(hashtblsize) = SCTP_BASE_SYSCTL(sctp_hashtblsize);
    6726             : 
    6727             : 
    6728           0 :         SCTP_BASE_INFO(sctp_vrfhash) = SCTP_HASH_INIT(SCTP_SIZE_OF_VRF_HASH,
    6729             :                                                       &SCTP_BASE_INFO(hashvrfmark));
    6730             : 
    6731           0 :         SCTP_BASE_INFO(vrf_ifn_hash) = SCTP_HASH_INIT(SCTP_VRF_IFN_HASH_SIZE,
    6732             :                                                       &SCTP_BASE_INFO(vrf_ifn_hashmark));
    6733             :         /* init the zones */
    6734             :         /*
    6735             :          * FIX ME: Should check for NULL returns, but if it does fail we are
    6736             :          * doomed to panic anyways... add later maybe.
    6737             :          */
    6738           0 :         SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_ep), "sctp_ep",
    6739             :                        sizeof(struct sctp_inpcb), maxsockets);
    6740             : 
    6741           0 :         SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_asoc), "sctp_asoc",
    6742             :                        sizeof(struct sctp_tcb), sctp_max_number_of_assoc);
    6743             : 
    6744           0 :         SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_laddr), "sctp_laddr",
    6745             :                        sizeof(struct sctp_laddr),
    6746             :                        (sctp_max_number_of_assoc * sctp_scale_up_for_address));
    6747             : 
    6748           0 :         SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_net), "sctp_raddr",
    6749             :                        sizeof(struct sctp_nets),
    6750             :                        (sctp_max_number_of_assoc * sctp_scale_up_for_address));
    6751             : 
    6752           0 :         SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_chunk), "sctp_chunk",
    6753             :                        sizeof(struct sctp_tmit_chunk),
    6754             :                        (sctp_max_number_of_assoc * SCTP_BASE_SYSCTL(sctp_chunkscale)));
    6755             : 
    6756           0 :         SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_readq), "sctp_readq",
    6757             :                        sizeof(struct sctp_queued_to_read),
    6758             :                        (sctp_max_number_of_assoc * SCTP_BASE_SYSCTL(sctp_chunkscale)));
    6759             : 
    6760           0 :         SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_strmoq), "sctp_stream_msg_out",
    6761             :                        sizeof(struct sctp_stream_queue_pending),
    6762             :                        (sctp_max_number_of_assoc * SCTP_BASE_SYSCTL(sctp_chunkscale)));
    6763             : 
    6764           0 :         SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_asconf), "sctp_asconf",
    6765             :                        sizeof(struct sctp_asconf),
    6766             :                        (sctp_max_number_of_assoc * SCTP_BASE_SYSCTL(sctp_chunkscale)));
    6767             : 
    6768           0 :         SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_asconf_ack), "sctp_asconf_ack",
    6769             :                        sizeof(struct sctp_asconf_ack),
    6770             :                        (sctp_max_number_of_assoc * SCTP_BASE_SYSCTL(sctp_chunkscale)));
    6771             : 
    6772             : 
    6773             :         /* Master Lock INIT for info structure */
    6774           0 :         SCTP_INP_INFO_LOCK_INIT();
    6775             :         SCTP_STATLOG_INIT_LOCK();
    6776             : 
    6777             :         SCTP_IPI_COUNT_INIT();
    6778           0 :         SCTP_IPI_ADDR_INIT();
    6779             : #ifdef SCTP_PACKET_LOGGING
    6780             :         SCTP_IP_PKTLOG_INIT();
    6781             : #endif
    6782           0 :         LIST_INIT(&SCTP_BASE_INFO(addr_wq));
    6783             : 
    6784           0 :         SCTP_WQ_ADDR_INIT();
    6785             :         /* not sure if we need all the counts */
    6786           0 :         SCTP_BASE_INFO(ipi_count_ep) = 0;
    6787             :         /* assoc/tcb zone info */
    6788           0 :         SCTP_BASE_INFO(ipi_count_asoc) = 0;
    6789             :         /* local addrlist zone info */
    6790           0 :         SCTP_BASE_INFO(ipi_count_laddr) = 0;
    6791             :         /* remote addrlist zone info */
    6792           0 :         SCTP_BASE_INFO(ipi_count_raddr) = 0;
    6793             :         /* chunk info */
    6794           0 :         SCTP_BASE_INFO(ipi_count_chunk) = 0;
    6795             : 
    6796             :         /* socket queue zone info */
    6797           0 :         SCTP_BASE_INFO(ipi_count_readq) = 0;
    6798             : 
    6799             :         /* stream out queue cont */
    6800           0 :         SCTP_BASE_INFO(ipi_count_strmoq) = 0;
    6801             : 
    6802           0 :         SCTP_BASE_INFO(ipi_free_strmoq) = 0;
    6803           0 :         SCTP_BASE_INFO(ipi_free_chunks) = 0;
    6804             : 
    6805           0 :         SCTP_OS_TIMER_INIT(&SCTP_BASE_INFO(addr_wq_timer.timer));
    6806             : 
    6807             :         /* Init the TIMEWAIT list */
    6808           0 :         for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
    6809           0 :                 LIST_INIT(&SCTP_BASE_INFO(vtag_timewait)[i]);
    6810             :         }
    6811             : #if defined(SCTP_PROCESS_LEVEL_LOCKS)
    6812             : #if defined(__Userspace_os_Windows)
    6813             :         InitializeConditionVariable(&sctp_it_ctl.iterator_wakeup);
    6814             : #else
    6815           0 :         (void)pthread_cond_init(&sctp_it_ctl.iterator_wakeup, NULL);
    6816             : #endif
    6817             : #endif
    6818           0 :         sctp_startup_iterator();
    6819             : 
    6820             : #if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP)
    6821             :         sctp_startup_mcore_threads();
    6822             : #endif
    6823             : 
    6824             : #ifndef __Panda__
    6825             :         /*
    6826             :          * INIT the default VRF which for BSD is the only one, other O/S's
    6827             :          * may have more. But initially they must start with one and then
    6828             :          * add the VRF's as addresses are added.
    6829             :          */
    6830           0 :         sctp_init_vrf_list(SCTP_DEFAULT_VRF);
    6831             : #endif
    6832             : #if defined(__FreeBSD__) && __FreeBSD_cc_version >= 1200000
    6833             :         if (ip_register_flow_handler(sctp_netisr_hdlr, IPPROTO_SCTP)) {
    6834             :                 SCTP_PRINTF("***SCTP- Error can't register netisr handler***\n");
    6835             :         }
    6836             : #endif
    6837             : #if defined(_SCTP_NEEDS_CALLOUT_) || defined(_USER_SCTP_NEEDS_CALLOUT_)
    6838             :         /* allocate the lock for the callout/timer queue */
    6839           0 :         SCTP_TIMERQ_LOCK_INIT();
    6840           0 :         TAILQ_INIT(&SCTP_BASE_INFO(callqueue));
    6841             : #endif
    6842             : #if defined(__Userspace__)
    6843           0 :         mbuf_init(NULL);
    6844           0 :         atomic_init();
    6845             : #if defined(INET) || defined(INET6)
    6846             :         recv_thread_init();
    6847             : #endif
    6848             : #endif
    6849             : }
    6850             : 
    6851             : /*
    6852             :  * Assumes that the SCTP_BASE_INFO() lock is NOT held.
    6853             :  */
    6854             : void
    6855           0 : sctp_pcb_finish(void)
    6856             : {
    6857             :         struct sctp_vrflist *vrf_bucket;
    6858             :         struct sctp_vrf *vrf, *nvrf;
    6859             :         struct sctp_ifn *ifn, *nifn;
    6860             :         struct sctp_ifa *ifa, *nifa;
    6861             :         struct sctpvtaghead *chain;
    6862             :         struct sctp_tagblock *twait_block, *prev_twait_block;
    6863             :         struct sctp_laddr *wi, *nwi;
    6864             :         int i;
    6865             :         struct sctp_iterator *it, *nit;
    6866             :         
    6867             : #if !defined(__FreeBSD__)
    6868             :         /* Notify the iterator to exit. */
    6869           0 :         SCTP_IPI_ITERATOR_WQ_LOCK();
    6870           0 :         sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_MUST_EXIT;
    6871           0 :         sctp_wakeup_iterator();
    6872           0 :         SCTP_IPI_ITERATOR_WQ_UNLOCK();
    6873             : #endif
    6874             : #if defined(__APPLE__)
    6875             : #if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
    6876             :         in_pcbinfo_detach(&SCTP_BASE_INFO(sctbinfo));
    6877             : #endif
    6878             :         SCTP_IPI_ITERATOR_WQ_LOCK();
    6879             :         do {
    6880             :                 msleep(&sctp_it_ctl.iterator_flags,
    6881             :                        sctp_it_ctl.ipi_iterator_wq_mtx,
    6882             :                        0, "waiting_for_work", 0);
    6883             :         } while ((sctp_it_ctl.iterator_flags & SCTP_ITERATOR_EXITED) == 0);
    6884             :         thread_deallocate(sctp_it_ctl.thread_proc);
    6885             :         SCTP_IPI_ITERATOR_WQ_UNLOCK();
    6886             : #endif
    6887             : #if defined(__Windows__)
    6888             :         if (sctp_it_ctl.iterator_thread_obj != NULL) {
    6889             :                 NTSTATUS status = STATUS_SUCCESS;
    6890             : 
    6891             :                 KeSetEvent(&sctp_it_ctl.iterator_wakeup[1], IO_NO_INCREMENT, FALSE);
    6892             :                 status = KeWaitForSingleObject(sctp_it_ctl.iterator_thread_obj,
    6893             :                                                Executive,
    6894             :                                                KernelMode,
    6895             :                                                FALSE,
    6896             :                                                NULL);
    6897             :                 ObDereferenceObject(sctp_it_ctl.iterator_thread_obj);
    6898             :         }
    6899             : #endif
    6900             : #if defined(__Userspace__)
    6901           0 :         if (sctp_it_ctl.thread_proc) {
    6902             : #if defined(__Userspace_os_Windows)
    6903             :                 WaitForSingleObject(sctp_it_ctl.thread_proc, INFINITE);
    6904             :                 CloseHandle(sctp_it_ctl.thread_proc);
    6905             :                 sctp_it_ctl.thread_proc = NULL;
    6906             : #else
    6907           0 :                 pthread_join(sctp_it_ctl.thread_proc, NULL);
    6908           0 :                 sctp_it_ctl.thread_proc = 0;
    6909             : #endif
    6910             :         }
    6911             : #endif
    6912             : #if defined(SCTP_PROCESS_LEVEL_LOCKS)
    6913             : #if defined(__Userspace_os_Windows)
    6914             :         DeleteConditionVariable(&sctp_it_ctl.iterator_wakeup);
    6915             : #else
    6916           0 :         pthread_cond_destroy(&sctp_it_ctl.iterator_wakeup);
    6917             : #endif
    6918             : #endif
    6919             :         /* In FreeBSD the iterator thread never exits
    6920             :          * but we do clean up.
    6921             :          * The only way FreeBSD reaches here is if we have VRF's
    6922             :          * but we still add the ifdef to make it compile on old versions.
    6923             :          */
    6924           0 :         SCTP_IPI_ITERATOR_WQ_LOCK();
    6925           0 :         TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
    6926             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
    6927             :                 if (it->vn != curvnet) {
    6928             :                         continue;
    6929             :                 }
    6930             : #endif
    6931           0 :                 TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
    6932           0 :                 if (it->function_atend != NULL) {
    6933           0 :                         (*it->function_atend) (it->pointer, it->val);
    6934             :                 }
    6935           0 :                 SCTP_FREE(it,SCTP_M_ITER);
    6936             :         }
    6937           0 :         SCTP_IPI_ITERATOR_WQ_UNLOCK();
    6938             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
    6939             :         SCTP_ITERATOR_LOCK();
    6940             :         if ((sctp_it_ctl.cur_it) &&
    6941             :             (sctp_it_ctl.cur_it->vn == curvnet)) {
    6942             :                 sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
    6943             :         }
    6944             :         SCTP_ITERATOR_UNLOCK();
    6945             : #endif
    6946             : #if !defined(__FreeBSD__)
    6947           0 :         SCTP_IPI_ITERATOR_WQ_DESTROY();
    6948           0 :         SCTP_ITERATOR_LOCK_DESTROY();
    6949             : #endif
    6950           0 :         SCTP_OS_TIMER_STOP(&SCTP_BASE_INFO(addr_wq_timer.timer));
    6951           0 :         SCTP_WQ_ADDR_LOCK();
    6952           0 :         LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) {
    6953           0 :                 LIST_REMOVE(wi, sctp_nxt_addr);
    6954           0 :                 SCTP_DECR_LADDR_COUNT();
    6955           0 :                 if (wi->action == SCTP_DEL_IP_ADDRESS) {
    6956           0 :                         SCTP_FREE(wi->ifa, SCTP_M_IFA);
    6957             :                 }
    6958           0 :                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), wi);
    6959             :         }
    6960           0 :         SCTP_WQ_ADDR_UNLOCK();
    6961             : 
    6962             :         /*
    6963             :          * free the vrf/ifn/ifa lists and hashes (be sure address monitor
    6964             :          * is destroyed first).
    6965             :          */
    6966           0 :         vrf_bucket = &SCTP_BASE_INFO(sctp_vrfhash)[(SCTP_DEFAULT_VRFID & SCTP_BASE_INFO(hashvrfmark))];
    6967           0 :         LIST_FOREACH_SAFE(vrf, vrf_bucket, next_vrf, nvrf) {
    6968           0 :                 LIST_FOREACH_SAFE(ifn, &vrf->ifnlist, next_ifn, nifn) {
    6969           0 :                         LIST_FOREACH_SAFE(ifa, &ifn->ifalist, next_ifa, nifa) {
    6970             :                                 /* free the ifa */
    6971           0 :                                 LIST_REMOVE(ifa, next_bucket);
    6972           0 :                                 LIST_REMOVE(ifa, next_ifa);
    6973           0 :                                 SCTP_FREE(ifa, SCTP_M_IFA);
    6974             :                         }
    6975             :                         /* free the ifn */
    6976           0 :                         LIST_REMOVE(ifn, next_bucket);
    6977           0 :                         LIST_REMOVE(ifn, next_ifn);
    6978           0 :                         SCTP_FREE(ifn, SCTP_M_IFN);
    6979             :                 }
    6980           0 :                 SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark);
    6981             :                 /* free the vrf */
    6982           0 :                 LIST_REMOVE(vrf, next_vrf);
    6983           0 :                 SCTP_FREE(vrf, SCTP_M_VRF);
    6984             :         }
    6985             :         /* free the vrf hashes */
    6986           0 :         SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_vrfhash), SCTP_BASE_INFO(hashvrfmark));
    6987           0 :         SCTP_HASH_FREE(SCTP_BASE_INFO(vrf_ifn_hash), SCTP_BASE_INFO(vrf_ifn_hashmark));
    6988             : #if defined(__Userspace__) && !defined(__Userspace_os_Windows)
    6989             :         /* free memory allocated by getifaddrs call */
    6990             : #if defined(INET) || defined(INET6)
    6991             :         freeifaddrs(g_interfaces);
    6992             : #endif
    6993             : #endif
    6994             : 
    6995             :         /* free the TIMEWAIT list elements malloc'd in the function
    6996             :          * sctp_add_vtag_to_timewait()...
    6997             :          */
    6998           0 :         for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
    6999           0 :                 chain = &SCTP_BASE_INFO(vtag_timewait)[i];
    7000           0 :                 if (!LIST_EMPTY(chain)) {
    7001           0 :                         prev_twait_block = NULL;
    7002           0 :                         LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
    7003           0 :                                 if (prev_twait_block) {
    7004           0 :                                         SCTP_FREE(prev_twait_block, SCTP_M_TIMW);
    7005             :                                 }
    7006           0 :                                 prev_twait_block = twait_block;
    7007             :                         }
    7008           0 :                         SCTP_FREE(prev_twait_block, SCTP_M_TIMW);
    7009             :                 }
    7010             :         }
    7011             : 
    7012             :         /* free the locks and mutexes */
    7013             : #if defined(__APPLE__)
    7014             :         SCTP_TIMERQ_LOCK_DESTROY();
    7015             : #endif
    7016             : #ifdef SCTP_PACKET_LOGGING
    7017             :         SCTP_IP_PKTLOG_DESTROY();
    7018             : #endif
    7019           0 :         SCTP_IPI_ADDR_DESTROY();
    7020             : #if defined(__APPLE__)
    7021             :         SCTP_IPI_COUNT_DESTROY();
    7022             : #endif
    7023             :         SCTP_STATLOG_DESTROY();
    7024           0 :         SCTP_INP_INFO_LOCK_DESTROY();
    7025             : 
    7026           0 :         SCTP_WQ_ADDR_DESTROY();
    7027             : 
    7028             : #if defined(__APPLE__)
    7029             : #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
    7030             :         lck_grp_attr_free(SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
    7031             :         lck_grp_free(SCTP_BASE_INFO(sctbinfo).mtx_grp);
    7032             :         lck_attr_free(SCTP_BASE_INFO(sctbinfo).mtx_attr);
    7033             : #else
    7034             :         lck_grp_attr_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
    7035             :         lck_grp_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp);
    7036             :         lck_attr_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
    7037             : #endif
    7038             : #endif
    7039             : #if defined(__Userspace__)
    7040           0 :         SCTP_TIMERQ_LOCK_DESTROY();
    7041             :         SCTP_ZONE_DESTROY(zone_mbuf);
    7042             :         SCTP_ZONE_DESTROY(zone_clust);
    7043             :         SCTP_ZONE_DESTROY(zone_ext_refcnt);
    7044             : #endif
    7045             : #if defined(__Windows__) || defined(__FreeBSD__) || defined(__Userspace__)
    7046             :         SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_ep));
    7047             :         SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asoc));
    7048             :         SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_laddr));
    7049             :         SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_net));
    7050             :         SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_chunk));
    7051             :         SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_readq));
    7052             :         SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_strmoq));
    7053             :         SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asconf));
    7054             :         SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asconf_ack));
    7055             : #endif
    7056             :         /* Get rid of other stuff to */
    7057           0 :         if (SCTP_BASE_INFO(sctp_asochash) != NULL)
    7058           0 :                 SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_asochash), SCTP_BASE_INFO(hashasocmark));
    7059           0 :         if (SCTP_BASE_INFO(sctp_ephash) != NULL)
    7060           0 :                 SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_ephash), SCTP_BASE_INFO(hashmark));
    7061           0 :         if (SCTP_BASE_INFO(sctp_tcpephash) != NULL)
    7062           0 :                 SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_tcpephash), SCTP_BASE_INFO(hashtcpmark));
    7063             : #if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
    7064             :         SCTP_FREE(SCTP_BASE_STATS, SCTP_M_MCORE);
    7065             : #endif
    7066           0 : }
    7067             : 
    7068             : 
    7069             : int
    7070           0 : sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
    7071             :                               int offset, int limit,
    7072             :                               struct sockaddr *src, struct sockaddr *dst,
    7073             :                               struct sockaddr *altsa)
    7074             : {
    7075             :         /*
    7076             :          * grub through the INIT pulling addresses and loading them to the
    7077             :          * nets structure in the asoc. The from address in the mbuf should
    7078             :          * also be loaded (if it is not already). This routine can be called
    7079             :          * with either INIT or INIT-ACK's as long as the m points to the IP
    7080             :          * packet and the offset points to the beginning of the parameters.
    7081             :          */
    7082             :         struct sctp_inpcb *inp;
    7083             :         struct sctp_nets *net, *nnet, *net_tmp;
    7084             :         struct sctp_paramhdr *phdr, parm_buf;
    7085             :         struct sctp_tcb *stcb_tmp;
    7086             :         uint16_t ptype, plen;
    7087             :         struct sockaddr *sa;
    7088             :         uint8_t random_store[SCTP_PARAM_BUFFER_SIZE];
    7089           0 :         struct sctp_auth_random *p_random = NULL;
    7090           0 :         uint16_t random_len = 0;
    7091             :         uint8_t hmacs_store[SCTP_PARAM_BUFFER_SIZE];
    7092           0 :         struct sctp_auth_hmac_algo *hmacs = NULL;
    7093           0 :         uint16_t hmacs_len = 0;
    7094           0 :         uint8_t saw_asconf = 0;
    7095           0 :         uint8_t saw_asconf_ack = 0;
    7096             :         uint8_t chunks_store[SCTP_PARAM_BUFFER_SIZE];
    7097           0 :         struct sctp_auth_chunk_list *chunks = NULL;
    7098           0 :         uint16_t num_chunks = 0;
    7099             :         sctp_key_t *new_key;
    7100             :         uint32_t keylen;
    7101           0 :         int got_random = 0, got_hmacs = 0, got_chklist = 0;
    7102             :         uint8_t peer_supports_ecn;
    7103             :         uint8_t peer_supports_prsctp;
    7104             :         uint8_t peer_supports_auth;
    7105             :         uint8_t peer_supports_asconf;
    7106             :         uint8_t peer_supports_asconf_ack;
    7107             :         uint8_t peer_supports_reconfig;
    7108             :         uint8_t peer_supports_nrsack;
    7109             :         uint8_t peer_supports_pktdrop;
    7110             : #ifdef INET
    7111             :         struct sockaddr_in sin;
    7112             : #endif
    7113             : #ifdef INET6
    7114             :         struct sockaddr_in6 sin6;
    7115             : #endif
    7116             : 
    7117             :         /* First get the destination address setup too. */
    7118             : #ifdef INET
    7119             :         memset(&sin, 0, sizeof(sin));
    7120             :         sin.sin_family = AF_INET;
    7121             : #ifdef HAVE_SIN_LEN
    7122             :         sin.sin_len = sizeof(sin);
    7123             : #endif
    7124             :         sin.sin_port = stcb->rport;
    7125             : #endif
    7126             : #ifdef INET6
    7127             :         memset(&sin6, 0, sizeof(sin6));
    7128             :         sin6.sin6_family = AF_INET6;
    7129             : #ifdef HAVE_SIN6_LEN
    7130             :         sin6.sin6_len = sizeof(struct sockaddr_in6);
    7131             : #endif
    7132             :         sin6.sin6_port = stcb->rport;
    7133             : #endif
    7134           0 :         if (altsa) {
    7135           0 :                 sa = altsa;
    7136             :         } else {
    7137           0 :                 sa = src;
    7138             :         }
    7139           0 :         peer_supports_ecn = 0;
    7140           0 :         peer_supports_prsctp = 0;
    7141           0 :         peer_supports_auth = 0;
    7142           0 :         peer_supports_asconf = 0;
    7143           0 :         peer_supports_reconfig = 0;
    7144           0 :         peer_supports_nrsack = 0;
    7145           0 :         peer_supports_pktdrop = 0;
    7146           0 :         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
    7147             :                 /* mark all addresses that we have currently on the list */
    7148           0 :                 net->dest_state |= SCTP_ADDR_NOT_IN_ASSOC;
    7149             :         }
    7150             :         /* does the source address already exist? if so skip it */
    7151           0 :         inp = stcb->sctp_ep;
    7152           0 :         atomic_add_int(&stcb->asoc.refcnt, 1);
    7153           0 :         stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net_tmp, dst, stcb);
    7154           0 :         atomic_add_int(&stcb->asoc.refcnt, -1);
    7155             : 
    7156           0 :         if ((stcb_tmp == NULL && inp == stcb->sctp_ep) || inp == NULL) {
    7157             :                 /* we must add the source address */
    7158             :                 /* no scope set here since we have a tcb already. */
    7159           0 :                 switch (sa->sa_family) {
    7160             : #ifdef INET
    7161             :                 case AF_INET:
    7162             :                         if (stcb->asoc.scope.ipv4_addr_legal) {
    7163             :                                 if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_2)) {
    7164             :                                         return (-1);
    7165             :                                 }
    7166             :                         }
    7167             :                         break;
    7168             : #endif
    7169             : #ifdef INET6
    7170             :                 case AF_INET6:
    7171             :                         if (stcb->asoc.scope.ipv6_addr_legal) {
    7172             :                                 if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_3)) {
    7173             :                                         return (-2);
    7174             :                                 }
    7175             :                         }
    7176             :                         break;
    7177             : #endif
    7178             : #if defined(__Userspace__)
    7179             :                 case AF_CONN:
    7180           0 :                         if (stcb->asoc.scope.conn_addr_legal) {
    7181           0 :                                 if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_3)) {
    7182           0 :                                         return (-2);
    7183             :                                 }
    7184             :                         }
    7185           0 :                         break;
    7186             : #endif
    7187             :                 default:
    7188           0 :                         break;
    7189             :                 }
    7190           0 :         } else {
    7191           0 :                 if (net_tmp != NULL && stcb_tmp == stcb) {
    7192           0 :                         net_tmp->dest_state &= ~SCTP_ADDR_NOT_IN_ASSOC;
    7193           0 :                 } else if (stcb_tmp != stcb) {
    7194             :                         /* It belongs to another association? */
    7195           0 :                         if (stcb_tmp)
    7196           0 :                                 SCTP_TCB_UNLOCK(stcb_tmp);
    7197           0 :                         return (-3);
    7198             :                 }
    7199             :         }
    7200           0 :         if (stcb->asoc.state == 0) {
    7201             :                 /* the assoc was freed? */
    7202           0 :                 return (-4);
    7203             :         }
    7204             :         /* now we must go through each of the params. */
    7205           0 :         phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
    7206           0 :         while (phdr) {
    7207           0 :                 ptype = ntohs(phdr->param_type);
    7208           0 :                 plen = ntohs(phdr->param_length);
    7209             :                 /*
    7210             :                  * SCTP_PRINTF("ptype => %0x, plen => %d\n", (uint32_t)ptype,
    7211             :                  * (int)plen);
    7212             :                  */
    7213           0 :                 if (offset + plen > limit) {
    7214           0 :                         break;
    7215             :                 }
    7216           0 :                 if (plen == 0) {
    7217           0 :                         break;
    7218             :                 }
    7219             : #ifdef INET
    7220             :                 if (ptype == SCTP_IPV4_ADDRESS) {
    7221             :                         if (stcb->asoc.scope.ipv4_addr_legal) {
    7222             :                                 struct sctp_ipv4addr_param *p4, p4_buf;
    7223             : 
    7224             :                                 /* ok get the v4 address and check/add */
    7225             :                                 phdr = sctp_get_next_param(m, offset,
    7226             :                                                            (struct sctp_paramhdr *)&p4_buf,
    7227             :                                                            sizeof(p4_buf));
    7228             :                                 if (plen != sizeof(struct sctp_ipv4addr_param) ||
    7229             :                                     phdr == NULL) {
    7230             :                                         return (-5);
    7231             :                                 }
    7232             :                                 p4 = (struct sctp_ipv4addr_param *)phdr;
    7233             :                                 sin.sin_addr.s_addr = p4->addr;
    7234             :                                 if (IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) {
    7235             :                                         /* Skip multi-cast addresses */
    7236             :                                         goto next_param;
    7237             :                                 }
    7238             :                                 if ((sin.sin_addr.s_addr == INADDR_BROADCAST) ||
    7239             :                                     (sin.sin_addr.s_addr == INADDR_ANY)) {
    7240             :                                         goto next_param;
    7241             :                                 }
    7242             :                                 sa = (struct sockaddr *)&sin;
    7243             :                                 inp = stcb->sctp_ep;
    7244             :                                 atomic_add_int(&stcb->asoc.refcnt, 1);
    7245             :                                 stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net,
    7246             :                                                                         dst, stcb);
    7247             :                                 atomic_add_int(&stcb->asoc.refcnt, -1);
    7248             : 
    7249             :                                 if ((stcb_tmp == NULL && inp == stcb->sctp_ep) ||
    7250             :                                     inp == NULL) {
    7251             :                                         /* we must add the source address */
    7252             :                                         /*
    7253             :                                          * no scope set since we have a tcb
    7254             :                                          * already
    7255             :                                          */
    7256             : 
    7257             :                                         /*
    7258             :                                          * we must validate the state again
    7259             :                                          * here
    7260             :                                          */
    7261             :                                 add_it_now:
    7262             :                                         if (stcb->asoc.state == 0) {
    7263             :                                                 /* the assoc was freed? */
    7264             :                                                 return (-7);
    7265             :                                         }
    7266             :                                         if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_4)) {
    7267             :                                                 return (-8);
    7268             :                                         }
    7269             :                                 } else if (stcb_tmp == stcb) {
    7270             :                                         if (stcb->asoc.state == 0) {
    7271             :                                                 /* the assoc was freed? */
    7272             :                                                 return (-10);
    7273             :                                         }
    7274             :                                         if (net != NULL) {
    7275             :                                                 /* clear flag */
    7276             :                                                 net->dest_state &=
    7277             :                                                         ~SCTP_ADDR_NOT_IN_ASSOC;
    7278             :                                         }
    7279             :                                 } else {
    7280             :                                         /*
    7281             :                                          * strange, address is in another
    7282             :                                          * assoc? straighten out locks.
    7283             :                                          */
    7284             :                                         if (stcb_tmp) {
    7285             :                                                 if (SCTP_GET_STATE(&stcb_tmp->asoc) & SCTP_STATE_COOKIE_WAIT) {
    7286             :                                                         /* in setup state we abort this guy */
    7287             :                                                         sctp_abort_an_association(stcb_tmp->sctp_ep,
    7288             :                                                                                   stcb_tmp, NULL, SCTP_SO_NOT_LOCKED);
    7289             :                                                         goto add_it_now;
    7290             :                                                 }
    7291             :                                                 SCTP_TCB_UNLOCK(stcb_tmp);
    7292             :                                         }
    7293             : 
    7294             :                                         if (stcb->asoc.state == 0) {
    7295             :                                                 /* the assoc was freed? */
    7296             :                                                 return (-12);
    7297             :                                         }
    7298             :                                         return (-13);
    7299             :                                 }
    7300             :                         }
    7301             :                 } else
    7302             : #endif
    7303             : #ifdef INET6
    7304             :                 if (ptype == SCTP_IPV6_ADDRESS) {
    7305             :                         if (stcb->asoc.scope.ipv6_addr_legal) {
    7306             :                                 /* ok get the v6 address and check/add */
    7307             :                                 struct sctp_ipv6addr_param *p6, p6_buf;
    7308             : 
    7309             :                                 phdr = sctp_get_next_param(m, offset,
    7310             :                                                            (struct sctp_paramhdr *)&p6_buf,
    7311             :                                                            sizeof(p6_buf));
    7312             :                                 if (plen != sizeof(struct sctp_ipv6addr_param) ||
    7313             :                                     phdr == NULL) {
    7314             :                                         return (-14);
    7315             :                                 }
    7316             :                                 p6 = (struct sctp_ipv6addr_param *)phdr;
    7317             :                                 memcpy((caddr_t)&sin6.sin6_addr, p6->addr,
    7318             :                                        sizeof(p6->addr));
    7319             :                                 if (IN6_IS_ADDR_MULTICAST(&sin6.sin6_addr)) {
    7320             :                                         /* Skip multi-cast addresses */
    7321             :                                         goto next_param;
    7322             :                                 }
    7323             :                                 if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) {
    7324             :                                         /* Link local make no sense without scope */
    7325             :                                         goto next_param;
    7326             :                                 }
    7327             :                                 sa = (struct sockaddr *)&sin6;
    7328             :                                 inp = stcb->sctp_ep;
    7329             :                                 atomic_add_int(&stcb->asoc.refcnt, 1);
    7330             :                                 stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net,
    7331             :                                                                         dst, stcb);
    7332             :                                 atomic_add_int(&stcb->asoc.refcnt, -1);
    7333             :                                 if (stcb_tmp == NULL &&
    7334             :                                     (inp == stcb->sctp_ep || inp == NULL)) {
    7335             :                                         /*
    7336             :                                          * we must validate the state again
    7337             :                                          * here
    7338             :                                          */
    7339             :                                 add_it_now6:
    7340             :                                         if (stcb->asoc.state == 0) {
    7341             :                                                 /* the assoc was freed? */
    7342             :                                                 return (-16);
    7343             :                                         }
    7344             :                                         /*
    7345             :                                          * we must add the address, no scope
    7346             :                                          * set
    7347             :                                          */
    7348             :                                         if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_5)) {
    7349             :                                                 return (-17);
    7350             :                                         }
    7351             :                                 } else if (stcb_tmp == stcb) {
    7352             :                                         /*
    7353             :                                          * we must validate the state again
    7354             :                                          * here
    7355             :                                          */
    7356             :                                         if (stcb->asoc.state == 0) {
    7357             :                                                 /* the assoc was freed? */
    7358             :                                                 return (-19);
    7359             :                                         }
    7360             :                                         if (net != NULL) {
    7361             :                                                 /* clear flag */
    7362             :                                                 net->dest_state &=
    7363             :                                                         ~SCTP_ADDR_NOT_IN_ASSOC;
    7364             :                                         }
    7365             :                                 } else {
    7366             :                                         /*
    7367             :                                          * strange, address is in another
    7368             :                                          * assoc? straighten out locks.
    7369             :                                          */
    7370             :                                         if (stcb_tmp)
    7371             :                                                 if (SCTP_GET_STATE(&stcb_tmp->asoc) & SCTP_STATE_COOKIE_WAIT) {
    7372             :                                                         /* in setup state we abort this guy */
    7373             :                                                         sctp_abort_an_association(stcb_tmp->sctp_ep,
    7374             :                                                                                   stcb_tmp, NULL, SCTP_SO_NOT_LOCKED);
    7375             :                                                         goto add_it_now6;
    7376             :                                                 }
    7377             :                                         SCTP_TCB_UNLOCK(stcb_tmp);
    7378             : 
    7379             :                                         if (stcb->asoc.state == 0) {
    7380             :                                                 /* the assoc was freed? */
    7381             :                                                 return (-21);
    7382             :                                         }
    7383             :                                         return (-22);
    7384             :                                 }
    7385             :                         }
    7386             :                 } else
    7387             : #endif
    7388           0 :                 if (ptype == SCTP_ECN_CAPABLE) {
    7389           0 :                         peer_supports_ecn = 1;
    7390           0 :                 } else if (ptype == SCTP_ULP_ADAPTATION) {
    7391           0 :                         if (stcb->asoc.state != SCTP_STATE_OPEN) {
    7392             :                                 struct sctp_adaptation_layer_indication ai, *aip;
    7393             : 
    7394           0 :                                 phdr = sctp_get_next_param(m, offset,
    7395             :                                                            (struct sctp_paramhdr *)&ai, sizeof(ai));
    7396           0 :                                 aip = (struct sctp_adaptation_layer_indication *)phdr;
    7397           0 :                                 if (aip) {
    7398           0 :                                         stcb->asoc.peers_adaptation = ntohl(aip->indication);
    7399           0 :                                         stcb->asoc.adaptation_needed = 1;
    7400             :                                 }
    7401             :                         }
    7402           0 :                 } else if (ptype == SCTP_SET_PRIM_ADDR) {
    7403             :                         struct sctp_asconf_addr_param lstore, *fee;
    7404             :                         int lptype;
    7405           0 :                         struct sockaddr *lsa = NULL;
    7406             : #ifdef INET
    7407             :                         struct sctp_asconf_addrv4_param *fii;
    7408             : #endif
    7409             : 
    7410           0 :                         if (stcb->asoc.asconf_supported == 0) {
    7411           0 :                                 return (-100);
    7412             :                         }
    7413           0 :                         if (plen > sizeof(lstore)) {
    7414           0 :                                 return (-23);
    7415             :                         }
    7416           0 :                         phdr = sctp_get_next_param(m, offset,
    7417             :                                                    (struct sctp_paramhdr *)&lstore,
    7418             :                                                    min(plen,sizeof(lstore)));
    7419           0 :                         if (phdr == NULL) {
    7420           0 :                                 return (-24);
    7421             :                         }
    7422           0 :                         fee = (struct sctp_asconf_addr_param *)phdr;
    7423           0 :                         lptype = ntohs(fee->addrp.ph.param_type);
    7424             :                         switch (lptype) {
    7425             : #ifdef INET
    7426             :                         case SCTP_IPV4_ADDRESS:
    7427             :                                 if (plen !=
    7428             :                                     sizeof(struct sctp_asconf_addrv4_param)) {
    7429             :                                         SCTP_PRINTF("Sizeof setprim in init/init ack not %d but %d - ignored\n",
    7430             :                                                     (int)sizeof(struct sctp_asconf_addrv4_param),
    7431             :                                                     plen);
    7432             :                                 } else {
    7433             :                                         fii = (struct sctp_asconf_addrv4_param *)fee;
    7434             :                                         sin.sin_addr.s_addr = fii->addrp.addr;
    7435             :                                         lsa = (struct sockaddr *)&sin;
    7436             :                                 }
    7437             :                                 break;
    7438             : #endif
    7439             : #ifdef INET6
    7440             :                         case SCTP_IPV6_ADDRESS:
    7441             :                                 if (plen !=
    7442             :                                     sizeof(struct sctp_asconf_addr_param)) {
    7443             :                                         SCTP_PRINTF("Sizeof setprim (v6) in init/init ack not %d but %d - ignored\n",
    7444             :                                                     (int)sizeof(struct sctp_asconf_addr_param),
    7445             :                                                     plen);
    7446             :                                 } else {
    7447             :                                         memcpy(sin6.sin6_addr.s6_addr,
    7448             :                                                fee->addrp.addr,
    7449             :                                                sizeof(fee->addrp.addr));
    7450             :                                         lsa = (struct sockaddr *)&sin6;
    7451             :                                 }
    7452             :                                 break;
    7453             : #endif
    7454             :                         default:
    7455           0 :                                 break;
    7456             :                         }
    7457           0 :                         if (lsa) {
    7458           0 :                                 (void)sctp_set_primary_addr(stcb, sa, NULL);
    7459             :                         }
    7460           0 :                 } else if (ptype == SCTP_HAS_NAT_SUPPORT) {
    7461           0 :                         stcb->asoc.peer_supports_nat = 1;
    7462           0 :                 } else if (ptype == SCTP_PRSCTP_SUPPORTED) {
    7463             :                         /* Peer supports pr-sctp */
    7464           0 :                         peer_supports_prsctp = 1;
    7465           0 :                 } else if (ptype == SCTP_SUPPORTED_CHUNK_EXT) {
    7466             :                         /* A supported extension chunk */
    7467             :                         struct sctp_supported_chunk_types_param *pr_supported;
    7468             :                         uint8_t local_store[SCTP_PARAM_BUFFER_SIZE];
    7469             :                         int num_ent, i;
    7470             : 
    7471           0 :                         phdr = sctp_get_next_param(m, offset,
    7472             :                                                    (struct sctp_paramhdr *)&local_store, min(sizeof(local_store),plen));
    7473           0 :                         if (phdr == NULL) {
    7474           0 :                                 return (-25);
    7475             :                         }
    7476           0 :                         pr_supported = (struct sctp_supported_chunk_types_param *)phdr;
    7477           0 :                         num_ent = plen - sizeof(struct sctp_paramhdr);
    7478           0 :                         for (i = 0; i < num_ent; i++) {
    7479           0 :                                 switch (pr_supported->chunk_types[i]) {
    7480             :                                 case SCTP_ASCONF:
    7481           0 :                                         peer_supports_asconf = 1;
    7482           0 :                                         break;
    7483             :                                 case SCTP_ASCONF_ACK:
    7484           0 :                                         peer_supports_asconf_ack = 1;
    7485           0 :                                         break;
    7486             :                                 case SCTP_FORWARD_CUM_TSN:
    7487           0 :                                         peer_supports_prsctp = 1;
    7488           0 :                                         break;
    7489             :                                 case SCTP_PACKET_DROPPED:
    7490           0 :                                         peer_supports_pktdrop = 1;
    7491           0 :                                         break;
    7492             :                                 case SCTP_NR_SELECTIVE_ACK:
    7493           0 :                                         peer_supports_nrsack = 1;
    7494           0 :                                         break;
    7495             :                                 case SCTP_STREAM_RESET:
    7496           0 :                                         peer_supports_reconfig = 1;
    7497           0 :                                         break;
    7498             :                                 case SCTP_AUTHENTICATION:
    7499           0 :                                         peer_supports_auth = 1;
    7500           0 :                                         break;
    7501             :                                 default:
    7502             :                                         /* one I have not learned yet */
    7503           0 :                                         break;
    7504             : 
    7505             :                                 }
    7506             :                         }
    7507           0 :                 } else if (ptype == SCTP_RANDOM) {
    7508           0 :                         if (plen > sizeof(random_store))
    7509           0 :                                 break;
    7510           0 :                         if (got_random) {
    7511             :                                 /* already processed a RANDOM */
    7512           0 :                                 goto next_param;
    7513             :                         }
    7514           0 :                         phdr = sctp_get_next_param(m, offset,
    7515             :                                                    (struct sctp_paramhdr *)random_store,
    7516             :                                                    min(sizeof(random_store),plen));
    7517           0 :                         if (phdr == NULL)
    7518           0 :                                 return (-26);
    7519           0 :                         p_random = (struct sctp_auth_random *)phdr;
    7520           0 :                         random_len = plen - sizeof(*p_random);
    7521             :                         /* enforce the random length */
    7522           0 :                         if (random_len != SCTP_AUTH_RANDOM_SIZE_REQUIRED) {
    7523           0 :                                 SCTPDBG(SCTP_DEBUG_AUTH1, "SCTP: invalid RANDOM len\n");
    7524           0 :                                 return (-27);
    7525             :                         }
    7526           0 :                         got_random = 1;
    7527           0 :                 } else if (ptype == SCTP_HMAC_LIST) {
    7528             :                         uint16_t num_hmacs;
    7529             :                         uint16_t i;
    7530             : 
    7531           0 :                         if (plen > sizeof(hmacs_store))
    7532           0 :                                 break;
    7533           0 :                         if (got_hmacs) {
    7534             :                                 /* already processed a HMAC list */
    7535           0 :                                 goto next_param;
    7536             :                         }
    7537           0 :                         phdr = sctp_get_next_param(m, offset,
    7538             :                                                    (struct sctp_paramhdr *)hmacs_store,
    7539             :                                                    min(plen,sizeof(hmacs_store)));
    7540           0 :                         if (phdr == NULL)
    7541           0 :                                 return (-28);
    7542           0 :                         hmacs = (struct sctp_auth_hmac_algo *)phdr;
    7543           0 :                         hmacs_len = plen - sizeof(*hmacs);
    7544           0 :                         num_hmacs = hmacs_len / sizeof(hmacs->hmac_ids[0]);
    7545             :                         /* validate the hmac list */
    7546           0 :                         if (sctp_verify_hmac_param(hmacs, num_hmacs)) {
    7547           0 :                                 return (-29);
    7548             :                         }
    7549           0 :                         if (stcb->asoc.peer_hmacs != NULL)
    7550           0 :                                 sctp_free_hmaclist(stcb->asoc.peer_hmacs);
    7551           0 :                         stcb->asoc.peer_hmacs = sctp_alloc_hmaclist(num_hmacs);
    7552           0 :                         if (stcb->asoc.peer_hmacs != NULL) {
    7553           0 :                                 for (i = 0; i < num_hmacs; i++) {
    7554           0 :                                         (void)sctp_auth_add_hmacid(stcb->asoc.peer_hmacs,
    7555           0 :                                                                    ntohs(hmacs->hmac_ids[i]));
    7556             :                                 }
    7557             :                         }
    7558           0 :                         got_hmacs = 1;
    7559           0 :                 } else if (ptype == SCTP_CHUNK_LIST) {
    7560             :                         int i;
    7561             : 
    7562           0 :                         if (plen > sizeof(chunks_store))
    7563           0 :                                 break;
    7564           0 :                         if (got_chklist) {
    7565             :                                 /* already processed a Chunks list */
    7566           0 :                                 goto next_param;
    7567             :                         }
    7568           0 :                         phdr = sctp_get_next_param(m, offset,
    7569             :                                                    (struct sctp_paramhdr *)chunks_store,
    7570             :                                                    min(plen,sizeof(chunks_store)));
    7571           0 :                         if (phdr == NULL)
    7572           0 :                                 return (-30);
    7573           0 :                         chunks = (struct sctp_auth_chunk_list *)phdr;
    7574           0 :                         num_chunks = plen - sizeof(*chunks);
    7575           0 :                         if (stcb->asoc.peer_auth_chunks != NULL)
    7576           0 :                                 sctp_clear_chunklist(stcb->asoc.peer_auth_chunks);
    7577             :                         else
    7578           0 :                                 stcb->asoc.peer_auth_chunks = sctp_alloc_chunklist();
    7579           0 :                         for (i = 0; i < num_chunks; i++) {
    7580           0 :                                 (void)sctp_auth_add_chunk(chunks->chunk_types[i],
    7581             :                                                           stcb->asoc.peer_auth_chunks);
    7582             :                                 /* record asconf/asconf-ack if listed */
    7583           0 :                                 if (chunks->chunk_types[i] == SCTP_ASCONF)
    7584           0 :                                         saw_asconf = 1;
    7585           0 :                                 if (chunks->chunk_types[i] == SCTP_ASCONF_ACK)
    7586           0 :                                         saw_asconf_ack = 1;
    7587             : 
    7588             :                         }
    7589           0 :                         got_chklist = 1;
    7590           0 :                 } else if ((ptype == SCTP_HEARTBEAT_INFO) ||
    7591           0 :                            (ptype == SCTP_STATE_COOKIE) ||
    7592           0 :                            (ptype == SCTP_UNRECOG_PARAM) ||
    7593           0 :                            (ptype == SCTP_COOKIE_PRESERVE) ||
    7594           0 :                            (ptype == SCTP_SUPPORTED_ADDRTYPE) ||
    7595           0 :                            (ptype == SCTP_ADD_IP_ADDRESS) ||
    7596           0 :                            (ptype == SCTP_DEL_IP_ADDRESS) ||
    7597           0 :                            (ptype == SCTP_ERROR_CAUSE_IND) ||
    7598             :                            (ptype == SCTP_SUCCESS_REPORT)) {
    7599             :                         /* don't care */ ;
    7600             :                 } else {
    7601           0 :                         if ((ptype & 0x8000) == 0x0000) {
    7602             :                                 /*
    7603             :                                  * must stop processing the rest of the
    7604             :                                  * param's. Any report bits were handled
    7605             :                                  * with the call to
    7606             :                                  * sctp_arethere_unrecognized_parameters()
    7607             :                                  * when the INIT or INIT-ACK was first seen.
    7608             :                                  */
    7609           0 :                                 break;
    7610             :                         }
    7611             :                 }
    7612             : 
    7613             :         next_param:
    7614           0 :                 offset += SCTP_SIZE32(plen);
    7615           0 :                 if (offset >= limit) {
    7616           0 :                         break;
    7617             :                 }
    7618           0 :                 phdr = sctp_get_next_param(m, offset, &parm_buf,
    7619             :                                            sizeof(parm_buf));
    7620             :         }
    7621             :         /* Now check to see if we need to purge any addresses */
    7622           0 :         TAILQ_FOREACH_SAFE(net, &stcb->asoc.nets, sctp_next, nnet) {
    7623           0 :                 if ((net->dest_state & SCTP_ADDR_NOT_IN_ASSOC) ==
    7624             :                     SCTP_ADDR_NOT_IN_ASSOC) {
    7625             :                         /* This address has been removed from the asoc */
    7626             :                         /* remove and free it */
    7627           0 :                         stcb->asoc.numnets--;
    7628           0 :                         TAILQ_REMOVE(&stcb->asoc.nets, net, sctp_next);
    7629           0 :                         sctp_free_remote_addr(net);
    7630           0 :                         if (net == stcb->asoc.primary_destination) {
    7631           0 :                                 stcb->asoc.primary_destination = NULL;
    7632           0 :                                 sctp_select_primary_destination(stcb);
    7633             :                         }
    7634             :                 }
    7635             :         }
    7636           0 :         if ((stcb->asoc.ecn_supported == 1) &&
    7637             :             (peer_supports_ecn == 0)) {
    7638           0 :                 stcb->asoc.ecn_supported = 0;
    7639             :         }
    7640           0 :         if ((stcb->asoc.prsctp_supported == 1) &&
    7641             :             (peer_supports_prsctp == 0)) {
    7642           0 :                 stcb->asoc.prsctp_supported = 0;
    7643             :         }
    7644           0 :         if ((stcb->asoc.auth_supported == 1) &&
    7645           0 :             ((peer_supports_auth == 0) ||
    7646           0 :              (got_random == 0) || (got_hmacs == 0))) {
    7647           0 :                 stcb->asoc.auth_supported = 0;
    7648             :         }
    7649           0 :         if ((stcb->asoc.asconf_supported == 1) &&
    7650           0 :             ((peer_supports_asconf == 0) || (peer_supports_asconf_ack == 0) ||
    7651           0 :              (stcb->asoc.auth_supported == 0) ||
    7652           0 :              (saw_asconf == 0) || (saw_asconf_ack == 0))) {
    7653           0 :                 stcb->asoc.asconf_supported = 0;
    7654             :         }
    7655           0 :         if ((stcb->asoc.reconfig_supported == 1) &&
    7656             :             (peer_supports_reconfig == 0)) {
    7657           0 :                 stcb->asoc.reconfig_supported = 0;
    7658             :         }
    7659           0 :         if ((stcb->asoc.nrsack_supported == 1) &&
    7660             :             (peer_supports_nrsack == 0)) {
    7661           0 :                 stcb->asoc.nrsack_supported = 0;
    7662             :         }
    7663           0 :         if ((stcb->asoc.pktdrop_supported == 1) &&
    7664             :             (peer_supports_pktdrop == 0)){
    7665           0 :                 stcb->asoc.pktdrop_supported = 0;
    7666             :         }
    7667             :         /* validate authentication required parameters */
    7668           0 :         if ((peer_supports_auth == 0) && (got_chklist == 1)) {
    7669             :                 /* peer does not support auth but sent a chunks list? */
    7670           0 :                 return (-31);
    7671             :         }
    7672           0 :         if ((peer_supports_asconf == 1) && (peer_supports_auth == 0)) {
    7673             :                 /* peer supports asconf but not auth? */
    7674           0 :                 return (-32);
    7675           0 :         } else if ((peer_supports_asconf == 1) &&
    7676           0 :                    (peer_supports_auth == 1) &&
    7677           0 :                    ((saw_asconf == 0) || (saw_asconf_ack == 0))) {
    7678           0 :                 return (-33);
    7679             :         }
    7680             :         /* concatenate the full random key */
    7681           0 :         keylen = sizeof(*p_random) + random_len + sizeof(*hmacs) + hmacs_len;
    7682           0 :         if (chunks != NULL) {
    7683           0 :                 keylen += sizeof(*chunks) + num_chunks;
    7684             :         }
    7685           0 :         new_key = sctp_alloc_key(keylen);
    7686           0 :         if (new_key != NULL) {
    7687             :                 /* copy in the RANDOM */
    7688           0 :                 if (p_random != NULL) {
    7689           0 :                         keylen = sizeof(*p_random) + random_len;
    7690           0 :                         bcopy(p_random, new_key->key, keylen);
    7691             :                 }
    7692             :                 /* append in the AUTH chunks */
    7693           0 :                 if (chunks != NULL) {
    7694           0 :                         bcopy(chunks, new_key->key + keylen,
    7695             :                               sizeof(*chunks) + num_chunks);
    7696           0 :                         keylen += sizeof(*chunks) + num_chunks;
    7697             :                 }
    7698             :                 /* append in the HMACs */
    7699           0 :                 if (hmacs != NULL) {
    7700           0 :                         bcopy(hmacs, new_key->key + keylen,
    7701             :                               sizeof(*hmacs) + hmacs_len);
    7702             :                 }
    7703             :         } else {
    7704             :                 /* failed to get memory for the key */
    7705           0 :                 return (-34);
    7706             :         }
    7707           0 :         if (stcb->asoc.authinfo.peer_random != NULL)
    7708           0 :                 sctp_free_key(stcb->asoc.authinfo.peer_random);
    7709           0 :         stcb->asoc.authinfo.peer_random = new_key;
    7710           0 :         sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.assoc_keyid);
    7711           0 :         sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.recv_keyid);
    7712             : 
    7713           0 :         return (0);
    7714             : }
    7715             : 
    7716             : int
    7717           0 : sctp_set_primary_addr(struct sctp_tcb *stcb, struct sockaddr *sa,
    7718             :                       struct sctp_nets *net)
    7719             : {
    7720             :         /* make sure the requested primary address exists in the assoc */
    7721           0 :         if (net == NULL && sa)
    7722           0 :                 net = sctp_findnet(stcb, sa);
    7723             : 
    7724           0 :         if (net == NULL) {
    7725             :                 /* didn't find the requested primary address! */
    7726           0 :                 return (-1);
    7727             :         } else {
    7728             :                 /* set the primary address */
    7729           0 :                 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
    7730             :                         /* Must be confirmed, so queue to set */
    7731           0 :                         net->dest_state |= SCTP_ADDR_REQ_PRIMARY;
    7732           0 :                         return (0);
    7733             :                 }
    7734           0 :                 stcb->asoc.primary_destination = net;
    7735           0 :                 if (!(net->dest_state & SCTP_ADDR_PF) && (stcb->asoc.alternate)) {
    7736           0 :                         sctp_free_remote_addr(stcb->asoc.alternate);
    7737           0 :                         stcb->asoc.alternate = NULL;
    7738             :                 }
    7739           0 :                 net = TAILQ_FIRST(&stcb->asoc.nets);
    7740           0 :                 if (net != stcb->asoc.primary_destination) {
    7741             :                         /* first one on the list is NOT the primary
    7742             :                          * sctp_cmpaddr() is much more efficient if
    7743             :                          * the primary is the first on the list, make it
    7744             :                          * so.
    7745             :                          */
    7746           0 :                         TAILQ_REMOVE(&stcb->asoc.nets, stcb->asoc.primary_destination, sctp_next);
    7747           0 :                         TAILQ_INSERT_HEAD(&stcb->asoc.nets, stcb->asoc.primary_destination, sctp_next);
    7748             :                 }
    7749           0 :                 return (0);
    7750             :         }
    7751             : }
    7752             : 
    7753             : int
    7754           0 : sctp_is_vtag_good(uint32_t tag, uint16_t lport, uint16_t rport, struct timeval *now)
    7755             : {
    7756             :         /*
    7757             :          * This function serves two purposes. It will see if a TAG can be
    7758             :          * re-used and return 1 for yes it is ok and 0 for don't use that
    7759             :          * tag. A secondary function it will do is purge out old tags that
    7760             :          * can be removed.
    7761             :          */
    7762             :         struct sctpvtaghead *chain;
    7763             :         struct sctp_tagblock *twait_block;
    7764             :         struct sctpasochead *head;
    7765             :         struct sctp_tcb *stcb;
    7766             :         int i;
    7767             : 
    7768           0 :         SCTP_INP_INFO_RLOCK();
    7769           0 :         head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(tag,
    7770             :                                                                 SCTP_BASE_INFO(hashasocmark))];
    7771           0 :         LIST_FOREACH(stcb, head, sctp_asocs) {
    7772             :                 /* We choose not to lock anything here. TCB's can't be
    7773             :                  * removed since we have the read lock, so they can't
    7774             :                  * be freed on us, same thing for the INP. I may
    7775             :                  * be wrong with this assumption, but we will go
    7776             :                  * with it for now :-)
    7777             :                  */
    7778           0 :                 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
    7779           0 :                         continue;
    7780             :                 }
    7781           0 :                 if (stcb->asoc.my_vtag == tag) {
    7782             :                         /* candidate */
    7783           0 :                         if (stcb->rport != rport) {
    7784           0 :                                 continue;
    7785             :                         }
    7786           0 :                         if (stcb->sctp_ep->sctp_lport != lport) {
    7787           0 :                                 continue;
    7788             :                         }
    7789             :                         /* Its a used tag set */
    7790           0 :                         SCTP_INP_INFO_RUNLOCK();
    7791           0 :                         return (0);
    7792             :                 }
    7793             :         }
    7794           0 :         chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
    7795             :         /* Now what about timed wait ? */
    7796           0 :         LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
    7797             :                 /*
    7798             :                  * Block(s) are present, lets see if we have this tag in the
    7799             :                  * list
    7800             :                  */
    7801           0 :                 for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
    7802           0 :                         if (twait_block->vtag_block[i].v_tag == 0) {
    7803             :                                 /* not used */
    7804           0 :                                 continue;
    7805           0 :                         } else if ((long)twait_block->vtag_block[i].tv_sec_at_expire  <
    7806           0 :                                    now->tv_sec) {
    7807             :                                 /* Audit expires this guy */
    7808           0 :                                 twait_block->vtag_block[i].tv_sec_at_expire = 0;
    7809           0 :                                 twait_block->vtag_block[i].v_tag = 0;
    7810           0 :                                 twait_block->vtag_block[i].lport = 0;
    7811           0 :                                 twait_block->vtag_block[i].rport = 0;
    7812           0 :                         } else if ((twait_block->vtag_block[i].v_tag == tag) &&
    7813           0 :                                    (twait_block->vtag_block[i].lport == lport) &&
    7814           0 :                                    (twait_block->vtag_block[i].rport == rport)) {
    7815             :                                 /* Bad tag, sorry :< */
    7816           0 :                                 SCTP_INP_INFO_RUNLOCK();
    7817           0 :                                 return (0);
    7818             :                         }
    7819             :                 }
    7820             :         }
    7821           0 :         SCTP_INP_INFO_RUNLOCK();
    7822           0 :         return (1);
    7823             : }
    7824             : 
    7825             : static void
    7826           0 : sctp_drain_mbufs(struct sctp_tcb *stcb)
    7827             : {
    7828             :         /*
    7829             :          * We must hunt this association for MBUF's past the cumack (i.e.
    7830             :          * out of order data that we can renege on).
    7831             :          */
    7832             :         struct sctp_association *asoc;
    7833             :         struct sctp_tmit_chunk *chk, *nchk;
    7834             :         uint32_t cumulative_tsn_p1;
    7835             :         struct sctp_queued_to_read *ctl, *nctl;
    7836             :         int cnt, strmat;
    7837             :         uint32_t gap, i;
    7838           0 :         int fnd = 0;
    7839             : 
    7840             :         /* We look for anything larger than the cum-ack + 1 */
    7841             : 
    7842           0 :         asoc = &stcb->asoc;
    7843           0 :         if (asoc->cumulative_tsn == asoc->highest_tsn_inside_map) {
    7844             :                 /* none we can reneg on. */
    7845           0 :                 return;
    7846             :         }
    7847           0 :         SCTP_STAT_INCR(sctps_protocol_drains_done);
    7848           0 :         cumulative_tsn_p1 = asoc->cumulative_tsn + 1;
    7849           0 :         cnt = 0;
    7850             :         /* First look in the re-assembly queue */
    7851           0 :         TAILQ_FOREACH_SAFE(chk, &asoc->reasmqueue, sctp_next, nchk) {
    7852           0 :                 if (SCTP_TSN_GT(chk->rec.data.TSN_seq, cumulative_tsn_p1)) {
    7853             :                         /* Yep it is above cum-ack */
    7854           0 :                         cnt++;
    7855           0 :                         SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.TSN_seq, asoc->mapping_array_base_tsn);
    7856           0 :                         asoc->size_on_reasm_queue = sctp_sbspace_sub(asoc->size_on_reasm_queue, chk->send_size);
    7857           0 :                         sctp_ucount_decr(asoc->cnt_on_reasm_queue);
    7858           0 :                         SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
    7859           0 :                         TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next);
    7860           0 :                         if (chk->data) {
    7861           0 :                                 sctp_m_freem(chk->data);
    7862           0 :                                 chk->data = NULL;
    7863             :                         }
    7864           0 :                         sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
    7865             :                 }
    7866             :         }
    7867             :         /* Ok that was fun, now we will drain all the inbound streams? */
    7868           0 :         for (strmat = 0; strmat < asoc->streamincnt; strmat++) {
    7869           0 :                 TAILQ_FOREACH_SAFE(ctl, &asoc->strmin[strmat].inqueue, next, nctl) {
    7870           0 :                         if (SCTP_TSN_GT(ctl->sinfo_tsn, cumulative_tsn_p1)) {
    7871             :                                 /* Yep it is above cum-ack */
    7872           0 :                                 cnt++;
    7873           0 :                                 SCTP_CALC_TSN_TO_GAP(gap, ctl->sinfo_tsn, asoc->mapping_array_base_tsn);
    7874           0 :                                 asoc->size_on_all_streams = sctp_sbspace_sub(asoc->size_on_all_streams, ctl->length);
    7875           0 :                                 sctp_ucount_decr(asoc->cnt_on_all_streams);
    7876           0 :                                 SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
    7877           0 :                                 TAILQ_REMOVE(&asoc->strmin[strmat].inqueue, ctl, next);
    7878           0 :                                 if (ctl->data) {
    7879           0 :                                         sctp_m_freem(ctl->data);
    7880           0 :                                         ctl->data = NULL;
    7881             :                                 }
    7882           0 :                                 sctp_free_remote_addr(ctl->whoFrom);
    7883           0 :                                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), ctl);
    7884           0 :                                 SCTP_DECR_READQ_COUNT();
    7885             :                         }
    7886             :                 }
    7887             :         }
    7888           0 :         if (cnt) {
    7889             :                 /* We must back down to see what the new highest is */
    7890           0 :                 for (i = asoc->highest_tsn_inside_map; SCTP_TSN_GE(i, asoc->mapping_array_base_tsn); i--) {
    7891           0 :                         SCTP_CALC_TSN_TO_GAP(gap, i, asoc->mapping_array_base_tsn);
    7892           0 :                         if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
    7893           0 :                                 asoc->highest_tsn_inside_map = i;
    7894           0 :                                 fnd = 1;
    7895           0 :                                 break;
    7896             :                         }
    7897             :                 }
    7898           0 :                 if (!fnd) {
    7899           0 :                         asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1;
    7900             :                 }
    7901             : 
    7902             :                 /*
    7903             :                  * Question, should we go through the delivery queue? The only
    7904             :                  * reason things are on here is the app not reading OR a p-d-api up.
    7905             :                  * An attacker COULD send enough in to initiate the PD-API and then
    7906             :                  * send a bunch of stuff to other streams... these would wind up on
    7907             :                  * the delivery queue.. and then we would not get to them. But in
    7908             :                  * order to do this I then have to back-track and un-deliver
    7909             :                  * sequence numbers in streams.. el-yucko. I think for now we will
    7910             :                  * NOT look at the delivery queue and leave it to be something to
    7911             :                  * consider later. An alternative would be to abort the P-D-API with
    7912             :                  * a notification and then deliver the data.... Or another method
    7913             :                  * might be to keep track of how many times the situation occurs and
    7914             :                  * if we see a possible attack underway just abort the association.
    7915             :                  */
    7916             : #ifdef SCTP_DEBUG
    7917           0 :                 SCTPDBG(SCTP_DEBUG_PCB1, "Freed %d chunks from reneg harvest\n", cnt);
    7918             : #endif
    7919             :                 /*
    7920             :                  * Now do we need to find a new
    7921             :                  * asoc->highest_tsn_inside_map?
    7922             :                  */
    7923           0 :                 asoc->last_revoke_count = cnt;
    7924           0 :                 (void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
    7925             :                 /*sa_ignore NO_NULL_CHK*/
    7926           0 :                 sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
    7927           0 :                 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_DRAIN, SCTP_SO_NOT_LOCKED);
    7928             :         }
    7929             :         /*
    7930             :          * Another issue, in un-setting the TSN's in the mapping array we
    7931             :          * DID NOT adjust the highest_tsn marker.  This will cause one of two
    7932             :          * things to occur. It may cause us to do extra work in checking for
    7933             :          * our mapping array movement. More importantly it may cause us to
    7934             :          * SACK every datagram. This may not be a bad thing though since we
    7935             :          * will recover once we get our cum-ack above and all this stuff we
    7936             :          * dumped recovered.
    7937             :          */
    7938             : }
    7939             : 
    7940             : void
    7941           0 : sctp_drain()
    7942             : {
    7943             :         /*
    7944             :          * We must walk the PCB lists for ALL associations here. The system
    7945             :          * is LOW on MBUF's and needs help. This is where reneging will
    7946             :          * occur. We really hope this does NOT happen!
    7947             :          */
    7948             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
    7949             :         VNET_ITERATOR_DECL(vnet_iter);
    7950             : #else
    7951             :         struct sctp_inpcb *inp;
    7952             :         struct sctp_tcb *stcb;
    7953             : 
    7954           0 :         SCTP_STAT_INCR(sctps_protocol_drain_calls);
    7955           0 :         if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
    7956           0 :                 return;
    7957             :         }
    7958             : #endif
    7959             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
    7960             :         VNET_LIST_RLOCK_NOSLEEP();
    7961             :         VNET_FOREACH(vnet_iter) {
    7962             :                 CURVNET_SET(vnet_iter);
    7963             :                 struct sctp_inpcb *inp;
    7964             :                 struct sctp_tcb *stcb;
    7965             : #endif
    7966             : 
    7967             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
    7968             :                 SCTP_STAT_INCR(sctps_protocol_drain_calls);
    7969             :                 if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
    7970             : #ifdef VIMAGE
    7971             :                         continue;
    7972             : #else
    7973             :                         return;
    7974             : #endif
    7975             :                 }
    7976             : #endif
    7977           0 :                 SCTP_INP_INFO_RLOCK();
    7978           0 :                 LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
    7979             :                         /* For each endpoint */
    7980           0 :                         SCTP_INP_RLOCK(inp);
    7981           0 :                         LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
    7982             :                                 /* For each association */
    7983           0 :                                 SCTP_TCB_LOCK(stcb);
    7984           0 :                                 sctp_drain_mbufs(stcb);
    7985           0 :                                 SCTP_TCB_UNLOCK(stcb);
    7986             :                         }
    7987           0 :                         SCTP_INP_RUNLOCK(inp);
    7988             :                 }
    7989           0 :                 SCTP_INP_INFO_RUNLOCK();
    7990             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
    7991             :                 CURVNET_RESTORE();
    7992             :         }
    7993             :         VNET_LIST_RUNLOCK_NOSLEEP();
    7994             : #endif
    7995             : }
    7996             : 
    7997             : /*
    7998             :  * start a new iterator
    7999             :  * iterates through all endpoints and associations based on the pcb_state
    8000             :  * flags and asoc_state.  "af" (mandatory) is executed for all matching
    8001             :  * assocs and "ef" (optional) is executed when the iterator completes.
    8002             :  * "inpf" (optional) is executed for each new endpoint as it is being
    8003             :  * iterated through. inpe (optional) is called when the inp completes
    8004             :  * its way through all the stcbs.
    8005             :  */
    8006             : int
    8007           0 : sctp_initiate_iterator(inp_func inpf,
    8008             :                        asoc_func af,
    8009             :                        inp_func inpe,
    8010             :                        uint32_t pcb_state,
    8011             :                        uint32_t pcb_features,
    8012             :                        uint32_t asoc_state,
    8013             :                        void *argp,
    8014             :                        uint32_t argi,
    8015             :                        end_func ef,
    8016             :                        struct sctp_inpcb *s_inp,
    8017             :                        uint8_t chunk_output_off)
    8018             : {
    8019           0 :         struct sctp_iterator *it = NULL;
    8020             : 
    8021           0 :         if (af == NULL) {
    8022           0 :                 return (-1);
    8023             :         }
    8024           0 :         SCTP_MALLOC(it, struct sctp_iterator *, sizeof(struct sctp_iterator),
    8025             :                     SCTP_M_ITER);
    8026           0 :         if (it == NULL) {
    8027             :                 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOMEM);
    8028           0 :                 return (ENOMEM);
    8029             :         }
    8030           0 :         memset(it, 0, sizeof(*it));
    8031           0 :         it->function_assoc = af;
    8032           0 :         it->function_inp = inpf;
    8033           0 :         if (inpf)
    8034           0 :                 it->done_current_ep = 0;
    8035             :         else
    8036           0 :                 it->done_current_ep = 1;
    8037           0 :         it->function_atend = ef;
    8038           0 :         it->pointer = argp;
    8039           0 :         it->val = argi;
    8040           0 :         it->pcb_flags = pcb_state;
    8041           0 :         it->pcb_features = pcb_features;
    8042           0 :         it->asoc_state = asoc_state;
    8043           0 :         it->function_inp_end = inpe;
    8044           0 :         it->no_chunk_output = chunk_output_off;
    8045             : #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
    8046             :         it->vn = curvnet;
    8047             : #endif
    8048           0 :         if (s_inp) {
    8049             :                 /* Assume lock is held here */
    8050           0 :                 it->inp = s_inp;
    8051           0 :                 SCTP_INP_INCR_REF(it->inp);
    8052           0 :                 it->iterator_flags = SCTP_ITERATOR_DO_SINGLE_INP;
    8053             :         } else {
    8054           0 :                 SCTP_INP_INFO_RLOCK();
    8055           0 :                 it->inp = LIST_FIRST(&SCTP_BASE_INFO(listhead));
    8056           0 :                 if (it->inp) {
    8057           0 :                         SCTP_INP_INCR_REF(it->inp);
    8058             :                 }
    8059           0 :                 SCTP_INP_INFO_RUNLOCK();
    8060           0 :                 it->iterator_flags = SCTP_ITERATOR_DO_ALL_INP;
    8061             : 
    8062             :         }
    8063           0 :         SCTP_IPI_ITERATOR_WQ_LOCK();
    8064             : 
    8065           0 :         TAILQ_INSERT_TAIL(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
    8066           0 :         if (sctp_it_ctl.iterator_running == 0) {
    8067           0 :                 sctp_wakeup_iterator();
    8068             :         }
    8069           0 :         SCTP_IPI_ITERATOR_WQ_UNLOCK();
    8070             :         /* sa_ignore MEMLEAK {memory is put on the tailq for the iterator} */
    8071           0 :         return (0);
    8072             : }

Generated by: LCOV version 1.13