Home | History | Annotate | Line # | Download | only in netinet
sctp_pcb.c revision 1.26
      1   1.1       rjs /* $KAME: sctp_pcb.c,v 1.39 2005/06/16 18:29:25 jinmei Exp $ */
      2  1.26    andvar /* $NetBSD: sctp_pcb.c,v 1.26 2022/10/15 21:53:21 andvar Exp $ */
      3   1.1       rjs 
      4   1.1       rjs /*
      5   1.1       rjs  * Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc.
      6   1.1       rjs  * All rights reserved.
      7   1.1       rjs  *
      8   1.1       rjs  * Redistribution and use in source and binary forms, with or without
      9   1.1       rjs  * modification, are permitted provided that the following conditions
     10   1.1       rjs  * are met:
     11   1.1       rjs  * 1. Redistributions of source code must retain the above copyright
     12   1.1       rjs  *    notice, this list of conditions and the following disclaimer.
     13   1.1       rjs  * 2. Redistributions in binary form must reproduce the above copyright
     14   1.1       rjs  *    notice, this list of conditions and the following disclaimer in the
     15   1.1       rjs  *    documentation and/or other materials provided with the distribution.
     16   1.1       rjs  * 3. All advertising materials mentioning features or use of this software
     17   1.1       rjs  *    must display the following acknowledgement:
     18   1.1       rjs  *      This product includes software developed by Cisco Systems, Inc.
     19   1.1       rjs  * 4. Neither the name of the project nor the names of its contributors
     20   1.1       rjs  *    may be used to endorse or promote products derived from this software
     21   1.1       rjs  *    without specific prior written permission.
     22   1.1       rjs  *
     23   1.1       rjs  * THIS SOFTWARE IS PROVIDED BY CISCO SYSTEMS AND CONTRIBUTORS ``AS IS'' AND
     24   1.1       rjs  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25   1.1       rjs  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26   1.1       rjs  * ARE DISCLAIMED.  IN NO EVENT SHALL CISCO SYSTEMS OR CONTRIBUTORS BE LIABLE
     27   1.1       rjs  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28   1.1       rjs  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29   1.1       rjs  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30   1.1       rjs  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31   1.1       rjs  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32   1.1       rjs  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33   1.1       rjs  * SUCH DAMAGE.
     34   1.1       rjs  */
     35   1.1       rjs #include <sys/cdefs.h>
     36  1.26    andvar __KERNEL_RCSID(0, "$NetBSD: sctp_pcb.c,v 1.26 2022/10/15 21:53:21 andvar Exp $");
     37   1.1       rjs 
     38   1.1       rjs #ifdef _KERNEL_OPT
     39   1.1       rjs #include "opt_inet.h"
     40  1.15       rjs #include "opt_ipsec.h"
     41   1.1       rjs #include "opt_sctp.h"
     42   1.1       rjs #endif /* _KERNEL_OPT */
     43   1.1       rjs 
     44   1.1       rjs #include <sys/param.h>
     45   1.1       rjs #include <sys/systm.h>
     46   1.1       rjs #include <sys/malloc.h>
     47   1.1       rjs #include <sys/mbuf.h>
     48   1.1       rjs #include <sys/domain.h>
     49   1.1       rjs #include <sys/protosw.h>
     50   1.1       rjs #include <sys/socket.h>
     51   1.1       rjs #include <sys/socketvar.h>
     52   1.1       rjs #include <sys/proc.h>
     53   1.1       rjs #include <sys/kauth.h>
     54   1.1       rjs #include <sys/kernel.h>
     55   1.1       rjs #include <sys/sysctl.h>
     56   1.1       rjs #include <sys/callout.h>
     57   1.1       rjs 
     58   1.1       rjs #include <machine/limits.h>
     59   1.1       rjs #include <machine/cpu.h>
     60   1.1       rjs 
     61   1.1       rjs #include <net/if.h>
     62   1.1       rjs #include <net/if_types.h>
     63   1.1       rjs #include <net/route.h>
     64   1.1       rjs #include <netinet/in.h>
     65   1.1       rjs #include <netinet/in_systm.h>
     66   1.1       rjs #include <netinet/ip.h>
     67   1.1       rjs #include <netinet/in_pcb.h>
     68   1.1       rjs #include <netinet/in_var.h>
     69   1.1       rjs #include <netinet/ip_var.h>
     70   1.1       rjs 
     71   1.1       rjs #ifdef INET6
     72   1.1       rjs #include <netinet/ip6.h>
     73   1.1       rjs #include <netinet6/ip6_var.h>
     74   1.1       rjs #include <netinet6/scope6_var.h>
     75   1.1       rjs #include <netinet6/in6_pcb.h>
     76   1.1       rjs #endif /* INET6 */
     77   1.1       rjs 
     78   1.1       rjs #ifdef IPSEC
     79   1.4       rjs #include <netipsec/ipsec.h>
     80   1.4       rjs #include <netipsec/key.h>
     81   1.1       rjs #endif /* IPSEC */
     82   1.1       rjs 
     83   1.1       rjs #include <netinet/sctp_var.h>
     84   1.1       rjs #include <netinet/sctp_pcb.h>
     85   1.1       rjs #include <netinet/sctputil.h>
     86   1.1       rjs #include <netinet/sctp.h>
     87   1.1       rjs #include <netinet/sctp_header.h>
     88   1.1       rjs #include <netinet/sctp_asconf.h>
     89   1.1       rjs #include <netinet/sctp_output.h>
     90   1.1       rjs #include <netinet/sctp_timer.h>
     91   1.1       rjs 
     92   1.1       rjs #ifndef SCTP_PCBHASHSIZE
     93   1.1       rjs /* default number of association hash buckets in each endpoint */
     94   1.1       rjs #define SCTP_PCBHASHSIZE 256
     95   1.1       rjs #endif
     96   1.1       rjs 
     97   1.1       rjs #ifdef SCTP_DEBUG
     98   1.1       rjs u_int32_t sctp_debug_on = SCTP_DEBUG_ALL;
     99   1.1       rjs #endif /* SCTP_DEBUG */
    100   1.1       rjs 
    101   1.1       rjs u_int32_t sctp_pegs[SCTP_NUMBER_OF_PEGS];
    102   1.1       rjs 
    103   1.1       rjs int sctp_pcbtblsize = SCTP_PCBHASHSIZE;
    104   1.1       rjs 
    105   1.1       rjs struct sctp_epinfo sctppcbinfo;
    106   1.1       rjs 
    107   1.1       rjs /* FIX: we don't handle multiple link local scopes */
    108   1.1       rjs /* "scopeless" replacement IN6_ARE_ADDR_EQUAL */
    109   1.1       rjs int
    110   1.1       rjs SCTP6_ARE_ADDR_EQUAL(const struct in6_addr *a, const struct in6_addr *b)
    111   1.1       rjs {
    112   1.1       rjs 	struct in6_addr tmp_a, tmp_b;
    113   1.1       rjs 	/* use a copy of a and b */
    114   1.1       rjs 	tmp_a = *a;
    115   1.1       rjs 	tmp_b = *b;
    116   1.1       rjs 	in6_clearscope(&tmp_a);
    117   1.1       rjs 	in6_clearscope(&tmp_b);
    118   1.1       rjs 	return (IN6_ARE_ADDR_EQUAL(&tmp_a, &tmp_b));
    119   1.1       rjs }
    120   1.1       rjs 
    121   1.1       rjs #if defined(__FreeBSD__) && __FreeBSD_version > 500000
    122   1.1       rjs 
    123   1.1       rjs #ifndef xyzzy
    124   1.1       rjs void sctp_validate_no_locks(void);
    125   1.1       rjs 
    126   1.1       rjs void
    127   1.1       rjs SCTP_INP_RLOCK(struct sctp_inpcb *inp)
    128   1.1       rjs {
    129   1.1       rjs 	struct sctp_tcb *stcb;
    130   1.1       rjs 	LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
    131   1.1       rjs 		if (mtx_owned(&(stcb)->tcb_mtx))
    132   1.1       rjs 			panic("I own TCB lock?");
    133   1.1       rjs 	}
    134   1.1       rjs         if (mtx_owned(&(inp)->inp_mtx))
    135   1.1       rjs 		panic("INP Recursive Lock-R");
    136   1.1       rjs         mtx_lock(&(inp)->inp_mtx);
    137   1.1       rjs }
    138   1.1       rjs 
    139   1.1       rjs void
    140   1.1       rjs SCTP_INP_WLOCK(struct sctp_inpcb *inp)
    141   1.1       rjs {
    142   1.1       rjs 	SCTP_INP_RLOCK(inp);
    143   1.1       rjs }
    144   1.1       rjs 
    145   1.1       rjs void
    146   1.1       rjs SCTP_INP_INFO_RLOCK()
    147   1.1       rjs {
    148   1.1       rjs 	struct sctp_inpcb *inp;
    149   1.1       rjs 	struct sctp_tcb *stcb;
    150   1.1       rjs 	LIST_FOREACH(inp, &sctppcbinfo.listhead, sctp_list) {
    151   1.1       rjs 		if (mtx_owned(&(inp)->inp_mtx))
    152   1.1       rjs 			panic("info-lock and own inp lock?");
    153   1.1       rjs 		LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
    154   1.1       rjs 			if (mtx_owned(&(stcb)->tcb_mtx))
    155   1.1       rjs 				panic("Info lock and own a tcb lock?");
    156   1.1       rjs 		}
    157   1.1       rjs 	}
    158   1.1       rjs 	if (mtx_owned(&sctppcbinfo.ipi_ep_mtx))
    159   1.1       rjs 		panic("INP INFO Recursive Lock-R");
    160   1.1       rjs 	mtx_lock(&sctppcbinfo.ipi_ep_mtx);
    161   1.1       rjs }
    162   1.1       rjs 
    163   1.1       rjs void
    164   1.1       rjs SCTP_INP_INFO_WLOCK()
    165   1.1       rjs {
    166   1.1       rjs 	SCTP_INP_INFO_RLOCK();
    167   1.1       rjs }
    168   1.1       rjs 
    169   1.1       rjs 
    170   1.1       rjs void sctp_validate_no_locks()
    171   1.1       rjs {
    172   1.1       rjs 	struct sctp_inpcb *inp;
    173   1.1       rjs 	struct sctp_tcb *stcb;
    174   1.1       rjs 
    175   1.1       rjs 	if (mtx_owned(&sctppcbinfo.ipi_ep_mtx))
    176   1.1       rjs 		panic("INP INFO lock is owned?");
    177   1.1       rjs 
    178   1.1       rjs 	LIST_FOREACH(inp, &sctppcbinfo.listhead, sctp_list) {
    179   1.1       rjs 		if (mtx_owned(&(inp)->inp_mtx))
    180   1.1       rjs 			panic("You own an INP lock?");
    181   1.1       rjs 		LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
    182   1.1       rjs 			if (mtx_owned(&(stcb)->tcb_mtx))
    183   1.1       rjs 				panic("You own a TCB lock?");
    184   1.1       rjs 		}
    185   1.1       rjs 	}
    186   1.1       rjs }
    187   1.1       rjs 
    188   1.1       rjs #endif
    189   1.1       rjs #endif
    190   1.1       rjs 
    191   1.1       rjs void
    192   1.1       rjs sctp_fill_pcbinfo(struct sctp_pcbinfo *spcb)
    193   1.1       rjs {
    194   1.1       rjs 	/* We really don't need
    195   1.1       rjs 	 * to lock this, but I will
    196   1.1       rjs 	 * just because it does not hurt.
    197   1.1       rjs 	 */
    198   1.1       rjs 	SCTP_INP_INFO_RLOCK();
    199   1.1       rjs 	spcb->ep_count = sctppcbinfo.ipi_count_ep;
    200   1.1       rjs 	spcb->asoc_count = sctppcbinfo.ipi_count_asoc;
    201   1.1       rjs 	spcb->laddr_count = sctppcbinfo.ipi_count_laddr;
    202   1.1       rjs 	spcb->raddr_count = sctppcbinfo.ipi_count_raddr;
    203   1.1       rjs 	spcb->chk_count = sctppcbinfo.ipi_count_chunk;
    204   1.1       rjs 	spcb->sockq_count = sctppcbinfo.ipi_count_sockq;
    205   1.1       rjs 	spcb->mbuf_track = sctppcbinfo.mbuf_track;
    206   1.1       rjs 	SCTP_INP_INFO_RUNLOCK();
    207   1.1       rjs }
    208   1.1       rjs 
    209   1.1       rjs 
    210   1.1       rjs /*
    211   1.1       rjs  * Notes on locks for FreeBSD 5 and up. All association
    212   1.1       rjs  * lookups that have a definte ep, the INP structure is
    213   1.1       rjs  * assumed to be locked for reading. If we need to go
    214  1.19   msaitoh  * find the INP (usually when a **inp is passed) then
    215   1.1       rjs  * we must lock the INFO structure first and if needed
    216   1.1       rjs  * lock the INP too. Note that if we lock it we must
    217   1.1       rjs  *
    218   1.1       rjs  */
    219   1.1       rjs 
    220   1.1       rjs 
    221   1.1       rjs /*
    222   1.1       rjs  * Given a endpoint, look and find in its association list any association
    223   1.1       rjs  * with the "to" address given. This can be a "from" address, too, for
    224   1.1       rjs  * inbound packets. For outbound packets it is a true "to" address.
    225   1.1       rjs  */
    226   1.1       rjs static struct sctp_tcb *
    227   1.1       rjs sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
    228   1.1       rjs 			struct sockaddr *to, struct sctp_nets **netp)
    229   1.1       rjs {
    230   1.1       rjs 	/**** ASSUMSES THE CALLER holds the INP_INFO_RLOCK */
    231   1.1       rjs 
    232   1.1       rjs 	/*
    233   1.1       rjs 	 * Note for this module care must be taken when observing what to is
    234   1.1       rjs 	 * for. In most of the rest of the code the TO field represents my
    235   1.1       rjs 	 * peer and the FROM field represents my address. For this module it
    236   1.1       rjs 	 * is reversed of that.
    237   1.1       rjs 	 */
    238   1.1       rjs 	/*
    239   1.1       rjs 	 * If we support the TCP model, then we must now dig through to
    240   1.1       rjs 	 * see if we can find our endpoint in the list of tcp ep's.
    241   1.1       rjs 	 */
    242   1.1       rjs 	uint16_t lport, rport;
    243   1.1       rjs 	struct sctppcbhead *ephead;
    244   1.1       rjs 	struct sctp_inpcb *inp;
    245   1.1       rjs 	struct sctp_laddr *laddr;
    246   1.1       rjs 	struct sctp_tcb *stcb;
    247   1.1       rjs 	struct sctp_nets *net;
    248   1.1       rjs 
    249   1.1       rjs 	if ((to == NULL) || (from == NULL)) {
    250   1.1       rjs 		return (NULL);
    251   1.1       rjs 	}
    252   1.1       rjs 
    253   1.1       rjs 	if (to->sa_family == AF_INET && from->sa_family == AF_INET) {
    254   1.1       rjs 		lport = ((struct sockaddr_in *)to)->sin_port;
    255   1.1       rjs 		rport = ((struct sockaddr_in *)from)->sin_port;
    256   1.1       rjs 	} else if (to->sa_family == AF_INET6 && from->sa_family == AF_INET6) {
    257   1.1       rjs 		lport = ((struct sockaddr_in6 *)to)->sin6_port;
    258   1.1       rjs 		rport = ((struct sockaddr_in6 *)from)->sin6_port;
    259   1.1       rjs 	} else {
    260   1.1       rjs 		return NULL;
    261   1.1       rjs 	}
    262   1.1       rjs 	ephead = &sctppcbinfo.sctp_tcpephash[SCTP_PCBHASH_ALLADDR(
    263   1.1       rjs 						     (lport + rport), sctppcbinfo.hashtcpmark)];
    264   1.1       rjs 	/*
    265   1.1       rjs 	 * Ok now for each of the guys in this bucket we must look
    266   1.1       rjs 	 * and see:
    267   1.1       rjs 	 *  - Does the remote port match.
    268   1.1       rjs 	 *  - Does there single association's addresses match this
    269   1.1       rjs 	 *    address (to).
    270   1.1       rjs 	 * If so we update p_ep to point to this ep and return the
    271   1.1       rjs 	 * tcb from it.
    272   1.1       rjs 	 */
    273   1.1       rjs 	LIST_FOREACH(inp, ephead, sctp_hash) {
    274   1.1       rjs 		if (lport != inp->sctp_lport) {
    275   1.1       rjs 			continue;
    276   1.1       rjs 		}
    277   1.1       rjs 		SCTP_INP_RLOCK(inp);
    278   1.1       rjs 		/* check to see if the ep has one of the addresses */
    279   1.1       rjs 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
    280   1.1       rjs 			/* We are NOT bound all, so look further */
    281   1.1       rjs 			int match = 0;
    282   1.1       rjs 
    283   1.1       rjs 			LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
    284   1.1       rjs 				if (laddr->ifa == NULL) {
    285   1.1       rjs #ifdef SCTP_DEBUG
    286   1.1       rjs 					if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    287   1.1       rjs 						printf("An ounce of prevention is worth a pound of cure\n");
    288   1.1       rjs 					}
    289   1.1       rjs #endif
    290   1.1       rjs 					continue;
    291   1.1       rjs 				}
    292   1.1       rjs 				if (laddr->ifa->ifa_addr == NULL) {
    293   1.1       rjs #ifdef SCTP_DEBUG
    294   1.1       rjs 					if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    295   1.1       rjs 						printf("ifa with a NULL address\n");
    296   1.1       rjs 					}
    297   1.1       rjs #endif
    298   1.1       rjs 					continue;
    299   1.1       rjs 				}
    300   1.1       rjs 				if (laddr->ifa->ifa_addr->sa_family ==
    301   1.1       rjs 				    to->sa_family) {
    302   1.1       rjs 					/* see if it matches */
    303   1.1       rjs 					struct sockaddr_in *intf_addr, *sin;
    304   1.1       rjs 					intf_addr = (struct sockaddr_in *)
    305   1.1       rjs 						laddr->ifa->ifa_addr;
    306   1.1       rjs 					sin = (struct sockaddr_in *)to;
    307   1.1       rjs 					if (from->sa_family == AF_INET) {
    308   1.1       rjs 						if (sin->sin_addr.s_addr ==
    309   1.1       rjs 						    intf_addr->sin_addr.s_addr) {
    310   1.1       rjs 							match = 1;
    311   1.1       rjs 							SCTP_INP_RUNLOCK(inp);
    312   1.1       rjs 							break;
    313   1.1       rjs 						}
    314   1.1       rjs 					} else {
    315   1.1       rjs 						struct sockaddr_in6 *intf_addr6;
    316   1.1       rjs 						struct sockaddr_in6 *sin6;
    317   1.1       rjs 						sin6 = (struct sockaddr_in6 *)
    318   1.1       rjs 							to;
    319   1.1       rjs 						intf_addr6 = (struct sockaddr_in6 *)
    320   1.1       rjs 							laddr->ifa->ifa_addr;
    321   1.1       rjs 
    322   1.1       rjs 						if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
    323   1.1       rjs 									 &intf_addr6->sin6_addr)) {
    324   1.1       rjs 							match = 1;
    325   1.1       rjs 							SCTP_INP_RUNLOCK(inp);
    326   1.1       rjs 							break;
    327   1.1       rjs 						}
    328   1.1       rjs 					}
    329   1.1       rjs 				}
    330   1.1       rjs 			}
    331   1.1       rjs 			if (match == 0) {
    332   1.1       rjs 				/* This endpoint does not have this address */
    333   1.1       rjs 				SCTP_INP_RUNLOCK(inp);
    334   1.1       rjs 				continue;
    335   1.1       rjs 			}
    336   1.1       rjs 		}
    337   1.1       rjs 		/*
    338   1.1       rjs 		 * Ok if we hit here the ep has the address, does it hold the
    339   1.1       rjs 		 * tcb?
    340   1.1       rjs 		 */
    341   1.1       rjs 
    342   1.1       rjs 		stcb = LIST_FIRST(&inp->sctp_asoc_list);
    343   1.1       rjs 		if (stcb == NULL) {
    344   1.1       rjs 			SCTP_INP_RUNLOCK(inp);
    345   1.1       rjs 			continue;
    346   1.1       rjs 		}
    347   1.1       rjs 		SCTP_TCB_LOCK(stcb);
    348   1.1       rjs 		if (stcb->rport != rport) {
    349   1.1       rjs 			/* remote port does not match. */
    350   1.1       rjs 			SCTP_TCB_UNLOCK(stcb);
    351   1.1       rjs 			SCTP_INP_RUNLOCK(inp);
    352   1.1       rjs 			continue;
    353   1.1       rjs 		}
    354   1.1       rjs 		/* Does this TCB have a matching address? */
    355   1.1       rjs 		TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
    356   1.1       rjs 			if (sctp_cmpaddr(from, rtcache_getdst(&net->ro))) {
    357   1.1       rjs 				/* found it */
    358   1.1       rjs 				if (netp != NULL) {
    359   1.1       rjs 					*netp = net;
    360   1.1       rjs 				}
    361   1.1       rjs 				/* Update the endpoint pointer */
    362   1.1       rjs 				*inp_p = inp;
    363   1.1       rjs 				SCTP_INP_RUNLOCK(inp);
    364   1.1       rjs 				return (stcb);
    365   1.1       rjs 			}
    366   1.1       rjs 		}
    367   1.1       rjs 		SCTP_TCB_UNLOCK(stcb);
    368   1.1       rjs 
    369   1.1       rjs 		SCTP_INP_RUNLOCK(inp);
    370   1.1       rjs 	}
    371   1.1       rjs 	return (NULL);
    372   1.1       rjs }
    373   1.1       rjs 
    374   1.1       rjs struct sctp_tcb *
    375   1.1       rjs sctp_findassociation_ep_asconf(struct mbuf *m, int iphlen, int offset,
    376   1.1       rjs     struct sctphdr *sh, struct sctp_inpcb **inp_p, struct sctp_nets **netp)
    377   1.1       rjs {
    378   1.1       rjs 	struct sctp_tcb *stcb;
    379   1.1       rjs 	struct sockaddr_in *sin;
    380   1.1       rjs 	struct sockaddr_in6 *sin6;
    381   1.1       rjs 	struct sockaddr_storage local_store, remote_store;
    382   1.1       rjs 	struct ip *iph;
    383   1.1       rjs 	struct sctp_paramhdr parm_buf, *phdr;
    384   1.1       rjs 	int ptype;
    385   1.1       rjs 
    386   1.1       rjs 	memset(&local_store, 0, sizeof(local_store));
    387   1.1       rjs 	memset(&remote_store, 0, sizeof(remote_store));
    388   1.1       rjs 
    389   1.1       rjs 	/* First get the destination address setup too. */
    390   1.1       rjs 	iph = mtod(m, struct ip *);
    391   1.1       rjs 	if (iph->ip_v == IPVERSION) {
    392   1.1       rjs 		/* its IPv4 */
    393   1.1       rjs 		sin = (struct sockaddr_in *)&local_store;
    394   1.1       rjs 		sin->sin_family = AF_INET;
    395   1.1       rjs 		sin->sin_len = sizeof(*sin);
    396   1.1       rjs 		sin->sin_port = sh->dest_port;
    397   1.1       rjs 		sin->sin_addr.s_addr = iph->ip_dst.s_addr ;
    398   1.1       rjs 	} else if (iph->ip_v == (IPV6_VERSION >> 4)) {
    399   1.1       rjs 		/* its IPv6 */
    400   1.1       rjs 		struct ip6_hdr *ip6;
    401   1.1       rjs 		ip6 = mtod(m, struct ip6_hdr *);
    402   1.1       rjs 		sin6 = (struct sockaddr_in6 *)&local_store;
    403   1.1       rjs 		sin6->sin6_family = AF_INET6;
    404   1.1       rjs 		sin6->sin6_len = sizeof(*sin6);
    405   1.1       rjs 		sin6->sin6_port = sh->dest_port;
    406   1.1       rjs 		sin6->sin6_addr = ip6->ip6_dst;
    407   1.1       rjs 	} else {
    408   1.1       rjs 		return NULL;
    409   1.1       rjs 	}
    410   1.1       rjs 
    411   1.1       rjs 	phdr = sctp_get_next_param(m, offset + sizeof(struct sctp_asconf_chunk),
    412   1.1       rjs 	    &parm_buf, sizeof(struct sctp_paramhdr));
    413   1.1       rjs 	if (phdr == NULL) {
    414   1.1       rjs #ifdef SCTP_DEBUG
    415   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_INPUT3) {
    416   1.1       rjs 			printf("sctp_process_control: failed to get asconf lookup addr\n");
    417   1.1       rjs 		}
    418   1.1       rjs #endif /* SCTP_DEBUG */
    419   1.1       rjs 		return NULL;
    420   1.1       rjs 	}
    421   1.1       rjs 	ptype = (int)((u_int)ntohs(phdr->param_type));
    422   1.1       rjs 	/* get the correlation address */
    423   1.1       rjs 	if (ptype == SCTP_IPV6_ADDRESS) {
    424   1.1       rjs 		/* ipv6 address param */
    425   1.1       rjs 		struct sctp_ipv6addr_param *p6, p6_buf;
    426   1.1       rjs 		if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv6addr_param)) {
    427   1.1       rjs 			return NULL;
    428   1.1       rjs 		}
    429   1.1       rjs 
    430   1.1       rjs 		p6 = (struct sctp_ipv6addr_param *)sctp_get_next_param(m,
    431   1.1       rjs 		    offset + sizeof(struct sctp_asconf_chunk),
    432   1.1       rjs 		    &p6_buf.ph, sizeof(*p6));
    433   1.1       rjs 		if (p6 == NULL) {
    434   1.1       rjs #ifdef SCTP_DEBUG
    435   1.1       rjs 			if (sctp_debug_on & SCTP_DEBUG_INPUT3) {
    436   1.1       rjs 				printf("sctp_process_control: failed to get asconf v6 lookup addr\n");
    437   1.1       rjs 			}
    438   1.1       rjs #endif /* SCTP_DEBUG */
    439   1.1       rjs 			return (NULL);
    440   1.1       rjs 		}
    441   1.1       rjs 		sin6 = (struct sockaddr_in6 *)&remote_store;
    442   1.1       rjs 		sin6->sin6_family = AF_INET6;
    443   1.1       rjs 		sin6->sin6_len = sizeof(*sin6);
    444   1.1       rjs 		sin6->sin6_port = sh->src_port;
    445   1.1       rjs 		memcpy(&sin6->sin6_addr, &p6->addr, sizeof(struct in6_addr));
    446   1.1       rjs 	} else if (ptype == SCTP_IPV4_ADDRESS) {
    447   1.1       rjs 		/* ipv4 address param */
    448   1.1       rjs 		struct sctp_ipv4addr_param *p4, p4_buf;
    449   1.1       rjs 		if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv4addr_param)) {
    450   1.1       rjs 			return NULL;
    451   1.1       rjs 		}
    452   1.1       rjs 
    453   1.1       rjs 		p4 = (struct sctp_ipv4addr_param *)sctp_get_next_param(m,
    454   1.1       rjs 		    offset + sizeof(struct sctp_asconf_chunk),
    455   1.1       rjs 		    &p4_buf.ph, sizeof(*p4));
    456   1.1       rjs 		if (p4 == NULL) {
    457   1.1       rjs #ifdef SCTP_DEBUG
    458   1.1       rjs 			if (sctp_debug_on & SCTP_DEBUG_INPUT3) {
    459   1.1       rjs 				printf("sctp_process_control: failed to get asconf v4 lookup addr\n");
    460   1.1       rjs 			}
    461   1.1       rjs #endif /* SCTP_DEBUG */
    462   1.1       rjs 			return (NULL);
    463   1.1       rjs 		}
    464   1.1       rjs 		sin = (struct sockaddr_in *)&remote_store;
    465   1.1       rjs 		sin->sin_family = AF_INET;
    466   1.1       rjs 		sin->sin_len = sizeof(*sin);
    467   1.1       rjs 		sin->sin_port = sh->src_port;
    468   1.1       rjs 		memcpy(&sin->sin_addr, &p4->addr, sizeof(struct in_addr));
    469   1.1       rjs 	} else {
    470   1.1       rjs 		/* invalid address param type */
    471   1.1       rjs 		return NULL;
    472   1.1       rjs 	}
    473   1.1       rjs 
    474   1.1       rjs 	stcb = sctp_findassociation_ep_addr(inp_p,
    475   1.1       rjs 	    (struct sockaddr *)&remote_store, netp,
    476   1.1       rjs 	    (struct sockaddr *)&local_store, NULL);
    477   1.1       rjs 	return (stcb);
    478   1.1       rjs }
    479   1.1       rjs 
    480   1.1       rjs struct sctp_tcb *
    481   1.1       rjs sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
    482   1.1       rjs     struct sctp_nets **netp, struct sockaddr *local, struct sctp_tcb *locked_tcb)
    483   1.1       rjs {
    484   1.1       rjs 	struct sctpasochead *head;
    485   1.1       rjs 	struct sctp_inpcb *inp;
    486   1.1       rjs 	struct sctp_tcb *stcb;
    487   1.1       rjs 	struct sctp_nets *net;
    488   1.1       rjs 	uint16_t rport;
    489   1.1       rjs 
    490   1.1       rjs 	inp = *inp_p;
    491   1.1       rjs 	if (remote->sa_family == AF_INET) {
    492   1.1       rjs 		rport = (((struct sockaddr_in *)remote)->sin_port);
    493   1.1       rjs 	} else if (remote->sa_family == AF_INET6) {
    494   1.1       rjs 		rport = (((struct sockaddr_in6 *)remote)->sin6_port);
    495   1.1       rjs 	} else {
    496   1.1       rjs 		return (NULL);
    497   1.1       rjs 	}
    498   1.1       rjs 	if (locked_tcb) {
    499   1.1       rjs 		/* UN-lock so we can do proper locking here
    500   1.1       rjs 		 * this occurs when called from load_addresses_from_init.
    501   1.1       rjs 		 */
    502   1.1       rjs 		SCTP_TCB_UNLOCK(locked_tcb);
    503   1.1       rjs 	}
    504   1.1       rjs 	SCTP_INP_INFO_RLOCK();
    505   1.1       rjs 	if (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
    506   1.1       rjs 		/*
    507   1.1       rjs 		 * Now either this guy is our listner or it's the connector.
    508   1.1       rjs 		 * If it is the one that issued the connect, then it's only
    509   1.1       rjs 		 * chance is to be the first TCB in the list. If it is the
    510   1.1       rjs 		 * acceptor, then do the special_lookup to hash and find the
    511   1.1       rjs 		 * real inp.
    512   1.1       rjs 		 */
    513   1.1       rjs 		if (inp->sctp_flags & SCTP_PCB_FLAGS_ACCEPTING) {
    514   1.1       rjs 			/* to is peer addr, from is my addr */
    515   1.1       rjs 			stcb = sctp_tcb_special_locate(inp_p, remote, local,
    516   1.1       rjs 						       netp);
    517   1.1       rjs 			if ((stcb != NULL) && (locked_tcb == NULL)){
    518   1.1       rjs 				/* we have a locked tcb, lower refcount */
    519   1.1       rjs 				SCTP_INP_WLOCK(inp);
    520   1.1       rjs 				SCTP_INP_DECR_REF(inp);
    521   1.1       rjs 				SCTP_INP_WUNLOCK(inp);
    522   1.1       rjs 			}
    523   1.1       rjs 			if (locked_tcb != NULL) {
    524   1.1       rjs 				SCTP_INP_RLOCK(locked_tcb->sctp_ep);
    525   1.1       rjs 				SCTP_TCB_LOCK(locked_tcb);
    526   1.1       rjs 				SCTP_INP_RUNLOCK(locked_tcb->sctp_ep);
    527   1.1       rjs 				if (stcb != NULL) {
    528   1.1       rjs 					SCTP_TCB_UNLOCK(stcb);
    529   1.1       rjs 				}
    530   1.1       rjs 			}
    531   1.1       rjs 			SCTP_INP_INFO_RUNLOCK();
    532   1.1       rjs 			return (stcb);
    533   1.1       rjs 		} else {
    534   1.1       rjs 			SCTP_INP_WLOCK(inp);
    535   1.1       rjs 			stcb = LIST_FIRST(&inp->sctp_asoc_list);
    536   1.1       rjs 			if (stcb == NULL) {
    537   1.1       rjs 				goto null_return;
    538   1.1       rjs 			}
    539   1.1       rjs 			SCTP_TCB_LOCK(stcb);
    540   1.1       rjs 			if (stcb->rport != rport) {
    541   1.1       rjs 				/* remote port does not match. */
    542   1.1       rjs 				SCTP_TCB_UNLOCK(stcb);
    543   1.1       rjs 				goto null_return;
    544   1.1       rjs 			}
    545   1.1       rjs 			/* now look at the list of remote addresses */
    546   1.1       rjs 			TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
    547   1.1       rjs 				if (sctp_cmpaddr(remote, rtcache_getdst(&net->ro))) {
    548   1.1       rjs 					/* found it */
    549   1.1       rjs 					if (netp != NULL) {
    550   1.1       rjs 						*netp = net;
    551   1.1       rjs 					}
    552   1.1       rjs 					if (locked_tcb == NULL) {
    553   1.1       rjs 						SCTP_INP_DECR_REF(inp);
    554   1.1       rjs 					}
    555   1.1       rjs 					SCTP_INP_WUNLOCK(inp);
    556   1.1       rjs 					SCTP_INP_INFO_RUNLOCK();
    557   1.1       rjs 					return (stcb);
    558   1.1       rjs 				}
    559   1.1       rjs 			}
    560   1.1       rjs 			SCTP_TCB_UNLOCK(stcb);
    561   1.1       rjs 		}
    562   1.1       rjs 	} else {
    563   1.1       rjs 		SCTP_INP_WLOCK(inp);
    564   1.1       rjs 		head = &inp->sctp_tcbhash[SCTP_PCBHASH_ALLADDR(rport,
    565   1.1       rjs 							       inp->sctp_hashmark)];
    566   1.1       rjs 		if (head == NULL) {
    567   1.1       rjs 			goto null_return;
    568   1.1       rjs 		}
    569   1.1       rjs 		LIST_FOREACH(stcb, head, sctp_tcbhash) {
    570   1.1       rjs 			if (stcb->rport != rport) {
    571   1.1       rjs 				/* remote port does not match */
    572   1.1       rjs 				continue;
    573   1.1       rjs 			}
    574   1.1       rjs 			/* now look at the list of remote addresses */
    575   1.1       rjs 			SCTP_TCB_LOCK(stcb);
    576   1.1       rjs 			TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
    577   1.1       rjs 				if (sctp_cmpaddr(remote, rtcache_getdst(&net->ro))) {
    578   1.1       rjs 					/* found it */
    579   1.1       rjs 					if (netp != NULL) {
    580   1.1       rjs 						*netp = net;
    581   1.1       rjs 					}
    582   1.1       rjs 					if (locked_tcb == NULL) {
    583   1.1       rjs 						SCTP_INP_DECR_REF(inp);
    584   1.1       rjs 					}
    585   1.1       rjs 					SCTP_INP_WUNLOCK(inp);
    586   1.1       rjs 					SCTP_INP_INFO_RUNLOCK();
    587   1.1       rjs 					return (stcb);
    588   1.1       rjs 				}
    589   1.1       rjs 			}
    590   1.1       rjs 			SCTP_TCB_UNLOCK(stcb);
    591   1.1       rjs 		}
    592   1.1       rjs 	}
    593   1.1       rjs  null_return:
    594   1.1       rjs 	/* clean up for returning null */
    595   1.1       rjs 	if (locked_tcb){
    596   1.1       rjs 		if (locked_tcb->sctp_ep != inp) {
    597   1.1       rjs 			SCTP_INP_RLOCK(locked_tcb->sctp_ep);
    598   1.1       rjs 			SCTP_TCB_LOCK(locked_tcb);
    599   1.1       rjs 			SCTP_INP_RUNLOCK(locked_tcb->sctp_ep);
    600   1.1       rjs 		} else {
    601   1.1       rjs 			SCTP_TCB_LOCK(locked_tcb);
    602   1.1       rjs 		}
    603   1.1       rjs 	}
    604   1.1       rjs 	SCTP_INP_WUNLOCK(inp);
    605   1.1       rjs 	SCTP_INP_INFO_RUNLOCK();
    606   1.1       rjs 	/* not found */
    607   1.1       rjs 	return (NULL);
    608   1.1       rjs }
    609   1.1       rjs 
    610   1.1       rjs /*
    611   1.1       rjs  * Find an association for a specific endpoint using the association id
    612   1.1       rjs  * given out in the COMM_UP notification
    613   1.1       rjs  */
    614   1.1       rjs struct sctp_tcb *
    615   1.1       rjs sctp_findassociation_ep_asocid(struct sctp_inpcb *inp, vaddr_t asoc_id)
    616   1.1       rjs {
    617   1.1       rjs 	/*
    618   1.1       rjs 	 * Use my the assoc_id to find a endpoint
    619   1.1       rjs 	 */
    620   1.1       rjs 	struct sctpasochead *head;
    621   1.1       rjs 	struct sctp_tcb *stcb;
    622   1.1       rjs 	u_int32_t vtag;
    623   1.1       rjs 
    624   1.1       rjs 	if (asoc_id == 0 || inp == NULL) {
    625   1.1       rjs 		return (NULL);
    626   1.1       rjs 	}
    627   1.1       rjs 	SCTP_INP_INFO_RLOCK();
    628   1.1       rjs 	vtag = (u_int32_t)asoc_id;
    629   1.1       rjs 	head = &sctppcbinfo.sctp_asochash[SCTP_PCBHASH_ASOC(vtag,
    630   1.1       rjs 	    sctppcbinfo.hashasocmark)];
    631   1.1       rjs 	if (head == NULL) {
    632   1.1       rjs 		/* invalid vtag */
    633   1.1       rjs 		SCTP_INP_INFO_RUNLOCK();
    634   1.1       rjs 		return (NULL);
    635   1.1       rjs 	}
    636   1.1       rjs 	LIST_FOREACH(stcb, head, sctp_asocs) {
    637   1.1       rjs 		SCTP_INP_RLOCK(stcb->sctp_ep);
    638   1.1       rjs 		SCTP_TCB_LOCK(stcb);
    639   1.1       rjs 		SCTP_INP_RUNLOCK(stcb->sctp_ep);
    640   1.1       rjs 		if (stcb->asoc.my_vtag == vtag) {
    641   1.1       rjs 			/* candidate */
    642   1.1       rjs 			if (inp != stcb->sctp_ep) {
    643   1.1       rjs 				/* some other guy has the
    644   1.1       rjs 				 * same vtag active (vtag collision).
    645   1.1       rjs 				 */
    646   1.1       rjs 				sctp_pegs[SCTP_VTAG_BOGUS]++;
    647   1.1       rjs 				SCTP_TCB_UNLOCK(stcb);
    648   1.1       rjs 				continue;
    649   1.1       rjs 			}
    650   1.1       rjs 			sctp_pegs[SCTP_VTAG_EXPR]++;
    651   1.1       rjs 			SCTP_INP_INFO_RUNLOCK();
    652   1.1       rjs 			return (stcb);
    653   1.1       rjs 		}
    654   1.1       rjs 		SCTP_TCB_UNLOCK(stcb);
    655   1.1       rjs 	}
    656   1.1       rjs 	SCTP_INP_INFO_RUNLOCK();
    657   1.1       rjs 	return (NULL);
    658   1.1       rjs }
    659   1.1       rjs 
    660   1.1       rjs static struct sctp_inpcb *
    661   1.1       rjs sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
    662   1.1       rjs 		    uint16_t lport)
    663   1.1       rjs {
    664   1.1       rjs 	struct sctp_inpcb *inp;
    665   1.1       rjs 	struct sockaddr_in *sin;
    666   1.1       rjs 	struct sockaddr_in6 *sin6;
    667   1.1       rjs 	struct sctp_laddr *laddr;
    668   1.1       rjs 
    669   1.1       rjs 	/* Endpoing probe expects
    670   1.1       rjs 	 * that the INP_INFO is locked.
    671   1.1       rjs 	 */
    672   1.1       rjs 	if (nam->sa_family == AF_INET) {
    673   1.1       rjs 		sin = (struct sockaddr_in *)nam;
    674   1.1       rjs 		sin6 = NULL;
    675   1.1       rjs 	} else if (nam->sa_family == AF_INET6) {
    676   1.1       rjs 		sin6 = (struct sockaddr_in6 *)nam;
    677   1.1       rjs 		sin = NULL;
    678   1.1       rjs 	} else {
    679   1.1       rjs 		/* unsupported family */
    680   1.1       rjs 		return (NULL);
    681   1.1       rjs 	}
    682   1.1       rjs 	if (head == NULL)
    683   1.1       rjs 		return (NULL);
    684   1.1       rjs 
    685   1.1       rjs 	LIST_FOREACH(inp, head, sctp_hash) {
    686   1.1       rjs 		SCTP_INP_RLOCK(inp);
    687   1.1       rjs 
    688   1.1       rjs 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) &&
    689   1.1       rjs 		    (inp->sctp_lport == lport)) {
    690   1.1       rjs 			/* got it */
    691   1.1       rjs 			if ((nam->sa_family == AF_INET) &&
    692   1.1       rjs 			    (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
    693   1.1       rjs 			    (((struct in6pcb *)inp)->in6p_flags & IN6P_IPV6_V6ONLY)
    694   1.1       rjs 				) {
    695   1.1       rjs 				/* IPv4 on a IPv6 socket with ONLY IPv6 set */
    696   1.1       rjs 				SCTP_INP_RUNLOCK(inp);
    697   1.1       rjs 				continue;
    698   1.1       rjs 			}
    699   1.1       rjs 			/* A V6 address and the endpoint is NOT bound V6 */
    700   1.1       rjs 			if (nam->sa_family == AF_INET6 &&
    701   1.1       rjs 			   (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
    702   1.1       rjs 				SCTP_INP_RUNLOCK(inp);
    703   1.1       rjs 				continue;
    704   1.1       rjs 			}
    705   1.1       rjs 			SCTP_INP_RUNLOCK(inp);
    706   1.1       rjs 			return (inp);
    707   1.1       rjs 		}
    708   1.1       rjs 		SCTP_INP_RUNLOCK(inp);
    709   1.1       rjs 	}
    710   1.1       rjs 
    711   1.1       rjs 	if ((nam->sa_family == AF_INET) &&
    712   1.1       rjs 	    (sin->sin_addr.s_addr == INADDR_ANY)) {
    713   1.1       rjs 		/* Can't hunt for one that has no address specified */
    714   1.1       rjs 		return (NULL);
    715   1.1       rjs 	} else if ((nam->sa_family == AF_INET6) &&
    716   1.1       rjs 		   (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))) {
    717   1.1       rjs 		/* Can't hunt for one that has no address specified */
    718   1.1       rjs 		return (NULL);
    719   1.1       rjs 	}
    720   1.1       rjs 	/*
    721   1.1       rjs 	 * ok, not bound to all so see if we can find a EP bound to this
    722   1.1       rjs 	 * address.
    723   1.1       rjs 	 */
    724   1.1       rjs #ifdef SCTP_DEBUG
    725   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    726   1.1       rjs 		printf("Ok, there is NO bound-all available for port:%x\n", ntohs(lport));
    727   1.1       rjs 	}
    728   1.1       rjs #endif
    729   1.1       rjs 	LIST_FOREACH(inp, head, sctp_hash) {
    730   1.1       rjs 		SCTP_INP_RLOCK(inp);
    731   1.1       rjs 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL)) {
    732   1.1       rjs 			SCTP_INP_RUNLOCK(inp);
    733   1.1       rjs 			continue;
    734   1.1       rjs 		}
    735   1.1       rjs 		/*
    736   1.1       rjs 		 * Ok this could be a likely candidate, look at all of
    737   1.1       rjs 		 * its addresses
    738   1.1       rjs 		 */
    739   1.1       rjs 		if (inp->sctp_lport != lport) {
    740   1.1       rjs 			SCTP_INP_RUNLOCK(inp);
    741   1.1       rjs 			continue;
    742   1.1       rjs 		}
    743   1.1       rjs #ifdef SCTP_DEBUG
    744   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    745  1.22    andvar 			printf("Ok, found matching local port\n");
    746   1.1       rjs 		}
    747   1.1       rjs #endif
    748   1.1       rjs 		LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
    749   1.1       rjs 			if (laddr->ifa == NULL) {
    750   1.1       rjs #ifdef SCTP_DEBUG
    751   1.1       rjs 				if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    752   1.1       rjs 					printf("An ounce of prevention is worth a pound of cure\n");
    753   1.1       rjs 				}
    754   1.1       rjs #endif
    755   1.1       rjs 				continue;
    756   1.1       rjs 			}
    757   1.1       rjs #ifdef SCTP_DEBUG
    758   1.1       rjs 			if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    759   1.1       rjs 				printf("Ok laddr->ifa:%p is possible, ",
    760   1.1       rjs 				    laddr->ifa);
    761   1.1       rjs 			}
    762   1.1       rjs #endif
    763   1.1       rjs 			if (laddr->ifa->ifa_addr == NULL) {
    764   1.1       rjs #ifdef SCTP_DEBUG
    765   1.1       rjs 				if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    766   1.1       rjs 					printf("Huh IFA as an ifa_addr=NULL, ");
    767   1.1       rjs 				}
    768   1.1       rjs #endif
    769   1.1       rjs 				continue;
    770   1.1       rjs 			}
    771   1.1       rjs #ifdef SCTP_DEBUG
    772   1.1       rjs 			if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    773   1.1       rjs 				printf("Ok laddr->ifa:%p is possible, ",
    774   1.1       rjs 				    laddr->ifa->ifa_addr);
    775   1.1       rjs 				sctp_print_address(laddr->ifa->ifa_addr);
    776   1.1       rjs 				printf("looking for ");
    777   1.1       rjs 				sctp_print_address(nam);
    778   1.1       rjs 			}
    779   1.1       rjs #endif
    780   1.1       rjs 			if (laddr->ifa->ifa_addr->sa_family == nam->sa_family) {
    781   1.1       rjs 				/* possible, see if it matches */
    782   1.1       rjs 				struct sockaddr_in *intf_addr;
    783   1.1       rjs 				intf_addr = (struct sockaddr_in *)
    784   1.1       rjs 				    laddr->ifa->ifa_addr;
    785   1.1       rjs 				if (nam->sa_family == AF_INET) {
    786   1.1       rjs 					if (sin->sin_addr.s_addr ==
    787   1.1       rjs 					    intf_addr->sin_addr.s_addr) {
    788   1.1       rjs #ifdef SCTP_DEBUG
    789   1.1       rjs 						if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    790   1.1       rjs 							printf("YES, return ep:%p\n", inp);
    791   1.1       rjs 						}
    792   1.1       rjs #endif
    793   1.1       rjs 						SCTP_INP_RUNLOCK(inp);
    794   1.1       rjs 						return (inp);
    795   1.1       rjs 					}
    796   1.1       rjs 				} else if (nam->sa_family == AF_INET6) {
    797   1.1       rjs 					struct sockaddr_in6 *intf_addr6;
    798   1.1       rjs 					intf_addr6 = (struct sockaddr_in6 *)
    799   1.1       rjs 					    laddr->ifa->ifa_addr;
    800   1.1       rjs 					if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
    801   1.1       rjs 				 	    &intf_addr6->sin6_addr)) {
    802   1.1       rjs #ifdef SCTP_DEBUG
    803   1.1       rjs 						if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    804   1.1       rjs 							printf("YES, return ep:%p\n", inp);
    805   1.1       rjs 						}
    806   1.1       rjs #endif
    807   1.1       rjs 						SCTP_INP_RUNLOCK(inp);
    808   1.1       rjs 						return (inp);
    809   1.1       rjs 					}
    810   1.1       rjs 				}
    811   1.1       rjs 			}
    812   1.1       rjs 			SCTP_INP_RUNLOCK(inp);
    813   1.1       rjs 		}
    814   1.1       rjs 	}
    815   1.1       rjs #ifdef SCTP_DEBUG
    816   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    817   1.1       rjs 		printf("NO, Falls out to NULL\n");
    818   1.1       rjs 	}
    819   1.1       rjs #endif
    820   1.1       rjs 	return (NULL);
    821   1.1       rjs }
    822   1.1       rjs 
    823   1.1       rjs 
    824   1.1       rjs struct sctp_inpcb *
    825   1.1       rjs sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock)
    826   1.1       rjs {
    827   1.1       rjs 	/*
    828   1.1       rjs 	 * First we check the hash table to see if someone has this port
    829   1.1       rjs 	 * bound with just the port.
    830   1.1       rjs 	 */
    831   1.1       rjs 	struct sctp_inpcb *inp;
    832   1.1       rjs 	struct sctppcbhead *head;
    833   1.1       rjs 	int lport;
    834   1.1       rjs #ifdef SCTP_DEBUG
    835   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    836   1.1       rjs 		printf("Looking for endpoint %d :",
    837   1.1       rjs 		       ntohs(((struct sockaddr_in *)nam)->sin_port));
    838   1.1       rjs 		sctp_print_address(nam);
    839   1.1       rjs 	}
    840   1.1       rjs #endif
    841   1.1       rjs 	if (nam->sa_family == AF_INET) {
    842   1.1       rjs 		lport = ((struct sockaddr_in *)nam)->sin_port;
    843   1.1       rjs 	} else if (nam->sa_family == AF_INET6) {
    844   1.1       rjs 		lport = ((struct sockaddr_in6 *)nam)->sin6_port;
    845   1.1       rjs 	} else {
    846   1.1       rjs 		/* unsupported family */
    847   1.1       rjs 		return (NULL);
    848   1.1       rjs 	}
    849   1.1       rjs 	/*
    850   1.1       rjs 	 * I could cheat here and just cast to one of the types but we will
    851   1.1       rjs 	 * do it right. It also provides the check against an Unsupported
    852   1.1       rjs 	 * type too.
    853   1.1       rjs 	 */
    854   1.1       rjs 	/* Find the head of the ALLADDR chain */
    855   1.1       rjs 	if (have_lock == 0) {
    856   1.1       rjs 		SCTP_INP_INFO_RLOCK();
    857   1.1       rjs 	}
    858   1.1       rjs 	head = &sctppcbinfo.sctp_ephash[SCTP_PCBHASH_ALLADDR(lport,
    859   1.1       rjs 							     sctppcbinfo.hashmark)];
    860   1.1       rjs #ifdef SCTP_DEBUG
    861   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    862   1.1       rjs 		printf("Main hash to lookup at head:%p\n", head);
    863   1.1       rjs 	}
    864   1.1       rjs #endif
    865   1.1       rjs  	inp = sctp_endpoint_probe(nam, head, lport);
    866   1.1       rjs 
    867   1.1       rjs 	/*
    868   1.1       rjs 	 * If the TCP model exists it could be that the main listening
    869   1.1       rjs 	 * endpoint is gone but there exists a connected socket for this
    870   1.1       rjs 	 * guy yet. If so we can return the first one that we find. This
    871   1.1       rjs 	 * may NOT be the correct one but the sctp_findassociation_ep_addr
    872   1.1       rjs 	 * has further code to look at all TCP models.
    873   1.1       rjs 	 */
    874   1.1       rjs 	if (inp == NULL && find_tcp_pool) {
    875   1.1       rjs 		unsigned int i;
    876   1.1       rjs #ifdef SCTP_DEBUG
    877   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    878   1.1       rjs 			printf("EP was NULL and TCP model is supported\n");
    879   1.1       rjs 		}
    880   1.1       rjs #endif
    881   1.1       rjs 		for (i = 0; i < sctppcbinfo.hashtblsize; i++) {
    882   1.1       rjs 			/*
    883   1.1       rjs 			 * This is real gross, but we do NOT have a remote
    884   1.1       rjs 			 * port at this point depending on who is calling. We
    885   1.1       rjs 			 * must therefore look for ANY one that matches our
    886   1.1       rjs 			 * local port :/
    887   1.1       rjs 			 */
    888   1.1       rjs 			head = &sctppcbinfo.sctp_tcpephash[i];
    889   1.1       rjs 			if (LIST_FIRST(head)) {
    890   1.1       rjs 				inp = sctp_endpoint_probe(nam, head, lport);
    891   1.1       rjs 				if (inp) {
    892   1.1       rjs 					/* Found one */
    893   1.1       rjs 					break;
    894   1.1       rjs 				}
    895   1.1       rjs 			}
    896   1.1       rjs 		}
    897   1.1       rjs 	}
    898   1.1       rjs #ifdef SCTP_DEBUG
    899   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
    900   1.1       rjs 		printf("EP to return is %p\n", inp);
    901   1.1       rjs 	}
    902   1.1       rjs #endif
    903   1.1       rjs 	if (have_lock == 0) {
    904   1.1       rjs 		if (inp) {
    905   1.1       rjs 			SCTP_INP_WLOCK(inp);
    906   1.1       rjs 			SCTP_INP_INCR_REF(inp);
    907   1.1       rjs 			SCTP_INP_WUNLOCK(inp);
    908   1.1       rjs 		}
    909   1.1       rjs 		SCTP_INP_INFO_RUNLOCK();
    910   1.1       rjs 	} else {
    911   1.1       rjs 		if (inp) {
    912   1.1       rjs 			SCTP_INP_WLOCK(inp);
    913   1.1       rjs 			SCTP_INP_INCR_REF(inp);
    914   1.1       rjs 			SCTP_INP_WUNLOCK(inp);
    915   1.1       rjs 		}
    916   1.1       rjs 	}
    917   1.1       rjs 	return (inp);
    918   1.1       rjs }
    919   1.1       rjs 
    920   1.1       rjs /*
    921   1.1       rjs  * Find an association for an endpoint with the pointer to whom you want
    922   1.1       rjs  * to send to and the endpoint pointer. The address can be IPv4 or IPv6.
    923   1.1       rjs  * We may need to change the *to to some other struct like a mbuf...
    924   1.1       rjs  */
    925   1.1       rjs struct sctp_tcb *
    926   1.1       rjs sctp_findassociation_addr_sa(struct sockaddr *to, struct sockaddr *from,
    927   1.1       rjs     struct sctp_inpcb **inp_p, struct sctp_nets **netp, int find_tcp_pool)
    928   1.1       rjs {
    929   1.1       rjs 	struct sctp_inpcb *inp;
    930   1.1       rjs 	struct sctp_tcb *retval;
    931   1.1       rjs 
    932   1.1       rjs 	SCTP_INP_INFO_RLOCK();
    933   1.1       rjs 	if (find_tcp_pool) {
    934   1.1       rjs 		if (inp_p != NULL) {
    935   1.1       rjs 			retval = sctp_tcb_special_locate(inp_p, from, to, netp);
    936   1.1       rjs 		} else {
    937   1.1       rjs 			retval = sctp_tcb_special_locate(&inp, from, to, netp);
    938   1.1       rjs 		}
    939   1.1       rjs 		if (retval != NULL) {
    940   1.1       rjs 			SCTP_INP_INFO_RUNLOCK();
    941   1.1       rjs 			return (retval);
    942   1.1       rjs 		}
    943   1.1       rjs 	}
    944   1.1       rjs 	inp = sctp_pcb_findep(to, 0, 1);
    945   1.1       rjs 	if (inp_p != NULL) {
    946   1.1       rjs 		*inp_p = inp;
    947   1.1       rjs 	}
    948   1.1       rjs 	SCTP_INP_INFO_RUNLOCK();
    949   1.1       rjs 
    950   1.1       rjs 	if (inp == NULL) {
    951   1.1       rjs 		return (NULL);
    952   1.1       rjs 	}
    953   1.1       rjs 
    954   1.1       rjs 	/*
    955   1.1       rjs 	 * ok, we have an endpoint, now lets find the assoc for it (if any)
    956   1.1       rjs 	 * we now place the source address or from in the to of the find
    957   1.1       rjs 	 * endpoint call. Since in reality this chain is used from the
    958   1.1       rjs 	 * inbound packet side.
    959   1.1       rjs 	 */
    960   1.1       rjs 	if (inp_p != NULL) {
    961   1.1       rjs 		return (sctp_findassociation_ep_addr(inp_p, from, netp, to, NULL));
    962   1.1       rjs 	} else {
    963   1.1       rjs 		return (sctp_findassociation_ep_addr(&inp, from, netp, to, NULL));
    964   1.1       rjs 	}
    965   1.1       rjs }
    966   1.1       rjs 
    967   1.1       rjs 
    968   1.1       rjs /*
    969   1.1       rjs  * This routine will grub through the mbuf that is a INIT or INIT-ACK and
    970   1.1       rjs  * find all addresses that the sender has specified in any address list.
    971   1.1       rjs  * Each address will be used to lookup the TCB and see if one exits.
    972   1.1       rjs  */
    973   1.1       rjs static struct sctp_tcb *
    974   1.1       rjs sctp_findassociation_special_addr(struct mbuf *m, int iphlen, int offset,
    975   1.1       rjs     struct sctphdr *sh, struct sctp_inpcb **inp_p, struct sctp_nets **netp,
    976   1.1       rjs     struct sockaddr *dest)
    977   1.1       rjs {
    978   1.1       rjs 	struct sockaddr_in sin4;
    979   1.1       rjs 	struct sockaddr_in6 sin6;
    980   1.1       rjs 	struct sctp_paramhdr *phdr, parm_buf;
    981   1.1       rjs 	struct sctp_tcb *retval;
    982   1.1       rjs 	u_int32_t ptype, plen;
    983   1.1       rjs 
    984   1.1       rjs 	memset(&sin4, 0, sizeof(sin4));
    985   1.1       rjs 	memset(&sin6, 0, sizeof(sin6));
    986   1.1       rjs 	sin4.sin_len = sizeof(sin4);
    987   1.1       rjs 	sin4.sin_family = AF_INET;
    988   1.1       rjs 	sin4.sin_port = sh->src_port;
    989   1.1       rjs 	sin6.sin6_len = sizeof(sin6);
    990   1.1       rjs 	sin6.sin6_family = AF_INET6;
    991   1.1       rjs 	sin6.sin6_port = sh->src_port;
    992   1.1       rjs 
    993   1.1       rjs 	retval = NULL;
    994   1.1       rjs 	offset += sizeof(struct sctp_init_chunk);
    995   1.1       rjs 
    996   1.1       rjs 	phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
    997   1.1       rjs 	while (phdr != NULL) {
    998   1.1       rjs 		/* now we must see if we want the parameter */
    999   1.1       rjs 		ptype = ntohs(phdr->param_type);
   1000   1.1       rjs 		plen = ntohs(phdr->param_length);
   1001   1.1       rjs 		if (plen == 0) {
   1002   1.1       rjs #ifdef SCTP_DEBUG
   1003   1.1       rjs 			if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   1004   1.1       rjs 				printf("sctp_findassociation_special_addr: Impossible length in parameter\n");
   1005   1.1       rjs 			}
   1006   1.1       rjs #endif /* SCTP_DEBUG */
   1007   1.1       rjs 			break;
   1008   1.1       rjs 		}
   1009   1.1       rjs 		if (ptype == SCTP_IPV4_ADDRESS &&
   1010   1.1       rjs 		    plen == sizeof(struct sctp_ipv4addr_param)) {
   1011   1.1       rjs 			/* Get the rest of the address */
   1012   1.1       rjs 			struct sctp_ipv4addr_param ip4_parm, *p4;
   1013   1.1       rjs 
   1014   1.1       rjs 			phdr = sctp_get_next_param(m, offset,
   1015   1.1       rjs 			    (struct sctp_paramhdr *)&ip4_parm, plen);
   1016   1.1       rjs 			if (phdr == NULL) {
   1017   1.1       rjs 				return (NULL);
   1018   1.1       rjs 			}
   1019   1.1       rjs 			p4 = (struct sctp_ipv4addr_param *)phdr;
   1020   1.1       rjs 			memcpy(&sin4.sin_addr, &p4->addr, sizeof(p4->addr));
   1021   1.1       rjs 			/* look it up */
   1022   1.1       rjs 			retval = sctp_findassociation_ep_addr(inp_p,
   1023   1.1       rjs 			    (struct sockaddr *)&sin4, netp, dest, NULL);
   1024   1.1       rjs 			if (retval != NULL) {
   1025   1.1       rjs 				return (retval);
   1026   1.1       rjs 			}
   1027   1.1       rjs 		} else if (ptype == SCTP_IPV6_ADDRESS &&
   1028   1.1       rjs 		    plen == sizeof(struct sctp_ipv6addr_param)) {
   1029   1.1       rjs 			/* Get the rest of the address */
   1030   1.1       rjs 			struct sctp_ipv6addr_param ip6_parm, *p6;
   1031   1.1       rjs 
   1032   1.1       rjs 			phdr = sctp_get_next_param(m, offset,
   1033   1.1       rjs 			    (struct sctp_paramhdr *)&ip6_parm, plen);
   1034   1.1       rjs 			if (phdr == NULL) {
   1035   1.1       rjs 				return (NULL);
   1036   1.1       rjs 			}
   1037   1.1       rjs 			p6 = (struct sctp_ipv6addr_param *)phdr;
   1038   1.1       rjs 			memcpy(&sin6.sin6_addr, &p6->addr, sizeof(p6->addr));
   1039   1.1       rjs 			/* look it up */
   1040   1.1       rjs 			retval = sctp_findassociation_ep_addr(inp_p,
   1041   1.1       rjs 			    (struct sockaddr *)&sin6, netp, dest, NULL);
   1042   1.1       rjs 			if (retval != NULL) {
   1043   1.1       rjs 				return (retval);
   1044   1.1       rjs 			}
   1045   1.1       rjs 		}
   1046   1.1       rjs 		offset += SCTP_SIZE32(plen);
   1047   1.1       rjs 		phdr = sctp_get_next_param(m, offset, &parm_buf,
   1048   1.1       rjs 		    sizeof(parm_buf));
   1049   1.1       rjs 	}
   1050   1.1       rjs 	return (NULL);
   1051   1.1       rjs }
   1052   1.1       rjs 
   1053   1.1       rjs static struct sctp_tcb *
   1054   1.1       rjs sctp_findassoc_by_vtag(struct sockaddr *from, uint32_t vtag,
   1055   1.1       rjs     struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint16_t rport,
   1056   1.1       rjs     uint16_t lport)
   1057   1.1       rjs {
   1058   1.1       rjs 	/*
   1059   1.1       rjs 	 * Use my vtag to hash. If we find it we then verify the source addr
   1060   1.1       rjs 	 * is in the assoc. If all goes well we save a bit on rec of a packet.
   1061   1.1       rjs 	 */
   1062   1.1       rjs 	struct sctpasochead *head;
   1063   1.1       rjs 	struct sctp_nets *net;
   1064   1.1       rjs 	struct sctp_tcb *stcb;
   1065   1.1       rjs 
   1066   1.1       rjs 	SCTP_INP_INFO_RLOCK();
   1067   1.1       rjs 	head = &sctppcbinfo.sctp_asochash[SCTP_PCBHASH_ASOC(vtag,
   1068   1.1       rjs 	    sctppcbinfo.hashasocmark)];
   1069   1.1       rjs 	if (head == NULL) {
   1070   1.1       rjs 		/* invalid vtag */
   1071   1.1       rjs 		SCTP_INP_INFO_RUNLOCK();
   1072   1.1       rjs 		return (NULL);
   1073   1.1       rjs 	}
   1074   1.1       rjs 	LIST_FOREACH(stcb, head, sctp_asocs) {
   1075   1.1       rjs 		SCTP_INP_RLOCK(stcb->sctp_ep);
   1076   1.1       rjs 		SCTP_TCB_LOCK(stcb);
   1077   1.1       rjs 		SCTP_INP_RUNLOCK(stcb->sctp_ep);
   1078   1.1       rjs 		if (stcb->asoc.my_vtag == vtag) {
   1079   1.1       rjs 			/* candidate */
   1080   1.1       rjs 			if (stcb->rport != rport) {
   1081   1.1       rjs 				/*
   1082   1.1       rjs 				 * we could remove this if vtags are unique
   1083   1.1       rjs 				 * across the system.
   1084   1.1       rjs 				 */
   1085   1.1       rjs 				SCTP_TCB_UNLOCK(stcb);
   1086   1.1       rjs 				continue;
   1087   1.1       rjs 			}
   1088   1.1       rjs 			if (stcb->sctp_ep->sctp_lport != lport) {
   1089   1.1       rjs 				/*
   1090   1.1       rjs 				 * we could remove this if vtags are unique
   1091   1.1       rjs 				 * across the system.
   1092   1.1       rjs 				 */
   1093   1.1       rjs 				SCTP_TCB_UNLOCK(stcb);
   1094   1.1       rjs 				continue;
   1095   1.1       rjs 			}
   1096   1.1       rjs 			net = sctp_findnet(stcb, from);
   1097   1.1       rjs 			if (net) {
   1098   1.1       rjs 				/* yep its him. */
   1099   1.1       rjs 				*netp = net;
   1100   1.1       rjs 				sctp_pegs[SCTP_VTAG_EXPR]++;
   1101   1.1       rjs 				*inp_p = stcb->sctp_ep;
   1102   1.1       rjs 				SCTP_INP_INFO_RUNLOCK();
   1103   1.1       rjs 				return (stcb);
   1104   1.1       rjs 			} else {
   1105   1.1       rjs  				/* not him, this should only
   1106   1.1       rjs  				 * happen in rare cases so
   1107   1.1       rjs  				 * I peg it.
   1108   1.1       rjs   				 */
   1109   1.1       rjs  				sctp_pegs[SCTP_VTAG_BOGUS]++;
   1110   1.1       rjs 			}
   1111   1.1       rjs 		}
   1112   1.1       rjs 		SCTP_TCB_UNLOCK(stcb);
   1113   1.1       rjs 	}
   1114   1.1       rjs 	SCTP_INP_INFO_RUNLOCK();
   1115   1.1       rjs 	return (NULL);
   1116   1.1       rjs }
   1117   1.1       rjs 
   1118   1.1       rjs /*
   1119   1.1       rjs  * Find an association with the pointer to the inbound IP packet. This
   1120   1.1       rjs  * can be a IPv4 or IPv6 packet.
   1121   1.1       rjs  */
   1122   1.1       rjs struct sctp_tcb *
   1123   1.1       rjs sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
   1124   1.1       rjs     struct sctphdr *sh, struct sctp_chunkhdr *ch,
   1125   1.1       rjs     struct sctp_inpcb **inp_p, struct sctp_nets **netp)
   1126   1.1       rjs {
   1127   1.1       rjs 	int find_tcp_pool;
   1128   1.1       rjs 	struct ip *iph;
   1129   1.1       rjs 	struct sctp_tcb *retval;
   1130   1.1       rjs 	struct sockaddr_storage to_store, from_store;
   1131   1.1       rjs 	struct sockaddr *to = (struct sockaddr *)&to_store;
   1132   1.1       rjs 	struct sockaddr *from = (struct sockaddr *)&from_store;
   1133   1.1       rjs 	struct sctp_inpcb *inp;
   1134   1.1       rjs 
   1135   1.1       rjs 
   1136   1.1       rjs 	iph = mtod(m, struct ip *);
   1137   1.1       rjs 	if (iph->ip_v == IPVERSION) {
   1138   1.1       rjs 		/* its IPv4 */
   1139   1.1       rjs 		struct sockaddr_in *to4, *from4;
   1140   1.1       rjs 
   1141   1.1       rjs 		to4 = (struct sockaddr_in *)&to_store;
   1142   1.1       rjs 		from4 = (struct sockaddr_in *)&from_store;
   1143   1.1       rjs 		memset(to4, 0, sizeof(*to4));
   1144   1.1       rjs 		memset(from4, 0, sizeof(*from4));
   1145   1.1       rjs 		from4->sin_family = to4->sin_family = AF_INET;
   1146   1.1       rjs 		from4->sin_len = to4->sin_len = sizeof(struct sockaddr_in);
   1147   1.1       rjs 		from4->sin_addr.s_addr  = iph->ip_src.s_addr;
   1148   1.1       rjs 		to4->sin_addr.s_addr = iph->ip_dst.s_addr ;
   1149   1.1       rjs 		from4->sin_port = sh->src_port;
   1150   1.1       rjs 		to4->sin_port = sh->dest_port;
   1151   1.1       rjs 	} else if (iph->ip_v == (IPV6_VERSION >> 4)) {
   1152   1.1       rjs 		/* its IPv6 */
   1153   1.1       rjs 		struct ip6_hdr *ip6;
   1154   1.1       rjs 		struct sockaddr_in6 *to6, *from6;
   1155   1.1       rjs 
   1156   1.1       rjs 		ip6 = mtod(m, struct ip6_hdr *);
   1157   1.1       rjs 		to6 = (struct sockaddr_in6 *)&to_store;
   1158   1.1       rjs 		from6 = (struct sockaddr_in6 *)&from_store;
   1159   1.1       rjs 		memset(to6, 0, sizeof(*to6));
   1160   1.1       rjs 		memset(from6, 0, sizeof(*from6));
   1161   1.1       rjs 		from6->sin6_family = to6->sin6_family = AF_INET6;
   1162   1.1       rjs 		from6->sin6_len = to6->sin6_len = sizeof(struct sockaddr_in6);
   1163   1.1       rjs 		from6->sin6_addr = ip6->ip6_src;
   1164   1.1       rjs 		to6->sin6_addr = ip6->ip6_dst;
   1165   1.1       rjs 		from6->sin6_port = sh->src_port;
   1166   1.1       rjs 		to6->sin6_port = sh->dest_port;
   1167   1.1       rjs 		/* Get the scopes in properly to the sin6 addr's */
   1168   1.1       rjs #if defined(SCTP_BASE_FREEBSD) || defined(__APPLE__)
   1169   1.1       rjs 		/* We probably don't need this operation (jinmei@kame) */
   1170   1.1       rjs 		(void)in6_recoverscope(to6, &to6->sin6_addr, NULL);
   1171   1.1       rjs 		(void)in6_embedscope(&to6->sin6_addr, to6, NULL, NULL);
   1172   1.1       rjs 
   1173   1.1       rjs 		(void)in6_recoverscope(from6, &from6->sin6_addr, NULL);
   1174   1.1       rjs 		(void)in6_embedscope(&from6->sin6_addr, from6, NULL, NULL);
   1175   1.1       rjs #endif
   1176   1.1       rjs 	} else {
   1177   1.1       rjs 		/* Currently not supported. */
   1178   1.1       rjs 		return (NULL);
   1179   1.1       rjs 	}
   1180   1.1       rjs #ifdef SCTP_DEBUG
   1181   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   1182   1.1       rjs 		printf("Looking for port %d address :",
   1183   1.1       rjs 		       ntohs(((struct sockaddr_in *)to)->sin_port));
   1184   1.1       rjs 		sctp_print_address(to);
   1185   1.1       rjs 		printf("From for port %d address :",
   1186   1.1       rjs 		       ntohs(((struct sockaddr_in *)from)->sin_port));
   1187   1.1       rjs 		sctp_print_address(from);
   1188   1.1       rjs 	}
   1189   1.1       rjs #endif
   1190   1.1       rjs 
   1191   1.1       rjs 	if (sh->v_tag) {
   1192   1.1       rjs 		/* we only go down this path if vtag is non-zero */
   1193   1.1       rjs 		retval = sctp_findassoc_by_vtag(from, ntohl(sh->v_tag),
   1194   1.1       rjs 		    inp_p, netp, sh->src_port, sh->dest_port);
   1195   1.1       rjs 		if (retval) {
   1196   1.1       rjs 			return (retval);
   1197   1.1       rjs 		}
   1198   1.1       rjs 	}
   1199   1.1       rjs 	find_tcp_pool = 0;
   1200   1.1       rjs 	if ((ch->chunk_type != SCTP_INITIATION) &&
   1201   1.1       rjs 	    (ch->chunk_type != SCTP_INITIATION_ACK) &&
   1202   1.1       rjs 	    (ch->chunk_type != SCTP_COOKIE_ACK) &&
   1203   1.1       rjs 	    (ch->chunk_type != SCTP_COOKIE_ECHO)) {
   1204   1.1       rjs 		/* Other chunk types go to the tcp pool. */
   1205   1.1       rjs 		find_tcp_pool = 1;
   1206   1.1       rjs 	}
   1207   1.1       rjs 	if (inp_p) {
   1208   1.1       rjs 		retval = sctp_findassociation_addr_sa(to, from, inp_p, netp,
   1209   1.1       rjs 		    find_tcp_pool);
   1210   1.1       rjs 		inp = *inp_p;
   1211   1.1       rjs 	} else {
   1212   1.1       rjs 		retval = sctp_findassociation_addr_sa(to, from, &inp, netp,
   1213   1.1       rjs 		    find_tcp_pool);
   1214   1.1       rjs 	}
   1215   1.1       rjs #ifdef SCTP_DEBUG
   1216   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   1217   1.1       rjs 		printf("retval:%p inp:%p\n", retval, inp);
   1218   1.1       rjs 	}
   1219   1.1       rjs #endif
   1220   1.1       rjs 	if (retval == NULL && inp) {
   1221   1.1       rjs 		/* Found a EP but not this address */
   1222   1.1       rjs #ifdef SCTP_DEBUG
   1223   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   1224   1.1       rjs 			printf("Found endpoint %p but no asoc - ep state:%x\n",
   1225   1.1       rjs 			    inp, inp->sctp_flags);
   1226   1.1       rjs 		}
   1227   1.1       rjs #endif
   1228   1.1       rjs 		if ((ch->chunk_type == SCTP_INITIATION) ||
   1229   1.1       rjs 		    (ch->chunk_type == SCTP_INITIATION_ACK)) {
   1230   1.1       rjs 			/*
   1231   1.1       rjs 			 * special hook, we do NOT return linp or an
   1232   1.1       rjs 			 * association that is linked to an existing
   1233   1.1       rjs 			 * association that is under the TCP pool (i.e. no
   1234   1.1       rjs 			 * listener exists). The endpoint finding routine
   1235   1.1       rjs 			 * will always find a listner before examining the
   1236   1.1       rjs 			 * TCP pool.
   1237   1.1       rjs 			 */
   1238   1.1       rjs 			if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) {
   1239   1.1       rjs #ifdef SCTP_DEBUG
   1240   1.1       rjs 				if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   1241   1.1       rjs 					printf("Gak, its in the TCP pool... return NULL");
   1242   1.1       rjs 				}
   1243   1.1       rjs #endif
   1244   1.1       rjs 				if (inp_p) {
   1245   1.1       rjs 					*inp_p = NULL;
   1246   1.1       rjs 				}
   1247   1.1       rjs 				return (NULL);
   1248   1.1       rjs 			}
   1249   1.1       rjs #ifdef SCTP_DEBUG
   1250   1.1       rjs 			if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   1251   1.1       rjs 				printf("Now doing SPECIAL find\n");
   1252   1.1       rjs 			}
   1253   1.1       rjs #endif
   1254   1.1       rjs 			retval = sctp_findassociation_special_addr(m, iphlen,
   1255   1.1       rjs 			    offset, sh, inp_p, netp, to);
   1256   1.1       rjs 		}
   1257   1.1       rjs 	}
   1258   1.1       rjs #ifdef SCTP_DEBUG
   1259   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   1260   1.1       rjs 	    printf("retval is %p\n", retval);
   1261   1.1       rjs 	}
   1262   1.1       rjs #endif
   1263   1.1       rjs 	return (retval);
   1264   1.1       rjs }
   1265   1.1       rjs 
   1266   1.1       rjs extern int sctp_max_burst_default;
   1267   1.1       rjs 
   1268   1.1       rjs extern unsigned int sctp_delayed_sack_time_default;
   1269   1.1       rjs extern unsigned int sctp_heartbeat_interval_default;
   1270   1.1       rjs extern unsigned int sctp_pmtu_raise_time_default;
   1271   1.1       rjs extern unsigned int sctp_shutdown_guard_time_default;
   1272   1.1       rjs extern unsigned int sctp_secret_lifetime_default;
   1273   1.1       rjs 
   1274   1.1       rjs extern unsigned int sctp_rto_max_default;
   1275   1.1       rjs extern unsigned int sctp_rto_min_default;
   1276   1.1       rjs extern unsigned int sctp_rto_initial_default;
   1277   1.1       rjs extern unsigned int sctp_init_rto_max_default;
   1278   1.1       rjs extern unsigned int sctp_valid_cookie_life_default;
   1279   1.1       rjs extern unsigned int sctp_init_rtx_max_default;
   1280   1.1       rjs extern unsigned int sctp_assoc_rtx_max_default;
   1281   1.1       rjs extern unsigned int sctp_path_rtx_max_default;
   1282   1.1       rjs extern unsigned int sctp_nr_outgoing_streams_default;
   1283   1.1       rjs 
   1284   1.1       rjs /*
   1285   1.1       rjs  * allocate a sctp_inpcb and setup a temporary binding to a port/all
   1286   1.1       rjs  * addresses. This way if we don't get a bind we by default pick a ephemeral
   1287   1.1       rjs  * port with all addresses bound.
   1288   1.1       rjs  */
   1289   1.1       rjs int
   1290   1.1       rjs sctp_inpcb_alloc(struct socket *so)
   1291   1.1       rjs {
   1292   1.1       rjs 	/*
   1293   1.1       rjs 	 * we get called when a new endpoint starts up. We need to allocate
   1294   1.1       rjs 	 * the sctp_inpcb structure from the zone and init it. Mark it as
   1295   1.1       rjs 	 * unbound and find a port that we can use as an ephemeral with
   1296   1.1       rjs 	 * INADDR_ANY. If the user binds later no problem we can then add
   1297   1.1       rjs 	 * in the specific addresses. And setup the default parameters for
   1298   1.1       rjs 	 * the EP.
   1299   1.1       rjs 	 */
   1300   1.1       rjs 	int i, error;
   1301  1.11       rjs 	struct sctp_inpcb *inp;
   1302  1.11       rjs #ifdef DEBUG
   1303  1.11       rjs 	struct sctp_inpcb *n_inp;
   1304  1.11       rjs #endif
   1305  1.15       rjs #ifdef IPSEC
   1306  1.15       rjs 	struct inpcbpolicy *pcb_sp = NULL;
   1307  1.15       rjs #endif
   1308   1.1       rjs 	struct sctp_pcb *m;
   1309   1.1       rjs 	struct timeval time;
   1310   1.1       rjs 
   1311   1.1       rjs 	error = 0;
   1312   1.1       rjs 
   1313   1.1       rjs         /* Hack alert:
   1314   1.1       rjs 	 *
   1315   1.1       rjs 	 * This code audits the entire INP list to see if
   1316   1.1       rjs 	 * any ep's that are in the GONE state are now
   1317   1.1       rjs 	 * all free. This should not happen really since when
   1318   1.1       rjs 	 * the last association if freed we should end up deleting
   1319   1.1       rjs 	 * the inpcb. This code including the locks should
   1320   1.1       rjs 	 * be taken out ... since the last set of fixes I
   1321   1.1       rjs 	 * have not seen the "Found a GONE on list" has not
   1322   1.1       rjs 	 * came out. But i am paranoid and we will leave this
   1323  1.24    andvar 	 * in at the cost of efficiency on allocation of PCB's.
   1324   1.1       rjs 	 * Probably we should move this to the invariant
   1325   1.1       rjs 	 * compile options
   1326   1.1       rjs 	 */
   1327  1.11       rjs #ifdef DEBUG
   1328   1.1       rjs 	SCTP_INP_INFO_RLOCK();
   1329   1.1       rjs 	inp = LIST_FIRST(&sctppcbinfo.listhead);
   1330   1.1       rjs 	while (inp) {
   1331   1.1       rjs 		n_inp = LIST_NEXT(inp, sctp_list);
   1332   1.1       rjs 		if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
   1333   1.1       rjs 			if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
   1334   1.1       rjs 				/* finish the job now */
   1335   1.1       rjs 				printf("Found a GONE on list\n");
   1336   1.1       rjs 				SCTP_INP_INFO_RUNLOCK();
   1337   1.1       rjs 				sctp_inpcb_free(inp, 1);
   1338   1.1       rjs 				SCTP_INP_INFO_RLOCK();
   1339   1.1       rjs 			}
   1340   1.1       rjs 		}
   1341   1.1       rjs 		inp = n_inp;
   1342   1.1       rjs 	}
   1343   1.1       rjs 	SCTP_INP_INFO_RUNLOCK();
   1344  1.11       rjs #endif /* DEBUG */
   1345   1.1       rjs 
   1346   1.1       rjs 	SCTP_INP_INFO_WLOCK();
   1347   1.1       rjs 	inp = (struct sctp_inpcb *)SCTP_ZONE_GET(sctppcbinfo.ipi_zone_ep);
   1348   1.1       rjs 	if (inp == NULL) {
   1349   1.1       rjs 		printf("Out of SCTP-INPCB structures - no resources\n");
   1350   1.1       rjs 		SCTP_INP_INFO_WUNLOCK();
   1351   1.1       rjs 		return (ENOBUFS);
   1352   1.1       rjs 	}
   1353   1.1       rjs 
   1354   1.1       rjs 	/* zap it */
   1355   1.1       rjs 	memset(inp, 0, sizeof(*inp));
   1356   1.1       rjs 
   1357   1.1       rjs 	/* setup socket pointers */
   1358   1.1       rjs 	inp->sctp_socket = so;
   1359   1.1       rjs 
   1360   1.1       rjs 	/* setup inpcb socket too */
   1361   1.1       rjs 	inp->ip_inp.inp.inp_socket = so;
   1362   1.1       rjs 	inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT;
   1363   1.1       rjs #ifdef IPSEC
   1364  1.15       rjs 	if (ipsec_enabled) {
   1365   1.1       rjs 		error = ipsec_init_pcbpolicy(so, &pcb_sp);
   1366  1.15       rjs 		if (error != 0) {
   1367  1.15       rjs 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp);
   1368  1.15       rjs 			SCTP_INP_INFO_WUNLOCK();
   1369  1.15       rjs 			return error;
   1370  1.15       rjs 		}
   1371   1.1       rjs 		/* Arrange to share the policy */
   1372   1.1       rjs 		inp->ip_inp.inp.inp_sp = pcb_sp;
   1373  1.15       rjs 		pcb_sp->sp_inph = (struct inpcb_hdr *)inp;
   1374   1.1       rjs 	}
   1375   1.1       rjs #endif /* IPSEC */
   1376   1.1       rjs 	sctppcbinfo.ipi_count_ep++;
   1377   1.1       rjs 	inp->inp_ip_ttl = ip_defttl;
   1378   1.1       rjs 	inp->inp_ip_tos = 0;
   1379   1.1       rjs 
   1380   1.1       rjs 	so->so_pcb = (void *)inp;
   1381   1.1       rjs 
   1382   1.1       rjs 	if ((so->so_type == SOCK_DGRAM) ||
   1383   1.1       rjs 	    (so->so_type == SOCK_SEQPACKET)) {
   1384   1.1       rjs 		/* UDP style socket */
   1385   1.1       rjs 		inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |
   1386   1.1       rjs 		    SCTP_PCB_FLAGS_UNBOUND);
   1387   1.1       rjs 		inp->sctp_flags |= (SCTP_PCB_FLAGS_RECVDATAIOEVNT);
   1388   1.1       rjs 		/* Be sure it is NON-BLOCKING IO for UDP */
   1389   1.1       rjs 		/*so->so_state |= SS_NBIO;*/
   1390   1.1       rjs 	} else if (so->so_type == SOCK_STREAM) {
   1391   1.1       rjs 		/* TCP style socket */
   1392   1.1       rjs 		inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE |
   1393   1.1       rjs 		    SCTP_PCB_FLAGS_UNBOUND);
   1394   1.1       rjs 		inp->sctp_flags |= (SCTP_PCB_FLAGS_RECVDATAIOEVNT);
   1395   1.1       rjs 		/* Be sure we have blocking IO bu default */
   1396   1.1       rjs 		so->so_state &= ~SS_NBIO;
   1397   1.1       rjs 	} else {
   1398   1.1       rjs 		/*
   1399   1.1       rjs 		 * unsupported socket type (RAW, etc)- in case we missed
   1400   1.1       rjs 		 * it in protosw
   1401   1.1       rjs 		 */
   1402   1.1       rjs 		SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp);
   1403   1.1       rjs 		SCTP_INP_INFO_WUNLOCK();
   1404   1.1       rjs 		return (EOPNOTSUPP);
   1405   1.1       rjs 	}
   1406   1.1       rjs 	inp->sctp_tcbhash = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_hash);
   1407   1.1       rjs 	if (inp->sctp_tcbhash == NULL) {
   1408   1.1       rjs 		printf("Out of SCTP-INPCB->hashinit - no resources\n");
   1409   1.1       rjs 		SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp);
   1410   1.1       rjs 		SCTP_INP_INFO_WUNLOCK();
   1411   1.1       rjs 		return (ENOBUFS);
   1412   1.1       rjs 	} else {
   1413   1.1       rjs 		for (i = 0; i < sctp_pcbtblsize; i++)
   1414   1.1       rjs 			LIST_INIT(&inp->sctp_tcbhash[i]);
   1415   1.1       rjs 		for (i = 1; i < sctp_pcbtblsize; i <<= 1)
   1416   1.1       rjs 			continue;
   1417   1.1       rjs 		inp->sctp_hashmark = i - 1;
   1418   1.1       rjs 	}
   1419   1.1       rjs         /* LOCK init's */
   1420   1.1       rjs 	SCTP_INP_LOCK_INIT(inp);
   1421   1.1       rjs 	SCTP_ASOC_CREATE_LOCK_INIT(inp);
   1422   1.1       rjs 	/* lock the new ep */
   1423   1.1       rjs 	SCTP_INP_WLOCK(inp);
   1424   1.1       rjs 
   1425   1.1       rjs 	/* add it to the info area */
   1426   1.1       rjs 	LIST_INSERT_HEAD(&sctppcbinfo.listhead, inp, sctp_list);
   1427   1.1       rjs 	SCTP_INP_INFO_WUNLOCK();
   1428   1.1       rjs 
   1429   1.1       rjs 	LIST_INIT(&inp->sctp_addr_list);
   1430   1.1       rjs 	LIST_INIT(&inp->sctp_asoc_list);
   1431   1.1       rjs 	TAILQ_INIT(&inp->sctp_queue_list);
   1432   1.1       rjs 	/* Init the timer structure for signature change */
   1433   1.1       rjs 	callout_init(&inp->sctp_ep.signature_change.timer, 0);
   1434   1.1       rjs 	inp->sctp_ep.signature_change.type = SCTP_TIMER_TYPE_NEWCOOKIE;
   1435   1.1       rjs 
   1436   1.1       rjs 	/* now init the actual endpoint default data */
   1437   1.1       rjs 	m = &inp->sctp_ep;
   1438   1.1       rjs 
   1439   1.1       rjs 	/* setup the base timeout information */
   1440   1.1       rjs 	m->sctp_timeoutticks[SCTP_TIMER_SEND] = SEC_TO_TICKS(SCTP_SEND_SEC); /* needed ? */
   1441   1.1       rjs 	m->sctp_timeoutticks[SCTP_TIMER_INIT] = SEC_TO_TICKS(SCTP_INIT_SEC); /* needed ? */
   1442   1.1       rjs 	m->sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(sctp_delayed_sack_time_default);
   1443   1.1       rjs 	m->sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_heartbeat_interval_default; /* this is in MSEC */
   1444   1.1       rjs 	m->sctp_timeoutticks[SCTP_TIMER_PMTU] = SEC_TO_TICKS(sctp_pmtu_raise_time_default);
   1445   1.1       rjs 	m->sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] = SEC_TO_TICKS(sctp_shutdown_guard_time_default);
   1446   1.1       rjs 	m->sctp_timeoutticks[SCTP_TIMER_SIGNATURE] = SEC_TO_TICKS(sctp_secret_lifetime_default);
   1447   1.1       rjs 	/* all max/min max are in ms */
   1448   1.1       rjs 	m->sctp_maxrto = sctp_rto_max_default;
   1449   1.1       rjs 	m->sctp_minrto = sctp_rto_min_default;
   1450   1.1       rjs 	m->initial_rto = sctp_rto_initial_default;
   1451   1.1       rjs 	m->initial_init_rto_max = sctp_init_rto_max_default;
   1452   1.1       rjs 
   1453   1.1       rjs 	m->max_open_streams_intome = MAX_SCTP_STREAMS;
   1454   1.1       rjs 
   1455   1.1       rjs 	m->max_init_times = sctp_init_rtx_max_default;
   1456   1.1       rjs 	m->max_send_times = sctp_assoc_rtx_max_default;
   1457   1.1       rjs 	m->def_net_failure = sctp_path_rtx_max_default;
   1458   1.1       rjs 	m->sctp_sws_sender = SCTP_SWS_SENDER_DEF;
   1459   1.1       rjs 	m->sctp_sws_receiver = SCTP_SWS_RECEIVER_DEF;
   1460   1.1       rjs 	m->max_burst = sctp_max_burst_default;
   1461   1.1       rjs 	/* number of streams to pre-open on a association */
   1462   1.1       rjs 	m->pre_open_stream_count = sctp_nr_outgoing_streams_default;
   1463   1.1       rjs 
   1464   1.1       rjs 	/* Add adaption cookie */
   1465   1.1       rjs 	m->adaption_layer_indicator = 0x504C5253;
   1466   1.1       rjs 
   1467   1.1       rjs 	/* Minimum cookie size */
   1468   1.1       rjs 	m->size_of_a_cookie = (sizeof(struct sctp_init_msg) * 2) +
   1469   1.1       rjs 		sizeof(struct sctp_state_cookie);
   1470   1.1       rjs 	m->size_of_a_cookie += SCTP_SIGNATURE_SIZE;
   1471   1.1       rjs 
   1472   1.1       rjs 	/* Setup the initial secret */
   1473   1.1       rjs 	SCTP_GETTIME_TIMEVAL(&time);
   1474   1.1       rjs 	m->time_of_secret_change = time.tv_sec;
   1475   1.1       rjs 
   1476   1.1       rjs 	for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) {
   1477   1.1       rjs 		m->secret_key[0][i] = sctp_select_initial_TSN(m);
   1478   1.1       rjs 	}
   1479   1.1       rjs 	sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL);
   1480   1.1       rjs 
   1481   1.1       rjs 	/* How long is a cookie good for ? */
   1482   1.1       rjs 	m->def_cookie_life = sctp_valid_cookie_life_default;
   1483   1.1       rjs 	SCTP_INP_WUNLOCK(inp);
   1484   1.1       rjs 	return (error);
   1485   1.1       rjs }
   1486   1.1       rjs 
   1487   1.1       rjs 
   1488   1.1       rjs void
   1489   1.1       rjs sctp_move_pcb_and_assoc(struct sctp_inpcb *old_inp, struct sctp_inpcb *new_inp,
   1490   1.1       rjs     struct sctp_tcb *stcb)
   1491   1.1       rjs {
   1492   1.1       rjs 	uint16_t lport, rport;
   1493   1.1       rjs 	struct sctppcbhead *head;
   1494   1.1       rjs 	struct sctp_laddr *laddr, *oladdr;
   1495   1.1       rjs 
   1496   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   1497   1.1       rjs 	SCTP_INP_INFO_WLOCK();
   1498   1.1       rjs 	SCTP_INP_WLOCK(old_inp);
   1499   1.1       rjs 	SCTP_INP_WLOCK(new_inp);
   1500   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   1501   1.1       rjs 
   1502   1.1       rjs 	new_inp->sctp_ep.time_of_secret_change =
   1503   1.1       rjs 	    old_inp->sctp_ep.time_of_secret_change;
   1504   1.1       rjs 	memcpy(new_inp->sctp_ep.secret_key, old_inp->sctp_ep.secret_key,
   1505   1.1       rjs 	    sizeof(old_inp->sctp_ep.secret_key));
   1506   1.1       rjs 	new_inp->sctp_ep.current_secret_number =
   1507   1.1       rjs 	    old_inp->sctp_ep.current_secret_number;
   1508   1.1       rjs 	new_inp->sctp_ep.last_secret_number =
   1509   1.1       rjs 	    old_inp->sctp_ep.last_secret_number;
   1510   1.1       rjs 	new_inp->sctp_ep.size_of_a_cookie = old_inp->sctp_ep.size_of_a_cookie;
   1511   1.1       rjs 
   1512   1.1       rjs 	/* Copy the port across */
   1513   1.1       rjs 	lport = new_inp->sctp_lport = old_inp->sctp_lport;
   1514   1.1       rjs 	rport = stcb->rport;
   1515   1.1       rjs 	/* Pull the tcb from the old association */
   1516   1.1       rjs 	LIST_REMOVE(stcb, sctp_tcbhash);
   1517   1.1       rjs 	LIST_REMOVE(stcb, sctp_tcblist);
   1518   1.1       rjs 
   1519   1.1       rjs 	/* Now insert the new_inp into the TCP connected hash */
   1520   1.1       rjs 	head = &sctppcbinfo.sctp_tcpephash[SCTP_PCBHASH_ALLADDR((lport + rport),
   1521   1.1       rjs 	    sctppcbinfo.hashtcpmark)];
   1522   1.1       rjs 
   1523   1.1       rjs 	LIST_INSERT_HEAD(head, new_inp, sctp_hash);
   1524   1.1       rjs 
   1525   1.1       rjs 	/* Now move the tcb into the endpoint list */
   1526   1.1       rjs 	LIST_INSERT_HEAD(&new_inp->sctp_asoc_list, stcb, sctp_tcblist);
   1527   1.1       rjs 	/*
   1528   1.1       rjs 	 * Question, do we even need to worry about the ep-hash since
   1529   1.1       rjs 	 * we only have one connection? Probably not :> so lets
   1530   1.1       rjs 	 * get rid of it and not suck up any kernel memory in that.
   1531   1.1       rjs 	 */
   1532   1.1       rjs 	SCTP_INP_INFO_WUNLOCK();
   1533   1.1       rjs 	stcb->sctp_socket = new_inp->sctp_socket;
   1534   1.1       rjs 	stcb->sctp_ep = new_inp;
   1535   1.1       rjs 	if (new_inp->sctp_tcbhash != NULL) {
   1536   1.1       rjs 		SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_hash,
   1537   1.1       rjs 			      new_inp->sctp_tcbhash);
   1538   1.1       rjs 		new_inp->sctp_tcbhash = NULL;
   1539   1.1       rjs 	}
   1540   1.1       rjs 	if ((new_inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
   1541   1.1       rjs 		/* Subset bound, so copy in the laddr list from the old_inp */
   1542   1.1       rjs 		LIST_FOREACH(oladdr, &old_inp->sctp_addr_list, sctp_nxt_addr) {
   1543   1.1       rjs 			laddr = (struct sctp_laddr *)SCTP_ZONE_GET(
   1544   1.1       rjs 			    sctppcbinfo.ipi_zone_laddr);
   1545   1.1       rjs 			if (laddr == NULL) {
   1546   1.1       rjs 				/*
   1547   1.1       rjs 				 * Gak, what can we do? This assoc is really
   1548   1.1       rjs 				 * HOSED. We probably should send an abort
   1549   1.1       rjs 				 * here.
   1550   1.1       rjs 				 */
   1551   1.1       rjs #ifdef SCTP_DEBUG
   1552   1.1       rjs 				if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   1553   1.1       rjs 					printf("Association hosed in TCP model, out of laddr memory\n");
   1554   1.1       rjs 				}
   1555   1.1       rjs #endif /* SCTP_DEBUG */
   1556   1.1       rjs 				continue;
   1557   1.1       rjs 			}
   1558   1.1       rjs 			sctppcbinfo.ipi_count_laddr++;
   1559   1.1       rjs 			sctppcbinfo.ipi_gencnt_laddr++;
   1560   1.1       rjs 			memset(laddr, 0, sizeof(*laddr));
   1561   1.1       rjs 			laddr->ifa = oladdr->ifa;
   1562   1.1       rjs 			LIST_INSERT_HEAD(&new_inp->sctp_addr_list, laddr,
   1563   1.1       rjs 			    sctp_nxt_addr);
   1564   1.1       rjs 			new_inp->laddr_count++;
   1565   1.1       rjs 		}
   1566   1.1       rjs 	}
   1567   1.1       rjs 	SCTP_INP_WUNLOCK(new_inp);
   1568   1.1       rjs 	SCTP_INP_WUNLOCK(old_inp);
   1569   1.1       rjs }
   1570   1.1       rjs 
   1571   1.1       rjs static int
   1572   1.1       rjs sctp_isport_inuse(struct sctp_inpcb *inp, uint16_t lport)
   1573   1.1       rjs {
   1574   1.1       rjs 	struct sctppcbhead *head;
   1575   1.1       rjs 	struct sctp_inpcb *t_inp;
   1576   1.1       rjs 
   1577   1.1       rjs 	head = &sctppcbinfo.sctp_ephash[SCTP_PCBHASH_ALLADDR(lport,
   1578   1.1       rjs 	    sctppcbinfo.hashmark)];
   1579   1.1       rjs 	LIST_FOREACH(t_inp, head, sctp_hash) {
   1580   1.1       rjs 		if (t_inp->sctp_lport != lport) {
   1581   1.1       rjs 			continue;
   1582   1.1       rjs 		}
   1583   1.1       rjs 		/* This one is in use. */
   1584   1.1       rjs 		/* check the v6/v4 binding issue */
   1585   1.1       rjs 		if ((t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
   1586  1.12       rjs 		    (((struct in6pcb *)t_inp)->in6p_flags & IN6P_IPV6_V6ONLY)) {
   1587   1.1       rjs 			if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
   1588   1.1       rjs 				/* collision in V6 space */
   1589   1.1       rjs 				return (1);
   1590   1.1       rjs 			} else {
   1591   1.1       rjs 				/* inp is BOUND_V4 no conflict */
   1592   1.1       rjs 				continue;
   1593   1.1       rjs 			}
   1594   1.1       rjs 		} else if (t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
   1595   1.1       rjs 			/* t_inp is bound v4 and v6, conflict always */
   1596   1.1       rjs 			return (1);
   1597   1.1       rjs 		} else {
   1598   1.1       rjs 			/* t_inp is bound only V4 */
   1599   1.1       rjs 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
   1600   1.1       rjs 			    (((struct in6pcb *)inp)->in6p_flags & IN6P_IPV6_V6ONLY)
   1601   1.1       rjs 				) {
   1602   1.1       rjs 				/* no conflict */
   1603   1.1       rjs 				continue;
   1604   1.1       rjs 			}
   1605   1.1       rjs 			/* else fall through to conflict */
   1606   1.1       rjs 		}
   1607   1.1       rjs 		return (1);
   1608   1.1       rjs 	}
   1609   1.1       rjs 	return (0);
   1610   1.1       rjs }
   1611   1.1       rjs 
   1612   1.1       rjs int
   1613   1.1       rjs sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, struct lwp *l)
   1614   1.1       rjs {
   1615   1.1       rjs 	/* bind a ep to a socket address */
   1616   1.1       rjs 	struct sctppcbhead *head;
   1617   1.1       rjs 	struct sctp_inpcb *inp, *inp_tmp;
   1618   1.1       rjs 	int bindall;
   1619   1.1       rjs 	uint16_t lport;
   1620   1.1       rjs 	int error;
   1621   1.1       rjs 
   1622   1.1       rjs 	lport = 0;
   1623   1.1       rjs 	error = 0;
   1624   1.1       rjs 	bindall = 1;
   1625   1.1       rjs 	inp = (struct sctp_inpcb *)so->so_pcb;
   1626   1.1       rjs #ifdef SCTP_DEBUG
   1627   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   1628   1.1       rjs 		if (addr) {
   1629   1.1       rjs 			printf("Bind called port:%d\n",
   1630   1.1       rjs 			       ntohs(((struct sockaddr_in *)addr)->sin_port));
   1631   1.1       rjs 			printf("Addr :");
   1632   1.1       rjs 			sctp_print_address(addr);
   1633   1.1       rjs 		}
   1634   1.1       rjs 	}
   1635   1.1       rjs #endif /* SCTP_DEBUG */
   1636   1.1       rjs 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) {
   1637   1.1       rjs 		/* already did a bind, subsequent binds NOT allowed ! */
   1638   1.1       rjs 		return (EINVAL);
   1639   1.1       rjs 	}
   1640   1.1       rjs 
   1641   1.1       rjs 	if (addr != NULL) {
   1642   1.1       rjs 		if (addr->sa_family == AF_INET) {
   1643   1.1       rjs 			struct sockaddr_in *sin;
   1644   1.1       rjs 
   1645   1.1       rjs 			/* IPV6_V6ONLY socket? */
   1646   1.1       rjs 			if (((struct in6pcb *)inp)->in6p_flags & IN6P_IPV6_V6ONLY) {
   1647   1.1       rjs 				return (EINVAL);
   1648   1.1       rjs 			}
   1649   1.1       rjs 
   1650   1.1       rjs 			if (addr->sa_len != sizeof(*sin))
   1651   1.1       rjs 				return (EINVAL);
   1652   1.1       rjs 
   1653   1.1       rjs 			sin = (struct sockaddr_in *)addr;
   1654   1.1       rjs 			lport = sin->sin_port;
   1655   1.1       rjs 
   1656   1.1       rjs 			if (sin->sin_addr.s_addr != INADDR_ANY) {
   1657   1.1       rjs 				bindall = 0;
   1658   1.1       rjs 			}
   1659  1.15       rjs #ifdef IPSEC
   1660  1.15       rjs 			inp->ip_inp.inp.inp_af = AF_INET;
   1661  1.15       rjs #endif
   1662   1.1       rjs 		} else if (addr->sa_family == AF_INET6) {
   1663   1.1       rjs 			/* Only for pure IPv6 Address. (No IPv4 Mapped!) */
   1664   1.1       rjs 			struct sockaddr_in6 *sin6;
   1665   1.1       rjs 
   1666   1.1       rjs 			sin6 = (struct sockaddr_in6 *)addr;
   1667   1.1       rjs 
   1668   1.1       rjs 			if (addr->sa_len != sizeof(*sin6))
   1669   1.1       rjs 				return (EINVAL);
   1670   1.1       rjs 
   1671   1.1       rjs 			lport = sin6->sin6_port;
   1672   1.1       rjs 			if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
   1673   1.1       rjs 				bindall = 0;
   1674   1.1       rjs 				/* KAME hack: embed scopeid */
   1675   1.1       rjs 				error = sa6_embedscope(sin6, ip6_use_defzone);
   1676   1.1       rjs 				if (error != 0)
   1677   1.1       rjs 					return (error);
   1678   1.1       rjs 			}
   1679   1.1       rjs #ifndef SCOPEDROUTING
   1680   1.1       rjs 			/* this must be cleared for ifa_ifwithaddr() */
   1681   1.1       rjs 			sin6->sin6_scope_id = 0;
   1682   1.1       rjs #endif /* SCOPEDROUTING */
   1683  1.15       rjs #ifdef IPSEC
   1684  1.15       rjs 			inp->ip_inp.inp.inp_af = AF_INET6;
   1685  1.15       rjs #endif
   1686   1.1       rjs 		} else {
   1687   1.1       rjs 			return (EAFNOSUPPORT);
   1688   1.1       rjs 		}
   1689  1.15       rjs #ifdef IPSEC
   1690  1.15       rjs 		if (ipsec_enabled) {
   1691  1.15       rjs 			inp->ip_inp.inp.inp_socket = so;
   1692  1.15       rjs 			error = ipsec_init_pcbpolicy(so, &inp->ip_inp.inp.inp_sp);
   1693  1.15       rjs 			if (error != 0)
   1694  1.15       rjs 				return (error);
   1695  1.15       rjs 			inp->ip_inp.inp.inp_sp->sp_inph = (struct inpcb_hdr *)inp;
   1696  1.15       rjs 		}
   1697  1.15       rjs #endif
   1698   1.1       rjs 	}
   1699   1.1       rjs 	SCTP_INP_INFO_WLOCK();
   1700   1.1       rjs #ifdef SCTP_DEBUG
   1701   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   1702   1.1       rjs 		printf("sctp_inpcb_bind: after SCTP_INP_INFO_WLOCK\n");
   1703   1.1       rjs 	}
   1704   1.1       rjs #endif /* SCTP_DEBUG */
   1705   1.1       rjs 	SCTP_INP_WLOCK(inp);
   1706   1.1       rjs 	/* increase our count due to the unlock we do */
   1707   1.1       rjs 	SCTP_INP_INCR_REF(inp);
   1708   1.1       rjs 	if (lport) {
   1709   1.1       rjs 		enum kauth_network_req req;
   1710   1.1       rjs 		/*
   1711   1.1       rjs 		 * Did the caller specify a port? if so we must see if a
   1712   1.1       rjs 		 * ep already has this one bound.
   1713   1.1       rjs 		 */
   1714   1.1       rjs 		if (ntohs(lport) < IPPORT_RESERVED)
   1715   1.1       rjs 			req = KAUTH_REQ_NETWORK_BIND_PRIVPORT;
   1716   1.1       rjs 		else
   1717   1.1       rjs 			req = KAUTH_REQ_NETWORK_BIND_PORT;
   1718   1.1       rjs 
   1719   1.1       rjs 		error = kauth_authorize_network(l->l_cred, KAUTH_NETWORK_BIND,
   1720   1.1       rjs 		    req, so, addr, NULL);
   1721   1.1       rjs 		if (error) {
   1722   1.1       rjs 			SCTP_INP_DECR_REF(inp);
   1723   1.1       rjs 			SCTP_INP_WUNLOCK(inp);
   1724   1.1       rjs 			SCTP_INP_INFO_WUNLOCK();
   1725   1.1       rjs 			return (EACCES);
   1726   1.1       rjs 		}
   1727   1.1       rjs 		SCTP_INP_WUNLOCK(inp);
   1728   1.1       rjs 		inp_tmp = sctp_pcb_findep(addr, 0, 1);
   1729   1.1       rjs 		if (inp_tmp != NULL) {
   1730   1.1       rjs 			/* lock guy returned and lower count
   1731   1.1       rjs 			 * note that we are not bound so inp_tmp
   1732   1.1       rjs 			 * should NEVER be inp. And it is this
   1733   1.1       rjs 			 * inp (inp_tmp) that gets the reference
   1734   1.1       rjs 			 * bump, so we must lower it.
   1735   1.1       rjs 			 */
   1736   1.1       rjs 			SCTP_INP_WLOCK(inp_tmp);
   1737   1.1       rjs 			SCTP_INP_DECR_REF(inp_tmp);
   1738   1.1       rjs 			SCTP_INP_WUNLOCK(inp_tmp);
   1739   1.1       rjs 
   1740   1.1       rjs 			/* unlock info */
   1741   1.1       rjs 			SCTP_INP_INFO_WUNLOCK();
   1742  1.18  christos 			return EADDRINUSE;
   1743   1.1       rjs 		}
   1744   1.1       rjs 		SCTP_INP_WLOCK(inp);
   1745   1.1       rjs 		if (bindall) {
   1746   1.1       rjs 			/* verify that no lport is not used by a singleton */
   1747   1.1       rjs 			if (sctp_isport_inuse(inp, lport)) {
   1748   1.1       rjs 				/* Sorry someone already has this one bound */
   1749   1.1       rjs 				SCTP_INP_DECR_REF(inp);
   1750   1.1       rjs 				SCTP_INP_WUNLOCK(inp);
   1751   1.1       rjs 				SCTP_INP_INFO_WUNLOCK();
   1752  1.18  christos 				return EADDRINUSE;
   1753   1.1       rjs 			}
   1754   1.1       rjs 		}
   1755   1.1       rjs 	} else {
   1756   1.1       rjs 		/*
   1757   1.1       rjs 		 * get any port but lets make sure no one has any address
   1758   1.1       rjs 		 * with this port bound
   1759   1.1       rjs 		 */
   1760   1.1       rjs 
   1761   1.1       rjs 		/*
   1762   1.1       rjs 		 * setup the inp to the top (I could use the union but this
   1763   1.1       rjs 		 * is just as easy
   1764   1.1       rjs 		 */
   1765   1.1       rjs 		uint32_t port_guess;
   1766   1.1       rjs 		uint16_t port_attempt;
   1767   1.1       rjs 		int not_done=1;
   1768   1.1       rjs 
   1769   1.1       rjs 		while (not_done) {
   1770   1.1       rjs 			port_guess = sctp_select_initial_TSN(&inp->sctp_ep);
   1771   1.1       rjs 			port_attempt = (port_guess &  0x0000ffff);
   1772   1.1       rjs 			if (port_attempt == 0) {
   1773   1.1       rjs 				goto next_half;
   1774   1.1       rjs 			}
   1775   1.1       rjs 			if (port_attempt < IPPORT_RESERVED) {
   1776   1.1       rjs 				port_attempt += IPPORT_RESERVED;
   1777   1.1       rjs 			}
   1778   1.1       rjs 
   1779   1.1       rjs 			if (sctp_isport_inuse(inp, htons(port_attempt)) == 0) {
   1780   1.1       rjs 				/* got a port we can use */
   1781   1.1       rjs 				not_done = 0;
   1782   1.1       rjs 				continue;
   1783   1.1       rjs 			}
   1784   1.1       rjs 			/* try upper half */
   1785   1.1       rjs 		next_half:
   1786   1.1       rjs 			port_attempt = ((port_guess >> 16) &  0x0000ffff);
   1787   1.1       rjs 			if (port_attempt == 0) {
   1788   1.1       rjs 				goto last_try;
   1789   1.1       rjs 			}
   1790   1.1       rjs 			if (port_attempt < IPPORT_RESERVED) {
   1791   1.1       rjs 				port_attempt += IPPORT_RESERVED;
   1792   1.1       rjs 			}
   1793   1.1       rjs 			if (sctp_isport_inuse(inp, htons(port_attempt)) == 0) {
   1794   1.1       rjs 				/* got a port we can use */
   1795   1.1       rjs 				not_done = 0;
   1796   1.1       rjs 				continue;
   1797   1.1       rjs 			}
   1798   1.1       rjs 			/* try two half's added together */
   1799   1.1       rjs 		last_try:
   1800   1.1       rjs 			port_attempt = (((port_guess >> 16) &  0x0000ffff) + (port_guess & 0x0000ffff));
   1801   1.1       rjs 			if (port_attempt == 0) {
   1802   1.1       rjs 				/* get a new random number */
   1803   1.1       rjs 				continue;
   1804   1.1       rjs 			}
   1805   1.1       rjs 			if (port_attempt < IPPORT_RESERVED) {
   1806   1.1       rjs 				port_attempt += IPPORT_RESERVED;
   1807   1.1       rjs 			}
   1808   1.1       rjs 			if (sctp_isport_inuse(inp, htons(port_attempt)) == 0) {
   1809   1.1       rjs 				/* got a port we can use */
   1810   1.1       rjs 				not_done = 0;
   1811   1.1       rjs 				continue;
   1812   1.1       rjs 			}
   1813   1.1       rjs 		}
   1814   1.1       rjs 		/* we don't get out of the loop until we have a port */
   1815   1.1       rjs 		lport = htons(port_attempt);
   1816   1.1       rjs 	}
   1817   1.1       rjs 	SCTP_INP_DECR_REF(inp);
   1818   1.1       rjs 	if (inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE|SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
   1819   1.1       rjs 		/* this really should not happen. The guy
   1820   1.1       rjs 		 * did a non-blocking bind and then did a close
   1821   1.1       rjs 		 * at the same time.
   1822   1.1       rjs 		 */
   1823   1.1       rjs 		SCTP_INP_WUNLOCK(inp);
   1824   1.1       rjs 		SCTP_INP_INFO_WUNLOCK();
   1825   1.1       rjs 		return (EINVAL);
   1826   1.1       rjs 	}
   1827   1.1       rjs 	/* ok we look clear to give out this port, so lets setup the binding */
   1828   1.1       rjs 	if (bindall) {
   1829   1.1       rjs 		/* binding to all addresses, so just set in the proper flags */
   1830   1.1       rjs 		inp->sctp_flags |= (SCTP_PCB_FLAGS_BOUNDALL |
   1831   1.1       rjs 		    SCTP_PCB_FLAGS_DO_ASCONF);
   1832   1.1       rjs 		/* set the automatic addr changes from kernel flag */
   1833   1.1       rjs 		if (sctp_auto_asconf == 0) {
   1834   1.1       rjs 			inp->sctp_flags &= ~SCTP_PCB_FLAGS_AUTO_ASCONF;
   1835   1.1       rjs 		} else {
   1836   1.1       rjs 			inp->sctp_flags |= SCTP_PCB_FLAGS_AUTO_ASCONF;
   1837   1.1       rjs 		}
   1838   1.1       rjs 	} else {
   1839   1.1       rjs 		/*
   1840   1.1       rjs 		 * bind specific, make sure flags is off and add a new address
   1841   1.1       rjs 		 * structure to the sctp_addr_list inside the ep structure.
   1842   1.1       rjs 		 *
   1843   1.1       rjs 		 * We will need to allocate one and insert it at the head.
   1844   1.1       rjs 		 * The socketopt call can just insert new addresses in there
   1845   1.1       rjs 		 * as well. It will also have to do the embed scope kame hack
   1846   1.1       rjs 		 * too (before adding).
   1847   1.1       rjs 		 */
   1848   1.1       rjs 		struct ifaddr *ifa;
   1849   1.1       rjs 		struct sockaddr_storage store_sa;
   1850   1.1       rjs 
   1851   1.1       rjs 		memset(&store_sa, 0, sizeof(store_sa));
   1852   1.1       rjs 		if (addr->sa_family == AF_INET) {
   1853   1.1       rjs 			struct sockaddr_in *sin;
   1854   1.1       rjs 
   1855   1.1       rjs 			sin = (struct sockaddr_in *)&store_sa;
   1856   1.1       rjs 			memcpy(sin, addr, sizeof(struct sockaddr_in));
   1857   1.1       rjs 			sin->sin_port = 0;
   1858   1.1       rjs 		} else if (addr->sa_family == AF_INET6) {
   1859   1.1       rjs 			struct sockaddr_in6 *sin6;
   1860   1.1       rjs 
   1861   1.1       rjs 			sin6 = (struct sockaddr_in6 *)&store_sa;
   1862   1.1       rjs 			memcpy(sin6, addr, sizeof(struct sockaddr_in6));
   1863   1.1       rjs 			sin6->sin6_port = 0;
   1864   1.1       rjs 		}
   1865   1.1       rjs 		/*
   1866   1.1       rjs 		 * first find the interface with the bound address
   1867   1.1       rjs 		 * need to zero out the port to find the address! yuck!
   1868   1.1       rjs 		 * can't do this earlier since need port for sctp_pcb_findep()
   1869   1.1       rjs 		 */
   1870   1.1       rjs 		ifa = sctp_find_ifa_by_addr((struct sockaddr *)&store_sa);
   1871   1.1       rjs 		if (ifa == NULL) {
   1872   1.1       rjs 			/* Can't find an interface with that address */
   1873   1.1       rjs 			SCTP_INP_WUNLOCK(inp);
   1874   1.1       rjs 			SCTP_INP_INFO_WUNLOCK();
   1875   1.1       rjs 			return (EADDRNOTAVAIL);
   1876   1.1       rjs 		}
   1877   1.1       rjs 		if (addr->sa_family == AF_INET6) {
   1878   1.1       rjs 			struct in6_ifaddr *ifa6;
   1879   1.1       rjs 			ifa6 = (struct in6_ifaddr *)ifa;
   1880   1.1       rjs 			/*
   1881   1.1       rjs 			 * allow binding of deprecated addresses as per
   1882   1.1       rjs 			 * RFC 2462 and ipng discussion
   1883   1.1       rjs 			 */
   1884   1.1       rjs 			if (ifa6->ia6_flags & (IN6_IFF_DETACHED |
   1885   1.1       rjs 			    IN6_IFF_ANYCAST |
   1886   1.1       rjs 			    IN6_IFF_NOTREADY)) {
   1887   1.1       rjs 				/* Can't bind a non-existent addr. */
   1888   1.1       rjs 				SCTP_INP_WUNLOCK(inp);
   1889   1.1       rjs 				SCTP_INP_INFO_WUNLOCK();
   1890   1.1       rjs 				return (EINVAL);
   1891   1.1       rjs 			}
   1892   1.1       rjs 		}
   1893   1.1       rjs 		/* we're not bound all */
   1894   1.1       rjs 		inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUNDALL;
   1895   1.1       rjs #if 0 /* use sysctl now */
   1896   1.1       rjs 		/* don't allow automatic addr changes from kernel */
   1897   1.1       rjs 		inp->sctp_flags &= ~SCTP_PCB_FLAGS_AUTO_ASCONF;
   1898   1.1       rjs #endif
   1899   1.1       rjs 		/* set the automatic addr changes from kernel flag */
   1900   1.1       rjs 		if (sctp_auto_asconf == 0) {
   1901   1.1       rjs 			inp->sctp_flags &= ~SCTP_PCB_FLAGS_AUTO_ASCONF;
   1902   1.1       rjs 		} else {
   1903   1.1       rjs 			inp->sctp_flags |= SCTP_PCB_FLAGS_AUTO_ASCONF;
   1904   1.1       rjs 		}
   1905   1.1       rjs 		/* allow bindx() to send ASCONF's for binding changes */
   1906   1.1       rjs 		inp->sctp_flags |= SCTP_PCB_FLAGS_DO_ASCONF;
   1907   1.1       rjs 		/* add this address to the endpoint list */
   1908   1.1       rjs 		error = sctp_insert_laddr(&inp->sctp_addr_list, ifa);
   1909   1.1       rjs 		if (error != 0) {
   1910   1.1       rjs 			SCTP_INP_WUNLOCK(inp);
   1911   1.1       rjs 			SCTP_INP_INFO_WUNLOCK();
   1912   1.1       rjs 			return (error);
   1913   1.1       rjs 		}
   1914   1.1       rjs 		inp->laddr_count++;
   1915   1.1       rjs 	}
   1916   1.1       rjs 	/* find the bucket */
   1917   1.1       rjs 	head = &sctppcbinfo.sctp_ephash[SCTP_PCBHASH_ALLADDR(lport,
   1918   1.1       rjs 	    sctppcbinfo.hashmark)];
   1919   1.1       rjs 	/* put it in the bucket */
   1920   1.1       rjs 	LIST_INSERT_HEAD(head, inp, sctp_hash);
   1921   1.1       rjs #ifdef SCTP_DEBUG
   1922   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   1923   1.1       rjs 		printf("Main hash to bind at head:%p, bound port:%d\n", head, ntohs(lport));
   1924   1.1       rjs 	}
   1925   1.1       rjs #endif
   1926   1.1       rjs 	/* set in the port */
   1927   1.1       rjs 	inp->sctp_lport = lport;
   1928   1.1       rjs 
   1929   1.1       rjs 	/* turn off just the unbound flag */
   1930   1.1       rjs 	inp->sctp_flags &= ~SCTP_PCB_FLAGS_UNBOUND;
   1931   1.1       rjs 	SCTP_INP_WUNLOCK(inp);
   1932   1.1       rjs 	SCTP_INP_INFO_WUNLOCK();
   1933   1.1       rjs 	return (0);
   1934   1.1       rjs }
   1935   1.1       rjs 
   1936   1.1       rjs 
   1937   1.1       rjs static void
   1938   1.1       rjs sctp_iterator_inp_being_freed(struct sctp_inpcb *inp, struct sctp_inpcb *inp_next)
   1939   1.1       rjs {
   1940   1.1       rjs 	struct sctp_iterator *it;
   1941   1.1       rjs 	/* We enter with the only the ITERATOR_LOCK in place and
   1942   1.1       rjs 	 * A write lock on the inp_info stuff.
   1943   1.1       rjs 	 */
   1944   1.1       rjs 
   1945   1.1       rjs 	/* Go through all iterators, we must do this since
   1946   1.1       rjs 	 * it is possible that some iterator does NOT have
   1947   1.1       rjs 	 * the lock, but is waiting for it. And the one that
   1948   1.1       rjs 	 * had the lock has either moved in the last iteration
   1949   1.1       rjs 	 * or we just cleared it above. We need to find all
   1950   1.1       rjs 	 * of those guys. The list of iterators should never
   1951   1.1       rjs 	 * be very big though.
   1952   1.1       rjs 	 */
   1953   1.1       rjs  	LIST_FOREACH(it, &sctppcbinfo.iteratorhead, sctp_nxt_itr) {
   1954   1.1       rjs 		if (it == inp->inp_starting_point_for_iterator)
   1955   1.1       rjs 			/* skip this guy, he's special */
   1956   1.1       rjs 			continue;
   1957   1.1       rjs  		if (it->inp == inp) {
   1958   1.1       rjs 			/* This is tricky and we DON'T lock the iterator.
   1959   1.1       rjs 			 * Reason is he's running but waiting for me since
   1960   1.1       rjs 			 * inp->inp_starting_point_for_iterator has the lock
   1961   1.1       rjs 			 * on me (the guy above we skipped). This tells us
   1962   1.1       rjs 			 * its is not running but waiting for inp->inp_starting_point_for_iterator
   1963   1.1       rjs 			 * to be released by the guy that does have our INP in a lock.
   1964   1.1       rjs 			 */
   1965   1.1       rjs 			if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
   1966   1.1       rjs 				it->inp = NULL;
   1967   1.1       rjs 				it->stcb = NULL;
   1968   1.1       rjs 			} else {
   1969   1.1       rjs 				/* set him up to do the next guy not me */
   1970   1.1       rjs 				it->inp = inp_next;
   1971   1.1       rjs 				it->stcb = NULL;
   1972   1.1       rjs 			}
   1973   1.1       rjs 		}
   1974   1.1       rjs 	}
   1975   1.1       rjs 	it = inp->inp_starting_point_for_iterator;
   1976   1.1       rjs 	if (it) {
   1977   1.1       rjs 		if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
   1978   1.1       rjs 			it->inp = NULL;
   1979   1.1       rjs 		} else {
   1980   1.1       rjs 			it->inp = inp_next;
   1981   1.1       rjs 		}
   1982   1.1       rjs 		it->stcb = NULL;
   1983   1.1       rjs 	}
   1984   1.1       rjs }
   1985   1.1       rjs 
   1986   1.1       rjs /* release sctp_inpcb unbind the port */
   1987   1.1       rjs void
   1988   1.1       rjs sctp_inpcb_free(struct sctp_inpcb *inp, int immediate)
   1989   1.1       rjs {
   1990   1.1       rjs 	/*
   1991   1.1       rjs 	 * Here we free a endpoint. We must find it (if it is in the Hash
   1992   1.1       rjs 	 * table) and remove it from there. Then we must also find it in
   1993   1.1       rjs 	 * the overall list and remove it from there. After all removals are
   1994   1.1       rjs 	 * complete then any timer has to be stopped. Then start the actual
   1995   1.1       rjs 	 * freeing.
   1996   1.1       rjs 	 * a) Any local lists.
   1997   1.1       rjs 	 * b) Any associations.
   1998   1.1       rjs 	 * c) The hash of all associations.
   1999   1.1       rjs 	 * d) finally the ep itself.
   2000   1.1       rjs 	 */
   2001   1.1       rjs 	struct sctp_inpcb *inp_save;
   2002   1.1       rjs 	struct sctp_tcb *asoc, *nasoc;
   2003   1.1       rjs 	struct sctp_laddr *laddr, *nladdr;
   2004   1.1       rjs 	struct inpcb *ip_pcb;
   2005   1.1       rjs 	struct socket *so;
   2006   1.1       rjs 	struct sctp_socket_q_list *sq;
   2007   1.1       rjs 	int s, cnt;
   2008   1.8     ozaki 	struct rtentry *rt;
   2009   1.1       rjs 
   2010   1.1       rjs 	s = splsoftnet();
   2011   1.1       rjs 	SCTP_ASOC_CREATE_LOCK(inp);
   2012   1.1       rjs 	SCTP_INP_WLOCK(inp);
   2013   1.1       rjs 
   2014   1.1       rjs 	if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
   2015   1.1       rjs 		/* been here before */
   2016   1.1       rjs 		splx(s);
   2017   1.1       rjs 		printf("Endpoint was all gone (dup free)?\n");
   2018   1.1       rjs 		SCTP_INP_WUNLOCK(inp);
   2019   1.1       rjs 		SCTP_ASOC_CREATE_UNLOCK(inp);
   2020   1.1       rjs 		return;
   2021   1.1       rjs 	}
   2022   1.1       rjs 	sctp_timer_stop(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL);
   2023   1.1       rjs 
   2024   1.1       rjs 	if (inp->control) {
   2025   1.1       rjs 		sctp_m_freem(inp->control);
   2026   1.1       rjs 		inp->control = NULL;
   2027   1.1       rjs 	}
   2028   1.1       rjs 	if (inp->pkt) {
   2029   1.1       rjs 		sctp_m_freem(inp->pkt);
   2030   1.1       rjs 		inp->pkt = NULL;
   2031   1.1       rjs 	}
   2032   1.9       rjs 	so = inp->sctp_socket;
   2033   1.1       rjs 	ip_pcb = &inp->ip_inp.inp; /* we could just cast the main
   2034   1.1       rjs 				   * pointer here but I will
   2035   1.1       rjs 				   * be nice :> (i.e. ip_pcb = ep;)
   2036   1.1       rjs 				   */
   2037   1.1       rjs 
   2038   1.1       rjs 	if (immediate == 0) {
   2039   1.1       rjs 		int cnt_in_sd;
   2040   1.1       rjs 		cnt_in_sd = 0;
   2041   1.1       rjs 		for ((asoc = LIST_FIRST(&inp->sctp_asoc_list)); asoc != NULL;
   2042   1.1       rjs 		     asoc = nasoc) {
   2043   1.1       rjs 			nasoc = LIST_NEXT(asoc, sctp_tcblist);
   2044   1.1       rjs 			if ((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_COOKIE_WAIT) ||
   2045   1.1       rjs 			    (SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_COOKIE_ECHOED)) {
   2046   1.1       rjs 				/* Just abandon things in the front states */
   2047   1.1       rjs 				SCTP_TCB_LOCK(asoc);
   2048   1.1       rjs 				SCTP_INP_WUNLOCK(inp);
   2049   1.1       rjs 				sctp_free_assoc(inp, asoc);
   2050   1.1       rjs 				SCTP_INP_WLOCK(inp);
   2051   1.1       rjs 				continue;
   2052   1.1       rjs 			} else {
   2053   1.1       rjs 				asoc->asoc.state |= SCTP_STATE_CLOSED_SOCKET;
   2054   1.1       rjs 			}
   2055   1.1       rjs 			if ((asoc->asoc.size_on_delivery_queue  > 0) ||
   2056   1.1       rjs 			    (asoc->asoc.size_on_reasm_queue > 0) ||
   2057   1.1       rjs 			    (asoc->asoc.size_on_all_streams > 0) ||
   2058   1.1       rjs 			    (so && (so->so_rcv.sb_cc > 0))
   2059   1.1       rjs 				) {
   2060   1.1       rjs 				/* Left with Data unread */
   2061   1.1       rjs 				struct mbuf *op_err;
   2062   1.1       rjs 				MGET(op_err, M_DONTWAIT, MT_DATA);
   2063   1.1       rjs 				if (op_err) {
   2064   1.1       rjs 					/* Fill in the user initiated abort */
   2065   1.1       rjs 					struct sctp_paramhdr *ph;
   2066   1.1       rjs 					op_err->m_len =
   2067   1.1       rjs 					    sizeof(struct sctp_paramhdr);
   2068   1.1       rjs 					ph = mtod(op_err,
   2069   1.1       rjs 					    struct sctp_paramhdr *);
   2070   1.1       rjs 					ph->param_type = htons(
   2071   1.1       rjs 					    SCTP_CAUSE_USER_INITIATED_ABT);
   2072   1.1       rjs 					ph->param_length = htons(op_err->m_len);
   2073   1.1       rjs 				}
   2074   1.1       rjs 				SCTP_TCB_LOCK(asoc);
   2075   1.1       rjs 				sctp_send_abort_tcb(asoc, op_err);
   2076   1.1       rjs 
   2077   1.1       rjs 				SCTP_INP_WUNLOCK(inp);
   2078   1.1       rjs 				sctp_free_assoc(inp, asoc);
   2079   1.1       rjs 				SCTP_INP_WLOCK(inp);
   2080   1.1       rjs 				continue;
   2081   1.1       rjs 			} else if (TAILQ_EMPTY(&asoc->asoc.send_queue) &&
   2082   1.1       rjs 			    TAILQ_EMPTY(&asoc->asoc.sent_queue)) {
   2083   1.1       rjs 				if ((SCTP_GET_STATE(&asoc->asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
   2084   1.1       rjs 				    (SCTP_GET_STATE(&asoc->asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
   2085   1.1       rjs 					/* there is nothing queued to send, so I send shutdown */
   2086   1.1       rjs 					SCTP_TCB_LOCK(asoc);
   2087   1.1       rjs 					sctp_send_shutdown(asoc, asoc->asoc.primary_destination);
   2088   1.1       rjs 					asoc->asoc.state = SCTP_STATE_SHUTDOWN_SENT;
   2089   1.1       rjs 					sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, asoc->sctp_ep, asoc,
   2090   1.1       rjs 							 asoc->asoc.primary_destination);
   2091   1.1       rjs 					sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, asoc->sctp_ep, asoc,
   2092   1.1       rjs 							 asoc->asoc.primary_destination);
   2093   1.1       rjs 					sctp_chunk_output(inp, asoc, 1);
   2094   1.1       rjs 					SCTP_TCB_UNLOCK(asoc);
   2095   1.1       rjs 				}
   2096   1.1       rjs 			} else {
   2097   1.1       rjs 				/* mark into shutdown pending */
   2098   1.1       rjs 				asoc->asoc.state |= SCTP_STATE_SHUTDOWN_PENDING;
   2099   1.1       rjs 			}
   2100   1.1       rjs 			cnt_in_sd++;
   2101   1.1       rjs 		}
   2102   1.1       rjs 		/* now is there some left in our SHUTDOWN state? */
   2103   1.1       rjs 		if (cnt_in_sd) {
   2104   1.1       rjs 			inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_GONE;
   2105   1.1       rjs 			splx(s);
   2106   1.1       rjs 			SCTP_INP_WUNLOCK(inp);
   2107   1.1       rjs 			SCTP_ASOC_CREATE_UNLOCK(inp);
   2108   1.1       rjs 			return;
   2109   1.1       rjs 		}
   2110   1.1       rjs 	}
   2111   1.1       rjs #if defined(__FreeBSD__) && __FreeBSD_version >= 503000
   2112   1.1       rjs 	if (inp->refcount) {
   2113   1.1       rjs 		sctp_timer_start(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL);
   2114   1.1       rjs 		SCTP_INP_WUNLOCK(inp);
   2115   1.1       rjs 		SCTP_ASOC_CREATE_UNLOCK(inp);
   2116   1.1       rjs 		return;
   2117   1.1       rjs 	}
   2118   1.1       rjs #endif
   2119   1.1       rjs 	inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_ALLGONE;
   2120   1.1       rjs 
   2121   1.8     ozaki 	/* XXX */
   2122   1.8     ozaki 	rt = rtcache_validate(&ip_pcb->inp_route);
   2123   1.8     ozaki 	rtcache_unref(rt, &ip_pcb->inp_route);
   2124   1.1       rjs 
   2125   1.1       rjs 	callout_stop(&inp->sctp_ep.signature_change.timer);
   2126   1.1       rjs 	callout_destroy(&inp->sctp_ep.signature_change.timer);
   2127   1.1       rjs 
   2128   1.1       rjs 	if (so) {
   2129   1.1       rjs 	/* First take care of socket level things */
   2130   1.1       rjs #ifdef IPSEC
   2131  1.15       rjs 		if (ipsec_enabled)
   2132  1.16      maxv 			ipsec_delete_pcbpolicy(ip_pcb);
   2133   1.1       rjs #endif /*IPSEC*/
   2134   1.1       rjs 		so->so_pcb = 0;
   2135   1.1       rjs 	}
   2136   1.1       rjs 
   2137   1.1       rjs 	if (ip_pcb->inp_options) {
   2138   1.1       rjs 		(void)m_free(ip_pcb->inp_options);
   2139   1.1       rjs 		ip_pcb->inp_options = 0;
   2140   1.1       rjs 	}
   2141   1.1       rjs 	rtcache_free(&ip_pcb->inp_route);
   2142   1.1       rjs 	if (ip_pcb->inp_moptions) {
   2143   1.1       rjs 		ip_freemoptions(ip_pcb->inp_moptions);
   2144   1.1       rjs 		ip_pcb->inp_moptions = 0;
   2145   1.1       rjs 	}
   2146   1.1       rjs 	inp->inp_vflag = 0;
   2147   1.1       rjs 
   2148   1.1       rjs 	/* Now the sctp_pcb things */
   2149   1.1       rjs 	/*
   2150   1.1       rjs 	 * free each asoc if it is not already closed/free. we can't use
   2151   1.1       rjs 	 * the macro here since le_next will get freed as part of the
   2152   1.1       rjs 	 * sctp_free_assoc() call.
   2153   1.1       rjs 	 */
   2154   1.1       rjs 	cnt = 0;
   2155   1.1       rjs 	for ((asoc = LIST_FIRST(&inp->sctp_asoc_list)); asoc != NULL;
   2156   1.1       rjs 	     asoc = nasoc) {
   2157   1.1       rjs 		nasoc = LIST_NEXT(asoc, sctp_tcblist);
   2158   1.1       rjs 		SCTP_TCB_LOCK(asoc);
   2159   1.1       rjs 		if (SCTP_GET_STATE(&asoc->asoc) != SCTP_STATE_COOKIE_WAIT) {
   2160   1.1       rjs 			struct mbuf *op_err;
   2161   1.1       rjs 			MGET(op_err, M_DONTWAIT, MT_DATA);
   2162   1.1       rjs 			if (op_err) {
   2163   1.1       rjs 				/* Fill in the user initiated abort */
   2164   1.1       rjs 				struct sctp_paramhdr *ph;
   2165   1.1       rjs 				op_err->m_len = sizeof(struct sctp_paramhdr);
   2166   1.1       rjs 				ph = mtod(op_err, struct sctp_paramhdr *);
   2167   1.1       rjs 				ph->param_type = htons(
   2168   1.1       rjs 				    SCTP_CAUSE_USER_INITIATED_ABT);
   2169   1.1       rjs 				ph->param_length = htons(op_err->m_len);
   2170   1.1       rjs 			}
   2171   1.1       rjs 			sctp_send_abort_tcb(asoc, op_err);
   2172   1.1       rjs 		}
   2173   1.1       rjs 		cnt++;
   2174   1.1       rjs 		/*
   2175   1.1       rjs 		 * sctp_free_assoc() will call sctp_inpcb_free(),
   2176   1.1       rjs 		 * if SCTP_PCB_FLAGS_SOCKET_GONE set.
   2177   1.1       rjs 		 * So, we clear it before sctp_free_assoc() making sure
   2178   1.1       rjs 		 * no double sctp_inpcb_free().
   2179   1.1       rjs 		 */
   2180   1.1       rjs 		inp->sctp_flags &= ~SCTP_PCB_FLAGS_SOCKET_GONE;
   2181   1.1       rjs 		SCTP_INP_WUNLOCK(inp);
   2182   1.1       rjs 		sctp_free_assoc(inp, asoc);
   2183   1.1       rjs 		SCTP_INP_WLOCK(inp);
   2184   1.1       rjs 	}
   2185   1.1       rjs 	while ((sq = TAILQ_FIRST(&inp->sctp_queue_list)) != NULL) {
   2186   1.1       rjs 		TAILQ_REMOVE(&inp->sctp_queue_list, sq, next_sq);
   2187   1.1       rjs 		SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_sockq, sq);
   2188   1.1       rjs 		sctppcbinfo.ipi_count_sockq--;
   2189   1.1       rjs 		sctppcbinfo.ipi_gencnt_sockq++;
   2190   1.1       rjs 	}
   2191   1.1       rjs 	inp->sctp_socket = 0;
   2192   1.1       rjs 	/* Now first we remove ourselves from the overall list of all EP's */
   2193   1.1       rjs 
   2194   1.1       rjs 	/* Unlock inp first, need correct order */
   2195   1.1       rjs 	SCTP_INP_WUNLOCK(inp);
   2196   1.1       rjs 	/* now iterator lock */
   2197   1.1       rjs 	SCTP_ITERATOR_LOCK();
   2198   1.1       rjs 	/* now info lock */
   2199   1.1       rjs 	SCTP_INP_INFO_WLOCK();
   2200   1.1       rjs 	/* now reget the inp lock */
   2201   1.1       rjs 	SCTP_INP_WLOCK(inp);
   2202   1.1       rjs 
   2203   1.1       rjs 	inp_save = LIST_NEXT(inp, sctp_list);
   2204   1.1       rjs 	LIST_REMOVE(inp, sctp_list);
   2205   1.1       rjs 	/*
   2206   1.1       rjs 	 * Now the question comes as to if this EP was ever bound at all.
   2207   1.1       rjs 	 * If it was, then we must pull it out of the EP hash list.
   2208   1.1       rjs 	 */
   2209   1.1       rjs 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) !=
   2210   1.1       rjs 	    SCTP_PCB_FLAGS_UNBOUND) {
   2211   1.1       rjs 		/*
   2212   1.1       rjs 		 * ok, this guy has been bound. It's port is somewhere
   2213   1.1       rjs 		 * in the sctppcbinfo hash table. Remove it!
   2214   1.1       rjs 		 */
   2215   1.1       rjs 		LIST_REMOVE(inp, sctp_hash);
   2216   1.1       rjs 	}
   2217   1.1       rjs         /* fix any iterators only after out of the list */
   2218   1.1       rjs 	sctp_iterator_inp_being_freed(inp, inp_save);
   2219   1.1       rjs 	SCTP_ITERATOR_UNLOCK();
   2220   1.1       rjs 	/*
   2221   1.1       rjs 	 * if we have an address list the following will free the list of
   2222   1.1       rjs 	 * ifaddr's that are set into this ep. Again macro limitations here,
   2223   1.1       rjs 	 * since the LIST_FOREACH could be a bad idea.
   2224   1.1       rjs 	 */
   2225   1.1       rjs 	for ((laddr = LIST_FIRST(&inp->sctp_addr_list)); laddr != NULL;
   2226   1.1       rjs 	     laddr = nladdr) {
   2227   1.1       rjs 		nladdr = LIST_NEXT(laddr, sctp_nxt_addr);
   2228   1.1       rjs 		LIST_REMOVE(laddr, sctp_nxt_addr);
   2229   1.1       rjs 		SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_laddr, laddr);
   2230   1.1       rjs 		sctppcbinfo.ipi_gencnt_laddr++;
   2231   1.1       rjs 		sctppcbinfo.ipi_count_laddr--;
   2232   1.1       rjs 	}
   2233   1.1       rjs 
   2234   1.1       rjs 	/* Now lets see about freeing the EP hash table. */
   2235   1.1       rjs 	if (inp->sctp_tcbhash != NULL) {
   2236   1.1       rjs 		SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_hash, inp->sctp_tcbhash);
   2237   1.1       rjs 		inp->sctp_tcbhash = NULL;
   2238   1.1       rjs 	}
   2239   1.1       rjs 	SCTP_INP_WUNLOCK(inp);
   2240   1.1       rjs 	SCTP_ASOC_CREATE_UNLOCK(inp);
   2241   1.1       rjs 	SCTP_INP_LOCK_DESTROY(inp);
   2242   1.1       rjs 	SCTP_ASOC_CREATE_LOCK_DESTROY(inp);
   2243   1.1       rjs 
   2244   1.1       rjs 	/* Now we must put the ep memory back into the zone pool */
   2245   1.1       rjs 	SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp);
   2246   1.1       rjs 	sctppcbinfo.ipi_count_ep--;
   2247   1.1       rjs 
   2248   1.1       rjs 	SCTP_INP_INFO_WUNLOCK();
   2249   1.1       rjs 	splx(s);
   2250  1.14       rjs 
   2251  1.14       rjs 	sofree(so);
   2252  1.14       rjs 	mutex_enter(softnet_lock);
   2253   1.1       rjs }
   2254   1.1       rjs 
   2255   1.1       rjs 
   2256   1.1       rjs struct sctp_nets *
   2257   1.1       rjs sctp_findnet(struct sctp_tcb *stcb, struct sockaddr *addr)
   2258   1.1       rjs {
   2259   1.1       rjs 	struct sctp_nets *net;
   2260   1.1       rjs 
   2261   1.1       rjs 	/* use the peer's/remote port for lookup if unspecified */
   2262   1.1       rjs #if 0 /* why do we need to check the port for a nets list on an assoc? */
   2263   1.1       rjs 	if (stcb->rport != sin->sin_port) {
   2264   1.1       rjs 		/* we cheat and just a sin for this test */
   2265   1.1       rjs 		return (NULL);
   2266   1.1       rjs 	}
   2267   1.1       rjs #endif
   2268   1.1       rjs 	/* locate the address */
   2269   1.1       rjs 	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   2270   1.1       rjs 		if (sctp_cmpaddr(addr, rtcache_getdst(&net->ro)))
   2271   1.1       rjs 			return (net);
   2272   1.1       rjs 	}
   2273   1.1       rjs 	return (NULL);
   2274   1.1       rjs }
   2275   1.1       rjs 
   2276   1.1       rjs 
   2277   1.1       rjs /*
   2278   1.1       rjs  * add's a remote endpoint address, done with the INIT/INIT-ACK
   2279   1.1       rjs  * as well as when a ASCONF arrives that adds it. It will also
   2280   1.1       rjs  * initialize all the cwnd stats of stuff.
   2281   1.1       rjs  */
   2282   1.1       rjs int
   2283   1.1       rjs sctp_is_address_on_local_host(struct sockaddr *addr)
   2284   1.1       rjs {
   2285   1.1       rjs 	struct ifnet *ifn;
   2286   1.1       rjs 	struct ifaddr *ifa;
   2287   1.5     ozaki 	int s;
   2288   1.5     ozaki 
   2289   1.5     ozaki 	s = pserialize_read_enter();
   2290   1.5     ozaki 	IFNET_READER_FOREACH(ifn) {
   2291   1.7     ozaki 		IFADDR_READER_FOREACH(ifa, ifn) {
   2292   1.1       rjs 			if (addr->sa_family == ifa->ifa_addr->sa_family) {
   2293   1.1       rjs 				/* same family */
   2294   1.1       rjs 				if (addr->sa_family == AF_INET) {
   2295   1.1       rjs 					struct sockaddr_in *sin, *sin_c;
   2296   1.1       rjs 					sin = (struct sockaddr_in *)addr;
   2297   1.1       rjs 					sin_c = (struct sockaddr_in *)
   2298   1.1       rjs 					    ifa->ifa_addr;
   2299   1.1       rjs 					if (sin->sin_addr.s_addr ==
   2300   1.1       rjs 					    sin_c->sin_addr.s_addr) {
   2301   1.1       rjs 						/* we are on the same machine */
   2302   1.5     ozaki 						pserialize_read_exit(s);
   2303   1.1       rjs 						return (1);
   2304   1.1       rjs 					}
   2305   1.1       rjs 				} else if (addr->sa_family == AF_INET6) {
   2306   1.1       rjs 					struct sockaddr_in6 *sin6, *sin_c6;
   2307   1.1       rjs 					sin6 = (struct sockaddr_in6 *)addr;
   2308   1.1       rjs 					sin_c6 = (struct sockaddr_in6 *)
   2309   1.1       rjs 					    ifa->ifa_addr;
   2310   1.1       rjs 					if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
   2311   1.1       rjs 					    &sin_c6->sin6_addr)) {
   2312   1.1       rjs 						/* we are on the same machine */
   2313   1.5     ozaki 						pserialize_read_exit(s);
   2314   1.1       rjs 						return (1);
   2315   1.1       rjs 					}
   2316   1.1       rjs 				}
   2317   1.1       rjs 			}
   2318   1.1       rjs 		}
   2319   1.1       rjs 	}
   2320   1.5     ozaki 	pserialize_read_exit(s);
   2321   1.5     ozaki 
   2322   1.1       rjs 	return (0);
   2323   1.1       rjs }
   2324   1.1       rjs 
   2325   1.1       rjs int
   2326   1.1       rjs sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
   2327   1.1       rjs     int set_scope, int from)
   2328   1.1       rjs {
   2329   1.1       rjs 	/*
   2330   1.1       rjs 	 * The following is redundant to the same lines in the
   2331   1.1       rjs 	 * sctp_aloc_assoc() but is needed since other's call the add
   2332   1.1       rjs 	 * address function
   2333   1.1       rjs 	 */
   2334   1.1       rjs 	struct sctp_nets *net, *netfirst;
   2335   1.1       rjs 	struct rtentry *rt, *netfirst_rt;
   2336   1.1       rjs 	int addr_inscope;
   2337   1.1       rjs 
   2338   1.1       rjs #ifdef SCTP_DEBUG
   2339   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   2340   1.1       rjs 		printf("Adding an address (from:%d) to the peer: ", from);
   2341   1.1       rjs 		sctp_print_address(newaddr);
   2342   1.1       rjs 	}
   2343   1.1       rjs #endif
   2344   1.1       rjs 	netfirst = sctp_findnet(stcb, newaddr);
   2345   1.1       rjs 	if (netfirst) {
   2346   1.1       rjs 		/*
   2347   1.1       rjs 		 * Lie and return ok, we don't want to make the association
   2348   1.1       rjs 		 * go away for this behavior. It will happen in the TCP model
   2349   1.1       rjs 		 * in a connected socket. It does not reach the hash table
   2350   1.1       rjs 		 * until after the association is built so it can't be found.
   2351   1.1       rjs 		 * Mark as reachable, since the initial creation will have
   2352   1.1       rjs 		 * been cleared and the NOT_IN_ASSOC flag will have been
   2353   1.1       rjs 		 * added... and we don't want to end up removing it back out.
   2354   1.1       rjs 		 */
   2355   1.1       rjs 		if (netfirst->dest_state & SCTP_ADDR_UNCONFIRMED) {
   2356   1.1       rjs 			netfirst->dest_state = (SCTP_ADDR_REACHABLE|
   2357   1.1       rjs 			    SCTP_ADDR_UNCONFIRMED);
   2358   1.1       rjs 		} else {
   2359   1.1       rjs 			netfirst->dest_state = SCTP_ADDR_REACHABLE;
   2360   1.1       rjs 		}
   2361   1.1       rjs 
   2362   1.1       rjs 		return (0);
   2363   1.1       rjs 	}
   2364   1.1       rjs 	addr_inscope = 1;
   2365   1.1       rjs 	if (newaddr->sa_family == AF_INET) {
   2366   1.1       rjs 		struct sockaddr_in *sin;
   2367   1.1       rjs 		sin = (struct sockaddr_in *)newaddr;
   2368   1.1       rjs 		if (sin->sin_addr.s_addr == 0) {
   2369   1.1       rjs 			/* Invalid address */
   2370   1.1       rjs 			return (-1);
   2371   1.1       rjs 		}
   2372   1.1       rjs 		/* zero out the bzero area */
   2373   1.1       rjs 		memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
   2374   1.1       rjs 
   2375   1.1       rjs 		/* assure len is set */
   2376   1.1       rjs 		sin->sin_len = sizeof(struct sockaddr_in);
   2377   1.1       rjs 		if (set_scope) {
   2378   1.1       rjs #ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
   2379   1.1       rjs 			stcb->ipv4_local_scope = 1;
   2380   1.1       rjs #else
   2381   1.1       rjs 			if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
   2382   1.1       rjs 				stcb->asoc.ipv4_local_scope = 1;
   2383   1.1       rjs 			}
   2384   1.1       rjs #endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */
   2385   1.1       rjs 
   2386   1.1       rjs 			if (sctp_is_address_on_local_host(newaddr)) {
   2387   1.1       rjs 				stcb->asoc.loopback_scope = 1;
   2388   1.1       rjs 				stcb->asoc.ipv4_local_scope = 1;
   2389   1.1       rjs 				stcb->asoc.local_scope = 1;
   2390   1.1       rjs 				stcb->asoc.site_scope = 1;
   2391   1.1       rjs 			}
   2392   1.1       rjs 		} else {
   2393   1.1       rjs 			if (from == 8) {
   2394   1.1       rjs 				/* From connectx */
   2395   1.1       rjs 				if (sctp_is_address_on_local_host(newaddr)) {
   2396   1.1       rjs 					stcb->asoc.loopback_scope = 1;
   2397   1.1       rjs 					stcb->asoc.ipv4_local_scope = 1;
   2398   1.1       rjs 					stcb->asoc.local_scope = 1;
   2399   1.1       rjs 					stcb->asoc.site_scope = 1;
   2400   1.1       rjs 				}
   2401   1.1       rjs 			}
   2402   1.1       rjs 			/* Validate the address is in scope */
   2403   1.1       rjs 			if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) &&
   2404   1.1       rjs 			    (stcb->asoc.ipv4_local_scope == 0)) {
   2405   1.1       rjs 				addr_inscope = 0;
   2406   1.1       rjs 			}
   2407   1.1       rjs 		}
   2408   1.1       rjs 	} else if (newaddr->sa_family == AF_INET6) {
   2409   1.1       rjs 		struct sockaddr_in6 *sin6;
   2410   1.1       rjs 		sin6 = (struct sockaddr_in6 *)newaddr;
   2411   1.1       rjs 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
   2412   1.1       rjs 			/* Invalid address */
   2413   1.1       rjs 			return (-1);
   2414   1.1       rjs 		}
   2415   1.1       rjs 		/* assure len is set */
   2416   1.1       rjs 		sin6->sin6_len = sizeof(struct sockaddr_in6);
   2417   1.1       rjs 		if (set_scope) {
   2418   1.1       rjs 			if (sctp_is_address_on_local_host(newaddr)) {
   2419   1.1       rjs 				stcb->asoc.loopback_scope = 1;
   2420   1.1       rjs 				stcb->asoc.local_scope = 1;
   2421   1.1       rjs 				stcb->asoc.ipv4_local_scope = 1;
   2422   1.1       rjs 				stcb->asoc.site_scope = 1;
   2423   1.1       rjs 			} else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
   2424   1.1       rjs 				/*
   2425   1.1       rjs 				 * If the new destination is a LINK_LOCAL
   2426   1.1       rjs 				 * we must have common site scope. Don't set
   2427   1.1       rjs 				 * the local scope since we may not share all
   2428   1.1       rjs 				 * links, only loopback can do this.
   2429   1.1       rjs  				 * Links on the local network would also
   2430   1.1       rjs  				 * be on our private network for v4 too.
   2431   1.1       rjs 				 */
   2432   1.1       rjs  				stcb->asoc.ipv4_local_scope = 1;
   2433   1.1       rjs 				stcb->asoc.site_scope = 1;
   2434   1.1       rjs 			} else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
   2435   1.1       rjs 				/*
   2436   1.1       rjs 				 * If the new destination is SITE_LOCAL
   2437   1.1       rjs 				 * then we must have site scope in common.
   2438   1.1       rjs 				 */
   2439   1.1       rjs 				stcb->asoc.site_scope = 1;
   2440   1.1       rjs 			}
   2441   1.1       rjs 		} else {
   2442   1.1       rjs 			if (from == 8) {
   2443   1.1       rjs 				/* From connectx */
   2444   1.1       rjs 				if (sctp_is_address_on_local_host(newaddr)) {
   2445   1.1       rjs 					stcb->asoc.loopback_scope = 1;
   2446   1.1       rjs 					stcb->asoc.ipv4_local_scope = 1;
   2447   1.1       rjs 					stcb->asoc.local_scope = 1;
   2448   1.1       rjs 					stcb->asoc.site_scope = 1;
   2449   1.1       rjs 				}
   2450   1.1       rjs 			}
   2451   1.1       rjs 			/* Validate the address is in scope */
   2452   1.1       rjs 			if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) &&
   2453   1.1       rjs 			    (stcb->asoc.loopback_scope == 0)) {
   2454   1.1       rjs 				addr_inscope = 0;
   2455   1.1       rjs 			} else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
   2456   1.1       rjs 				   (stcb->asoc.local_scope == 0)) {
   2457   1.1       rjs 				addr_inscope = 0;
   2458   1.1       rjs 			} else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&
   2459   1.1       rjs 				   (stcb->asoc.site_scope == 0)) {
   2460   1.1       rjs 				addr_inscope = 0;
   2461   1.1       rjs 			}
   2462   1.1       rjs 		}
   2463   1.1       rjs 	} else {
   2464   1.1       rjs 		/* not supported family type */
   2465   1.1       rjs 		return (-1);
   2466   1.1       rjs 	}
   2467   1.1       rjs 	net = (struct sctp_nets *)SCTP_ZONE_GET(sctppcbinfo.ipi_zone_net);
   2468   1.1       rjs 	if (net == NULL) {
   2469   1.1       rjs 		return (-1);
   2470   1.1       rjs 	}
   2471   1.1       rjs 	sctppcbinfo.ipi_count_raddr++;
   2472   1.1       rjs 	sctppcbinfo.ipi_gencnt_raddr++;
   2473   1.1       rjs 	memset(net, 0, sizeof(*net));
   2474   1.1       rjs 	if (newaddr->sa_family == AF_INET) {
   2475   1.1       rjs 		((struct sockaddr_in *)newaddr)->sin_port = stcb->rport;
   2476   1.1       rjs 	} else if (newaddr->sa_family == AF_INET6) {
   2477   1.1       rjs 		((struct sockaddr_in6 *)newaddr)->sin6_port = stcb->rport;
   2478   1.1       rjs 	}
   2479   1.1       rjs 	net->addr_is_local = sctp_is_address_on_local_host(newaddr);
   2480   1.1       rjs 	net->failure_threshold = stcb->asoc.def_net_failure;
   2481   1.1       rjs 	if (addr_inscope == 0) {
   2482   1.1       rjs #ifdef SCTP_DEBUG
   2483   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   2484   1.1       rjs 			printf("Adding an address which is OUT OF SCOPE\n");
   2485   1.1       rjs 		}
   2486   1.1       rjs #endif /* SCTP_DEBUG */
   2487   1.1       rjs 		net->dest_state = (SCTP_ADDR_REACHABLE |
   2488   1.1       rjs 		    SCTP_ADDR_OUT_OF_SCOPE);
   2489   1.1       rjs 	} else {
   2490   1.1       rjs 		if (from == 8)
   2491   1.1       rjs 			/* 8 is passed by connect_x */
   2492   1.1       rjs 			net->dest_state = SCTP_ADDR_REACHABLE;
   2493   1.1       rjs 		else
   2494   1.1       rjs 			net->dest_state = SCTP_ADDR_REACHABLE |
   2495   1.1       rjs 			    SCTP_ADDR_UNCONFIRMED;
   2496   1.1       rjs 	}
   2497   1.1       rjs 	net->RTO = stcb->asoc.initial_rto;
   2498   1.1       rjs 	stcb->asoc.numnets++;
   2499   1.1       rjs 	net->ref_count = 1;
   2500   1.1       rjs 
   2501   1.1       rjs 	/* Init the timer structure */
   2502   1.1       rjs 	callout_init(&net->rxt_timer.timer, 0);
   2503   1.1       rjs 	callout_init(&net->pmtu_timer.timer, 0);
   2504   1.1       rjs 
   2505   1.1       rjs 	/* Now generate a route for this guy */
   2506   1.1       rjs 	/* KAME hack: embed scope zone ID */
   2507   1.1       rjs 	if (newaddr->sa_family == AF_INET6) {
   2508   1.1       rjs 		struct sockaddr_in6 *sin6;
   2509   1.1       rjs 		sin6 = (struct sockaddr_in6 *)newaddr;
   2510   1.1       rjs 		if (sa6_embedscope(sin6, ip6_use_defzone) != 0)
   2511   1.1       rjs 			return (-1);
   2512   1.1       rjs 	}
   2513   1.1       rjs 	rt = rtcache_lookup(&net->ro, newaddr);
   2514   1.1       rjs 	if (rt) {
   2515   1.1       rjs 		net->mtu = rt->rt_ifp->if_mtu;
   2516   1.1       rjs 		if (from == 1) {
   2517   1.1       rjs 			stcb->asoc.smallest_mtu = net->mtu;
   2518   1.1       rjs 		}
   2519   1.1       rjs 		/* start things off to match mtu of interface please. */
   2520   1.1       rjs 		rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;
   2521   1.1       rjs 	} else {
   2522   1.1       rjs 		net->mtu = stcb->asoc.smallest_mtu;
   2523   1.1       rjs 	}
   2524   1.1       rjs #ifdef SCTP_DEBUG
   2525   1.1       rjs 	printf("After lookup\n");
   2526   1.1       rjs #endif
   2527   1.1       rjs 	if (stcb->asoc.smallest_mtu > net->mtu) {
   2528   1.1       rjs 		stcb->asoc.smallest_mtu = net->mtu;
   2529   1.1       rjs 	}
   2530   1.1       rjs 	/* We take the max of the burst limit times a MTU or the INITIAL_CWND.
   2531   1.1       rjs 	 * We then limit this to 4 MTU's of sending.
   2532   1.1       rjs 	 */
   2533  1.17  riastrad  	net->cwnd = uimin((net->mtu * 4), uimax((stcb->asoc.max_burst * net->mtu), SCTP_INITIAL_CWND));
   2534   1.1       rjs 
   2535   1.1       rjs 	/* we always get at LEAST 2 MTU's */
   2536   1.1       rjs 	if (net->cwnd < (2 * net->mtu)) {
   2537   1.1       rjs 		net->cwnd = 2 * net->mtu;
   2538   1.1       rjs 	}
   2539   1.1       rjs 
   2540   1.1       rjs 	net->ssthresh = stcb->asoc.peers_rwnd;
   2541   1.1       rjs 
   2542   1.1       rjs 	net->src_addr_selected = 0;
   2543   1.1       rjs 	netfirst = TAILQ_FIRST(&stcb->asoc.nets);
   2544   1.1       rjs 	if (rt == NULL) {
   2545   1.1       rjs 		/* Since we have no route put it at the back */
   2546   1.1       rjs 		TAILQ_INSERT_TAIL(&stcb->asoc.nets, net, sctp_next);
   2547   1.1       rjs 	} else if (netfirst == NULL) {
   2548   1.1       rjs 		/* We are the first one in the pool. */
   2549   1.1       rjs 		TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next);
   2550   1.1       rjs 	} else if ((netfirst_rt = rtcache_validate(&netfirst->ro)) == NULL) {
   2551   1.1       rjs 		/*
   2552   1.1       rjs 		 * First one has NO route. Place this one ahead of the
   2553   1.1       rjs 		 * first one.
   2554   1.1       rjs 		 */
   2555   1.1       rjs 		TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next);
   2556   1.1       rjs 	} else if (rt->rt_ifp != netfirst_rt->rt_ifp) {
   2557   1.8     ozaki 		rtcache_unref(netfirst_rt, &netfirst->ro);
   2558   1.1       rjs 		/*
   2559   1.1       rjs 		 * This one has a different interface than the one at the
   2560   1.1       rjs 		 * top of the list. Place it ahead.
   2561   1.1       rjs 		 */
   2562   1.1       rjs 		TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next);
   2563   1.1       rjs 	} else {
   2564   1.1       rjs 		/*
   2565   1.1       rjs 		 * Ok we have the same interface as the first one. Move
   2566   1.1       rjs 		 * forward until we find either
   2567   1.1       rjs 		 *   a) one with a NULL route... insert ahead of that
   2568   1.1       rjs 		 *   b) one with a different ifp.. insert after that.
   2569   1.1       rjs 		 *   c) end of the list.. insert at the tail.
   2570   1.1       rjs 		 */
   2571   1.1       rjs 		struct sctp_nets *netlook;
   2572   1.1       rjs 		struct rtentry *netlook_rt;
   2573   1.1       rjs 		do {
   2574   1.1       rjs 			netlook = TAILQ_NEXT(netfirst, sctp_next);
   2575   1.1       rjs 			if (netlook == NULL) {
   2576   1.1       rjs 				/* End of the list */
   2577   1.1       rjs 				TAILQ_INSERT_TAIL(&stcb->asoc.nets, net,
   2578   1.1       rjs 				    sctp_next);
   2579   1.1       rjs 				break;
   2580   1.1       rjs 			} else if ((netlook_rt = rtcache_validate(&netlook->ro)) == NULL) {
   2581   1.1       rjs 				/* next one has NO route */
   2582   1.1       rjs 				TAILQ_INSERT_BEFORE(netfirst, net, sctp_next);
   2583   1.1       rjs 				break;
   2584   1.1       rjs 			} else if (netlook_rt->rt_ifp != rt->rt_ifp) {
   2585   1.8     ozaki 				rtcache_unref(netlook_rt, &netlook->ro);
   2586   1.1       rjs 				TAILQ_INSERT_AFTER(&stcb->asoc.nets, netlook,
   2587   1.1       rjs 				    net, sctp_next);
   2588   1.1       rjs 				break;
   2589   1.1       rjs 			}
   2590   1.8     ozaki 			rtcache_unref(netlook_rt, &netlook->ro);
   2591   1.1       rjs 			/* Shift forward */
   2592   1.1       rjs 			netfirst = netlook;
   2593   1.1       rjs 		} while (netlook != NULL);
   2594   1.8     ozaki 		rtcache_unref(netfirst_rt, &netfirst->ro);
   2595   1.1       rjs 	}
   2596   1.1       rjs 	/* got to have a primary set */
   2597   1.1       rjs 	if (stcb->asoc.primary_destination == 0) {
   2598   1.1       rjs 		stcb->asoc.primary_destination = net;
   2599   1.1       rjs 	} else if (!rtcache_validate(&stcb->asoc.primary_destination->ro)) {
   2600   1.1       rjs 		/* No route to current primary adopt new primary */
   2601   1.1       rjs 		stcb->asoc.primary_destination = net;
   2602   1.1       rjs 	}
   2603   1.1       rjs 	sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb,
   2604   1.1       rjs 	    net);
   2605   1.1       rjs 
   2606   1.1       rjs 	return (0);
   2607   1.1       rjs }
   2608   1.1       rjs 
   2609   1.1       rjs 
   2610   1.1       rjs /*
   2611   1.1       rjs  * allocate an association and add it to the endpoint. The caller must
   2612   1.1       rjs  * be careful to add all additional addresses once they are know right
   2613   1.1       rjs  * away or else the assoc will be may experience a blackout scenario.
   2614   1.1       rjs  */
   2615   1.1       rjs struct sctp_tcb *
   2616   1.1       rjs sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
   2617   1.1       rjs     int for_a_init, int *error,  uint32_t override_tag)
   2618   1.1       rjs {
   2619   1.1       rjs 	struct sctp_tcb *stcb;
   2620   1.1       rjs 	struct sctp_association *asoc;
   2621   1.1       rjs 	struct sctpasochead *head;
   2622   1.1       rjs 	uint16_t rport;
   2623   1.1       rjs 	int err;
   2624   1.1       rjs 
   2625   1.1       rjs 	/*
   2626   1.1       rjs 	 * Assumption made here:
   2627   1.1       rjs 	 *  Caller has done a sctp_findassociation_ep_addr(ep, addr's);
   2628   1.1       rjs 	 *  to make sure the address does not exist already.
   2629   1.1       rjs 	 */
   2630   1.1       rjs 	if (sctppcbinfo.ipi_count_asoc >= SCTP_MAX_NUM_OF_ASOC) {
   2631   1.1       rjs 		/* Hit max assoc, sorry no more */
   2632   1.1       rjs 		*error = ENOBUFS;
   2633   1.1       rjs 		return (NULL);
   2634   1.1       rjs 	}
   2635   1.1       rjs 	SCTP_INP_RLOCK(inp);
   2636   1.1       rjs 	if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) {
   2637   1.1       rjs 		/*
   2638   1.1       rjs 		 * If its in the TCP pool, its NOT allowed to create an
   2639   1.1       rjs 		 * association. The parent listener needs to call
   2640   1.1       rjs 		 * sctp_aloc_assoc.. or the one-2-many socket. If a
   2641   1.1       rjs 		 * peeled off, or connected one does this.. its an error.
   2642   1.1       rjs 		 */
   2643   1.1       rjs 		SCTP_INP_RUNLOCK(inp);
   2644   1.1       rjs 		*error = EINVAL;
   2645   1.1       rjs 		return (NULL);
   2646   1.1       rjs  	}
   2647   1.1       rjs 
   2648   1.1       rjs #ifdef SCTP_DEBUG
   2649   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB3) {
   2650   1.1       rjs 		printf("Allocate an association for peer:");
   2651   1.1       rjs 		if (firstaddr)
   2652   1.1       rjs 			sctp_print_address(firstaddr);
   2653   1.1       rjs 		else
   2654   1.1       rjs 			printf("None\n");
   2655   1.1       rjs 		printf("Port:%d\n",
   2656   1.1       rjs 		       ntohs(((struct sockaddr_in *)firstaddr)->sin_port));
   2657   1.1       rjs 	}
   2658   1.1       rjs #endif /* SCTP_DEBUG */
   2659   1.1       rjs 	if (firstaddr->sa_family == AF_INET) {
   2660   1.1       rjs 		struct sockaddr_in *sin;
   2661   1.1       rjs 		sin = (struct sockaddr_in *)firstaddr;
   2662   1.1       rjs 		if ((sin->sin_port == 0) || (sin->sin_addr.s_addr == 0)) {
   2663   1.1       rjs 			/* Invalid address */
   2664   1.1       rjs #ifdef SCTP_DEBUG
   2665   1.1       rjs 			if (sctp_debug_on & SCTP_DEBUG_PCB3) {
   2666   1.1       rjs 				printf("peer address invalid\n");
   2667   1.1       rjs 			}
   2668   1.1       rjs #endif
   2669   1.1       rjs 			SCTP_INP_RUNLOCK(inp);
   2670   1.1       rjs 			*error = EINVAL;
   2671   1.1       rjs 			return (NULL);
   2672   1.1       rjs 		}
   2673   1.1       rjs 		rport = sin->sin_port;
   2674   1.1       rjs 	} else if (firstaddr->sa_family == AF_INET6) {
   2675   1.1       rjs 		struct sockaddr_in6 *sin6;
   2676   1.1       rjs 		sin6 = (struct sockaddr_in6 *)firstaddr;
   2677   1.1       rjs 		if ((sin6->sin6_port == 0) ||
   2678   1.1       rjs 		    (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))) {
   2679   1.1       rjs 			/* Invalid address */
   2680   1.1       rjs #ifdef SCTP_DEBUG
   2681   1.1       rjs 			if (sctp_debug_on & SCTP_DEBUG_PCB3) {
   2682   1.1       rjs 				printf("peer address invalid\n");
   2683   1.1       rjs 			}
   2684   1.1       rjs #endif
   2685   1.1       rjs 			SCTP_INP_RUNLOCK(inp);
   2686   1.1       rjs 			*error = EINVAL;
   2687   1.1       rjs 			return (NULL);
   2688   1.1       rjs 		}
   2689   1.1       rjs 		rport = sin6->sin6_port;
   2690   1.1       rjs 	} else {
   2691   1.1       rjs 		/* not supported family type */
   2692   1.1       rjs #ifdef SCTP_DEBUG
   2693   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_PCB3) {
   2694   1.1       rjs 			printf("BAD family %d\n", firstaddr->sa_family);
   2695   1.1       rjs 		}
   2696   1.1       rjs #endif
   2697   1.1       rjs 		SCTP_INP_RUNLOCK(inp);
   2698   1.1       rjs 		*error = EINVAL;
   2699   1.1       rjs 		return (NULL);
   2700   1.1       rjs 	}
   2701   1.1       rjs 	SCTP_INP_RUNLOCK(inp);
   2702   1.1       rjs 	if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
   2703   1.1       rjs 		/*
   2704   1.1       rjs 		 * If you have not performed a bind, then we need to do
   2705   1.1       rjs 		 * the ephemerial bind for you.
   2706   1.1       rjs 		 */
   2707   1.1       rjs #ifdef SCTP_DEBUG
   2708   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_PCB3) {
   2709   1.1       rjs 			printf("Doing implicit BIND\n");
   2710   1.1       rjs 		}
   2711   1.1       rjs #endif
   2712   1.1       rjs 
   2713   1.1       rjs 		if ((err = sctp_inpcb_bind(inp->sctp_socket,
   2714   1.1       rjs 		    (struct sockaddr *)NULL, (struct lwp *)NULL))){
   2715   1.1       rjs 			/* bind error, probably perm */
   2716   1.1       rjs #ifdef SCTP_DEBUG
   2717   1.1       rjs 			if (sctp_debug_on & SCTP_DEBUG_PCB3) {
   2718   1.1       rjs 				printf("BIND FAILS ret:%d\n", err);
   2719   1.1       rjs 			}
   2720   1.1       rjs #endif
   2721   1.1       rjs 
   2722   1.1       rjs 			*error = err;
   2723   1.1       rjs 			return (NULL);
   2724   1.1       rjs 		}
   2725   1.1       rjs 	}
   2726   1.1       rjs 	stcb = (struct sctp_tcb *)SCTP_ZONE_GET(sctppcbinfo.ipi_zone_asoc);
   2727   1.1       rjs 	if (stcb == NULL) {
   2728   1.1       rjs 		/* out of memory? */
   2729   1.1       rjs #ifdef SCTP_DEBUG
   2730   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_PCB3) {
   2731   1.1       rjs 			printf("aloc_assoc: no assoc mem left, stcb=NULL\n");
   2732   1.1       rjs 		}
   2733   1.1       rjs #endif
   2734   1.1       rjs 		*error = ENOMEM;
   2735   1.1       rjs 		return (NULL);
   2736   1.1       rjs 	}
   2737   1.1       rjs 	sctppcbinfo.ipi_count_asoc++;
   2738   1.1       rjs 	sctppcbinfo.ipi_gencnt_asoc++;
   2739   1.1       rjs 
   2740   1.1       rjs 	memset(stcb, 0, sizeof(*stcb));
   2741   1.1       rjs 	asoc = &stcb->asoc;
   2742   1.1       rjs 	SCTP_TCB_LOCK_INIT(stcb);
   2743   1.1       rjs 	/* setup back pointers */
   2744   1.1       rjs #ifdef SCTP_DEBUG
   2745   1.1       rjs 	printf("Before back pointers\n");
   2746   1.1       rjs #endif
   2747   1.1       rjs 	stcb->sctp_ep = inp;
   2748   1.1       rjs 	stcb->sctp_socket = inp->sctp_socket;
   2749   1.1       rjs 	if ((err = sctp_init_asoc(inp, asoc, for_a_init, override_tag))) {
   2750   1.1       rjs 		/* failed */
   2751   1.1       rjs 		SCTP_TCB_LOCK_DESTROY (stcb);
   2752   1.1       rjs 		SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_asoc, stcb);
   2753   1.1       rjs 		sctppcbinfo.ipi_count_asoc--;
   2754   1.1       rjs #ifdef SCTP_DEBUG
   2755   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_PCB3) {
   2756   1.1       rjs 			printf("aloc_assoc: couldn't init asoc, out of mem?!\n");
   2757   1.1       rjs 		}
   2758   1.1       rjs #endif
   2759   1.1       rjs 		*error = err;
   2760   1.1       rjs 		return (NULL);
   2761   1.1       rjs 	}
   2762   1.1       rjs 	/* and the port */
   2763   1.1       rjs 	stcb->rport = rport;
   2764   1.1       rjs 	SCTP_INP_INFO_WLOCK();
   2765   1.1       rjs 	SCTP_INP_WLOCK(inp);
   2766   1.1       rjs 	if (inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE|SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
   2767   1.1       rjs 		/* inpcb freed while alloc going on */
   2768   1.1       rjs 		SCTP_TCB_LOCK_DESTROY (stcb);
   2769   1.1       rjs 		SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_asoc, stcb);
   2770   1.1       rjs 		SCTP_INP_WUNLOCK(inp);
   2771   1.1       rjs 		SCTP_INP_INFO_WUNLOCK();
   2772   1.1       rjs 		sctppcbinfo.ipi_count_asoc--;
   2773   1.1       rjs #ifdef SCTP_DEBUG
   2774   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_PCB3) {
   2775   1.1       rjs 			printf("aloc_assoc: couldn't init asoc, out of mem?!\n");
   2776   1.1       rjs 		}
   2777   1.1       rjs #endif
   2778   1.1       rjs 		*error = EINVAL;
   2779   1.1       rjs 		return (NULL);
   2780   1.1       rjs 	}
   2781   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   2782   1.1       rjs 
   2783   1.1       rjs 	/* now that my_vtag is set, add it to the  hash */
   2784   1.1       rjs 	head = &sctppcbinfo.sctp_asochash[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag,
   2785   1.1       rjs 	     sctppcbinfo.hashasocmark)];
   2786   1.1       rjs 	/* put it in the bucket in the vtag hash of assoc's for the system */
   2787   1.1       rjs 	LIST_INSERT_HEAD(head, stcb, sctp_asocs);
   2788   1.1       rjs 	SCTP_INP_INFO_WUNLOCK();
   2789   1.1       rjs 
   2790   1.1       rjs 
   2791   1.1       rjs 	if ((err = sctp_add_remote_addr(stcb, firstaddr, 1, 1))) {
   2792   1.1       rjs 		/* failure.. memory error? */
   2793   1.1       rjs 		if (asoc->strmout)
   2794   1.1       rjs 			free(asoc->strmout, M_PCB);
   2795   1.1       rjs 		if (asoc->mapping_array)
   2796   1.1       rjs 			free(asoc->mapping_array, M_PCB);
   2797   1.1       rjs 
   2798   1.1       rjs 		SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_asoc, stcb);
   2799   1.1       rjs 		sctppcbinfo.ipi_count_asoc--;
   2800   1.1       rjs #ifdef SCTP_DEBUG
   2801   1.1       rjs 		if (sctp_debug_on & SCTP_DEBUG_PCB3) {
   2802   1.1       rjs 			printf("aloc_assoc: couldn't add remote addr!\n");
   2803   1.1       rjs 		}
   2804   1.1       rjs #endif
   2805   1.1       rjs 		SCTP_TCB_LOCK_DESTROY (stcb);
   2806   1.1       rjs 		*error = ENOBUFS;
   2807   1.1       rjs 		return (NULL);
   2808   1.1       rjs 	}
   2809   1.1       rjs 	/* Init all the timers */
   2810   1.1       rjs 	callout_init(&asoc->hb_timer.timer, 0);
   2811   1.1       rjs 	callout_init(&asoc->dack_timer.timer, 0);
   2812   1.1       rjs 	callout_init(&asoc->asconf_timer.timer, 0);
   2813   1.1       rjs 	callout_init(&asoc->shut_guard_timer.timer, 0);
   2814   1.1       rjs 	callout_init(&asoc->autoclose_timer.timer, 0);
   2815   1.1       rjs 	callout_init(&asoc->delayed_event_timer.timer, 0);
   2816   1.1       rjs 	LIST_INSERT_HEAD(&inp->sctp_asoc_list, stcb, sctp_tcblist);
   2817   1.1       rjs 	/* now file the port under the hash as well */
   2818   1.1       rjs #ifdef SCTP_DEBUG
   2819   1.1       rjs 	printf("Before hashing %ld size %d\n",
   2820   1.1       rjs 		inp->sctp_hashmark, sctp_pcbtblsize);
   2821   1.1       rjs #endif
   2822   1.1       rjs 	if (inp->sctp_tcbhash != NULL) {
   2823   1.1       rjs 		head = &inp->sctp_tcbhash[SCTP_PCBHASH_ALLADDR(stcb->rport,
   2824   1.1       rjs 		   inp->sctp_hashmark)];
   2825   1.1       rjs 		LIST_INSERT_HEAD(head, stcb, sctp_tcbhash);
   2826   1.1       rjs 	}
   2827   1.1       rjs #ifdef SCTP_DEBUG
   2828   1.1       rjs 	printf("After hashing\n");
   2829   1.1       rjs #endif
   2830   1.1       rjs 	SCTP_INP_WUNLOCK(inp);
   2831   1.1       rjs #ifdef SCTP_DEBUG
   2832   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   2833   1.1       rjs 		printf("Association %p now allocated\n", stcb);
   2834   1.1       rjs 	}
   2835   1.1       rjs #endif
   2836   1.1       rjs 	return (stcb);
   2837   1.1       rjs }
   2838   1.1       rjs 
   2839   1.1       rjs void
   2840   1.1       rjs sctp_free_remote_addr(struct sctp_nets *net)
   2841   1.1       rjs {
   2842   1.1       rjs 	if (net == NULL)
   2843   1.1       rjs 		return;
   2844   1.1       rjs 	net->ref_count--;
   2845   1.1       rjs 	if (net->ref_count <= 0) {
   2846   1.1       rjs 		/* stop timer if running */
   2847   1.1       rjs 		callout_stop(&net->rxt_timer.timer);
   2848   1.1       rjs 		callout_stop(&net->pmtu_timer.timer);
   2849   1.1       rjs 		callout_destroy(&net->rxt_timer.timer);
   2850   1.1       rjs 		callout_destroy(&net->pmtu_timer.timer);
   2851   1.1       rjs 		net->dest_state = SCTP_ADDR_NOT_REACHABLE;
   2852   1.6       rjs 		rtcache_free(&net->ro);
   2853   1.1       rjs 		SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_net, net);
   2854   1.1       rjs 		sctppcbinfo.ipi_count_raddr--;
   2855   1.1       rjs 	}
   2856   1.1       rjs }
   2857   1.1       rjs 
   2858   1.1       rjs /*
   2859   1.1       rjs  * remove a remote endpoint address from an association, it
   2860   1.1       rjs  * will fail if the address does not exist.
   2861   1.1       rjs  */
   2862   1.1       rjs int
   2863   1.1       rjs sctp_del_remote_addr(struct sctp_tcb *stcb, struct sockaddr *remaddr)
   2864   1.1       rjs {
   2865   1.1       rjs 	/*
   2866   1.1       rjs 	 * Here we need to remove a remote address. This is quite simple, we
   2867   1.1       rjs 	 * first find it in the list of address for the association
   2868   1.1       rjs 	 * (tasoc->asoc.nets) and then if it is there, we do a LIST_REMOVE on
   2869   1.1       rjs 	 * that item.
   2870   1.1       rjs 	 * Note we do not allow it to be removed if there are no other
   2871   1.1       rjs 	 * addresses.
   2872   1.1       rjs 	 */
   2873   1.1       rjs 	struct sctp_association *asoc;
   2874   1.1       rjs 	struct sctp_nets *net, *net_tmp;
   2875   1.1       rjs 	asoc = &stcb->asoc;
   2876   1.1       rjs 	if (asoc->numnets < 2) {
   2877   1.1       rjs 		/* Must have at LEAST two remote addresses */
   2878   1.1       rjs 		return (-1);
   2879   1.1       rjs 	}
   2880   1.1       rjs 	/* locate the address */
   2881   1.1       rjs 	for (net = TAILQ_FIRST(&asoc->nets); net != NULL; net = net_tmp) {
   2882   1.1       rjs 		net_tmp = TAILQ_NEXT(net, sctp_next);
   2883   1.1       rjs 		if (rtcache_getdst(&net->ro)->sa_family != remaddr->sa_family) {
   2884   1.1       rjs 			continue;
   2885   1.1       rjs 		}
   2886   1.1       rjs 		if (sctp_cmpaddr(rtcache_getdst(&net->ro), remaddr)) {
   2887   1.1       rjs 			/* we found the guy */
   2888   1.1       rjs 			asoc->numnets--;
   2889   1.1       rjs 			TAILQ_REMOVE(&asoc->nets, net, sctp_next);
   2890   1.1       rjs 			sctp_free_remote_addr(net);
   2891   1.1       rjs 			if (net == asoc->primary_destination) {
   2892   1.1       rjs 				/* Reset primary */
   2893   1.1       rjs 				struct sctp_nets *lnet;
   2894   1.1       rjs 				lnet = TAILQ_FIRST(&asoc->nets);
   2895   1.1       rjs 				/* Try to find a confirmed primary */
   2896   1.1       rjs 				asoc->primary_destination =
   2897   1.1       rjs 				    sctp_find_alternate_net(stcb, lnet);
   2898   1.1       rjs 			}
   2899   1.1       rjs 			if (net == asoc->last_data_chunk_from) {
   2900   1.1       rjs 				/* Reset primary */
   2901   1.1       rjs 				asoc->last_data_chunk_from =
   2902   1.1       rjs 				    TAILQ_FIRST(&asoc->nets);
   2903   1.1       rjs 			}
   2904   1.1       rjs 			if (net == asoc->last_control_chunk_from) {
   2905   1.1       rjs 				/* Reset primary */
   2906   1.1       rjs 				asoc->last_control_chunk_from =
   2907   1.1       rjs 				    TAILQ_FIRST(&asoc->nets);
   2908   1.1       rjs 			}
   2909   1.1       rjs 			if (net == asoc->asconf_last_sent_to) {
   2910   1.1       rjs 				/* Reset primary */
   2911   1.1       rjs 				asoc->asconf_last_sent_to =
   2912   1.1       rjs 				    TAILQ_FIRST(&asoc->nets);
   2913   1.1       rjs 			}
   2914   1.1       rjs 			return (0);
   2915   1.1       rjs 		}
   2916   1.1       rjs 	}
   2917   1.1       rjs 	/* not found. */
   2918   1.1       rjs 	return (-2);
   2919   1.1       rjs }
   2920   1.1       rjs 
   2921   1.1       rjs 
   2922   1.1       rjs static void
   2923   1.1       rjs sctp_add_vtag_to_timewait(struct sctp_inpcb *inp, u_int32_t tag)
   2924   1.1       rjs {
   2925   1.1       rjs 	struct sctpvtaghead *chain;
   2926   1.1       rjs 	struct sctp_tagblock *twait_block;
   2927   1.1       rjs 	struct timeval now;
   2928   1.1       rjs 	int set, i;
   2929   1.1       rjs 	SCTP_GETTIME_TIMEVAL(&now);
   2930   1.1       rjs 	chain = &sctppcbinfo.vtag_timewait[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
   2931   1.1       rjs 	set = 0;
   2932   1.1       rjs 	if (!LIST_EMPTY(chain)) {
   2933   1.1       rjs 		/* Block(s) present, lets find space, and expire on the fly */
   2934   1.1       rjs 		LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
   2935   1.1       rjs 			for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
   2936   1.1       rjs 				if ((twait_block->vtag_block[i].v_tag == 0) &&
   2937   1.1       rjs 				    !set) {
   2938   1.1       rjs 					twait_block->vtag_block[0].tv_sec_at_expire =
   2939   1.1       rjs 					    now.tv_sec + SCTP_TIME_WAIT;
   2940   1.1       rjs 					twait_block->vtag_block[0].v_tag = tag;
   2941   1.1       rjs 					set = 1;
   2942   1.1       rjs 				} else if ((twait_block->vtag_block[i].v_tag) &&
   2943   1.1       rjs 				    ((long)twait_block->vtag_block[i].tv_sec_at_expire >
   2944   1.1       rjs 				    now.tv_sec)) {
   2945   1.1       rjs 					/* Audit expires this guy */
   2946   1.1       rjs 					twait_block->vtag_block[i].tv_sec_at_expire = 0;
   2947   1.1       rjs 					twait_block->vtag_block[i].v_tag = 0;
   2948   1.1       rjs 					if (set == 0) {
   2949   1.1       rjs 						/* Reuse it for my new tag */
   2950   1.1       rjs 						twait_block->vtag_block[0].tv_sec_at_expire = now.tv_sec + SCTP_TIME_WAIT;
   2951   1.1       rjs 						twait_block->vtag_block[0].v_tag = tag;
   2952   1.1       rjs 						set = 1;
   2953   1.1       rjs 					}
   2954   1.1       rjs 				}
   2955   1.1       rjs 			}
   2956   1.1       rjs 			if (set) {
   2957   1.1       rjs 				/*
   2958   1.1       rjs 				 * We only do up to the block where we can
   2959   1.1       rjs 				 * place our tag for audits
   2960   1.1       rjs 				 */
   2961   1.1       rjs 				break;
   2962   1.1       rjs 			}
   2963   1.1       rjs 		}
   2964   1.1       rjs 	}
   2965   1.1       rjs 	/* Need to add a new block to chain */
   2966   1.1       rjs 	if (!set) {
   2967   1.1       rjs 		twait_block = malloc(sizeof(struct sctp_tagblock), M_PCB, M_NOWAIT);
   2968   1.1       rjs 		if (twait_block == NULL) {
   2969   1.1       rjs 			return;
   2970   1.1       rjs 		}
   2971   1.1       rjs 		memset(twait_block, 0, sizeof(struct sctp_timewait));
   2972   1.1       rjs 		LIST_INSERT_HEAD(chain, twait_block, sctp_nxt_tagblock);
   2973   1.1       rjs 		twait_block->vtag_block[0].tv_sec_at_expire = now.tv_sec +
   2974   1.1       rjs 		    SCTP_TIME_WAIT;
   2975   1.1       rjs 		twait_block->vtag_block[0].v_tag = tag;
   2976   1.1       rjs 	}
   2977   1.1       rjs }
   2978   1.1       rjs 
   2979   1.1       rjs 
   2980   1.1       rjs static void
   2981   1.1       rjs sctp_iterator_asoc_being_freed(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
   2982   1.1       rjs {
   2983   1.1       rjs 	struct sctp_iterator *it;
   2984   1.1       rjs 
   2985   1.1       rjs 
   2986   1.1       rjs 
   2987   1.1       rjs 	/* Unlock the tcb lock we do this so
   2988   1.1       rjs 	 * we avoid a dead lock scenario where
   2989   1.1       rjs 	 * the iterator is waiting on the TCB lock
   2990   1.1       rjs 	 * and the TCB lock is waiting on the iterator
   2991   1.1       rjs 	 * lock.
   2992   1.1       rjs 	 */
   2993   1.1       rjs 	SCTP_ITERATOR_LOCK();
   2994   1.1       rjs 	SCTP_INP_INFO_WLOCK();
   2995   1.1       rjs 	SCTP_INP_WLOCK(inp);
   2996   1.1       rjs 	SCTP_TCB_LOCK(stcb);
   2997   1.1       rjs 
   2998   1.1       rjs 	it = stcb->asoc.stcb_starting_point_for_iterator;
   2999   1.1       rjs 	if (it == NULL) {
   3000   1.1       rjs 		return;
   3001   1.1       rjs 	}
   3002   1.1       rjs 	if (it->inp != stcb->sctp_ep) {
   3003   1.1       rjs 		/* hm, focused on the wrong one? */
   3004   1.1       rjs 		return;
   3005   1.1       rjs 	}
   3006   1.1       rjs 	if (it->stcb != stcb) {
   3007   1.1       rjs 		return;
   3008   1.1       rjs 	}
   3009   1.1       rjs 	it->stcb = LIST_NEXT(stcb, sctp_tcblist);
   3010   1.1       rjs 	if (it->stcb == NULL) {
   3011   1.1       rjs 		/* done with all asoc's in this assoc */
   3012   1.1       rjs 		if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
   3013   1.1       rjs 			it->inp = NULL;
   3014   1.1       rjs 		} else {
   3015   1.1       rjs 
   3016   1.1       rjs 			it->inp = LIST_NEXT(inp, sctp_list);
   3017   1.1       rjs 		}
   3018   1.1       rjs 	}
   3019   1.1       rjs }
   3020   1.1       rjs 
   3021   1.1       rjs /*
   3022   1.1       rjs  * Free the association after un-hashing the remote port.
   3023   1.1       rjs  */
   3024   1.1       rjs void
   3025   1.1       rjs sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
   3026   1.1       rjs {
   3027   1.1       rjs 	struct sctp_association *asoc;
   3028   1.1       rjs 	struct sctp_nets *net, *prev;
   3029   1.1       rjs 	struct sctp_laddr *laddr;
   3030   1.1       rjs 	struct sctp_tmit_chunk *chk;
   3031   1.1       rjs 	struct sctp_asconf_addr *aparam;
   3032   1.1       rjs 	struct sctp_socket_q_list *sq;
   3033   1.1       rjs 	int s;
   3034   1.1       rjs 
   3035   1.1       rjs 	/* first, lets purge the entry from the hash table. */
   3036   1.1       rjs 	s = splsoftnet();
   3037   1.1       rjs 	if (stcb->asoc.state == 0) {
   3038   1.1       rjs 		printf("Freeing already free association:%p - huh??\n",
   3039   1.1       rjs 		    stcb);
   3040   1.1       rjs 		splx(s);
   3041   1.1       rjs 		return;
   3042   1.1       rjs 	}
   3043   1.1       rjs 	asoc = &stcb->asoc;
   3044   1.1       rjs 	asoc->state = 0;
   3045   1.1       rjs 	/* now clean up any other timers */
   3046   1.1       rjs 	callout_stop(&asoc->hb_timer.timer);
   3047   1.1       rjs 	callout_destroy(&asoc->hb_timer.timer);
   3048   1.1       rjs 	callout_stop(&asoc->dack_timer.timer);
   3049   1.1       rjs 	callout_destroy(&asoc->dack_timer.timer);
   3050   1.1       rjs 	callout_stop(&asoc->asconf_timer.timer);
   3051   1.1       rjs 	callout_destroy(&asoc->asconf_timer.timer);
   3052   1.1       rjs 	callout_stop(&asoc->shut_guard_timer.timer);
   3053   1.1       rjs 	callout_destroy(&asoc->shut_guard_timer.timer);
   3054   1.1       rjs 	callout_stop(&asoc->autoclose_timer.timer);
   3055   1.1       rjs 	callout_destroy(&asoc->autoclose_timer.timer);
   3056   1.1       rjs 	callout_stop(&asoc->delayed_event_timer.timer);
   3057   1.1       rjs 	callout_destroy(&asoc->delayed_event_timer.timer);
   3058   1.1       rjs 	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
   3059   1.1       rjs 		callout_stop(&net->rxt_timer.timer);
   3060   1.1       rjs 		callout_stop(&net->pmtu_timer.timer);
   3061   1.1       rjs 		callout_destroy(&net->rxt_timer.timer);
   3062   1.1       rjs 		callout_destroy(&net->pmtu_timer.timer);
   3063   1.1       rjs 	}
   3064   1.1       rjs 
   3065   1.1       rjs 	/* Iterator asoc being freed we send an
   3066   1.1       rjs 	 * unlocked TCB. It returns with INP_INFO
   3067   1.1       rjs 	 * and INP write locked and the TCB locked
   3068   1.1       rjs 	 * too and of course the iterator lock
   3069   1.1       rjs 	 * in place as well..
   3070   1.1       rjs 	 */
   3071   1.1       rjs 	SCTP_TCB_UNLOCK(stcb);
   3072   1.1       rjs 	sctp_iterator_asoc_being_freed(inp, stcb);
   3073   1.1       rjs 
   3074   1.1       rjs 	/* Null all of my entry's on the socket q */
   3075   1.1       rjs 	TAILQ_FOREACH(sq, &inp->sctp_queue_list, next_sq) {
   3076   1.1       rjs 		if (sq->tcb == stcb) {
   3077   1.1       rjs 			sq->tcb = NULL;
   3078   1.1       rjs 		}
   3079   1.1       rjs 	}
   3080   1.1       rjs 
   3081   1.1       rjs 	if (inp->sctp_tcb_at_block == (void *)stcb) {
   3082   1.1       rjs 		inp->error_on_block = ECONNRESET;
   3083   1.1       rjs 	}
   3084   1.1       rjs 
   3085   1.1       rjs 	if (inp->sctp_tcbhash) {
   3086   1.1       rjs 		LIST_REMOVE(stcb, sctp_tcbhash);
   3087   1.1       rjs 	}
   3088   1.1       rjs 	/* Now lets remove it from the list of ALL associations in the EP */
   3089   1.1       rjs 	LIST_REMOVE(stcb, sctp_tcblist);
   3090   1.1       rjs 	SCTP_INP_WUNLOCK(inp);
   3091   1.1       rjs 	SCTP_ITERATOR_UNLOCK();
   3092   1.1       rjs 
   3093   1.1       rjs 
   3094   1.1       rjs 	/* pull from vtag hash */
   3095   1.1       rjs 	LIST_REMOVE(stcb, sctp_asocs);
   3096   1.1       rjs 
   3097   1.1       rjs 	/*
   3098   1.1       rjs 	 * Now before we can free the assoc, we must  remove all of the
   3099   1.1       rjs 	 * networks and any other allocated space.. i.e. add removes here
   3100   1.1       rjs 	 * before the SCTP_ZONE_FREE() of the tasoc entry.
   3101   1.1       rjs 	 */
   3102   1.1       rjs 
   3103   1.1       rjs 	sctp_add_vtag_to_timewait(inp, asoc->my_vtag);
   3104   1.1       rjs 	SCTP_INP_INFO_WUNLOCK();
   3105   1.1       rjs 	prev = NULL;
   3106   1.1       rjs 	while (!TAILQ_EMPTY(&asoc->nets)) {
   3107   1.1       rjs 		net = TAILQ_FIRST(&asoc->nets);
   3108   1.1       rjs 		/* pull from list */
   3109   1.1       rjs 		if ((sctppcbinfo.ipi_count_raddr == 0) || (prev == net)) {
   3110   1.1       rjs 			break;
   3111   1.1       rjs 		}
   3112   1.1       rjs 		prev = net;
   3113   1.1       rjs 		TAILQ_REMOVE(&asoc->nets, net, sctp_next);
   3114   1.6       rjs 		rtcache_free(&net->ro);
   3115   1.1       rjs 		/* free it */
   3116   1.1       rjs 		net->ref_count = 0;
   3117   1.1       rjs 		SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_net, net);
   3118   1.1       rjs 		sctppcbinfo.ipi_count_raddr--;
   3119   1.1       rjs 	}
   3120   1.1       rjs 	/*
   3121   1.1       rjs 	 * The chunk lists and such SHOULD be empty but we check them
   3122   1.1       rjs 	 * just in case.
   3123   1.1       rjs 	 */
   3124   1.1       rjs 	/* anything on the wheel needs to be removed */
   3125   1.1       rjs 	while (!TAILQ_EMPTY(&asoc->out_wheel)) {
   3126   1.1       rjs 		struct sctp_stream_out *outs;
   3127   1.1       rjs 		outs = TAILQ_FIRST(&asoc->out_wheel);
   3128   1.1       rjs 		TAILQ_REMOVE(&asoc->out_wheel, outs, next_spoke);
   3129   1.1       rjs 		/* now clean up any chunks here */
   3130   1.1       rjs 		chk = TAILQ_FIRST(&outs->outqueue);
   3131   1.1       rjs 		while (chk) {
   3132   1.1       rjs 			TAILQ_REMOVE(&outs->outqueue, chk, sctp_next);
   3133   1.1       rjs 			if (chk->data) {
   3134   1.1       rjs 				sctp_m_freem(chk->data);
   3135   1.1       rjs 				chk->data = NULL;
   3136   1.1       rjs 			}
   3137   1.1       rjs 			chk->whoTo = NULL;
   3138   1.1       rjs 			chk->asoc = NULL;
   3139   1.1       rjs 			/* Free the chunk */
   3140   1.1       rjs 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   3141   1.1       rjs 			sctppcbinfo.ipi_count_chunk--;
   3142   1.1       rjs 			sctppcbinfo.ipi_gencnt_chunk++;
   3143   1.1       rjs 			if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   3144   1.1       rjs 				panic("Chunk count is negative");
   3145   1.1       rjs 			}
   3146   1.1       rjs 			chk = TAILQ_FIRST(&outs->outqueue);
   3147   1.1       rjs 		}
   3148   1.1       rjs 		outs = TAILQ_FIRST(&asoc->out_wheel);
   3149   1.1       rjs 	}
   3150   1.1       rjs 
   3151   1.1       rjs 	if (asoc->pending_reply) {
   3152   1.1       rjs 		free(asoc->pending_reply, M_PCB);
   3153   1.1       rjs 		asoc->pending_reply = NULL;
   3154   1.1       rjs 	}
   3155   1.1       rjs 	chk = TAILQ_FIRST(&asoc->pending_reply_queue);
   3156   1.1       rjs 	while (chk) {
   3157   1.1       rjs 		TAILQ_REMOVE(&asoc->pending_reply_queue, chk, sctp_next);
   3158   1.1       rjs 		if (chk->data) {
   3159   1.1       rjs 			sctp_m_freem(chk->data);
   3160   1.1       rjs 			chk->data = NULL;
   3161   1.1       rjs 		}
   3162   1.1       rjs 		chk->whoTo = NULL;
   3163   1.1       rjs 		chk->asoc = NULL;
   3164   1.1       rjs 		/* Free the chunk */
   3165   1.1       rjs 		SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   3166   1.1       rjs 		sctppcbinfo.ipi_count_chunk--;
   3167   1.1       rjs 		sctppcbinfo.ipi_gencnt_chunk++;
   3168   1.1       rjs 		if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   3169   1.1       rjs 			panic("Chunk count is negative");
   3170   1.1       rjs 		}
   3171   1.1       rjs 		chk = TAILQ_FIRST(&asoc->pending_reply_queue);
   3172   1.1       rjs 	}
   3173   1.1       rjs 	/* pending send queue SHOULD be empty */
   3174   1.1       rjs 	if (!TAILQ_EMPTY(&asoc->send_queue)) {
   3175   1.1       rjs 		chk = TAILQ_FIRST(&asoc->send_queue);
   3176   1.1       rjs 		while (chk) {
   3177   1.1       rjs 			TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
   3178   1.1       rjs 			if (chk->data) {
   3179   1.1       rjs 				sctp_m_freem(chk->data);
   3180   1.1       rjs 				chk->data = NULL;
   3181   1.1       rjs 			}
   3182   1.1       rjs 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   3183   1.1       rjs 			sctppcbinfo.ipi_count_chunk--;
   3184   1.1       rjs 			if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   3185   1.1       rjs 				panic("Chunk count is negative");
   3186   1.1       rjs 			}
   3187   1.1       rjs 			sctppcbinfo.ipi_gencnt_chunk++;
   3188   1.1       rjs 			chk = TAILQ_FIRST(&asoc->send_queue);
   3189   1.1       rjs 		}
   3190   1.1       rjs 	}
   3191   1.1       rjs 	/* sent queue SHOULD be empty */
   3192   1.1       rjs 	if (!TAILQ_EMPTY(&asoc->sent_queue)) {
   3193   1.1       rjs 		chk = TAILQ_FIRST(&asoc->sent_queue);
   3194   1.1       rjs 		while (chk) {
   3195   1.1       rjs 			TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
   3196   1.1       rjs 			if (chk->data) {
   3197   1.1       rjs 				sctp_m_freem(chk->data);
   3198   1.1       rjs 				chk->data = NULL;
   3199   1.1       rjs 			}
   3200   1.1       rjs 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   3201   1.1       rjs 			sctppcbinfo.ipi_count_chunk--;
   3202   1.1       rjs 			if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   3203   1.1       rjs 				panic("Chunk count is negative");
   3204   1.1       rjs 			}
   3205   1.1       rjs 			sctppcbinfo.ipi_gencnt_chunk++;
   3206   1.1       rjs 			chk = TAILQ_FIRST(&asoc->sent_queue);
   3207   1.1       rjs 		}
   3208   1.1       rjs 	}
   3209   1.1       rjs 	/* control queue MAY not be empty */
   3210   1.1       rjs 	if (!TAILQ_EMPTY(&asoc->control_send_queue)) {
   3211   1.1       rjs 		chk = TAILQ_FIRST(&asoc->control_send_queue);
   3212   1.1       rjs 		while (chk) {
   3213   1.1       rjs 			TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
   3214   1.1       rjs 			if (chk->data) {
   3215   1.1       rjs 				sctp_m_freem(chk->data);
   3216   1.1       rjs 				chk->data = NULL;
   3217   1.1       rjs 			}
   3218   1.1       rjs 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   3219   1.1       rjs 			sctppcbinfo.ipi_count_chunk--;
   3220   1.1       rjs 			if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   3221   1.1       rjs 				panic("Chunk count is negative");
   3222   1.1       rjs 			}
   3223   1.1       rjs 			sctppcbinfo.ipi_gencnt_chunk++;
   3224   1.1       rjs 			chk = TAILQ_FIRST(&asoc->control_send_queue);
   3225   1.1       rjs 		}
   3226   1.1       rjs 	}
   3227   1.1       rjs 	if (!TAILQ_EMPTY(&asoc->reasmqueue)) {
   3228   1.1       rjs 		chk = TAILQ_FIRST(&asoc->reasmqueue);
   3229   1.1       rjs 		while (chk) {
   3230   1.1       rjs 			TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next);
   3231   1.1       rjs 			if (chk->data) {
   3232   1.1       rjs 				sctp_m_freem(chk->data);
   3233   1.1       rjs 				chk->data = NULL;
   3234   1.1       rjs 			}
   3235   1.1       rjs 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   3236   1.1       rjs 			sctppcbinfo.ipi_count_chunk--;
   3237   1.1       rjs 			if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   3238   1.1       rjs 				panic("Chunk count is negative");
   3239   1.1       rjs 			}
   3240   1.1       rjs 			sctppcbinfo.ipi_gencnt_chunk++;
   3241   1.1       rjs 			chk = TAILQ_FIRST(&asoc->reasmqueue);
   3242   1.1       rjs 		}
   3243   1.1       rjs 	}
   3244   1.1       rjs 	if (!TAILQ_EMPTY(&asoc->delivery_queue)) {
   3245   1.1       rjs 		chk = TAILQ_FIRST(&asoc->delivery_queue);
   3246   1.1       rjs 		while (chk) {
   3247   1.1       rjs 			TAILQ_REMOVE(&asoc->delivery_queue, chk, sctp_next);
   3248   1.1       rjs 			if (chk->data) {
   3249   1.1       rjs 				sctp_m_freem(chk->data);
   3250   1.1       rjs 				chk->data = NULL;
   3251   1.1       rjs 			}
   3252   1.1       rjs 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   3253   1.1       rjs 			sctppcbinfo.ipi_count_chunk--;
   3254   1.1       rjs 			if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   3255   1.1       rjs 				panic("Chunk count is negative");
   3256   1.1       rjs 			}
   3257   1.1       rjs 			sctppcbinfo.ipi_gencnt_chunk++;
   3258   1.1       rjs 			chk = TAILQ_FIRST(&asoc->delivery_queue);
   3259   1.1       rjs 		}
   3260   1.1       rjs 	}
   3261   1.1       rjs 	if (asoc->mapping_array) {
   3262   1.1       rjs 		free(asoc->mapping_array, M_PCB);
   3263   1.1       rjs 		asoc->mapping_array = NULL;
   3264   1.1       rjs 	}
   3265   1.1       rjs 
   3266   1.1       rjs 	/* the stream outs */
   3267   1.1       rjs 	if (asoc->strmout) {
   3268   1.1       rjs 		free(asoc->strmout, M_PCB);
   3269   1.1       rjs 		asoc->strmout = NULL;
   3270   1.1       rjs 	}
   3271   1.1       rjs 	asoc->streamoutcnt = 0;
   3272   1.1       rjs 	if (asoc->strmin) {
   3273   1.1       rjs 		int i;
   3274   1.1       rjs 		for (i = 0; i < asoc->streamincnt; i++) {
   3275   1.1       rjs 			if (!TAILQ_EMPTY(&asoc->strmin[i].inqueue)) {
   3276   1.1       rjs 				/* We have somethings on the streamin queue */
   3277   1.1       rjs 				chk = TAILQ_FIRST(&asoc->strmin[i].inqueue);
   3278   1.1       rjs 				while (chk) {
   3279   1.1       rjs 					TAILQ_REMOVE(&asoc->strmin[i].inqueue,
   3280   1.1       rjs 					    chk, sctp_next);
   3281   1.1       rjs 					if (chk->data) {
   3282   1.1       rjs 						sctp_m_freem(chk->data);
   3283   1.1       rjs 						chk->data = NULL;
   3284   1.1       rjs 					}
   3285   1.1       rjs 					SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk,
   3286   1.1       rjs 					    chk);
   3287   1.1       rjs 					sctppcbinfo.ipi_count_chunk--;
   3288   1.1       rjs 					if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   3289   1.1       rjs 						panic("Chunk count is negative");
   3290   1.1       rjs 					}
   3291   1.1       rjs 					sctppcbinfo.ipi_gencnt_chunk++;
   3292   1.1       rjs 					chk = TAILQ_FIRST(&asoc->strmin[i].inqueue);
   3293   1.1       rjs 				}
   3294   1.1       rjs 			}
   3295   1.1       rjs 		}
   3296   1.1       rjs 		free(asoc->strmin, M_PCB);
   3297   1.1       rjs 		asoc->strmin = NULL;
   3298   1.1       rjs 	}
   3299   1.1       rjs 	asoc->streamincnt = 0;
   3300   1.1       rjs 	/* local addresses, if any */
   3301   1.1       rjs 	while (!LIST_EMPTY(&asoc->sctp_local_addr_list)) {
   3302   1.1       rjs 		laddr = LIST_FIRST(&asoc->sctp_local_addr_list);
   3303   1.1       rjs 		LIST_REMOVE(laddr, sctp_nxt_addr);
   3304   1.1       rjs 		SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_laddr, laddr);
   3305   1.1       rjs 		sctppcbinfo.ipi_count_laddr--;
   3306   1.1       rjs 	}
   3307   1.1       rjs 	/* pending asconf (address) parameters */
   3308   1.1       rjs 	while (!TAILQ_EMPTY(&asoc->asconf_queue)) {
   3309   1.1       rjs 		aparam = TAILQ_FIRST(&asoc->asconf_queue);
   3310   1.1       rjs 		TAILQ_REMOVE(&asoc->asconf_queue, aparam, next);
   3311   1.1       rjs 		free(aparam, M_PCB);
   3312   1.1       rjs 	}
   3313   1.1       rjs 	if (asoc->last_asconf_ack_sent != NULL) {
   3314   1.1       rjs 		sctp_m_freem(asoc->last_asconf_ack_sent);
   3315   1.1       rjs 		asoc->last_asconf_ack_sent = NULL;
   3316   1.1       rjs 	}
   3317   1.1       rjs 	/* Insert new items here :> */
   3318   1.1       rjs 
   3319   1.1       rjs 	/* Get rid of LOCK */
   3320   1.1       rjs 	SCTP_TCB_LOCK_DESTROY(stcb);
   3321   1.1       rjs 
   3322   1.1       rjs 	/* now clean up the tasoc itself */
   3323   1.1       rjs 	SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_asoc, stcb);
   3324   1.1       rjs 	sctppcbinfo.ipi_count_asoc--;
   3325   1.1       rjs 	if ((inp->sctp_socket->so_snd.sb_cc) ||
   3326   1.1       rjs 	    (inp->sctp_socket->so_snd.sb_mbcnt)) {
   3327   1.1       rjs 		/* This will happen when a abort is done */
   3328   1.1       rjs 		inp->sctp_socket->so_snd.sb_cc = 0;
   3329   1.1       rjs 		inp->sctp_socket->so_snd.sb_mbcnt = 0;
   3330   1.1       rjs 	}
   3331   1.1       rjs 	if (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
   3332   1.1       rjs 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) {
   3333   1.1       rjs 			if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
   3334   1.1       rjs 				/*
   3335   1.1       rjs 				 * For the base fd, that is NOT in TCP pool we
   3336   1.1       rjs 				 * turn off the connected flag. This allows
   3337   1.1       rjs 				 * non-listening endpoints to connect/shutdown/
   3338   1.1       rjs 				 * connect.
   3339   1.1       rjs 				 */
   3340   1.1       rjs 				inp->sctp_flags &= ~SCTP_PCB_FLAGS_CONNECTED;
   3341   1.1       rjs 				soisdisconnected(inp->sctp_socket);
   3342   1.1       rjs 			}
   3343   1.1       rjs 			/*
   3344   1.1       rjs 			 * For those that are in the TCP pool we just leave
   3345   1.1       rjs 			 * so it cannot be used. When they close the fd we
   3346   1.1       rjs 			 * will free it all.
   3347   1.1       rjs 			 */
   3348   1.1       rjs 		}
   3349   1.1       rjs 	}
   3350   1.1       rjs 	if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
   3351   1.1       rjs 		sctp_inpcb_free(inp, 0);
   3352   1.1       rjs 	}
   3353   1.1       rjs 	splx(s);
   3354   1.1       rjs }
   3355   1.1       rjs 
   3356   1.1       rjs 
   3357   1.1       rjs /*
   3358   1.1       rjs  * determine if a destination is "reachable" based upon the addresses
   3359   1.1       rjs  * bound to the current endpoint (e.g. only v4 or v6 currently bound)
   3360   1.1       rjs  */
   3361   1.1       rjs /*
   3362   1.1       rjs  * FIX: if we allow assoc-level bindx(), then this needs to be fixed
   3363   1.1       rjs  * to use assoc level v4/v6 flags, as the assoc *may* not have the
   3364   1.1       rjs  * same address types bound as its endpoint
   3365   1.1       rjs  */
   3366   1.1       rjs int
   3367   1.1       rjs sctp_destination_is_reachable(struct sctp_tcb *stcb, const struct sockaddr *destaddr)
   3368   1.1       rjs {
   3369   1.1       rjs 	struct sctp_inpcb *inp;
   3370   1.1       rjs 	int answer;
   3371   1.1       rjs 
   3372   1.1       rjs 	/* No locks here, the TCB, in all cases is already
   3373   1.1       rjs 	 * locked and an assoc is up. There is either a
   3374   1.1       rjs 	 * INP lock by the caller applied (in asconf case when
   3375   1.1       rjs 	 * deleting an address) or NOT in the HB case, however
   3376   1.1       rjs 	 * if HB then the INP increment is up and the INP
   3377   1.1       rjs 	 * will not be removed (on top of the fact that
   3378   1.1       rjs 	 * we have a TCB lock). So we only want to
   3379   1.1       rjs 	 * read the sctp_flags, which is either bound-all
   3380   1.1       rjs 	 * or not.. no protection needed since once an
   3381   1.1       rjs 	 * assoc is up you can't be changing your binding.
   3382   1.1       rjs 	 */
   3383   1.1       rjs 	inp = stcb->sctp_ep;
   3384   1.1       rjs 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
   3385   1.1       rjs 		/* if bound all, destination is not restricted */
   3386   1.1       rjs 		/* RRS: Question during lock work: Is this
   3387   1.1       rjs 		 * correct? If you are bound-all you still
   3388   1.1       rjs 		 * might need to obey the V4--V6 flags???
   3389   1.1       rjs 		 * IMO this bound-all stuff needs to be removed!
   3390   1.1       rjs 		 */
   3391   1.1       rjs 		return (1);
   3392   1.1       rjs 	}
   3393   1.1       rjs 	/* NOTE: all "scope" checks are done when local addresses are added */
   3394   1.1       rjs 	if (destaddr->sa_family == AF_INET6) {
   3395   1.1       rjs 		answer = inp->inp_vflag & INP_IPV6;
   3396   1.1       rjs 	} else if (destaddr->sa_family == AF_INET) {
   3397   1.1       rjs 		answer = inp->inp_vflag & INP_IPV4;
   3398   1.1       rjs 	} else {
   3399   1.1       rjs 		/* invalid family, so it's unreachable */
   3400   1.1       rjs 		answer = 0;
   3401   1.1       rjs 	}
   3402   1.1       rjs 	return (answer);
   3403   1.1       rjs }
   3404   1.1       rjs 
   3405   1.1       rjs /*
   3406   1.1       rjs  * update the inp_vflags on an endpoint
   3407   1.1       rjs  */
   3408   1.1       rjs static void
   3409   1.1       rjs sctp_update_ep_vflag(struct sctp_inpcb *inp) {
   3410   1.1       rjs 	struct sctp_laddr *laddr;
   3411   1.1       rjs 
   3412   1.1       rjs 	/* first clear the flag */
   3413   1.1       rjs 	inp->inp_vflag = 0;
   3414  1.12       rjs 
   3415   1.1       rjs 	/* set the flag based on addresses on the ep list */
   3416   1.1       rjs 	LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
   3417   1.1       rjs 		if (laddr->ifa == NULL) {
   3418   1.1       rjs #ifdef SCTP_DEBUG
   3419   1.1       rjs 			if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   3420   1.1       rjs 				printf("An ounce of prevention is worth a pound of cure\n");
   3421   1.1       rjs 			}
   3422   1.1       rjs #endif /* SCTP_DEBUG */
   3423   1.1       rjs 			continue;
   3424   1.1       rjs 		}
   3425   1.1       rjs 		if (laddr->ifa->ifa_addr) {
   3426   1.1       rjs 			continue;
   3427   1.1       rjs 		}
   3428   1.1       rjs 		if (laddr->ifa->ifa_addr->sa_family == AF_INET6) {
   3429   1.1       rjs 			inp->inp_vflag |= INP_IPV6;
   3430   1.1       rjs 		} else if (laddr->ifa->ifa_addr->sa_family == AF_INET) {
   3431   1.1       rjs 			inp->inp_vflag |= INP_IPV4;
   3432   1.1       rjs 		}
   3433   1.1       rjs 	}
   3434   1.1       rjs }
   3435   1.1       rjs 
   3436   1.1       rjs /*
   3437   1.1       rjs  * Add the address to the endpoint local address list
   3438   1.1       rjs  * There is nothing to be done if we are bound to all addresses
   3439   1.1       rjs  */
   3440   1.1       rjs int
   3441   1.1       rjs sctp_add_local_addr_ep(struct sctp_inpcb *inp, struct ifaddr *ifa)
   3442   1.1       rjs {
   3443   1.1       rjs 	struct sctp_laddr *laddr;
   3444   1.1       rjs 	int fnd, error;
   3445   1.1       rjs 	fnd = 0;
   3446   1.1       rjs 
   3447   1.1       rjs 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
   3448   1.1       rjs 		/* You are already bound to all. You have it already */
   3449   1.1       rjs 		return (0);
   3450   1.1       rjs 	}
   3451   1.1       rjs 	if (ifa->ifa_addr->sa_family == AF_INET6) {
   3452   1.1       rjs 		struct in6_ifaddr *ifa6;
   3453   1.1       rjs 		ifa6 = (struct in6_ifaddr *)ifa;
   3454   1.1       rjs 		if (ifa6->ia6_flags & (IN6_IFF_DETACHED |
   3455   1.1       rjs 		    IN6_IFF_DEPRECATED | IN6_IFF_ANYCAST | IN6_IFF_NOTREADY))
   3456   1.1       rjs 			/* Can't bind a non-existent addr. */
   3457   1.1       rjs 			return (-1);
   3458   1.1       rjs 	}
   3459   1.1       rjs 	/* first, is it already present? */
   3460   1.1       rjs 	LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
   3461   1.1       rjs 		if (laddr->ifa == ifa) {
   3462   1.1       rjs 			fnd = 1;
   3463   1.1       rjs 			break;
   3464   1.1       rjs 		}
   3465   1.1       rjs 	}
   3466   1.1       rjs 
   3467   1.1       rjs 	if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) && (fnd == 0)) {
   3468   1.1       rjs 		/* Not bound to all */
   3469   1.1       rjs 		error = sctp_insert_laddr(&inp->sctp_addr_list, ifa);
   3470   1.1       rjs 		if (error != 0)
   3471   1.1       rjs 			return (error);
   3472   1.1       rjs 		inp->laddr_count++;
   3473   1.1       rjs 		/* update inp_vflag flags */
   3474   1.1       rjs 		if (ifa->ifa_addr->sa_family == AF_INET6) {
   3475   1.1       rjs 			inp->inp_vflag |= INP_IPV6;
   3476   1.1       rjs 		} else if (ifa->ifa_addr->sa_family == AF_INET) {
   3477   1.1       rjs 			inp->inp_vflag |= INP_IPV4;
   3478   1.1       rjs 		}
   3479   1.1       rjs 	}
   3480   1.1       rjs 	return (0);
   3481   1.1       rjs }
   3482   1.1       rjs 
   3483   1.1       rjs 
   3484   1.1       rjs /*
   3485   1.1       rjs  * select a new (hopefully reachable) destination net
   3486   1.1       rjs  * (should only be used when we deleted an ep addr that is the
   3487   1.1       rjs  * only usable source address to reach the destination net)
   3488   1.1       rjs  */
   3489   1.1       rjs static void
   3490   1.1       rjs sctp_select_primary_destination(struct sctp_tcb *stcb)
   3491   1.1       rjs {
   3492   1.1       rjs 	struct sctp_nets *net;
   3493   1.1       rjs 
   3494   1.1       rjs 	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   3495   1.1       rjs 		/* for now, we'll just pick the first reachable one we find */
   3496   1.1       rjs 		if (net->dest_state & SCTP_ADDR_UNCONFIRMED)
   3497   1.1       rjs 			continue;
   3498   1.1       rjs 		if (sctp_destination_is_reachable(stcb,
   3499   1.1       rjs 			rtcache_getdst(&net->ro))) {
   3500   1.1       rjs 			/* found a reachable destination */
   3501   1.1       rjs 			stcb->asoc.primary_destination = net;
   3502   1.1       rjs 		}
   3503   1.1       rjs 	}
   3504   1.1       rjs 	/* I can't there from here! ...we're gonna die shortly... */
   3505   1.1       rjs }
   3506   1.1       rjs 
   3507   1.1       rjs 
   3508   1.1       rjs /*
   3509   1.1       rjs  * Delete the address from the endpoint local address list
   3510   1.1       rjs  * There is nothing to be done if we are bound to all addresses
   3511   1.1       rjs  */
   3512   1.1       rjs int
   3513   1.1       rjs sctp_del_local_addr_ep(struct sctp_inpcb *inp, struct ifaddr *ifa)
   3514   1.1       rjs {
   3515   1.1       rjs 	struct sctp_laddr *laddr;
   3516   1.1       rjs 	int fnd;
   3517   1.1       rjs 	fnd = 0;
   3518   1.1       rjs 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
   3519   1.1       rjs 		/* You are already bound to all. You have it already */
   3520   1.1       rjs 		return (EINVAL);
   3521   1.1       rjs 	}
   3522   1.1       rjs 
   3523   1.1       rjs 	LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
   3524   1.1       rjs 		if (laddr->ifa == ifa) {
   3525   1.1       rjs 			fnd = 1;
   3526   1.1       rjs 			break;
   3527   1.1       rjs 		}
   3528   1.1       rjs 	}
   3529   1.1       rjs 	if (fnd && (inp->laddr_count < 2)) {
   3530   1.1       rjs 		/* can't delete unless there are at LEAST 2 addresses */
   3531   1.1       rjs 		return (-1);
   3532   1.1       rjs 	}
   3533   1.1       rjs 	if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) && (fnd)) {
   3534   1.1       rjs 		/*
   3535   1.1       rjs 		 * clean up any use of this address
   3536   1.1       rjs 		 * go through our associations and clear any
   3537   1.1       rjs 		 *  last_used_address that match this one
   3538   1.1       rjs 		 * for each assoc, see if a new primary_destination is needed
   3539   1.1       rjs 		 */
   3540   1.1       rjs 		struct sctp_tcb *stcb;
   3541   1.1       rjs 
   3542   1.1       rjs 		/* clean up "next_addr_touse" */
   3543   1.1       rjs 		if (inp->next_addr_touse == laddr)
   3544   1.1       rjs 			/* delete this address */
   3545   1.1       rjs 			inp->next_addr_touse = NULL;
   3546   1.1       rjs 
   3547   1.1       rjs 		/* clean up "last_used_address" */
   3548   1.1       rjs 		LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   3549   1.1       rjs 			if (stcb->asoc.last_used_address == laddr)
   3550   1.1       rjs 				/* delete this address */
   3551   1.1       rjs 				stcb->asoc.last_used_address = NULL;
   3552   1.1       rjs 		} /* for each tcb */
   3553   1.1       rjs 
   3554   1.1       rjs 		/* remove it from the ep list */
   3555   1.1       rjs 		sctp_remove_laddr(laddr);
   3556   1.1       rjs 		inp->laddr_count--;
   3557   1.1       rjs 		/* update inp_vflag flags */
   3558   1.1       rjs 		sctp_update_ep_vflag(inp);
   3559   1.1       rjs 		/* select a new primary destination if needed */
   3560   1.1       rjs 		LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   3561   1.1       rjs 			/* presume caller (sctp_asconf.c) already owns INP lock */
   3562   1.1       rjs 			SCTP_TCB_LOCK(stcb);
   3563   1.1       rjs 			if (sctp_destination_is_reachable(stcb,
   3564   1.1       rjs 			    rtcache_getdst(&stcb->asoc.primary_destination->ro)) == 0) {
   3565   1.1       rjs 				sctp_select_primary_destination(stcb);
   3566   1.1       rjs 			}
   3567   1.1       rjs 			SCTP_TCB_UNLOCK(stcb);
   3568   1.1       rjs 		} /* for each tcb */
   3569   1.1       rjs 	}
   3570   1.1       rjs 	return (0);
   3571   1.1       rjs }
   3572   1.1       rjs 
   3573   1.1       rjs /*
   3574   1.1       rjs  * Add the addr to the TCB local address list
   3575   1.1       rjs  * For the BOUNDALL or dynamic case, this is a "pending" address list
   3576   1.1       rjs  * (eg. addresses waiting for an ASCONF-ACK response)
   3577   1.1       rjs  * For the subset binding, static case, this is a "valid" address list
   3578   1.1       rjs  */
   3579   1.1       rjs int
   3580   1.1       rjs sctp_add_local_addr_assoc(struct sctp_tcb *stcb, struct ifaddr *ifa)
   3581   1.1       rjs {
   3582   1.1       rjs 	struct sctp_laddr *laddr;
   3583   1.1       rjs 	int error;
   3584   1.1       rjs 
   3585   1.1       rjs 	/* Assumes TCP is locked.. and possiblye
   3586   1.1       rjs 	 * the INP. May need to confirm/fix that if
   3587   1.1       rjs 	 * we need it and is not the case.
   3588   1.1       rjs 	 */
   3589   1.1       rjs 	if (ifa->ifa_addr->sa_family == AF_INET6) {
   3590   1.1       rjs 		struct in6_ifaddr *ifa6;
   3591   1.1       rjs 		ifa6 = (struct in6_ifaddr *)ifa;
   3592   1.1       rjs 		if (ifa6->ia6_flags & (IN6_IFF_DETACHED |
   3593   1.1       rjs 		    /* IN6_IFF_DEPRECATED | */
   3594   1.1       rjs 		    IN6_IFF_ANYCAST |
   3595   1.1       rjs 		    IN6_IFF_NOTREADY))
   3596   1.1       rjs 			/* Can't bind a non-existent addr. */
   3597   1.1       rjs 			return (-1);
   3598   1.1       rjs 	}
   3599   1.1       rjs 	/* does the address already exist? */
   3600   1.1       rjs 	LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) {
   3601   1.1       rjs 		if (laddr->ifa == ifa) {
   3602   1.1       rjs 			return (-1);
   3603   1.1       rjs 		}
   3604   1.1       rjs 	}
   3605   1.1       rjs 
   3606   1.1       rjs 	/* add to the list */
   3607   1.1       rjs 	error = sctp_insert_laddr(&stcb->asoc.sctp_local_addr_list, ifa);
   3608   1.1       rjs 	if (error != 0)
   3609   1.1       rjs 		return (error);
   3610   1.1       rjs 	return (0);
   3611   1.1       rjs }
   3612   1.1       rjs 
   3613   1.1       rjs /*
   3614   1.1       rjs  * insert an laddr entry with the given ifa for the desired list
   3615   1.1       rjs  */
   3616   1.1       rjs int
   3617   1.1       rjs sctp_insert_laddr(struct sctpladdr *list, struct ifaddr *ifa) {
   3618   1.1       rjs 	struct sctp_laddr *laddr;
   3619   1.1       rjs 	int s;
   3620   1.1       rjs 
   3621   1.1       rjs 	s = splsoftnet();
   3622   1.1       rjs 
   3623   1.1       rjs 	laddr = (struct sctp_laddr *)SCTP_ZONE_GET(sctppcbinfo.ipi_zone_laddr);
   3624   1.1       rjs 	if (laddr == NULL) {
   3625   1.1       rjs 		/* out of memory? */
   3626   1.1       rjs 		splx(s);
   3627   1.1       rjs 		return (EINVAL);
   3628   1.1       rjs 	}
   3629   1.1       rjs 	sctppcbinfo.ipi_count_laddr++;
   3630   1.1       rjs 	sctppcbinfo.ipi_gencnt_laddr++;
   3631   1.1       rjs 	memset(laddr, 0, sizeof(*laddr));
   3632   1.1       rjs 	laddr->ifa = ifa;
   3633   1.1       rjs 	/* insert it */
   3634   1.1       rjs 	LIST_INSERT_HEAD(list, laddr, sctp_nxt_addr);
   3635   1.1       rjs 
   3636   1.1       rjs 	splx(s);
   3637   1.1       rjs 	return (0);
   3638   1.1       rjs }
   3639   1.1       rjs 
   3640   1.1       rjs /*
   3641   1.1       rjs  * Remove an laddr entry from the local address list (on an assoc)
   3642   1.1       rjs  */
   3643   1.1       rjs void
   3644   1.1       rjs sctp_remove_laddr(struct sctp_laddr *laddr)
   3645   1.1       rjs {
   3646   1.1       rjs 	int s;
   3647   1.1       rjs 	s = splsoftnet();
   3648   1.1       rjs 	/* remove from the list */
   3649   1.1       rjs 	LIST_REMOVE(laddr, sctp_nxt_addr);
   3650   1.1       rjs 	SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_laddr, laddr);
   3651   1.1       rjs 	sctppcbinfo.ipi_count_laddr--;
   3652   1.1       rjs 	sctppcbinfo.ipi_gencnt_laddr++;
   3653   1.1       rjs 
   3654   1.1       rjs 	splx(s);
   3655   1.1       rjs }
   3656   1.1       rjs 
   3657   1.1       rjs /*
   3658   1.1       rjs  * Remove an address from the TCB local address list
   3659   1.1       rjs  */
   3660   1.1       rjs int
   3661   1.1       rjs sctp_del_local_addr_assoc(struct sctp_tcb *stcb, struct ifaddr *ifa)
   3662   1.1       rjs {
   3663   1.1       rjs 	struct sctp_inpcb *inp;
   3664   1.1       rjs 	struct sctp_laddr *laddr;
   3665   1.1       rjs 
   3666   1.1       rjs 	/* This is called by asconf work. It is assumed that
   3667   1.1       rjs 	 * a) The TCB is locked
   3668   1.1       rjs 	 * and
   3669   1.1       rjs 	 * b) The INP is locked.
   3670   1.1       rjs 	 * This is true in as much as I can trace through
   3671   1.1       rjs 	 * the entry asconf code where I did these locks.
   3672   1.1       rjs 	 * Again, the ASCONF code is a bit different in
   3673   1.1       rjs 	 * that it does lock the INP during its work often
   3674   1.1       rjs 	 * times. This must be since we don't want other
   3675   1.1       rjs 	 * proc's looking up things while what they are
   3676   1.1       rjs 	 * looking up is changing :-D
   3677   1.1       rjs 	 */
   3678   1.1       rjs 
   3679   1.1       rjs 	inp = stcb->sctp_ep;
   3680   1.1       rjs 	/* if subset bound and don't allow ASCONF's, can't delete last */
   3681   1.1       rjs 	if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) &&
   3682   1.1       rjs 	    ((inp->sctp_flags & SCTP_PCB_FLAGS_DO_ASCONF) == 0)) {
   3683   1.1       rjs 		if (stcb->asoc.numnets < 2) {
   3684   1.1       rjs 			/* can't delete last address */
   3685   1.1       rjs 			return (-1);
   3686   1.1       rjs 		}
   3687   1.1       rjs 	}
   3688   1.1       rjs 
   3689   1.1       rjs 	LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) {
   3690   1.1       rjs 		/* remove the address if it exists */
   3691   1.1       rjs 		if (laddr->ifa == NULL)
   3692   1.1       rjs 			continue;
   3693   1.1       rjs 		if (laddr->ifa == ifa) {
   3694   1.1       rjs 			sctp_remove_laddr(laddr);
   3695   1.1       rjs 			return (0);
   3696   1.1       rjs 		}
   3697   1.1       rjs 	}
   3698   1.1       rjs 
   3699   1.1       rjs 	/* address not found! */
   3700   1.1       rjs 	return (-1);
   3701   1.1       rjs }
   3702   1.1       rjs 
   3703   1.1       rjs /*
   3704   1.1       rjs  * Remove an address from the TCB local address list
   3705   1.1       rjs  * lookup using a sockaddr addr
   3706   1.1       rjs  */
   3707   1.1       rjs int
   3708   1.1       rjs sctp_del_local_addr_assoc_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
   3709   1.1       rjs {
   3710   1.1       rjs 	struct sctp_inpcb *inp;
   3711   1.1       rjs 	struct sctp_laddr *laddr;
   3712   1.1       rjs 	struct sockaddr *l_sa;
   3713   1.1       rjs 
   3714   1.1       rjs         /*
   3715   1.1       rjs          * This function I find does not seem to have a caller.
   3716   1.1       rjs 	 * As such we NEED TO DELETE this code. If we do
   3717   1.1       rjs 	 * find a caller, the caller MUST have locked the TCB
   3718   1.1       rjs 	 * at the least and probably the INP as well.
   3719   1.1       rjs          */
   3720   1.1       rjs 	inp = stcb->sctp_ep;
   3721   1.1       rjs 	/* if subset bound and don't allow ASCONF's, can't delete last */
   3722   1.1       rjs 	if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) &&
   3723   1.1       rjs 	    ((inp->sctp_flags & SCTP_PCB_FLAGS_DO_ASCONF) == 0)) {
   3724   1.1       rjs 		if (stcb->asoc.numnets < 2) {
   3725   1.1       rjs 			/* can't delete last address */
   3726   1.1       rjs 			return (-1);
   3727   1.1       rjs 		}
   3728   1.1       rjs 	}
   3729   1.1       rjs 
   3730   1.1       rjs 	LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) {
   3731   1.1       rjs 		/* make sure the address exists */
   3732   1.1       rjs 		if (laddr->ifa == NULL)
   3733   1.1       rjs 			continue;
   3734   1.1       rjs 		if (laddr->ifa->ifa_addr == NULL)
   3735   1.1       rjs 			continue;
   3736   1.1       rjs 
   3737   1.1       rjs 		l_sa = laddr->ifa->ifa_addr;
   3738   1.1       rjs 		if (l_sa->sa_family == AF_INET6) {
   3739   1.1       rjs 			/* IPv6 address */
   3740   1.1       rjs 			struct sockaddr_in6 *sin1, *sin2;
   3741   1.1       rjs 			sin1 = (struct sockaddr_in6 *)l_sa;
   3742   1.1       rjs 			sin2 = (struct sockaddr_in6 *)sa;
   3743   1.1       rjs 			if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
   3744   1.1       rjs 			    sizeof(struct in6_addr)) == 0) {
   3745   1.1       rjs 				/* matched */
   3746   1.1       rjs 				sctp_remove_laddr(laddr);
   3747   1.1       rjs 				return (0);
   3748   1.1       rjs 			}
   3749   1.1       rjs 		} else if (l_sa->sa_family == AF_INET) {
   3750   1.1       rjs 			/* IPv4 address */
   3751   1.1       rjs 			struct sockaddr_in *sin1, *sin2;
   3752   1.1       rjs 			sin1 = (struct sockaddr_in *)l_sa;
   3753   1.1       rjs 			sin2 = (struct sockaddr_in *)sa;
   3754   1.1       rjs 			if (sin1->sin_addr.s_addr == sin2->sin_addr.s_addr) {
   3755   1.1       rjs 				/* matched */
   3756   1.1       rjs 				sctp_remove_laddr(laddr);
   3757   1.1       rjs 				return (0);
   3758   1.1       rjs 			}
   3759   1.1       rjs 		} else {
   3760   1.1       rjs 			/* invalid family */
   3761   1.1       rjs 			return (-1);
   3762   1.1       rjs 		}
   3763   1.1       rjs 	} /* end foreach */
   3764   1.1       rjs 	/* address not found! */
   3765   1.1       rjs 	return (-1);
   3766   1.1       rjs }
   3767   1.1       rjs 
   3768   1.1       rjs static char sctp_pcb_initialized = 0;
   3769   1.1       rjs 
   3770   1.1       rjs #if defined(__FreeBSD__) || defined(__APPLE__)
   3771   1.1       rjs /* sysctl */
   3772   1.1       rjs static int sctp_max_number_of_assoc = SCTP_MAX_NUM_OF_ASOC;
   3773   1.1       rjs static int sctp_scale_up_for_address = SCTP_SCALE_FOR_ADDR;
   3774   1.1       rjs 
   3775   1.1       rjs #endif /* FreeBSD || APPLE */
   3776   1.1       rjs 
   3777   1.1       rjs #ifndef SCTP_TCBHASHSIZE
   3778   1.1       rjs #define SCTP_TCBHASHSIZE 1024
   3779   1.1       rjs #endif
   3780   1.1       rjs 
   3781   1.1       rjs #ifndef SCTP_CHUNKQUEUE_SCALE
   3782   1.1       rjs #define SCTP_CHUNKQUEUE_SCALE 10
   3783   1.1       rjs #endif
   3784   1.1       rjs 
   3785   1.1       rjs void
   3786   1.1       rjs sctp_pcb_init(void)
   3787   1.1       rjs {
   3788   1.1       rjs 	/*
   3789   1.1       rjs 	 * SCTP initialization for the PCB structures
   3790  1.26    andvar 	 * should be called by the sctp_init() function.
   3791   1.1       rjs 	 */
   3792   1.1       rjs 	int i;
   3793   1.1       rjs 	int hashtblsize = SCTP_TCBHASHSIZE;
   3794   1.1       rjs 
   3795   1.1       rjs #if defined(__FreeBSD__) || defined(__APPLE__)
   3796   1.1       rjs 	int sctp_chunkscale = SCTP_CHUNKQUEUE_SCALE;
   3797   1.1       rjs #endif
   3798   1.1       rjs 
   3799   1.1       rjs 	if (sctp_pcb_initialized != 0) {
   3800   1.1       rjs 		/* error I was called twice */
   3801   1.1       rjs 		return;
   3802   1.1       rjs 	}
   3803   1.1       rjs 	sctp_pcb_initialized = 1;
   3804   1.1       rjs 
   3805   1.1       rjs 	/* Init all peg counts */
   3806   1.1       rjs 	for (i = 0; i < SCTP_NUMBER_OF_PEGS; i++) {
   3807   1.1       rjs 		sctp_pegs[i] = 0;
   3808   1.1       rjs 	}
   3809   1.1       rjs 
   3810   1.1       rjs 	/* init the empty list of (All) Endpoints */
   3811   1.1       rjs 	LIST_INIT(&sctppcbinfo.listhead);
   3812   1.1       rjs 
   3813   1.1       rjs 	/* init the iterator head */
   3814   1.1       rjs 	LIST_INIT(&sctppcbinfo.iteratorhead);
   3815   1.1       rjs 
   3816   1.1       rjs 	/* init the hash table of endpoints */
   3817   1.1       rjs #if defined(__FreeBSD__)
   3818   1.1       rjs #if defined(__FreeBSD_cc_version) && __FreeBSD_cc_version >= 440000
   3819   1.1       rjs 	TUNABLE_INT_FETCH("net.inet.sctp.tcbhashsize", &hashtblsize);
   3820   1.1       rjs 	TUNABLE_INT_FETCH("net.inet.sctp.pcbhashsize", &sctp_pcbtblsize);
   3821   1.1       rjs 	TUNABLE_INT_FETCH("net.inet.sctp.chunkscale", &sctp_chunkscale);
   3822   1.1       rjs #else
   3823   1.1       rjs 	TUNABLE_INT_FETCH("net.inet.sctp.tcbhashsize", SCTP_TCBHASHSIZE,
   3824   1.1       rjs 	    hashtblsize);
   3825   1.1       rjs 	TUNABLE_INT_FETCH("net.inet.sctp.pcbhashsize", SCTP_PCBHASHSIZE,
   3826   1.1       rjs 	    sctp_pcbtblsize);
   3827   1.1       rjs 	TUNABLE_INT_FETCH("net.inet.sctp.chunkscale", SCTP_CHUNKQUEUE_SCALE,
   3828   1.1       rjs 	    sctp_chunkscale);
   3829   1.1       rjs #endif
   3830   1.1       rjs #endif
   3831   1.1       rjs 
   3832   1.1       rjs 	sctppcbinfo.sctp_asochash = hashinit((hashtblsize * 31), HASH_LIST,
   3833   1.1       rjs 			M_WAITOK, &sctppcbinfo.hashasocmark);
   3834   1.1       rjs 
   3835   1.1       rjs 	sctppcbinfo.sctp_ephash = hashinit(hashtblsize, HASH_LIST,
   3836   1.1       rjs 			M_WAITOK, &sctppcbinfo.hashmark);
   3837   1.1       rjs 
   3838   1.1       rjs 	sctppcbinfo.sctp_tcpephash = hashinit(hashtblsize, HASH_LIST,
   3839   1.1       rjs 			M_WAITOK, &sctppcbinfo.hashtcpmark);
   3840   1.1       rjs 
   3841   1.1       rjs 	sctppcbinfo.hashtblsize = hashtblsize;
   3842   1.1       rjs 
   3843   1.1       rjs 	/* init the zones */
   3844   1.1       rjs 	/*
   3845   1.1       rjs 	 * FIX ME: Should check for NULL returns, but if it does fail we
   3846   1.1       rjs 	 * are doomed to panic anyways... add later maybe.
   3847   1.1       rjs 	 */
   3848   1.1       rjs 	SCTP_ZONE_INIT(sctppcbinfo.ipi_zone_ep, "sctp_ep",
   3849   1.1       rjs 	    sizeof(struct sctp_inpcb), maxsockets);
   3850   1.1       rjs 
   3851   1.1       rjs 	SCTP_ZONE_INIT(sctppcbinfo.ipi_zone_asoc, "sctp_asoc",
   3852   1.1       rjs 	    sizeof(struct sctp_tcb), sctp_max_number_of_assoc);
   3853   1.1       rjs 
   3854   1.1       rjs 	SCTP_ZONE_INIT(sctppcbinfo.ipi_zone_laddr, "sctp_laddr",
   3855   1.1       rjs 	    sizeof(struct sctp_laddr),
   3856   1.1       rjs 	    (sctp_max_number_of_assoc * sctp_scale_up_for_address));
   3857   1.1       rjs 
   3858   1.1       rjs 	SCTP_ZONE_INIT(sctppcbinfo.ipi_zone_net, "sctp_raddr",
   3859   1.1       rjs 	    sizeof(struct sctp_nets),
   3860   1.1       rjs 	    (sctp_max_number_of_assoc * sctp_scale_up_for_address));
   3861   1.1       rjs 
   3862   1.1       rjs 	SCTP_ZONE_INIT(sctppcbinfo.ipi_zone_chunk, "sctp_chunk",
   3863   1.1       rjs 	    sizeof(struct sctp_tmit_chunk),
   3864   1.1       rjs 	    (sctp_max_number_of_assoc * sctp_scale_up_for_address *
   3865   1.1       rjs 	    sctp_chunkscale));
   3866   1.1       rjs 
   3867   1.1       rjs 	SCTP_ZONE_INIT(sctppcbinfo.ipi_zone_sockq, "sctp_sockq",
   3868   1.1       rjs 	    sizeof(struct sctp_socket_q_list),
   3869   1.1       rjs 	    (sctp_max_number_of_assoc * sctp_scale_up_for_address *
   3870   1.1       rjs 	    sctp_chunkscale));
   3871   1.1       rjs 
   3872   1.1       rjs 	SCTP_ZONE_INIT(sctppcbinfo.ipi_zone_hash, "sctp_hash",
   3873   1.1       rjs 		       sizeof(void *) * sctp_pcbtblsize, maxsockets);
   3874   1.1       rjs 
   3875   1.1       rjs         /* Master Lock INIT for info structure */
   3876   1.1       rjs 	SCTP_INP_INFO_LOCK_INIT();
   3877   1.1       rjs 	SCTP_ITERATOR_LOCK_INIT();
   3878   1.1       rjs 	/* not sure if we need all the counts */
   3879   1.1       rjs 	sctppcbinfo.ipi_count_ep = 0;
   3880   1.1       rjs 	sctppcbinfo.ipi_gencnt_ep = 0;
   3881   1.1       rjs 	/* assoc/tcb zone info */
   3882   1.1       rjs 	sctppcbinfo.ipi_count_asoc = 0;
   3883   1.1       rjs 	sctppcbinfo.ipi_gencnt_asoc = 0;
   3884   1.1       rjs 	/* local addrlist zone info */
   3885   1.1       rjs 	sctppcbinfo.ipi_count_laddr = 0;
   3886   1.1       rjs 	sctppcbinfo.ipi_gencnt_laddr = 0;
   3887   1.1       rjs 	/* remote addrlist zone info */
   3888   1.1       rjs 	sctppcbinfo.ipi_count_raddr = 0;
   3889   1.1       rjs 	sctppcbinfo.ipi_gencnt_raddr = 0;
   3890   1.1       rjs 	/* chunk info */
   3891   1.1       rjs 	sctppcbinfo.ipi_count_chunk = 0;
   3892   1.1       rjs 	sctppcbinfo.ipi_gencnt_chunk = 0;
   3893   1.1       rjs 
   3894   1.1       rjs 	/* socket queue zone info */
   3895   1.1       rjs 	sctppcbinfo.ipi_count_sockq = 0;
   3896   1.1       rjs 	sctppcbinfo.ipi_gencnt_sockq = 0;
   3897   1.1       rjs 
   3898   1.1       rjs 	/* mbuf tracker */
   3899   1.1       rjs 	sctppcbinfo.mbuf_track = 0;
   3900   1.1       rjs 	/* port stuff */
   3901   1.1       rjs 	sctppcbinfo.lastlow = anonportmin;
   3902  1.12       rjs 
   3903   1.1       rjs 	/* Init the TIMEWAIT list */
   3904   1.1       rjs 	for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
   3905   1.1       rjs 		LIST_INIT(&sctppcbinfo.vtag_timewait[i]);
   3906   1.1       rjs 	}
   3907   1.1       rjs 
   3908   1.1       rjs #if defined(_SCTP_NEEDS_CALLOUT_) && !defined(__APPLE__)
   3909   1.1       rjs 	TAILQ_INIT(&sctppcbinfo.callqueue);
   3910   1.1       rjs #endif
   3911   1.1       rjs 
   3912   1.1       rjs }
   3913   1.1       rjs 
   3914   1.1       rjs int
   3915   1.1       rjs sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
   3916   1.1       rjs     int iphlen, int offset, int limit, struct sctphdr *sh,
   3917   1.1       rjs     struct sockaddr *altsa)
   3918   1.1       rjs {
   3919   1.1       rjs 	/*
   3920   1.1       rjs 	 * grub through the INIT pulling addresses and
   3921   1.1       rjs 	 * loading them to the nets structure in the asoc.
   3922   1.1       rjs 	 * The from address in the mbuf should also be loaded
   3923   1.1       rjs 	 * (if it is not already). This routine can be called
   3924   1.1       rjs 	 * with either INIT or INIT-ACK's as long as the
   3925   1.1       rjs 	 * m points to the IP packet and the offset points
   3926   1.1       rjs 	 * to the beginning of the parameters.
   3927   1.1       rjs 	 */
   3928   1.1       rjs 	struct sctp_inpcb *inp, *l_inp;
   3929   1.1       rjs 	struct sctp_nets *net, *net_tmp;
   3930   1.1       rjs 	struct ip *iph;
   3931   1.1       rjs 	struct sctp_paramhdr *phdr, parm_buf;
   3932   1.1       rjs 	struct sctp_tcb *stcb_tmp;
   3933   1.1       rjs 	u_int16_t ptype, plen;
   3934   1.1       rjs 	struct sockaddr *sa;
   3935   1.1       rjs 	struct sockaddr_storage dest_store;
   3936   1.1       rjs 	struct sockaddr *local_sa = (struct sockaddr *)&dest_store;
   3937   1.1       rjs 	struct sockaddr_in sin;
   3938   1.1       rjs 	struct sockaddr_in6 sin6;
   3939   1.1       rjs 
   3940   1.1       rjs 	/* First get the destination address setup too. */
   3941   1.1       rjs 	memset(&sin, 0, sizeof(sin));
   3942   1.1       rjs 	memset(&sin6, 0, sizeof(sin6));
   3943   1.1       rjs 
   3944   1.1       rjs 	sin.sin_family = AF_INET;
   3945   1.1       rjs 	sin.sin_len = sizeof(sin);
   3946   1.1       rjs 	sin.sin_port = stcb->rport;
   3947   1.1       rjs 
   3948   1.1       rjs 	sin6.sin6_family = AF_INET6;
   3949   1.1       rjs 	sin6.sin6_len = sizeof(struct sockaddr_in6);
   3950   1.1       rjs 	sin6.sin6_port = stcb->rport;
   3951   1.1       rjs 	if (altsa == NULL) {
   3952   1.1       rjs 		iph = mtod(m, struct ip *);
   3953   1.1       rjs 		if (iph->ip_v == IPVERSION) {
   3954   1.1       rjs 			/* its IPv4 */
   3955   1.1       rjs 			struct sockaddr_in *sin_2;
   3956   1.1       rjs 			sin_2 = (struct sockaddr_in *)(local_sa);
   3957   1.1       rjs 			memset(sin_2, 0, sizeof(sin));
   3958   1.1       rjs 			sin_2->sin_family = AF_INET;
   3959   1.1       rjs 			sin_2->sin_len = sizeof(sin);
   3960   1.1       rjs 			sin_2->sin_port = sh->dest_port;
   3961   1.1       rjs 			sin_2->sin_addr.s_addr = iph->ip_dst.s_addr ;
   3962   1.1       rjs 			sin.sin_addr = iph->ip_src;
   3963   1.1       rjs 			sa = (struct sockaddr *)&sin;
   3964   1.1       rjs 		} else if (iph->ip_v == (IPV6_VERSION >> 4)) {
   3965   1.1       rjs 			/* its IPv6 */
   3966   1.1       rjs 			struct ip6_hdr *ip6;
   3967   1.1       rjs 			struct sockaddr_in6 *sin6_2;
   3968   1.1       rjs 
   3969   1.1       rjs 			ip6 = mtod(m, struct ip6_hdr *);
   3970   1.1       rjs 			sin6_2 = (struct sockaddr_in6 *)(local_sa);
   3971   1.1       rjs 			memset(sin6_2, 0, sizeof(sin6));
   3972   1.1       rjs 			sin6_2->sin6_family = AF_INET6;
   3973   1.1       rjs 			sin6_2->sin6_len = sizeof(struct sockaddr_in6);
   3974   1.1       rjs 			sin6_2->sin6_port = sh->dest_port;
   3975   1.1       rjs 			sin6.sin6_addr = ip6->ip6_src;
   3976   1.1       rjs 			sa = (struct sockaddr *)&sin6;
   3977   1.1       rjs 		} else {
   3978   1.1       rjs 			sa = NULL;
   3979   1.1       rjs 		}
   3980   1.1       rjs 	} else {
   3981   1.1       rjs 		/*
   3982   1.1       rjs 		 * For cookies we use the src address NOT from the packet
   3983   1.1       rjs 		 * but from the original INIT
   3984   1.1       rjs 		 */
   3985   1.1       rjs 		sa = altsa;
   3986   1.1       rjs 	}
   3987   1.1       rjs 	/* Turn off ECN until we get through all params */
   3988   1.1       rjs 	stcb->asoc.ecn_allowed = 0;
   3989   1.1       rjs 
   3990   1.1       rjs 	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
   3991   1.1       rjs 		/* mark all addresses that we have currently on the list */
   3992   1.1       rjs 		net->dest_state |= SCTP_ADDR_NOT_IN_ASSOC;
   3993   1.1       rjs 	}
   3994   1.1       rjs 	/* does the source address already exist? if so skip it */
   3995   1.1       rjs 	l_inp = inp = stcb->sctp_ep;
   3996   1.1       rjs 	stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net_tmp, local_sa, stcb);
   3997   1.1       rjs 	if ((stcb_tmp == NULL && inp == stcb->sctp_ep) || inp == NULL) {
   3998   1.1       rjs 		/* we must add the source address */
   3999   1.1       rjs 		/* no scope set here since we have a tcb already. */
   4000   1.1       rjs 		if ((sa->sa_family == AF_INET) &&
   4001   1.1       rjs 		    (stcb->asoc.ipv4_addr_legal)) {
   4002   1.1       rjs 			if (sctp_add_remote_addr(stcb, sa, 0, 2)) {
   4003   1.1       rjs 				return (-1);
   4004   1.1       rjs 			}
   4005   1.1       rjs 		} else if ((sa->sa_family == AF_INET6) &&
   4006   1.1       rjs 		    (stcb->asoc.ipv6_addr_legal)) {
   4007   1.1       rjs 			if (sctp_add_remote_addr(stcb, sa, 0, 3)) {
   4008   1.1       rjs 				return (-1);
   4009   1.1       rjs 			}
   4010   1.1       rjs 		}
   4011   1.1       rjs 	} else {
   4012   1.1       rjs 		if (net_tmp != NULL && stcb_tmp == stcb) {
   4013   1.1       rjs 			net_tmp->dest_state &= ~SCTP_ADDR_NOT_IN_ASSOC;
   4014   1.1       rjs 		} else if (stcb_tmp != stcb) {
   4015   1.1       rjs 			/* It belongs to another association? */
   4016   1.1       rjs 			return (-1);
   4017   1.1       rjs 		}
   4018   1.1       rjs 	}
   4019  1.23    andvar 	/* since a unlock occurred we must check the
   4020   1.1       rjs 	 * TCB's state and the pcb's gone flags.
   4021   1.1       rjs 	 */
   4022   1.1       rjs 	if (l_inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE|SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
   4023   1.1       rjs 		/* the user freed the ep */
   4024   1.1       rjs 		return (-1);
   4025   1.1       rjs 	}
   4026   1.1       rjs 	if (stcb->asoc.state == 0) {
   4027   1.1       rjs 		/* the assoc was freed? */
   4028   1.1       rjs 		return (-1);
   4029   1.1       rjs 	}
   4030   1.1       rjs 
   4031   1.1       rjs 	/* now we must go through each of the params. */
   4032   1.1       rjs 	phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
   4033   1.1       rjs 	while (phdr) {
   4034   1.1       rjs 		ptype = ntohs(phdr->param_type);
   4035   1.1       rjs 		plen = ntohs(phdr->param_length);
   4036   1.1       rjs 		/*printf("ptype => %d, plen => %d\n", ptype, plen);*/
   4037   1.1       rjs 		if (offset + plen > limit) {
   4038   1.1       rjs 			break;
   4039   1.1       rjs 		}
   4040   1.1       rjs 		if (plen == 0) {
   4041   1.1       rjs 			break;
   4042   1.1       rjs 		}
   4043   1.1       rjs 		if ((ptype == SCTP_IPV4_ADDRESS) &&
   4044   1.1       rjs 		    (stcb->asoc.ipv4_addr_legal)) {
   4045   1.1       rjs 			struct sctp_ipv4addr_param *p4, p4_buf;
   4046   1.1       rjs 			/* ok get the v4 address and check/add */
   4047   1.1       rjs 			phdr = sctp_get_next_param(m, offset,
   4048   1.1       rjs 			    (struct sctp_paramhdr *)&p4_buf, sizeof(p4_buf));
   4049   1.1       rjs 			if (plen != sizeof(struct sctp_ipv4addr_param) ||
   4050   1.1       rjs 			    phdr == NULL) {
   4051   1.1       rjs 				return (-1);
   4052   1.1       rjs 			}
   4053   1.1       rjs 			p4 = (struct sctp_ipv4addr_param *)phdr;
   4054   1.1       rjs 			sin.sin_addr.s_addr = p4->addr;
   4055   1.1       rjs 			sa = (struct sockaddr *)&sin;
   4056   1.1       rjs 			inp = stcb->sctp_ep;
   4057   1.1       rjs 			stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net,
   4058   1.1       rjs 			    local_sa, stcb);
   4059   1.1       rjs 
   4060   1.1       rjs 			if ((stcb_tmp== NULL && inp == stcb->sctp_ep) ||
   4061   1.1       rjs 			    inp == NULL) {
   4062   1.1       rjs 				/* we must add the source address */
   4063   1.1       rjs 				/* no scope set since we have a tcb already */
   4064   1.1       rjs 
   4065   1.1       rjs 				/* we must validate the state again here */
   4066   1.1       rjs 				if (l_inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE|SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
   4067   1.1       rjs 					/* the user freed the ep */
   4068   1.1       rjs 					return (-1);
   4069   1.1       rjs 				}
   4070   1.1       rjs 				if (stcb->asoc.state == 0) {
   4071   1.1       rjs 					/* the assoc was freed? */
   4072   1.1       rjs 					return (-1);
   4073   1.1       rjs 				}
   4074   1.1       rjs 				if (sctp_add_remote_addr(stcb, sa, 0, 4)) {
   4075   1.1       rjs 					return (-1);
   4076   1.1       rjs 				}
   4077   1.1       rjs 			} else if (stcb_tmp == stcb) {
   4078   1.1       rjs 				if (l_inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE|SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
   4079   1.1       rjs 					/* the user freed the ep */
   4080   1.1       rjs 					return (-1);
   4081   1.1       rjs 				}
   4082   1.1       rjs 				if (stcb->asoc.state == 0) {
   4083   1.1       rjs 					/* the assoc was freed? */
   4084   1.1       rjs 					return (-1);
   4085   1.1       rjs 				}
   4086   1.1       rjs 				if (net != NULL) {
   4087   1.1       rjs 					/* clear flag */
   4088   1.1       rjs 					net->dest_state &=
   4089   1.1       rjs 					    ~SCTP_ADDR_NOT_IN_ASSOC;
   4090   1.1       rjs 				}
   4091   1.1       rjs 			} else {
   4092   1.1       rjs 				/* strange, address is in another assoc?
   4093   1.1       rjs 				 * straighten out locks.
   4094   1.1       rjs 				 */
   4095   1.1       rjs 				SCTP_TCB_UNLOCK(stcb_tmp);
   4096   1.1       rjs 				SCTP_INP_RLOCK(inp);
   4097   1.1       rjs 				if (l_inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE|SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
   4098   1.1       rjs 					/* the user freed the ep */
   4099   1.1       rjs 					SCTP_INP_RUNLOCK(l_inp);
   4100   1.1       rjs 					return (-1);
   4101   1.1       rjs 				}
   4102   1.1       rjs 				if (stcb->asoc.state == 0) {
   4103   1.1       rjs 					/* the assoc was freed? */
   4104   1.1       rjs 					SCTP_INP_RUNLOCK(l_inp);
   4105   1.1       rjs 					return (-1);
   4106   1.1       rjs 				}
   4107   1.1       rjs 				SCTP_TCB_LOCK(stcb);
   4108   1.1       rjs 				SCTP_INP_RUNLOCK(stcb->sctp_ep);
   4109   1.1       rjs 				return (-1);
   4110   1.1       rjs 			}
   4111   1.1       rjs 		} else if ((ptype == SCTP_IPV6_ADDRESS) &&
   4112   1.1       rjs 		    (stcb->asoc.ipv6_addr_legal)) {
   4113   1.1       rjs 			/* ok get the v6 address and check/add */
   4114   1.1       rjs 			struct sctp_ipv6addr_param *p6, p6_buf;
   4115   1.1       rjs 			phdr = sctp_get_next_param(m, offset,
   4116   1.1       rjs 			    (struct sctp_paramhdr *)&p6_buf, sizeof(p6_buf));
   4117   1.1       rjs 			if (plen != sizeof(struct sctp_ipv6addr_param) ||
   4118   1.1       rjs 			    phdr == NULL) {
   4119   1.1       rjs 				return (-1);
   4120   1.1       rjs 			}
   4121   1.1       rjs 			p6 = (struct sctp_ipv6addr_param *)phdr;
   4122   1.1       rjs 			memcpy((void *)&sin6.sin6_addr, p6->addr,
   4123   1.1       rjs 			    sizeof(p6->addr));
   4124   1.1       rjs 			sa = (struct sockaddr *)&sin6;
   4125   1.1       rjs 			inp = stcb->sctp_ep;
   4126   1.1       rjs 			stcb_tmp= sctp_findassociation_ep_addr(&inp, sa, &net,
   4127   1.1       rjs 			    local_sa, stcb);
   4128   1.1       rjs 			if (stcb_tmp == NULL && (inp == stcb->sctp_ep ||
   4129   1.1       rjs 			    inp == NULL)) {
   4130   1.1       rjs 				/* we must validate the state again here */
   4131   1.1       rjs 				if (l_inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE|SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
   4132   1.1       rjs 					/* the user freed the ep */
   4133   1.1       rjs 					return (-1);
   4134   1.1       rjs 				}
   4135   1.1       rjs 				if (stcb->asoc.state == 0) {
   4136   1.1       rjs 					/* the assoc was freed? */
   4137   1.1       rjs 					return (-1);
   4138   1.1       rjs 				}
   4139   1.1       rjs 				/* we must add the address, no scope set */
   4140   1.1       rjs 				if (sctp_add_remote_addr(stcb, sa, 0, 5)) {
   4141   1.1       rjs 					return (-1);
   4142   1.1       rjs 				}
   4143   1.1       rjs 			} else if (stcb_tmp == stcb) {
   4144   1.1       rjs 				/* we must validate the state again here */
   4145   1.1       rjs 				if (l_inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE|SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
   4146   1.1       rjs 					/* the user freed the ep */
   4147   1.1       rjs 					return (-1);
   4148   1.1       rjs 				}
   4149   1.1       rjs 				if (stcb->asoc.state == 0) {
   4150   1.1       rjs 					/* the assoc was freed? */
   4151   1.1       rjs 					return (-1);
   4152   1.1       rjs 				}
   4153   1.1       rjs 				if (net != NULL) {
   4154   1.1       rjs 					/* clear flag */
   4155   1.1       rjs 					net->dest_state &=
   4156   1.1       rjs 					    ~SCTP_ADDR_NOT_IN_ASSOC;
   4157   1.1       rjs 				}
   4158   1.1       rjs 			} else {
   4159   1.1       rjs 				/* strange, address is in another assoc?
   4160   1.1       rjs 				 * straighten out locks.
   4161   1.1       rjs 				 */
   4162   1.1       rjs 				SCTP_TCB_UNLOCK(stcb_tmp);
   4163   1.1       rjs 				SCTP_INP_RLOCK(l_inp);
   4164   1.1       rjs 				/* we must validate the state again here */
   4165   1.1       rjs 				if (l_inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE|SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
   4166   1.1       rjs 					/* the user freed the ep */
   4167   1.1       rjs 					SCTP_INP_RUNLOCK(l_inp);
   4168   1.1       rjs 					return (-1);
   4169   1.1       rjs 				}
   4170   1.1       rjs 				if (stcb->asoc.state == 0) {
   4171   1.1       rjs 					/* the assoc was freed? */
   4172   1.1       rjs 					SCTP_INP_RUNLOCK(l_inp);
   4173   1.1       rjs 					return (-1);
   4174   1.1       rjs 				}
   4175   1.1       rjs 				SCTP_TCB_LOCK(stcb);
   4176   1.1       rjs 				SCTP_INP_RUNLOCK(l_inp);
   4177   1.1       rjs 				return (-1);
   4178   1.1       rjs 			}
   4179   1.1       rjs 		} else if (ptype == SCTP_ECN_CAPABLE) {
   4180   1.1       rjs 			stcb->asoc.ecn_allowed = 1;
   4181   1.1       rjs 		} else if (ptype == SCTP_ULP_ADAPTION) {
   4182   1.1       rjs 			if (stcb->asoc.state != SCTP_STATE_OPEN) {
   4183   1.1       rjs 				struct sctp_adaption_layer_indication ai, *aip;
   4184   1.1       rjs 
   4185   1.1       rjs 				phdr = sctp_get_next_param(m, offset,
   4186   1.1       rjs 							   (struct sctp_paramhdr *)&ai, sizeof(ai));
   4187   1.1       rjs 				aip = (struct sctp_adaption_layer_indication *)phdr;
   4188   1.1       rjs 				sctp_ulp_notify(SCTP_NOTIFY_ADAPTION_INDICATION,
   4189   1.1       rjs 						stcb, ntohl(aip->indication), NULL);
   4190   1.1       rjs 			}
   4191   1.1       rjs 		} else if (ptype == SCTP_SET_PRIM_ADDR) {
   4192   1.1       rjs 			struct sctp_asconf_addr_param lstore, *fee;
   4193   1.1       rjs 			struct sctp_asconf_addrv4_param *fii;
   4194   1.1       rjs 			int lptype;
   4195   1.1       rjs 			struct sockaddr *lsa = NULL;
   4196   1.1       rjs 
   4197   1.1       rjs 			stcb->asoc.peer_supports_asconf = 1;
   4198   1.1       rjs 			stcb->asoc.peer_supports_asconf_setprim = 1;
   4199   1.1       rjs 			if (plen > sizeof(lstore)) {
   4200   1.1       rjs 				return (-1);
   4201   1.1       rjs 			}
   4202   1.1       rjs 			phdr = sctp_get_next_param(m, offset,
   4203   1.1       rjs     			    (struct sctp_paramhdr *)&lstore, plen);
   4204   1.1       rjs 			if (phdr == NULL) {
   4205   1.1       rjs 				return (-1);
   4206   1.1       rjs 			}
   4207   1.1       rjs 
   4208   1.1       rjs 			fee  = (struct sctp_asconf_addr_param *)phdr;
   4209   1.1       rjs 			lptype = ntohs(fee->addrp.ph.param_type);
   4210   1.1       rjs 			if (lptype == SCTP_IPV4_ADDRESS) {
   4211   1.1       rjs 				if (plen !=
   4212   1.1       rjs 				    sizeof(struct sctp_asconf_addrv4_param)) {
   4213   1.1       rjs 					printf("Sizeof setprim in init/init ack not %d but %d - ignored\n",
   4214   1.1       rjs 				           (int)sizeof(struct sctp_asconf_addrv4_param),
   4215   1.1       rjs 				           plen);
   4216   1.1       rjs 				} else {
   4217   1.1       rjs 					fii = (struct sctp_asconf_addrv4_param *)fee;
   4218   1.1       rjs 					sin.sin_addr.s_addr = fii->addrp.addr;
   4219   1.1       rjs 					lsa = (struct sockaddr *)&sin;
   4220   1.1       rjs 				}
   4221   1.1       rjs 			} else if (lptype == SCTP_IPV6_ADDRESS) {
   4222   1.1       rjs 				if (plen !=
   4223   1.1       rjs 				    sizeof(struct sctp_asconf_addr_param)) {
   4224   1.1       rjs 					printf("Sizeof setprim (v6) in init/init ack not %d but %d - ignored\n",
   4225   1.1       rjs 				           (int)sizeof(struct sctp_asconf_addr_param),
   4226   1.1       rjs 				           plen);
   4227   1.1       rjs 				} else {
   4228   1.1       rjs 					memcpy(sin6.sin6_addr.s6_addr,
   4229   1.1       rjs 					    fee->addrp.addr,
   4230   1.1       rjs 					    sizeof(fee->addrp.addr));
   4231   1.1       rjs 					lsa = (struct sockaddr *)&sin6;
   4232   1.1       rjs 				}
   4233   1.1       rjs 			}
   4234   1.1       rjs 			if (lsa) {
   4235   1.1       rjs 				sctp_set_primary_addr(stcb, sa, NULL);
   4236   1.1       rjs 			}
   4237   1.1       rjs 
   4238   1.1       rjs 		} else if (ptype == SCTP_PRSCTP_SUPPORTED) {
   4239   1.1       rjs 			/* Peer supports pr-sctp */
   4240   1.1       rjs 			stcb->asoc.peer_supports_prsctp = 1;
   4241   1.1       rjs 		} else if (ptype == SCTP_SUPPORTED_CHUNK_EXT) {
   4242   1.1       rjs 			/* A supported extension chunk */
   4243   1.1       rjs 			struct sctp_supported_chunk_types_param *pr_supported;
   4244   1.1       rjs 			uint8_t local_store[128];
   4245   1.1       rjs 			int num_ent, i;
   4246   1.1       rjs 
   4247   1.1       rjs 			phdr = sctp_get_next_param(m, offset,
   4248   1.1       rjs     			    (struct sctp_paramhdr *)&local_store, plen);
   4249   1.1       rjs 			if (phdr == NULL) {
   4250   1.1       rjs 				return (-1);
   4251   1.1       rjs 			}
   4252   1.1       rjs 			stcb->asoc.peer_supports_asconf = 0;
   4253   1.1       rjs 			stcb->asoc.peer_supports_asconf_setprim = 0;
   4254   1.1       rjs 			stcb->asoc.peer_supports_prsctp = 0;
   4255   1.1       rjs 			stcb->asoc.peer_supports_pktdrop = 0;
   4256   1.1       rjs 			stcb->asoc.peer_supports_strreset = 0;
   4257   1.1       rjs 			pr_supported = (struct sctp_supported_chunk_types_param *)phdr;
   4258   1.1       rjs 			num_ent = plen - sizeof(struct sctp_paramhdr);
   4259   1.1       rjs 			for (i=0; i<num_ent; i++) {
   4260   1.1       rjs 				switch (pr_supported->chunk_types[i]) {
   4261   1.1       rjs 				case SCTP_ASCONF:
   4262   1.1       rjs 					stcb->asoc.peer_supports_asconf = 1;
   4263   1.1       rjs 					stcb->asoc.peer_supports_asconf_setprim = 1;
   4264   1.1       rjs 					break;
   4265   1.1       rjs 				case SCTP_ASCONF_ACK:
   4266   1.1       rjs 					stcb->asoc.peer_supports_asconf = 1;
   4267   1.1       rjs 					stcb->asoc.peer_supports_asconf_setprim = 1;
   4268   1.1       rjs 					break;
   4269   1.1       rjs 				case SCTP_FORWARD_CUM_TSN:
   4270   1.1       rjs 					stcb->asoc.peer_supports_prsctp = 1;
   4271   1.1       rjs 					break;
   4272   1.1       rjs 				case SCTP_PACKET_DROPPED:
   4273   1.1       rjs 					stcb->asoc.peer_supports_pktdrop = 1;
   4274   1.1       rjs 					break;
   4275   1.1       rjs 				case SCTP_STREAM_RESET:
   4276   1.1       rjs 					stcb->asoc.peer_supports_strreset = 1;
   4277   1.1       rjs 					break;
   4278   1.1       rjs 				default:
   4279   1.1       rjs 					/* one I have not learned yet */
   4280   1.1       rjs 					break;
   4281   1.1       rjs 
   4282   1.1       rjs 				}
   4283   1.1       rjs 			}
   4284   1.1       rjs 		} else if (ptype == SCTP_ECN_NONCE_SUPPORTED) {
   4285   1.1       rjs 			/* Peer supports ECN-nonce */
   4286   1.1       rjs 			stcb->asoc.peer_supports_ecn_nonce = 1;
   4287   1.1       rjs 			stcb->asoc.ecn_nonce_allowed = 1;
   4288   1.1       rjs 		} else if ((ptype == SCTP_HEARTBEAT_INFO) ||
   4289   1.1       rjs 			   (ptype == SCTP_STATE_COOKIE) ||
   4290   1.1       rjs 			   (ptype == SCTP_UNRECOG_PARAM) ||
   4291   1.1       rjs 			   (ptype == SCTP_COOKIE_PRESERVE) ||
   4292   1.1       rjs 			   (ptype == SCTP_SUPPORTED_ADDRTYPE) ||
   4293   1.1       rjs 			   (ptype == SCTP_ADD_IP_ADDRESS) ||
   4294   1.1       rjs 			   (ptype == SCTP_DEL_IP_ADDRESS) ||
   4295   1.1       rjs 			   (ptype == SCTP_ERROR_CAUSE_IND) ||
   4296   1.1       rjs 			   (ptype == SCTP_SUCCESS_REPORT)) {
   4297   1.1       rjs 			/* don't care */;
   4298   1.1       rjs 		} else {
   4299   1.1       rjs 			if ((ptype & 0x8000) == 0x0000) {
   4300   1.1       rjs 				/* must stop processing the rest of
   4301   1.1       rjs 				 * the param's. Any report bits were
   4302   1.1       rjs 				 * handled with the call to sctp_arethere_unrecognized_parameters()
   4303   1.1       rjs 				 * when the INIT or INIT-ACK was first seen.
   4304   1.1       rjs 				 */
   4305   1.1       rjs 				break;
   4306   1.1       rjs 			}
   4307   1.1       rjs 		}
   4308   1.1       rjs 		offset += SCTP_SIZE32(plen);
   4309   1.1       rjs 		if (offset >= limit) {
   4310   1.1       rjs 			break;
   4311   1.1       rjs 		}
   4312   1.1       rjs 		phdr = sctp_get_next_param(m, offset, &parm_buf,
   4313   1.1       rjs 		    sizeof(parm_buf));
   4314   1.1       rjs 	}
   4315   1.1       rjs 	/* Now check to see if we need to purge any addresses */
   4316   1.1       rjs 	for (net = TAILQ_FIRST(&stcb->asoc.nets); net != NULL; net = net_tmp) {
   4317   1.1       rjs 		net_tmp = TAILQ_NEXT(net, sctp_next);
   4318   1.1       rjs 		if ((net->dest_state & SCTP_ADDR_NOT_IN_ASSOC) ==
   4319   1.1       rjs 		    SCTP_ADDR_NOT_IN_ASSOC) {
   4320   1.1       rjs 			/* This address has been removed from the asoc */
   4321   1.1       rjs 			/* remove and free it */
   4322   1.1       rjs 			stcb->asoc.numnets--;
   4323   1.1       rjs 			TAILQ_REMOVE(&stcb->asoc.nets, net, sctp_next);
   4324   1.1       rjs 			sctp_free_remote_addr(net);
   4325   1.1       rjs 			if (net == stcb->asoc.primary_destination) {
   4326   1.1       rjs 				stcb->asoc.primary_destination = NULL;
   4327   1.1       rjs 				sctp_select_primary_destination(stcb);
   4328   1.1       rjs 			}
   4329   1.1       rjs 		}
   4330   1.1       rjs 	}
   4331   1.1       rjs 	return (0);
   4332   1.1       rjs }
   4333   1.1       rjs 
   4334   1.1       rjs int
   4335   1.1       rjs sctp_set_primary_addr(struct sctp_tcb *stcb, struct sockaddr *sa,
   4336   1.1       rjs     struct sctp_nets *net)
   4337   1.1       rjs {
   4338   1.1       rjs 	/* make sure the requested primary address exists in the assoc */
   4339   1.1       rjs 	if (net == NULL && sa)
   4340   1.1       rjs 		net = sctp_findnet(stcb, sa);
   4341   1.1       rjs 
   4342   1.1       rjs 	if (net == NULL) {
   4343   1.1       rjs 		/* didn't find the requested primary address! */
   4344   1.1       rjs 		return (-1);
   4345   1.1       rjs 	} else {
   4346   1.1       rjs 		/* set the primary address */
   4347   1.1       rjs 		if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
   4348   1.1       rjs 			/* Must be confirmed */
   4349   1.1       rjs 			return (-1);
   4350   1.1       rjs 		}
   4351   1.1       rjs 		stcb->asoc.primary_destination = net;
   4352   1.1       rjs 		net->dest_state &= ~SCTP_ADDR_WAS_PRIMARY;
   4353   1.1       rjs 		return (0);
   4354   1.1       rjs 	}
   4355   1.1       rjs }
   4356   1.1       rjs 
   4357   1.1       rjs 
   4358   1.1       rjs int
   4359   1.1       rjs sctp_is_vtag_good(struct sctp_inpcb *inp, u_int32_t tag, struct timeval *now)
   4360   1.1       rjs {
   4361   1.1       rjs 	/*
   4362   1.1       rjs 	 * This function serves two purposes. It will see if a TAG can be
   4363   1.1       rjs 	 * re-used and return 1 for yes it is ok and 0 for don't use that
   4364   1.1       rjs 	 * tag.
   4365   1.1       rjs 	 * A secondary function it will do is purge out old tags that can
   4366   1.1       rjs 	 * be removed.
   4367   1.1       rjs 	 */
   4368   1.1       rjs 	struct sctpasochead *head;
   4369   1.1       rjs 	struct sctpvtaghead *chain;
   4370   1.1       rjs 	struct sctp_tagblock *twait_block;
   4371   1.1       rjs 	struct sctp_tcb *stcb;
   4372   1.1       rjs 
   4373   1.1       rjs 	int i;
   4374   1.1       rjs 	SCTP_INP_INFO_WLOCK();
   4375   1.1       rjs 	chain = &sctppcbinfo.vtag_timewait[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
   4376   1.1       rjs 	/* First is the vtag in use ? */
   4377   1.1       rjs 
   4378   1.1       rjs 	head = &sctppcbinfo.sctp_asochash[SCTP_PCBHASH_ASOC(tag,
   4379   1.1       rjs 	    sctppcbinfo.hashasocmark)];
   4380   1.1       rjs 	if (head == NULL) {
   4381   1.1       rjs 		SCTP_INP_INFO_WUNLOCK();
   4382   1.1       rjs 		return (0);
   4383   1.1       rjs 	}
   4384   1.1       rjs 	LIST_FOREACH(stcb, head, sctp_asocs) {
   4385   1.1       rjs 		if (stcb->asoc.my_vtag == tag) {
   4386   1.1       rjs 			/* We should remove this if and
   4387   1.1       rjs 			 * return 0 always if we want vtags
   4388   1.1       rjs 			 * unique across all endpoints. For
   4389   1.1       rjs 			 * now within a endpoint is ok.
   4390   1.1       rjs 			 */
   4391   1.1       rjs  			if (inp == stcb->sctp_ep) {
   4392   1.1       rjs 				/* bad tag, in use */
   4393   1.1       rjs 				SCTP_INP_INFO_WUNLOCK();
   4394   1.1       rjs 				return (0);
   4395   1.1       rjs 			}
   4396   1.1       rjs 		}
   4397   1.1       rjs 	}
   4398   1.1       rjs 	if (!LIST_EMPTY(chain)) {
   4399   1.1       rjs 		/*
   4400   1.1       rjs 		 * Block(s) are present, lets see if we have this tag in
   4401   1.1       rjs 		 * the list
   4402   1.1       rjs 		 */
   4403   1.1       rjs 		LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
   4404   1.1       rjs 			for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
   4405   1.1       rjs 				if (twait_block->vtag_block[i].v_tag == 0) {
   4406   1.1       rjs 					/* not used */
   4407   1.1       rjs 					continue;
   4408   1.1       rjs 				} else if ((long)twait_block->vtag_block[i].tv_sec_at_expire >
   4409   1.1       rjs 				    now->tv_sec) {
   4410   1.1       rjs 					/* Audit expires this guy */
   4411   1.1       rjs 					twait_block->vtag_block[i].tv_sec_at_expire = 0;
   4412   1.1       rjs 					twait_block->vtag_block[i].v_tag = 0;
   4413   1.1       rjs 				} else if (twait_block->vtag_block[i].v_tag ==
   4414   1.1       rjs 				    tag) {
   4415   1.1       rjs 					/* Bad tag, sorry :< */
   4416   1.1       rjs 					SCTP_INP_INFO_WUNLOCK();
   4417   1.1       rjs 					return (0);
   4418   1.1       rjs 				}
   4419   1.1       rjs 			}
   4420   1.1       rjs 		}
   4421   1.1       rjs 	}
   4422   1.1       rjs 	/* Not found, ok to use the tag */
   4423   1.1       rjs 	SCTP_INP_INFO_WUNLOCK();
   4424   1.1       rjs 	return (1);
   4425   1.1       rjs }
   4426   1.1       rjs 
   4427   1.1       rjs 
   4428   1.1       rjs /*
   4429   1.1       rjs  * Delete the address from the endpoint local address list
   4430   1.1       rjs  * Lookup using a sockaddr address (ie. not an ifaddr)
   4431   1.1       rjs  */
   4432   1.1       rjs int
   4433   1.1       rjs sctp_del_local_addr_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa)
   4434   1.1       rjs {
   4435   1.1       rjs 	struct sctp_laddr *laddr;
   4436   1.1       rjs 	struct sockaddr *l_sa;
   4437   1.1       rjs 	int found = 0;
   4438   1.1       rjs 	/* Here is another function I cannot find a
   4439   1.1       rjs 	 * caller for. As such we SHOULD delete it
   4440   1.1       rjs 	 * if we have no users. If we find a user that
   4441   1.1       rjs 	 * user MUST have the INP locked.
   4442   1.1       rjs 	 *
   4443   1.1       rjs 	 */
   4444   1.1       rjs 
   4445   1.1       rjs 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
   4446   1.1       rjs 		/* You are already bound to all. You have it already */
   4447   1.1       rjs 		return (EINVAL);
   4448   1.1       rjs 	}
   4449   1.1       rjs 
   4450   1.1       rjs 	LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
   4451   1.1       rjs 		/* make sure the address exists */
   4452   1.1       rjs 		if (laddr->ifa == NULL)
   4453   1.1       rjs 			continue;
   4454   1.1       rjs 		if (laddr->ifa->ifa_addr == NULL)
   4455   1.1       rjs 			continue;
   4456   1.1       rjs 
   4457   1.1       rjs 		l_sa = laddr->ifa->ifa_addr;
   4458   1.1       rjs 		if (l_sa->sa_family == AF_INET6) {
   4459   1.1       rjs 			/* IPv6 address */
   4460   1.1       rjs 			struct sockaddr_in6 *sin1, *sin2;
   4461   1.1       rjs 			sin1 = (struct sockaddr_in6 *)l_sa;
   4462   1.1       rjs 			sin2 = (struct sockaddr_in6 *)sa;
   4463   1.1       rjs 			if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
   4464   1.1       rjs 			    sizeof(struct in6_addr)) == 0) {
   4465   1.1       rjs 				/* matched */
   4466   1.1       rjs 				found = 1;
   4467   1.1       rjs 				break;
   4468   1.1       rjs 			}
   4469   1.1       rjs 		} else if (l_sa->sa_family == AF_INET) {
   4470   1.1       rjs 			/* IPv4 address */
   4471   1.1       rjs 			struct sockaddr_in *sin1, *sin2;
   4472   1.1       rjs 			sin1 = (struct sockaddr_in *)l_sa;
   4473   1.1       rjs 			sin2 = (struct sockaddr_in *)sa;
   4474   1.1       rjs 			if (sin1->sin_addr.s_addr == sin2->sin_addr.s_addr) {
   4475   1.1       rjs 				/* matched */
   4476   1.1       rjs 				found = 1;
   4477   1.1       rjs 				break;
   4478   1.1       rjs 			}
   4479   1.1       rjs 		} else {
   4480   1.1       rjs 			/* invalid family */
   4481   1.1       rjs 			return (-1);
   4482   1.1       rjs 		}
   4483   1.1       rjs 	}
   4484   1.1       rjs 
   4485   1.1       rjs 	if (found && inp->laddr_count < 2) {
   4486   1.1       rjs 		/* can't delete unless there are at LEAST 2 addresses */
   4487   1.1       rjs 		return (-1);
   4488   1.1       rjs 	}
   4489   1.1       rjs 
   4490   1.1       rjs 	if (found && (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
   4491   1.1       rjs 		/*
   4492   1.1       rjs 		 * remove it from the ep list, this should NOT be
   4493   1.1       rjs 		 * done until its really gone from the interface list and
   4494   1.1       rjs 		 * we won't be receiving more of these. Probably right
   4495   1.1       rjs 		 * away. If we do allow a removal of an address from
   4496   1.1       rjs 		 * an association (sub-set bind) than this should NOT
   4497   1.1       rjs 		 * be called until the all ASCONF come back from this
   4498   1.1       rjs 		 * association.
   4499   1.1       rjs 		 */
   4500   1.1       rjs 		sctp_remove_laddr(laddr);
   4501   1.1       rjs 		return (0);
   4502   1.1       rjs 	} else {
   4503   1.1       rjs 		return (-1);
   4504   1.1       rjs 	}
   4505   1.1       rjs }
   4506   1.1       rjs 
   4507   1.1       rjs static void
   4508   1.1       rjs sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
   4509   1.1       rjs {
   4510   1.1       rjs 	/*
   4511   1.1       rjs 	 * We must hunt this association for MBUF's past the cumack
   4512   1.1       rjs 	 * (i.e. out of order data that we can renege on).
   4513   1.1       rjs 	 */
   4514   1.1       rjs 	struct sctp_association *asoc;
   4515   1.1       rjs 	struct sctp_tmit_chunk *chk, *nchk;
   4516   1.1       rjs 	u_int32_t cumulative_tsn_p1, tsn;
   4517   1.1       rjs 	int cnt, strmat, gap;
   4518   1.1       rjs 	/* We look for anything larger than the cum-ack + 1 */
   4519   1.1       rjs 
   4520   1.1       rjs 	asoc = &stcb->asoc;
   4521   1.1       rjs 	cumulative_tsn_p1 = asoc->cumulative_tsn + 1;
   4522   1.1       rjs 	cnt = 0;
   4523   1.1       rjs 	/* First look in the re-assembly queue */
   4524   1.1       rjs 	chk = TAILQ_FIRST(&asoc->reasmqueue);
   4525   1.1       rjs 	while (chk) {
   4526   1.1       rjs 		/* Get the next one */
   4527   1.1       rjs 		nchk = TAILQ_NEXT(chk, sctp_next);
   4528   1.1       rjs 		if (compare_with_wrap(chk->rec.data.TSN_seq,
   4529   1.1       rjs 		    cumulative_tsn_p1, MAX_TSN)) {
   4530   1.1       rjs 			/* Yep it is above cum-ack */
   4531   1.1       rjs 			cnt++;
   4532   1.1       rjs 			tsn = chk->rec.data.TSN_seq;
   4533   1.1       rjs 			if (tsn >= asoc->mapping_array_base_tsn) {
   4534   1.1       rjs 				gap  = tsn - asoc->mapping_array_base_tsn;
   4535   1.1       rjs 			} else {
   4536   1.1       rjs 				gap = (MAX_TSN - asoc->mapping_array_base_tsn) +
   4537   1.1       rjs 				    tsn + 1;
   4538   1.1       rjs 			}
   4539   1.1       rjs 			asoc->size_on_reasm_queue -= chk->send_size;
   4540   1.1       rjs 			asoc->cnt_on_reasm_queue--;
   4541   1.1       rjs 			SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
   4542   1.1       rjs 			TAILQ_REMOVE(&asoc->reasmqueue, chk, sctp_next);
   4543   1.1       rjs 			if (chk->data) {
   4544   1.1       rjs 				sctp_m_freem(chk->data);
   4545   1.1       rjs 				chk->data = NULL;
   4546   1.1       rjs 			}
   4547   1.1       rjs 			SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   4548   1.1       rjs 			sctppcbinfo.ipi_count_chunk--;
   4549   1.1       rjs 			if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   4550   1.1       rjs 				panic("Chunk count is negative");
   4551   1.1       rjs 			}
   4552   1.1       rjs 			sctppcbinfo.ipi_gencnt_chunk++;
   4553   1.1       rjs 		}
   4554   1.1       rjs 		chk = nchk;
   4555   1.1       rjs 	}
   4556   1.1       rjs 	/* Ok that was fun, now we will drain all the inbound streams? */
   4557   1.1       rjs 	for (strmat = 0; strmat < asoc->streamincnt; strmat++) {
   4558   1.1       rjs 		chk = TAILQ_FIRST(&asoc->strmin[strmat].inqueue);
   4559   1.1       rjs 		while (chk) {
   4560   1.1       rjs 			nchk = TAILQ_NEXT(chk, sctp_next);
   4561   1.1       rjs 			if (compare_with_wrap(chk->rec.data.TSN_seq,
   4562   1.1       rjs 			    cumulative_tsn_p1, MAX_TSN)) {
   4563   1.1       rjs 				/* Yep it is above cum-ack */
   4564   1.1       rjs 				cnt++;
   4565   1.1       rjs 				tsn = chk->rec.data.TSN_seq;
   4566   1.1       rjs 				if (tsn >= asoc->mapping_array_base_tsn) {
   4567   1.1       rjs 					gap = tsn -
   4568   1.1       rjs 					    asoc->mapping_array_base_tsn;
   4569   1.1       rjs 				} else {
   4570   1.1       rjs 					gap = (MAX_TSN -
   4571   1.1       rjs 					    asoc->mapping_array_base_tsn) +
   4572   1.1       rjs 					    tsn + 1;
   4573   1.1       rjs 				}
   4574   1.1       rjs 				asoc->size_on_all_streams -= chk->send_size;
   4575   1.1       rjs 				asoc->cnt_on_all_streams--;
   4576   1.1       rjs 
   4577   1.1       rjs 				SCTP_UNSET_TSN_PRESENT(asoc->mapping_array,
   4578   1.1       rjs 				    gap);
   4579   1.1       rjs 				TAILQ_REMOVE(&asoc->strmin[strmat].inqueue,
   4580   1.1       rjs 				    chk, sctp_next);
   4581   1.1       rjs 				if (chk->data) {
   4582   1.1       rjs 					sctp_m_freem(chk->data);
   4583   1.1       rjs 					chk->data = NULL;
   4584   1.1       rjs 				}
   4585   1.1       rjs 				SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
   4586   1.1       rjs 				sctppcbinfo.ipi_count_chunk--;
   4587   1.1       rjs 				if ((int)sctppcbinfo.ipi_count_chunk < 0) {
   4588   1.1       rjs 					panic("Chunk count is negative");
   4589   1.1       rjs 				}
   4590   1.1       rjs 				sctppcbinfo.ipi_gencnt_chunk++;
   4591   1.1       rjs 			}
   4592   1.1       rjs 			chk = nchk;
   4593   1.1       rjs 		}
   4594   1.1       rjs 	}
   4595   1.1       rjs 	/*
   4596   1.1       rjs 	 * Question, should we go through the delivery queue?
   4597   1.1       rjs 	 * The only reason things are on here is the app not reading OR a
   4598   1.1       rjs 	 * p-d-api up. An attacker COULD send enough in to initiate the
   4599   1.1       rjs 	 * PD-API and then send a bunch of stuff to other streams... these
   4600   1.1       rjs 	 * would wind up on the delivery queue.. and then we would not get
   4601   1.1       rjs 	 * to them. But in order to do this I then have to back-track and
   4602   1.1       rjs 	 * un-deliver sequence numbers in streams.. el-yucko. I think for
   4603   1.1       rjs 	 * now we will NOT look at the delivery queue and leave it to be
   4604   1.1       rjs 	 * something to consider later. An alternative would be to abort
   4605   1.1       rjs 	 * the P-D-API with a notification and then deliver the data....
   4606   1.1       rjs 	 * Or another method might be to keep track of how many times the
   4607   1.1       rjs 	 * situation occurs and if we see a possible attack underway just
   4608   1.1       rjs 	 * abort the association.
   4609   1.1       rjs 	 */
   4610   1.1       rjs #ifdef SCTP_DEBUG
   4611   1.1       rjs 	if (sctp_debug_on & SCTP_DEBUG_PCB1) {
   4612   1.1       rjs 		if (cnt) {
   4613   1.1       rjs 			printf("Freed %d chunks from reneg harvest\n", cnt);
   4614   1.1       rjs 		}
   4615   1.1       rjs 	}
   4616   1.1       rjs #endif /* SCTP_DEBUG */
   4617   1.1       rjs 
   4618   1.1       rjs 	/*
   4619   1.1       rjs 	 * Another issue, in un-setting the TSN's in the mapping array we
   4620  1.25    andvar 	 * DID NOT adjust the highest_tsn marker.  This will cause one of
   4621   1.1       rjs 	 * two things to occur. It may cause us to do extra work in checking
   4622   1.1       rjs 	 * for our mapping array movement. More importantly it may cause us
   4623   1.1       rjs 	 * to SACK every datagram. This may not be a bad thing though since
   4624   1.1       rjs 	 * we will recover once we get our cum-ack above and all this stuff
   4625   1.1       rjs 	 * we dumped recovered.
   4626   1.1       rjs 	 */
   4627   1.1       rjs }
   4628   1.1       rjs 
   4629   1.1       rjs void
   4630   1.1       rjs sctp_drain(void)
   4631   1.1       rjs {
   4632   1.1       rjs 	/*
   4633   1.1       rjs 	 * We must walk the PCB lists for ALL associations here. The system
   4634   1.1       rjs 	 * is LOW on MBUF's and needs help. This is where reneging will
   4635   1.1       rjs 	 * occur. We really hope this does NOT happen!
   4636   1.1       rjs 	 */
   4637   1.1       rjs 	struct sctp_inpcb *inp;
   4638   1.1       rjs 	struct sctp_tcb *stcb;
   4639   1.1       rjs 
   4640   1.1       rjs 	SCTP_INP_INFO_RLOCK();
   4641   1.1       rjs 	LIST_FOREACH(inp, &sctppcbinfo.listhead, sctp_list) {
   4642   1.1       rjs 		/* For each endpoint */
   4643   1.1       rjs 		SCTP_INP_RLOCK(inp);
   4644   1.1       rjs 		LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
   4645   1.1       rjs 			/* For each association */
   4646   1.1       rjs 			SCTP_TCB_LOCK(stcb);
   4647   1.1       rjs 			sctp_drain_mbufs(inp, stcb);
   4648   1.1       rjs 			SCTP_TCB_UNLOCK(stcb);
   4649   1.1       rjs 		}
   4650   1.1       rjs 		SCTP_INP_RUNLOCK(inp);
   4651   1.1       rjs 	}
   4652   1.1       rjs 	SCTP_INP_INFO_RUNLOCK();
   4653   1.1       rjs }
   4654   1.1       rjs 
   4655   1.1       rjs int
   4656   1.1       rjs sctp_add_to_socket_q(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
   4657   1.1       rjs {
   4658   1.1       rjs 	struct sctp_socket_q_list *sq;
   4659   1.1       rjs 
   4660   1.1       rjs 	/* write lock on INP assumed */
   4661   1.1       rjs 	if ((inp == NULL) || (stcb == NULL)) {
   4662   1.1       rjs 		/* I am paranoid */
   4663   1.1       rjs 		return (0);
   4664   1.1       rjs 	}
   4665   1.1       rjs 	sq = (struct sctp_socket_q_list *)SCTP_ZONE_GET(
   4666   1.1       rjs 	    sctppcbinfo.ipi_zone_sockq);
   4667   1.1       rjs 	if (sq == NULL) {
   4668   1.1       rjs 		/* out of sq structs */
   4669   1.1       rjs 		return (0);
   4670   1.1       rjs 	}
   4671   1.1       rjs 	sctppcbinfo.ipi_count_sockq++;
   4672   1.1       rjs 	sctppcbinfo.ipi_gencnt_sockq++;
   4673   1.1       rjs 	if (stcb)
   4674   1.1       rjs 		stcb->asoc.cnt_msg_on_sb++;
   4675   1.1       rjs 	sq->tcb = stcb;
   4676   1.1       rjs 	TAILQ_INSERT_TAIL(&inp->sctp_queue_list, sq, next_sq);
   4677   1.1       rjs 	return (1);
   4678   1.1       rjs }
   4679   1.1       rjs 
   4680   1.1       rjs 
   4681   1.1       rjs struct sctp_tcb *
   4682   1.1       rjs sctp_remove_from_socket_q(struct sctp_inpcb *inp)
   4683   1.1       rjs {
   4684   1.1       rjs 	struct sctp_tcb *stcb = NULL;
   4685   1.1       rjs 	struct sctp_socket_q_list *sq;
   4686   1.1       rjs 
   4687   1.1       rjs 	/* W-Lock on INP assumed held */
   4688   1.1       rjs 	sq = TAILQ_FIRST(&inp->sctp_queue_list);
   4689   1.1       rjs 	if (sq == NULL)
   4690   1.1       rjs 		return (NULL);
   4691   1.1       rjs 
   4692   1.1       rjs 	stcb = sq->tcb;
   4693   1.1       rjs 	TAILQ_REMOVE(&inp->sctp_queue_list, sq, next_sq);
   4694   1.1       rjs 	SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_sockq, sq);
   4695   1.1       rjs 	sctppcbinfo.ipi_count_sockq--;
   4696   1.1       rjs 	sctppcbinfo.ipi_gencnt_sockq++;
   4697   1.1       rjs 	if (stcb) {
   4698   1.1       rjs 		stcb->asoc.cnt_msg_on_sb--;
   4699   1.1       rjs 	}
   4700   1.1       rjs 	return (stcb);
   4701   1.1       rjs }
   4702   1.1       rjs 
   4703   1.1       rjs int
   4704   1.1       rjs sctp_initiate_iterator(asoc_func af, uint32_t pcb_state, uint32_t asoc_state,
   4705   1.1       rjs 		       void *argp, uint32_t argi, end_func ef,
   4706   1.1       rjs 		       struct sctp_inpcb *s_inp)
   4707   1.1       rjs {
   4708   1.1       rjs 	struct sctp_iterator *it=NULL;
   4709   1.1       rjs 	int s;
   4710   1.1       rjs 	if (af == NULL) {
   4711   1.1       rjs 		return (-1);
   4712   1.1       rjs 	}
   4713   1.1       rjs 	it = malloc(sizeof(struct sctp_iterator), M_PCB, M_WAITOK);
   4714   1.1       rjs 	if (it == NULL) {
   4715   1.1       rjs 		return (ENOMEM);
   4716   1.1       rjs 	}
   4717   1.1       rjs 	memset(it, 0, sizeof(*it));
   4718   1.1       rjs 	it->function_toapply = af;
   4719   1.1       rjs 	it->function_atend = ef;
   4720   1.1       rjs 	it->pointer = argp;
   4721   1.1       rjs 	it->val = argi;
   4722   1.1       rjs 	it->pcb_flags = pcb_state;
   4723   1.1       rjs 	it->asoc_state = asoc_state;
   4724   1.1       rjs 	if (s_inp) {
   4725   1.1       rjs 		it->inp = s_inp;
   4726   1.1       rjs 		it->iterator_flags = SCTP_ITERATOR_DO_SINGLE_INP;
   4727   1.1       rjs 	} else {
   4728   1.1       rjs 		SCTP_INP_INFO_RLOCK();
   4729   1.1       rjs 		it->inp = LIST_FIRST(&sctppcbinfo.listhead);
   4730   1.1       rjs 		SCTP_INP_INFO_RUNLOCK();
   4731   1.1       rjs 		it->iterator_flags = SCTP_ITERATOR_DO_ALL_INP;
   4732   1.1       rjs 
   4733   1.1       rjs 	}
   4734   1.1       rjs 	/* Init the timer */
   4735   1.1       rjs 	callout_init(&it->tmr.timer, 0);
   4736   1.1       rjs 	/* add to the list of all iterators */
   4737   1.1       rjs 	SCTP_INP_INFO_WLOCK();
   4738   1.1       rjs 	LIST_INSERT_HEAD(&sctppcbinfo.iteratorhead, it, sctp_nxt_itr);
   4739   1.1       rjs 	SCTP_INP_INFO_WUNLOCK();
   4740   1.1       rjs 	s = splsoftnet();
   4741   1.1       rjs 	sctp_iterator_timer(it);
   4742   1.1       rjs 	splx(s);
   4743   1.1       rjs 	return (0);
   4744   1.1       rjs }
   4745   1.1       rjs 
   4746   1.1       rjs 
   4747