blob: a94b28b0ea653933fab3eb5d8e2fe985c5344ae1 [file] [log] [blame]
tuexendd729232011-11-01 23:04:43 +00001/*-
2 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
tuexen194eae12012-05-23 12:03:48 +00003 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
4 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
tuexendd729232011-11-01 23:04:43 +00005 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * a) Redistributions of source code must retain the above copyright notice,
tuexen9784e9a2011-12-18 13:04:23 +000010 * this list of conditions and the following disclaimer.
tuexendd729232011-11-01 23:04:43 +000011 *
12 * b) Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
tuexen9784e9a2011-12-18 13:04:23 +000014 * the documentation and/or other materials provided with the distribution.
tuexendd729232011-11-01 23:04:43 +000015 *
16 * c) Neither the name of Cisco Systems, Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
tuexendd729232011-11-01 23:04:43 +000033#ifdef __FreeBSD__
34#include <sys/cdefs.h>
Michael Tuexen923f7352016-05-01 23:55:35 +020035__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 298902 2016-05-01 21:48:55Z tuexen $");
tuexendd729232011-11-01 23:04:43 +000036#endif
37
38#include <netinet/sctp_os.h>
39#ifdef __FreeBSD__
40#include <sys/proc.h>
41#endif
42#include <netinet/sctp_var.h>
43#include <netinet/sctp_sysctl.h>
44#include <netinet/sctp_pcb.h>
45#include <netinet/sctputil.h>
46#include <netinet/sctp.h>
47#include <netinet/sctp_header.h>
48#include <netinet/sctp_asconf.h>
49#include <netinet/sctp_output.h>
50#include <netinet/sctp_timer.h>
51#include <netinet/sctp_bsd_addr.h>
Michael Tuexene5001952016-04-17 19:25:27 +020052#if defined(__FreeBSD__) && __FreeBSD_version >= 1000000
tuexendd729232011-11-01 23:04:43 +000053#include <netinet/sctp_dtrace_define.h>
tuexen63fc0bb2011-12-27 12:24:52 +000054#endif
t00fcxen1ce83bb2014-07-11 07:17:36 +000055#if defined(INET) || defined(INET6)
tuexen9784e9a2011-12-18 13:04:23 +000056#if !defined(__Userspace_os_Windows)
tuexendd729232011-11-01 23:04:43 +000057#include <netinet/udp.h>
tuexen6019b072011-12-15 18:38:03 +000058#endif
t00fcxen5ab37c82014-06-30 20:55:44 +000059#endif
tuexendd729232011-11-01 23:04:43 +000060#ifdef INET6
tuexen5154a002011-12-23 18:47:55 +000061#if defined(__Userspace__)
62#include "user_ip6_var.h"
63#else
tuexendd729232011-11-01 23:04:43 +000064#include <netinet6/ip6_var.h>
65#endif
tuexen5154a002011-12-23 18:47:55 +000066#endif
tuexendd729232011-11-01 23:04:43 +000067#if defined(__FreeBSD__)
68#include <sys/sched.h>
69#include <sys/smp.h>
tuexenc0bb6122012-01-15 14:21:21 +000070#include <sys/unistd.h>
tuexendd729232011-11-01 23:04:43 +000071#endif
tuexen5154a002011-12-23 18:47:55 +000072#if defined(__Userspace__)
73#include <user_socketvar.h>
t00fcxen37058da2015-03-16 21:59:21 +000074#if !defined(__Userspace_os_Windows)
75#include <netdb.h>
76#endif
tuexen5154a002011-12-23 18:47:55 +000077#endif
tuexendd729232011-11-01 23:04:43 +000078
79#if defined(__APPLE__)
80#define APPLE_FILE_NO 4
81#endif
82
83#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
84VNET_DEFINE(struct sctp_base_info, system_base_info);
85#else
86struct sctp_base_info system_base_info;
87#endif
88
tuexendd729232011-11-01 23:04:43 +000089/* FIX: we don't handle multiple link local scopes */
90/* "scopeless" replacement IN6_ARE_ADDR_EQUAL */
91#ifdef INET6
92int
93SCTP6_ARE_ADDR_EQUAL(struct sockaddr_in6 *a, struct sockaddr_in6 *b)
94{
95#ifdef SCTP_EMBEDDED_V6_SCOPE
tuexene3851592012-06-01 08:31:45 +000096#if defined(__APPLE__)
tuexendd729232011-11-01 23:04:43 +000097 struct in6_addr tmp_a, tmp_b;
98
99 tmp_a = a->sin6_addr;
tuexen9a218b12012-08-04 21:17:58 +0000100#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
tuexendd729232011-11-01 23:04:43 +0000101 if (in6_embedscope(&tmp_a, a, NULL, NULL) != 0) {
tuexen9a218b12012-08-04 21:17:58 +0000102#else
103 if (in6_embedscope(&tmp_a, a, NULL, NULL, NULL) != 0) {
tuexendd729232011-11-01 23:04:43 +0000104#endif
tuexen63fc0bb2011-12-27 12:24:52 +0000105 return (0);
tuexendd729232011-11-01 23:04:43 +0000106 }
107 tmp_b = b->sin6_addr;
tuexen9a218b12012-08-04 21:17:58 +0000108#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
tuexendd729232011-11-01 23:04:43 +0000109 if (in6_embedscope(&tmp_b, b, NULL, NULL) != 0) {
tuexen9a218b12012-08-04 21:17:58 +0000110#else
111 if (in6_embedscope(&tmp_b, b, NULL, NULL, NULL) != 0) {
tuexendd729232011-11-01 23:04:43 +0000112#endif
tuexen63fc0bb2011-12-27 12:24:52 +0000113 return (0);
tuexendd729232011-11-01 23:04:43 +0000114 }
115 return (IN6_ARE_ADDR_EQUAL(&tmp_a, &tmp_b));
116#elif defined(SCTP_KAME)
117 struct sockaddr_in6 tmp_a, tmp_b;
118
119 memcpy(&tmp_a, a, sizeof(struct sockaddr_in6));
120 if (sa6_embedscope(&tmp_a, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
tuexen63fc0bb2011-12-27 12:24:52 +0000121 return (0);
tuexendd729232011-11-01 23:04:43 +0000122 }
123 memcpy(&tmp_b, b, sizeof(struct sockaddr_in6));
124 if (sa6_embedscope(&tmp_b, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
tuexen63fc0bb2011-12-27 12:24:52 +0000125 return (0);
tuexendd729232011-11-01 23:04:43 +0000126 }
127 return (IN6_ARE_ADDR_EQUAL(&tmp_a.sin6_addr, &tmp_b.sin6_addr));
128#else
129 struct in6_addr tmp_a, tmp_b;
130
131 tmp_a = a->sin6_addr;
132 if (in6_embedscope(&tmp_a, a) != 0) {
tuexen63fc0bb2011-12-27 12:24:52 +0000133 return (0);
tuexendd729232011-11-01 23:04:43 +0000134 }
135 tmp_b = b->sin6_addr;
136 if (in6_embedscope(&tmp_b, b) != 0) {
tuexen63fc0bb2011-12-27 12:24:52 +0000137 return (0);
tuexendd729232011-11-01 23:04:43 +0000138 }
139 return (IN6_ARE_ADDR_EQUAL(&tmp_a, &tmp_b));
140#endif
141#else
tuexen5154a002011-12-23 18:47:55 +0000142 return (IN6_ARE_ADDR_EQUAL(&(a->sin6_addr), &(b->sin6_addr)));
tuexendd729232011-11-01 23:04:43 +0000143#endif /* SCTP_EMBEDDED_V6_SCOPE */
144}
145#endif
146
147void
148sctp_fill_pcbinfo(struct sctp_pcbinfo *spcb)
149{
150 /*
151 * We really don't need to lock this, but I will just because it
152 * does not hurt.
153 */
tuexendd729232011-11-01 23:04:43 +0000154 SCTP_INP_INFO_RLOCK();
155 spcb->ep_count = SCTP_BASE_INFO(ipi_count_ep);
156 spcb->asoc_count = SCTP_BASE_INFO(ipi_count_asoc);
157 spcb->laddr_count = SCTP_BASE_INFO(ipi_count_laddr);
158 spcb->raddr_count = SCTP_BASE_INFO(ipi_count_raddr);
159 spcb->chk_count = SCTP_BASE_INFO(ipi_count_chunk);
160 spcb->readq_count = SCTP_BASE_INFO(ipi_count_readq);
161 spcb->stream_oque = SCTP_BASE_INFO(ipi_count_strmoq);
162 spcb->free_chunks = SCTP_BASE_INFO(ipi_free_chunks);
tuexendd729232011-11-01 23:04:43 +0000163 SCTP_INP_INFO_RUNLOCK();
164}
165
t00fcxend0ad16b2013-02-09 18:34:24 +0000166/*-
tuexendd729232011-11-01 23:04:43 +0000167 * Addresses are added to VRF's (Virtual Router's). For BSD we
168 * have only the default VRF 0. We maintain a hash list of
169 * VRF's. Each VRF has its own list of sctp_ifn's. Each of
170 * these has a list of addresses. When we add a new address
171 * to a VRF we lookup the ifn/ifn_index, if the ifn does
172 * not exist we create it and add it to the list of IFN's
173 * within the VRF. Once we have the sctp_ifn, we add the
174 * address to the list. So we look something like:
175 *
176 * hash-vrf-table
177 * vrf-> ifn-> ifn -> ifn
178 * vrf |
179 * ... +--ifa-> ifa -> ifa
180 * vrf
181 *
182 * We keep these separate lists since the SCTP subsystem will
183 * point to these from its source address selection nets structure.
184 * When an address is deleted it does not happen right away on
185 * the SCTP side, it gets scheduled. What we do when a
186 * delete happens is immediately remove the address from
187 * the master list and decrement the refcount. As our
188 * addip iterator works through and frees the src address
189 * selection pointing to the sctp_ifa, eventually the refcount
190 * will reach 0 and we will delete it. Note that it is assumed
191 * that any locking on system level ifn/ifa is done at the
192 * caller of these functions and these routines will only
193 * lock the SCTP structures as they add or delete things.
194 *
195 * Other notes on VRF concepts.
196 * - An endpoint can be in multiple VRF's
197 * - An association lives within a VRF and only one VRF.
198 * - Any incoming packet we can deduce the VRF for by
199 * looking at the mbuf/pak inbound (for BSD its VRF=0 :D)
200 * - Any downward send call or connect call must supply the
201 * VRF via ancillary data or via some sort of set default
202 * VRF socket option call (again for BSD no brainer since
203 * the VRF is always 0).
204 * - An endpoint may add multiple VRF's to it.
205 * - Listening sockets can accept associations in any
206 * of the VRF's they are in but the assoc will end up
207 * in only one VRF (gotten from the packet or connect/send).
208 *
209 */
210
211struct sctp_vrf *
212sctp_allocate_vrf(int vrf_id)
213{
tuexen63fc0bb2011-12-27 12:24:52 +0000214 struct sctp_vrf *vrf = NULL;
tuexendd729232011-11-01 23:04:43 +0000215 struct sctp_vrflist *bucket;
216
217 /* First allocate the VRF structure */
218 vrf = sctp_find_vrf(vrf_id);
219 if (vrf) {
220 /* Already allocated */
221 return (vrf);
222 }
223 SCTP_MALLOC(vrf, struct sctp_vrf *, sizeof(struct sctp_vrf),
224 SCTP_M_VRF);
t00fcxen8dd95b82014-07-11 20:41:28 +0000225 if (vrf == NULL) {
226 /* No memory */
tuexendd729232011-11-01 23:04:43 +0000227#ifdef INVARIANTS
228 panic("No memory for VRF:%d", vrf_id);
229#endif
230 return (NULL);
231 }
232 /* setup the VRF */
233 memset(vrf, 0, sizeof(struct sctp_vrf));
234 vrf->vrf_id = vrf_id;
235 LIST_INIT(&vrf->ifnlist);
236 vrf->total_ifa_count = 0;
237 vrf->refcount = 0;
238 /* now also setup table ids */
239 SCTP_INIT_VRF_TABLEID(vrf);
240 /* Init the HASH of addresses */
241 vrf->vrf_addr_hash = SCTP_HASH_INIT(SCTP_VRF_ADDR_HASH_SIZE,
242 &vrf->vrf_addr_hashmark);
243 if (vrf->vrf_addr_hash == NULL) {
t00fcxen8dd95b82014-07-11 20:41:28 +0000244 /* No memory */
tuexendd729232011-11-01 23:04:43 +0000245#ifdef INVARIANTS
246 panic("No memory for VRF:%d", vrf_id);
247#endif
248 SCTP_FREE(vrf, SCTP_M_VRF);
249 return (NULL);
250 }
251
252 /* Add it to the hash table */
253 bucket = &SCTP_BASE_INFO(sctp_vrfhash)[(vrf_id & SCTP_BASE_INFO(hashvrfmark))];
254 LIST_INSERT_HEAD(bucket, vrf, next_vrf);
255 atomic_add_int(&SCTP_BASE_INFO(ipi_count_vrfs), 1);
256 return (vrf);
257}
258
259
260struct sctp_ifn *
261sctp_find_ifn(void *ifn, uint32_t ifn_index)
262{
263 struct sctp_ifn *sctp_ifnp;
264 struct sctp_ifnlist *hash_ifn_head;
265
266 /* We assume the lock is held for the addresses
267 * if that's wrong problems could occur :-)
268 */
269 hash_ifn_head = &SCTP_BASE_INFO(vrf_ifn_hash)[(ifn_index & SCTP_BASE_INFO(vrf_ifn_hashmark))];
270 LIST_FOREACH(sctp_ifnp, hash_ifn_head, next_bucket) {
271 if (sctp_ifnp->ifn_index == ifn_index) {
tuexen63fc0bb2011-12-27 12:24:52 +0000272 return (sctp_ifnp);
tuexendd729232011-11-01 23:04:43 +0000273 }
274 if (sctp_ifnp->ifn_p && ifn && (sctp_ifnp->ifn_p == ifn)) {
tuexen63fc0bb2011-12-27 12:24:52 +0000275 return (sctp_ifnp);
tuexendd729232011-11-01 23:04:43 +0000276 }
277 }
tuexen63fc0bb2011-12-27 12:24:52 +0000278 return (NULL);
tuexendd729232011-11-01 23:04:43 +0000279}
280
281
tuexendd729232011-11-01 23:04:43 +0000282struct sctp_vrf *
283sctp_find_vrf(uint32_t vrf_id)
284{
285 struct sctp_vrflist *bucket;
286 struct sctp_vrf *liste;
t00fcxend0ad16b2013-02-09 18:34:24 +0000287
tuexendd729232011-11-01 23:04:43 +0000288 bucket = &SCTP_BASE_INFO(sctp_vrfhash)[(vrf_id & SCTP_BASE_INFO(hashvrfmark))];
289 LIST_FOREACH(liste, bucket, next_vrf) {
290 if (vrf_id == liste->vrf_id) {
tuexen63fc0bb2011-12-27 12:24:52 +0000291 return (liste);
tuexendd729232011-11-01 23:04:43 +0000292 }
293 }
294 return (NULL);
295}
296
t00fcxend0ad16b2013-02-09 18:34:24 +0000297
tuexendd729232011-11-01 23:04:43 +0000298void
299sctp_free_vrf(struct sctp_vrf *vrf)
300{
301 if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&vrf->refcount)) {
302 if (vrf->vrf_addr_hash) {
303 SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark);
304 vrf->vrf_addr_hash = NULL;
305 }
306 /* We zero'd the count */
307 LIST_REMOVE(vrf, next_vrf);
308 SCTP_FREE(vrf, SCTP_M_VRF);
309 atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_vrfs), 1);
310 }
311}
312
t00fcxend0ad16b2013-02-09 18:34:24 +0000313
tuexendd729232011-11-01 23:04:43 +0000314void
315sctp_free_ifn(struct sctp_ifn *sctp_ifnp)
316{
317 if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&sctp_ifnp->refcount)) {
318 /* We zero'd the count */
319 if (sctp_ifnp->vrf) {
320 sctp_free_vrf(sctp_ifnp->vrf);
321 }
322 SCTP_FREE(sctp_ifnp, SCTP_M_IFN);
323 atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ifns), 1);
324 }
325}
326
t00fcxend0ad16b2013-02-09 18:34:24 +0000327
tuexendd729232011-11-01 23:04:43 +0000328void
329sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu)
330{
331 struct sctp_ifn *sctp_ifnp;
332
333 sctp_ifnp = sctp_find_ifn((void *)NULL, ifn_index);
334 if (sctp_ifnp != NULL) {
335 sctp_ifnp->ifn_mtu = mtu;
336 }
337}
338
339
340void
341sctp_free_ifa(struct sctp_ifa *sctp_ifap)
342{
343 if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&sctp_ifap->refcount)) {
344 /* We zero'd the count */
345 if (sctp_ifap->ifn_p) {
346 sctp_free_ifn(sctp_ifap->ifn_p);
347 }
348 SCTP_FREE(sctp_ifap, SCTP_M_IFA);
349 atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ifas), 1);
350 }
351}
352
t00fcxend0ad16b2013-02-09 18:34:24 +0000353
tuexendd729232011-11-01 23:04:43 +0000354static void
355sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock)
356{
357 struct sctp_ifn *found;
358
359 found = sctp_find_ifn(sctp_ifnp->ifn_p, sctp_ifnp->ifn_index);
360 if (found == NULL) {
361 /* Not in the list.. sorry */
362 return;
363 }
364 if (hold_addr_lock == 0)
365 SCTP_IPI_ADDR_WLOCK();
366 LIST_REMOVE(sctp_ifnp, next_bucket);
367 LIST_REMOVE(sctp_ifnp, next_ifn);
368 SCTP_DEREGISTER_INTERFACE(sctp_ifnp->ifn_index,
369 sctp_ifnp->registered_af);
370 if (hold_addr_lock == 0)
371 SCTP_IPI_ADDR_WUNLOCK();
372 /* Take away the reference, and possibly free it */
373 sctp_free_ifn(sctp_ifnp);
374}
375
t00fcxend0ad16b2013-02-09 18:34:24 +0000376
tuexendd729232011-11-01 23:04:43 +0000377void
378sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr,
379 const char *if_name, uint32_t ifn_index)
380{
381 struct sctp_vrf *vrf;
t00fcxend0ad16b2013-02-09 18:34:24 +0000382 struct sctp_ifa *sctp_ifap;
383
tuexendd729232011-11-01 23:04:43 +0000384 SCTP_IPI_ADDR_RLOCK();
385 vrf = sctp_find_vrf(vrf_id);
386 if (vrf == NULL) {
387 SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id);
388 goto out;
389
390 }
391 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
392 if (sctp_ifap == NULL) {
393 SCTPDBG(SCTP_DEBUG_PCB4, "Can't find sctp_ifap for address\n");
394 goto out;
tuexen0e813942011-11-18 09:18:32 +0000395 }
tuexendd729232011-11-01 23:04:43 +0000396 if (sctp_ifap->ifn_p == NULL) {
397 SCTPDBG(SCTP_DEBUG_PCB4, "IFA has no IFN - can't mark unuseable\n");
398 goto out;
399 }
400 if (if_name) {
tuexen0e813942011-11-18 09:18:32 +0000401 if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) != 0) {
tuexendd729232011-11-01 23:04:43 +0000402 SCTPDBG(SCTP_DEBUG_PCB4, "IFN %s of IFA not the same as %s\n",
tuexen0e813942011-11-18 09:18:32 +0000403 sctp_ifap->ifn_p->ifn_name, if_name);
tuexendd729232011-11-01 23:04:43 +0000404 goto out;
405 }
406 } else {
407 if (sctp_ifap->ifn_p->ifn_index != ifn_index) {
408 SCTPDBG(SCTP_DEBUG_PCB4, "IFA owned by ifn_index:%d down command for ifn_index:%d - ignored\n",
409 sctp_ifap->ifn_p->ifn_index, ifn_index);
410 goto out;
411 }
412 }
tuexen0e813942011-11-18 09:18:32 +0000413
tuexendd729232011-11-01 23:04:43 +0000414 sctp_ifap->localifa_flags &= (~SCTP_ADDR_VALID);
415 sctp_ifap->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE;
416 out:
417 SCTP_IPI_ADDR_RUNLOCK();
418}
419
t00fcxend0ad16b2013-02-09 18:34:24 +0000420
tuexendd729232011-11-01 23:04:43 +0000421void
422sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr,
423 const char *if_name, uint32_t ifn_index)
424{
425 struct sctp_vrf *vrf;
t00fcxend0ad16b2013-02-09 18:34:24 +0000426 struct sctp_ifa *sctp_ifap;
427
tuexendd729232011-11-01 23:04:43 +0000428 SCTP_IPI_ADDR_RLOCK();
429 vrf = sctp_find_vrf(vrf_id);
430 if (vrf == NULL) {
431 SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id);
432 goto out;
433
434 }
435 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
436 if (sctp_ifap == NULL) {
437 SCTPDBG(SCTP_DEBUG_PCB4, "Can't find sctp_ifap for address\n");
438 goto out;
tuexen0e813942011-11-18 09:18:32 +0000439 }
tuexendd729232011-11-01 23:04:43 +0000440 if (sctp_ifap->ifn_p == NULL) {
441 SCTPDBG(SCTP_DEBUG_PCB4, "IFA has no IFN - can't mark unuseable\n");
442 goto out;
443 }
444 if (if_name) {
tuexen0e813942011-11-18 09:18:32 +0000445 if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) != 0) {
tuexendd729232011-11-01 23:04:43 +0000446 SCTPDBG(SCTP_DEBUG_PCB4, "IFN %s of IFA not the same as %s\n",
tuexen0e813942011-11-18 09:18:32 +0000447 sctp_ifap->ifn_p->ifn_name, if_name);
tuexendd729232011-11-01 23:04:43 +0000448 goto out;
449 }
450 } else {
451 if (sctp_ifap->ifn_p->ifn_index != ifn_index) {
452 SCTPDBG(SCTP_DEBUG_PCB4, "IFA owned by ifn_index:%d down command for ifn_index:%d - ignored\n",
453 sctp_ifap->ifn_p->ifn_index, ifn_index);
454 goto out;
455 }
456 }
457
458 sctp_ifap->localifa_flags &= (~SCTP_ADDR_IFA_UNUSEABLE);
459 sctp_ifap->localifa_flags |= SCTP_ADDR_VALID;
460 out:
461 SCTP_IPI_ADDR_RUNLOCK();
462}
463
t00fcxend0ad16b2013-02-09 18:34:24 +0000464
tuexendd729232011-11-01 23:04:43 +0000465/*-
466 * Add an ifa to an ifn.
467 * Register the interface as necessary.
468 * NOTE: ADDR write lock MUST be held.
469 */
470static void
471sctp_add_ifa_to_ifn(struct sctp_ifn *sctp_ifnp, struct sctp_ifa *sctp_ifap)
472{
473 int ifa_af;
474
475 LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa);
476 sctp_ifap->ifn_p = sctp_ifnp;
477 atomic_add_int(&sctp_ifap->ifn_p->refcount, 1);
478 /* update address counts */
479 sctp_ifnp->ifa_count++;
480 ifa_af = sctp_ifap->address.sa.sa_family;
481 switch (ifa_af) {
482#ifdef INET
483 case AF_INET:
484 sctp_ifnp->num_v4++;
485 break;
486#endif
487#ifdef INET6
488 case AF_INET6:
489 sctp_ifnp->num_v6++;
490 break;
491#endif
492 default:
493 break;
494 }
495 if (sctp_ifnp->ifa_count == 1) {
496 /* register the new interface */
497 SCTP_REGISTER_INTERFACE(sctp_ifnp->ifn_index, ifa_af);
498 sctp_ifnp->registered_af = ifa_af;
499 }
500}
501
t00fcxend0ad16b2013-02-09 18:34:24 +0000502
tuexendd729232011-11-01 23:04:43 +0000503/*-
504 * Remove an ifa from its ifn.
505 * If no more addresses exist, remove the ifn too. Otherwise, re-register
506 * the interface based on the remaining address families left.
507 * NOTE: ADDR write lock MUST be held.
508 */
509static void
510sctp_remove_ifa_from_ifn(struct sctp_ifa *sctp_ifap)
511{
tuexendd729232011-11-01 23:04:43 +0000512 LIST_REMOVE(sctp_ifap, next_ifa);
513 if (sctp_ifap->ifn_p) {
514 /* update address counts */
515 sctp_ifap->ifn_p->ifa_count--;
516 switch (sctp_ifap->address.sa.sa_family) {
517#ifdef INET
518 case AF_INET:
519 sctp_ifap->ifn_p->num_v4--;
520 break;
521#endif
522#ifdef INET6
523 case AF_INET6:
524 sctp_ifap->ifn_p->num_v6--;
525 break;
526#endif
527 default:
528 break;
529 }
530
tuexendd729232011-11-01 23:04:43 +0000531 if (LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) {
532 /* remove the ifn, possibly freeing it */
533 sctp_delete_ifn(sctp_ifap->ifn_p, SCTP_ADDR_LOCKED);
534 } else {
535 /* re-register address family type, if needed */
536 if ((sctp_ifap->ifn_p->num_v6 == 0) &&
537 (sctp_ifap->ifn_p->registered_af == AF_INET6)) {
tuexen63fc0bb2011-12-27 12:24:52 +0000538 SCTP_DEREGISTER_INTERFACE(sctp_ifap->ifn_p->ifn_index, AF_INET6);
539 SCTP_REGISTER_INTERFACE(sctp_ifap->ifn_p->ifn_index, AF_INET);
tuexendd729232011-11-01 23:04:43 +0000540 sctp_ifap->ifn_p->registered_af = AF_INET;
541 } else if ((sctp_ifap->ifn_p->num_v4 == 0) &&
542 (sctp_ifap->ifn_p->registered_af == AF_INET)) {
tuexen63fc0bb2011-12-27 12:24:52 +0000543 SCTP_DEREGISTER_INTERFACE(sctp_ifap->ifn_p->ifn_index, AF_INET);
544 SCTP_REGISTER_INTERFACE(sctp_ifap->ifn_p->ifn_index, AF_INET6);
tuexendd729232011-11-01 23:04:43 +0000545 sctp_ifap->ifn_p->registered_af = AF_INET6;
546 }
547 /* free the ifn refcount */
548 sctp_free_ifn(sctp_ifap->ifn_p);
549 }
550 sctp_ifap->ifn_p = NULL;
551 }
552}
553
t00fcxend0ad16b2013-02-09 18:34:24 +0000554
tuexendd729232011-11-01 23:04:43 +0000555struct sctp_ifa *
556sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
557 uint32_t ifn_type, const char *if_name, void *ifa,
558 struct sockaddr *addr, uint32_t ifa_flags,
559 int dynamic_add)
560{
561 struct sctp_vrf *vrf;
562 struct sctp_ifn *sctp_ifnp = NULL;
563 struct sctp_ifa *sctp_ifap = NULL;
564 struct sctp_ifalist *hash_addr_head;
565 struct sctp_ifnlist *hash_ifn_head;
566 uint32_t hash_of_addr;
567 int new_ifn_af = 0;
568
569#ifdef SCTP_DEBUG
570 SCTPDBG(SCTP_DEBUG_PCB4, "vrf_id 0x%x: adding address: ", vrf_id);
571 SCTPDBG_ADDR(SCTP_DEBUG_PCB4, addr);
572#endif
573 SCTP_IPI_ADDR_WLOCK();
574 sctp_ifnp = sctp_find_ifn(ifn, ifn_index);
575 if (sctp_ifnp) {
576 vrf = sctp_ifnp->vrf;
577 } else {
578 vrf = sctp_find_vrf(vrf_id);
579 if (vrf == NULL) {
580 vrf = sctp_allocate_vrf(vrf_id);
581 if (vrf == NULL) {
582 SCTP_IPI_ADDR_WUNLOCK();
583 return (NULL);
584 }
585 }
586 }
587 if (sctp_ifnp == NULL) {
588 /* build one and add it, can't hold lock
589 * until after malloc done though.
590 */
591 SCTP_IPI_ADDR_WUNLOCK();
592 SCTP_MALLOC(sctp_ifnp, struct sctp_ifn *,
593 sizeof(struct sctp_ifn), SCTP_M_IFN);
594 if (sctp_ifnp == NULL) {
595#ifdef INVARIANTS
596 panic("No memory for IFN");
597#endif
598 return (NULL);
599 }
600 memset(sctp_ifnp, 0, sizeof(struct sctp_ifn));
601 sctp_ifnp->ifn_index = ifn_index;
602 sctp_ifnp->ifn_p = ifn;
603 sctp_ifnp->ifn_type = ifn_type;
604 sctp_ifnp->refcount = 0;
605 sctp_ifnp->vrf = vrf;
606 atomic_add_int(&vrf->refcount, 1);
607 sctp_ifnp->ifn_mtu = SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index, addr->sa_family);
608 if (if_name != NULL) {
tuexenb740ef62011-11-13 11:58:06 +0000609 snprintf(sctp_ifnp->ifn_name, SCTP_IFNAMSIZ, "%s", if_name);
tuexendd729232011-11-01 23:04:43 +0000610 } else {
tuexenb740ef62011-11-13 11:58:06 +0000611 snprintf(sctp_ifnp->ifn_name, SCTP_IFNAMSIZ, "%s", "unknown");
tuexendd729232011-11-01 23:04:43 +0000612 }
613 hash_ifn_head = &SCTP_BASE_INFO(vrf_ifn_hash)[(ifn_index & SCTP_BASE_INFO(vrf_ifn_hashmark))];
614 LIST_INIT(&sctp_ifnp->ifalist);
615 SCTP_IPI_ADDR_WLOCK();
616 LIST_INSERT_HEAD(hash_ifn_head, sctp_ifnp, next_bucket);
617 LIST_INSERT_HEAD(&vrf->ifnlist, sctp_ifnp, next_ifn);
618 atomic_add_int(&SCTP_BASE_INFO(ipi_count_ifns), 1);
619 new_ifn_af = 1;
620 }
621 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
622 if (sctp_ifap) {
623 /* Hmm, it already exists? */
624 if ((sctp_ifap->ifn_p) &&
625 (sctp_ifap->ifn_p->ifn_index == ifn_index)) {
626 SCTPDBG(SCTP_DEBUG_PCB4, "Using existing ifn %s (0x%x) for ifa %p\n",
627 sctp_ifap->ifn_p->ifn_name, ifn_index,
t00fcxen8fca7ff2012-09-05 18:58:42 +0000628 (void *)sctp_ifap);
tuexendd729232011-11-01 23:04:43 +0000629 if (new_ifn_af) {
630 /* Remove the created one that we don't want */
631 sctp_delete_ifn(sctp_ifnp, SCTP_ADDR_LOCKED);
632 }
633 if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) {
634 /* easy to solve, just switch back to active */
635 SCTPDBG(SCTP_DEBUG_PCB4, "Clearing deleted ifa flag\n");
636 sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
637 sctp_ifap->ifn_p = sctp_ifnp;
638 atomic_add_int(&sctp_ifap->ifn_p->refcount, 1);
639 }
640 exit_stage_left:
641 SCTP_IPI_ADDR_WUNLOCK();
642 return (sctp_ifap);
643 } else {
644 if (sctp_ifap->ifn_p) {
645 /*
646 * The last IFN gets the address, remove the
647 * old one
648 */
649 SCTPDBG(SCTP_DEBUG_PCB4, "Moving ifa %p from %s (0x%x) to %s (0x%x)\n",
t00fcxen8fca7ff2012-09-05 18:58:42 +0000650 (void *)sctp_ifap, sctp_ifap->ifn_p->ifn_name,
tuexendd729232011-11-01 23:04:43 +0000651 sctp_ifap->ifn_p->ifn_index, if_name,
652 ifn_index);
653 /* remove the address from the old ifn */
654 sctp_remove_ifa_from_ifn(sctp_ifap);
655 /* move the address over to the new ifn */
656 sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap);
t00fcxen8dd95b82014-07-11 20:41:28 +0000657 goto exit_stage_left;
tuexendd729232011-11-01 23:04:43 +0000658 } else {
659 /* repair ifnp which was NULL ? */
660 sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
661 SCTPDBG(SCTP_DEBUG_PCB4, "Repairing ifn %p for ifa %p\n",
t00fcxen8fca7ff2012-09-05 18:58:42 +0000662 (void *)sctp_ifnp, (void *)sctp_ifap);
tuexendd729232011-11-01 23:04:43 +0000663 sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap);
664 }
665 goto exit_stage_left;
666 }
667 }
668 SCTP_IPI_ADDR_WUNLOCK();
669 SCTP_MALLOC(sctp_ifap, struct sctp_ifa *, sizeof(struct sctp_ifa), SCTP_M_IFA);
670 if (sctp_ifap == NULL) {
671#ifdef INVARIANTS
672 panic("No memory for IFA");
673#endif
674 return (NULL);
675 }
676 memset(sctp_ifap, 0, sizeof(struct sctp_ifa));
677 sctp_ifap->ifn_p = sctp_ifnp;
678 atomic_add_int(&sctp_ifnp->refcount, 1);
679 sctp_ifap->vrf_id = vrf_id;
680 sctp_ifap->ifa = ifa;
t00fcxena8a26f62012-09-12 19:24:54 +0000681#ifdef HAVE_SA_LEN
tuexendd729232011-11-01 23:04:43 +0000682 memcpy(&sctp_ifap->address, addr, addr->sa_len);
683#else
t00fcxend0ad16b2013-02-09 18:34:24 +0000684 switch (addr->sa_family) {
685#ifdef INET
686 case AF_INET:
tuexendd729232011-11-01 23:04:43 +0000687 memcpy(&sctp_ifap->address, addr, sizeof(struct sockaddr_in));
t00fcxend0ad16b2013-02-09 18:34:24 +0000688 break;
689#endif
690#ifdef INET6
691 case AF_INET6:
tuexendd729232011-11-01 23:04:43 +0000692 memcpy(&sctp_ifap->address, addr, sizeof(struct sockaddr_in6));
t00fcxend0ad16b2013-02-09 18:34:24 +0000693 break;
694#endif
695#if defined(__Userspace__)
696 case AF_CONN:
t00fcxen6df84312013-02-12 08:58:40 +0000697 memcpy(&sctp_ifap->address, addr, sizeof(struct sockaddr_conn));
t00fcxend0ad16b2013-02-09 18:34:24 +0000698 break;
699#endif
700 default:
701 /* TSNH */
702 break;
tuexendd729232011-11-01 23:04:43 +0000703 }
704#endif
705 sctp_ifap->localifa_flags = SCTP_ADDR_VALID | SCTP_ADDR_DEFER_USE;
706 sctp_ifap->flags = ifa_flags;
707 /* Set scope */
708 switch (sctp_ifap->address.sa.sa_family) {
709#ifdef INET
710 case AF_INET:
711 {
712 struct sockaddr_in *sin;
t00fcxend0ad16b2013-02-09 18:34:24 +0000713
t00fcxen05f07c02014-09-07 10:15:26 +0000714 sin = &sctp_ifap->address.sin;
tuexendd729232011-11-01 23:04:43 +0000715 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
716 (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) {
717 sctp_ifap->src_is_loop = 1;
718 }
719 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
720 sctp_ifap->src_is_priv = 1;
721 }
722 sctp_ifnp->num_v4++;
723 if (new_ifn_af)
724 new_ifn_af = AF_INET;
725 break;
726 }
727#endif
728#ifdef INET6
729 case AF_INET6:
730 {
731 /* ok to use deprecated addresses? */
732 struct sockaddr_in6 *sin6;
t00fcxend0ad16b2013-02-09 18:34:24 +0000733
t00fcxen05f07c02014-09-07 10:15:26 +0000734 sin6 = &sctp_ifap->address.sin6;
tuexendd729232011-11-01 23:04:43 +0000735 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
736 (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) {
737 sctp_ifap->src_is_loop = 1;
738 }
739 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
740 sctp_ifap->src_is_priv = 1;
741 }
742 sctp_ifnp->num_v6++;
743 if (new_ifn_af)
744 new_ifn_af = AF_INET6;
745 break;
746 }
747#endif
t00fcxend0ad16b2013-02-09 18:34:24 +0000748#if defined(__Userspace__)
749 case AF_CONN:
750 if (new_ifn_af)
751 new_ifn_af = AF_CONN;
752 break;
753#endif
tuexendd729232011-11-01 23:04:43 +0000754 default:
755 new_ifn_af = 0;
756 break;
757 }
758 hash_of_addr = sctp_get_ifa_hash_val(&sctp_ifap->address.sa);
759
760 if ((sctp_ifap->src_is_priv == 0) &&
761 (sctp_ifap->src_is_loop == 0)) {
762 sctp_ifap->src_is_glob = 1;
763 }
764 SCTP_IPI_ADDR_WLOCK();
765 hash_addr_head = &vrf->vrf_addr_hash[(hash_of_addr & vrf->vrf_addr_hashmark)];
766 LIST_INSERT_HEAD(hash_addr_head, sctp_ifap, next_bucket);
767 sctp_ifap->refcount = 1;
768 LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa);
769 sctp_ifnp->ifa_count++;
770 vrf->total_ifa_count++;
771 atomic_add_int(&SCTP_BASE_INFO(ipi_count_ifas), 1);
772 if (new_ifn_af) {
773 SCTP_REGISTER_INTERFACE(ifn_index, new_ifn_af);
774 sctp_ifnp->registered_af = new_ifn_af;
775 }
776 SCTP_IPI_ADDR_WUNLOCK();
777 if (dynamic_add) {
778 /* Bump up the refcount so that when the timer
779 * completes it will drop back down.
780 */
781 struct sctp_laddr *wi;
782
783 atomic_add_int(&sctp_ifap->refcount, 1);
784 wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
785 if (wi == NULL) {
786 /*
787 * Gak, what can we do? We have lost an address
788 * change can you say HOSED?
789 */
790 SCTPDBG(SCTP_DEBUG_PCB4, "Lost an address change?\n");
791 /* Opps, must decrement the count */
792 sctp_del_addr_from_vrf(vrf_id, addr, ifn_index,
793 if_name);
794 return (NULL);
795 }
796 SCTP_INCR_LADDR_COUNT();
797 bzero(wi, sizeof(*wi));
798 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time);
799 wi->ifa = sctp_ifap;
800 wi->action = SCTP_ADD_IP_ADDRESS;
tuexen09631162012-04-18 11:23:02 +0000801
tuexendd729232011-11-01 23:04:43 +0000802 SCTP_WQ_ADDR_LOCK();
803 LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr);
804 SCTP_WQ_ADDR_UNLOCK();
805
806 sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
807 (struct sctp_inpcb *)NULL,
808 (struct sctp_tcb *)NULL,
809 (struct sctp_nets *)NULL);
810 } else {
811 /* it's ready for use */
812 sctp_ifap->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
813 }
814 return (sctp_ifap);
815}
816
817void
818sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr,
819 uint32_t ifn_index, const char *if_name)
820{
821 struct sctp_vrf *vrf;
822 struct sctp_ifa *sctp_ifap = NULL;
823
824 SCTP_IPI_ADDR_WLOCK();
825 vrf = sctp_find_vrf(vrf_id);
826 if (vrf == NULL) {
827 SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id);
828 goto out_now;
829 }
830
831#ifdef SCTP_DEBUG
832 SCTPDBG(SCTP_DEBUG_PCB4, "vrf_id 0x%x: deleting address:", vrf_id);
833 SCTPDBG_ADDR(SCTP_DEBUG_PCB4, addr);
834#endif
835 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
836 if (sctp_ifap) {
837 /* Validate the delete */
838 if (sctp_ifap->ifn_p) {
tuexenb740ef62011-11-13 11:58:06 +0000839 int valid = 0;
tuexendd729232011-11-01 23:04:43 +0000840 /*-
841 * The name has priority over the ifn_index
842 * if its given. We do this especially for
843 * panda who might recycle indexes fast.
844 */
845 if (if_name) {
tuexenb740ef62011-11-13 11:58:06 +0000846 if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) == 0) {
847 /* They match its a correct delete */
848 valid = 1;
tuexendd729232011-11-01 23:04:43 +0000849 }
850 }
851 if (!valid) {
852 /* last ditch check ifn_index */
853 if (ifn_index == sctp_ifap->ifn_p->ifn_index) {
854 valid = 1;
855 }
856 }
857 if (!valid) {
858 SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d ifname:%s does not match addresses\n",
859 ifn_index, ((if_name == NULL) ? "NULL" : if_name));
860 SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d ifname:%s - ignoring delete\n",
861 sctp_ifap->ifn_p->ifn_index, sctp_ifap->ifn_p->ifn_name);
862 SCTP_IPI_ADDR_WUNLOCK();
863 return;
864 }
865 }
t00fcxen8fca7ff2012-09-05 18:58:42 +0000866 SCTPDBG(SCTP_DEBUG_PCB4, "Deleting ifa %p\n", (void *)sctp_ifap);
tuexendd729232011-11-01 23:04:43 +0000867 sctp_ifap->localifa_flags &= SCTP_ADDR_VALID;
t00fcxen97887d62014-03-29 21:31:12 +0000868 /*
869 * We don't set the flag. This means that the structure will
870 * hang around in EP's that have bound specific to it until
871 * they close. This gives us TCP like behavior if someone
872 * removes an address (or for that matter adds it right back).
873 */
874 /* sctp_ifap->localifa_flags |= SCTP_BEING_DELETED; */
tuexendd729232011-11-01 23:04:43 +0000875 vrf->total_ifa_count--;
876 LIST_REMOVE(sctp_ifap, next_bucket);
877 sctp_remove_ifa_from_ifn(sctp_ifap);
878 }
879#ifdef SCTP_DEBUG
880 else {
881 SCTPDBG(SCTP_DEBUG_PCB4, "Del Addr-ifn:%d Could not find address:",
882 ifn_index);
883 SCTPDBG_ADDR(SCTP_DEBUG_PCB1, addr);
884 }
885#endif
886
887 out_now:
888 SCTP_IPI_ADDR_WUNLOCK();
889 if (sctp_ifap) {
890 struct sctp_laddr *wi;
891
892 wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
893 if (wi == NULL) {
894 /*
895 * Gak, what can we do? We have lost an address
896 * change can you say HOSED?
897 */
898 SCTPDBG(SCTP_DEBUG_PCB4, "Lost an address change?\n");
899
900 /* Oops, must decrement the count */
901 sctp_free_ifa(sctp_ifap);
902 return;
903 }
904 SCTP_INCR_LADDR_COUNT();
905 bzero(wi, sizeof(*wi));
906 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time);
907 wi->ifa = sctp_ifap;
908 wi->action = SCTP_DEL_IP_ADDRESS;
909 SCTP_WQ_ADDR_LOCK();
910 /*
911 * Should this really be a tailq? As it is we will process the
912 * newest first :-0
913 */
914 LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr);
915 SCTP_WQ_ADDR_UNLOCK();
916
917 sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
918 (struct sctp_inpcb *)NULL,
919 (struct sctp_tcb *)NULL,
920 (struct sctp_nets *)NULL);
921 }
922 return;
923}
924
925
t00fcxen60d0dea2013-02-10 20:04:03 +0000926static int
927sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
928{
t00fcxenaff14b62013-11-02 18:02:02 +0000929 int loopback_scope;
930#if defined(INET)
931 int ipv4_local_scope, ipv4_addr_legal;
932#endif
933#if defined(INET6)
934 int local_scope, site_scope, ipv6_addr_legal;
935#endif
t00fcxen60d0dea2013-02-10 20:04:03 +0000936#if defined(__Userspace__)
937 int conn_addr_legal;
938#endif
939 struct sctp_vrf *vrf;
940 struct sctp_ifn *sctp_ifn;
941 struct sctp_ifa *sctp_ifa;
942
943 loopback_scope = stcb->asoc.scope.loopback_scope;
t00fcxenaff14b62013-11-02 18:02:02 +0000944#if defined(INET)
t00fcxen60d0dea2013-02-10 20:04:03 +0000945 ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
t00fcxenaff14b62013-11-02 18:02:02 +0000946 ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
947#endif
948#if defined(INET6)
t00fcxen60d0dea2013-02-10 20:04:03 +0000949 local_scope = stcb->asoc.scope.local_scope;
950 site_scope = stcb->asoc.scope.site_scope;
t00fcxen60d0dea2013-02-10 20:04:03 +0000951 ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
t00fcxenaff14b62013-11-02 18:02:02 +0000952#endif
t00fcxen60d0dea2013-02-10 20:04:03 +0000953#if defined(__Userspace__)
954 conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
955#endif
956
957 SCTP_IPI_ADDR_RLOCK();
958 vrf = sctp_find_vrf(stcb->asoc.vrf_id);
959 if (vrf == NULL) {
960 /* no vrf, no addresses */
961 SCTP_IPI_ADDR_RUNLOCK();
962 return (0);
963 }
964
965 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
966 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
967 if ((loopback_scope == 0) &&
968 SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
969 continue;
970 }
971 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
972 if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
973 (!sctp_is_addr_pending(stcb, sctp_ifa))) {
974 /* We allow pending addresses, where we
975 * have sent an asconf-add to be considered
976 * valid.
977 */
978 continue;
979 }
t00fcxenba8aa202013-11-16 15:37:17 +0000980 if (sctp_ifa->address.sa.sa_family != to->sa_family) {
981 continue;
982 }
t00fcxen60d0dea2013-02-10 20:04:03 +0000983 switch (sctp_ifa->address.sa.sa_family) {
984#ifdef INET
985 case AF_INET:
986 if (ipv4_addr_legal) {
987 struct sockaddr_in *sin, *rsin;
988
989 sin = &sctp_ifa->address.sin;
990 rsin = (struct sockaddr_in *)to;
991 if ((ipv4_local_scope == 0) &&
992 IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
993 continue;
994 }
t00fcxen326aa4b2014-06-20 13:42:13 +0000995#if defined(__FreeBSD__)
996 if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
997 &sin->sin_addr) != 0) {
998 continue;
999 }
1000#endif
t00fcxen60d0dea2013-02-10 20:04:03 +00001001 if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) {
1002 SCTP_IPI_ADDR_RUNLOCK();
1003 return (1);
1004 }
1005 }
1006 break;
1007#endif
1008#ifdef INET6
1009 case AF_INET6:
1010 if (ipv6_addr_legal) {
1011 struct sockaddr_in6 *sin6, *rsin6;
1012#if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME)
1013 struct sockaddr_in6 lsa6;
1014#endif
1015 sin6 = &sctp_ifa->address.sin6;
1016 rsin6 = (struct sockaddr_in6 *)to;
t00fcxen326aa4b2014-06-20 13:42:13 +00001017#if defined(__FreeBSD__)
1018 if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
1019 &sin6->sin6_addr) != 0) {
1020 continue;
1021 }
1022#endif
t00fcxen60d0dea2013-02-10 20:04:03 +00001023 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
1024 if (local_scope == 0)
1025 continue;
1026#if defined(SCTP_EMBEDDED_V6_SCOPE)
1027 if (sin6->sin6_scope_id == 0) {
1028#ifdef SCTP_KAME
1029 if (sa6_recoverscope(sin6) != 0)
1030 continue;
1031#else
1032 lsa6 = *sin6;
1033 if (in6_recoverscope(&lsa6,
1034 &lsa6.sin6_addr,
1035 NULL))
1036 continue;
1037 sin6 = &lsa6;
1038#endif /* SCTP_KAME */
1039 }
1040#endif /* SCTP_EMBEDDED_V6_SCOPE */
1041 }
1042 if ((site_scope == 0) &&
1043 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
1044 continue;
1045 }
1046 if (SCTP6_ARE_ADDR_EQUAL(sin6, rsin6)) {
1047 SCTP_IPI_ADDR_RUNLOCK();
1048 return (1);
1049 }
1050 }
1051 break;
1052#endif
1053#if defined(__Userspace__)
1054 case AF_CONN:
1055 if (conn_addr_legal) {
1056 struct sockaddr_conn *sconn, *rsconn;
1057
1058 sconn = &sctp_ifa->address.sconn;
1059 rsconn = (struct sockaddr_conn *)to;
1060 if (sconn->sconn_addr == rsconn->sconn_addr) {
1061 SCTP_IPI_ADDR_RUNLOCK();
1062 return (1);
1063 }
1064 }
1065 break;
1066#endif
1067 default:
1068 /* TSNH */
1069 break;
1070 }
1071 }
1072 }
1073 } else {
1074 struct sctp_laddr *laddr;
1075
1076 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
1077 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
1078 SCTPDBG(SCTP_DEBUG_PCB1, "ifa being deleted\n");
1079 continue;
1080 }
1081 if (sctp_is_addr_restricted(stcb, laddr->ifa) &&
1082 (!sctp_is_addr_pending(stcb, laddr->ifa))) {
1083 /* We allow pending addresses, where we
1084 * have sent an asconf-add to be considered
1085 * valid.
1086 */
1087 continue;
1088 }
1089 if (laddr->ifa->address.sa.sa_family != to->sa_family) {
1090 continue;
1091 }
1092 switch (to->sa_family) {
1093#ifdef INET
1094 case AF_INET:
1095 {
1096 struct sockaddr_in *sin, *rsin;
1097
t00fcxen05f07c02014-09-07 10:15:26 +00001098 sin = &laddr->ifa->address.sin;
t00fcxen60d0dea2013-02-10 20:04:03 +00001099 rsin = (struct sockaddr_in *)to;
1100 if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) {
1101 SCTP_IPI_ADDR_RUNLOCK();
1102 return (1);
1103 }
1104 break;
1105 }
1106#endif
1107#ifdef INET6
1108 case AF_INET6:
1109 {
1110 struct sockaddr_in6 *sin6, *rsin6;
1111
t00fcxen05f07c02014-09-07 10:15:26 +00001112 sin6 = &laddr->ifa->address.sin6;
t00fcxen60d0dea2013-02-10 20:04:03 +00001113 rsin6 = (struct sockaddr_in6 *)to;
1114 if (SCTP6_ARE_ADDR_EQUAL(sin6, rsin6)) {
1115 SCTP_IPI_ADDR_RUNLOCK();
1116 return (1);
1117 }
1118 break;
1119 }
1120
1121#endif
1122#if defined(__Userspace__)
1123 case AF_CONN:
1124 {
1125 struct sockaddr_conn *sconn, *rsconn;
1126
t00fcxen05f07c02014-09-07 10:15:26 +00001127 sconn = &laddr->ifa->address.sconn;
t00fcxen60d0dea2013-02-10 20:04:03 +00001128 rsconn = (struct sockaddr_conn *)to;
1129 if (sconn->sconn_addr == rsconn->sconn_addr) {
1130 SCTP_IPI_ADDR_RUNLOCK();
1131 return (1);
1132 }
1133 break;
1134 }
1135#endif
1136 default:
1137 /* TSNH */
1138 break;
1139 }
1140
1141 }
1142 }
1143 SCTP_IPI_ADDR_RUNLOCK();
1144 return (0);
1145}
1146
1147
tuexendd729232011-11-01 23:04:43 +00001148static struct sctp_tcb *
1149sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
1150 struct sockaddr *to, struct sctp_nets **netp, uint32_t vrf_id)
1151{
1152 /**** ASSUMES THE CALLER holds the INP_INFO_RLOCK */
1153 /*
1154 * If we support the TCP model, then we must now dig through to see
1155 * if we can find our endpoint in the list of tcp ep's.
1156 */
1157 uint16_t lport, rport;
1158 struct sctppcbhead *ephead;
1159 struct sctp_inpcb *inp;
1160 struct sctp_laddr *laddr;
1161 struct sctp_tcb *stcb;
1162 struct sctp_nets *net;
1163#ifdef SCTP_MVRF
1164 int fnd, i;
1165#endif
t00fcxend0ad16b2013-02-09 18:34:24 +00001166
tuexendd729232011-11-01 23:04:43 +00001167 if ((to == NULL) || (from == NULL)) {
1168 return (NULL);
1169 }
1170
1171 switch (to->sa_family) {
1172#ifdef INET
1173 case AF_INET:
1174 if (from->sa_family == AF_INET) {
1175 lport = ((struct sockaddr_in *)to)->sin_port;
1176 rport = ((struct sockaddr_in *)from)->sin_port;
1177 } else {
1178 return (NULL);
1179 }
1180 break;
1181#endif
1182#ifdef INET6
1183 case AF_INET6:
1184 if (from->sa_family == AF_INET6) {
1185 lport = ((struct sockaddr_in6 *)to)->sin6_port;
1186 rport = ((struct sockaddr_in6 *)from)->sin6_port;
1187 } else {
1188 return (NULL);
1189 }
1190 break;
1191#endif
tuexen5d9b9742012-07-11 21:52:01 +00001192#if defined(__Userspace__)
1193 case AF_CONN:
1194 if (from->sa_family == AF_CONN) {
1195 lport = ((struct sockaddr_conn *)to)->sconn_port;
1196 rport = ((struct sockaddr_conn *)from)->sconn_port;
1197 } else {
1198 return (NULL);
1199 }
1200 break;
1201#endif
tuexendd729232011-11-01 23:04:43 +00001202 default:
1203 return (NULL);
1204 }
1205 ephead = &SCTP_BASE_INFO(sctp_tcpephash)[SCTP_PCBHASH_ALLADDR((lport | rport), SCTP_BASE_INFO(hashtcpmark))];
1206 /*
1207 * Ok now for each of the guys in this bucket we must look and see:
1208 * - Does the remote port match. - Does there single association's
1209 * addresses match this address (to). If so we update p_ep to point
1210 * to this ep and return the tcb from it.
1211 */
1212 LIST_FOREACH(inp, ephead, sctp_hash) {
1213 SCTP_INP_RLOCK(inp);
1214 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
1215 SCTP_INP_RUNLOCK(inp);
1216 continue;
1217 }
1218 if (lport != inp->sctp_lport) {
1219 SCTP_INP_RUNLOCK(inp);
1220 continue;
1221 }
t00fcxen326aa4b2014-06-20 13:42:13 +00001222#if defined(__FreeBSD__)
1223 switch (to->sa_family) {
1224#ifdef INET
1225 case AF_INET:
1226 {
1227 struct sockaddr_in *sin;
1228
1229 sin = (struct sockaddr_in *)to;
1230 if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
1231 &sin->sin_addr) != 0) {
1232 SCTP_INP_RUNLOCK(inp);
1233 continue;
1234 }
1235 break;
1236 }
1237#endif
1238#ifdef INET6
1239 case AF_INET6:
1240 {
1241 struct sockaddr_in6 *sin6;
1242
1243 sin6 = (struct sockaddr_in6 *)to;
1244 if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
1245 &sin6->sin6_addr) != 0) {
1246 SCTP_INP_RUNLOCK(inp);
1247 continue;
1248 }
1249 break;
1250 }
1251#endif
1252 default:
1253 SCTP_INP_RUNLOCK(inp);
1254 continue;
1255 }
1256#endif
tuexendd729232011-11-01 23:04:43 +00001257#ifdef SCTP_MVRF
1258 fnd = 0;
tuexen9784e9a2011-12-18 13:04:23 +00001259 for (i = 0; i < inp->num_vrfs; i++) {
tuexendd729232011-11-01 23:04:43 +00001260 if (inp->m_vrf_ids[i] == vrf_id) {
1261 fnd = 1;
1262 break;
1263 }
1264 }
1265 if (fnd == 0) {
1266 SCTP_INP_RUNLOCK(inp);
1267 continue;
1268 }
1269#else
1270 if (inp->def_vrf_id != vrf_id) {
1271 SCTP_INP_RUNLOCK(inp);
1272 continue;
1273 }
1274#endif
1275 /* check to see if the ep has one of the addresses */
1276 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
1277 /* We are NOT bound all, so look further */
1278 int match = 0;
1279
1280 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
1281
1282 if (laddr->ifa == NULL) {
Saúl Ibarra Corretgé8b04b412015-09-26 09:53:06 +02001283 SCTPDBG(SCTP_DEBUG_PCB1, "%s: NULL ifa\n", __func__);
tuexendd729232011-11-01 23:04:43 +00001284 continue;
1285 }
1286 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
1287 SCTPDBG(SCTP_DEBUG_PCB1, "ifa being deleted\n");
1288 continue;
1289 }
1290 if (laddr->ifa->address.sa.sa_family ==
1291 to->sa_family) {
1292 /* see if it matches */
tuexendd729232011-11-01 23:04:43 +00001293#ifdef INET
1294 if (from->sa_family == AF_INET) {
1295 struct sockaddr_in *intf_addr, *sin;
1296
1297 intf_addr = &laddr->ifa->address.sin;
1298 sin = (struct sockaddr_in *)to;
1299 if (sin->sin_addr.s_addr ==
1300 intf_addr->sin_addr.s_addr) {
1301 match = 1;
1302 break;
1303 }
1304 }
1305#endif
1306#ifdef INET6
1307 if (from->sa_family == AF_INET6) {
1308 struct sockaddr_in6 *intf_addr6;
1309 struct sockaddr_in6 *sin6;
1310
1311 sin6 = (struct sockaddr_in6 *)
1312 to;
1313 intf_addr6 = &laddr->ifa->address.sin6;
1314
1315 if (SCTP6_ARE_ADDR_EQUAL(sin6,
1316 intf_addr6)) {
1317 match = 1;
1318 break;
1319 }
1320 }
1321#endif
tuexen5d9b9742012-07-11 21:52:01 +00001322#if defined(__Userspace__)
1323 if (from->sa_family == AF_CONN) {
1324 struct sockaddr_conn *intf_addr, *sconn;
1325
1326 intf_addr = &laddr->ifa->address.sconn;
1327 sconn = (struct sockaddr_conn *)to;
1328 if (sconn->sconn_addr ==
1329 intf_addr->sconn_addr) {
1330 match = 1;
1331 break;
1332 }
1333 }
1334#endif
tuexendd729232011-11-01 23:04:43 +00001335 }
1336 }
1337 if (match == 0) {
1338 /* This endpoint does not have this address */
1339 SCTP_INP_RUNLOCK(inp);
1340 continue;
1341 }
1342 }
1343 /*
1344 * Ok if we hit here the ep has the address, does it hold
1345 * the tcb?
1346 */
t00fcxen60d0dea2013-02-10 20:04:03 +00001347 /* XXX: Why don't we TAILQ_FOREACH through sctp_asoc_list? */
tuexendd729232011-11-01 23:04:43 +00001348 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1349 if (stcb == NULL) {
1350 SCTP_INP_RUNLOCK(inp);
1351 continue;
1352 }
1353 SCTP_TCB_LOCK(stcb);
t00fcxen60d0dea2013-02-10 20:04:03 +00001354 if (!sctp_does_stcb_own_this_addr(stcb, to)) {
1355 SCTP_TCB_UNLOCK(stcb);
1356 SCTP_INP_RUNLOCK(inp);
1357 continue;
1358 }
tuexendd729232011-11-01 23:04:43 +00001359 if (stcb->rport != rport) {
1360 /* remote port does not match. */
tuexen09631162012-04-18 11:23:02 +00001361 SCTP_TCB_UNLOCK(stcb);
tuexendd729232011-11-01 23:04:43 +00001362 SCTP_INP_RUNLOCK(inp);
1363 continue;
1364 }
1365 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
tuexen09631162012-04-18 11:23:02 +00001366 SCTP_TCB_UNLOCK(stcb);
tuexendd729232011-11-01 23:04:43 +00001367 SCTP_INP_RUNLOCK(inp);
1368 continue;
1369 }
t00fcxen60d0dea2013-02-10 20:04:03 +00001370 if (!sctp_does_stcb_own_this_addr(stcb, to)) {
1371 SCTP_TCB_UNLOCK(stcb);
1372 SCTP_INP_RUNLOCK(inp);
1373 continue;
1374 }
tuexendd729232011-11-01 23:04:43 +00001375 /* Does this TCB have a matching address? */
1376 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1377
1378 if (net->ro._l_addr.sa.sa_family != from->sa_family) {
1379 /* not the same family, can't be a match */
1380 continue;
1381 }
1382 switch (from->sa_family) {
1383#ifdef INET
1384 case AF_INET:
1385 {
1386 struct sockaddr_in *sin, *rsin;
1387
1388 sin = (struct sockaddr_in *)&net->ro._l_addr;
1389 rsin = (struct sockaddr_in *)from;
1390 if (sin->sin_addr.s_addr ==
1391 rsin->sin_addr.s_addr) {
1392 /* found it */
1393 if (netp != NULL) {
1394 *netp = net;
1395 }
1396 /* Update the endpoint pointer */
1397 *inp_p = inp;
1398 SCTP_INP_RUNLOCK(inp);
1399 return (stcb);
1400 }
1401 break;
1402 }
1403#endif
1404#ifdef INET6
1405 case AF_INET6:
1406 {
1407 struct sockaddr_in6 *sin6, *rsin6;
1408
1409 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
1410 rsin6 = (struct sockaddr_in6 *)from;
1411 if (SCTP6_ARE_ADDR_EQUAL(sin6,
1412 rsin6)) {
1413 /* found it */
1414 if (netp != NULL) {
1415 *netp = net;
1416 }
1417 /* Update the endpoint pointer */
1418 *inp_p = inp;
1419 SCTP_INP_RUNLOCK(inp);
1420 return (stcb);
1421 }
1422 break;
1423 }
1424#endif
tuexen5d9b9742012-07-11 21:52:01 +00001425#if defined(__Userspace__)
1426 case AF_CONN:
1427 {
1428 struct sockaddr_conn *sconn, *rsconn;
1429
1430 sconn = (struct sockaddr_conn *)&net->ro._l_addr;
1431 rsconn = (struct sockaddr_conn *)from;
1432 if (sconn->sconn_addr == rsconn->sconn_addr) {
1433 /* found it */
1434 if (netp != NULL) {
1435 *netp = net;
1436 }
1437 /* Update the endpoint pointer */
1438 *inp_p = inp;
1439 SCTP_INP_RUNLOCK(inp);
1440 return (stcb);
1441 }
1442 break;
1443 }
1444#endif
tuexendd729232011-11-01 23:04:43 +00001445 default:
1446 /* TSNH */
1447 break;
1448 }
1449 }
1450 SCTP_TCB_UNLOCK(stcb);
1451 SCTP_INP_RUNLOCK(inp);
1452 }
1453 return (NULL);
1454}
1455
t00fcxend0ad16b2013-02-09 18:34:24 +00001456
tuexendd729232011-11-01 23:04:43 +00001457/*
1458 * rules for use
1459 *
1460 * 1) If I return a NULL you must decrement any INP ref cnt. 2) If I find an
1461 * stcb, both will be locked (locked_tcb and stcb) but decrement will be done
1462 * (if locked == NULL). 3) Decrement happens on return ONLY if locked ==
1463 * NULL.
1464 */
1465
1466struct sctp_tcb *
1467sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
1468 struct sctp_nets **netp, struct sockaddr *local, struct sctp_tcb *locked_tcb)
1469{
1470 struct sctpasochead *head;
1471 struct sctp_inpcb *inp;
tuexen63fc0bb2011-12-27 12:24:52 +00001472 struct sctp_tcb *stcb = NULL;
tuexendd729232011-11-01 23:04:43 +00001473 struct sctp_nets *net;
1474 uint16_t rport;
1475
1476 inp = *inp_p;
tuexen5d9b9742012-07-11 21:52:01 +00001477 switch (remote->sa_family) {
1478#ifdef INET
1479 case AF_INET:
tuexendd729232011-11-01 23:04:43 +00001480 rport = (((struct sockaddr_in *)remote)->sin_port);
tuexen5d9b9742012-07-11 21:52:01 +00001481 break;
1482#endif
1483#ifdef INET6
1484 case AF_INET6:
tuexendd729232011-11-01 23:04:43 +00001485 rport = (((struct sockaddr_in6 *)remote)->sin6_port);
tuexen5d9b9742012-07-11 21:52:01 +00001486 break;
1487#endif
1488#if defined(__Userspace__)
1489 case AF_CONN:
1490 rport = (((struct sockaddr_in6 *)remote)->sin6_port);
1491 break;
1492#endif
1493 default:
tuexendd729232011-11-01 23:04:43 +00001494 return (NULL);
1495 }
1496 if (locked_tcb) {
1497 /*
1498 * UN-lock so we can do proper locking here this occurs when
1499 * called from load_addresses_from_init.
1500 */
1501 atomic_add_int(&locked_tcb->asoc.refcnt, 1);
1502 SCTP_TCB_UNLOCK(locked_tcb);
1503 }
1504 SCTP_INP_INFO_RLOCK();
t00fcxenf2d781c2012-11-26 16:47:12 +00001505 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
1506 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
tuexendd729232011-11-01 23:04:43 +00001507 /*-
1508 * Now either this guy is our listener or it's the
1509 * connector. If it is the one that issued the connect, then
1510 * it's only chance is to be the first TCB in the list. If
1511 * it is the acceptor, then do the special_lookup to hash
1512 * and find the real inp.
1513 */
1514 if ((inp->sctp_socket) && (inp->sctp_socket->so_qlimit)) {
1515 /* to is peer addr, from is my addr */
1516#ifndef SCTP_MVRF
1517 stcb = sctp_tcb_special_locate(inp_p, remote, local,
1518 netp, inp->def_vrf_id);
1519 if ((stcb != NULL) && (locked_tcb == NULL)) {
1520 /* we have a locked tcb, lower refcount */
1521 SCTP_INP_DECR_REF(inp);
1522 }
1523 if ((locked_tcb != NULL) && (locked_tcb != stcb)) {
1524 SCTP_INP_RLOCK(locked_tcb->sctp_ep);
1525 SCTP_TCB_LOCK(locked_tcb);
1526 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1527 SCTP_INP_RUNLOCK(locked_tcb->sctp_ep);
1528 }
1529#else
1530 /*-
1531 * MVRF is tricky, we must look in every VRF
1532 * the endpoint has.
1533 */
t00fcxen60d0dea2013-02-10 20:04:03 +00001534 int i;
tuexendd729232011-11-01 23:04:43 +00001535
t00fcxen60d0dea2013-02-10 20:04:03 +00001536 for (i = 0; i < inp->num_vrfs; i++) {
1537 stcb = sctp_tcb_special_locate(inp_p, remote, local,
1538 netp, inp->m_vrf_ids[i]);
1539 if ((stcb != NULL) && (locked_tcb == NULL)) {
1540 /* we have a locked tcb, lower refcount */
1541 SCTP_INP_DECR_REF(inp);
1542 break;
1543 }
1544 if ((locked_tcb != NULL) && (locked_tcb != stcb)) {
1545 SCTP_INP_RLOCK(locked_tcb->sctp_ep);
1546 SCTP_TCB_LOCK(locked_tcb);
1547 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1548 SCTP_INP_RUNLOCK(locked_tcb->sctp_ep);
1549 break;
tuexendd729232011-11-01 23:04:43 +00001550 }
1551 }
1552#endif
1553 SCTP_INP_INFO_RUNLOCK();
1554 return (stcb);
1555 } else {
1556 SCTP_INP_WLOCK(inp);
1557 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
1558 goto null_return;
1559 }
1560 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1561 if (stcb == NULL) {
1562 goto null_return;
1563 }
1564 SCTP_TCB_LOCK(stcb);
1565
1566 if (stcb->rport != rport) {
1567 /* remote port does not match. */
1568 SCTP_TCB_UNLOCK(stcb);
1569 goto null_return;
1570 }
1571 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
tuexen09631162012-04-18 11:23:02 +00001572 SCTP_TCB_UNLOCK(stcb);
tuexendd729232011-11-01 23:04:43 +00001573 goto null_return;
1574 }
1575 if (local && !sctp_does_stcb_own_this_addr(stcb, local)) {
1576 SCTP_TCB_UNLOCK(stcb);
1577 goto null_return;
1578 }
1579 /* now look at the list of remote addresses */
1580 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1581#ifdef INVARIANTS
1582 if (net == (TAILQ_NEXT(net, sctp_next))) {
1583 panic("Corrupt net list");
1584 }
1585#endif
1586 if (net->ro._l_addr.sa.sa_family !=
1587 remote->sa_family) {
1588 /* not the same family */
1589 continue;
1590 }
1591 switch (remote->sa_family) {
1592#ifdef INET
1593 case AF_INET:
1594 {
1595 struct sockaddr_in *sin, *rsin;
1596
1597 sin = (struct sockaddr_in *)
1598 &net->ro._l_addr;
1599 rsin = (struct sockaddr_in *)remote;
1600 if (sin->sin_addr.s_addr ==
1601 rsin->sin_addr.s_addr) {
1602 /* found it */
1603 if (netp != NULL) {
1604 *netp = net;
1605 }
1606 if (locked_tcb == NULL) {
1607 SCTP_INP_DECR_REF(inp);
1608 } else if (locked_tcb != stcb) {
1609 SCTP_TCB_LOCK(locked_tcb);
1610 }
1611 if (locked_tcb) {
1612 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1613 }
1614
1615 SCTP_INP_WUNLOCK(inp);
1616 SCTP_INP_INFO_RUNLOCK();
1617 return (stcb);
1618 }
1619 break;
1620 }
1621#endif
1622#ifdef INET6
1623 case AF_INET6:
1624 {
1625 struct sockaddr_in6 *sin6, *rsin6;
1626
1627 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
1628 rsin6 = (struct sockaddr_in6 *)remote;
1629 if (SCTP6_ARE_ADDR_EQUAL(sin6,
1630 rsin6)) {
1631 /* found it */
1632 if (netp != NULL) {
1633 *netp = net;
1634 }
1635 if (locked_tcb == NULL) {
1636 SCTP_INP_DECR_REF(inp);
1637 } else if (locked_tcb != stcb) {
1638 SCTP_TCB_LOCK(locked_tcb);
1639 }
1640 if (locked_tcb) {
1641 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1642 }
1643 SCTP_INP_WUNLOCK(inp);
1644 SCTP_INP_INFO_RUNLOCK();
1645 return (stcb);
1646 }
1647 break;
1648 }
1649#endif
tuexen5d9b9742012-07-11 21:52:01 +00001650#if defined(__Userspace__)
1651 case AF_CONN:
1652 {
1653 struct sockaddr_conn *sconn, *rsconn;
1654
1655 sconn = (struct sockaddr_conn *)&net->ro._l_addr;
1656 rsconn = (struct sockaddr_conn *)remote;
1657 if (sconn->sconn_addr == rsconn->sconn_addr) {
1658 /* found it */
1659 if (netp != NULL) {
1660 *netp = net;
1661 }
1662 if (locked_tcb == NULL) {
1663 SCTP_INP_DECR_REF(inp);
1664 } else if (locked_tcb != stcb) {
1665 SCTP_TCB_LOCK(locked_tcb);
1666 }
1667 if (locked_tcb) {
1668 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1669 }
1670 SCTP_INP_WUNLOCK(inp);
1671 SCTP_INP_INFO_RUNLOCK();
1672 return (stcb);
1673 }
1674 break;
1675 }
1676#endif
tuexendd729232011-11-01 23:04:43 +00001677 default:
1678 /* TSNH */
1679 break;
1680 }
1681 }
1682 SCTP_TCB_UNLOCK(stcb);
1683 }
1684 } else {
1685 SCTP_INP_WLOCK(inp);
1686 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
1687 goto null_return;
1688 }
1689 head = &inp->sctp_tcbhash[SCTP_PCBHASH_ALLADDR(rport,
t00fcxen1369cd42015-01-11 21:57:30 +00001690 inp->sctp_hashmark)];
tuexendd729232011-11-01 23:04:43 +00001691 LIST_FOREACH(stcb, head, sctp_tcbhash) {
1692 if (stcb->rport != rport) {
1693 /* remote port does not match */
1694 continue;
1695 }
1696 SCTP_TCB_LOCK(stcb);
1697 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
1698 SCTP_TCB_UNLOCK(stcb);
1699 continue;
1700 }
1701 if (local && !sctp_does_stcb_own_this_addr(stcb, local)) {
1702 SCTP_TCB_UNLOCK(stcb);
1703 continue;
1704 }
1705 /* now look at the list of remote addresses */
1706 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1707#ifdef INVARIANTS
1708 if (net == (TAILQ_NEXT(net, sctp_next))) {
1709 panic("Corrupt net list");
1710 }
1711#endif
1712 if (net->ro._l_addr.sa.sa_family !=
1713 remote->sa_family) {
1714 /* not the same family */
1715 continue;
1716 }
1717 switch (remote->sa_family) {
1718#ifdef INET
1719 case AF_INET:
1720 {
1721 struct sockaddr_in *sin, *rsin;
1722
1723 sin = (struct sockaddr_in *)
1724 &net->ro._l_addr;
1725 rsin = (struct sockaddr_in *)remote;
1726 if (sin->sin_addr.s_addr ==
1727 rsin->sin_addr.s_addr) {
1728 /* found it */
1729 if (netp != NULL) {
1730 *netp = net;
1731 }
1732 if (locked_tcb == NULL) {
1733 SCTP_INP_DECR_REF(inp);
1734 } else if (locked_tcb != stcb) {
1735 SCTP_TCB_LOCK(locked_tcb);
1736 }
1737 if (locked_tcb) {
1738 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1739 }
1740 SCTP_INP_WUNLOCK(inp);
1741 SCTP_INP_INFO_RUNLOCK();
1742 return (stcb);
1743 }
1744 break;
1745 }
1746#endif
1747#ifdef INET6
1748 case AF_INET6:
1749 {
1750 struct sockaddr_in6 *sin6, *rsin6;
1751
1752 sin6 = (struct sockaddr_in6 *)
1753 &net->ro._l_addr;
1754 rsin6 = (struct sockaddr_in6 *)remote;
1755 if (SCTP6_ARE_ADDR_EQUAL(sin6,
1756 rsin6)) {
1757 /* found it */
1758 if (netp != NULL) {
1759 *netp = net;
1760 }
1761 if (locked_tcb == NULL) {
1762 SCTP_INP_DECR_REF(inp);
1763 } else if (locked_tcb != stcb) {
1764 SCTP_TCB_LOCK(locked_tcb);
1765 }
1766 if (locked_tcb) {
1767 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1768 }
1769 SCTP_INP_WUNLOCK(inp);
1770 SCTP_INP_INFO_RUNLOCK();
1771 return (stcb);
1772 }
1773 break;
1774 }
1775#endif
tuexen5d9b9742012-07-11 21:52:01 +00001776#if defined(__Userspace__)
1777 case AF_CONN:
1778 {
1779 struct sockaddr_conn *sconn, *rsconn;
1780
1781 sconn = (struct sockaddr_conn *)&net->ro._l_addr;
1782 rsconn = (struct sockaddr_conn *)remote;
1783 if (sconn->sconn_addr == rsconn->sconn_addr) {
1784 /* found it */
1785 if (netp != NULL) {
1786 *netp = net;
1787 }
1788 if (locked_tcb == NULL) {
1789 SCTP_INP_DECR_REF(inp);
1790 } else if (locked_tcb != stcb) {
1791 SCTP_TCB_LOCK(locked_tcb);
1792 }
1793 if (locked_tcb) {
1794 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1795 }
1796 SCTP_INP_WUNLOCK(inp);
1797 SCTP_INP_INFO_RUNLOCK();
1798 return (stcb);
1799 }
1800 break;
1801 }
1802#endif
tuexendd729232011-11-01 23:04:43 +00001803 default:
1804 /* TSNH */
1805 break;
1806 }
1807 }
1808 SCTP_TCB_UNLOCK(stcb);
1809 }
1810 }
1811null_return:
1812 /* clean up for returning null */
1813 if (locked_tcb) {
1814 SCTP_TCB_LOCK(locked_tcb);
1815 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1816 }
1817 SCTP_INP_WUNLOCK(inp);
1818 SCTP_INP_INFO_RUNLOCK();
1819 /* not found */
1820 return (NULL);
1821}
1822
t00fcxend0ad16b2013-02-09 18:34:24 +00001823
tuexendd729232011-11-01 23:04:43 +00001824/*
1825 * Find an association for a specific endpoint using the association id given
1826 * out in the COMM_UP notification
1827 */
tuexendd729232011-11-01 23:04:43 +00001828struct sctp_tcb *
1829sctp_findasoc_ep_asocid_locked(struct sctp_inpcb *inp, sctp_assoc_t asoc_id, int want_lock)
1830{
1831 /*
1832 * Use my the assoc_id to find a endpoint
1833 */
1834 struct sctpasochead *head;
1835 struct sctp_tcb *stcb;
1836 uint32_t id;
t00fcxend0ad16b2013-02-09 18:34:24 +00001837
tuexendd729232011-11-01 23:04:43 +00001838 if (inp == NULL) {
1839 SCTP_PRINTF("TSNH ep_associd\n");
1840 return (NULL);
1841 }
1842 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
1843 SCTP_PRINTF("TSNH ep_associd0\n");
1844 return (NULL);
1845 }
1846 id = (uint32_t)asoc_id;
1847 head = &inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(id, inp->hashasocidmark)];
1848 if (head == NULL) {
1849 /* invalid id TSNH */
1850 SCTP_PRINTF("TSNH ep_associd1\n");
1851 return (NULL);
1852 }
1853 LIST_FOREACH(stcb, head, sctp_tcbasocidhash) {
1854 if (stcb->asoc.assoc_id == id) {
1855 if (inp != stcb->sctp_ep) {
1856 /*
1857 * some other guy has the same id active (id
1858 * collision ??).
1859 */
1860 SCTP_PRINTF("TSNH ep_associd2\n");
1861 continue;
1862 }
1863 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
1864 continue;
1865 }
1866 if (want_lock) {
1867 SCTP_TCB_LOCK(stcb);
1868 }
1869 return (stcb);
1870 }
1871 }
1872 return (NULL);
1873}
1874
1875
1876struct sctp_tcb *
1877sctp_findassociation_ep_asocid(struct sctp_inpcb *inp, sctp_assoc_t asoc_id, int want_lock)
1878{
t00fcxend0ad16b2013-02-09 18:34:24 +00001879 struct sctp_tcb *stcb;
1880
1881 SCTP_INP_RLOCK(inp);
1882 stcb = sctp_findasoc_ep_asocid_locked(inp, asoc_id, want_lock);
1883 SCTP_INP_RUNLOCK(inp);
1884 return (stcb);
tuexendd729232011-11-01 23:04:43 +00001885}
1886
1887
t00fcxend0ad16b2013-02-09 18:34:24 +00001888/*
1889 * Endpoint probe expects that the INP_INFO is locked.
1890 */
tuexendd729232011-11-01 23:04:43 +00001891static struct sctp_inpcb *
1892sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
1893 uint16_t lport, uint32_t vrf_id)
1894{
1895 struct sctp_inpcb *inp;
1896 struct sctp_laddr *laddr;
1897#ifdef INET
1898 struct sockaddr_in *sin;
1899#endif
1900#ifdef INET6
1901 struct sockaddr_in6 *sin6;
1902 struct sockaddr_in6 *intf_addr6;
1903#endif
tuexen09a676e2012-07-08 21:03:18 +00001904#if defined(__Userspace__)
1905 struct sockaddr_conn *sconn;
1906#endif
tuexendd729232011-11-01 23:04:43 +00001907#ifdef SCTP_MVRF
1908 int i;
1909#endif
1910 int fnd;
t00fcxend0ad16b2013-02-09 18:34:24 +00001911
tuexendd729232011-11-01 23:04:43 +00001912#ifdef INET
1913 sin = NULL;
1914#endif
1915#ifdef INET6
1916 sin6 = NULL;
1917#endif
t00fcxenb4c54ac2012-09-15 09:17:50 +00001918#if defined(__Userspace__)
1919 sconn = NULL;
1920#endif
tuexendd729232011-11-01 23:04:43 +00001921 switch (nam->sa_family) {
1922#ifdef INET
1923 case AF_INET:
1924 sin = (struct sockaddr_in *)nam;
1925 break;
1926#endif
1927#ifdef INET6
1928 case AF_INET6:
1929 sin6 = (struct sockaddr_in6 *)nam;
1930 break;
1931#endif
tuexen09a676e2012-07-08 21:03:18 +00001932#if defined(__Userspace__)
1933 case AF_CONN:
1934 sconn = (struct sockaddr_conn *)nam;
1935 break;
1936#endif
tuexendd729232011-11-01 23:04:43 +00001937 default:
1938 /* unsupported family */
1939 return (NULL);
1940 }
1941
1942 if (head == NULL)
1943 return (NULL);
tuexen09631162012-04-18 11:23:02 +00001944
tuexendd729232011-11-01 23:04:43 +00001945 LIST_FOREACH(inp, head, sctp_hash) {
1946 SCTP_INP_RLOCK(inp);
1947 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
1948 SCTP_INP_RUNLOCK(inp);
1949 continue;
1950 }
1951 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) &&
1952 (inp->sctp_lport == lport)) {
1953 /* got it */
t00fcxen326aa4b2014-06-20 13:42:13 +00001954 switch (nam->sa_family) {
tuexendd729232011-11-01 23:04:43 +00001955#ifdef INET
t00fcxen326aa4b2014-06-20 13:42:13 +00001956 case AF_INET:
1957 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
1958 SCTP_IPV6_V6ONLY(inp)) {
1959 /* IPv4 on a IPv6 socket with ONLY IPv6 set */
1960 SCTP_INP_RUNLOCK(inp);
1961 continue;
1962 }
1963#if defined(__FreeBSD__)
1964 if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
1965 &sin->sin_addr) != 0) {
1966 SCTP_INP_RUNLOCK(inp);
1967 continue;
1968 }
1969#endif
1970 break;
tuexendd729232011-11-01 23:04:43 +00001971#endif
1972#ifdef INET6
t00fcxen326aa4b2014-06-20 13:42:13 +00001973 case AF_INET6:
1974 /* A V6 address and the endpoint is NOT bound V6 */
1975 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
1976 SCTP_INP_RUNLOCK(inp);
1977 continue;
1978 }
1979#if defined(__FreeBSD__)
1980 if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
1981 &sin6->sin6_addr) != 0) {
1982 SCTP_INP_RUNLOCK(inp);
1983 continue;
1984 }
tuexendd729232011-11-01 23:04:43 +00001985#endif
t00fcxen326aa4b2014-06-20 13:42:13 +00001986 break;
1987#endif
1988 default:
1989 break;
1990 }
tuexendd729232011-11-01 23:04:43 +00001991 /* does a VRF id match? */
1992 fnd = 0;
1993#ifdef SCTP_MVRF
1994 for (i = 0; i < inp->num_vrfs; i++) {
1995 if (inp->m_vrf_ids[i] == vrf_id) {
1996 fnd = 1;
1997 break;
1998 }
1999 }
2000#else
2001 if (inp->def_vrf_id == vrf_id)
2002 fnd = 1;
2003#endif
2004
2005 SCTP_INP_RUNLOCK(inp);
2006 if (!fnd)
2007 continue;
2008 return (inp);
2009 }
2010 SCTP_INP_RUNLOCK(inp);
2011 }
2012 switch (nam->sa_family) {
2013#ifdef INET
2014 case AF_INET:
2015 if (sin->sin_addr.s_addr == INADDR_ANY) {
2016 /* Can't hunt for one that has no address specified */
2017 return (NULL);
2018 }
2019 break;
2020#endif
2021#ifdef INET6
2022 case AF_INET6:
tuexen63fc0bb2011-12-27 12:24:52 +00002023 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
tuexendd729232011-11-01 23:04:43 +00002024 /* Can't hunt for one that has no address specified */
2025 return (NULL);
2026 }
2027 break;
2028#endif
tuexen09a676e2012-07-08 21:03:18 +00002029#if defined(__Userspace__)
2030 case AF_CONN:
2031 if (sconn->sconn_addr == NULL) {
2032 return (NULL);
2033 }
2034 break;
2035#endif
tuexendd729232011-11-01 23:04:43 +00002036 default:
2037 break;
2038 }
2039 /*
2040 * ok, not bound to all so see if we can find a EP bound to this
2041 * address.
2042 */
2043 LIST_FOREACH(inp, head, sctp_hash) {
2044 SCTP_INP_RLOCK(inp);
2045 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
2046 SCTP_INP_RUNLOCK(inp);
2047 continue;
2048 }
2049 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL)) {
2050 SCTP_INP_RUNLOCK(inp);
2051 continue;
2052 }
2053 /*
2054 * Ok this could be a likely candidate, look at all of its
2055 * addresses
2056 */
2057 if (inp->sctp_lport != lport) {
2058 SCTP_INP_RUNLOCK(inp);
2059 continue;
2060 }
2061 /* does a VRF id match? */
2062 fnd = 0;
2063#ifdef SCTP_MVRF
2064 for (i = 0; i < inp->num_vrfs; i++) {
2065 if (inp->m_vrf_ids[i] == vrf_id) {
2066 fnd = 1;
2067 break;
2068 }
2069 }
2070#else
2071 if (inp->def_vrf_id == vrf_id)
2072 fnd = 1;
2073
2074#endif
2075 if (!fnd) {
2076 SCTP_INP_RUNLOCK(inp);
2077 continue;
2078 }
2079 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
2080 if (laddr->ifa == NULL) {
2081 SCTPDBG(SCTP_DEBUG_PCB1, "%s: NULL ifa\n",
Saúl Ibarra Corretgé8b04b412015-09-26 09:53:06 +02002082 __func__);
tuexendd729232011-11-01 23:04:43 +00002083 continue;
2084 }
2085 SCTPDBG(SCTP_DEBUG_PCB1, "Ok laddr->ifa:%p is possible, ",
t00fcxen8fca7ff2012-09-05 18:58:42 +00002086 (void *)laddr->ifa);
tuexendd729232011-11-01 23:04:43 +00002087 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
2088 SCTPDBG(SCTP_DEBUG_PCB1, "Huh IFA being deleted\n");
2089 continue;
2090 }
2091 if (laddr->ifa->address.sa.sa_family == nam->sa_family) {
2092 /* possible, see if it matches */
2093 switch (nam->sa_family) {
2094#ifdef INET
2095 case AF_INET:
tuexen63fc0bb2011-12-27 12:24:52 +00002096#if defined(__APPLE__)
2097 if (sin == NULL) {
2098 /* TSNH */
2099 break;
2100 }
2101#endif
tuexendd729232011-11-01 23:04:43 +00002102 if (sin->sin_addr.s_addr ==
2103 laddr->ifa->address.sin.sin_addr.s_addr) {
2104 SCTP_INP_RUNLOCK(inp);
2105 return (inp);
2106 }
2107 break;
2108#endif
2109#ifdef INET6
2110 case AF_INET6:
2111 intf_addr6 = &laddr->ifa->address.sin6;
2112 if (SCTP6_ARE_ADDR_EQUAL(sin6,
2113 intf_addr6)) {
2114 SCTP_INP_RUNLOCK(inp);
2115 return (inp);
2116 }
2117 break;
2118#endif
tuexen09a676e2012-07-08 21:03:18 +00002119#if defined(__Userspace__)
2120 case AF_CONN:
2121 if (sconn->sconn_addr == laddr->ifa->address.sconn.sconn_addr) {
2122 SCTP_INP_RUNLOCK(inp);
2123 return (inp);
2124 }
2125 break;
2126#endif
tuexendd729232011-11-01 23:04:43 +00002127 }
2128 }
2129 }
2130 SCTP_INP_RUNLOCK(inp);
2131 }
2132 return (NULL);
2133}
2134
2135
2136static struct sctp_inpcb *
2137sctp_isport_inuse(struct sctp_inpcb *inp, uint16_t lport, uint32_t vrf_id)
2138{
2139 struct sctppcbhead *head;
2140 struct sctp_inpcb *t_inp;
2141#ifdef SCTP_MVRF
2142 int i;
2143#endif
2144 int fnd;
2145
2146 head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(lport,
2147 SCTP_BASE_INFO(hashmark))];
2148 LIST_FOREACH(t_inp, head, sctp_hash) {
2149 if (t_inp->sctp_lport != lport) {
2150 continue;
2151 }
2152 /* is it in the VRF in question */
2153 fnd = 0;
2154#ifdef SCTP_MVRF
tuexen63fc0bb2011-12-27 12:24:52 +00002155 for (i = 0; i < inp->num_vrfs; i++) {
tuexendd729232011-11-01 23:04:43 +00002156 if (t_inp->m_vrf_ids[i] == vrf_id) {
2157 fnd = 1;
2158 break;
2159 }
2160 }
2161#else
2162 if (t_inp->def_vrf_id == vrf_id)
2163 fnd = 1;
2164#endif
2165 if (!fnd)
2166 continue;
2167
2168 /* This one is in use. */
2169 /* check the v6/v4 binding issue */
2170 if ((t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2171 SCTP_IPV6_V6ONLY(t_inp)) {
2172 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2173 /* collision in V6 space */
2174 return (t_inp);
2175 } else {
2176 /* inp is BOUND_V4 no conflict */
2177 continue;
2178 }
2179 } else if (t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2180 /* t_inp is bound v4 and v6, conflict always */
2181 return (t_inp);
2182 } else {
2183 /* t_inp is bound only V4 */
2184 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2185 SCTP_IPV6_V6ONLY(inp)) {
2186 /* no conflict */
2187 continue;
2188 }
2189 /* else fall through to conflict */
2190 }
2191 return (t_inp);
2192 }
2193 return (NULL);
2194}
2195
2196
2197int
2198sctp_swap_inpcb_for_listen(struct sctp_inpcb *inp)
2199{
2200 /* For 1-2-1 with port reuse */
2201 struct sctppcbhead *head;
t00fcxenc00f4bc2015-03-24 21:17:16 +00002202 struct sctp_inpcb *tinp, *ninp;
tuexendd729232011-11-01 23:04:43 +00002203
2204 if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE)) {
2205 /* only works with port reuse on */
tuexen63fc0bb2011-12-27 12:24:52 +00002206 return (-1);
tuexendd729232011-11-01 23:04:43 +00002207 }
2208 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) {
2209 return (0);
2210 }
2211 SCTP_INP_RUNLOCK(inp);
t00fcxenc00f4bc2015-03-24 21:17:16 +00002212 SCTP_INP_INFO_WLOCK();
tuexendd729232011-11-01 23:04:43 +00002213 head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(inp->sctp_lport,
2214 SCTP_BASE_INFO(hashmark))];
2215 /* Kick out all non-listeners to the TCP hash */
t00fcxenc00f4bc2015-03-24 21:17:16 +00002216 LIST_FOREACH_SAFE(tinp, head, sctp_hash, ninp) {
tuexendd729232011-11-01 23:04:43 +00002217 if (tinp->sctp_lport != inp->sctp_lport) {
2218 continue;
2219 }
2220 if (tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
2221 continue;
2222 }
2223 if (tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
2224 continue;
2225 }
2226 if (tinp->sctp_socket->so_qlimit) {
2227 continue;
2228 }
2229 SCTP_INP_WLOCK(tinp);
2230 LIST_REMOVE(tinp, sctp_hash);
2231 head = &SCTP_BASE_INFO(sctp_tcpephash)[SCTP_PCBHASH_ALLADDR(tinp->sctp_lport, SCTP_BASE_INFO(hashtcpmark))];
2232 tinp->sctp_flags |= SCTP_PCB_FLAGS_IN_TCPPOOL;
2233 LIST_INSERT_HEAD(head, tinp, sctp_hash);
2234 SCTP_INP_WUNLOCK(tinp);
2235 }
2236 SCTP_INP_WLOCK(inp);
2237 /* Pull from where he was */
2238 LIST_REMOVE(inp, sctp_hash);
2239 inp->sctp_flags &= ~SCTP_PCB_FLAGS_IN_TCPPOOL;
2240 head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(inp->sctp_lport, SCTP_BASE_INFO(hashmark))];
2241 LIST_INSERT_HEAD(head, inp, sctp_hash);
2242 SCTP_INP_WUNLOCK(inp);
2243 SCTP_INP_RLOCK(inp);
t00fcxenc00f4bc2015-03-24 21:17:16 +00002244 SCTP_INP_INFO_WUNLOCK();
tuexendd729232011-11-01 23:04:43 +00002245 return (0);
2246}
2247
2248
2249struct sctp_inpcb *
2250sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock,
2251 uint32_t vrf_id)
2252{
2253 /*
2254 * First we check the hash table to see if someone has this port
2255 * bound with just the port.
2256 */
2257 struct sctp_inpcb *inp;
2258 struct sctppcbhead *head;
2259 int lport;
2260 unsigned int i;
2261#ifdef INET
2262 struct sockaddr_in *sin;
2263#endif
2264#ifdef INET6
2265 struct sockaddr_in6 *sin6;
2266#endif
tuexen09a676e2012-07-08 21:03:18 +00002267#if defined(__Userspace__)
2268 struct sockaddr_conn *sconn;
2269#endif
tuexendd729232011-11-01 23:04:43 +00002270
2271 switch (nam->sa_family) {
2272#ifdef INET
2273 case AF_INET:
2274 sin = (struct sockaddr_in *)nam;
tuexen63fc0bb2011-12-27 12:24:52 +00002275 lport = sin->sin_port;
tuexendd729232011-11-01 23:04:43 +00002276 break;
2277#endif
2278#ifdef INET6
2279 case AF_INET6:
2280 sin6 = (struct sockaddr_in6 *)nam;
tuexen63fc0bb2011-12-27 12:24:52 +00002281 lport = sin6->sin6_port;
tuexendd729232011-11-01 23:04:43 +00002282 break;
2283#endif
tuexen09a676e2012-07-08 21:03:18 +00002284#if defined(__Userspace__)
2285 case AF_CONN:
2286 sconn = (struct sockaddr_conn *)nam;
2287 lport = sconn->sconn_port;
2288 break;
2289#endif
tuexendd729232011-11-01 23:04:43 +00002290 default:
2291 return (NULL);
2292 }
2293 /*
2294 * I could cheat here and just cast to one of the types but we will
2295 * do it right. It also provides the check against an Unsupported
2296 * type too.
2297 */
2298 /* Find the head of the ALLADDR chain */
2299 if (have_lock == 0) {
2300 SCTP_INP_INFO_RLOCK();
2301 }
2302 head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(lport,
2303 SCTP_BASE_INFO(hashmark))];
2304 inp = sctp_endpoint_probe(nam, head, lport, vrf_id);
2305
2306 /*
2307 * If the TCP model exists it could be that the main listening
2308 * endpoint is gone but there still exists a connected socket for this
2309 * guy. If so we can return the first one that we find. This may NOT
2310 * be the correct one so the caller should be wary on the returned INP.
2311 * Currently the only caller that sets find_tcp_pool is in bindx where
2312 * we are verifying that a user CAN bind the address. He either
2313 * has bound it already, or someone else has, or its open to bind,
2314 * so this is good enough.
2315 */
2316 if (inp == NULL && find_tcp_pool) {
2317 for (i = 0; i < SCTP_BASE_INFO(hashtcpmark) + 1; i++) {
2318 head = &SCTP_BASE_INFO(sctp_tcpephash)[i];
2319 inp = sctp_endpoint_probe(nam, head, lport, vrf_id);
2320 if (inp) {
2321 break;
2322 }
2323 }
2324 }
2325 if (inp) {
2326 SCTP_INP_INCR_REF(inp);
2327 }
2328 if (have_lock == 0) {
2329 SCTP_INP_INFO_RUNLOCK();
2330 }
2331 return (inp);
2332}
2333
t00fcxend0ad16b2013-02-09 18:34:24 +00002334
tuexendd729232011-11-01 23:04:43 +00002335/*
2336 * Find an association for an endpoint with the pointer to whom you want to
2337 * send to and the endpoint pointer. The address can be IPv4 or IPv6. We may
2338 * need to change the *to to some other struct like a mbuf...
2339 */
2340struct sctp_tcb *
tuexen664967a2012-06-28 16:24:36 +00002341sctp_findassociation_addr_sa(struct sockaddr *from, struct sockaddr *to,
tuexendd729232011-11-01 23:04:43 +00002342 struct sctp_inpcb **inp_p, struct sctp_nets **netp, int find_tcp_pool,
2343 uint32_t vrf_id)
2344{
2345 struct sctp_inpcb *inp = NULL;
t00fcxen60d0dea2013-02-10 20:04:03 +00002346 struct sctp_tcb *stcb;
tuexendd729232011-11-01 23:04:43 +00002347
2348 SCTP_INP_INFO_RLOCK();
2349 if (find_tcp_pool) {
2350 if (inp_p != NULL) {
t00fcxen60d0dea2013-02-10 20:04:03 +00002351 stcb = sctp_tcb_special_locate(inp_p, from, to, netp,
2352 vrf_id);
tuexendd729232011-11-01 23:04:43 +00002353 } else {
t00fcxen60d0dea2013-02-10 20:04:03 +00002354 stcb = sctp_tcb_special_locate(&inp, from, to, netp,
2355 vrf_id);
tuexendd729232011-11-01 23:04:43 +00002356 }
t00fcxen60d0dea2013-02-10 20:04:03 +00002357 if (stcb != NULL) {
tuexendd729232011-11-01 23:04:43 +00002358 SCTP_INP_INFO_RUNLOCK();
t00fcxen60d0dea2013-02-10 20:04:03 +00002359 return (stcb);
tuexendd729232011-11-01 23:04:43 +00002360 }
2361 }
2362 inp = sctp_pcb_findep(to, 0, 1, vrf_id);
2363 if (inp_p != NULL) {
2364 *inp_p = inp;
2365 }
2366 SCTP_INP_INFO_RUNLOCK();
tuexendd729232011-11-01 23:04:43 +00002367 if (inp == NULL) {
2368 return (NULL);
2369 }
2370 /*
2371 * ok, we have an endpoint, now lets find the assoc for it (if any)
2372 * we now place the source address or from in the to of the find
2373 * endpoint call. Since in reality this chain is used from the
2374 * inbound packet side.
2375 */
2376 if (inp_p != NULL) {
t00fcxen60d0dea2013-02-10 20:04:03 +00002377 stcb = sctp_findassociation_ep_addr(inp_p, from, netp, to,
2378 NULL);
tuexendd729232011-11-01 23:04:43 +00002379 } else {
t00fcxen60d0dea2013-02-10 20:04:03 +00002380 stcb = sctp_findassociation_ep_addr(&inp, from, netp, to,
2381 NULL);
tuexendd729232011-11-01 23:04:43 +00002382 }
t00fcxen60d0dea2013-02-10 20:04:03 +00002383 return (stcb);
tuexendd729232011-11-01 23:04:43 +00002384}
2385
2386
2387/*
2388 * This routine will grub through the mbuf that is a INIT or INIT-ACK and
2389 * find all addresses that the sender has specified in any address list. Each
2390 * address will be used to lookup the TCB and see if one exits.
2391 */
2392static struct sctp_tcb *
tuexen9784e9a2011-12-18 13:04:23 +00002393sctp_findassociation_special_addr(struct mbuf *m, int offset,
tuexendd729232011-11-01 23:04:43 +00002394 struct sctphdr *sh, struct sctp_inpcb **inp_p, struct sctp_nets **netp,
tuexen664967a2012-06-28 16:24:36 +00002395 struct sockaddr *dst)
tuexendd729232011-11-01 23:04:43 +00002396{
2397 struct sctp_paramhdr *phdr, parm_buf;
t00fcxenaff14b62013-11-02 18:02:02 +00002398#if defined(INET) || defined(INET6)
t00fcxen6ebb6032013-11-02 18:03:31 +00002399 struct sctp_tcb *stcb;
t00fcxenaff14b62013-11-02 18:02:02 +00002400 uint16_t ptype;
2401#endif
2402 uint16_t plen;
tuexendd729232011-11-01 23:04:43 +00002403#ifdef INET
2404 struct sockaddr_in sin4;
2405#endif
2406#ifdef INET6
2407 struct sockaddr_in6 sin6;
2408#endif
2409
2410#ifdef INET
2411 memset(&sin4, 0, sizeof(sin4));
t00fcxen8fbaee32012-09-04 16:41:39 +00002412#ifdef HAVE_SIN_LEN
tuexendd729232011-11-01 23:04:43 +00002413 sin4.sin_len = sizeof(sin4);
2414#endif
2415 sin4.sin_family = AF_INET;
2416 sin4.sin_port = sh->src_port;
2417#endif
2418#ifdef INET6
2419 memset(&sin6, 0, sizeof(sin6));
t00fcxen8fbaee32012-09-04 16:41:39 +00002420#ifdef HAVE_SIN6_LEN
tuexendd729232011-11-01 23:04:43 +00002421 sin6.sin6_len = sizeof(sin6);
2422#endif
2423 sin6.sin6_family = AF_INET6;
2424 sin6.sin6_port = sh->src_port;
2425#endif
2426
tuexendd729232011-11-01 23:04:43 +00002427 offset += sizeof(struct sctp_init_chunk);
2428
2429 phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
2430 while (phdr != NULL) {
2431 /* now we must see if we want the parameter */
t00fcxenaff14b62013-11-02 18:02:02 +00002432#if defined(INET) || defined(INET6)
tuexendd729232011-11-01 23:04:43 +00002433 ptype = ntohs(phdr->param_type);
t00fcxenaff14b62013-11-02 18:02:02 +00002434#endif
tuexendd729232011-11-01 23:04:43 +00002435 plen = ntohs(phdr->param_length);
2436 if (plen == 0) {
2437 break;
2438 }
2439#ifdef INET
2440 if (ptype == SCTP_IPV4_ADDRESS &&
2441 plen == sizeof(struct sctp_ipv4addr_param)) {
2442 /* Get the rest of the address */
2443 struct sctp_ipv4addr_param ip4_parm, *p4;
2444
2445 phdr = sctp_get_next_param(m, offset,
2446 (struct sctp_paramhdr *)&ip4_parm, min(plen, sizeof(ip4_parm)));
2447 if (phdr == NULL) {
2448 return (NULL);
2449 }
2450 p4 = (struct sctp_ipv4addr_param *)phdr;
2451 memcpy(&sin4.sin_addr, &p4->addr, sizeof(p4->addr));
2452 /* look it up */
t00fcxen60d0dea2013-02-10 20:04:03 +00002453 stcb = sctp_findassociation_ep_addr(inp_p,
tuexen664967a2012-06-28 16:24:36 +00002454 (struct sockaddr *)&sin4, netp, dst, NULL);
t00fcxen60d0dea2013-02-10 20:04:03 +00002455 if (stcb != NULL) {
2456 return (stcb);
tuexendd729232011-11-01 23:04:43 +00002457 }
2458 }
2459#endif
2460#ifdef INET6
2461 if (ptype == SCTP_IPV6_ADDRESS &&
2462 plen == sizeof(struct sctp_ipv6addr_param)) {
2463 /* Get the rest of the address */
2464 struct sctp_ipv6addr_param ip6_parm, *p6;
2465
2466 phdr = sctp_get_next_param(m, offset,
2467 (struct sctp_paramhdr *)&ip6_parm, min(plen,sizeof(ip6_parm)));
2468 if (phdr == NULL) {
2469 return (NULL);
2470 }
2471 p6 = (struct sctp_ipv6addr_param *)phdr;
2472 memcpy(&sin6.sin6_addr, &p6->addr, sizeof(p6->addr));
2473 /* look it up */
t00fcxen60d0dea2013-02-10 20:04:03 +00002474 stcb = sctp_findassociation_ep_addr(inp_p,
tuexen664967a2012-06-28 16:24:36 +00002475 (struct sockaddr *)&sin6, netp, dst, NULL);
t00fcxen60d0dea2013-02-10 20:04:03 +00002476 if (stcb != NULL) {
2477 return (stcb);
tuexendd729232011-11-01 23:04:43 +00002478 }
2479 }
2480#endif
2481 offset += SCTP_SIZE32(plen);
2482 phdr = sctp_get_next_param(m, offset, &parm_buf,
2483 sizeof(parm_buf));
2484 }
2485 return (NULL);
2486}
2487
2488static struct sctp_tcb *
2489sctp_findassoc_by_vtag(struct sockaddr *from, struct sockaddr *to, uint32_t vtag,
2490 struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint16_t rport,
2491 uint16_t lport, int skip_src_check, uint32_t vrf_id, uint32_t remote_tag)
2492{
2493 /*
2494 * Use my vtag to hash. If we find it we then verify the source addr
2495 * is in the assoc. If all goes well we save a bit on rec of a
2496 * packet.
2497 */
2498 struct sctpasochead *head;
2499 struct sctp_nets *net;
2500 struct sctp_tcb *stcb;
tuexen9784e9a2011-12-18 13:04:23 +00002501#ifdef SCTP_MVRF
2502 unsigned int i;
2503#endif
tuexendd729232011-11-01 23:04:43 +00002504
tuexendd729232011-11-01 23:04:43 +00002505 SCTP_INP_INFO_RLOCK();
2506 head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(vtag,
t00fcxen0d664882015-01-11 21:47:36 +00002507 SCTP_BASE_INFO(hashasocmark))];
tuexendd729232011-11-01 23:04:43 +00002508 LIST_FOREACH(stcb, head, sctp_asocs) {
2509 SCTP_INP_RLOCK(stcb->sctp_ep);
2510 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
2511 SCTP_INP_RUNLOCK(stcb->sctp_ep);
2512 continue;
2513 }
tuexen9784e9a2011-12-18 13:04:23 +00002514#ifdef SCTP_MVRF
2515 for (i = 0; i < stcb->sctp_ep->num_vrfs; i++) {
2516 if (stcb->sctp_ep->m_vrf_ids[i] == vrf_id) {
2517 break;
2518 }
2519 }
2520 if (i == stcb->sctp_ep->num_vrfs) {
2521 SCTP_INP_RUNLOCK(inp);
2522 continue;
2523 }
2524#else
2525 if (stcb->sctp_ep->def_vrf_id != vrf_id) {
2526 SCTP_INP_RUNLOCK(stcb->sctp_ep);
2527 continue;
2528 }
2529#endif
tuexendd729232011-11-01 23:04:43 +00002530 SCTP_TCB_LOCK(stcb);
2531 SCTP_INP_RUNLOCK(stcb->sctp_ep);
2532 if (stcb->asoc.my_vtag == vtag) {
2533 /* candidate */
2534 if (stcb->rport != rport) {
2535 SCTP_TCB_UNLOCK(stcb);
2536 continue;
2537 }
2538 if (stcb->sctp_ep->sctp_lport != lport) {
2539 SCTP_TCB_UNLOCK(stcb);
2540 continue;
2541 }
2542 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
2543 SCTP_TCB_UNLOCK(stcb);
2544 continue;
2545 }
2546 /* RRS:Need toaddr check here */
2547 if (sctp_does_stcb_own_this_addr(stcb, to) == 0) {
2548 /* Endpoint does not own this address */
2549 SCTP_TCB_UNLOCK(stcb);
2550 continue;
2551 }
2552 if (remote_tag) {
2553 /* If we have both vtags that's all we match on */
2554 if (stcb->asoc.peer_vtag == remote_tag) {
2555 /* If both tags match we consider it conclusive
2556 * and check NO source/destination addresses
2557 */
2558 goto conclusive;
2559 }
2560 }
2561 if (skip_src_check) {
2562 conclusive:
2563 if (from) {
tuexen63fc0bb2011-12-27 12:24:52 +00002564 *netp = sctp_findnet(stcb, from);
tuexendd729232011-11-01 23:04:43 +00002565 } else {
2566 *netp = NULL; /* unknown */
2567 }
2568 if (inp_p)
2569 *inp_p = stcb->sctp_ep;
2570 SCTP_INP_INFO_RUNLOCK();
2571 return (stcb);
2572 }
2573 net = sctp_findnet(stcb, from);
2574 if (net) {
2575 /* yep its him. */
2576 *netp = net;
2577 SCTP_STAT_INCR(sctps_vtagexpress);
2578 *inp_p = stcb->sctp_ep;
2579 SCTP_INP_INFO_RUNLOCK();
2580 return (stcb);
2581 } else {
2582 /*
2583 * not him, this should only happen in rare
2584 * cases so I peg it.
2585 */
2586 SCTP_STAT_INCR(sctps_vtagbogus);
2587 }
2588 }
2589 SCTP_TCB_UNLOCK(stcb);
2590 }
2591 SCTP_INP_INFO_RUNLOCK();
2592 return (NULL);
2593}
2594
t00fcxend0ad16b2013-02-09 18:34:24 +00002595
tuexendd729232011-11-01 23:04:43 +00002596/*
2597 * Find an association with the pointer to the inbound IP packet. This can be
2598 * a IPv4 or IPv6 packet.
2599 */
2600struct sctp_tcb *
tuexen9784e9a2011-12-18 13:04:23 +00002601sctp_findassociation_addr(struct mbuf *m, int offset,
tuexen664967a2012-06-28 16:24:36 +00002602 struct sockaddr *src, struct sockaddr *dst,
tuexendd729232011-11-01 23:04:43 +00002603 struct sctphdr *sh, struct sctp_chunkhdr *ch,
2604 struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id)
2605{
t00fcxen60d0dea2013-02-10 20:04:03 +00002606 struct sctp_tcb *stcb;
tuexendd729232011-11-01 23:04:43 +00002607 struct sctp_inpcb *inp;
2608
tuexendd729232011-11-01 23:04:43 +00002609 if (sh->v_tag) {
2610 /* we only go down this path if vtag is non-zero */
t00fcxen60d0dea2013-02-10 20:04:03 +00002611 stcb = sctp_findassoc_by_vtag(src, dst, ntohl(sh->v_tag),
t00fcxenafd21192013-05-10 18:15:02 +00002612 inp_p, netp, sh->src_port, sh->dest_port, 0, vrf_id, 0);
t00fcxen60d0dea2013-02-10 20:04:03 +00002613 if (stcb) {
2614 return (stcb);
tuexendd729232011-11-01 23:04:43 +00002615 }
2616 }
2617
tuexendd729232011-11-01 23:04:43 +00002618 if (inp_p) {
t00fcxen60d0dea2013-02-10 20:04:03 +00002619 stcb = sctp_findassociation_addr_sa(src, dst, inp_p, netp,
Michael Tuexen7f202782016-01-28 17:09:30 +01002620 1, vrf_id);
tuexendd729232011-11-01 23:04:43 +00002621 inp = *inp_p;
2622 } else {
t00fcxen60d0dea2013-02-10 20:04:03 +00002623 stcb = sctp_findassociation_addr_sa(src, dst, &inp, netp,
Michael Tuexen7f202782016-01-28 17:09:30 +01002624 1, vrf_id);
tuexendd729232011-11-01 23:04:43 +00002625 }
t00fcxen60d0dea2013-02-10 20:04:03 +00002626 SCTPDBG(SCTP_DEBUG_PCB1, "stcb:%p inp:%p\n", (void *)stcb, (void *)inp);
2627 if (stcb == NULL && inp) {
tuexendd729232011-11-01 23:04:43 +00002628 /* Found a EP but not this address */
2629 if ((ch->chunk_type == SCTP_INITIATION) ||
2630 (ch->chunk_type == SCTP_INITIATION_ACK)) {
2631 /*-
2632 * special hook, we do NOT return linp or an
2633 * association that is linked to an existing
2634 * association that is under the TCP pool (i.e. no
2635 * listener exists). The endpoint finding routine
2636 * will always find a listener before examining the
2637 * TCP pool.
2638 */
2639 if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) {
2640 if (inp_p) {
2641 *inp_p = NULL;
2642 }
2643 return (NULL);
2644 }
t00fcxen60d0dea2013-02-10 20:04:03 +00002645 stcb = sctp_findassociation_special_addr(m,
tuexen664967a2012-06-28 16:24:36 +00002646 offset, sh, &inp, netp, dst);
tuexendd729232011-11-01 23:04:43 +00002647 if (inp_p != NULL) {
2648 *inp_p = inp;
2649 }
2650 }
2651 }
t00fcxen60d0dea2013-02-10 20:04:03 +00002652 SCTPDBG(SCTP_DEBUG_PCB1, "stcb is %p\n", (void *)stcb);
2653 return (stcb);
tuexendd729232011-11-01 23:04:43 +00002654}
2655
2656/*
2657 * lookup an association by an ASCONF lookup address.
2658 * if the lookup address is 0.0.0.0 or ::0, use the vtag to do the lookup
2659 */
2660struct sctp_tcb *
tuexen9784e9a2011-12-18 13:04:23 +00002661sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
tuexen664967a2012-06-28 16:24:36 +00002662 struct sockaddr *dst, struct sctphdr *sh,
2663 struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id)
tuexendd729232011-11-01 23:04:43 +00002664{
2665 struct sctp_tcb *stcb;
t00fcxen05f07c02014-09-07 10:15:26 +00002666 union sctp_sockstore remote_store;
tuexendd729232011-11-01 23:04:43 +00002667 struct sctp_paramhdr parm_buf, *phdr;
2668 int ptype;
2669 int zero_address = 0;
2670#ifdef INET
2671 struct sockaddr_in *sin;
2672#endif
2673#ifdef INET6
tuexendd729232011-11-01 23:04:43 +00002674 struct sockaddr_in6 *sin6;
2675#endif
2676
tuexendd729232011-11-01 23:04:43 +00002677 memset(&remote_store, 0, sizeof(remote_store));
tuexendd729232011-11-01 23:04:43 +00002678 phdr = sctp_get_next_param(m, offset + sizeof(struct sctp_asconf_chunk),
2679 &parm_buf, sizeof(struct sctp_paramhdr));
2680 if (phdr == NULL) {
2681 SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf lookup addr\n",
Saúl Ibarra Corretgé8b04b412015-09-26 09:53:06 +02002682 __func__);
tuexendd729232011-11-01 23:04:43 +00002683 return NULL;
2684 }
2685 ptype = (int)((uint32_t) ntohs(phdr->param_type));
2686 /* get the correlation address */
2687 switch (ptype) {
2688#ifdef INET6
2689 case SCTP_IPV6_ADDRESS:
2690 {
2691 /* ipv6 address param */
2692 struct sctp_ipv6addr_param *p6, p6_buf;
2693
2694 if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv6addr_param)) {
2695 return NULL;
2696 }
2697 p6 = (struct sctp_ipv6addr_param *)sctp_get_next_param(m,
2698 offset + sizeof(struct sctp_asconf_chunk),
2699 &p6_buf.ph, sizeof(*p6));
2700 if (p6 == NULL) {
2701 SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf v6 lookup addr\n",
Saúl Ibarra Corretgé8b04b412015-09-26 09:53:06 +02002702 __func__);
tuexendd729232011-11-01 23:04:43 +00002703 return (NULL);
2704 }
t00fcxen05f07c02014-09-07 10:15:26 +00002705 sin6 = &remote_store.sin6;
tuexendd729232011-11-01 23:04:43 +00002706 sin6->sin6_family = AF_INET6;
t00fcxen8fbaee32012-09-04 16:41:39 +00002707#ifdef HAVE_SIN6_LEN
tuexendd729232011-11-01 23:04:43 +00002708 sin6->sin6_len = sizeof(*sin6);
2709#endif
2710 sin6->sin6_port = sh->src_port;
2711 memcpy(&sin6->sin6_addr, &p6->addr, sizeof(struct in6_addr));
2712 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
2713 zero_address = 1;
2714 break;
2715 }
2716#endif
2717#ifdef INET
2718 case SCTP_IPV4_ADDRESS:
2719 {
2720 /* ipv4 address param */
2721 struct sctp_ipv4addr_param *p4, p4_buf;
2722
2723 if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv4addr_param)) {
2724 return NULL;
2725 }
2726 p4 = (struct sctp_ipv4addr_param *)sctp_get_next_param(m,
2727 offset + sizeof(struct sctp_asconf_chunk),
2728 &p4_buf.ph, sizeof(*p4));
2729 if (p4 == NULL) {
2730 SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf v4 lookup addr\n",
Saúl Ibarra Corretgé8b04b412015-09-26 09:53:06 +02002731 __func__);
tuexendd729232011-11-01 23:04:43 +00002732 return (NULL);
2733 }
t00fcxen05f07c02014-09-07 10:15:26 +00002734 sin = &remote_store.sin;
tuexendd729232011-11-01 23:04:43 +00002735 sin->sin_family = AF_INET;
t00fcxen8fbaee32012-09-04 16:41:39 +00002736#ifdef HAVE_SIN_LEN
tuexendd729232011-11-01 23:04:43 +00002737 sin->sin_len = sizeof(*sin);
2738#endif
2739 sin->sin_port = sh->src_port;
2740 memcpy(&sin->sin_addr, &p4->addr, sizeof(struct in_addr));
2741 if (sin->sin_addr.s_addr == INADDR_ANY)
2742 zero_address = 1;
2743 break;
2744 }
2745#endif
2746 default:
2747 /* invalid address param type */
2748 return NULL;
2749 }
2750
2751 if (zero_address) {
tuexen664967a2012-06-28 16:24:36 +00002752 stcb = sctp_findassoc_by_vtag(NULL, dst, ntohl(sh->v_tag), inp_p,
tuexendd729232011-11-01 23:04:43 +00002753 netp, sh->src_port, sh->dest_port, 1, vrf_id, 0);
tuexenb53ec512012-08-05 10:55:12 +00002754 if (stcb != NULL) {
2755 SCTP_INP_DECR_REF(*inp_p);
2756 }
tuexendd729232011-11-01 23:04:43 +00002757 } else {
2758 stcb = sctp_findassociation_ep_addr(inp_p,
t00fcxen05f07c02014-09-07 10:15:26 +00002759 &remote_store.sa, netp,
tuexen664967a2012-06-28 16:24:36 +00002760 dst, NULL);
tuexendd729232011-11-01 23:04:43 +00002761 }
2762 return (stcb);
2763}
2764
2765
2766/*
2767 * allocate a sctp_inpcb and setup a temporary binding to a port/all
2768 * addresses. This way if we don't get a bind we by default pick a ephemeral
2769 * port with all addresses bound.
2770 */
2771int
2772sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
2773{
2774 /*
2775 * we get called when a new endpoint starts up. We need to allocate
2776 * the sctp_inpcb structure from the zone and init it. Mark it as
2777 * unbound and find a port that we can use as an ephemeral with
2778 * INADDR_ANY. If the user binds later no problem we can then add in
2779 * the specific addresses. And setup the default parameters for the
2780 * EP.
2781 */
2782 int i, error;
2783 struct sctp_inpcb *inp;
2784 struct sctp_pcb *m;
2785 struct timeval time;
2786 sctp_sharedkey_t *null_key;
2787
2788 error = 0;
2789
2790 SCTP_INP_INFO_WLOCK();
2791 inp = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_ep), struct sctp_inpcb);
2792 if (inp == NULL) {
2793 SCTP_PRINTF("Out of SCTP-INPCB structures - no resources\n");
2794 SCTP_INP_INFO_WUNLOCK();
2795 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
2796 return (ENOBUFS);
2797 }
2798 /* zap it */
2799 bzero(inp, sizeof(*inp));
2800
2801 /* bump generations */
2802#if defined(__APPLE__)
2803 inp->ip_inp.inp.inp_state = INPCB_STATE_INUSE;
2804#endif
2805 /* setup socket pointers */
2806 inp->sctp_socket = so;
2807 inp->ip_inp.inp.inp_socket = so;
t00fcxen326aa4b2014-06-20 13:42:13 +00002808#if defined(__FreeBSD__)
2809 inp->ip_inp.inp.inp_cred = crhold(so->so_cred);
2810#endif
tuexenc0bb6122012-01-15 14:21:21 +00002811#ifdef INET6
tuexen76eb2092012-04-01 16:35:28 +00002812#if !defined(__Userspace__) && !defined(__Windows__)
t00fcxenafd21192013-05-10 18:15:02 +00002813 if (INP_SOCKAF(so) == AF_INET6) {
2814 if (MODULE_GLOBAL(ip6_auto_flowlabel)) {
2815 inp->ip_inp.inp.inp_flags |= IN6P_AUTOFLOWLABEL;
2816 }
2817 if (MODULE_GLOBAL(ip6_v6only)) {
2818 inp->ip_inp.inp.inp_flags |= IN6P_IPV6_V6ONLY;
2819 }
tuexendd729232011-11-01 23:04:43 +00002820 }
2821#endif
tuexenc0bb6122012-01-15 14:21:21 +00002822#endif
tuexendd729232011-11-01 23:04:43 +00002823 inp->sctp_associd_counter = 1;
2824 inp->partial_delivery_point = SCTP_SB_LIMIT_RCV(so) >> SCTP_PARTIAL_DELIVERY_SHIFT;
2825 inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT;
t00fcxen3eda0f22015-03-10 20:10:45 +00002826 inp->max_cwnd = 0;
tuexendd729232011-11-01 23:04:43 +00002827 inp->sctp_cmt_on_off = SCTP_BASE_SYSCTL(sctp_cmt_on_off);
t00fcxen478b7722014-08-02 18:24:12 +00002828 inp->ecn_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_ecn_enable);
t00fcxen0e78cef2014-08-02 22:05:33 +00002829 inp->prsctp_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pr_enable);
t00fcxenb3969a12014-08-12 13:19:21 +00002830 inp->auth_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_auth_enable);
t00fcxenaac0f452014-08-12 12:51:45 +00002831 inp->asconf_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_asconf_enable);
t00fcxenfa7e1a02014-08-04 20:41:36 +00002832 inp->reconfig_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_reconfig_enable);
t00fcxen3656cf92014-08-03 15:25:02 +00002833 inp->nrsack_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_nrsack_enable);
t00fcxen1cc0ba82014-08-03 20:32:08 +00002834 inp->pktdrop_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pktdrop_enable);
Michael Tuexene5001952016-04-17 19:25:27 +02002835 inp->idata_supported = 0;
2836
t00fcxena51e4462015-06-17 15:53:23 +00002837#if defined(__FreeBSD__)
2838 inp->fibnum = so->so_fibnum;
2839#else
2840 inp->fibnum = 0;
2841#endif
tuexen09631162012-04-18 11:23:02 +00002842#if defined(__Userspace__)
tuexeneda9dbb2012-05-27 11:10:08 +00002843 inp->ulp_info = NULL;
tuexen09631162012-04-18 11:23:02 +00002844 inp->recv_callback = NULL;
2845 inp->send_callback = NULL;
2846 inp->send_sb_threshold = 0;
tuexen09631162012-04-18 11:23:02 +00002847#endif
tuexendd729232011-11-01 23:04:43 +00002848 /* init the small hash table we use to track asocid <-> tcb */
2849 inp->sctp_asocidhash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, &inp->hashasocidmark);
2850 if (inp->sctp_asocidhash == NULL) {
t00fcxen326aa4b2014-06-20 13:42:13 +00002851#if defined(__FreeBSD__)
2852 crfree(inp->ip_inp.inp.inp_cred);
2853#endif
tuexendd729232011-11-01 23:04:43 +00002854 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
2855 SCTP_INP_INFO_WUNLOCK();
2856 return (ENOBUFS);
2857 }
2858#ifdef IPSEC
2859#if !(defined(__APPLE__))
Michael Tuexen372872e2015-11-21 19:25:27 +01002860 error = ipsec_init_policy(so, &inp->ip_inp.inp.inp_sp);
tuexendd729232011-11-01 23:04:43 +00002861#else
tuexendd729232011-11-01 23:04:43 +00002862 error = 0;
2863#endif
2864 if (error != 0) {
t00fcxen326aa4b2014-06-20 13:42:13 +00002865#if defined(__FreeBSD__)
2866 crfree(inp->ip_inp.inp.inp_cred);
2867#endif
tuexendd729232011-11-01 23:04:43 +00002868 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
2869 SCTP_INP_INFO_WUNLOCK();
2870 return error;
2871 }
2872#endif /* IPSEC */
2873 SCTP_INCR_EP_COUNT();
tuexendd729232011-11-01 23:04:43 +00002874 inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
tuexendd729232011-11-01 23:04:43 +00002875 SCTP_INP_INFO_WUNLOCK();
2876
2877 so->so_pcb = (caddr_t)inp;
2878
tuexen5fc22842012-02-11 13:32:19 +00002879#if defined(__FreeBSD__) && __FreeBSD_version < 803000
tuexendd729232011-11-01 23:04:43 +00002880 if ((SCTP_SO_TYPE(so) == SOCK_DGRAM) ||
2881 (SCTP_SO_TYPE(so) == SOCK_SEQPACKET)) {
2882#else
2883 if (SCTP_SO_TYPE(so) == SOCK_SEQPACKET) {
2884#endif
2885 /* UDP style socket */
2886 inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |
2887 SCTP_PCB_FLAGS_UNBOUND);
2888 /* Be sure it is NON-BLOCKING IO for UDP */
2889 /* SCTP_SET_SO_NBIO(so); */
2890 } else if (SCTP_SO_TYPE(so) == SOCK_STREAM) {
2891 /* TCP style socket */
2892 inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE |
2893 SCTP_PCB_FLAGS_UNBOUND);
2894 /* Be sure we have blocking IO by default */
2895 SCTP_CLEAR_SO_NBIO(so);
2896#if defined(__Panda__)
2897 } else if (SCTP_SO_TYPE(so) == SOCK_FASTSEQPACKET) {
2898 inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |
2899 SCTP_PCB_FLAGS_UNBOUND);
2900 sctp_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE);
2901 } else if (SCTP_SO_TYPE(so) == SOCK_FASTSTREAM) {
2902 inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE |
2903 SCTP_PCB_FLAGS_UNBOUND);
2904 sctp_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE);
2905#endif
2906 } else {
2907 /*
2908 * unsupported socket type (RAW, etc)- in case we missed it
2909 * in protosw
2910 */
2911 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EOPNOTSUPP);
2912 so->so_pcb = NULL;
t00fcxen326aa4b2014-06-20 13:42:13 +00002913#if defined(__FreeBSD__)
2914 crfree(inp->ip_inp.inp.inp_cred);
Michael Tuexen372872e2015-11-21 19:25:27 +01002915#ifdef IPSEC
2916 ipsec_delete_pcbpolicy(&inp->ip_inp.inp);
2917#endif
t00fcxen326aa4b2014-06-20 13:42:13 +00002918#endif
tuexendd729232011-11-01 23:04:43 +00002919 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
2920 return (EOPNOTSUPP);
2921 }
2922 if (SCTP_BASE_SYSCTL(sctp_default_frag_interleave) == SCTP_FRAG_LEVEL_1) {
2923 sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
2924 sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
2925 } else if (SCTP_BASE_SYSCTL(sctp_default_frag_interleave) == SCTP_FRAG_LEVEL_2) {
2926 sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
2927 sctp_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
2928 } else if (SCTP_BASE_SYSCTL(sctp_default_frag_interleave) == SCTP_FRAG_LEVEL_0) {
2929 sctp_feature_off(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
2930 sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
2931 }
2932 inp->sctp_tcbhash = SCTP_HASH_INIT(SCTP_BASE_SYSCTL(sctp_pcbtblsize),
2933 &inp->sctp_hashmark);
2934 if (inp->sctp_tcbhash == NULL) {
2935 SCTP_PRINTF("Out of SCTP-INPCB->hashinit - no resources\n");
2936 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
2937 so->so_pcb = NULL;
t00fcxen326aa4b2014-06-20 13:42:13 +00002938#if defined(__FreeBSD__)
2939 crfree(inp->ip_inp.inp.inp_cred);
Michael Tuexen372872e2015-11-21 19:25:27 +01002940#ifdef IPSEC
2941 ipsec_delete_pcbpolicy(&inp->ip_inp.inp);
2942#endif
t00fcxen326aa4b2014-06-20 13:42:13 +00002943#endif
tuexendd729232011-11-01 23:04:43 +00002944 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
2945 return (ENOBUFS);
2946 }
2947#ifdef SCTP_MVRF
2948 inp->vrf_size = SCTP_DEFAULT_VRF_SIZE;
2949 SCTP_MALLOC(inp->m_vrf_ids, uint32_t *,
2950 (sizeof(uint32_t) * inp->vrf_size), SCTP_M_MVRF);
2951 if (inp->m_vrf_ids == NULL) {
2952 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
2953 so->so_pcb = NULL;
2954 SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark);
t00fcxen326aa4b2014-06-20 13:42:13 +00002955#if defined(__FreeBSD__)
2956 crfree(inp->ip_inp.inp.inp_cred);
Michael Tuexen372872e2015-11-21 19:25:27 +01002957#ifdef IPSEC
2958 ipsec_delete_pcbpolicy(&inp->ip_inp.inp);
2959#endif
t00fcxen326aa4b2014-06-20 13:42:13 +00002960#endif
tuexendd729232011-11-01 23:04:43 +00002961 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
2962 return (ENOBUFS);
2963 }
2964 inp->m_vrf_ids[0] = vrf_id;
2965 inp->num_vrfs = 1;
2966#endif
2967 inp->def_vrf_id = vrf_id;
2968
2969#if defined(__APPLE__)
tuexen9a218b12012-08-04 21:17:58 +00002970#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
t00fcxenbc766ab2014-01-03 19:29:31 +00002971 inp->ip_inp.inp.inpcb_mtx = lck_mtx_alloc_init(SCTP_BASE_INFO(sctbinfo).mtx_grp, SCTP_BASE_INFO(sctbinfo).mtx_attr);
tuexendd729232011-11-01 23:04:43 +00002972 if (inp->ip_inp.inp.inpcb_mtx == NULL) {
t00fcxen8fca7ff2012-09-05 18:58:42 +00002973 SCTP_PRINTF("in_pcballoc: can't alloc mutex! so=%p\n", (void *)so);
tuexendd729232011-11-01 23:04:43 +00002974#ifdef SCTP_MVRF
2975 SCTP_FREE(inp->m_vrf_ids, SCTP_M_MVRF);
2976#endif
2977 SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark);
2978 so->so_pcb = NULL;
t00fcxen326aa4b2014-06-20 13:42:13 +00002979#if defined(__FreeBSD__)
2980 crfree(inp->ip_inp.inp.inp_cred);
Michael Tuexen372872e2015-11-21 19:25:27 +01002981#ifdef IPSEC
2982 ipsec_delete_pcbpolicy(&inp->ip_inp.inp);
2983#endif
t00fcxen326aa4b2014-06-20 13:42:13 +00002984#endif
tuexendd729232011-11-01 23:04:43 +00002985 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
t00fcxenbc766ab2014-01-03 19:29:31 +00002986 SCTP_UNLOCK_EXC(SCTP_BASE_INFO(sctbinfo).ipi_lock);
tuexendd729232011-11-01 23:04:43 +00002987 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOMEM);
2988 return (ENOMEM);
2989 }
t00fcxenbc766ab2014-01-03 19:29:31 +00002990#elif defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
2991 lck_mtx_init(&inp->ip_inp.inp.inpcb_mtx, SCTP_BASE_INFO(sctbinfo).mtx_grp, SCTP_BASE_INFO(sctbinfo).mtx_attr);
tuexen9a218b12012-08-04 21:17:58 +00002992#else
t00fcxenbc766ab2014-01-03 19:29:31 +00002993 lck_mtx_init(&inp->ip_inp.inp.inpcb_mtx, SCTP_BASE_INFO(sctbinfo).ipi_lock_grp, SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
tuexendd729232011-11-01 23:04:43 +00002994#endif
2995#endif
2996 SCTP_INP_INFO_WLOCK();
2997 SCTP_INP_LOCK_INIT(inp);
2998#if defined(__FreeBSD__)
2999 INP_LOCK_INIT(&inp->ip_inp.inp, "inp", "sctpinp");
3000#endif
3001 SCTP_INP_READ_INIT(inp);
3002 SCTP_ASOC_CREATE_LOCK_INIT(inp);
3003 /* lock the new ep */
3004 SCTP_INP_WLOCK(inp);
3005
3006 /* add it to the info area */
3007 LIST_INSERT_HEAD(&SCTP_BASE_INFO(listhead), inp, sctp_list);
3008#if defined(__APPLE__)
t00fcxenbc766ab2014-01-03 19:29:31 +00003009 inp->ip_inp.inp.inp_pcbinfo = &SCTP_BASE_INFO(sctbinfo);
3010#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
3011 LIST_INSERT_HEAD(SCTP_BASE_INFO(sctbinfo).listhead, &inp->ip_inp.inp, inp_list);
3012#else
3013 LIST_INSERT_HEAD(SCTP_BASE_INFO(sctbinfo).ipi_listhead, &inp->ip_inp.inp, inp_list);
3014#endif
tuexendd729232011-11-01 23:04:43 +00003015#endif
3016 SCTP_INP_INFO_WUNLOCK();
3017
3018 TAILQ_INIT(&inp->read_queue);
3019 LIST_INIT(&inp->sctp_addr_list);
3020
3021 LIST_INIT(&inp->sctp_asoc_list);
3022
3023#ifdef SCTP_TRACK_FREED_ASOCS
3024 /* TEMP CODE */
3025 LIST_INIT(&inp->sctp_asoc_free_list);
3026#endif
3027 /* Init the timer structure for signature change */
3028 SCTP_OS_TIMER_INIT(&inp->sctp_ep.signature_change.timer);
3029 inp->sctp_ep.signature_change.type = SCTP_TIMER_TYPE_NEWCOOKIE;
3030
3031 /* now init the actual endpoint default data */
3032 m = &inp->sctp_ep;
3033
3034 /* setup the base timeout information */
3035 m->sctp_timeoutticks[SCTP_TIMER_SEND] = SEC_TO_TICKS(SCTP_SEND_SEC); /* needed ? */
3036 m->sctp_timeoutticks[SCTP_TIMER_INIT] = SEC_TO_TICKS(SCTP_INIT_SEC); /* needed ? */
3037 m->sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_delayed_sack_time_default));
3038 m->sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_heartbeat_interval_default));
3039 m->sctp_timeoutticks[SCTP_TIMER_PMTU] = SEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_pmtu_raise_time_default));
3040 m->sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] = SEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_shutdown_guard_time_default));
3041 m->sctp_timeoutticks[SCTP_TIMER_SIGNATURE] = SEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_secret_lifetime_default));
3042 /* all max/min max are in ms */
3043 m->sctp_maxrto = SCTP_BASE_SYSCTL(sctp_rto_max_default);
3044 m->sctp_minrto = SCTP_BASE_SYSCTL(sctp_rto_min_default);
3045 m->initial_rto = SCTP_BASE_SYSCTL(sctp_rto_initial_default);
3046 m->initial_init_rto_max = SCTP_BASE_SYSCTL(sctp_init_rto_max_default);
3047 m->sctp_sack_freq = SCTP_BASE_SYSCTL(sctp_sack_freq_default);
tuexendd729232011-11-01 23:04:43 +00003048 m->max_init_times = SCTP_BASE_SYSCTL(sctp_init_rtx_max_default);
3049 m->max_send_times = SCTP_BASE_SYSCTL(sctp_assoc_rtx_max_default);
3050 m->def_net_failure = SCTP_BASE_SYSCTL(sctp_path_rtx_max_default);
3051 m->def_net_pf_threshold = SCTP_BASE_SYSCTL(sctp_path_pf_threshold);
3052 m->sctp_sws_sender = SCTP_SWS_SENDER_DEF;
3053 m->sctp_sws_receiver = SCTP_SWS_RECEIVER_DEF;
3054 m->max_burst = SCTP_BASE_SYSCTL(sctp_max_burst_default);
3055 m->fr_max_burst = SCTP_BASE_SYSCTL(sctp_fr_max_burst_default);
3056
3057 m->sctp_default_cc_module = SCTP_BASE_SYSCTL(sctp_default_cc_module);
3058 m->sctp_default_ss_module = SCTP_BASE_SYSCTL(sctp_default_ss_module);
t00fcxenc45180a2013-07-05 10:17:17 +00003059 m->max_open_streams_intome = SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default);
tuexendd729232011-11-01 23:04:43 +00003060 /* number of streams to pre-open on a association */
3061 m->pre_open_stream_count = SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default);
3062
3063 /* Add adaptation cookie */
t00fcxen36377202013-02-11 21:07:33 +00003064 m->adaptation_layer_indicator = 0;
3065 m->adaptation_layer_indicator_provided = 0;
tuexendd729232011-11-01 23:04:43 +00003066
3067 /* seed random number generator */
3068 m->random_counter = 1;
3069 m->store_at = SCTP_SIGNATURE_SIZE;
3070 SCTP_READ_RANDOM(m->random_numbers, sizeof(m->random_numbers));
3071 sctp_fill_random_store(m);
3072
3073 /* Minimum cookie size */
3074 m->size_of_a_cookie = (sizeof(struct sctp_init_msg) * 2) +
3075 sizeof(struct sctp_state_cookie);
3076 m->size_of_a_cookie += SCTP_SIGNATURE_SIZE;
3077
3078 /* Setup the initial secret */
3079 (void)SCTP_GETTIME_TIMEVAL(&time);
3080 m->time_of_secret_change = time.tv_sec;
3081
3082 for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) {
3083 m->secret_key[0][i] = sctp_select_initial_TSN(m);
3084 }
3085 sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL);
3086
3087 /* How long is a cookie good for ? */
3088 m->def_cookie_life = MSEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_valid_cookie_life_default));
3089 /*
3090 * Initialize authentication parameters
3091 */
3092 m->local_hmacs = sctp_default_supported_hmaclist();
3093 m->local_auth_chunks = sctp_alloc_chunklist();
t00fcxenaac0f452014-08-12 12:51:45 +00003094 if (inp->asconf_supported) {
3095 sctp_auth_add_chunk(SCTP_ASCONF, m->local_auth_chunks);
3096 sctp_auth_add_chunk(SCTP_ASCONF_ACK, m->local_auth_chunks);
3097 }
tuexendd729232011-11-01 23:04:43 +00003098 m->default_dscp = 0;
3099#ifdef INET6
3100 m->default_flowlabel = 0;
3101#endif
tuexen9d7b2072011-11-20 16:35:17 +00003102 m->port = 0; /* encapsulation disabled by default */
tuexendd729232011-11-01 23:04:43 +00003103 LIST_INIT(&m->shared_keys);
3104 /* add default NULL key as key id 0 */
3105 null_key = sctp_alloc_sharedkey();
3106 sctp_insert_sharedkey(&m->shared_keys, null_key);
3107 SCTP_INP_WUNLOCK(inp);
3108#ifdef SCTP_LOG_CLOSING
3109 sctp_log_closing(inp, NULL, 12);
3110#endif
3111 return (error);
3112}
3113
3114
3115void
3116sctp_move_pcb_and_assoc(struct sctp_inpcb *old_inp, struct sctp_inpcb *new_inp,
3117 struct sctp_tcb *stcb)
3118{
3119 struct sctp_nets *net;
3120 uint16_t lport, rport;
3121 struct sctppcbhead *head;
3122 struct sctp_laddr *laddr, *oladdr;
3123
3124 atomic_add_int(&stcb->asoc.refcnt, 1);
3125 SCTP_TCB_UNLOCK(stcb);
3126 SCTP_INP_INFO_WLOCK();
3127 SCTP_INP_WLOCK(old_inp);
3128 SCTP_INP_WLOCK(new_inp);
3129 SCTP_TCB_LOCK(stcb);
3130 atomic_subtract_int(&stcb->asoc.refcnt, 1);
3131
3132 new_inp->sctp_ep.time_of_secret_change =
3133 old_inp->sctp_ep.time_of_secret_change;
3134 memcpy(new_inp->sctp_ep.secret_key, old_inp->sctp_ep.secret_key,
3135 sizeof(old_inp->sctp_ep.secret_key));
3136 new_inp->sctp_ep.current_secret_number =
3137 old_inp->sctp_ep.current_secret_number;
3138 new_inp->sctp_ep.last_secret_number =
3139 old_inp->sctp_ep.last_secret_number;
3140 new_inp->sctp_ep.size_of_a_cookie = old_inp->sctp_ep.size_of_a_cookie;
3141
3142 /* make it so new data pours into the new socket */
3143 stcb->sctp_socket = new_inp->sctp_socket;
3144 stcb->sctp_ep = new_inp;
3145
3146 /* Copy the port across */
3147 lport = new_inp->sctp_lport = old_inp->sctp_lport;
3148 rport = stcb->rport;
3149 /* Pull the tcb from the old association */
3150 LIST_REMOVE(stcb, sctp_tcbhash);
3151 LIST_REMOVE(stcb, sctp_tcblist);
3152 if (stcb->asoc.in_asocid_hash) {
3153 LIST_REMOVE(stcb, sctp_tcbasocidhash);
3154 }
3155 /* Now insert the new_inp into the TCP connected hash */
3156 head = &SCTP_BASE_INFO(sctp_tcpephash)[SCTP_PCBHASH_ALLADDR((lport | rport), SCTP_BASE_INFO(hashtcpmark))];
3157
3158 LIST_INSERT_HEAD(head, new_inp, sctp_hash);
3159 /* Its safe to access */
3160 new_inp->sctp_flags &= ~SCTP_PCB_FLAGS_UNBOUND;
3161
3162 /* Now move the tcb into the endpoint list */
3163 LIST_INSERT_HEAD(&new_inp->sctp_asoc_list, stcb, sctp_tcblist);
3164 /*
3165 * Question, do we even need to worry about the ep-hash since we
3166 * only have one connection? Probably not :> so lets get rid of it
3167 * and not suck up any kernel memory in that.
3168 */
3169 if (stcb->asoc.in_asocid_hash) {
3170 struct sctpasochead *lhd;
3171 lhd = &new_inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(stcb->asoc.assoc_id,
3172 new_inp->hashasocidmark)];
3173 LIST_INSERT_HEAD(lhd, stcb, sctp_tcbasocidhash);
3174 }
3175 /* Ok. Let's restart timer. */
3176 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
3177 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, new_inp,
3178 stcb, net);
3179 }
3180
3181 SCTP_INP_INFO_WUNLOCK();
3182 if (new_inp->sctp_tcbhash != NULL) {
3183 SCTP_HASH_FREE(new_inp->sctp_tcbhash, new_inp->sctp_hashmark);
3184 new_inp->sctp_tcbhash = NULL;
3185 }
3186 if ((new_inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
3187 /* Subset bound, so copy in the laddr list from the old_inp */
3188 LIST_FOREACH(oladdr, &old_inp->sctp_addr_list, sctp_nxt_addr) {
3189 laddr = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
3190 if (laddr == NULL) {
3191 /*
3192 * Gak, what can we do? This assoc is really
3193 * HOSED. We probably should send an abort
3194 * here.
3195 */
3196 SCTPDBG(SCTP_DEBUG_PCB1, "Association hosed in TCP model, out of laddr memory\n");
3197 continue;
3198 }
3199 SCTP_INCR_LADDR_COUNT();
3200 bzero(laddr, sizeof(*laddr));
3201 (void)SCTP_GETTIME_TIMEVAL(&laddr->start_time);
3202 laddr->ifa = oladdr->ifa;
3203 atomic_add_int(&laddr->ifa->refcount, 1);
3204 LIST_INSERT_HEAD(&new_inp->sctp_addr_list, laddr,
3205 sctp_nxt_addr);
3206 new_inp->laddr_count++;
3207 if (oladdr == stcb->asoc.last_used_address) {
3208 stcb->asoc.last_used_address = laddr;
3209 }
3210 }
3211 }
3212 /* Now any running timers need to be adjusted
3213 * since we really don't care if they are running
3214 * or not just blast in the new_inp into all of
3215 * them.
3216 */
3217
3218 stcb->asoc.dack_timer.ep = (void *)new_inp;
3219 stcb->asoc.asconf_timer.ep = (void *)new_inp;
3220 stcb->asoc.strreset_timer.ep = (void *)new_inp;
3221 stcb->asoc.shut_guard_timer.ep = (void *)new_inp;
3222 stcb->asoc.autoclose_timer.ep = (void *)new_inp;
3223 stcb->asoc.delayed_event_timer.ep = (void *)new_inp;
3224 stcb->asoc.delete_prim_timer.ep = (void *)new_inp;
3225 /* now what about the nets? */
3226 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
3227 net->pmtu_timer.ep = (void *)new_inp;
3228 net->hb_timer.ep = (void *)new_inp;
3229 net->rxt_timer.ep = (void *)new_inp;
3230 }
3231 SCTP_INP_WUNLOCK(new_inp);
3232 SCTP_INP_WUNLOCK(old_inp);
3233}
3234
Michael Tuexen71a83fb2016-02-16 21:52:58 +01003235/*
3236 * insert an laddr entry with the given ifa for the desired list
3237 */
3238static int
3239sctp_insert_laddr(struct sctpladdr *list, struct sctp_ifa *ifa, uint32_t act)
3240{
3241 struct sctp_laddr *laddr;
3242
3243 laddr = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
3244 if (laddr == NULL) {
3245 /* out of memory? */
3246 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
3247 return (EINVAL);
3248 }
3249 SCTP_INCR_LADDR_COUNT();
3250 bzero(laddr, sizeof(*laddr));
3251 (void)SCTP_GETTIME_TIMEVAL(&laddr->start_time);
3252 laddr->ifa = ifa;
3253 laddr->action = act;
3254 atomic_add_int(&ifa->refcount, 1);
3255 /* insert it */
3256 LIST_INSERT_HEAD(list, laddr, sctp_nxt_addr);
3257
3258 return (0);
3259}
3260
3261/*
3262 * Remove an laddr entry from the local address list (on an assoc)
3263 */
3264static void
3265sctp_remove_laddr(struct sctp_laddr *laddr)
3266{
3267
3268 /* remove from the list */
3269 LIST_REMOVE(laddr, sctp_nxt_addr);
3270 sctp_free_ifa(laddr->ifa);
3271 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), laddr);
3272 SCTP_DECR_LADDR_COUNT();
3273}
tuexendd729232011-11-01 23:04:43 +00003274
3275#if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__))
3276/*
3277 * Don't know why, but without this there is an unknown reference when
3278 * compiling NetBSD... hmm
3279 */
3280extern void in6_sin6_2_sin(struct sockaddr_in *, struct sockaddr_in6 *sin6);
3281#endif
3282
3283
3284/* sctp_ifap is used to bypass normal local address validation checks */
3285int
3286#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
3287sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
t00fcxenc24796c2014-05-06 15:39:13 +00003288 struct sctp_ifa *sctp_ifap, struct thread *p)
tuexendd729232011-11-01 23:04:43 +00003289#elif defined(__Windows__)
3290sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
t00fcxenc24796c2014-05-06 15:39:13 +00003291 struct sctp_ifa *sctp_ifap, PKTHREAD p)
tuexendd729232011-11-01 23:04:43 +00003292#else
3293sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
t00fcxenc24796c2014-05-06 15:39:13 +00003294 struct sctp_ifa *sctp_ifap, struct proc *p)
tuexendd729232011-11-01 23:04:43 +00003295#endif
3296{
3297 /* bind a ep to a socket address */
3298 struct sctppcbhead *head;
3299 struct sctp_inpcb *inp, *inp_tmp;
t00fcxen8dc82e82013-11-02 19:15:33 +00003300#if defined(INET) || (defined(INET6) && defined(__APPLE__)) || defined(__FreeBSD__) || defined(__APPLE__)
tuexendd729232011-11-01 23:04:43 +00003301 struct inpcb *ip_inp;
t00fcxenaff14b62013-11-02 18:02:02 +00003302#endif
tuexendd729232011-11-01 23:04:43 +00003303 int port_reuse_active = 0;
3304 int bindall;
3305#ifdef SCTP_MVRF
3306 int i;
3307#endif
3308 uint16_t lport;
3309 int error;
3310 uint32_t vrf_id;
3311
3312 lport = 0;
tuexendd729232011-11-01 23:04:43 +00003313 bindall = 1;
3314 inp = (struct sctp_inpcb *)so->so_pcb;
t00fcxen8dc82e82013-11-02 19:15:33 +00003315#if defined(INET) || (defined(INET6) && defined(__APPLE__)) || defined(__FreeBSD__) || defined(__APPLE__)
tuexendd729232011-11-01 23:04:43 +00003316 ip_inp = (struct inpcb *)so->so_pcb;
t00fcxenaff14b62013-11-02 18:02:02 +00003317#endif
tuexendd729232011-11-01 23:04:43 +00003318#ifdef SCTP_DEBUG
3319 if (addr) {
t00fcxen94dfd1e2012-12-27 08:14:10 +00003320 SCTPDBG(SCTP_DEBUG_PCB1, "Bind called port: %d\n",
tuexendd729232011-11-01 23:04:43 +00003321 ntohs(((struct sockaddr_in *)addr)->sin_port));
t00fcxen94dfd1e2012-12-27 08:14:10 +00003322 SCTPDBG(SCTP_DEBUG_PCB1, "Addr: ");
tuexendd729232011-11-01 23:04:43 +00003323 SCTPDBG_ADDR(SCTP_DEBUG_PCB1, addr);
3324 }
3325#endif
3326 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) {
3327 /* already did a bind, subsequent binds NOT allowed ! */
3328 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
3329 return (EINVAL);
3330 }
3331#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
3332#ifdef INVARIANTS
3333 if (p == NULL)
3334 panic("null proc/thread");
3335#endif
3336#endif
3337 if (addr != NULL) {
3338 switch (addr->sa_family) {
3339#ifdef INET
3340 case AF_INET:
3341 {
3342 struct sockaddr_in *sin;
3343
3344 /* IPV6_V6ONLY socket? */
3345 if (SCTP_IPV6_V6ONLY(ip_inp)) {
3346 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
3347 return (EINVAL);
3348 }
t00fcxena8a26f62012-09-12 19:24:54 +00003349#ifdef HAVE_SA_LEN
tuexendd729232011-11-01 23:04:43 +00003350 if (addr->sa_len != sizeof(*sin)) {
3351 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
3352 return (EINVAL);
3353 }
3354#endif
3355
3356 sin = (struct sockaddr_in *)addr;
3357 lport = sin->sin_port;
3358#if defined(__FreeBSD__) && __FreeBSD_version >= 800000
t00fcxenc24796c2014-05-06 15:39:13 +00003359 /*
3360 * For LOOPBACK the prison_local_ip4() call will transmute the ip address
3361 * to the proper value.
3362 */
3363 if (p && (error = prison_local_ip4(p->td_ucred, &sin->sin_addr)) != 0) {
3364 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
3365 return (error);
3366 }
tuexendd729232011-11-01 23:04:43 +00003367#endif
3368 if (sin->sin_addr.s_addr != INADDR_ANY) {
3369 bindall = 0;
3370 }
3371 break;
3372 }
3373#endif
3374#ifdef INET6
3375 case AF_INET6:
3376 {
3377 /* Only for pure IPv6 Address. (No IPv4 Mapped!) */
3378 struct sockaddr_in6 *sin6;
3379
3380 sin6 = (struct sockaddr_in6 *)addr;
3381
t00fcxena8a26f62012-09-12 19:24:54 +00003382#ifdef HAVE_SA_LEN
tuexendd729232011-11-01 23:04:43 +00003383 if (addr->sa_len != sizeof(*sin6)) {
3384 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
3385 return (EINVAL);
3386 }
3387#endif
tuexendd729232011-11-01 23:04:43 +00003388 lport = sin6->sin6_port;
3389#if defined(__FreeBSD__) && __FreeBSD_version >= 800000
t00fcxenc24796c2014-05-06 15:39:13 +00003390 /*
3391 * For LOOPBACK the prison_local_ip6() call will transmute the ipv6 address
3392 * to the proper value.
3393 */
3394 if (p && (error = prison_local_ip6(p->td_ucred, &sin6->sin6_addr,
3395 (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
3396 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
3397 return (error);
3398 }
tuexendd729232011-11-01 23:04:43 +00003399#endif
3400 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
3401 bindall = 0;
3402#ifdef SCTP_EMBEDDED_V6_SCOPE
3403 /* KAME hack: embed scopeid */
3404#if defined(SCTP_KAME)
3405 if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
3406 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
3407 return (EINVAL);
3408 }
tuexene3851592012-06-01 08:31:45 +00003409#elif defined(__APPLE__)
tuexen9a218b12012-08-04 21:17:58 +00003410#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
3411 if (in6_embedscope(&sin6->sin6_addr, sin6, ip_inp, NULL) != 0) {
tuexendd729232011-11-01 23:04:43 +00003412#else
tuexen9a218b12012-08-04 21:17:58 +00003413 if (in6_embedscope(&sin6->sin6_addr, sin6, ip_inp, NULL, NULL) != 0) {
tuexendd729232011-11-01 23:04:43 +00003414#endif
3415 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
3416 return (EINVAL);
3417 }
3418#elif defined(__FreeBSD__)
3419 error = scope6_check_id(sin6, MODULE_GLOBAL(ip6_use_defzone));
3420 if (error != 0) {
3421 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
3422 return (error);
3423 }
tuexendd729232011-11-01 23:04:43 +00003424#else
3425 if (in6_embedscope(&sin6->sin6_addr, sin6) != 0) {
3426 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
3427 return (EINVAL);
3428 }
3429#endif
3430#endif /* SCTP_EMBEDDED_V6_SCOPE */
3431 }
3432#ifndef SCOPEDROUTING
3433 /* this must be cleared for ifa_ifwithaddr() */
3434 sin6->sin6_scope_id = 0;
3435#endif /* SCOPEDROUTING */
3436 break;
3437 }
3438#endif
tuexen09a676e2012-07-08 21:03:18 +00003439#if defined(__Userspace__)
3440 case AF_CONN:
3441 {
3442 struct sockaddr_conn *sconn;
t00fcxenefb47e72012-09-09 08:16:51 +00003443
t00fcxena8a26f62012-09-12 19:24:54 +00003444#ifdef HAVE_SA_LEN
tuexen09a676e2012-07-08 21:03:18 +00003445 if (addr->sa_len != sizeof(struct sockaddr_conn)) {
3446 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
3447 return (EINVAL);
3448 }
3449#endif
3450 sconn = (struct sockaddr_conn *)addr;
3451 lport = sconn->sconn_port;
3452 if (sconn->sconn_addr != NULL) {
3453 bindall = 0;
3454 }
3455 break;
3456 }
3457#endif
tuexendd729232011-11-01 23:04:43 +00003458 default:
3459 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EAFNOSUPPORT);
3460 return (EAFNOSUPPORT);
3461 }
3462 }
3463 SCTP_INP_INFO_WLOCK();
3464 SCTP_INP_WLOCK(inp);
3465 /* Setup a vrf_id to be the default for the non-bind-all case. */
t00fcxenc24796c2014-05-06 15:39:13 +00003466 vrf_id = inp->def_vrf_id;
tuexendd729232011-11-01 23:04:43 +00003467
3468 /* increase our count due to the unlock we do */
3469 SCTP_INP_INCR_REF(inp);
3470 if (lport) {
3471 /*
t00fcxenefb47e72012-09-09 08:16:51 +00003472 * Did the caller specify a port? if so we must see if an ep
tuexendd729232011-11-01 23:04:43 +00003473 * already has this one bound.
3474 */
3475 /* got to be root to get at low ports */
3476#if !defined(__Windows__)
3477 if (ntohs(lport) < IPPORT_RESERVED) {
3478 if (p && (error =
3479#ifdef __FreeBSD__
3480#if __FreeBSD_version > 602000
3481 priv_check(p, PRIV_NETINET_RESERVEDPORT)
3482#elif __FreeBSD_version >= 500000
3483 suser_cred(p->td_ucred, 0)
3484#else
3485 suser(p)
3486#endif
3487#elif defined(__APPLE__)
3488 suser(p->p_ucred, &p->p_acflag)
3489#elif defined(__Userspace__) /* must be true to use raw socket */
t00fcxenc24796c2014-05-06 15:39:13 +00003490 1
tuexendd729232011-11-01 23:04:43 +00003491#else
3492 suser(p, 0)
3493#endif
3494 )) {
3495 SCTP_INP_DECR_REF(inp);
3496 SCTP_INP_WUNLOCK(inp);
3497 SCTP_INP_INFO_WUNLOCK();
3498 return (error);
3499 }
3500#if defined(__Panda__)
3501 if (!SCTP_IS_PRIVILEDGED(so)) {
3502 SCTP_INP_DECR_REF(inp);
3503 SCTP_INP_WUNLOCK(inp);
3504 SCTP_INP_INFO_WUNLOCK();
3505 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EACCES);
3506 return (EACCES);
3507 }
3508#endif
3509 }
tuexendd729232011-11-01 23:04:43 +00003510#endif /* __Windows__ */
3511 SCTP_INP_WUNLOCK(inp);
3512 if (bindall) {
3513#ifdef SCTP_MVRF
tuexen63fc0bb2011-12-27 12:24:52 +00003514 for (i = 0; i < inp->num_vrfs; i++) {
tuexendd729232011-11-01 23:04:43 +00003515 vrf_id = inp->m_vrf_ids[i];
3516#else
3517 vrf_id = inp->def_vrf_id;
3518#endif
3519 inp_tmp = sctp_pcb_findep(addr, 0, 1, vrf_id);
3520 if (inp_tmp != NULL) {
3521 /*
3522 * lock guy returned and lower count
3523 * note that we are not bound so
3524 * inp_tmp should NEVER be inp. And
3525 * it is this inp (inp_tmp) that gets
3526 * the reference bump, so we must
3527 * lower it.
3528 */
3529 SCTP_INP_DECR_REF(inp_tmp);
3530 /* unlock info */
3531 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) &&
3532 (sctp_is_feature_on(inp_tmp, SCTP_PCB_FLAGS_PORTREUSE))) {
3533 /* Ok, must be one-2-one and allowing port re-use */
3534 port_reuse_active = 1;
3535 goto continue_anyway;
3536 }
3537 SCTP_INP_DECR_REF(inp);
3538 SCTP_INP_INFO_WUNLOCK();
3539 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRINUSE);
3540 return (EADDRINUSE);
3541 }
3542#ifdef SCTP_MVRF
3543 }
3544#endif
3545 } else {
3546 inp_tmp = sctp_pcb_findep(addr, 0, 1, vrf_id);
3547 if (inp_tmp != NULL) {
3548 /*
3549 * lock guy returned and lower count note
3550 * that we are not bound so inp_tmp should
3551 * NEVER be inp. And it is this inp (inp_tmp)
3552 * that gets the reference bump, so we must
3553 * lower it.
3554 */
3555 SCTP_INP_DECR_REF(inp_tmp);
3556 /* unlock info */
3557 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) &&
3558 (sctp_is_feature_on(inp_tmp, SCTP_PCB_FLAGS_PORTREUSE))) {
3559 /* Ok, must be one-2-one and allowing port re-use */
3560 port_reuse_active = 1;
3561 goto continue_anyway;
3562 }
3563 SCTP_INP_DECR_REF(inp);
3564 SCTP_INP_INFO_WUNLOCK();
3565 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRINUSE);
3566 return (EADDRINUSE);
3567 }
3568 }
3569 continue_anyway:
3570 SCTP_INP_WLOCK(inp);
3571 if (bindall) {
3572 /* verify that no lport is not used by a singleton */
t00fcxenefb47e72012-09-09 08:16:51 +00003573 if ((port_reuse_active == 0) &&
3574 (inp_tmp = sctp_isport_inuse(inp, lport, vrf_id))) {
tuexendd729232011-11-01 23:04:43 +00003575 /* Sorry someone already has this one bound */
3576 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) &&
3577 (sctp_is_feature_on(inp_tmp, SCTP_PCB_FLAGS_PORTREUSE))) {
3578 port_reuse_active = 1;
3579 } else {
3580 SCTP_INP_DECR_REF(inp);
3581 SCTP_INP_WUNLOCK(inp);
3582 SCTP_INP_INFO_WUNLOCK();
3583 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRINUSE);
3584 return (EADDRINUSE);
3585 }
3586 }
3587 }
3588 } else {
3589 uint16_t first, last, candidate;
t00fcxenc24796c2014-05-06 15:39:13 +00003590 uint16_t count;
tuexendd729232011-11-01 23:04:43 +00003591 int done;
3592
3593#if defined(__Windows__)
3594 first = 1;
3595 last = 0xffff;
3596#else
3597#if defined(__Userspace__)
t00fcxenc24796c2014-05-06 15:39:13 +00003598 /* TODO ensure uid is 0, etc... */
tuexendd729232011-11-01 23:04:43 +00003599#elif defined(__FreeBSD__) || defined(__APPLE__)
t00fcxenc24796c2014-05-06 15:39:13 +00003600 if (ip_inp->inp_flags & INP_HIGHPORT) {
3601 first = MODULE_GLOBAL(ipport_hifirstauto);
3602 last = MODULE_GLOBAL(ipport_hilastauto);
3603 } else if (ip_inp->inp_flags & INP_LOWPORT) {
tuexendd729232011-11-01 23:04:43 +00003604 if (p && (error =
3605#ifdef __FreeBSD__
3606#if __FreeBSD_version > 602000
3607 priv_check(p, PRIV_NETINET_RESERVEDPORT)
3608#elif __FreeBSD_version >= 500000
3609 suser_cred(p->td_ucred, 0)
3610#else
3611 suser(p)
3612#endif
3613#elif defined(__APPLE__)
3614 suser(p->p_ucred, &p->p_acflag)
3615#else
3616 suser(p, 0)
3617#endif
3618 )) {
3619 SCTP_INP_DECR_REF(inp);
3620 SCTP_INP_WUNLOCK(inp);
3621 SCTP_INP_INFO_WUNLOCK();
3622 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
3623 return (error);
3624 }
t00fcxenc24796c2014-05-06 15:39:13 +00003625 first = MODULE_GLOBAL(ipport_lowfirstauto);
3626 last = MODULE_GLOBAL(ipport_lowlastauto);
3627 } else {
tuexendd729232011-11-01 23:04:43 +00003628#endif
t00fcxen8dd95b82014-07-11 20:41:28 +00003629 first = MODULE_GLOBAL(ipport_firstauto);
3630 last = MODULE_GLOBAL(ipport_lastauto);
tuexendd729232011-11-01 23:04:43 +00003631#if defined(__FreeBSD__) || defined(__APPLE__)
t00fcxenc24796c2014-05-06 15:39:13 +00003632 }
tuexendd729232011-11-01 23:04:43 +00003633#endif
3634#endif /* __Windows__ */
3635 if (first > last) {
3636 uint16_t temp;
3637
3638 temp = first;
3639 first = last;
3640 last = temp;
3641 }
3642 count = last - first + 1; /* number of candidates */
3643 candidate = first + sctp_select_initial_TSN(&inp->sctp_ep) % (count);
3644
3645 done = 0;
3646 while (!done) {
3647#ifdef SCTP_MVRF
tuexen63fc0bb2011-12-27 12:24:52 +00003648 for (i = 0; i < inp->num_vrfs; i++) {
tuexendd729232011-11-01 23:04:43 +00003649 if (sctp_isport_inuse(inp, htons(candidate), inp->m_vrf_ids[i]) != NULL) {
3650 break;
3651 }
3652 }
3653 if (i == inp->num_vrfs) {
3654 done = 1;
3655 }
3656#else
3657 if (sctp_isport_inuse(inp, htons(candidate), inp->def_vrf_id) == NULL) {
3658 done = 1;
3659 }
3660#endif
3661 if (!done) {
3662 if (--count == 0) {
3663 SCTP_INP_DECR_REF(inp);
3664 SCTP_INP_WUNLOCK(inp);
3665 SCTP_INP_INFO_WUNLOCK();
3666 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRINUSE);
3667 return (EADDRINUSE);
3668 }
3669 if (candidate == last)
3670 candidate = first;
3671 else
3672 candidate = candidate + 1;
3673 }
3674 }
3675 lport = htons(candidate);
3676 }
3677 SCTP_INP_DECR_REF(inp);
3678 if (inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE |
3679 SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
3680 /*
3681 * this really should not happen. The guy did a non-blocking
3682 * bind and then did a close at the same time.
3683 */
3684 SCTP_INP_WUNLOCK(inp);
3685 SCTP_INP_INFO_WUNLOCK();
3686 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
3687 return (EINVAL);
3688 }
3689 /* ok we look clear to give out this port, so lets setup the binding */
3690 if (bindall) {
3691 /* binding to all addresses, so just set in the proper flags */
3692 inp->sctp_flags |= SCTP_PCB_FLAGS_BOUNDALL;
3693 /* set the automatic addr changes from kernel flag */
3694 if (SCTP_BASE_SYSCTL(sctp_auto_asconf) == 0) {
3695 sctp_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF);
3696 sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
3697 } else {
3698 sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF);
3699 sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
3700 }
3701 if (SCTP_BASE_SYSCTL(sctp_multiple_asconfs) == 0) {
3702 sctp_feature_off(inp, SCTP_PCB_FLAGS_MULTIPLE_ASCONFS);
3703 } else {
3704 sctp_feature_on(inp, SCTP_PCB_FLAGS_MULTIPLE_ASCONFS);
3705 }
3706 /* set the automatic mobility_base from kernel
3707 flag (by micchie)
3708 */
3709 if (SCTP_BASE_SYSCTL(sctp_mobility_base) == 0) {
3710 sctp_mobility_feature_off(inp, SCTP_MOBILITY_BASE);
3711 sctp_mobility_feature_off(inp, SCTP_MOBILITY_PRIM_DELETED);
t00fcxenefb47e72012-09-09 08:16:51 +00003712 } else {
tuexendd729232011-11-01 23:04:43 +00003713 sctp_mobility_feature_on(inp, SCTP_MOBILITY_BASE);
3714 sctp_mobility_feature_off(inp, SCTP_MOBILITY_PRIM_DELETED);
3715 }
3716 /* set the automatic mobility_fasthandoff from kernel
3717 flag (by micchie)
3718 */
3719 if (SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff) == 0) {
3720 sctp_mobility_feature_off(inp, SCTP_MOBILITY_FASTHANDOFF);
3721 sctp_mobility_feature_off(inp, SCTP_MOBILITY_PRIM_DELETED);
t00fcxenefb47e72012-09-09 08:16:51 +00003722 } else {
tuexendd729232011-11-01 23:04:43 +00003723 sctp_mobility_feature_on(inp, SCTP_MOBILITY_FASTHANDOFF);
3724 sctp_mobility_feature_off(inp, SCTP_MOBILITY_PRIM_DELETED);
3725 }
3726 } else {
3727 /*
3728 * bind specific, make sure flags is off and add a new
3729 * address structure to the sctp_addr_list inside the ep
3730 * structure.
3731 *
3732 * We will need to allocate one and insert it at the head. The
3733 * socketopt call can just insert new addresses in there as
3734 * well. It will also have to do the embed scope kame hack
3735 * too (before adding).
3736 */
3737 struct sctp_ifa *ifa;
t00fcxen05f07c02014-09-07 10:15:26 +00003738 union sctp_sockstore store;
tuexendd729232011-11-01 23:04:43 +00003739
t00fcxen05f07c02014-09-07 10:15:26 +00003740 memset(&store, 0, sizeof(store));
tuexendd729232011-11-01 23:04:43 +00003741 switch (addr->sa_family) {
tuexen310f1bc2012-07-15 11:20:56 +00003742#ifdef INET
tuexendd729232011-11-01 23:04:43 +00003743 case AF_INET:
t00fcxen05f07c02014-09-07 10:15:26 +00003744 memcpy(&store.sin, addr, sizeof(struct sockaddr_in));
3745 store.sin.sin_port = 0;
tuexendd729232011-11-01 23:04:43 +00003746 break;
tuexen310f1bc2012-07-15 11:20:56 +00003747#endif
3748#ifdef INET6
tuexendd729232011-11-01 23:04:43 +00003749 case AF_INET6:
t00fcxen05f07c02014-09-07 10:15:26 +00003750 memcpy(&store.sin6, addr, sizeof(struct sockaddr_in6));
3751 store.sin6.sin6_port = 0;
tuexendd729232011-11-01 23:04:43 +00003752 break;
tuexen310f1bc2012-07-15 11:20:56 +00003753#endif
tuexencc2b1422012-07-10 21:50:32 +00003754#if defined(__Userspace__)
3755 case AF_CONN:
t00fcxen05f07c02014-09-07 10:15:26 +00003756 memcpy(&store.sconn, addr, sizeof(struct sockaddr_conn));
3757 store.sconn.sconn_port = 0;
tuexencc2b1422012-07-10 21:50:32 +00003758 break;
tuexencc2b1422012-07-10 21:50:32 +00003759#endif
tuexendd729232011-11-01 23:04:43 +00003760 default:
3761 break;
3762 }
3763 /*
3764 * first find the interface with the bound address need to
3765 * zero out the port to find the address! yuck! can't do
3766 * this earlier since need port for sctp_pcb_findep()
3767 */
t00fcxenefb47e72012-09-09 08:16:51 +00003768 if (sctp_ifap != NULL) {
tuexendd729232011-11-01 23:04:43 +00003769 ifa = sctp_ifap;
t00fcxenefb47e72012-09-09 08:16:51 +00003770 } else {
tuexendd729232011-11-01 23:04:43 +00003771 /* Note for BSD we hit here always other
3772 * O/S's will pass things in via the
3773 * sctp_ifap argument (Panda).
3774 */
t00fcxen05f07c02014-09-07 10:15:26 +00003775 ifa = sctp_find_ifa_by_addr(&store.sa,
tuexendd729232011-11-01 23:04:43 +00003776 vrf_id, SCTP_ADDR_NOT_LOCKED);
3777 }
3778 if (ifa == NULL) {
3779 /* Can't find an interface with that address */
3780 SCTP_INP_WUNLOCK(inp);
3781 SCTP_INP_INFO_WUNLOCK();
3782 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRNOTAVAIL);
3783 return (EADDRNOTAVAIL);
3784 }
3785#ifdef INET6
3786 if (addr->sa_family == AF_INET6) {
3787 /* GAK, more FIXME IFA lock? */
3788 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
3789 /* Can't bind a non-existent addr. */
3790 SCTP_INP_WUNLOCK(inp);
3791 SCTP_INP_INFO_WUNLOCK();
3792 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
3793 return (EINVAL);
3794 }
3795 }
3796#endif
3797 /* we're not bound all */
3798 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUNDALL;
3799 /* allow bindx() to send ASCONF's for binding changes */
3800 sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF);
3801 /* clear automatic addr changes from kernel flag */
3802 sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
3803
3804 /* add this address to the endpoint list */
3805 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, 0);
3806 if (error != 0) {
3807 SCTP_INP_WUNLOCK(inp);
3808 SCTP_INP_INFO_WUNLOCK();
3809 return (error);
3810 }
3811 inp->laddr_count++;
3812 }
3813 /* find the bucket */
tuexen98456cf2012-04-19 15:37:07 +00003814 if (port_reuse_active) {
tuexendd729232011-11-01 23:04:43 +00003815 /* Put it into tcp 1-2-1 hash */
3816 head = &SCTP_BASE_INFO(sctp_tcpephash)[SCTP_PCBHASH_ALLADDR(lport, SCTP_BASE_INFO(hashtcpmark))];
3817 inp->sctp_flags |= SCTP_PCB_FLAGS_IN_TCPPOOL;
t00fcxenc24796c2014-05-06 15:39:13 +00003818 } else {
tuexendd729232011-11-01 23:04:43 +00003819 head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(lport, SCTP_BASE_INFO(hashmark))];
3820 }
3821 /* put it in the bucket */
3822 LIST_INSERT_HEAD(head, inp, sctp_hash);
3823 SCTPDBG(SCTP_DEBUG_PCB1, "Main hash to bind at head:%p, bound port:%d - in tcp_pool=%d\n",
t00fcxen8fca7ff2012-09-05 18:58:42 +00003824 (void *)head, ntohs(lport), port_reuse_active);
tuexendd729232011-11-01 23:04:43 +00003825 /* set in the port */
3826 inp->sctp_lport = lport;
3827
3828 /* turn off just the unbound flag */
3829 inp->sctp_flags &= ~SCTP_PCB_FLAGS_UNBOUND;
3830 SCTP_INP_WUNLOCK(inp);
3831 SCTP_INP_INFO_WUNLOCK();
3832 return (0);
3833}
3834
3835
3836static void
3837sctp_iterator_inp_being_freed(struct sctp_inpcb *inp)
3838{
3839 struct sctp_iterator *it, *nit;
3840
3841 /*
3842 * We enter with the only the ITERATOR_LOCK in place and a write
3843 * lock on the inp_info stuff.
3844 */
3845 it = sctp_it_ctl.cur_it;
3846#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
3847 if (it && (it->vn != curvnet)) {
3848 /* Its not looking at our VNET */
3849 return;
3850 }
3851#endif
3852 if (it && (it->inp == inp)) {
3853 /*
3854 * This is tricky and we hold the iterator lock,
3855 * but when it returns and gets the lock (when we
3856 * release it) the iterator will try to operate on
3857 * inp. We need to stop that from happening. But
3858 * of course the iterator has a reference on the
3859 * stcb and inp. We can mark it and it will stop.
3860 *
3861 * If its a single iterator situation, we
3862 * set the end iterator flag. Otherwise
3863 * we set the iterator to go to the next inp.
3864 *
3865 */
3866 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
3867 sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
3868 } else {
3869 sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_INP;
3870 }
3871 }
3872 /* Now go through and remove any single reference to
3873 * our inp that may be still pending on the list
3874 */
3875 SCTP_IPI_ITERATOR_WQ_LOCK();
3876 TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
3877#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
3878 if (it->vn != curvnet) {
3879 continue;
tuexen09631162012-04-18 11:23:02 +00003880 }
tuexendd729232011-11-01 23:04:43 +00003881#endif
3882 if (it->inp == inp) {
3883 /* This one points to me is it inp specific? */
3884 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
3885 /* Remove and free this one */
3886 TAILQ_REMOVE(&sctp_it_ctl.iteratorhead,
3887 it, sctp_nxt_itr);
3888 if (it->function_atend != NULL) {
3889 (*it->function_atend) (it->pointer, it->val);
3890 }
3891 SCTP_FREE(it, SCTP_M_ITER);
3892 } else {
3893 it->inp = LIST_NEXT(it->inp, sctp_list);
3894 if (it->inp) {
3895 SCTP_INP_INCR_REF(it->inp);
3896 }
3897 }
3898 /* When its put in the refcnt is incremented so decr it */
3899 SCTP_INP_DECR_REF(inp);
3900 }
3901 }
3902 SCTP_IPI_ITERATOR_WQ_UNLOCK();
3903}
3904
3905/* release sctp_inpcb unbind the port */
3906void
3907sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
3908{
3909 /*
3910 * Here we free a endpoint. We must find it (if it is in the Hash
3911 * table) and remove it from there. Then we must also find it in the
3912 * overall list and remove it from there. After all removals are
3913 * complete then any timer has to be stopped. Then start the actual
3914 * freeing. a) Any local lists. b) Any associations. c) The hash of
3915 * all associations. d) finally the ep itself.
3916 */
tuexendd729232011-11-01 23:04:43 +00003917 struct sctp_tcb *asoc, *nasoc;
3918 struct sctp_laddr *laddr, *nladdr;
3919 struct inpcb *ip_pcb;
3920 struct socket *so;
tuexen63fc0bb2011-12-27 12:24:52 +00003921 int being_refed = 0;
tuexendd729232011-11-01 23:04:43 +00003922 struct sctp_queued_to_read *sq, *nsq;
3923#if !defined(__Panda__) && !defined(__Userspace__)
3924#if !defined(__FreeBSD__) || __FreeBSD_version < 500000
3925 sctp_rtentry_t *rt;
3926#endif
3927#endif
3928 int cnt;
3929 sctp_sharedkey_t *shared_key, *nshared_key;
3930
3931
3932#if defined(__APPLE__)
3933 sctp_lock_assert(SCTP_INP_SO(inp));
3934#endif
3935#ifdef SCTP_LOG_CLOSING
3936 sctp_log_closing(inp, NULL, 0);
3937#endif
3938 SCTP_ITERATOR_LOCK();
3939 /* mark any iterators on the list or being processed */
3940 sctp_iterator_inp_being_freed(inp);
3941 SCTP_ITERATOR_UNLOCK();
3942 so = inp->sctp_socket;
3943 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
3944 /* been here before.. eeks.. get out of here */
3945 SCTP_PRINTF("This conflict in free SHOULD not be happening! from %d, imm %d\n", from, immediate);
3946#ifdef SCTP_LOG_CLOSING
3947 sctp_log_closing(inp, NULL, 1);
3948#endif
3949 return;
3950 }
3951 SCTP_ASOC_CREATE_LOCK(inp);
3952 SCTP_INP_INFO_WLOCK();
3953
3954 SCTP_INP_WLOCK(inp);
3955 if (from == SCTP_CALLED_AFTER_CMPSET_OFCLOSE) {
3956 inp->sctp_flags &= ~SCTP_PCB_FLAGS_CLOSE_IP;
3957 /* socket is gone, so no more wakeups allowed */
3958 inp->sctp_flags |= SCTP_PCB_FLAGS_DONT_WAKE;
3959 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT;
3960 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT;
3961
3962 }
3963 /* First time through we have the socket lock, after that no more. */
3964 sctp_timer_stop(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL,
t00fcxen0057a6d2015-05-28 16:42:49 +00003965 SCTP_FROM_SCTP_PCB + SCTP_LOC_1);
tuexendd729232011-11-01 23:04:43 +00003966
3967 if (inp->control) {
3968 sctp_m_freem(inp->control);
3969 inp->control = NULL;
3970 }
3971 if (inp->pkt) {
3972 sctp_m_freem(inp->pkt);
3973 inp->pkt = NULL;
3974 }
tuexendd729232011-11-01 23:04:43 +00003975 ip_pcb = &inp->ip_inp.inp; /* we could just cast the main pointer
3976 * here but I will be nice :> (i.e.
3977 * ip_pcb = ep;) */
3978 if (immediate == SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE) {
3979 int cnt_in_sd;
3980
3981 cnt_in_sd = 0;
3982 LIST_FOREACH_SAFE(asoc, &inp->sctp_asoc_list, sctp_tcblist, nasoc) {
3983 SCTP_TCB_LOCK(asoc);
3984 if (asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
3985 /* Skip guys being freed */
3986 cnt_in_sd++;
3987 if (asoc->asoc.state & SCTP_STATE_IN_ACCEPT_QUEUE) {
3988 /*
3989 * Special case - we did not start a kill
3990 * timer on the asoc due to it was not
3991 * closed. So go ahead and start it now.
3992 */
3993 asoc->asoc.state &= ~SCTP_STATE_IN_ACCEPT_QUEUE;
3994 sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, asoc, NULL);
3995 }
3996 SCTP_TCB_UNLOCK(asoc);
3997 continue;
3998 }
3999 if (((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_COOKIE_WAIT) ||
4000 (SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_COOKIE_ECHOED)) &&
4001 (asoc->asoc.total_output_queue_size == 0)) {
4002 /* If we have data in queue, we don't want to just
4003 * free since the app may have done, send()/close
4004 * or connect/send/close. And it wants the data
4005 * to get across first.
4006 */
4007 /* Just abandon things in the front states */
4008 if (sctp_free_assoc(inp, asoc, SCTP_PCBFREE_NOFORCE,
t00fcxen0057a6d2015-05-28 16:42:49 +00004009 SCTP_FROM_SCTP_PCB + SCTP_LOC_2) == 0) {
tuexendd729232011-11-01 23:04:43 +00004010 cnt_in_sd++;
4011 }
4012 continue;
4013 }
4014 /* Disconnect the socket please */
4015 asoc->sctp_socket = NULL;
4016 asoc->asoc.state |= SCTP_STATE_CLOSED_SOCKET;
4017 if ((asoc->asoc.size_on_reasm_queue > 0) ||
4018 (asoc->asoc.control_pdapi) ||
4019 (asoc->asoc.size_on_all_streams > 0) ||
tuexen63fc0bb2011-12-27 12:24:52 +00004020 (so && (so->so_rcv.sb_cc > 0))) {
tuexendd729232011-11-01 23:04:43 +00004021 /* Left with Data unread */
4022 struct mbuf *op_err;
4023
t00fcxen08f9ff92014-03-16 13:38:54 +00004024 op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
t00fcxen0057a6d2015-05-28 16:42:49 +00004025 asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_3;
tuexendd729232011-11-01 23:04:43 +00004026 sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
4027 SCTP_STAT_INCR_COUNTER32(sctps_aborted);
4028 if ((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_OPEN) ||
4029 (SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
4030 SCTP_STAT_DECR_GAUGE32(sctps_currestab);
4031 }
4032 if (sctp_free_assoc(inp, asoc,
t00fcxen0057a6d2015-05-28 16:42:49 +00004033 SCTP_PCBFREE_NOFORCE, SCTP_FROM_SCTP_PCB + SCTP_LOC_4) == 0) {
tuexendd729232011-11-01 23:04:43 +00004034 cnt_in_sd++;
4035 }
4036 continue;
4037 } else if (TAILQ_EMPTY(&asoc->asoc.send_queue) &&
4038 TAILQ_EMPTY(&asoc->asoc.sent_queue) &&
t00fcxen28611aa2012-09-23 07:45:40 +00004039 (asoc->asoc.stream_queue_cnt == 0)) {
tuexendd729232011-11-01 23:04:43 +00004040 if (asoc->asoc.locked_on_sending) {
4041 goto abort_anyway;
4042 }
4043 if ((SCTP_GET_STATE(&asoc->asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
4044 (SCTP_GET_STATE(&asoc->asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
4045 struct sctp_nets *netp;
4046
t00fcxend0ad16b2013-02-09 18:34:24 +00004047 /*
4048 * there is nothing queued to send,
4049 * so I send shutdown
4050 */
4051 if ((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_OPEN) ||
4052 (SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
4053 SCTP_STAT_DECR_GAUGE32(sctps_currestab);
4054 }
4055 SCTP_SET_STATE(&asoc->asoc, SCTP_STATE_SHUTDOWN_SENT);
4056 SCTP_CLEAR_SUBSTATE(&asoc->asoc, SCTP_STATE_SHUTDOWN_PENDING);
4057 sctp_stop_timers_for_shutdown(asoc);
tuexendd729232011-11-01 23:04:43 +00004058 if (asoc->asoc.alternate) {
4059 netp = asoc->asoc.alternate;
4060 } else {
4061 netp = asoc->asoc.primary_destination;
4062 }
tuexendd729232011-11-01 23:04:43 +00004063 sctp_send_shutdown(asoc, netp);
tuexendd729232011-11-01 23:04:43 +00004064 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, asoc->sctp_ep, asoc,
4065 netp);
4066 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, asoc->sctp_ep, asoc,
4067 asoc->asoc.primary_destination);
4068 sctp_chunk_output(inp, asoc, SCTP_OUTPUT_FROM_SHUT_TMR, SCTP_SO_LOCKED);
4069 }
4070 } else {
4071 /* mark into shutdown pending */
4072 struct sctp_stream_queue_pending *sp;
4073
4074 asoc->asoc.state |= SCTP_STATE_SHUTDOWN_PENDING;
4075 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, asoc->sctp_ep, asoc,
4076 asoc->asoc.primary_destination);
4077 if (asoc->asoc.locked_on_sending) {
4078 sp = TAILQ_LAST(&((asoc->asoc.locked_on_sending)->outqueue),
4079 sctp_streamhead);
4080 if (sp == NULL) {
4081 SCTP_PRINTF("Error, sp is NULL, locked on sending is %p strm:%d\n",
t00fcxen8fca7ff2012-09-05 18:58:42 +00004082 (void *)asoc->asoc.locked_on_sending,
tuexendd729232011-11-01 23:04:43 +00004083 asoc->asoc.locked_on_sending->stream_no);
4084 } else {
4085 if ((sp->length == 0) && (sp->msg_is_complete == 0))
4086 asoc->asoc.state |= SCTP_STATE_PARTIAL_MSG_LEFT;
4087 }
4088 }
4089 if (TAILQ_EMPTY(&asoc->asoc.send_queue) &&
4090 TAILQ_EMPTY(&asoc->asoc.sent_queue) &&
4091 (asoc->asoc.state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
4092 struct mbuf *op_err;
4093 abort_anyway:
t00fcxen08f9ff92014-03-16 13:38:54 +00004094 op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
t00fcxen0057a6d2015-05-28 16:42:49 +00004095 asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_5;
tuexendd729232011-11-01 23:04:43 +00004096 sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
4097 SCTP_STAT_INCR_COUNTER32(sctps_aborted);
4098 if ((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_OPEN) ||
4099 (SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
4100 SCTP_STAT_DECR_GAUGE32(sctps_currestab);
4101 }
4102 if (sctp_free_assoc(inp, asoc,
4103 SCTP_PCBFREE_NOFORCE,
t00fcxen0057a6d2015-05-28 16:42:49 +00004104 SCTP_FROM_SCTP_PCB + SCTP_LOC_6) == 0) {
tuexendd729232011-11-01 23:04:43 +00004105 cnt_in_sd++;
4106 }
4107 continue;
4108 } else {
4109 sctp_chunk_output(inp, asoc, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
4110 }
4111 }
4112 cnt_in_sd++;
4113 SCTP_TCB_UNLOCK(asoc);
4114 }
4115 /* now is there some left in our SHUTDOWN state? */
4116 if (cnt_in_sd) {
4117#ifdef SCTP_LOG_CLOSING
4118 sctp_log_closing(inp, NULL, 2);
4119#endif
4120 inp->sctp_socket = NULL;
4121 SCTP_INP_WUNLOCK(inp);
4122 SCTP_ASOC_CREATE_UNLOCK(inp);
4123 SCTP_INP_INFO_WUNLOCK();
4124 return;
4125 }
4126 }
4127 inp->sctp_socket = NULL;
4128 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) !=
4129 SCTP_PCB_FLAGS_UNBOUND) {
4130 /*
4131 * ok, this guy has been bound. It's port is
4132 * somewhere in the SCTP_BASE_INFO(hash table). Remove
4133 * it!
4134 */
4135 LIST_REMOVE(inp, sctp_hash);
4136 inp->sctp_flags |= SCTP_PCB_FLAGS_UNBOUND;
4137 }
4138
4139 /* If there is a timer running to kill us,
4140 * forget it, since it may have a contest
4141 * on the INP lock.. which would cause us
4142 * to die ...
4143 */
4144 cnt = 0;
4145 LIST_FOREACH_SAFE(asoc, &inp->sctp_asoc_list, sctp_tcblist, nasoc) {
4146 SCTP_TCB_LOCK(asoc);
4147 if (asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
4148 if (asoc->asoc.state & SCTP_STATE_IN_ACCEPT_QUEUE) {
t00fcxen28611aa2012-09-23 07:45:40 +00004149 asoc->asoc.state &= ~SCTP_STATE_IN_ACCEPT_QUEUE;
4150 sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, asoc, NULL);
tuexendd729232011-11-01 23:04:43 +00004151 }
4152 cnt++;
4153 SCTP_TCB_UNLOCK(asoc);
4154 continue;
4155 }
4156 /* Free associations that are NOT killing us */
4157 if ((SCTP_GET_STATE(&asoc->asoc) != SCTP_STATE_COOKIE_WAIT) &&
4158 ((asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) {
4159 struct mbuf *op_err;
t00fcxen28611aa2012-09-23 07:45:40 +00004160
t00fcxen08f9ff92014-03-16 13:38:54 +00004161 op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
t00fcxen0057a6d2015-05-28 16:42:49 +00004162 asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_7;
tuexendd729232011-11-01 23:04:43 +00004163 sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
4164 SCTP_STAT_INCR_COUNTER32(sctps_aborted);
4165 } else if (asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
4166 cnt++;
4167 SCTP_TCB_UNLOCK(asoc);
4168 continue;
4169 }
4170 if ((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_OPEN) ||
4171 (SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
4172 SCTP_STAT_DECR_GAUGE32(sctps_currestab);
4173 }
t00fcxen0057a6d2015-05-28 16:42:49 +00004174 if (sctp_free_assoc(inp, asoc, SCTP_PCBFREE_FORCE,
4175 SCTP_FROM_SCTP_PCB + SCTP_LOC_8) == 0) {
tuexendd729232011-11-01 23:04:43 +00004176 cnt++;
4177 }
4178 }
4179 if (cnt) {
4180 /* Ok we have someone out there that will kill us */
4181 (void)SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
4182#ifdef SCTP_LOG_CLOSING
4183 sctp_log_closing(inp, NULL, 3);
4184#endif
4185 SCTP_INP_WUNLOCK(inp);
4186 SCTP_ASOC_CREATE_UNLOCK(inp);
4187 SCTP_INP_INFO_WUNLOCK();
4188 return;
4189 }
4190 if (SCTP_INP_LOCK_CONTENDED(inp))
4191 being_refed++;
4192 if (SCTP_INP_READ_CONTENDED(inp))
4193 being_refed++;
tuexen63fc0bb2011-12-27 12:24:52 +00004194 if (SCTP_ASOC_CREATE_LOCK_CONTENDED(inp))
tuexendd729232011-11-01 23:04:43 +00004195 being_refed++;
4196
tuexen63fc0bb2011-12-27 12:24:52 +00004197 if ((inp->refcount) ||
t00fcxen28611aa2012-09-23 07:45:40 +00004198 (being_refed) ||
4199 (inp->sctp_flags & SCTP_PCB_FLAGS_CLOSE_IP)) {
tuexendd729232011-11-01 23:04:43 +00004200 (void)SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
4201#ifdef SCTP_LOG_CLOSING
4202 sctp_log_closing(inp, NULL, 4);
4203#endif
4204 sctp_timer_start(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL);
4205 SCTP_INP_WUNLOCK(inp);
4206 SCTP_ASOC_CREATE_UNLOCK(inp);
4207 SCTP_INP_INFO_WUNLOCK();
4208 return;
4209 }
4210 inp->sctp_ep.signature_change.type = 0;
4211 inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_ALLGONE;
4212 /* Remove it from the list .. last thing we need a
4213 * lock for.
4214 */
4215 LIST_REMOVE(inp, sctp_list);
4216 SCTP_INP_WUNLOCK(inp);
4217 SCTP_ASOC_CREATE_UNLOCK(inp);
4218 SCTP_INP_INFO_WUNLOCK();
4219 /* Now we release all locks. Since this INP
4220 * cannot be found anymore except possibly by the
4221 * kill timer that might be running. We call
4222 * the drain function here. It should hit the case
4223 * were it sees the ACTIVE flag cleared and exit
4224 * out freeing us to proceed and destroy everything.
4225 */
4226 if (from != SCTP_CALLED_FROM_INPKILL_TIMER) {
4227 (void)SCTP_OS_TIMER_STOP_DRAIN(&inp->sctp_ep.signature_change.timer);
4228 } else {
4229 /* Probably un-needed */
4230 (void)SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
4231 }
4232
4233#ifdef SCTP_LOG_CLOSING
4234 sctp_log_closing(inp, NULL, 5);
4235#endif
4236
4237#if !(defined(__Panda__) || defined(__Windows__) || defined(__Userspace__))
4238#if !defined(__FreeBSD__) || __FreeBSD_version < 500000
4239 rt = ip_pcb->inp_route.ro_rt;
4240#endif
4241#endif
4242
4243#if defined(__Panda__)
4244 if (inp->pak_to_read) {
4245 (void)SCTP_OS_TIMER_STOP(&inp->sctp_ep.zero_copy_timer.timer);
4246 SCTP_RELEASE_PKT(inp->pak_to_read);
4247 inp->pak_to_read = NULL;
4248 }
4249 if (inp->pak_to_read_sendq) {
4250 (void)SCTP_OS_TIMER_STOP(&inp->sctp_ep.zero_copy_sendq_timer.timer);
4251 SCTP_RELEASE_PKT(inp->pak_to_read_sendq);
4252 inp->pak_to_read_sendq = NULL;
4253 }
4254#endif
4255 if ((inp->sctp_asocidhash) != NULL) {
4256 SCTP_HASH_FREE(inp->sctp_asocidhash, inp->hashasocidmark);
4257 inp->sctp_asocidhash = NULL;
4258 }
4259 /*sa_ignore FREED_MEMORY*/
4260 TAILQ_FOREACH_SAFE(sq, &inp->read_queue, next, nsq) {
4261 /* Its only abandoned if it had data left */
4262 if (sq->length)
4263 SCTP_STAT_INCR(sctps_left_abandon);
4264
4265 TAILQ_REMOVE(&inp->read_queue, sq, next);
4266 sctp_free_remote_addr(sq->whoFrom);
4267 if (so)
4268 so->so_rcv.sb_cc -= sq->length;
4269 if (sq->data) {
4270 sctp_m_freem(sq->data);
4271 sq->data = NULL;
4272 }
4273 /*
4274 * no need to free the net count, since at this point all
4275 * assoc's are gone.
4276 */
Michael Tuexene5001952016-04-17 19:25:27 +02004277 sctp_free_a_readq(NULL, sq);
tuexendd729232011-11-01 23:04:43 +00004278 }
4279 /* Now the sctp_pcb things */
4280 /*
4281 * free each asoc if it is not already closed/free. we can't use the
4282 * macro here since le_next will get freed as part of the
4283 * sctp_free_assoc() call.
4284 */
tuexendd729232011-11-01 23:04:43 +00004285#ifdef IPSEC
Michael Tuexen372872e2015-11-21 19:25:27 +01004286 ipsec_delete_pcbpolicy(ip_pcb);
4287#endif
tuexendd729232011-11-01 23:04:43 +00004288#ifndef __Panda__
4289 if (ip_pcb->inp_options) {
4290 (void)sctp_m_free(ip_pcb->inp_options);
4291 ip_pcb->inp_options = 0;
4292 }
4293#endif
4294
4295#if !(defined(__Panda__) || defined(__Windows__) || defined(__Userspace__))
4296#if !defined(__FreeBSD__) || __FreeBSD_version < 500000
4297 if (rt) {
4298 RTFREE(rt);
4299 ip_pcb->inp_route.ro_rt = 0;
4300 }
4301#endif
tuexen5fc22842012-02-11 13:32:19 +00004302#if defined(__FreeBSD__) && __FreeBSD_version < 803000
tuexendd729232011-11-01 23:04:43 +00004303#ifdef INET
4304 if (ip_pcb->inp_moptions) {
4305 inp_freemoptions(ip_pcb->inp_moptions);
4306 ip_pcb->inp_moptions = 0;
4307 }
4308#endif
4309#endif
4310#endif
4311
4312#ifdef INET6
t00fcxen4c76a912012-09-14 14:31:21 +00004313#if !(defined(__Panda__) || defined(__Windows__) || defined(__Userspace__))
4314#if defined(__FreeBSD__) || defined(__APPLE__)
tuexendd729232011-11-01 23:04:43 +00004315 if (ip_pcb->inp_vflag & INP_IPV6) {
t00fcxen4c76a912012-09-14 14:31:21 +00004316#else
4317 if (inp->inp_vflag & INP_IPV6) {
tuexendd729232011-11-01 23:04:43 +00004318#endif
4319 struct in6pcb *in6p;
4320
4321 in6p = (struct in6pcb *)inp;
tuexendd729232011-11-01 23:04:43 +00004322 ip6_freepcbopts(in6p->in6p_outputopts);
tuexendd729232011-11-01 23:04:43 +00004323 }
t00fcxen4c76a912012-09-14 14:31:21 +00004324#endif
tuexendd729232011-11-01 23:04:43 +00004325#endif /* INET6 */
4326#if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
4327 inp->inp_vflag = 0;
4328#else
4329 ip_pcb->inp_vflag = 0;
4330#endif
4331 /* free up authentication fields */
4332 if (inp->sctp_ep.local_auth_chunks != NULL)
4333 sctp_free_chunklist(inp->sctp_ep.local_auth_chunks);
4334 if (inp->sctp_ep.local_hmacs != NULL)
4335 sctp_free_hmaclist(inp->sctp_ep.local_hmacs);
4336
4337 LIST_FOREACH_SAFE(shared_key, &inp->sctp_ep.shared_keys, next, nshared_key) {
4338 LIST_REMOVE(shared_key, next);
4339 sctp_free_sharedkey(shared_key);
4340 /*sa_ignore FREED_MEMORY*/
4341 }
4342
4343#if defined(__APPLE__)
4344 inp->ip_inp.inp.inp_state = INPCB_STATE_DEAD;
tuexen6d01b942012-05-04 18:15:17 +00004345 if (in_pcb_checkstate(&inp->ip_inp.inp, WNT_STOPUSING, 1) != WNT_STOPUSING) {
tuexen49fdcc82012-05-04 10:13:12 +00004346#ifdef INVARIANTS
t00fcxen8fca7ff2012-09-05 18:58:42 +00004347 panic("sctp_inpcb_free inp = %p couldn't set to STOPUSING\n", (void *)inp);
tuexen6d01b942012-05-04 18:15:17 +00004348#else
t00fcxen8fca7ff2012-09-05 18:58:42 +00004349 SCTP_PRINTF("sctp_inpcb_free inp = %p couldn't set to STOPUSING\n", (void *)inp);
tuexen49fdcc82012-05-04 10:13:12 +00004350#endif
tuexen6d01b942012-05-04 18:15:17 +00004351 }
tuexendd729232011-11-01 23:04:43 +00004352 inp->ip_inp.inp.inp_socket->so_flags |= SOF_PCBCLEARING;
4353#endif
4354 /*
4355 * if we have an address list the following will free the list of
4356 * ifaddr's that are set into this ep. Again macro limitations here,
4357 * since the LIST_FOREACH could be a bad idea.
4358 */
4359 LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
4360 sctp_remove_laddr(laddr);
4361 }
4362
4363#ifdef SCTP_TRACK_FREED_ASOCS
4364 /* TEMP CODE */
4365 LIST_FOREACH_SAFE(asoc, &inp->sctp_asoc_free_list, sctp_tcblist, nasoc) {
4366 LIST_REMOVE(asoc, sctp_tcblist);
4367 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), asoc);
4368 SCTP_DECR_ASOC_COUNT();
4369 }
4370 /* *** END TEMP CODE ****/
4371#endif
4372#ifdef SCTP_MVRF
4373 SCTP_FREE(inp->m_vrf_ids, SCTP_M_MVRF);
4374#endif
4375 /* Now lets see about freeing the EP hash table. */
4376 if (inp->sctp_tcbhash != NULL) {
4377 SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark);
4378 inp->sctp_tcbhash = NULL;
4379 }
4380 /* Now we must put the ep memory back into the zone pool */
4381#if defined(__FreeBSD__)
t00fcxen326aa4b2014-06-20 13:42:13 +00004382 crfree(inp->ip_inp.inp.inp_cred);
tuexendd729232011-11-01 23:04:43 +00004383 INP_LOCK_DESTROY(&inp->ip_inp.inp);
4384#endif
4385 SCTP_INP_LOCK_DESTROY(inp);
4386 SCTP_INP_READ_DESTROY(inp);
4387 SCTP_ASOC_CREATE_LOCK_DESTROY(inp);
4388#if !defined(__APPLE__)
4389 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
4390 SCTP_DECR_EP_COUNT();
4391#else
4392 /* For Tiger, we will do this later... */
4393#endif
4394}
4395
4396
4397struct sctp_nets *
4398sctp_findnet(struct sctp_tcb *stcb, struct sockaddr *addr)
4399{
4400 struct sctp_nets *net;
4401 /* locate the address */
4402 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
4403 if (sctp_cmpaddr(addr, (struct sockaddr *)&net->ro._l_addr))
4404 return (net);
4405 }
4406 return (NULL);
4407}
4408
4409
4410int
4411sctp_is_address_on_local_host(struct sockaddr *addr, uint32_t vrf_id)
4412{
4413#ifdef __Panda__
4414 return (0);
4415#else
4416 struct sctp_ifa *sctp_ifa;
4417 sctp_ifa = sctp_find_ifa_by_addr(addr, vrf_id, SCTP_ADDR_NOT_LOCKED);
4418 if (sctp_ifa) {
4419 return (1);
4420 } else {
4421 return (0);
4422 }
4423#endif
4424}
4425
4426/*
4427 * add's a remote endpoint address, done with the INIT/INIT-ACK as well as
4428 * when a ASCONF arrives that adds it. It will also initialize all the cwnd
4429 * stats of stuff.
4430 */
4431int
4432sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
Michael Tuexen27574422016-04-30 16:35:29 +02004433 struct sctp_nets **netp, uint16_t port, int set_scope, int from)
tuexendd729232011-11-01 23:04:43 +00004434{
4435 /*
4436 * The following is redundant to the same lines in the
4437 * sctp_aloc_assoc() but is needed since others call the add
4438 * address function
4439 */
4440 struct sctp_nets *net, *netfirst;
4441 int addr_inscope;
4442
4443 SCTPDBG(SCTP_DEBUG_PCB1, "Adding an address (from:%d) to the peer: ",
4444 from);
4445 SCTPDBG_ADDR(SCTP_DEBUG_PCB1, newaddr);
4446
4447 netfirst = sctp_findnet(stcb, newaddr);
4448 if (netfirst) {
4449 /*
4450 * Lie and return ok, we don't want to make the association
4451 * go away for this behavior. It will happen in the TCP
4452 * model in a connected socket. It does not reach the hash
4453 * table until after the association is built so it can't be
4454 * found. Mark as reachable, since the initial creation will
4455 * have been cleared and the NOT_IN_ASSOC flag will have
4456 * been added... and we don't want to end up removing it
4457 * back out.
4458 */
4459 if (netfirst->dest_state & SCTP_ADDR_UNCONFIRMED) {
4460 netfirst->dest_state = (SCTP_ADDR_REACHABLE |
4461 SCTP_ADDR_UNCONFIRMED);
4462 } else {
4463 netfirst->dest_state = SCTP_ADDR_REACHABLE;
4464 }
4465
4466 return (0);
4467 }
4468 addr_inscope = 1;
4469 switch (newaddr->sa_family) {
4470#ifdef INET
4471 case AF_INET:
4472 {
4473 struct sockaddr_in *sin;
4474
4475 sin = (struct sockaddr_in *)newaddr;
4476 if (sin->sin_addr.s_addr == 0) {
4477 /* Invalid address */
4478 return (-1);
4479 }
4480 /* zero out the bzero area */
4481 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
4482
4483 /* assure len is set */
t00fcxen8fbaee32012-09-04 16:41:39 +00004484#ifdef HAVE_SIN_LEN
tuexendd729232011-11-01 23:04:43 +00004485 sin->sin_len = sizeof(struct sockaddr_in);
4486#endif
4487 if (set_scope) {
tuexendd729232011-11-01 23:04:43 +00004488 if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
t00fcxend0ad16b2013-02-09 18:34:24 +00004489 stcb->asoc.scope.ipv4_local_scope = 1;
tuexendd729232011-11-01 23:04:43 +00004490 }
tuexendd729232011-11-01 23:04:43 +00004491 } else {
4492 /* Validate the address is in scope */
4493 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) &&
t00fcxend0ad16b2013-02-09 18:34:24 +00004494 (stcb->asoc.scope.ipv4_local_scope == 0)) {
tuexendd729232011-11-01 23:04:43 +00004495 addr_inscope = 0;
4496 }
4497 }
4498 break;
4499 }
4500#endif
4501#ifdef INET6
4502 case AF_INET6:
4503 {
4504 struct sockaddr_in6 *sin6;
4505
4506 sin6 = (struct sockaddr_in6 *)newaddr;
4507 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
4508 /* Invalid address */
4509 return (-1);
4510 }
4511 /* assure len is set */
t00fcxen8fbaee32012-09-04 16:41:39 +00004512#ifdef HAVE_SIN6_LEN
tuexendd729232011-11-01 23:04:43 +00004513 sin6->sin6_len = sizeof(struct sockaddr_in6);
4514#endif
4515 if (set_scope) {
4516 if (sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id)) {
t00fcxend0ad16b2013-02-09 18:34:24 +00004517 stcb->asoc.scope.loopback_scope = 1;
4518 stcb->asoc.scope.local_scope = 0;
4519 stcb->asoc.scope.ipv4_local_scope = 1;
4520 stcb->asoc.scope.site_scope = 1;
tuexendd729232011-11-01 23:04:43 +00004521 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
4522 /*
4523 * If the new destination is a LINK_LOCAL we
4524 * must have common site scope. Don't set
4525 * the local scope since we may not share
4526 * all links, only loopback can do this.
4527 * Links on the local network would also be
4528 * on our private network for v4 too.
4529 */
t00fcxend0ad16b2013-02-09 18:34:24 +00004530 stcb->asoc.scope.ipv4_local_scope = 1;
4531 stcb->asoc.scope.site_scope = 1;
tuexendd729232011-11-01 23:04:43 +00004532 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
4533 /*
4534 * If the new destination is SITE_LOCAL then
4535 * we must have site scope in common.
4536 */
t00fcxend0ad16b2013-02-09 18:34:24 +00004537 stcb->asoc.scope.site_scope = 1;
tuexendd729232011-11-01 23:04:43 +00004538 }
4539 } else {
4540 /* Validate the address is in scope */
4541 if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) &&
t00fcxend0ad16b2013-02-09 18:34:24 +00004542 (stcb->asoc.scope.loopback_scope == 0)) {
tuexendd729232011-11-01 23:04:43 +00004543 addr_inscope = 0;
4544 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
t00fcxend0ad16b2013-02-09 18:34:24 +00004545 (stcb->asoc.scope.local_scope == 0)) {
tuexendd729232011-11-01 23:04:43 +00004546 addr_inscope = 0;
4547 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&
t00fcxend0ad16b2013-02-09 18:34:24 +00004548 (stcb->asoc.scope.site_scope == 0)) {
tuexendd729232011-11-01 23:04:43 +00004549 addr_inscope = 0;
4550 }
4551 }
4552 break;
4553 }
4554#endif
tuexencc2b1422012-07-10 21:50:32 +00004555#if defined(__Userspace__)
4556 case AF_CONN:
4557 {
4558 struct sockaddr_conn *sconn;
4559
4560 sconn = (struct sockaddr_conn *)newaddr;
4561 if (sconn->sconn_addr == NULL) {
4562 /* Invalid address */
4563 return (-1);
4564 }
t00fcxen8fbaee32012-09-04 16:41:39 +00004565#ifdef HAVE_SCONN_LEN
tuexencc2b1422012-07-10 21:50:32 +00004566 sconn->sconn_len = sizeof(struct sockaddr_conn);
4567#endif
4568 break;
4569 }
4570#endif
tuexendd729232011-11-01 23:04:43 +00004571 default:
4572 /* not supported family type */
4573 return (-1);
4574 }
4575 net = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_net), struct sctp_nets);
4576 if (net == NULL) {
4577 return (-1);
4578 }
4579 SCTP_INCR_RADDR_COUNT();
4580 bzero(net, sizeof(struct sctp_nets));
4581 (void)SCTP_GETTIME_TIMEVAL(&net->start_time);
t00fcxen907930b2012-09-12 19:43:22 +00004582#ifdef HAVE_SA_LEN
4583 memcpy(&net->ro._l_addr, newaddr, newaddr->sa_len);
4584#endif
tuexendd729232011-11-01 23:04:43 +00004585 switch (newaddr->sa_family) {
4586#ifdef INET
4587 case AF_INET:
t00fcxen907930b2012-09-12 19:43:22 +00004588#ifndef HAVE_SA_LEN
tuexendd729232011-11-01 23:04:43 +00004589 memcpy(&net->ro._l_addr, newaddr, sizeof(struct sockaddr_in));
4590#endif
4591 ((struct sockaddr_in *)&net->ro._l_addr)->sin_port = stcb->rport;
4592 break;
4593#endif
4594#ifdef INET6
4595 case AF_INET6:
t00fcxen907930b2012-09-12 19:43:22 +00004596#ifndef HAVE_SA_LEN
tuexendd729232011-11-01 23:04:43 +00004597 memcpy(&net->ro._l_addr, newaddr, sizeof(struct sockaddr_in6));
4598#endif
4599 ((struct sockaddr_in6 *)&net->ro._l_addr)->sin6_port = stcb->rport;
4600 break;
4601#endif
tuexencc2b1422012-07-10 21:50:32 +00004602#if defined(__Userspace__)
4603 case AF_CONN:
t00fcxen907930b2012-09-12 19:43:22 +00004604#ifndef HAVE_SA_LEN
tuexencc2b1422012-07-10 21:50:32 +00004605 memcpy(&net->ro._l_addr, newaddr, sizeof(struct sockaddr_conn));
4606#endif
4607 ((struct sockaddr_conn *)&net->ro._l_addr)->sconn_port = stcb->rport;
4608 break;
4609#endif
tuexendd729232011-11-01 23:04:43 +00004610 default:
4611 break;
4612 }
4613 net->addr_is_local = sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id);
4614 if (net->addr_is_local && ((set_scope || (from == SCTP_ADDR_IS_CONFIRMED)))) {
t00fcxend0ad16b2013-02-09 18:34:24 +00004615 stcb->asoc.scope.loopback_scope = 1;
4616 stcb->asoc.scope.ipv4_local_scope = 1;
4617 stcb->asoc.scope.local_scope = 0;
4618 stcb->asoc.scope.site_scope = 1;
tuexendd729232011-11-01 23:04:43 +00004619 addr_inscope = 1;
4620 }
4621 net->failure_threshold = stcb->asoc.def_net_failure;
4622 net->pf_threshold = stcb->asoc.def_net_pf_threshold;
4623 if (addr_inscope == 0) {
4624 net->dest_state = (SCTP_ADDR_REACHABLE |
4625 SCTP_ADDR_OUT_OF_SCOPE);
4626 } else {
4627 if (from == SCTP_ADDR_IS_CONFIRMED)
4628 /* SCTP_ADDR_IS_CONFIRMED is passed by connect_x */
4629 net->dest_state = SCTP_ADDR_REACHABLE;
4630 else
4631 net->dest_state = SCTP_ADDR_REACHABLE |
4632 SCTP_ADDR_UNCONFIRMED;
4633 }
4634 /* We set this to 0, the timer code knows that
4635 * this means its an initial value
4636 */
4637 net->rto_needed = 1;
t00fcxen8dd95b82014-07-11 20:41:28 +00004638 net->RTO = 0;
tuexendd729232011-11-01 23:04:43 +00004639 net->RTO_measured = 0;
4640 stcb->asoc.numnets++;
tuexen9d7b2072011-11-20 16:35:17 +00004641 net->ref_count = 1;
tuexendd729232011-11-01 23:04:43 +00004642 net->cwr_window_tsn = net->last_cwr_tsn = stcb->asoc.sending_seq - 1;
Michael Tuexen27574422016-04-30 16:35:29 +02004643 net->port = port;
tuexendd729232011-11-01 23:04:43 +00004644 net->dscp = stcb->asoc.default_dscp;
4645#ifdef INET6
4646 net->flowlabel = stcb->asoc.default_flowlabel;
4647#endif
4648 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) {
4649 net->dest_state |= SCTP_ADDR_NOHB;
4650 } else {
4651 net->dest_state &= ~SCTP_ADDR_NOHB;
4652 }
4653 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) {
4654 net->dest_state |= SCTP_ADDR_NO_PMTUD;
4655 } else {
4656 net->dest_state &= ~SCTP_ADDR_NO_PMTUD;
4657 }
4658 net->heart_beat_delay = stcb->asoc.heart_beat_delay;
4659 /* Init the timer structure */
4660 SCTP_OS_TIMER_INIT(&net->rxt_timer.timer);
4661 SCTP_OS_TIMER_INIT(&net->pmtu_timer.timer);
4662 SCTP_OS_TIMER_INIT(&net->hb_timer.timer);
4663
4664 /* Now generate a route for this guy */
4665#ifdef INET6
4666#ifdef SCTP_EMBEDDED_V6_SCOPE
4667 /* KAME hack: embed scopeid */
4668 if (newaddr->sa_family == AF_INET6) {
4669 struct sockaddr_in6 *sin6;
4670
4671 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
tuexene3851592012-06-01 08:31:45 +00004672#if defined(__APPLE__)
tuexen9a218b12012-08-04 21:17:58 +00004673#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
4674 (void)in6_embedscope(&sin6->sin6_addr, sin6, &stcb->sctp_ep->ip_inp.inp, NULL);
tuexendd729232011-11-01 23:04:43 +00004675#else
tuexen9a218b12012-08-04 21:17:58 +00004676 (void)in6_embedscope(&sin6->sin6_addr, sin6, &stcb->sctp_ep->ip_inp.inp, NULL, NULL);
tuexendd729232011-11-01 23:04:43 +00004677#endif
4678#elif defined(SCTP_KAME)
4679 (void)sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
4680#else
4681 (void)in6_embedscope(&sin6->sin6_addr, sin6);
4682#endif
4683#ifndef SCOPEDROUTING
4684 sin6->sin6_scope_id = 0;
4685#endif
4686 }
4687#endif /* SCTP_EMBEDDED_V6_SCOPE */
4688#endif
t00fcxena51e4462015-06-17 15:53:23 +00004689 SCTP_RTALLOC((sctp_route_t *)&net->ro,
4690 stcb->asoc.vrf_id,
4691 stcb->sctp_ep->fibnum);
tuexendd729232011-11-01 23:04:43 +00004692
t00fcxen8b6ef092014-07-11 17:37:40 +00004693#if defined(__Userspace__)
4694 net->src_addr_selected = 0;
4695#else
tuexendd729232011-11-01 23:04:43 +00004696 if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) {
4697 /* Get source address */
4698 net->ro._s_addr = sctp_source_address_selection(stcb->sctp_ep,
4699 stcb,
4700 (sctp_route_t *)&net->ro,
4701 net,
4702 0,
4703 stcb->asoc.vrf_id);
t00fcxen8b6ef092014-07-11 17:37:40 +00004704 if (net->ro._s_addr != NULL) {
4705 net->src_addr_selected = 1;
4706 /* Now get the interface MTU */
4707 if (net->ro._s_addr->ifn_p != NULL) {
4708 net->mtu = SCTP_GATHER_MTU_FROM_INTFC(net->ro._s_addr->ifn_p);
4709 }
4710 } else {
4711 net->src_addr_selected = 0;
tuexendd729232011-11-01 23:04:43 +00004712 }
tuexene81177b2011-11-15 20:48:08 +00004713 if (net->mtu > 0) {
tuexendd729232011-11-01 23:04:43 +00004714 uint32_t rmtu;
4715
4716 rmtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, net->ro.ro_rt);
4717 if (rmtu == 0) {
4718 /* Start things off to match mtu of interface please. */
4719 SCTP_SET_MTU_OF_ROUTE(&net->ro._l_addr.sa,
4720 net->ro.ro_rt, net->mtu);
4721 } else {
4722 /* we take the route mtu over the interface, since
4723 * the route may be leading out the loopback, or
4724 * a different interface.
4725 */
t00fcxen8b6ef092014-07-11 17:37:40 +00004726 net->mtu = rmtu;
tuexendd729232011-11-01 23:04:43 +00004727 }
t00fcxen8b6ef092014-07-11 17:37:40 +00004728 }
4729 } else {
4730 net->src_addr_selected = 0;
tuexen09631162012-04-18 11:23:02 +00004731 }
t00fcxen6d60eb02013-08-30 07:37:01 +00004732#endif
tuexene81177b2011-11-15 20:48:08 +00004733 if (net->mtu == 0) {
4734 switch (newaddr->sa_family) {
4735#ifdef INET
4736 case AF_INET:
4737 net->mtu = SCTP_DEFAULT_MTU;
4738 break;
4739#endif
4740#ifdef INET6
4741 case AF_INET6:
4742 net->mtu = 1280;
4743 break;
4744#endif
tuexencc2b1422012-07-10 21:50:32 +00004745#if defined(__Userspace__)
4746 case AF_CONN:
4747 net->mtu = 1280;
4748 break;
4749#endif
tuexene81177b2011-11-15 20:48:08 +00004750 default:
4751 break;
tuexendd729232011-11-01 23:04:43 +00004752 }
tuexene81177b2011-11-15 20:48:08 +00004753 }
t00fcxen1ce83bb2014-07-11 07:17:36 +00004754#if defined(INET) || defined(INET6)
tuexene81177b2011-11-15 20:48:08 +00004755 if (net->port) {
4756 net->mtu -= (uint32_t)sizeof(struct udphdr);
4757 }
t00fcxen5ab37c82014-06-30 20:55:44 +00004758#endif
tuexene81177b2011-11-15 20:48:08 +00004759 if (from == SCTP_ALLOC_ASOC) {
4760 stcb->asoc.smallest_mtu = net->mtu;
4761 }
4762 if (stcb->asoc.smallest_mtu > net->mtu) {
Michael Tuexen923f7352016-05-01 23:55:35 +02004763 sctp_pathmtu_adjustment(stcb, net->mtu);
tuexendd729232011-11-01 23:04:43 +00004764 }
4765#ifdef INET6
4766#ifdef SCTP_EMBEDDED_V6_SCOPE
4767 if (newaddr->sa_family == AF_INET6) {
4768 struct sockaddr_in6 *sin6;
4769
4770 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
4771#ifdef SCTP_KAME
4772 (void)sa6_recoverscope(sin6);
4773#else
4774 (void)in6_recoverscope(sin6, &sin6->sin6_addr, NULL);
4775#endif /* SCTP_KAME */
4776 }
4777#endif /* SCTP_EMBEDDED_V6_SCOPE */
4778#endif
tuexendd729232011-11-01 23:04:43 +00004779
4780 /* JRS - Use the congestion control given in the CC module */
tuexen09631162012-04-18 11:23:02 +00004781 if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL)
tuexendd729232011-11-01 23:04:43 +00004782 (*stcb->asoc.cc_functions.sctp_set_initial_cc_param)(stcb, net);
4783
4784 /*
4785 * CMT: CUC algo - set find_pseudo_cumack to TRUE (1) at beginning
4786 * of assoc (2005/06/27, iyengar@cis.udel.edu)
4787 */
4788 net->find_pseudo_cumack = 1;
4789 net->find_rtx_pseudo_cumack = 1;
tuexendd729232011-11-01 23:04:43 +00004790#if defined(__FreeBSD__)
4791 /* Choose an initial flowid. */
4792 net->flowid = stcb->asoc.my_vtag ^
4793 ntohs(stcb->rport) ^
4794 ntohs(stcb->sctp_ep->sctp_lport);
t00fcxenb9ccd4f2014-12-05 07:49:28 +00004795 net->flowtype = M_HASHTYPE_OPAQUE;
tuexendd729232011-11-01 23:04:43 +00004796#endif
4797 if (netp) {
4798 *netp = net;
4799 }
4800 netfirst = TAILQ_FIRST(&stcb->asoc.nets);
4801 if (net->ro.ro_rt == NULL) {
4802 /* Since we have no route put it at the back */
4803 TAILQ_INSERT_TAIL(&stcb->asoc.nets, net, sctp_next);
4804 } else if (netfirst == NULL) {
4805 /* We are the first one in the pool. */
4806 TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next);
4807 } else if (netfirst->ro.ro_rt == NULL) {
4808 /*
4809 * First one has NO route. Place this one ahead of the first
4810 * one.
4811 */
4812 TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next);
4813#ifndef __Panda__
4814 } else if (net->ro.ro_rt->rt_ifp != netfirst->ro.ro_rt->rt_ifp) {
4815 /*
4816 * This one has a different interface than the one at the
4817 * top of the list. Place it ahead.
4818 */
4819 TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next);
4820#endif
4821 } else {
4822 /*
4823 * Ok we have the same interface as the first one. Move
4824 * forward until we find either a) one with a NULL route...
4825 * insert ahead of that b) one with a different ifp.. insert
4826 * after that. c) end of the list.. insert at the tail.
4827 */
4828 struct sctp_nets *netlook;
4829
4830 do {
4831 netlook = TAILQ_NEXT(netfirst, sctp_next);
4832 if (netlook == NULL) {
4833 /* End of the list */
4834 TAILQ_INSERT_TAIL(&stcb->asoc.nets, net, sctp_next);
4835 break;
4836 } else if (netlook->ro.ro_rt == NULL) {
4837 /* next one has NO route */
4838 TAILQ_INSERT_BEFORE(netfirst, net, sctp_next);
4839 break;
4840 }
4841#ifndef __Panda__
4842 else if (netlook->ro.ro_rt->rt_ifp != net->ro.ro_rt->rt_ifp)
4843#else
4844 else
4845#endif
4846 {
4847 TAILQ_INSERT_AFTER(&stcb->asoc.nets, netlook,
4848 net, sctp_next);
4849 break;
4850 }
4851#ifndef __Panda__
4852 /* Shift forward */
4853 netfirst = netlook;
4854#endif
4855 } while (netlook != NULL);
4856 }
4857
4858 /* got to have a primary set */
4859 if (stcb->asoc.primary_destination == 0) {
4860 stcb->asoc.primary_destination = net;
4861 } else if ((stcb->asoc.primary_destination->ro.ro_rt == NULL) &&
4862 (net->ro.ro_rt) &&
4863 ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0)) {
4864 /* No route to current primary adopt new primary */
4865 stcb->asoc.primary_destination = net;
4866 }
4867 /* Validate primary is first */
4868 net = TAILQ_FIRST(&stcb->asoc.nets);
4869 if ((net != stcb->asoc.primary_destination) &&
4870 (stcb->asoc.primary_destination)) {
4871 /* first one on the list is NOT the primary
4872 * sctp_cmpaddr() is much more efficient if
4873 * the primary is the first on the list, make it
4874 * so.
4875 */
4876 TAILQ_REMOVE(&stcb->asoc.nets,
4877 stcb->asoc.primary_destination, sctp_next);
4878 TAILQ_INSERT_HEAD(&stcb->asoc.nets,
4879 stcb->asoc.primary_destination, sctp_next);
4880 }
4881 return (0);
4882}
4883
4884
4885static uint32_t
4886sctp_aloc_a_assoc_id(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
4887{
4888 uint32_t id;
4889 struct sctpasochead *head;
4890 struct sctp_tcb *lstcb;
4891
4892 SCTP_INP_WLOCK(inp);
4893 try_again:
4894 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
4895 /* TSNH */
4896 SCTP_INP_WUNLOCK(inp);
4897 return (0);
4898 }
4899 /*
4900 * We don't allow assoc id to be one of SCTP_FUTURE_ASSOC,
4901 * SCTP_CURRENT_ASSOC and SCTP_ALL_ASSOC.
4902 */
4903 if (inp->sctp_associd_counter <= SCTP_ALL_ASSOC) {
4904 inp->sctp_associd_counter = SCTP_ALL_ASSOC + 1;
4905 }
4906 id = inp->sctp_associd_counter;
4907 inp->sctp_associd_counter++;
4908 lstcb = sctp_findasoc_ep_asocid_locked(inp, (sctp_assoc_t)id, 0);
4909 if (lstcb) {
4910 goto try_again;
4911 }
4912 head = &inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(id, inp->hashasocidmark)];
4913 LIST_INSERT_HEAD(head, stcb, sctp_tcbasocidhash);
4914 stcb->asoc.in_asocid_hash = 1;
4915 SCTP_INP_WUNLOCK(inp);
4916 return id;
4917}
4918
4919/*
4920 * allocate an association and add it to the endpoint. The caller must be
4921 * careful to add all additional addresses once they are know right away or
4922 * else the assoc will be may experience a blackout scenario.
4923 */
4924struct sctp_tcb *
4925sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
Michael Tuexen49335e12015-12-06 17:31:45 +01004926 int *error, uint32_t override_tag, uint32_t vrf_id,
Michael Tuexen923f7352016-05-01 23:55:35 +02004927 uint16_t o_streams, uint16_t port,
tuexendd729232011-11-01 23:04:43 +00004928#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
4929 struct thread *p
4930#elif defined(__Windows__)
4931 PKTHREAD p
4932#else
4933#if defined(__Userspace__)
4934 /* __Userspace__ NULL proc is going to be passed here. See sctp_lower_sosend */
4935#endif
4936 struct proc *p
4937#endif
4938)
4939{
4940 /* note the p argument is only valid in unbound sockets */
4941
4942 struct sctp_tcb *stcb;
4943 struct sctp_association *asoc;
4944 struct sctpasochead *head;
4945 uint16_t rport;
4946 int err;
4947
4948 /*
4949 * Assumption made here: Caller has done a
4950 * sctp_findassociation_ep_addr(ep, addr's); to make sure the
4951 * address does not exist already.
4952 */
4953 if (SCTP_BASE_INFO(ipi_count_asoc) >= SCTP_MAX_NUM_OF_ASOC) {
4954 /* Hit max assoc, sorry no more */
4955 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
4956 *error = ENOBUFS;
4957 return (NULL);
4958 }
4959 if (firstaddr == NULL) {
4960 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
4961 *error = EINVAL;
4962 return (NULL);
4963 }
4964 SCTP_INP_RLOCK(inp);
4965 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) &&
4966 ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE)) ||
4967 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) {
4968 /*
4969 * If its in the TCP pool, its NOT allowed to create an
4970 * association. The parent listener needs to call
4971 * sctp_aloc_assoc.. or the one-2-many socket. If a peeled
4972 * off, or connected one does this.. its an error.
4973 */
4974 SCTP_INP_RUNLOCK(inp);
4975 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
4976 *error = EINVAL;
4977 return (NULL);
4978 }
4979 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
4980 (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)) {
4981 if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) ||
4982 (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED)) {
4983 SCTP_INP_RUNLOCK(inp);
4984 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
4985 *error = EINVAL;
4986 return (NULL);
4987 }
4988 }
4989 SCTPDBG(SCTP_DEBUG_PCB3, "Allocate an association for peer:");
4990#ifdef SCTP_DEBUG
4991 if (firstaddr) {
4992 SCTPDBG_ADDR(SCTP_DEBUG_PCB3, firstaddr);
4993 switch (firstaddr->sa_family) {
4994#ifdef INET
4995 case AF_INET:
4996 SCTPDBG(SCTP_DEBUG_PCB3, "Port:%d\n",
4997 ntohs(((struct sockaddr_in *)firstaddr)->sin_port));
4998 break;
4999#endif
5000#ifdef INET6
5001 case AF_INET6:
5002 SCTPDBG(SCTP_DEBUG_PCB3, "Port:%d\n",
5003 ntohs(((struct sockaddr_in6 *)firstaddr)->sin6_port));
5004 break;
5005#endif
tuexencc2b1422012-07-10 21:50:32 +00005006#if defined(__Userspace__)
5007 case AF_CONN:
5008 SCTPDBG(SCTP_DEBUG_PCB3, "Port:%d\n",
5009 ntohs(((struct sockaddr_conn *)firstaddr)->sconn_port));
5010 break;
5011#endif
tuexendd729232011-11-01 23:04:43 +00005012 default:
5013 break;
5014 }
5015 } else {
5016 SCTPDBG(SCTP_DEBUG_PCB3,"None\n");
5017 }
5018#endif /* SCTP_DEBUG */
5019 switch (firstaddr->sa_family) {
5020#ifdef INET
5021 case AF_INET:
5022 {
5023 struct sockaddr_in *sin;
5024
5025 sin = (struct sockaddr_in *)firstaddr;
5026 if ((ntohs(sin->sin_port) == 0) ||
5027 (sin->sin_addr.s_addr == INADDR_ANY) ||
5028 (sin->sin_addr.s_addr == INADDR_BROADCAST) ||
5029 IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
5030 /* Invalid address */
5031 SCTP_INP_RUNLOCK(inp);
5032 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
5033 *error = EINVAL;
5034 return (NULL);
5035 }
5036 rport = sin->sin_port;
5037 break;
5038 }
5039#endif
5040#ifdef INET6
5041 case AF_INET6:
5042 {
5043 struct sockaddr_in6 *sin6;
5044
5045 sin6 = (struct sockaddr_in6 *)firstaddr;
5046 if ((ntohs(sin6->sin6_port) == 0) ||
5047 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
5048 IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
5049 /* Invalid address */
5050 SCTP_INP_RUNLOCK(inp);
5051 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
5052 *error = EINVAL;
5053 return (NULL);
5054 }
5055 rport = sin6->sin6_port;
5056 break;
5057 }
5058#endif
tuexencc2b1422012-07-10 21:50:32 +00005059#if defined(__Userspace__)
5060 case AF_CONN:
5061 {
5062 struct sockaddr_conn *sconn;
5063
5064 sconn = (struct sockaddr_conn *)firstaddr;
5065 if ((ntohs(sconn->sconn_port) == 0) ||
5066 (sconn->sconn_addr == NULL)) {
5067 /* Invalid address */
5068 SCTP_INP_RUNLOCK(inp);
5069 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
5070 *error = EINVAL;
5071 return (NULL);
5072 }
5073 rport = sconn->sconn_port;
5074 break;
5075 }
5076#endif
tuexendd729232011-11-01 23:04:43 +00005077 default:
5078 /* not supported family type */
5079 SCTP_INP_RUNLOCK(inp);
5080 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
5081 *error = EINVAL;
5082 return (NULL);
5083 }
5084 SCTP_INP_RUNLOCK(inp);
5085 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
5086 /*
5087 * If you have not performed a bind, then we need to do the
5088 * ephemeral bind for you.
5089 */
5090 if ((err = sctp_inpcb_bind(inp->sctp_socket,
5091 (struct sockaddr *)NULL,
5092 (struct sctp_ifa *)NULL,
5093#ifndef __Panda__
5094 p
5095#else
5096 (struct proc *)NULL
5097#endif
5098 ))) {
5099 /* bind error, probably perm */
5100 *error = err;
5101 return (NULL);
5102 }
5103 }
5104 stcb = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_asoc), struct sctp_tcb);
5105 if (stcb == NULL) {
5106 /* out of memory? */
5107 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOMEM);
5108 *error = ENOMEM;
5109 return (NULL);
5110 }
5111 SCTP_INCR_ASOC_COUNT();
5112
5113 bzero(stcb, sizeof(*stcb));
5114 asoc = &stcb->asoc;
5115
5116 asoc->assoc_id = sctp_aloc_a_assoc_id(inp, stcb);
5117 SCTP_TCB_LOCK_INIT(stcb);
5118 SCTP_TCB_SEND_LOCK_INIT(stcb);
5119 stcb->rport = rport;
5120 /* setup back pointer's */
5121 stcb->sctp_ep = inp;
5122 stcb->sctp_socket = inp->sctp_socket;
Michael Tuexen49335e12015-12-06 17:31:45 +01005123 if ((err = sctp_init_asoc(inp, stcb, override_tag, vrf_id, o_streams))) {
tuexendd729232011-11-01 23:04:43 +00005124 /* failed */
5125 SCTP_TCB_LOCK_DESTROY(stcb);
5126 SCTP_TCB_SEND_LOCK_DESTROY(stcb);
5127 LIST_REMOVE(stcb, sctp_tcbasocidhash);
5128 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
5129 SCTP_DECR_ASOC_COUNT();
5130 *error = err;
5131 return (NULL);
5132 }
5133 /* and the port */
5134 SCTP_INP_INFO_WLOCK();
5135 SCTP_INP_WLOCK(inp);
5136 if (inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
5137 /* inpcb freed while alloc going on */
5138 SCTP_TCB_LOCK_DESTROY(stcb);
5139 SCTP_TCB_SEND_LOCK_DESTROY(stcb);
5140 LIST_REMOVE(stcb, sctp_tcbasocidhash);
5141 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
5142 SCTP_INP_WUNLOCK(inp);
5143 SCTP_INP_INFO_WUNLOCK();
5144 SCTP_DECR_ASOC_COUNT();
5145 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
5146 *error = EINVAL;
5147 return (NULL);
5148 }
5149 SCTP_TCB_LOCK(stcb);
5150
5151 /* now that my_vtag is set, add it to the hash */
5152 head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
5153 /* put it in the bucket in the vtag hash of assoc's for the system */
5154 LIST_INSERT_HEAD(head, stcb, sctp_asocs);
5155 SCTP_INP_INFO_WUNLOCK();
5156
Michael Tuexen923f7352016-05-01 23:55:35 +02005157 if ((err = sctp_add_remote_addr(stcb, firstaddr, NULL, port, SCTP_DO_SETSCOPE, SCTP_ALLOC_ASOC))) {
tuexendd729232011-11-01 23:04:43 +00005158 /* failure.. memory error? */
5159 if (asoc->strmout) {
5160 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
5161 asoc->strmout = NULL;
5162 }
5163 if (asoc->mapping_array) {
5164 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
5165 asoc->mapping_array = NULL;
5166 }
5167 if (asoc->nr_mapping_array) {
5168 SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
5169 asoc->nr_mapping_array = NULL;
5170 }
5171 SCTP_DECR_ASOC_COUNT();
t00fcxen2c2ff922013-11-03 14:03:35 +00005172 SCTP_TCB_UNLOCK(stcb);
tuexendd729232011-11-01 23:04:43 +00005173 SCTP_TCB_LOCK_DESTROY(stcb);
5174 SCTP_TCB_SEND_LOCK_DESTROY(stcb);
5175 LIST_REMOVE(stcb, sctp_tcbasocidhash);
5176 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
5177 SCTP_INP_WUNLOCK(inp);
5178 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
5179 *error = ENOBUFS;
5180 return (NULL);
5181 }
5182 /* Init all the timers */
5183 SCTP_OS_TIMER_INIT(&asoc->dack_timer.timer);
5184 SCTP_OS_TIMER_INIT(&asoc->strreset_timer.timer);
5185 SCTP_OS_TIMER_INIT(&asoc->asconf_timer.timer);
5186 SCTP_OS_TIMER_INIT(&asoc->shut_guard_timer.timer);
5187 SCTP_OS_TIMER_INIT(&asoc->autoclose_timer.timer);
5188 SCTP_OS_TIMER_INIT(&asoc->delayed_event_timer.timer);
5189 SCTP_OS_TIMER_INIT(&asoc->delete_prim_timer.timer);
5190
5191 LIST_INSERT_HEAD(&inp->sctp_asoc_list, stcb, sctp_tcblist);
5192 /* now file the port under the hash as well */
5193 if (inp->sctp_tcbhash != NULL) {
5194 head = &inp->sctp_tcbhash[SCTP_PCBHASH_ALLADDR(stcb->rport,
5195 inp->sctp_hashmark)];
5196 LIST_INSERT_HEAD(head, stcb, sctp_tcbhash);
5197 }
5198 SCTP_INP_WUNLOCK(inp);
t00fcxen8fca7ff2012-09-05 18:58:42 +00005199 SCTPDBG(SCTP_DEBUG_PCB1, "Association %p now allocated\n", (void *)stcb);
tuexendd729232011-11-01 23:04:43 +00005200 return (stcb);
5201}
5202
5203
5204void
5205sctp_remove_net(struct sctp_tcb *stcb, struct sctp_nets *net)
5206{
5207 struct sctp_association *asoc;
5208
5209 asoc = &stcb->asoc;
5210 asoc->numnets--;
5211 TAILQ_REMOVE(&asoc->nets, net, sctp_next);
5212 if (net == asoc->primary_destination) {
5213 /* Reset primary */
5214 struct sctp_nets *lnet;
5215
5216 lnet = TAILQ_FIRST(&asoc->nets);
5217 /* Mobility adaptation
5218 Ideally, if deleted destination is the primary, it becomes
5219 a fast retransmission trigger by the subsequent SET PRIMARY.
5220 (by micchie)
5221 */
5222 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
t00fcxen8dd95b82014-07-11 20:41:28 +00005223 SCTP_MOBILITY_BASE) ||
tuexendd729232011-11-01 23:04:43 +00005224 sctp_is_mobility_feature_on(stcb->sctp_ep,
t00fcxen8dd95b82014-07-11 20:41:28 +00005225 SCTP_MOBILITY_FASTHANDOFF)) {
tuexendd729232011-11-01 23:04:43 +00005226 SCTPDBG(SCTP_DEBUG_ASCONF1, "remove_net: primary dst is deleting\n");
5227 if (asoc->deleted_primary != NULL) {
5228 SCTPDBG(SCTP_DEBUG_ASCONF1, "remove_net: deleted primary may be already stored\n");
5229 goto out;
5230 }
5231 asoc->deleted_primary = net;
5232 atomic_add_int(&net->ref_count, 1);
5233 memset(&net->lastsa, 0, sizeof(net->lastsa));
5234 memset(&net->lastsv, 0, sizeof(net->lastsv));
5235 sctp_mobility_feature_on(stcb->sctp_ep,
5236 SCTP_MOBILITY_PRIM_DELETED);
5237 sctp_timer_start(SCTP_TIMER_TYPE_PRIM_DELETED,
5238 stcb->sctp_ep, stcb, NULL);
5239 }
5240out:
5241 /* Try to find a confirmed primary */
5242 asoc->primary_destination = sctp_find_alternate_net(stcb, lnet, 0);
5243 }
5244 if (net == asoc->last_data_chunk_from) {
5245 /* Reset primary */
5246 asoc->last_data_chunk_from = TAILQ_FIRST(&asoc->nets);
5247 }
5248 if (net == asoc->last_control_chunk_from) {
5249 /* Clear net */
5250 asoc->last_control_chunk_from = NULL;
5251 }
5252 if (net == stcb->asoc.alternate) {
5253 sctp_free_remote_addr(stcb->asoc.alternate);
5254 stcb->asoc.alternate = NULL;
5255 }
5256 sctp_free_remote_addr(net);
5257}
5258
5259/*
5260 * remove a remote endpoint address from an association, it will fail if the
5261 * address does not exist.
5262 */
5263int
5264sctp_del_remote_addr(struct sctp_tcb *stcb, struct sockaddr *remaddr)
5265{
5266 /*
5267 * Here we need to remove a remote address. This is quite simple, we
5268 * first find it in the list of address for the association
5269 * (tasoc->asoc.nets) and then if it is there, we do a LIST_REMOVE
5270 * on that item. Note we do not allow it to be removed if there are
5271 * no other addresses.
5272 */
5273 struct sctp_association *asoc;
5274 struct sctp_nets *net, *nnet;
5275
5276 asoc = &stcb->asoc;
5277
5278 /* locate the address */
5279 TAILQ_FOREACH_SAFE(net, &asoc->nets, sctp_next, nnet) {
5280 if (net->ro._l_addr.sa.sa_family != remaddr->sa_family) {
5281 continue;
5282 }
5283 if (sctp_cmpaddr((struct sockaddr *)&net->ro._l_addr,
5284 remaddr)) {
5285 /* we found the guy */
5286 if (asoc->numnets < 2) {
5287 /* Must have at LEAST two remote addresses */
5288 return (-1);
5289 } else {
5290 sctp_remove_net(stcb, net);
5291 return (0);
5292 }
5293 }
5294 }
5295 /* not found. */
5296 return (-2);
5297}
5298
5299void
5300sctp_delete_from_timewait(uint32_t tag, uint16_t lport, uint16_t rport)
5301{
5302 struct sctpvtaghead *chain;
5303 struct sctp_tagblock *twait_block;
tuexen63fc0bb2011-12-27 12:24:52 +00005304 int found = 0;
tuexendd729232011-11-01 23:04:43 +00005305 int i;
5306
5307 chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
t00fcxen14f8fbb2013-06-25 09:32:47 +00005308 LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
5309 for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
5310 if ((twait_block->vtag_block[i].v_tag == tag) &&
5311 (twait_block->vtag_block[i].lport == lport) &&
5312 (twait_block->vtag_block[i].rport == rport)) {
5313 twait_block->vtag_block[i].tv_sec_at_expire = 0;
5314 twait_block->vtag_block[i].v_tag = 0;
5315 twait_block->vtag_block[i].lport = 0;
5316 twait_block->vtag_block[i].rport = 0;
5317 found = 1;
tuexendd729232011-11-01 23:04:43 +00005318 break;
t00fcxen14f8fbb2013-06-25 09:32:47 +00005319 }
tuexendd729232011-11-01 23:04:43 +00005320 }
t00fcxen14f8fbb2013-06-25 09:32:47 +00005321 if (found)
5322 break;
tuexendd729232011-11-01 23:04:43 +00005323 }
5324}
5325
5326int
5327sctp_is_in_timewait(uint32_t tag, uint16_t lport, uint16_t rport)
5328{
5329 struct sctpvtaghead *chain;
5330 struct sctp_tagblock *twait_block;
tuexen63fc0bb2011-12-27 12:24:52 +00005331 int found = 0;
tuexendd729232011-11-01 23:04:43 +00005332 int i;
5333
5334 SCTP_INP_INFO_WLOCK();
5335 chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
t00fcxen14f8fbb2013-06-25 09:32:47 +00005336 LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
5337 for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
5338 if ((twait_block->vtag_block[i].v_tag == tag) &&
5339 (twait_block->vtag_block[i].lport == lport) &&
5340 (twait_block->vtag_block[i].rport == rport)) {
5341 found = 1;
tuexendd729232011-11-01 23:04:43 +00005342 break;
t00fcxen14f8fbb2013-06-25 09:32:47 +00005343 }
tuexendd729232011-11-01 23:04:43 +00005344 }
t00fcxen14f8fbb2013-06-25 09:32:47 +00005345 if (found)
5346 break;
tuexendd729232011-11-01 23:04:43 +00005347 }
5348 SCTP_INP_INFO_WUNLOCK();
tuexen63fc0bb2011-12-27 12:24:52 +00005349 return (found);
tuexendd729232011-11-01 23:04:43 +00005350}
5351
5352
5353void
5354sctp_add_vtag_to_timewait(uint32_t tag, uint32_t time, uint16_t lport, uint16_t rport)
5355{
5356 struct sctpvtaghead *chain;
5357 struct sctp_tagblock *twait_block;
5358 struct timeval now;
5359 int set, i;
5360
5361 if (time == 0) {
5362 /* Its disabled */
5363 return;
5364 }
5365 (void)SCTP_GETTIME_TIMEVAL(&now);
5366 chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
5367 set = 0;
t00fcxen14f8fbb2013-06-25 09:32:47 +00005368 LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
tuexendd729232011-11-01 23:04:43 +00005369 /* Block(s) present, lets find space, and expire on the fly */
t00fcxen14f8fbb2013-06-25 09:32:47 +00005370 for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
5371 if ((twait_block->vtag_block[i].v_tag == 0) &&
5372 !set) {
5373 twait_block->vtag_block[i].tv_sec_at_expire =
5374 now.tv_sec + time;
5375 twait_block->vtag_block[i].v_tag = tag;
5376 twait_block->vtag_block[i].lport = lport;
5377 twait_block->vtag_block[i].rport = rport;
5378 set = 1;
5379 } else if ((twait_block->vtag_block[i].v_tag) &&
5380 ((long)twait_block->vtag_block[i].tv_sec_at_expire < now.tv_sec)) {
5381 /* Audit expires this guy */
5382 twait_block->vtag_block[i].tv_sec_at_expire = 0;
5383 twait_block->vtag_block[i].v_tag = 0;
5384 twait_block->vtag_block[i].lport = 0;
5385 twait_block->vtag_block[i].rport = 0;
5386 if (set == 0) {
5387 /* Reuse it for my new tag */
5388 twait_block->vtag_block[i].tv_sec_at_expire = now.tv_sec + time;
tuexendd729232011-11-01 23:04:43 +00005389 twait_block->vtag_block[i].v_tag = tag;
5390 twait_block->vtag_block[i].lport = lport;
5391 twait_block->vtag_block[i].rport = rport;
5392 set = 1;
tuexendd729232011-11-01 23:04:43 +00005393 }
5394 }
t00fcxen14f8fbb2013-06-25 09:32:47 +00005395 }
5396 if (set) {
5397 /*
5398 * We only do up to the block where we can
5399 * place our tag for audits
5400 */
5401 break;
tuexendd729232011-11-01 23:04:43 +00005402 }
5403 }
5404 /* Need to add a new block to chain */
5405 if (!set) {
5406 SCTP_MALLOC(twait_block, struct sctp_tagblock *,
5407 sizeof(struct sctp_tagblock), SCTP_M_TIMW);
5408 if (twait_block == NULL) {
5409#ifdef INVARIANTS
5410 panic("Can not alloc tagblock");
5411#endif
5412 return;
5413 }
5414 memset(twait_block, 0, sizeof(struct sctp_tagblock));
5415 LIST_INSERT_HEAD(chain, twait_block, sctp_nxt_tagblock);
5416 twait_block->vtag_block[0].tv_sec_at_expire = now.tv_sec + time;
5417 twait_block->vtag_block[0].v_tag = tag;
5418 twait_block->vtag_block[0].lport = lport;
5419 twait_block->vtag_block[0].rport = rport;
5420 }
5421}
5422
Michael Tuexene5001952016-04-17 19:25:27 +02005423void
5424sctp_clean_up_stream(struct sctp_tcb *stcb, struct sctp_readhead *rh)
5425{
5426 struct sctp_tmit_chunk *chk, *nchk;
5427 struct sctp_queued_to_read *ctl, *nctl;
5428 TAILQ_FOREACH_SAFE(ctl, rh, next_instrm, nctl) {
5429 TAILQ_REMOVE(rh, ctl, next_instrm);
5430 ctl->on_strm_q = 0;
5431 if (ctl->on_read_q == 0) {
5432 sctp_free_remote_addr(ctl->whoFrom);
5433 if (ctl->data) {
5434 sctp_m_freem(ctl->data);
5435 ctl->data = NULL;
5436 }
5437 }
5438 /* Reassembly free? */
5439 TAILQ_FOREACH_SAFE(chk, &ctl->reasm, sctp_next, nchk) {
5440 TAILQ_REMOVE(&ctl->reasm, chk, sctp_next);
5441 if (chk->data) {
5442 sctp_m_freem(chk->data);
5443 chk->data = NULL;
5444 }
5445 if (chk->holds_key_ref)
5446 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
5447 sctp_free_remote_addr(chk->whoTo);
5448 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
5449 SCTP_DECR_CHK_COUNT();
5450 /*sa_ignore FREED_MEMORY*/
5451 }
5452 /*
5453 * We don't free the address here
5454 * since all the net's were freed
5455 * above.
5456 */
5457 if (ctl->on_read_q == 0) {
5458 sctp_free_a_readq(stcb, ctl);
5459 }
5460 }
5461}
tuexendd729232011-11-01 23:04:43 +00005462
5463#ifdef __Panda__
5464void panda_wakeup_socket(struct socket *so);
5465#endif
5466
5467/*-
5468 * Free the association after un-hashing the remote port. This
5469 * function ALWAYS returns holding NO LOCK on the stcb. It DOES
5470 * expect that the input to this function IS a locked TCB.
5471 * It will return 0, if it did NOT destroy the association (instead
5472 * it unlocks it. It will return NON-zero if it either destroyed the
5473 * association OR the association is already destroyed.
5474 */
5475int
5476sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfree, int from_location)
5477{
5478 int i;
5479 struct sctp_association *asoc;
5480 struct sctp_nets *net, *nnet;
5481 struct sctp_laddr *laddr, *naddr;
5482 struct sctp_tmit_chunk *chk, *nchk;
5483 struct sctp_asconf_addr *aparam, *naparam;
5484 struct sctp_asconf_ack *aack, *naack;
5485 struct sctp_stream_reset_list *strrst, *nstrrst;
5486 struct sctp_queued_to_read *sq, *nsq;
5487 struct sctp_stream_queue_pending *sp, *nsp;
5488 sctp_sharedkey_t *shared_key, *nshared_key;
5489 struct socket *so;
5490
5491 /* first, lets purge the entry from the hash table. */
5492#if defined(__APPLE__)
5493 sctp_lock_assert(SCTP_INP_SO(inp));
5494#endif
5495
5496#ifdef SCTP_LOG_CLOSING
5497 sctp_log_closing(inp, stcb, 6);
5498#endif
5499 if (stcb->asoc.state == 0) {
5500#ifdef SCTP_LOG_CLOSING
5501 sctp_log_closing(inp, NULL, 7);
5502#endif
5503 /* there is no asoc, really TSNH :-0 */
5504 return (1);
5505 }
5506 if (stcb->asoc.alternate) {
5507 sctp_free_remote_addr(stcb->asoc.alternate);
5508 stcb->asoc.alternate = NULL;
5509 }
5510#if !defined(__APPLE__) /* TEMP: moved to below */
5511 /* TEMP CODE */
5512 if (stcb->freed_from_where == 0) {
5513 /* Only record the first place free happened from */
5514 stcb->freed_from_where = from_location;
5515 }
5516 /* TEMP CODE */
5517#endif
5518
5519 asoc = &stcb->asoc;
5520 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
5521 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
5522 /* nothing around */
5523 so = NULL;
5524 else
5525 so = inp->sctp_socket;
5526
5527 /*
5528 * We used timer based freeing if a reader or writer is in the way.
5529 * So we first check if we are actually being called from a timer,
5530 * if so we abort early if a reader or writer is still in the way.
5531 */
5532 if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) &&
5533 (from_inpcbfree == SCTP_NORMAL_PROC)) {
5534 /*
5535 * is it the timer driving us? if so are the reader/writers
5536 * gone?
5537 */
5538 if (stcb->asoc.refcnt) {
5539 /* nope, reader or writer in the way */
5540 sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
5541 /* no asoc destroyed */
5542 SCTP_TCB_UNLOCK(stcb);
5543#ifdef SCTP_LOG_CLOSING
5544 sctp_log_closing(inp, stcb, 8);
5545#endif
5546 return (0);
5547 }
5548 }
5549 /* now clean up any other timers */
5550 (void)SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
5551 asoc->dack_timer.self = NULL;
5552 (void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
5553 /*-
5554 * For stream reset we don't blast this unless
5555 * it is a str-reset timer, it might be the
5556 * free-asoc timer which we DON'T want to
5557 * disturb.
5558 */
5559 if (asoc->strreset_timer.type == SCTP_TIMER_TYPE_STRRESET)
5560 asoc->strreset_timer.self = NULL;
5561 (void)SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer);
5562 asoc->asconf_timer.self = NULL;
5563 (void)SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer);
5564 asoc->autoclose_timer.self = NULL;
5565 (void)SCTP_OS_TIMER_STOP(&asoc->shut_guard_timer.timer);
5566 asoc->shut_guard_timer.self = NULL;
5567 (void)SCTP_OS_TIMER_STOP(&asoc->delayed_event_timer.timer);
5568 asoc->delayed_event_timer.self = NULL;
5569 /* Mobility adaptation */
5570 (void)SCTP_OS_TIMER_STOP(&asoc->delete_prim_timer.timer);
5571 asoc->delete_prim_timer.self = NULL;
5572 TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
5573 (void)SCTP_OS_TIMER_STOP(&net->rxt_timer.timer);
5574 net->rxt_timer.self = NULL;
5575 (void)SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer);
5576 net->pmtu_timer.self = NULL;
5577 (void)SCTP_OS_TIMER_STOP(&net->hb_timer.timer);
5578 net->hb_timer.self = NULL;
5579 }
5580 /* Now the read queue needs to be cleaned up (only once) */
5581 if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0) {
5582 stcb->asoc.state |= SCTP_STATE_ABOUT_TO_BE_FREED;
5583 SCTP_INP_READ_LOCK(inp);
5584 TAILQ_FOREACH(sq, &inp->read_queue, next) {
5585 if (sq->stcb == stcb) {
5586 sq->do_not_ref_stcb = 1;
5587 sq->sinfo_cumtsn = stcb->asoc.cumulative_tsn;
5588 /* If there is no end, there never
5589 * will be now.
5590 */
5591 if (sq->end_added == 0) {
5592 /* Held for PD-API clear that. */
5593 sq->pdapi_aborted = 1;
5594 sq->held_length = 0;
5595 if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_PDAPIEVNT) && (so != NULL)) {
5596 /*
5597 * Need to add a PD-API aborted indication.
5598 * Setting the control_pdapi assures that it will
5599 * be added right after this msg.
5600 */
5601 uint32_t strseq;
5602 stcb->asoc.control_pdapi = sq;
5603 strseq = (sq->sinfo_stream << 16) | sq->sinfo_ssn;
5604 sctp_ulp_notify(SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION,
5605 stcb,
5606 SCTP_PARTIAL_DELIVERY_ABORTED,
5607 (void *)&strseq,
5608 SCTP_SO_LOCKED);
5609 stcb->asoc.control_pdapi = NULL;
5610 }
5611 }
5612 /* Add an end to wake them */
5613 sq->end_added = 1;
5614 }
5615 }
5616 SCTP_INP_READ_UNLOCK(inp);
5617 if (stcb->block_entry) {
5618 SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_PCB, ECONNRESET);
5619 stcb->block_entry->error = ECONNRESET;
5620 stcb->block_entry = NULL;
5621 }
5622 }
5623 if ((stcb->asoc.refcnt) || (stcb->asoc.state & SCTP_STATE_IN_ACCEPT_QUEUE)) {
5624 /* Someone holds a reference OR the socket is unaccepted yet.
5625 */
5626 if ((stcb->asoc.refcnt) ||
5627 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
5628 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
5629 stcb->asoc.state &= ~SCTP_STATE_IN_ACCEPT_QUEUE;
5630 sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
5631 }
5632 SCTP_TCB_UNLOCK(stcb);
5633 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
5634 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
5635 /* nothing around */
5636 so = NULL;
5637 if (so) {
5638 /* Wake any reader/writers */
5639 sctp_sorwakeup(inp, so);
5640 sctp_sowwakeup(inp, so);
5641 }
5642
5643#ifdef SCTP_LOG_CLOSING
5644 sctp_log_closing(inp, stcb, 9);
5645#endif
5646 /* no asoc destroyed */
5647 return (0);
5648 }
5649#ifdef SCTP_LOG_CLOSING
5650 sctp_log_closing(inp, stcb, 10);
5651#endif
5652 /* When I reach here, no others want
5653 * to kill the assoc yet.. and I own
5654 * the lock. Now its possible an abort
5655 * comes in when I do the lock exchange
5656 * below to grab all the locks to do
5657 * the final take out. to prevent this
5658 * we increment the count, which will
5659 * start a timer and blow out above thus
5660 * assuring us that we hold exclusive
5661 * killing of the asoc. Note that
5662 * after getting back the TCB lock
5663 * we will go ahead and increment the
5664 * counter back up and stop any timer
5665 * a passing stranger may have started :-S
5666 */
5667 if (from_inpcbfree == SCTP_NORMAL_PROC) {
5668 atomic_add_int(&stcb->asoc.refcnt, 1);
5669
5670 SCTP_TCB_UNLOCK(stcb);
5671 SCTP_INP_INFO_WLOCK();
5672 SCTP_INP_WLOCK(inp);
5673 SCTP_TCB_LOCK(stcb);
5674 }
5675 /* Double check the GONE flag */
5676 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
5677 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
5678 /* nothing around */
5679 so = NULL;
5680
5681 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
5682 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
5683 /*
5684 * For TCP type we need special handling when we are
5685 * connected. We also include the peel'ed off ones to.
5686 */
5687 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
5688 inp->sctp_flags &= ~SCTP_PCB_FLAGS_CONNECTED;
5689 inp->sctp_flags |= SCTP_PCB_FLAGS_WAS_CONNECTED;
5690 if (so) {
5691 SOCK_LOCK(so);
5692 if (so->so_rcv.sb_cc == 0) {
5693 so->so_state &= ~(SS_ISCONNECTING |
5694 SS_ISDISCONNECTING |
5695 SS_ISCONFIRMING |
5696 SS_ISCONNECTED);
5697 }
5698#if defined(__APPLE__)
5699 socantrcvmore(so);
5700#else
5701 socantrcvmore_locked(so);
5702#endif
5703 sctp_sowwakeup(inp, so);
5704 sctp_sorwakeup(inp, so);
5705 SCTP_SOWAKEUP(so);
5706 }
5707 }
5708 }
5709
5710 /* Make it invalid too, that way if its
5711 * about to run it will abort and return.
5712 */
5713 /* re-increment the lock */
5714 if (from_inpcbfree == SCTP_NORMAL_PROC) {
5715 atomic_add_int(&stcb->asoc.refcnt, -1);
5716 }
5717 if (stcb->asoc.refcnt) {
5718 stcb->asoc.state &= ~SCTP_STATE_IN_ACCEPT_QUEUE;
5719 sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
5720 if (from_inpcbfree == SCTP_NORMAL_PROC) {
5721 SCTP_INP_INFO_WUNLOCK();
5722 SCTP_INP_WUNLOCK(inp);
5723 }
5724 SCTP_TCB_UNLOCK(stcb);
5725 return (0);
5726 }
5727 asoc->state = 0;
5728 if (inp->sctp_tcbhash) {
5729 LIST_REMOVE(stcb, sctp_tcbhash);
5730 }
5731 if (stcb->asoc.in_asocid_hash) {
5732 LIST_REMOVE(stcb, sctp_tcbasocidhash);
5733 }
5734 /* Now lets remove it from the list of ALL associations in the EP */
5735 LIST_REMOVE(stcb, sctp_tcblist);
5736 if (from_inpcbfree == SCTP_NORMAL_PROC) {
5737 SCTP_INP_INCR_REF(inp);
5738 SCTP_INP_WUNLOCK(inp);
5739 }
5740 /* pull from vtag hash */
5741 LIST_REMOVE(stcb, sctp_asocs);
5742 sctp_add_vtag_to_timewait(asoc->my_vtag, SCTP_BASE_SYSCTL(sctp_vtag_time_wait),
5743 inp->sctp_lport, stcb->rport);
5744
5745 /* Now restop the timers to be sure
5746 * this is paranoia at is finest!
5747 */
5748 (void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
5749 (void)SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
5750 (void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
5751 (void)SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer);
5752 (void)SCTP_OS_TIMER_STOP(&asoc->shut_guard_timer.timer);
5753 (void)SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer);
5754 (void)SCTP_OS_TIMER_STOP(&asoc->delayed_event_timer.timer);
5755 TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
5756 (void)SCTP_OS_TIMER_STOP(&net->rxt_timer.timer);
5757 (void)SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer);
5758 (void)SCTP_OS_TIMER_STOP(&net->hb_timer.timer);
5759 }
5760
5761 asoc->strreset_timer.type = SCTP_TIMER_TYPE_NONE;
5762 /*
5763 * The chunk lists and such SHOULD be empty but we check them just
5764 * in case.
5765 */
5766 /* anything on the wheel needs to be removed */
5767 for (i = 0; i < asoc->streamoutcnt; i++) {
5768 struct sctp_stream_out *outs;
5769
5770 outs = &asoc->strmout[i];
5771 /* now clean up any chunks here */
5772 TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) {
5773 TAILQ_REMOVE(&outs->outqueue, sp, next);
tuexen30ca8172012-07-17 13:09:48 +00005774 sctp_free_spbufspace(stcb, asoc, sp);
tuexendd729232011-11-01 23:04:43 +00005775 if (sp->data) {
5776 if (so) {
5777 /* Still an open socket - report */
5778 sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb,
tuexenda53ff02012-05-14 09:00:59 +00005779 0, (void *)sp, SCTP_SO_LOCKED);
tuexendd729232011-11-01 23:04:43 +00005780 }
5781 if (sp->data) {
5782 sctp_m_freem(sp->data);
5783 sp->data = NULL;
5784 sp->tail_mbuf = NULL;
tuexen30ca8172012-07-17 13:09:48 +00005785 sp->length = 0;
tuexendd729232011-11-01 23:04:43 +00005786 }
5787 }
5788 if (sp->net) {
5789 sctp_free_remote_addr(sp->net);
5790 sp->net = NULL;
5791 }
tuexen30ca8172012-07-17 13:09:48 +00005792 sctp_free_a_strmoq(stcb, sp, SCTP_SO_LOCKED);
tuexendd729232011-11-01 23:04:43 +00005793 }
5794 }
5795 /*sa_ignore FREED_MEMORY*/
5796 TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) {
5797 TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp);
5798 SCTP_FREE(strrst, SCTP_M_STRESET);
5799 }
5800 TAILQ_FOREACH_SAFE(sq, &asoc->pending_reply_queue, next, nsq) {
5801 TAILQ_REMOVE(&asoc->pending_reply_queue, sq, next);
5802 if (sq->data) {
5803 sctp_m_freem(sq->data);
5804 sq->data = NULL;
5805 }
5806 sctp_free_remote_addr(sq->whoFrom);
5807 sq->whoFrom = NULL;
5808 sq->stcb = NULL;
5809 /* Free the ctl entry */
Michael Tuexene5001952016-04-17 19:25:27 +02005810 sctp_free_a_readq(stcb, sq);
tuexendd729232011-11-01 23:04:43 +00005811 /*sa_ignore FREED_MEMORY*/
5812 }
5813 TAILQ_FOREACH_SAFE(chk, &asoc->free_chunks, sctp_next, nchk) {
5814 TAILQ_REMOVE(&asoc->free_chunks, chk, sctp_next);
5815 if (chk->data) {
5816 sctp_m_freem(chk->data);
5817 chk->data = NULL;
5818 }
5819 if (chk->holds_key_ref)
5820 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
5821 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
5822 SCTP_DECR_CHK_COUNT();
5823 atomic_subtract_int(&SCTP_BASE_INFO(ipi_free_chunks), 1);
5824 asoc->free_chunk_cnt--;
5825 /*sa_ignore FREED_MEMORY*/
5826 }
5827 /* pending send queue SHOULD be empty */
5828 TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
t00fcxen8fcc5142012-11-16 19:46:12 +00005829 if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
5830 asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
5831#ifdef INVARIANTS
5832 } else {
5833 panic("No chunks on the queues for sid %u.", chk->rec.data.stream_number);
5834#endif
5835 }
tuexendd729232011-11-01 23:04:43 +00005836 TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
5837 if (chk->data) {
5838 if (so) {
5839 /* Still a socket? */
tuexenda53ff02012-05-14 09:00:59 +00005840 sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb,
5841 0, chk, SCTP_SO_LOCKED);
tuexendd729232011-11-01 23:04:43 +00005842 }
5843 if (chk->data) {
5844 sctp_m_freem(chk->data);
5845 chk->data = NULL;
5846 }
5847 }
5848 if (chk->holds_key_ref)
5849 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
5850 if (chk->whoTo) {
5851 sctp_free_remote_addr(chk->whoTo);
5852 chk->whoTo = NULL;
5853 }
5854 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
5855 SCTP_DECR_CHK_COUNT();
5856 /*sa_ignore FREED_MEMORY*/
5857 }
5858 /* sent queue SHOULD be empty */
5859 TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
t00fcxen8fcc5142012-11-16 19:46:12 +00005860 if (chk->sent != SCTP_DATAGRAM_NR_ACKED) {
t00fcxen9ad90772012-11-07 22:19:57 +00005861 if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
5862 asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
5863#ifdef INVARIANTS
5864 } else {
5865 panic("No chunks on the queues for sid %u.", chk->rec.data.stream_number);
5866#endif
5867 }
5868 }
tuexendd729232011-11-01 23:04:43 +00005869 TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
5870 if (chk->data) {
5871 if (so) {
5872 /* Still a socket? */
tuexenda53ff02012-05-14 09:00:59 +00005873 sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb,
5874 0, chk, SCTP_SO_LOCKED);
tuexendd729232011-11-01 23:04:43 +00005875 }
5876 if (chk->data) {
5877 sctp_m_freem(chk->data);
5878 chk->data = NULL;
5879 }
5880 }
5881 if (chk->holds_key_ref)
5882 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
5883 sctp_free_remote_addr(chk->whoTo);
5884 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
5885 SCTP_DECR_CHK_COUNT();
5886 /*sa_ignore FREED_MEMORY*/
5887 }
t00fcxen8fcc5142012-11-16 19:46:12 +00005888#ifdef INVARIANTS
5889 for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
5890 if (stcb->asoc.strmout[i].chunks_on_queues > 0) {
5891 panic("%u chunks left for stream %u.", stcb->asoc.strmout[i].chunks_on_queues, i);
5892 }
5893 }
5894#endif
tuexendd729232011-11-01 23:04:43 +00005895 /* control queue MAY not be empty */
5896 TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) {
5897 TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
5898 if (chk->data) {
5899 sctp_m_freem(chk->data);
5900 chk->data = NULL;
5901 }
5902 if (chk->holds_key_ref)
5903 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
5904 sctp_free_remote_addr(chk->whoTo);
5905 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
5906 SCTP_DECR_CHK_COUNT();
5907 /*sa_ignore FREED_MEMORY*/
5908 }
5909 /* ASCONF queue MAY not be empty */
5910 TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) {
5911 TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next);
5912 if (chk->data) {
5913 sctp_m_freem(chk->data);
5914 chk->data = NULL;
5915 }
5916 if (chk->holds_key_ref)
5917 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
5918 sctp_free_remote_addr(chk->whoTo);
5919 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
5920 SCTP_DECR_CHK_COUNT();
5921 /*sa_ignore FREED_MEMORY*/
5922 }
tuexendd729232011-11-01 23:04:43 +00005923 if (asoc->mapping_array) {
5924 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
5925 asoc->mapping_array = NULL;
5926 }
5927 if (asoc->nr_mapping_array) {
5928 SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
5929 asoc->nr_mapping_array = NULL;
5930 }
5931 /* the stream outs */
5932 if (asoc->strmout) {
5933 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
5934 asoc->strmout = NULL;
5935 }
5936 asoc->strm_realoutsize = asoc->streamoutcnt = 0;
5937 if (asoc->strmin) {
tuexendd729232011-11-01 23:04:43 +00005938 for (i = 0; i < asoc->streamincnt; i++) {
Michael Tuexene5001952016-04-17 19:25:27 +02005939 sctp_clean_up_stream(stcb, &asoc->strmin[i].inqueue);
5940 sctp_clean_up_stream(stcb, &asoc->strmin[i].uno_inqueue);
tuexendd729232011-11-01 23:04:43 +00005941 }
5942 SCTP_FREE(asoc->strmin, SCTP_M_STRMI);
5943 asoc->strmin = NULL;
5944 }
5945 asoc->streamincnt = 0;
5946 TAILQ_FOREACH_SAFE(net, &asoc->nets, sctp_next, nnet) {
5947#ifdef INVARIANTS
5948 if (SCTP_BASE_INFO(ipi_count_raddr) == 0) {
5949 panic("no net's left alloc'ed, or list points to itself");
5950 }
5951#endif
5952 TAILQ_REMOVE(&asoc->nets, net, sctp_next);
5953 sctp_free_remote_addr(net);
5954 }
5955 LIST_FOREACH_SAFE(laddr, &asoc->sctp_restricted_addrs, sctp_nxt_addr, naddr) {
5956 /*sa_ignore FREED_MEMORY*/
5957 sctp_remove_laddr(laddr);
5958 }
5959
5960 /* pending asconf (address) parameters */
5961 TAILQ_FOREACH_SAFE(aparam, &asoc->asconf_queue, next, naparam) {
5962 /*sa_ignore FREED_MEMORY*/
5963 TAILQ_REMOVE(&asoc->asconf_queue, aparam, next);
5964 SCTP_FREE(aparam,SCTP_M_ASC_ADDR);
5965 }
5966 TAILQ_FOREACH_SAFE(aack, &asoc->asconf_ack_sent, next, naack) {
5967 /*sa_ignore FREED_MEMORY*/
5968 TAILQ_REMOVE(&asoc->asconf_ack_sent, aack, next);
5969 if (aack->data != NULL) {
5970 sctp_m_freem(aack->data);
5971 }
5972 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asconf_ack), aack);
5973 }
5974 /* clean up auth stuff */
5975 if (asoc->local_hmacs)
5976 sctp_free_hmaclist(asoc->local_hmacs);
5977 if (asoc->peer_hmacs)
5978 sctp_free_hmaclist(asoc->peer_hmacs);
5979
5980 if (asoc->local_auth_chunks)
5981 sctp_free_chunklist(asoc->local_auth_chunks);
5982 if (asoc->peer_auth_chunks)
5983 sctp_free_chunklist(asoc->peer_auth_chunks);
5984
5985 sctp_free_authinfo(&asoc->authinfo);
5986
5987 LIST_FOREACH_SAFE(shared_key, &asoc->shared_keys, next, nshared_key) {
5988 LIST_REMOVE(shared_key, next);
5989 sctp_free_sharedkey(shared_key);
5990 /*sa_ignore FREED_MEMORY*/
5991 }
5992
5993 /* Insert new items here :> */
5994
5995 /* Get rid of LOCK */
t00fcxen2c2ff922013-11-03 14:03:35 +00005996 SCTP_TCB_UNLOCK(stcb);
tuexendd729232011-11-01 23:04:43 +00005997 SCTP_TCB_LOCK_DESTROY(stcb);
5998 SCTP_TCB_SEND_LOCK_DESTROY(stcb);
5999 if (from_inpcbfree == SCTP_NORMAL_PROC) {
6000 SCTP_INP_INFO_WUNLOCK();
6001 SCTP_INP_RLOCK(inp);
6002 }
6003#if defined(__APPLE__) /* TEMP CODE */
6004 stcb->freed_from_where = from_location;
6005#endif
6006#ifdef SCTP_TRACK_FREED_ASOCS
6007 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
6008 /* now clean up the tasoc itself */
6009 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
6010 SCTP_DECR_ASOC_COUNT();
6011 } else {
6012 LIST_INSERT_HEAD(&inp->sctp_asoc_free_list, stcb, sctp_tcblist);
6013 }
6014#else
6015 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
6016 SCTP_DECR_ASOC_COUNT();
6017#endif
6018 if (from_inpcbfree == SCTP_NORMAL_PROC) {
6019 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
6020 /* If its NOT the inp_free calling us AND
6021 * sctp_close as been called, we
6022 * call back...
6023 */
6024 SCTP_INP_RUNLOCK(inp);
6025 /* This will start the kill timer (if we are
6026 * the last one) since we hold an increment yet. But
6027 * this is the only safe way to do this
6028 * since otherwise if the socket closes
6029 * at the same time we are here we might
6030 * collide in the cleanup.
6031 */
6032 sctp_inpcb_free(inp,
6033 SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE,
6034 SCTP_CALLED_DIRECTLY_NOCMPSET);
6035 SCTP_INP_DECR_REF(inp);
6036 goto out_of;
6037 } else {
6038 /* The socket is still open. */
6039 SCTP_INP_DECR_REF(inp);
6040 }
6041 }
6042 if (from_inpcbfree == SCTP_NORMAL_PROC) {
6043 SCTP_INP_RUNLOCK(inp);
6044 }
6045 out_of:
6046 /* destroyed the asoc */
6047#ifdef SCTP_LOG_CLOSING
6048 sctp_log_closing(inp, NULL, 11);
6049#endif
6050 return (1);
6051}
6052
6053
6054
6055/*
6056 * determine if a destination is "reachable" based upon the addresses bound
6057 * to the current endpoint (e.g. only v4 or v6 currently bound)
6058 */
6059/*
6060 * FIX: if we allow assoc-level bindx(), then this needs to be fixed to use
6061 * assoc level v4/v6 flags, as the assoc *may* not have the same address
6062 * types bound as its endpoint
6063 */
6064int
6065sctp_destination_is_reachable(struct sctp_tcb *stcb, struct sockaddr *destaddr)
6066{
6067 struct sctp_inpcb *inp;
6068 int answer;
6069
6070 /*
6071 * No locks here, the TCB, in all cases is already locked and an
6072 * assoc is up. There is either a INP lock by the caller applied (in
6073 * asconf case when deleting an address) or NOT in the HB case,
6074 * however if HB then the INP increment is up and the INP will not
6075 * be removed (on top of the fact that we have a TCB lock). So we
6076 * only want to read the sctp_flags, which is either bound-all or
6077 * not.. no protection needed since once an assoc is up you can't be
6078 * changing your binding.
6079 */
6080 inp = stcb->sctp_ep;
6081 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
6082 /* if bound all, destination is not restricted */
6083 /*
6084 * RRS: Question during lock work: Is this correct? If you
6085 * are bound-all you still might need to obey the V4--V6
6086 * flags??? IMO this bound-all stuff needs to be removed!
6087 */
6088 return (1);
6089 }
6090 /* NOTE: all "scope" checks are done when local addresses are added */
6091 switch (destaddr->sa_family) {
tuexen310f1bc2012-07-15 11:20:56 +00006092#ifdef INET6
tuexendd729232011-11-01 23:04:43 +00006093 case AF_INET6:
6094#if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
6095 answer = inp->inp_vflag & INP_IPV6;
6096#else
6097 answer = inp->ip_inp.inp.inp_vflag & INP_IPV6;
6098#endif
6099 break;
tuexen310f1bc2012-07-15 11:20:56 +00006100#endif
6101#ifdef INET
tuexendd729232011-11-01 23:04:43 +00006102 case AF_INET:
6103#if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
6104 answer = inp->inp_vflag & INP_IPV4;
6105#else
6106 answer = inp->ip_inp.inp.inp_vflag & INP_IPV4;
6107#endif
tuexen46570542012-07-14 20:37:24 +00006108 break;
tuexen310f1bc2012-07-15 11:20:56 +00006109#endif
tuexen5d9b9742012-07-11 21:52:01 +00006110#if defined(__Userspace__)
6111 case AF_CONN:
6112 answer = inp->ip_inp.inp.inp_vflag & INP_CONN;
tuexendd729232011-11-01 23:04:43 +00006113 break;
tuexen5d9b9742012-07-11 21:52:01 +00006114#endif
tuexendd729232011-11-01 23:04:43 +00006115 default:
6116 /* invalid family, so it's unreachable */
6117 answer = 0;
6118 break;
6119 }
6120 return (answer);
6121}
6122
6123/*
6124 * update the inp_vflags on an endpoint
6125 */
6126static void
6127sctp_update_ep_vflag(struct sctp_inpcb *inp)
6128{
6129 struct sctp_laddr *laddr;
6130
6131 /* first clear the flag */
6132#if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
6133 inp->inp_vflag = 0;
6134#else
6135 inp->ip_inp.inp.inp_vflag = 0;
6136#endif
6137 /* set the flag based on addresses on the ep list */
6138 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
6139 if (laddr->ifa == NULL) {
6140 SCTPDBG(SCTP_DEBUG_PCB1, "%s: NULL ifa\n",
Saúl Ibarra Corretgé8b04b412015-09-26 09:53:06 +02006141 __func__);
tuexendd729232011-11-01 23:04:43 +00006142 continue;
6143 }
6144
6145 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
6146 continue;
6147 }
6148 switch (laddr->ifa->address.sa.sa_family) {
6149#ifdef INET6
6150 case AF_INET6:
6151#if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
6152 inp->inp_vflag |= INP_IPV6;
6153#else
6154 inp->ip_inp.inp.inp_vflag |= INP_IPV6;
6155#endif
6156 break;
6157#endif
6158#ifdef INET
6159 case AF_INET:
6160#if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
6161 inp->inp_vflag |= INP_IPV4;
6162#else
6163 inp->ip_inp.inp.inp_vflag |= INP_IPV4;
6164#endif
6165 break;
6166#endif
tuexen5d9b9742012-07-11 21:52:01 +00006167#if defined(__Userspace__)
6168 case AF_CONN:
6169 inp->ip_inp.inp.inp_vflag |= INP_CONN;
6170 break;
6171#endif
tuexendd729232011-11-01 23:04:43 +00006172 default:
6173 break;
6174 }
6175 }
6176}
6177
6178/*
6179 * Add the address to the endpoint local address list There is nothing to be
6180 * done if we are bound to all addresses
6181 */
6182void
6183sctp_add_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa, uint32_t action)
6184{
6185 struct sctp_laddr *laddr;
Michael Tuexend75dc0c2016-03-28 21:38:43 +02006186 struct sctp_tcb *stcb;
tuexen63fc0bb2011-12-27 12:24:52 +00006187 int fnd, error = 0;
tuexendd729232011-11-01 23:04:43 +00006188
6189 fnd = 0;
6190
6191 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
6192 /* You are already bound to all. You have it already */
6193 return;
6194 }
6195#ifdef INET6
6196 if (ifa->address.sa.sa_family == AF_INET6) {
6197 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
6198 /* Can't bind a non-useable addr. */
6199 return;
6200 }
6201 }
6202#endif
6203 /* first, is it already present? */
6204 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
6205 if (laddr->ifa == ifa) {
6206 fnd = 1;
6207 break;
6208 }
6209 }
6210
6211 if (fnd == 0) {
6212 /* Not in the ep list */
6213 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, action);
6214 if (error != 0)
6215 return;
6216 inp->laddr_count++;
6217 /* update inp_vflag flags */
6218 switch (ifa->address.sa.sa_family) {
6219#ifdef INET6
6220 case AF_INET6:
6221#if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
6222 inp->inp_vflag |= INP_IPV6;
6223#else
6224 inp->ip_inp.inp.inp_vflag |= INP_IPV6;
6225#endif
6226 break;
6227#endif
tuexen310f1bc2012-07-15 11:20:56 +00006228#ifdef INET
tuexendd729232011-11-01 23:04:43 +00006229 case AF_INET:
6230#if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__))
6231 inp->inp_vflag |= INP_IPV4;
6232#else
6233 inp->ip_inp.inp.inp_vflag |= INP_IPV4;
6234#endif
6235 break;
6236#endif
tuexen5d9b9742012-07-11 21:52:01 +00006237#if defined(__Userspace__)
6238 case AF_CONN:
6239 inp->ip_inp.inp.inp_vflag |= INP_CONN;
6240 break;
6241#endif
tuexendd729232011-11-01 23:04:43 +00006242 default:
6243 break;
6244 }
Michael Tuexend75dc0c2016-03-28 21:38:43 +02006245 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
6246 sctp_add_local_addr_restricted(stcb, ifa);
6247 }
tuexendd729232011-11-01 23:04:43 +00006248 }
6249 return;
6250}
6251
6252
6253/*
6254 * select a new (hopefully reachable) destination net (should only be used
6255 * when we deleted an ep addr that is the only usable source address to reach
6256 * the destination net)
6257 */
6258static void
6259sctp_select_primary_destination(struct sctp_tcb *stcb)
6260{
6261 struct sctp_nets *net;
6262
6263 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
6264 /* for now, we'll just pick the first reachable one we find */
6265 if (net->dest_state & SCTP_ADDR_UNCONFIRMED)
6266 continue;
6267 if (sctp_destination_is_reachable(stcb,
6268 (struct sockaddr *)&net->ro._l_addr)) {
6269 /* found a reachable destination */
6270 stcb->asoc.primary_destination = net;
6271 }
6272 }
6273 /* I can't there from here! ...we're gonna die shortly... */
6274}
6275
6276
6277/*
Michael Tuexen24e6c732016-02-19 12:28:21 +01006278 * Delete the address from the endpoint local address list. There is nothing
tuexendd729232011-11-01 23:04:43 +00006279 * to be done if we are bound to all addresses
6280 */
6281void
6282sctp_del_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa)
6283{
6284 struct sctp_laddr *laddr;
6285 int fnd;
6286
6287 fnd = 0;
6288 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
6289 /* You are already bound to all. You have it already */
6290 return;
6291 }
6292 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
6293 if (laddr->ifa == ifa) {
6294 fnd = 1;
6295 break;
6296 }
6297 }
6298 if (fnd && (inp->laddr_count < 2)) {
6299 /* can't delete unless there are at LEAST 2 addresses */
6300 return;
6301 }
6302 if (fnd) {
6303 /*
6304 * clean up any use of this address go through our
6305 * associations and clear any last_used_address that match
6306 * this one for each assoc, see if a new primary_destination
6307 * is needed
6308 */
6309 struct sctp_tcb *stcb;
6310
6311 /* clean up "next_addr_touse" */
6312 if (inp->next_addr_touse == laddr)
6313 /* delete this address */
6314 inp->next_addr_touse = NULL;
6315
6316 /* clean up "last_used_address" */
6317 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
6318 struct sctp_nets *net;
Michael Tuexen24e6c732016-02-19 12:28:21 +01006319
tuexendd729232011-11-01 23:04:43 +00006320 SCTP_TCB_LOCK(stcb);
6321 if (stcb->asoc.last_used_address == laddr)
6322 /* delete this address */
6323 stcb->asoc.last_used_address = NULL;
6324 /* Now spin through all the nets and purge any ref to laddr */
6325 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
Michael Tuexen24e6c732016-02-19 12:28:21 +01006326 if (net->ro._s_addr == laddr->ifa) {
tuexendd729232011-11-01 23:04:43 +00006327 /* Yep, purge src address selected */
6328 sctp_rtentry_t *rt;
6329
6330 /* delete this address if cached */
6331 rt = net->ro.ro_rt;
6332 if (rt != NULL) {
6333 RTFREE(rt);
6334 net->ro.ro_rt = NULL;
6335 }
6336 sctp_free_ifa(net->ro._s_addr);
6337 net->ro._s_addr = NULL;
6338 net->src_addr_selected = 0;
6339 }
6340 }
6341 SCTP_TCB_UNLOCK(stcb);
6342 } /* for each tcb */
6343 /* remove it from the ep list */
6344 sctp_remove_laddr(laddr);
6345 inp->laddr_count--;
6346 /* update inp_vflag flags */
6347 sctp_update_ep_vflag(inp);
6348 }
6349 return;
6350}
6351
6352/*
6353 * Add the address to the TCB local address restricted list.
6354 * This is a "pending" address list (eg. addresses waiting for an
6355 * ASCONF-ACK response) and cannot be used as a valid source address.
6356 */
6357void
6358sctp_add_local_addr_restricted(struct sctp_tcb *stcb, struct sctp_ifa *ifa)
6359{
tuexendd729232011-11-01 23:04:43 +00006360 struct sctp_laddr *laddr;
6361 struct sctpladdr *list;
6362
6363 /*
6364 * Assumes TCB is locked.. and possibly the INP. May need to
6365 * confirm/fix that if we need it and is not the case.
6366 */
6367 list = &stcb->asoc.sctp_restricted_addrs;
6368
tuexendd729232011-11-01 23:04:43 +00006369#ifdef INET6
6370 if (ifa->address.sa.sa_family == AF_INET6) {
6371 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
6372 /* Can't bind a non-existent addr. */
6373 return;
6374 }
6375 }
6376#endif
6377 /* does the address already exist? */
6378 LIST_FOREACH(laddr, list, sctp_nxt_addr) {
6379 if (laddr->ifa == ifa) {
6380 return;
6381 }
6382 }
6383
6384 /* add to the list */
6385 (void)sctp_insert_laddr(list, ifa, 0);
6386 return;
6387}
6388
6389/*
tuexendd729232011-11-01 23:04:43 +00006390 * Remove a local address from the TCB local address restricted list
6391 */
6392void
6393sctp_del_local_addr_restricted(struct sctp_tcb *stcb, struct sctp_ifa *ifa)
6394{
6395 struct sctp_inpcb *inp;
6396 struct sctp_laddr *laddr;
6397
6398 /*
6399 * This is called by asconf work. It is assumed that a) The TCB is
6400 * locked and b) The INP is locked. This is true in as much as I can
6401 * trace through the entry asconf code where I did these locks.
6402 * Again, the ASCONF code is a bit different in that it does lock
6403 * the INP during its work often times. This must be since we don't
6404 * want other proc's looking up things while what they are looking
6405 * up is changing :-D
6406 */
6407
6408 inp = stcb->sctp_ep;
6409 /* if subset bound and don't allow ASCONF's, can't delete last */
6410 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) &&
6411 sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
6412 if (stcb->sctp_ep->laddr_count < 2) {
6413 /* can't delete last address */
6414 return;
6415 }
6416 }
6417 LIST_FOREACH(laddr, &stcb->asoc.sctp_restricted_addrs, sctp_nxt_addr) {
6418 /* remove the address if it exists */
6419 if (laddr->ifa == NULL)
6420 continue;
6421 if (laddr->ifa == ifa) {
6422 sctp_remove_laddr(laddr);
6423 return;
6424 }
6425 }
6426
6427 /* address not found! */
6428 return;
6429}
6430
6431#if defined(__FreeBSD__)
6432/*
6433 * Temporarily remove for __APPLE__ until we use the Tiger equivalents
6434 */
6435/* sysctl */
6436static int sctp_max_number_of_assoc = SCTP_MAX_NUM_OF_ASOC;
6437static int sctp_scale_up_for_address = SCTP_SCALE_FOR_ADDR;
6438#endif /* FreeBSD || APPLE */
6439
6440
6441
6442#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP)
tuexen63fc0bb2011-12-27 12:24:52 +00006443struct sctp_mcore_ctrl *sctp_mcore_workers = NULL;
6444int *sctp_cpuarry = NULL;
tuexendd729232011-11-01 23:04:43 +00006445void
6446sctp_queue_to_mcore(struct mbuf *m, int off, int cpu_to_use)
6447{
6448 /* Queue a packet to a processor for the specified core */
6449 struct sctp_mcore_queue *qent;
6450 struct sctp_mcore_ctrl *wkq;
tuexen63fc0bb2011-12-27 12:24:52 +00006451 int need_wake = 0;
tuexendd729232011-11-01 23:04:43 +00006452 if (sctp_mcore_workers == NULL) {
6453 /* Something went way bad during setup */
6454 sctp_input_with_port(m, off, 0);
6455 return;
6456 }
6457 SCTP_MALLOC(qent, struct sctp_mcore_queue *,
6458 (sizeof(struct sctp_mcore_queue)),
6459 SCTP_M_MCORE);
6460 if (qent == NULL) {
6461 /* This is trouble */
6462 sctp_input_with_port(m, off, 0);
6463 return;
6464 }
6465#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
6466 qent->vn = curvnet;
6467#endif
6468 qent->m = m;
6469 qent->off = off;
6470 qent->v6 = 0;
6471 wkq = &sctp_mcore_workers[cpu_to_use];
6472 SCTP_MCORE_QLOCK(wkq);
6473
6474 TAILQ_INSERT_TAIL(&wkq->que, qent, next);
6475 if (wkq->running == 0) {
6476 need_wake = 1;
6477 }
6478 SCTP_MCORE_QUNLOCK(wkq);
tuexen63fc0bb2011-12-27 12:24:52 +00006479 if (need_wake) {
tuexendd729232011-11-01 23:04:43 +00006480 wakeup(&wkq->running);
6481 }
6482}
6483
6484static void
6485sctp_mcore_thread(void *arg)
6486{
6487
6488 struct sctp_mcore_ctrl *wkq;
6489 struct sctp_mcore_queue *qent;
6490
6491 wkq = (struct sctp_mcore_ctrl *)arg;
6492 struct mbuf *m;
6493 int off, v6;
6494
6495 /* Wait for first tickle */
6496 SCTP_MCORE_LOCK(wkq);
6497 wkq->running = 0;
6498 msleep(&wkq->running,
6499 &wkq->core_mtx,
6500 0, "wait for pkt", 0);
6501 SCTP_MCORE_UNLOCK(wkq);
6502
6503 /* Bind to our cpu */
6504 thread_lock(curthread);
6505 sched_bind(curthread, wkq->cpuid);
6506 thread_unlock(curthread);
6507
6508 /* Now lets start working */
6509 SCTP_MCORE_LOCK(wkq);
6510 /* Now grab lock and go */
tuexen9784e9a2011-12-18 13:04:23 +00006511 for (;;) {
tuexendd729232011-11-01 23:04:43 +00006512 SCTP_MCORE_QLOCK(wkq);
6513 skip_sleep:
6514 wkq->running = 1;
6515 qent = TAILQ_FIRST(&wkq->que);
6516 if (qent) {
6517 TAILQ_REMOVE(&wkq->que, qent, next);
6518 SCTP_MCORE_QUNLOCK(wkq);
6519#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
6520 CURVNET_SET(qent->vn);
6521#endif
6522 m = qent->m;
6523 off = qent->off;
6524 v6 = qent->v6;
6525 SCTP_FREE(qent, SCTP_M_MCORE);
6526 if (v6 == 0) {
6527 sctp_input_with_port(m, off, 0);
6528 } else {
tuexencb5fe8d2012-05-04 09:50:27 +00006529 SCTP_PRINTF("V6 not yet supported\n");
tuexendd729232011-11-01 23:04:43 +00006530 sctp_m_freem(m);
6531 }
6532#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
6533 CURVNET_RESTORE();
6534#endif
6535 SCTP_MCORE_QLOCK(wkq);
6536 }
6537 wkq->running = 0;
6538 if (!TAILQ_EMPTY(&wkq->que)) {
6539 goto skip_sleep;
6540 }
6541 SCTP_MCORE_QUNLOCK(wkq);
6542 msleep(&wkq->running,
6543 &wkq->core_mtx,
6544 0, "wait for pkt", 0);
tuexen63fc0bb2011-12-27 12:24:52 +00006545 }
tuexendd729232011-11-01 23:04:43 +00006546}
6547
6548static void
6549sctp_startup_mcore_threads(void)
6550{
6551 int i, cpu;
6552
6553 if (mp_ncpus == 1)
6554 return;
6555
6556 if (sctp_mcore_workers != NULL) {
6557 /* Already been here in some previous
6558 * vnet?
6559 */
6560 return;
6561 }
6562 SCTP_MALLOC(sctp_mcore_workers, struct sctp_mcore_ctrl *,
6563 ((mp_maxid+1) * sizeof(struct sctp_mcore_ctrl)),
6564 SCTP_M_MCORE);
6565 if (sctp_mcore_workers == NULL) {
6566 /* TSNH I hope */
6567 return;
6568 }
tuexen09631162012-04-18 11:23:02 +00006569 memset(sctp_mcore_workers, 0 , ((mp_maxid+1) *
tuexendd729232011-11-01 23:04:43 +00006570 sizeof(struct sctp_mcore_ctrl)));
6571 /* Init the structures */
tuexen63fc0bb2011-12-27 12:24:52 +00006572 for (i = 0; i<=mp_maxid; i++) {
tuexendd729232011-11-01 23:04:43 +00006573 TAILQ_INIT(&sctp_mcore_workers[i].que);
6574 SCTP_MCORE_LOCK_INIT(&sctp_mcore_workers[i]);
6575 SCTP_MCORE_QLOCK_INIT(&sctp_mcore_workers[i]);
6576 sctp_mcore_workers[i].cpuid = i;
6577 }
6578 if (sctp_cpuarry == NULL) {
6579 SCTP_MALLOC(sctp_cpuarry, int *,
6580 (mp_ncpus * sizeof(int)),
6581 SCTP_M_MCORE);
tuexen63fc0bb2011-12-27 12:24:52 +00006582 i = 0;
tuexendd729232011-11-01 23:04:43 +00006583 CPU_FOREACH(cpu) {
6584 sctp_cpuarry[i] = cpu;
6585 i++;
6586 }
6587 }
6588
6589 /* Now start them all */
6590 CPU_FOREACH(cpu) {
6591#if __FreeBSD_version <= 701000
6592 (void)kthread_create(sctp_mcore_thread,
6593 (void *)&sctp_mcore_workers[cpu],
6594 &sctp_mcore_workers[cpu].thread_proc,
6595 RFPROC,
6596 SCTP_KTHREAD_PAGES,
6597 SCTP_MCORE_NAME);
6598
6599#else
6600 (void)kproc_create(sctp_mcore_thread,
6601 (void *)&sctp_mcore_workers[cpu],
6602 &sctp_mcore_workers[cpu].thread_proc,
6603 RFPROC,
6604 SCTP_KTHREAD_PAGES,
6605 SCTP_MCORE_NAME);
6606#endif
tuexen09631162012-04-18 11:23:02 +00006607
tuexendd729232011-11-01 23:04:43 +00006608 }
6609}
6610#endif
t00fcxena50000e2014-03-29 20:43:12 +00006611#if defined(__FreeBSD__) && __FreeBSD_cc_version >= 1200000
tuexendd729232011-11-01 23:04:43 +00006612static struct mbuf *
6613sctp_netisr_hdlr(struct mbuf *m, uintptr_t source)
6614{
6615 struct ip *ip;
6616 struct sctphdr *sh;
6617 int offset;
6618 uint32_t flowid, tag;
tuexen76eb2092012-04-01 16:35:28 +00006619
tuexendd729232011-11-01 23:04:43 +00006620 /*
6621 * No flow id built by lower layers fix it so we
6622 * create one.
6623 */
6624 ip = mtod(m, struct ip *);
tuexen664967a2012-06-28 16:24:36 +00006625 offset = (ip->ip_hl << 2) + sizeof(struct sctphdr);
tuexendd729232011-11-01 23:04:43 +00006626 if (SCTP_BUF_LEN(m) < offset) {
tuexen664967a2012-06-28 16:24:36 +00006627 if ((m = m_pullup(m, offset)) == NULL) {
tuexendd729232011-11-01 23:04:43 +00006628 SCTP_STAT_INCR(sctps_hdrops);
6629 return (NULL);
6630 }
6631 ip = mtod(m, struct ip *);
6632 }
6633 sh = (struct sctphdr *)((caddr_t)ip + (ip->ip_hl << 2));
tuexendd729232011-11-01 23:04:43 +00006634 tag = htonl(sh->v_tag);
6635 flowid = tag ^ ntohs(sh->dest_port) ^ ntohs(sh->src_port);
6636 m->m_pkthdr.flowid = flowid;
6637 m->m_flags |= M_FLOWID;
6638 return (m);
6639}
6640#endif
6641
6642void
6643sctp_pcb_init()
6644{
6645 /*
6646 * SCTP initialization for the PCB structures should be called by
6647 * the sctp_init() funciton.
6648 */
6649 int i;
6650 struct timeval tv;
tuexen6019b072011-12-15 18:38:03 +00006651
tuexendd729232011-11-01 23:04:43 +00006652 if (SCTP_BASE_VAR(sctp_pcb_initialized) != 0) {
6653 /* error I was called twice */
6654 return;
6655 }
6656 SCTP_BASE_VAR(sctp_pcb_initialized) = 1;
6657
Michael Tuexencb2878b2015-11-13 12:59:40 +01006658#if defined(SCTP_PROCESS_LEVEL_LOCKS)
6659#if !defined(__Userspace_os_Windows)
6660 pthread_mutexattr_init(&SCTP_BASE_VAR(mtx_attr));
6661#ifdef INVARIANTS
6662 pthread_mutexattr_settype(&SCTP_BASE_VAR(mtx_attr), PTHREAD_MUTEX_ERRORCHECK);
6663#endif
6664#endif
6665#endif
tuexendd729232011-11-01 23:04:43 +00006666#if defined(SCTP_LOCAL_TRACE_BUF)
6667#if defined(__Windows__)
6668 if (SCTP_BASE_SYSCTL(sctp_log) != NULL) {
6669 bzero(SCTP_BASE_SYSCTL(sctp_log), sizeof(struct sctp_log));
6670 }
6671#else
6672 bzero(&SCTP_BASE_SYSCTL(sctp_log), sizeof(struct sctp_log));
6673#endif
6674#endif
6675#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
6676 SCTP_MALLOC(SCTP_BASE_STATS, struct sctpstat *,
6677 ((mp_maxid+1) * sizeof(struct sctpstat)),
6678 SCTP_M_MCORE);
6679#endif
6680 (void)SCTP_GETTIME_TIMEVAL(&tv);
6681#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
6682 bzero(SCTP_BASE_STATS, (sizeof(struct sctpstat) * (mp_maxid+1)));
6683 SCTP_BASE_STATS[PCPU_GET(cpuid)].sctps_discontinuitytime.tv_sec = (uint32_t)tv.tv_sec;
6684 SCTP_BASE_STATS[PCPU_GET(cpuid)].sctps_discontinuitytime.tv_usec = (uint32_t)tv.tv_usec;
6685#else
6686 bzero(&SCTP_BASE_STATS, sizeof(struct sctpstat));
6687 SCTP_BASE_STAT(sctps_discontinuitytime).tv_sec = (uint32_t)tv.tv_sec;
6688 SCTP_BASE_STAT(sctps_discontinuitytime).tv_usec = (uint32_t)tv.tv_usec;
6689#endif
6690 /* init the empty list of (All) Endpoints */
6691 LIST_INIT(&SCTP_BASE_INFO(listhead));
6692#if defined(__APPLE__)
6693 LIST_INIT(&SCTP_BASE_INFO(inplisthead));
t00fcxenbc766ab2014-01-03 19:29:31 +00006694#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
6695 SCTP_BASE_INFO(sctbinfo).listhead = &SCTP_BASE_INFO(inplisthead);
6696 SCTP_BASE_INFO(sctbinfo).mtx_grp_attr = lck_grp_attr_alloc_init();
6697 lck_grp_attr_setdefault(SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
6698 SCTP_BASE_INFO(sctbinfo).mtx_grp = lck_grp_alloc_init("sctppcb", SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
6699 SCTP_BASE_INFO(sctbinfo).mtx_attr = lck_attr_alloc_init();
6700 lck_attr_setdefault(SCTP_BASE_INFO(sctbinfo).mtx_attr);
6701#else
6702 SCTP_BASE_INFO(sctbinfo).ipi_listhead = &SCTP_BASE_INFO(inplisthead);
6703 SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr = lck_grp_attr_alloc_init();
6704 lck_grp_attr_setdefault(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
6705 SCTP_BASE_INFO(sctbinfo).ipi_lock_grp = lck_grp_alloc_init("sctppcb", SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
6706 SCTP_BASE_INFO(sctbinfo).ipi_lock_attr = lck_attr_alloc_init();
6707 lck_attr_setdefault(SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
6708#endif
6709#if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
6710 SCTP_BASE_INFO(sctbinfo).ipi_gc = sctp_gc;
6711 in_pcbinfo_attach(&SCTP_BASE_INFO(sctbinfo));
6712#endif
tuexendd729232011-11-01 23:04:43 +00006713#endif
6714
6715
6716 /* init the hash table of endpoints */
6717#if defined(__FreeBSD__)
6718#if defined(__FreeBSD_cc_version) && __FreeBSD_cc_version >= 440000
6719 TUNABLE_INT_FETCH("net.inet.sctp.tcbhashsize", &SCTP_BASE_SYSCTL(sctp_hashtblsize));
6720 TUNABLE_INT_FETCH("net.inet.sctp.pcbhashsize", &SCTP_BASE_SYSCTL(sctp_pcbtblsize));
6721 TUNABLE_INT_FETCH("net.inet.sctp.chunkscale", &SCTP_BASE_SYSCTL(sctp_chunkscale));
6722#else
6723 TUNABLE_INT_FETCH("net.inet.sctp.tcbhashsize", SCTP_TCBHASHSIZE,
6724 SCTP_BASE_SYSCTL(sctp_hashtblsize));
6725 TUNABLE_INT_FETCH("net.inet.sctp.pcbhashsize", SCTP_PCBHASHSIZE,
6726 SCTP_BASE_SYSCTL(sctp_pcbtblsize));
6727 TUNABLE_INT_FETCH("net.inet.sctp.chunkscale", SCTP_CHUNKQUEUE_SCALE,
6728 SCTP_BASE_SYSCTL(sctp_chunkscale));
6729#endif
6730#endif
6731 SCTP_BASE_INFO(sctp_asochash) = SCTP_HASH_INIT((SCTP_BASE_SYSCTL(sctp_hashtblsize) * 31),
6732 &SCTP_BASE_INFO(hashasocmark));
6733 SCTP_BASE_INFO(sctp_ephash) = SCTP_HASH_INIT(SCTP_BASE_SYSCTL(sctp_hashtblsize),
6734 &SCTP_BASE_INFO(hashmark));
6735 SCTP_BASE_INFO(sctp_tcpephash) = SCTP_HASH_INIT(SCTP_BASE_SYSCTL(sctp_hashtblsize),
6736 &SCTP_BASE_INFO(hashtcpmark));
6737 SCTP_BASE_INFO(hashtblsize) = SCTP_BASE_SYSCTL(sctp_hashtblsize);
6738
6739
6740 SCTP_BASE_INFO(sctp_vrfhash) = SCTP_HASH_INIT(SCTP_SIZE_OF_VRF_HASH,
6741 &SCTP_BASE_INFO(hashvrfmark));
6742
6743 SCTP_BASE_INFO(vrf_ifn_hash) = SCTP_HASH_INIT(SCTP_VRF_IFN_HASH_SIZE,
6744 &SCTP_BASE_INFO(vrf_ifn_hashmark));
6745 /* init the zones */
6746 /*
6747 * FIX ME: Should check for NULL returns, but if it does fail we are
6748 * doomed to panic anyways... add later maybe.
6749 */
6750 SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_ep), "sctp_ep",
6751 sizeof(struct sctp_inpcb), maxsockets);
6752
6753 SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_asoc), "sctp_asoc",
6754 sizeof(struct sctp_tcb), sctp_max_number_of_assoc);
6755
6756 SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_laddr), "sctp_laddr",
6757 sizeof(struct sctp_laddr),
6758 (sctp_max_number_of_assoc * sctp_scale_up_for_address));
6759
6760 SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_net), "sctp_raddr",
6761 sizeof(struct sctp_nets),
6762 (sctp_max_number_of_assoc * sctp_scale_up_for_address));
6763
6764 SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_chunk), "sctp_chunk",
6765 sizeof(struct sctp_tmit_chunk),
6766 (sctp_max_number_of_assoc * SCTP_BASE_SYSCTL(sctp_chunkscale)));
6767
6768 SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_readq), "sctp_readq",
6769 sizeof(struct sctp_queued_to_read),
6770 (sctp_max_number_of_assoc * SCTP_BASE_SYSCTL(sctp_chunkscale)));
6771
6772 SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_strmoq), "sctp_stream_msg_out",
6773 sizeof(struct sctp_stream_queue_pending),
6774 (sctp_max_number_of_assoc * SCTP_BASE_SYSCTL(sctp_chunkscale)));
6775
6776 SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_asconf), "sctp_asconf",
6777 sizeof(struct sctp_asconf),
6778 (sctp_max_number_of_assoc * SCTP_BASE_SYSCTL(sctp_chunkscale)));
6779
6780 SCTP_ZONE_INIT(SCTP_BASE_INFO(ipi_zone_asconf_ack), "sctp_asconf_ack",
6781 sizeof(struct sctp_asconf_ack),
6782 (sctp_max_number_of_assoc * SCTP_BASE_SYSCTL(sctp_chunkscale)));
6783
tuexen9784e9a2011-12-18 13:04:23 +00006784
tuexendd729232011-11-01 23:04:43 +00006785 /* Master Lock INIT for info structure */
tuexendd729232011-11-01 23:04:43 +00006786 SCTP_INP_INFO_LOCK_INIT();
6787 SCTP_STATLOG_INIT_LOCK();
6788
6789 SCTP_IPI_COUNT_INIT();
6790 SCTP_IPI_ADDR_INIT();
6791#ifdef SCTP_PACKET_LOGGING
6792 SCTP_IP_PKTLOG_INIT();
6793#endif
6794 LIST_INIT(&SCTP_BASE_INFO(addr_wq));
6795
6796 SCTP_WQ_ADDR_INIT();
6797 /* not sure if we need all the counts */
6798 SCTP_BASE_INFO(ipi_count_ep) = 0;
6799 /* assoc/tcb zone info */
6800 SCTP_BASE_INFO(ipi_count_asoc) = 0;
6801 /* local addrlist zone info */
6802 SCTP_BASE_INFO(ipi_count_laddr) = 0;
6803 /* remote addrlist zone info */
6804 SCTP_BASE_INFO(ipi_count_raddr) = 0;
6805 /* chunk info */
6806 SCTP_BASE_INFO(ipi_count_chunk) = 0;
6807
6808 /* socket queue zone info */
6809 SCTP_BASE_INFO(ipi_count_readq) = 0;
6810
6811 /* stream out queue cont */
6812 SCTP_BASE_INFO(ipi_count_strmoq) = 0;
6813
6814 SCTP_BASE_INFO(ipi_free_strmoq) = 0;
6815 SCTP_BASE_INFO(ipi_free_chunks) = 0;
6816
6817 SCTP_OS_TIMER_INIT(&SCTP_BASE_INFO(addr_wq_timer.timer));
6818
6819 /* Init the TIMEWAIT list */
6820 for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
6821 LIST_INIT(&SCTP_BASE_INFO(vtag_timewait)[i]);
6822 }
tuexendd729232011-11-01 23:04:43 +00006823#if defined(SCTP_PROCESS_LEVEL_LOCKS)
tuexen5154a002011-12-23 18:47:55 +00006824#if defined(__Userspace_os_Windows)
tuexen6019b072011-12-15 18:38:03 +00006825 InitializeConditionVariable(&sctp_it_ctl.iterator_wakeup);
6826#else
tuexendd729232011-11-01 23:04:43 +00006827 (void)pthread_cond_init(&sctp_it_ctl.iterator_wakeup, NULL);
6828#endif
tuexen6019b072011-12-15 18:38:03 +00006829#endif
tuexendd729232011-11-01 23:04:43 +00006830 sctp_startup_iterator();
6831
6832#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP)
6833 sctp_startup_mcore_threads();
6834#endif
6835
6836#ifndef __Panda__
6837 /*
6838 * INIT the default VRF which for BSD is the only one, other O/S's
6839 * may have more. But initially they must start with one and then
6840 * add the VRF's as addresses are added.
6841 */
6842 sctp_init_vrf_list(SCTP_DEFAULT_VRF);
6843#endif
t00fcxena50000e2014-03-29 20:43:12 +00006844#if defined(__FreeBSD__) && __FreeBSD_cc_version >= 1200000
tuexendd729232011-11-01 23:04:43 +00006845 if (ip_register_flow_handler(sctp_netisr_hdlr, IPPROTO_SCTP)) {
tuexencb5fe8d2012-05-04 09:50:27 +00006846 SCTP_PRINTF("***SCTP- Error can't register netisr handler***\n");
tuexendd729232011-11-01 23:04:43 +00006847 }
6848#endif
6849#if defined(_SCTP_NEEDS_CALLOUT_) || defined(_USER_SCTP_NEEDS_CALLOUT_)
6850 /* allocate the lock for the callout/timer queue */
6851 SCTP_TIMERQ_LOCK_INIT();
6852 TAILQ_INIT(&SCTP_BASE_INFO(callqueue));
6853#endif
6854#if defined(__Userspace__)
6855 mbuf_init(NULL);
6856 atomic_init();
tuexenc4178972012-07-15 20:40:54 +00006857#if defined(INET) || defined(INET6)
tuexen852c7962012-04-28 16:39:32 +00006858 recv_thread_init();
tuexendd729232011-11-01 23:04:43 +00006859#endif
tuexenc4178972012-07-15 20:40:54 +00006860#endif
tuexendd729232011-11-01 23:04:43 +00006861}
6862
6863/*
6864 * Assumes that the SCTP_BASE_INFO() lock is NOT held.
6865 */
6866void
6867sctp_pcb_finish(void)
6868{
6869 struct sctp_vrflist *vrf_bucket;
6870 struct sctp_vrf *vrf, *nvrf;
6871 struct sctp_ifn *ifn, *nifn;
6872 struct sctp_ifa *ifa, *nifa;
6873 struct sctpvtaghead *chain;
6874 struct sctp_tagblock *twait_block, *prev_twait_block;
6875 struct sctp_laddr *wi, *nwi;
6876 int i;
t00fcxenc7932282013-11-16 14:57:41 +00006877 struct sctp_iterator *it, *nit;
Michael Tuexen20785d42015-11-13 12:48:35 +01006878
Michael Tuexen71a83fb2016-02-16 21:52:58 +01006879 if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
6880 SCTP_PRINTF("%s: race condition on teardown.\n", __func__);
6881 return;
6882 }
6883 SCTP_BASE_VAR(sctp_pcb_initialized) = 0;
t00fcxen9232a652013-11-30 09:34:24 +00006884#if !defined(__FreeBSD__)
tuexendd729232011-11-01 23:04:43 +00006885 /* Notify the iterator to exit. */
6886 SCTP_IPI_ITERATOR_WQ_LOCK();
6887 sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_MUST_EXIT;
6888 sctp_wakeup_iterator();
6889 SCTP_IPI_ITERATOR_WQ_UNLOCK();
6890#endif
6891#if defined(__APPLE__)
t00fcxenbc766ab2014-01-03 19:29:31 +00006892#if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
6893 in_pcbinfo_detach(&SCTP_BASE_INFO(sctbinfo));
6894#endif
tuexendd729232011-11-01 23:04:43 +00006895 SCTP_IPI_ITERATOR_WQ_LOCK();
6896 do {
6897 msleep(&sctp_it_ctl.iterator_flags,
6898 sctp_it_ctl.ipi_iterator_wq_mtx,
6899 0, "waiting_for_work", 0);
6900 } while ((sctp_it_ctl.iterator_flags & SCTP_ITERATOR_EXITED) == 0);
6901 thread_deallocate(sctp_it_ctl.thread_proc);
6902 SCTP_IPI_ITERATOR_WQ_UNLOCK();
tuexendd729232011-11-01 23:04:43 +00006903#endif
6904#if defined(__Windows__)
6905 if (sctp_it_ctl.iterator_thread_obj != NULL) {
6906 NTSTATUS status = STATUS_SUCCESS;
6907
6908 KeSetEvent(&sctp_it_ctl.iterator_wakeup[1], IO_NO_INCREMENT, FALSE);
6909 status = KeWaitForSingleObject(sctp_it_ctl.iterator_thread_obj,
6910 Executive,
6911 KernelMode,
6912 FALSE,
6913 NULL);
6914 ObDereferenceObject(sctp_it_ctl.iterator_thread_obj);
6915 }
6916#endif
t00fcxen92a5ac42013-11-16 12:58:54 +00006917#if defined(__Userspace__)
6918 if (sctp_it_ctl.thread_proc) {
6919#if defined(__Userspace_os_Windows)
6920 WaitForSingleObject(sctp_it_ctl.thread_proc, INFINITE);
6921 CloseHandle(sctp_it_ctl.thread_proc);
6922 sctp_it_ctl.thread_proc = NULL;
6923#else
6924 pthread_join(sctp_it_ctl.thread_proc, NULL);
6925 sctp_it_ctl.thread_proc = 0;
6926#endif
6927 }
6928#endif
6929#if defined(SCTP_PROCESS_LEVEL_LOCKS)
6930#if defined(__Userspace_os_Windows)
6931 DeleteConditionVariable(&sctp_it_ctl.iterator_wakeup);
6932#else
6933 pthread_cond_destroy(&sctp_it_ctl.iterator_wakeup);
Michael Tuexen89e15a72015-11-13 12:42:55 +01006934 pthread_mutexattr_destroy(&SCTP_BASE_VAR(mtx_attr));
t00fcxen92a5ac42013-11-16 12:58:54 +00006935#endif
6936#endif
t00fcxen9232a652013-11-30 09:34:24 +00006937 /* In FreeBSD the iterator thread never exits
6938 * but we do clean up.
6939 * The only way FreeBSD reaches here is if we have VRF's
6940 * but we still add the ifdef to make it compile on old versions.
6941 */
Michael Tuexen71a83fb2016-02-16 21:52:58 +01006942#if defined(__FreeBSD__)
6943retry:
6944#endif
t00fcxen9232a652013-11-30 09:34:24 +00006945 SCTP_IPI_ITERATOR_WQ_LOCK();
Michael Tuexen71a83fb2016-02-16 21:52:58 +01006946#if defined(__FreeBSD__)
6947 /*
6948 * sctp_iterator_worker() might be working on an it entry without
6949 * holding the lock. We won't find it on the list either and
6950 * continue and free/destroy it. While holding the lock, spin, to
6951 * avoid the race condition as sctp_iterator_worker() will have to
6952 * wait to re-aquire the lock.
6953 */
6954 if (sctp_it_ctl.iterator_running != 0 || sctp_it_ctl.cur_it != NULL) {
6955 SCTP_IPI_ITERATOR_WQ_UNLOCK();
6956 SCTP_PRINTF("%s: Iterator running while we held the lock. Retry. "
6957 "cur_it=%p\n", __func__, sctp_it_ctl.cur_it);
6958 DELAY(10);
6959 goto retry;
6960 }
6961#endif
t00fcxen9232a652013-11-30 09:34:24 +00006962 TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
t00fcxen433c6e12013-11-30 09:45:11 +00006963#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
t00fcxen9232a652013-11-30 09:34:24 +00006964 if (it->vn != curvnet) {
6965 continue;
6966 }
6967#endif
6968 TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
6969 if (it->function_atend != NULL) {
6970 (*it->function_atend) (it->pointer, it->val);
6971 }
6972 SCTP_FREE(it,SCTP_M_ITER);
6973 }
6974 SCTP_IPI_ITERATOR_WQ_UNLOCK();
t00fcxen433c6e12013-11-30 09:45:11 +00006975#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
t00fcxen9232a652013-11-30 09:34:24 +00006976 SCTP_ITERATOR_LOCK();
6977 if ((sctp_it_ctl.cur_it) &&
6978 (sctp_it_ctl.cur_it->vn == curvnet)) {
6979 sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
6980 }
6981 SCTP_ITERATOR_UNLOCK();
6982#endif
t00fcxenc7932282013-11-16 14:57:41 +00006983#if !defined(__FreeBSD__)
t00fcxen92a5ac42013-11-16 12:58:54 +00006984 SCTP_IPI_ITERATOR_WQ_DESTROY();
t00fcxen8dd95b82014-07-11 20:41:28 +00006985 SCTP_ITERATOR_LOCK_DESTROY();
t00fcxenc7932282013-11-16 14:57:41 +00006986#endif
Michael Tuexen71a83fb2016-02-16 21:52:58 +01006987 SCTP_OS_TIMER_STOP_DRAIN(&SCTP_BASE_INFO(addr_wq_timer.timer));
tuexendd729232011-11-01 23:04:43 +00006988 SCTP_WQ_ADDR_LOCK();
6989 LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) {
6990 LIST_REMOVE(wi, sctp_nxt_addr);
6991 SCTP_DECR_LADDR_COUNT();
t00fcxen9892b7f2014-09-06 20:06:39 +00006992 if (wi->action == SCTP_DEL_IP_ADDRESS) {
6993 SCTP_FREE(wi->ifa, SCTP_M_IFA);
6994 }
tuexendd729232011-11-01 23:04:43 +00006995 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), wi);
6996 }
6997 SCTP_WQ_ADDR_UNLOCK();
tuexen09631162012-04-18 11:23:02 +00006998
tuexendd729232011-11-01 23:04:43 +00006999 /*
7000 * free the vrf/ifn/ifa lists and hashes (be sure address monitor
7001 * is destroyed first).
7002 */
7003 vrf_bucket = &SCTP_BASE_INFO(sctp_vrfhash)[(SCTP_DEFAULT_VRFID & SCTP_BASE_INFO(hashvrfmark))];
7004 LIST_FOREACH_SAFE(vrf, vrf_bucket, next_vrf, nvrf) {
7005 LIST_FOREACH_SAFE(ifn, &vrf->ifnlist, next_ifn, nifn) {
7006 LIST_FOREACH_SAFE(ifa, &ifn->ifalist, next_ifa, nifa) {
7007 /* free the ifa */
7008 LIST_REMOVE(ifa, next_bucket);
7009 LIST_REMOVE(ifa, next_ifa);
7010 SCTP_FREE(ifa, SCTP_M_IFA);
7011 }
7012 /* free the ifn */
7013 LIST_REMOVE(ifn, next_bucket);
7014 LIST_REMOVE(ifn, next_ifn);
7015 SCTP_FREE(ifn, SCTP_M_IFN);
7016 }
7017 SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark);
7018 /* free the vrf */
7019 LIST_REMOVE(vrf, next_vrf);
7020 SCTP_FREE(vrf, SCTP_M_VRF);
7021 }
7022 /* free the vrf hashes */
7023 SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_vrfhash), SCTP_BASE_INFO(hashvrfmark));
7024 SCTP_HASH_FREE(SCTP_BASE_INFO(vrf_ifn_hash), SCTP_BASE_INFO(vrf_ifn_hashmark));
tuexendd729232011-11-01 23:04:43 +00007025
7026 /* free the TIMEWAIT list elements malloc'd in the function
7027 * sctp_add_vtag_to_timewait()...
7028 */
7029 for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
7030 chain = &SCTP_BASE_INFO(vtag_timewait)[i];
7031 if (!LIST_EMPTY(chain)) {
7032 prev_twait_block = NULL;
7033 LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
7034 if (prev_twait_block) {
7035 SCTP_FREE(prev_twait_block, SCTP_M_TIMW);
7036 }
7037 prev_twait_block = twait_block;
7038 }
7039 SCTP_FREE(prev_twait_block, SCTP_M_TIMW);
7040 }
7041 }
7042
7043 /* free the locks and mutexes */
7044#if defined(__APPLE__)
7045 SCTP_TIMERQ_LOCK_DESTROY();
7046#endif
7047#ifdef SCTP_PACKET_LOGGING
7048 SCTP_IP_PKTLOG_DESTROY();
7049#endif
7050 SCTP_IPI_ADDR_DESTROY();
7051#if defined(__APPLE__)
7052 SCTP_IPI_COUNT_DESTROY();
7053#endif
7054 SCTP_STATLOG_DESTROY();
tuexendd729232011-11-01 23:04:43 +00007055 SCTP_INP_INFO_LOCK_DESTROY();
tuexen09631162012-04-18 11:23:02 +00007056
tuexendd729232011-11-01 23:04:43 +00007057 SCTP_WQ_ADDR_DESTROY();
tuexen09631162012-04-18 11:23:02 +00007058
tuexendd729232011-11-01 23:04:43 +00007059#if defined(__APPLE__)
t00fcxenbc766ab2014-01-03 19:29:31 +00007060#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
7061 lck_grp_attr_free(SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
7062 lck_grp_free(SCTP_BASE_INFO(sctbinfo).mtx_grp);
7063 lck_attr_free(SCTP_BASE_INFO(sctbinfo).mtx_attr);
7064#else
7065 lck_grp_attr_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
7066 lck_grp_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp);
7067 lck_attr_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
7068#endif
tuexendd729232011-11-01 23:04:43 +00007069#endif
7070#if defined(__Userspace__)
7071 SCTP_TIMERQ_LOCK_DESTROY();
7072 SCTP_ZONE_DESTROY(zone_mbuf);
7073 SCTP_ZONE_DESTROY(zone_clust);
7074 SCTP_ZONE_DESTROY(zone_ext_refcnt);
7075#endif
Michael Tuexen71a83fb2016-02-16 21:52:58 +01007076 /* Get rid of other stuff too. */
7077 if (SCTP_BASE_INFO(sctp_asochash) != NULL)
7078 SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_asochash), SCTP_BASE_INFO(hashasocmark));
7079 if (SCTP_BASE_INFO(sctp_ephash) != NULL)
7080 SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_ephash), SCTP_BASE_INFO(hashmark));
7081 if (SCTP_BASE_INFO(sctp_tcpephash) != NULL)
7082 SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_tcpephash), SCTP_BASE_INFO(hashtcpmark));
7083
tuexendd729232011-11-01 23:04:43 +00007084#if defined(__Windows__) || defined(__FreeBSD__) || defined(__Userspace__)
7085 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_ep));
7086 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asoc));
7087 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_laddr));
7088 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_net));
7089 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_chunk));
7090 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_readq));
7091 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_strmoq));
7092 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asconf));
7093 SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asconf_ack));
7094#endif
tuexendd729232011-11-01 23:04:43 +00007095#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
tuexen09631162012-04-18 11:23:02 +00007096 SCTP_FREE(SCTP_BASE_STATS, SCTP_M_MCORE);
tuexendd729232011-11-01 23:04:43 +00007097#endif
7098}
7099
7100
7101int
7102sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
tuexen664967a2012-06-28 16:24:36 +00007103 int offset, int limit,
7104 struct sockaddr *src, struct sockaddr *dst,
Michael Tuexen923f7352016-05-01 23:55:35 +02007105 struct sockaddr *altsa, uint16_t port)
tuexendd729232011-11-01 23:04:43 +00007106{
7107 /*
7108 * grub through the INIT pulling addresses and loading them to the
7109 * nets structure in the asoc. The from address in the mbuf should
7110 * also be loaded (if it is not already). This routine can be called
7111 * with either INIT or INIT-ACK's as long as the m points to the IP
7112 * packet and the offset points to the beginning of the parameters.
7113 */
tuexen63fc0bb2011-12-27 12:24:52 +00007114 struct sctp_inpcb *inp;
tuexendd729232011-11-01 23:04:43 +00007115 struct sctp_nets *net, *nnet, *net_tmp;
tuexendd729232011-11-01 23:04:43 +00007116 struct sctp_paramhdr *phdr, parm_buf;
7117 struct sctp_tcb *stcb_tmp;
7118 uint16_t ptype, plen;
7119 struct sockaddr *sa;
tuexendd729232011-11-01 23:04:43 +00007120 uint8_t random_store[SCTP_PARAM_BUFFER_SIZE];
7121 struct sctp_auth_random *p_random = NULL;
7122 uint16_t random_len = 0;
7123 uint8_t hmacs_store[SCTP_PARAM_BUFFER_SIZE];
7124 struct sctp_auth_hmac_algo *hmacs = NULL;
7125 uint16_t hmacs_len = 0;
tuexen63fc0bb2011-12-27 12:24:52 +00007126 uint8_t saw_asconf = 0;
7127 uint8_t saw_asconf_ack = 0;
tuexendd729232011-11-01 23:04:43 +00007128 uint8_t chunks_store[SCTP_PARAM_BUFFER_SIZE];
7129 struct sctp_auth_chunk_list *chunks = NULL;
7130 uint16_t num_chunks = 0;
7131 sctp_key_t *new_key;
7132 uint32_t keylen;
7133 int got_random = 0, got_hmacs = 0, got_chklist = 0;
t00fcxenaac0f452014-08-12 12:51:45 +00007134 uint8_t peer_supports_ecn;
7135 uint8_t peer_supports_prsctp;
7136 uint8_t peer_supports_auth;
7137 uint8_t peer_supports_asconf;
7138 uint8_t peer_supports_asconf_ack;
7139 uint8_t peer_supports_reconfig;
7140 uint8_t peer_supports_nrsack;
7141 uint8_t peer_supports_pktdrop;
Michael Tuexene5001952016-04-17 19:25:27 +02007142 uint8_t peer_supports_idata;
tuexendd729232011-11-01 23:04:43 +00007143#ifdef INET
7144 struct sockaddr_in sin;
7145#endif
7146#ifdef INET6
7147 struct sockaddr_in6 sin6;
7148#endif
7149
7150 /* First get the destination address setup too. */
7151#ifdef INET
7152 memset(&sin, 0, sizeof(sin));
7153 sin.sin_family = AF_INET;
t00fcxen8fbaee32012-09-04 16:41:39 +00007154#ifdef HAVE_SIN_LEN
tuexendd729232011-11-01 23:04:43 +00007155 sin.sin_len = sizeof(sin);
7156#endif
7157 sin.sin_port = stcb->rport;
7158#endif
7159#ifdef INET6
7160 memset(&sin6, 0, sizeof(sin6));
7161 sin6.sin6_family = AF_INET6;
t00fcxen8fbaee32012-09-04 16:41:39 +00007162#ifdef HAVE_SIN6_LEN
tuexendd729232011-11-01 23:04:43 +00007163 sin6.sin6_len = sizeof(struct sockaddr_in6);
7164#endif
7165 sin6.sin6_port = stcb->rport;
7166#endif
tuexen664967a2012-06-28 16:24:36 +00007167 if (altsa) {
7168 sa = altsa;
7169 } else {
7170 sa = src;
tuexendd729232011-11-01 23:04:43 +00007171 }
Michael Tuexene5001952016-04-17 19:25:27 +02007172 peer_supports_idata = 0;
t00fcxenaac0f452014-08-12 12:51:45 +00007173 peer_supports_ecn = 0;
7174 peer_supports_prsctp = 0;
7175 peer_supports_auth = 0;
7176 peer_supports_asconf = 0;
t00fcxenaac0f452014-08-12 12:51:45 +00007177 peer_supports_reconfig = 0;
7178 peer_supports_nrsack = 0;
7179 peer_supports_pktdrop = 0;
tuexendd729232011-11-01 23:04:43 +00007180 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
7181 /* mark all addresses that we have currently on the list */
7182 net->dest_state |= SCTP_ADDR_NOT_IN_ASSOC;
7183 }
7184 /* does the source address already exist? if so skip it */
tuexen63fc0bb2011-12-27 12:24:52 +00007185 inp = stcb->sctp_ep;
tuexendd729232011-11-01 23:04:43 +00007186 atomic_add_int(&stcb->asoc.refcnt, 1);
tuexen664967a2012-06-28 16:24:36 +00007187 stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net_tmp, dst, stcb);
tuexendd729232011-11-01 23:04:43 +00007188 atomic_add_int(&stcb->asoc.refcnt, -1);
7189
7190 if ((stcb_tmp == NULL && inp == stcb->sctp_ep) || inp == NULL) {
7191 /* we must add the source address */
7192 /* no scope set here since we have a tcb already. */
7193 switch (sa->sa_family) {
7194#ifdef INET
7195 case AF_INET:
t00fcxend0ad16b2013-02-09 18:34:24 +00007196 if (stcb->asoc.scope.ipv4_addr_legal) {
Michael Tuexen923f7352016-05-01 23:55:35 +02007197 if (sctp_add_remote_addr(stcb, sa, NULL, port, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_2)) {
tuexendd729232011-11-01 23:04:43 +00007198 return (-1);
7199 }
7200 }
7201 break;
7202#endif
7203#ifdef INET6
7204 case AF_INET6:
t00fcxend0ad16b2013-02-09 18:34:24 +00007205 if (stcb->asoc.scope.ipv6_addr_legal) {
Michael Tuexen923f7352016-05-01 23:55:35 +02007206 if (sctp_add_remote_addr(stcb, sa, NULL, port, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_3)) {
tuexendd729232011-11-01 23:04:43 +00007207 return (-2);
7208 }
7209 }
7210 break;
7211#endif
tuexen430ca6c2012-07-10 23:36:36 +00007212#if defined(__Userspace__)
7213 case AF_CONN:
t00fcxend0ad16b2013-02-09 18:34:24 +00007214 if (stcb->asoc.scope.conn_addr_legal) {
Michael Tuexen923f7352016-05-01 23:55:35 +02007215 if (sctp_add_remote_addr(stcb, sa, NULL, port, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_3)) {
t00fcxend0ad16b2013-02-09 18:34:24 +00007216 return (-2);
7217 }
tuexen430ca6c2012-07-10 23:36:36 +00007218 }
7219 break;
7220#endif
tuexendd729232011-11-01 23:04:43 +00007221 default:
7222 break;
7223 }
7224 } else {
7225 if (net_tmp != NULL && stcb_tmp == stcb) {
7226 net_tmp->dest_state &= ~SCTP_ADDR_NOT_IN_ASSOC;
7227 } else if (stcb_tmp != stcb) {
7228 /* It belongs to another association? */
7229 if (stcb_tmp)
7230 SCTP_TCB_UNLOCK(stcb_tmp);
7231 return (-3);
7232 }
7233 }
7234 if (stcb->asoc.state == 0) {
7235 /* the assoc was freed? */
7236 return (-4);
7237 }
tuexendd729232011-11-01 23:04:43 +00007238 /* now we must go through each of the params. */
7239 phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
7240 while (phdr) {
7241 ptype = ntohs(phdr->param_type);
7242 plen = ntohs(phdr->param_length);
7243 /*
tuexencb5fe8d2012-05-04 09:50:27 +00007244 * SCTP_PRINTF("ptype => %0x, plen => %d\n", (uint32_t)ptype,
tuexendd729232011-11-01 23:04:43 +00007245 * (int)plen);
7246 */
7247 if (offset + plen > limit) {
7248 break;
7249 }
7250 if (plen == 0) {
7251 break;
7252 }
7253#ifdef INET
7254 if (ptype == SCTP_IPV4_ADDRESS) {
t00fcxend0ad16b2013-02-09 18:34:24 +00007255 if (stcb->asoc.scope.ipv4_addr_legal) {
tuexendd729232011-11-01 23:04:43 +00007256 struct sctp_ipv4addr_param *p4, p4_buf;
7257
7258 /* ok get the v4 address and check/add */
7259 phdr = sctp_get_next_param(m, offset,
7260 (struct sctp_paramhdr *)&p4_buf,
7261 sizeof(p4_buf));
7262 if (plen != sizeof(struct sctp_ipv4addr_param) ||
7263 phdr == NULL) {
7264 return (-5);
7265 }
7266 p4 = (struct sctp_ipv4addr_param *)phdr;
7267 sin.sin_addr.s_addr = p4->addr;
7268 if (IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) {
7269 /* Skip multi-cast addresses */
7270 goto next_param;
7271 }
7272 if ((sin.sin_addr.s_addr == INADDR_BROADCAST) ||
7273 (sin.sin_addr.s_addr == INADDR_ANY)) {
7274 goto next_param;
7275 }
7276 sa = (struct sockaddr *)&sin;
7277 inp = stcb->sctp_ep;
7278 atomic_add_int(&stcb->asoc.refcnt, 1);
7279 stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net,
tuexen664967a2012-06-28 16:24:36 +00007280 dst, stcb);
tuexendd729232011-11-01 23:04:43 +00007281 atomic_add_int(&stcb->asoc.refcnt, -1);
7282
7283 if ((stcb_tmp == NULL && inp == stcb->sctp_ep) ||
7284 inp == NULL) {
7285 /* we must add the source address */
7286 /*
7287 * no scope set since we have a tcb
7288 * already
7289 */
7290
7291 /*
7292 * we must validate the state again
7293 * here
7294 */
7295 add_it_now:
7296 if (stcb->asoc.state == 0) {
7297 /* the assoc was freed? */
7298 return (-7);
7299 }
Michael Tuexen923f7352016-05-01 23:55:35 +02007300 if (sctp_add_remote_addr(stcb, sa, NULL, port, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_4)) {
tuexendd729232011-11-01 23:04:43 +00007301 return (-8);
7302 }
7303 } else if (stcb_tmp == stcb) {
7304 if (stcb->asoc.state == 0) {
7305 /* the assoc was freed? */
7306 return (-10);
7307 }
7308 if (net != NULL) {
7309 /* clear flag */
7310 net->dest_state &=
7311 ~SCTP_ADDR_NOT_IN_ASSOC;
7312 }
7313 } else {
7314 /*
7315 * strange, address is in another
7316 * assoc? straighten out locks.
7317 */
7318 if (stcb_tmp) {
7319 if (SCTP_GET_STATE(&stcb_tmp->asoc) & SCTP_STATE_COOKIE_WAIT) {
Michael Tüxenac142282015-07-28 00:42:03 +02007320 struct mbuf *op_err;
7321 char msg[SCTP_DIAG_INFO_LEN];
7322
tuexendd729232011-11-01 23:04:43 +00007323 /* in setup state we abort this guy */
Michael Tüxenac142282015-07-28 00:42:03 +02007324 snprintf(msg, sizeof(msg),
Saúl Ibarra Corretgé8b04b412015-09-26 09:53:06 +02007325 "%s:%d at %s", __FILE__, __LINE__, __func__);
Michael Tüxenac142282015-07-28 00:42:03 +02007326 op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
7327 msg);
tuexendd729232011-11-01 23:04:43 +00007328 sctp_abort_an_association(stcb_tmp->sctp_ep,
Michael Tüxenac142282015-07-28 00:42:03 +02007329 stcb_tmp, op_err,
7330 SCTP_SO_NOT_LOCKED);
tuexendd729232011-11-01 23:04:43 +00007331 goto add_it_now;
7332 }
7333 SCTP_TCB_UNLOCK(stcb_tmp);
7334 }
7335
7336 if (stcb->asoc.state == 0) {
7337 /* the assoc was freed? */
7338 return (-12);
7339 }
7340 return (-13);
7341 }
7342 }
7343 } else
7344#endif
7345#ifdef INET6
7346 if (ptype == SCTP_IPV6_ADDRESS) {
t00fcxend0ad16b2013-02-09 18:34:24 +00007347 if (stcb->asoc.scope.ipv6_addr_legal) {
tuexendd729232011-11-01 23:04:43 +00007348 /* ok get the v6 address and check/add */
7349 struct sctp_ipv6addr_param *p6, p6_buf;
7350
7351 phdr = sctp_get_next_param(m, offset,
7352 (struct sctp_paramhdr *)&p6_buf,
7353 sizeof(p6_buf));
7354 if (plen != sizeof(struct sctp_ipv6addr_param) ||
7355 phdr == NULL) {
7356 return (-14);
7357 }
7358 p6 = (struct sctp_ipv6addr_param *)phdr;
7359 memcpy((caddr_t)&sin6.sin6_addr, p6->addr,
7360 sizeof(p6->addr));
7361 if (IN6_IS_ADDR_MULTICAST(&sin6.sin6_addr)) {
7362 /* Skip multi-cast addresses */
7363 goto next_param;
7364 }
7365 if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) {
7366 /* Link local make no sense without scope */
7367 goto next_param;
7368 }
7369 sa = (struct sockaddr *)&sin6;
7370 inp = stcb->sctp_ep;
7371 atomic_add_int(&stcb->asoc.refcnt, 1);
7372 stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net,
tuexen664967a2012-06-28 16:24:36 +00007373 dst, stcb);
tuexendd729232011-11-01 23:04:43 +00007374 atomic_add_int(&stcb->asoc.refcnt, -1);
7375 if (stcb_tmp == NULL &&
7376 (inp == stcb->sctp_ep || inp == NULL)) {
7377 /*
7378 * we must validate the state again
7379 * here
7380 */
7381 add_it_now6:
7382 if (stcb->asoc.state == 0) {
7383 /* the assoc was freed? */
7384 return (-16);
7385 }
7386 /*
7387 * we must add the address, no scope
7388 * set
7389 */
Michael Tuexen923f7352016-05-01 23:55:35 +02007390 if (sctp_add_remote_addr(stcb, sa, NULL, port, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_5)) {
tuexendd729232011-11-01 23:04:43 +00007391 return (-17);
7392 }
7393 } else if (stcb_tmp == stcb) {
7394 /*
7395 * we must validate the state again
7396 * here
7397 */
7398 if (stcb->asoc.state == 0) {
7399 /* the assoc was freed? */
7400 return (-19);
7401 }
7402 if (net != NULL) {
7403 /* clear flag */
7404 net->dest_state &=
7405 ~SCTP_ADDR_NOT_IN_ASSOC;
7406 }
7407 } else {
7408 /*
7409 * strange, address is in another
7410 * assoc? straighten out locks.
7411 */
Michael Tüxenac142282015-07-28 00:42:03 +02007412 if (stcb_tmp) {
tuexendd729232011-11-01 23:04:43 +00007413 if (SCTP_GET_STATE(&stcb_tmp->asoc) & SCTP_STATE_COOKIE_WAIT) {
Michael Tüxenac142282015-07-28 00:42:03 +02007414 struct mbuf *op_err;
7415 char msg[SCTP_DIAG_INFO_LEN];
7416
tuexendd729232011-11-01 23:04:43 +00007417 /* in setup state we abort this guy */
Michael Tüxenac142282015-07-28 00:42:03 +02007418 snprintf(msg, sizeof(msg),
Saúl Ibarra Corretgé8b04b412015-09-26 09:53:06 +02007419 "%s:%d at %s", __FILE__, __LINE__, __func__);
Michael Tüxenac142282015-07-28 00:42:03 +02007420 op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
7421 msg);
tuexendd729232011-11-01 23:04:43 +00007422 sctp_abort_an_association(stcb_tmp->sctp_ep,
Michael Tüxenac142282015-07-28 00:42:03 +02007423 stcb_tmp, op_err,
7424 SCTP_SO_NOT_LOCKED);
tuexendd729232011-11-01 23:04:43 +00007425 goto add_it_now6;
7426 }
Michael Tüxenac142282015-07-28 00:42:03 +02007427 SCTP_TCB_UNLOCK(stcb_tmp);
7428 }
tuexendd729232011-11-01 23:04:43 +00007429 if (stcb->asoc.state == 0) {
7430 /* the assoc was freed? */
7431 return (-21);
7432 }
7433 return (-22);
7434 }
7435 }
7436 } else
7437#endif
7438 if (ptype == SCTP_ECN_CAPABLE) {
t00fcxenaac0f452014-08-12 12:51:45 +00007439 peer_supports_ecn = 1;
tuexendd729232011-11-01 23:04:43 +00007440 } else if (ptype == SCTP_ULP_ADAPTATION) {
7441 if (stcb->asoc.state != SCTP_STATE_OPEN) {
7442 struct sctp_adaptation_layer_indication ai, *aip;
7443
7444 phdr = sctp_get_next_param(m, offset,
7445 (struct sctp_paramhdr *)&ai, sizeof(ai));
7446 aip = (struct sctp_adaptation_layer_indication *)phdr;
7447 if (aip) {
7448 stcb->asoc.peers_adaptation = ntohl(aip->indication);
7449 stcb->asoc.adaptation_needed = 1;
7450 }
7451 }
7452 } else if (ptype == SCTP_SET_PRIM_ADDR) {
7453 struct sctp_asconf_addr_param lstore, *fee;
7454 int lptype;
7455 struct sockaddr *lsa = NULL;
7456#ifdef INET
7457 struct sctp_asconf_addrv4_param *fii;
7458#endif
7459
t00fcxenaac0f452014-08-12 12:51:45 +00007460 if (stcb->asoc.asconf_supported == 0) {
7461 return (-100);
7462 }
tuexendd729232011-11-01 23:04:43 +00007463 if (plen > sizeof(lstore)) {
7464 return (-23);
7465 }
7466 phdr = sctp_get_next_param(m, offset,
7467 (struct sctp_paramhdr *)&lstore,
7468 min(plen,sizeof(lstore)));
7469 if (phdr == NULL) {
7470 return (-24);
7471 }
7472 fee = (struct sctp_asconf_addr_param *)phdr;
7473 lptype = ntohs(fee->addrp.ph.param_type);
7474 switch (lptype) {
7475#ifdef INET
7476 case SCTP_IPV4_ADDRESS:
7477 if (plen !=
7478 sizeof(struct sctp_asconf_addrv4_param)) {
7479 SCTP_PRINTF("Sizeof setprim in init/init ack not %d but %d - ignored\n",
7480 (int)sizeof(struct sctp_asconf_addrv4_param),
7481 plen);
7482 } else {
7483 fii = (struct sctp_asconf_addrv4_param *)fee;
7484 sin.sin_addr.s_addr = fii->addrp.addr;
7485 lsa = (struct sockaddr *)&sin;
7486 }
7487 break;
7488#endif
7489#ifdef INET6
7490 case SCTP_IPV6_ADDRESS:
7491 if (plen !=
7492 sizeof(struct sctp_asconf_addr_param)) {
7493 SCTP_PRINTF("Sizeof setprim (v6) in init/init ack not %d but %d - ignored\n",
7494 (int)sizeof(struct sctp_asconf_addr_param),
7495 plen);
7496 } else {
7497 memcpy(sin6.sin6_addr.s6_addr,
7498 fee->addrp.addr,
7499 sizeof(fee->addrp.addr));
7500 lsa = (struct sockaddr *)&sin6;
7501 }
7502 break;
7503#endif
7504 default:
7505 break;
7506 }
7507 if (lsa) {
7508 (void)sctp_set_primary_addr(stcb, sa, NULL);
7509 }
7510 } else if (ptype == SCTP_HAS_NAT_SUPPORT) {
7511 stcb->asoc.peer_supports_nat = 1;
7512 } else if (ptype == SCTP_PRSCTP_SUPPORTED) {
7513 /* Peer supports pr-sctp */
t00fcxenaac0f452014-08-12 12:51:45 +00007514 peer_supports_prsctp = 1;
tuexendd729232011-11-01 23:04:43 +00007515 } else if (ptype == SCTP_SUPPORTED_CHUNK_EXT) {
7516 /* A supported extension chunk */
7517 struct sctp_supported_chunk_types_param *pr_supported;
7518 uint8_t local_store[SCTP_PARAM_BUFFER_SIZE];
7519 int num_ent, i;
7520
7521 phdr = sctp_get_next_param(m, offset,
7522 (struct sctp_paramhdr *)&local_store, min(sizeof(local_store),plen));
7523 if (phdr == NULL) {
7524 return (-25);
7525 }
tuexendd729232011-11-01 23:04:43 +00007526 pr_supported = (struct sctp_supported_chunk_types_param *)phdr;
7527 num_ent = plen - sizeof(struct sctp_paramhdr);
7528 for (i = 0; i < num_ent; i++) {
7529 switch (pr_supported->chunk_types[i]) {
7530 case SCTP_ASCONF:
t00fcxenaac0f452014-08-12 12:51:45 +00007531 peer_supports_asconf = 1;
t00fcxen10c96982014-12-17 20:37:01 +00007532 break;
tuexendd729232011-11-01 23:04:43 +00007533 case SCTP_ASCONF_ACK:
t00fcxenaac0f452014-08-12 12:51:45 +00007534 peer_supports_asconf_ack = 1;
tuexendd729232011-11-01 23:04:43 +00007535 break;
7536 case SCTP_FORWARD_CUM_TSN:
t00fcxenaac0f452014-08-12 12:51:45 +00007537 peer_supports_prsctp = 1;
tuexendd729232011-11-01 23:04:43 +00007538 break;
7539 case SCTP_PACKET_DROPPED:
t00fcxenaac0f452014-08-12 12:51:45 +00007540 peer_supports_pktdrop = 1;
tuexendd729232011-11-01 23:04:43 +00007541 break;
7542 case SCTP_NR_SELECTIVE_ACK:
t00fcxenaac0f452014-08-12 12:51:45 +00007543 peer_supports_nrsack = 1;
tuexendd729232011-11-01 23:04:43 +00007544 break;
7545 case SCTP_STREAM_RESET:
t00fcxenaac0f452014-08-12 12:51:45 +00007546 peer_supports_reconfig = 1;
tuexendd729232011-11-01 23:04:43 +00007547 break;
7548 case SCTP_AUTHENTICATION:
t00fcxenaac0f452014-08-12 12:51:45 +00007549 peer_supports_auth = 1;
tuexendd729232011-11-01 23:04:43 +00007550 break;
Michael Tuexene5001952016-04-17 19:25:27 +02007551 case SCTP_IDATA:
7552 peer_supports_idata = 1;
7553 break;
tuexendd729232011-11-01 23:04:43 +00007554 default:
7555 /* one I have not learned yet */
7556 break;
7557
7558 }
7559 }
7560 } else if (ptype == SCTP_RANDOM) {
7561 if (plen > sizeof(random_store))
7562 break;
7563 if (got_random) {
7564 /* already processed a RANDOM */
7565 goto next_param;
7566 }
7567 phdr = sctp_get_next_param(m, offset,
7568 (struct sctp_paramhdr *)random_store,
7569 min(sizeof(random_store),plen));
7570 if (phdr == NULL)
7571 return (-26);
7572 p_random = (struct sctp_auth_random *)phdr;
7573 random_len = plen - sizeof(*p_random);
7574 /* enforce the random length */
7575 if (random_len != SCTP_AUTH_RANDOM_SIZE_REQUIRED) {
7576 SCTPDBG(SCTP_DEBUG_AUTH1, "SCTP: invalid RANDOM len\n");
7577 return (-27);
7578 }
7579 got_random = 1;
7580 } else if (ptype == SCTP_HMAC_LIST) {
t00fcxen05d0bb92014-09-16 14:25:27 +00007581 uint16_t num_hmacs;
7582 uint16_t i;
tuexendd729232011-11-01 23:04:43 +00007583
7584 if (plen > sizeof(hmacs_store))
7585 break;
7586 if (got_hmacs) {
7587 /* already processed a HMAC list */
7588 goto next_param;
7589 }
7590 phdr = sctp_get_next_param(m, offset,
7591 (struct sctp_paramhdr *)hmacs_store,
7592 min(plen,sizeof(hmacs_store)));
7593 if (phdr == NULL)
7594 return (-28);
7595 hmacs = (struct sctp_auth_hmac_algo *)phdr;
7596 hmacs_len = plen - sizeof(*hmacs);
7597 num_hmacs = hmacs_len / sizeof(hmacs->hmac_ids[0]);
7598 /* validate the hmac list */
7599 if (sctp_verify_hmac_param(hmacs, num_hmacs)) {
7600 return (-29);
7601 }
7602 if (stcb->asoc.peer_hmacs != NULL)
7603 sctp_free_hmaclist(stcb->asoc.peer_hmacs);
7604 stcb->asoc.peer_hmacs = sctp_alloc_hmaclist(num_hmacs);
7605 if (stcb->asoc.peer_hmacs != NULL) {
7606 for (i = 0; i < num_hmacs; i++) {
7607 (void)sctp_auth_add_hmacid(stcb->asoc.peer_hmacs,
7608 ntohs(hmacs->hmac_ids[i]));
7609 }
7610 }
7611 got_hmacs = 1;
7612 } else if (ptype == SCTP_CHUNK_LIST) {
7613 int i;
7614
7615 if (plen > sizeof(chunks_store))
7616 break;
7617 if (got_chklist) {
7618 /* already processed a Chunks list */
7619 goto next_param;
7620 }
7621 phdr = sctp_get_next_param(m, offset,
7622 (struct sctp_paramhdr *)chunks_store,
7623 min(plen,sizeof(chunks_store)));
7624 if (phdr == NULL)
7625 return (-30);
7626 chunks = (struct sctp_auth_chunk_list *)phdr;
7627 num_chunks = plen - sizeof(*chunks);
7628 if (stcb->asoc.peer_auth_chunks != NULL)
7629 sctp_clear_chunklist(stcb->asoc.peer_auth_chunks);
7630 else
7631 stcb->asoc.peer_auth_chunks = sctp_alloc_chunklist();
7632 for (i = 0; i < num_chunks; i++) {
7633 (void)sctp_auth_add_chunk(chunks->chunk_types[i],
7634 stcb->asoc.peer_auth_chunks);
7635 /* record asconf/asconf-ack if listed */
7636 if (chunks->chunk_types[i] == SCTP_ASCONF)
7637 saw_asconf = 1;
7638 if (chunks->chunk_types[i] == SCTP_ASCONF_ACK)
7639 saw_asconf_ack = 1;
7640
7641 }
7642 got_chklist = 1;
7643 } else if ((ptype == SCTP_HEARTBEAT_INFO) ||
7644 (ptype == SCTP_STATE_COOKIE) ||
7645 (ptype == SCTP_UNRECOG_PARAM) ||
7646 (ptype == SCTP_COOKIE_PRESERVE) ||
7647 (ptype == SCTP_SUPPORTED_ADDRTYPE) ||
7648 (ptype == SCTP_ADD_IP_ADDRESS) ||
7649 (ptype == SCTP_DEL_IP_ADDRESS) ||
7650 (ptype == SCTP_ERROR_CAUSE_IND) ||
7651 (ptype == SCTP_SUCCESS_REPORT)) {
7652 /* don't care */ ;
7653 } else {
7654 if ((ptype & 0x8000) == 0x0000) {
7655 /*
7656 * must stop processing the rest of the
7657 * param's. Any report bits were handled
7658 * with the call to
7659 * sctp_arethere_unrecognized_parameters()
7660 * when the INIT or INIT-ACK was first seen.
7661 */
7662 break;
7663 }
7664 }
tuexen09631162012-04-18 11:23:02 +00007665
tuexendd729232011-11-01 23:04:43 +00007666 next_param:
7667 offset += SCTP_SIZE32(plen);
7668 if (offset >= limit) {
7669 break;
7670 }
7671 phdr = sctp_get_next_param(m, offset, &parm_buf,
7672 sizeof(parm_buf));
7673 }
7674 /* Now check to see if we need to purge any addresses */
7675 TAILQ_FOREACH_SAFE(net, &stcb->asoc.nets, sctp_next, nnet) {
7676 if ((net->dest_state & SCTP_ADDR_NOT_IN_ASSOC) ==
7677 SCTP_ADDR_NOT_IN_ASSOC) {
7678 /* This address has been removed from the asoc */
7679 /* remove and free it */
7680 stcb->asoc.numnets--;
7681 TAILQ_REMOVE(&stcb->asoc.nets, net, sctp_next);
7682 sctp_free_remote_addr(net);
7683 if (net == stcb->asoc.primary_destination) {
7684 stcb->asoc.primary_destination = NULL;
7685 sctp_select_primary_destination(stcb);
7686 }
7687 }
7688 }
t00fcxenaac0f452014-08-12 12:51:45 +00007689 if ((stcb->asoc.ecn_supported == 1) &&
7690 (peer_supports_ecn == 0)) {
7691 stcb->asoc.ecn_supported = 0;
tuexendd729232011-11-01 23:04:43 +00007692 }
t00fcxenaac0f452014-08-12 12:51:45 +00007693 if ((stcb->asoc.prsctp_supported == 1) &&
7694 (peer_supports_prsctp == 0)) {
7695 stcb->asoc.prsctp_supported = 0;
7696 }
7697 if ((stcb->asoc.auth_supported == 1) &&
7698 ((peer_supports_auth == 0) ||
7699 (got_random == 0) || (got_hmacs == 0))) {
7700 stcb->asoc.auth_supported = 0;
7701 }
7702 if ((stcb->asoc.asconf_supported == 1) &&
7703 ((peer_supports_asconf == 0) || (peer_supports_asconf_ack == 0) ||
7704 (stcb->asoc.auth_supported == 0) ||
7705 (saw_asconf == 0) || (saw_asconf_ack == 0))) {
7706 stcb->asoc.asconf_supported = 0;
7707 }
7708 if ((stcb->asoc.reconfig_supported == 1) &&
7709 (peer_supports_reconfig == 0)) {
7710 stcb->asoc.reconfig_supported = 0;
7711 }
Michael Tuexene5001952016-04-17 19:25:27 +02007712 if ((stcb->asoc.idata_supported == 1) &&
7713 (peer_supports_idata == 0)) {
7714 stcb->asoc.idata_supported = 0;
7715 }
t00fcxenaac0f452014-08-12 12:51:45 +00007716 if ((stcb->asoc.nrsack_supported == 1) &&
7717 (peer_supports_nrsack == 0)) {
7718 stcb->asoc.nrsack_supported = 0;
7719 }
7720 if ((stcb->asoc.pktdrop_supported == 1) &&
7721 (peer_supports_pktdrop == 0)){
7722 stcb->asoc.pktdrop_supported = 0;
7723 }
7724 /* validate authentication required parameters */
7725 if ((peer_supports_auth == 0) && (got_chklist == 1)) {
tuexendd729232011-11-01 23:04:43 +00007726 /* peer does not support auth but sent a chunks list? */
7727 return (-31);
7728 }
t00fcxenaac0f452014-08-12 12:51:45 +00007729 if ((peer_supports_asconf == 1) && (peer_supports_auth == 0)) {
tuexendd729232011-11-01 23:04:43 +00007730 /* peer supports asconf but not auth? */
7731 return (-32);
t00fcxenaac0f452014-08-12 12:51:45 +00007732 } else if ((peer_supports_asconf == 1) &&
7733 (peer_supports_auth == 1) &&
tuexendd729232011-11-01 23:04:43 +00007734 ((saw_asconf == 0) || (saw_asconf_ack == 0))) {
7735 return (-33);
7736 }
7737 /* concatenate the full random key */
7738 keylen = sizeof(*p_random) + random_len + sizeof(*hmacs) + hmacs_len;
7739 if (chunks != NULL) {
7740 keylen += sizeof(*chunks) + num_chunks;
7741 }
7742 new_key = sctp_alloc_key(keylen);
7743 if (new_key != NULL) {
7744 /* copy in the RANDOM */
7745 if (p_random != NULL) {
7746 keylen = sizeof(*p_random) + random_len;
7747 bcopy(p_random, new_key->key, keylen);
7748 }
7749 /* append in the AUTH chunks */
7750 if (chunks != NULL) {
7751 bcopy(chunks, new_key->key + keylen,
7752 sizeof(*chunks) + num_chunks);
7753 keylen += sizeof(*chunks) + num_chunks;
7754 }
7755 /* append in the HMACs */
7756 if (hmacs != NULL) {
7757 bcopy(hmacs, new_key->key + keylen,
7758 sizeof(*hmacs) + hmacs_len);
7759 }
7760 } else {
7761 /* failed to get memory for the key */
7762 return (-34);
7763 }
7764 if (stcb->asoc.authinfo.peer_random != NULL)
7765 sctp_free_key(stcb->asoc.authinfo.peer_random);
7766 stcb->asoc.authinfo.peer_random = new_key;
7767 sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.assoc_keyid);
7768 sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.recv_keyid);
7769
7770 return (0);
7771}
7772
7773int
7774sctp_set_primary_addr(struct sctp_tcb *stcb, struct sockaddr *sa,
7775 struct sctp_nets *net)
7776{
7777 /* make sure the requested primary address exists in the assoc */
7778 if (net == NULL && sa)
7779 net = sctp_findnet(stcb, sa);
7780
7781 if (net == NULL) {
7782 /* didn't find the requested primary address! */
7783 return (-1);
7784 } else {
7785 /* set the primary address */
7786 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
7787 /* Must be confirmed, so queue to set */
7788 net->dest_state |= SCTP_ADDR_REQ_PRIMARY;
7789 return (0);
7790 }
7791 stcb->asoc.primary_destination = net;
7792 if (!(net->dest_state & SCTP_ADDR_PF) && (stcb->asoc.alternate)) {
7793 sctp_free_remote_addr(stcb->asoc.alternate);
7794 stcb->asoc.alternate = NULL;
7795 }
7796 net = TAILQ_FIRST(&stcb->asoc.nets);
7797 if (net != stcb->asoc.primary_destination) {
7798 /* first one on the list is NOT the primary
7799 * sctp_cmpaddr() is much more efficient if
7800 * the primary is the first on the list, make it
7801 * so.
7802 */
7803 TAILQ_REMOVE(&stcb->asoc.nets, stcb->asoc.primary_destination, sctp_next);
7804 TAILQ_INSERT_HEAD(&stcb->asoc.nets, stcb->asoc.primary_destination, sctp_next);
7805 }
7806 return (0);
7807 }
7808}
7809
7810int
tuexen9784e9a2011-12-18 13:04:23 +00007811sctp_is_vtag_good(uint32_t tag, uint16_t lport, uint16_t rport, struct timeval *now)
tuexendd729232011-11-01 23:04:43 +00007812{
7813 /*
7814 * This function serves two purposes. It will see if a TAG can be
7815 * re-used and return 1 for yes it is ok and 0 for don't use that
7816 * tag. A secondary function it will do is purge out old tags that
7817 * can be removed.
7818 */
7819 struct sctpvtaghead *chain;
7820 struct sctp_tagblock *twait_block;
7821 struct sctpasochead *head;
7822 struct sctp_tcb *stcb;
7823 int i;
7824
7825 SCTP_INP_INFO_RLOCK();
7826 head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(tag,
7827 SCTP_BASE_INFO(hashasocmark))];
tuexendd729232011-11-01 23:04:43 +00007828 LIST_FOREACH(stcb, head, sctp_asocs) {
7829 /* We choose not to lock anything here. TCB's can't be
7830 * removed since we have the read lock, so they can't
7831 * be freed on us, same thing for the INP. I may
7832 * be wrong with this assumption, but we will go
7833 * with it for now :-)
7834 */
7835 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
7836 continue;
7837 }
7838 if (stcb->asoc.my_vtag == tag) {
7839 /* candidate */
7840 if (stcb->rport != rport) {
7841 continue;
7842 }
7843 if (stcb->sctp_ep->sctp_lport != lport) {
7844 continue;
7845 }
7846 /* Its a used tag set */
7847 SCTP_INP_INFO_RUNLOCK();
7848 return (0);
7849 }
7850 }
tuexendd729232011-11-01 23:04:43 +00007851 chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
7852 /* Now what about timed wait ? */
t00fcxen14f8fbb2013-06-25 09:32:47 +00007853 LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
tuexendd729232011-11-01 23:04:43 +00007854 /*
7855 * Block(s) are present, lets see if we have this tag in the
7856 * list
7857 */
t00fcxen14f8fbb2013-06-25 09:32:47 +00007858 for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
7859 if (twait_block->vtag_block[i].v_tag == 0) {
7860 /* not used */
7861 continue;
7862 } else if ((long)twait_block->vtag_block[i].tv_sec_at_expire <
7863 now->tv_sec) {
7864 /* Audit expires this guy */
7865 twait_block->vtag_block[i].tv_sec_at_expire = 0;
7866 twait_block->vtag_block[i].v_tag = 0;
7867 twait_block->vtag_block[i].lport = 0;
7868 twait_block->vtag_block[i].rport = 0;
7869 } else if ((twait_block->vtag_block[i].v_tag == tag) &&
7870 (twait_block->vtag_block[i].lport == lport) &&
7871 (twait_block->vtag_block[i].rport == rport)) {
7872 /* Bad tag, sorry :< */
7873 SCTP_INP_INFO_RUNLOCK();
7874 return (0);
tuexendd729232011-11-01 23:04:43 +00007875 }
7876 }
7877 }
7878 SCTP_INP_INFO_RUNLOCK();
7879 return (1);
7880}
7881
tuexendd729232011-11-01 23:04:43 +00007882static void
tuexen9784e9a2011-12-18 13:04:23 +00007883sctp_drain_mbufs(struct sctp_tcb *stcb)
tuexendd729232011-11-01 23:04:43 +00007884{
7885 /*
7886 * We must hunt this association for MBUF's past the cumack (i.e.
7887 * out of order data that we can renege on).
7888 */
7889 struct sctp_association *asoc;
7890 struct sctp_tmit_chunk *chk, *nchk;
7891 uint32_t cumulative_tsn_p1;
7892 struct sctp_queued_to_read *ctl, *nctl;
7893 int cnt, strmat;
7894 uint32_t gap, i;
tuexen63fc0bb2011-12-27 12:24:52 +00007895 int fnd = 0;
tuexendd729232011-11-01 23:04:43 +00007896
7897 /* We look for anything larger than the cum-ack + 1 */
7898
7899 asoc = &stcb->asoc;
7900 if (asoc->cumulative_tsn == asoc->highest_tsn_inside_map) {
7901 /* none we can reneg on. */
7902 return;
7903 }
7904 SCTP_STAT_INCR(sctps_protocol_drains_done);
7905 cumulative_tsn_p1 = asoc->cumulative_tsn + 1;
7906 cnt = 0;
tuexendd729232011-11-01 23:04:43 +00007907 /* Ok that was fun, now we will drain all the inbound streams? */
7908 for (strmat = 0; strmat < asoc->streamincnt; strmat++) {
Michael Tuexene5001952016-04-17 19:25:27 +02007909 TAILQ_FOREACH_SAFE(ctl, &asoc->strmin[strmat].inqueue, next_instrm, nctl) {
tuexendd729232011-11-01 23:04:43 +00007910 if (SCTP_TSN_GT(ctl->sinfo_tsn, cumulative_tsn_p1)) {
7911 /* Yep it is above cum-ack */
7912 cnt++;
7913 SCTP_CALC_TSN_TO_GAP(gap, ctl->sinfo_tsn, asoc->mapping_array_base_tsn);
7914 asoc->size_on_all_streams = sctp_sbspace_sub(asoc->size_on_all_streams, ctl->length);
7915 sctp_ucount_decr(asoc->cnt_on_all_streams);
7916 SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
Michael Tuexene5001952016-04-17 19:25:27 +02007917 TAILQ_REMOVE(&asoc->strmin[strmat].inqueue, ctl, next_instrm);
tuexendd729232011-11-01 23:04:43 +00007918 if (ctl->data) {
7919 sctp_m_freem(ctl->data);
7920 ctl->data = NULL;
7921 }
7922 sctp_free_remote_addr(ctl->whoFrom);
Michael Tuexene5001952016-04-17 19:25:27 +02007923 /* Now its reasm? */
7924 TAILQ_FOREACH_SAFE(chk, &ctl->reasm, sctp_next, nchk) {
7925 cnt++;
7926 SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.TSN_seq, asoc->mapping_array_base_tsn);
7927 asoc->size_on_reasm_queue = sctp_sbspace_sub(asoc->size_on_reasm_queue, chk->send_size);
7928 sctp_ucount_decr(asoc->cnt_on_reasm_queue);
7929 SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
7930 TAILQ_REMOVE(&ctl->reasm, chk, sctp_next);
7931 if (chk->data) {
7932 sctp_m_freem(chk->data);
7933 chk->data = NULL;
7934 }
7935 sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
7936 }
7937 sctp_free_a_readq(stcb, ctl);
7938 }
7939 }
7940 TAILQ_FOREACH_SAFE(ctl, &asoc->strmin[strmat].uno_inqueue, next_instrm, nctl) {
7941 if (SCTP_TSN_GT(ctl->sinfo_tsn, cumulative_tsn_p1)) {
7942 /* Yep it is above cum-ack */
7943 cnt++;
7944 SCTP_CALC_TSN_TO_GAP(gap, ctl->sinfo_tsn, asoc->mapping_array_base_tsn);
7945 asoc->size_on_all_streams = sctp_sbspace_sub(asoc->size_on_all_streams, ctl->length);
7946 sctp_ucount_decr(asoc->cnt_on_all_streams);
7947 SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
7948 TAILQ_REMOVE(&asoc->strmin[strmat].uno_inqueue, ctl, next_instrm);
7949 if (ctl->data) {
7950 sctp_m_freem(ctl->data);
7951 ctl->data = NULL;
7952 }
7953 sctp_free_remote_addr(ctl->whoFrom);
7954 /* Now its reasm? */
7955 TAILQ_FOREACH_SAFE(chk, &ctl->reasm, sctp_next, nchk) {
7956 cnt++;
7957 SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.TSN_seq, asoc->mapping_array_base_tsn);
7958 asoc->size_on_reasm_queue = sctp_sbspace_sub(asoc->size_on_reasm_queue, chk->send_size);
7959 sctp_ucount_decr(asoc->cnt_on_reasm_queue);
7960 SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
7961 TAILQ_REMOVE(&ctl->reasm, chk, sctp_next);
7962 if (chk->data) {
7963 sctp_m_freem(chk->data);
7964 chk->data = NULL;
7965 }
7966 sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
7967 }
7968 sctp_free_a_readq(stcb, ctl);
tuexendd729232011-11-01 23:04:43 +00007969 }
7970 }
7971 }
7972 if (cnt) {
7973 /* We must back down to see what the new highest is */
7974 for (i = asoc->highest_tsn_inside_map; SCTP_TSN_GE(i, asoc->mapping_array_base_tsn); i--) {
7975 SCTP_CALC_TSN_TO_GAP(gap, i, asoc->mapping_array_base_tsn);
7976 if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
7977 asoc->highest_tsn_inside_map = i;
7978 fnd = 1;
7979 break;
7980 }
7981 }
7982 if (!fnd) {
7983 asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1;
7984 }
7985
7986 /*
7987 * Question, should we go through the delivery queue? The only
7988 * reason things are on here is the app not reading OR a p-d-api up.
7989 * An attacker COULD send enough in to initiate the PD-API and then
7990 * send a bunch of stuff to other streams... these would wind up on
7991 * the delivery queue.. and then we would not get to them. But in
7992 * order to do this I then have to back-track and un-deliver
7993 * sequence numbers in streams.. el-yucko. I think for now we will
7994 * NOT look at the delivery queue and leave it to be something to
7995 * consider later. An alternative would be to abort the P-D-API with
7996 * a notification and then deliver the data.... Or another method
7997 * might be to keep track of how many times the situation occurs and
7998 * if we see a possible attack underway just abort the association.
7999 */
8000#ifdef SCTP_DEBUG
8001 SCTPDBG(SCTP_DEBUG_PCB1, "Freed %d chunks from reneg harvest\n", cnt);
8002#endif
8003 /*
8004 * Now do we need to find a new
8005 * asoc->highest_tsn_inside_map?
8006 */
8007 asoc->last_revoke_count = cnt;
8008 (void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
8009 /*sa_ignore NO_NULL_CHK*/
8010 sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
8011 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_DRAIN, SCTP_SO_NOT_LOCKED);
tuexendd729232011-11-01 23:04:43 +00008012 }
8013 /*
8014 * Another issue, in un-setting the TSN's in the mapping array we
8015 * DID NOT adjust the highest_tsn marker. This will cause one of two
8016 * things to occur. It may cause us to do extra work in checking for
8017 * our mapping array movement. More importantly it may cause us to
8018 * SACK every datagram. This may not be a bad thing though since we
8019 * will recover once we get our cum-ack above and all this stuff we
8020 * dumped recovered.
8021 */
8022}
8023
8024void
8025sctp_drain()
8026{
8027 /*
8028 * We must walk the PCB lists for ALL associations here. The system
8029 * is LOW on MBUF's and needs help. This is where reneging will
8030 * occur. We really hope this does NOT happen!
8031 */
8032#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
8033 VNET_ITERATOR_DECL(vnet_iter);
8034#else
8035 struct sctp_inpcb *inp;
8036 struct sctp_tcb *stcb;
8037
8038 SCTP_STAT_INCR(sctps_protocol_drain_calls);
8039 if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
8040 return;
8041 }
8042#endif
8043#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
8044 VNET_LIST_RLOCK_NOSLEEP();
8045 VNET_FOREACH(vnet_iter) {
8046 CURVNET_SET(vnet_iter);
8047 struct sctp_inpcb *inp;
8048 struct sctp_tcb *stcb;
8049#endif
8050
8051#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
8052 SCTP_STAT_INCR(sctps_protocol_drain_calls);
8053 if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
8054#ifdef VIMAGE
8055 continue;
8056#else
8057 return;
tuexen09631162012-04-18 11:23:02 +00008058#endif
tuexendd729232011-11-01 23:04:43 +00008059 }
8060#endif
8061 SCTP_INP_INFO_RLOCK();
8062 LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
8063 /* For each endpoint */
8064 SCTP_INP_RLOCK(inp);
8065 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
8066 /* For each association */
8067 SCTP_TCB_LOCK(stcb);
tuexen9784e9a2011-12-18 13:04:23 +00008068 sctp_drain_mbufs(stcb);
tuexendd729232011-11-01 23:04:43 +00008069 SCTP_TCB_UNLOCK(stcb);
8070 }
8071 SCTP_INP_RUNLOCK(inp);
8072 }
8073 SCTP_INP_INFO_RUNLOCK();
8074#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
8075 CURVNET_RESTORE();
8076 }
8077 VNET_LIST_RUNLOCK_NOSLEEP();
8078#endif
8079}
8080
8081/*
8082 * start a new iterator
8083 * iterates through all endpoints and associations based on the pcb_state
8084 * flags and asoc_state. "af" (mandatory) is executed for all matching
8085 * assocs and "ef" (optional) is executed when the iterator completes.
8086 * "inpf" (optional) is executed for each new endpoint as it is being
8087 * iterated through. inpe (optional) is called when the inp completes
8088 * its way through all the stcbs.
8089 */
8090int
8091sctp_initiate_iterator(inp_func inpf,
8092 asoc_func af,
8093 inp_func inpe,
8094 uint32_t pcb_state,
8095 uint32_t pcb_features,
8096 uint32_t asoc_state,
8097 void *argp,
8098 uint32_t argi,
8099 end_func ef,
8100 struct sctp_inpcb *s_inp,
8101 uint8_t chunk_output_off)
8102{
8103 struct sctp_iterator *it = NULL;
8104
8105 if (af == NULL) {
8106 return (-1);
8107 }
Michael Tuexen71a83fb2016-02-16 21:52:58 +01008108 if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
8109 SCTP_PRINTF("%s: abort on initialize being %d\n", __func__,
8110 SCTP_BASE_VAR(sctp_pcb_initialized));
8111 return (-1);
8112 }
tuexendd729232011-11-01 23:04:43 +00008113 SCTP_MALLOC(it, struct sctp_iterator *, sizeof(struct sctp_iterator),
8114 SCTP_M_ITER);
8115 if (it == NULL) {
8116 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOMEM);
8117 return (ENOMEM);
8118 }
8119 memset(it, 0, sizeof(*it));
8120 it->function_assoc = af;
8121 it->function_inp = inpf;
8122 if (inpf)
8123 it->done_current_ep = 0;
8124 else
8125 it->done_current_ep = 1;
8126 it->function_atend = ef;
8127 it->pointer = argp;
8128 it->val = argi;
8129 it->pcb_flags = pcb_state;
8130 it->pcb_features = pcb_features;
8131 it->asoc_state = asoc_state;
8132 it->function_inp_end = inpe;
8133 it->no_chunk_output = chunk_output_off;
8134#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
8135 it->vn = curvnet;
tuexen09631162012-04-18 11:23:02 +00008136#endif
tuexendd729232011-11-01 23:04:43 +00008137 if (s_inp) {
8138 /* Assume lock is held here */
8139 it->inp = s_inp;
8140 SCTP_INP_INCR_REF(it->inp);
8141 it->iterator_flags = SCTP_ITERATOR_DO_SINGLE_INP;
8142 } else {
8143 SCTP_INP_INFO_RLOCK();
8144 it->inp = LIST_FIRST(&SCTP_BASE_INFO(listhead));
8145 if (it->inp) {
8146 SCTP_INP_INCR_REF(it->inp);
8147 }
8148 SCTP_INP_INFO_RUNLOCK();
8149 it->iterator_flags = SCTP_ITERATOR_DO_ALL_INP;
8150
8151 }
8152 SCTP_IPI_ITERATOR_WQ_LOCK();
Michael Tuexen71a83fb2016-02-16 21:52:58 +01008153 if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
8154 SCTP_IPI_ITERATOR_WQ_UNLOCK();
8155 SCTP_PRINTF("%s: rollback on initialize being %d it=%p\n", __func__,
8156 SCTP_BASE_VAR(sctp_pcb_initialized), it);
8157 SCTP_FREE(it, SCTP_M_ITER);
8158 return (-1);
8159 }
tuexendd729232011-11-01 23:04:43 +00008160 TAILQ_INSERT_TAIL(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
8161 if (sctp_it_ctl.iterator_running == 0) {
8162 sctp_wakeup_iterator();
8163 }
8164 SCTP_IPI_ITERATOR_WQ_UNLOCK();
8165 /* sa_ignore MEMLEAK {memory is put on the tailq for the iterator} */
8166 return (0);
8167}