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