Deleted Added
full compact
sctp_pcb.c (166675) sctp_pcb.c (167598)
1/*-
2 * Copyright (c) 2001-2007, Cisco Systems, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * a) Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.

--- 17 unchanged lines hidden (view full) ---

26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/* $KAME: sctp_pcb.c,v 1.38 2005/03/06 16:04:18 itojun Exp $ */
32
33#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001-2007, Cisco Systems, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * a) Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.

--- 17 unchanged lines hidden (view full) ---

26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/* $KAME: sctp_pcb.c,v 1.38 2005/03/06 16:04:18 itojun Exp $ */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 166675 2007-02-12 23:24:31Z rrs $");
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 167598 2007-03-15 11:27:14Z rrs $");
35
36#include <netinet/sctp_os.h>
37#include <sys/proc.h>
38#include <netinet/sctp_var.h>
35
36#include <netinet/sctp_os.h>
37#include <sys/proc.h>
38#include <netinet/sctp_var.h>
39#include <netinet/sctp_sysctl.h>
39#include <netinet/sctp_pcb.h>
40#include <netinet/sctputil.h>
41#include <netinet/sctp.h>
42#include <netinet/sctp_header.h>
43#include <netinet/sctp_asconf.h>
44#include <netinet/sctp_output.h>
45#include <netinet/sctp_timer.h>
40#include <netinet/sctp_pcb.h>
41#include <netinet/sctputil.h>
42#include <netinet/sctp.h>
43#include <netinet/sctp_header.h>
44#include <netinet/sctp_asconf.h>
45#include <netinet/sctp_output.h>
46#include <netinet/sctp_timer.h>
47#include <netinet/sctp_bsd_addr.h>
46
47
48
49
48#ifdef SCTP_DEBUG
49uint32_t sctp_debug_on = 0;
50
51#endif /* SCTP_DEBUG */
52
53
54extern int sctp_pcbtblsize;
55extern int sctp_hashtblsize;
56extern int sctp_chunkscale;
57
58struct sctp_epinfo sctppcbinfo;
59
60/* FIX: we don't handle multiple link local scopes */
61/* "scopeless" replacement IN6_ARE_ADDR_EQUAL */
62int
63SCTP6_ARE_ADDR_EQUAL(struct in6_addr *a, struct in6_addr *b)
64{
65 struct in6_addr tmp_a, tmp_b;
66
67 /* use a copy of a and b */
68 tmp_a = *a;
69 tmp_b = *b;
70 in6_clearscope(&tmp_a);
71 in6_clearscope(&tmp_b);
72 return (IN6_ARE_ADDR_EQUAL(&tmp_a, &tmp_b));
73}
74
50struct sctp_epinfo sctppcbinfo;
51
52/* FIX: we don't handle multiple link local scopes */
53/* "scopeless" replacement IN6_ARE_ADDR_EQUAL */
54int
55SCTP6_ARE_ADDR_EQUAL(struct in6_addr *a, struct in6_addr *b)
56{
57 struct in6_addr tmp_a, tmp_b;
58
59 /* use a copy of a and b */
60 tmp_a = *a;
61 tmp_b = *b;
62 in6_clearscope(&tmp_a);
63 in6_clearscope(&tmp_b);
64 return (IN6_ARE_ADDR_EQUAL(&tmp_a, &tmp_b));
65}
66
75
76void
77sctp_fill_pcbinfo(struct sctp_pcbinfo *spcb)
78{
79 /*
80 * We really don't need to lock this, but I will just because it
81 * does not hurt.
82 */
83 SCTP_INP_INFO_RLOCK();

--- 4 unchanged lines hidden (view full) ---

88 spcb->chk_count = sctppcbinfo.ipi_count_chunk;
89 spcb->readq_count = sctppcbinfo.ipi_count_readq;
90 spcb->stream_oque = sctppcbinfo.ipi_count_strmoq;
91 spcb->free_chunks = sctppcbinfo.ipi_free_chunks;
92
93 SCTP_INP_INFO_RUNLOCK();
94}
95
67void
68sctp_fill_pcbinfo(struct sctp_pcbinfo *spcb)
69{
70 /*
71 * We really don't need to lock this, but I will just because it
72 * does not hurt.
73 */
74 SCTP_INP_INFO_RLOCK();

--- 4 unchanged lines hidden (view full) ---

79 spcb->chk_count = sctppcbinfo.ipi_count_chunk;
80 spcb->readq_count = sctppcbinfo.ipi_count_readq;
81 spcb->stream_oque = sctppcbinfo.ipi_count_strmoq;
82 spcb->free_chunks = sctppcbinfo.ipi_free_chunks;
83
84 SCTP_INP_INFO_RUNLOCK();
85}
86
87/*
88 * Addresses are added to VRF's (Virtual Router's). For BSD we
89 * have only the default VRF 0. We maintain a hash list of
90 * VRF's. Each VRF has its own list of sctp_ifn's. Each of
91 * these has a list of addresses. When we add a new address
92 * to a VRF we lookup the ifn/ifn_index, if the ifn does
93 * not exist we create it and add it to the list of IFN's
94 * within the VRF. Once we have the sctp_ifn, we add the
95 * address to the list. So we look something like:
96 *
97 * hash-vrf-table
98 * vrf-> ifn-> ifn -> ifn
99 * vrf |
100 * ... +--ifa-> ifa -> ifa
101 * vrf
102 *
103 * We keep these seperate lists since the SCTP subsystem will
104 * point to these from its source address selection nets structure.
105 * When an address is deleted it does not happen right away on
106 * the SCTP side, it gets scheduled. What we do when a
107 * delete happens is immediately remove the address from
108 * the master list and decrement the refcount. As our
109 * addip iterator works through and frees the src address
110 * selection pointing to the sctp_ifa, eventually the refcount
111 * will reach 0 and we will delete it. Note that it is assumed
112 * that any locking on system level ifn/ifa is done at the
113 * caller of these functions and these routines will only
114 * lock the SCTP structures as they add or delete things.
115 *
116 * Other notes on VRF concepts.
117 * - An endpoint can be in multiple VRF's
118 * - An association lives within a VRF and only one VRF.
119 * - Any incoming packet we can deduce the VRF for by
120 * looking at the mbuf/pak inbound (for BSD its VRF=0 :D)
121 * - Any downward send call or connect call must supply the
122 * VRF via ancillary data or via some sort of set default
123 * VRF socket option call (again for BSD no brainer since
124 * the VRF is always 0).
125 * - An endpoint may add multiple VRF's to it.
126 * - Listening sockets can accept associations in any
127 * of the VRF's they are in but the assoc will end up
128 * in only one VRF (gotten from the packet or connect/send).
129 *
130 */
96
131
132struct sctp_vrf *
133sctp_allocate_vrf(int vrfid)
134{
135 struct sctp_vrf *vrf = NULL;
136 struct sctp_vrflist *bucket;
137
138 /* First allocate the VRF structure */
139 vrf = sctp_find_vrf(vrfid);
140 if (vrf) {
141 /* Already allocated */
142 return (vrf);
143 }
144 SCTP_MALLOC(vrf, struct sctp_vrf *, sizeof(struct sctp_vrf),
145 "SCTP_VRF");
146 if (vrf == NULL) {
147 /* No memory */
148#ifdef INVARIANTS
149 panic("No memory for VRF:%d", vrfid);
150#endif
151 return (NULL);
152 }
153 /* setup the VRF */
154 memset(vrf, 0, sizeof(struct sctp_vrf));
155 vrf->vrf_id = vrfid;
156 LIST_INIT(&vrf->ifnlist);
157 vrf->total_ifa_count = 0;
158 /* Add it to the hash table */
159 bucket = &sctppcbinfo.sctp_vrfhash[(vrfid & sctppcbinfo.hashvrfmark)];
160 LIST_INSERT_HEAD(bucket, vrf, next_vrf);
161 return (vrf);
162}
163
164
165struct sctp_ifn *
166sctp_find_ifn(struct sctp_vrf *vrf, void *ifn, uint32_t ifn_index)
167{
168 struct sctp_ifn *sctp_ifnp;
169
170 /*
171 * We assume the lock is held for the addresses if thats wrong
172 * problems could occur :-)
173 */
174 LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) {
175 if (sctp_ifnp->ifn_index == ifn_index) {
176 return (sctp_ifnp);
177 }
178 if (sctp_ifnp->ifn_p && ifn && (sctp_ifnp->ifn_p == ifn)) {
179 return (sctp_ifnp);
180 }
181 }
182 return (NULL);
183}
184
185struct sctp_vrf *
186sctp_find_vrf(uint32_t vrfid)
187{
188 struct sctp_vrflist *bucket;
189 struct sctp_vrf *liste;
190
191 bucket = &sctppcbinfo.sctp_vrfhash[(vrfid & sctppcbinfo.hashvrfmark)];
192 LIST_FOREACH(liste, bucket, next_vrf) {
193 if (vrfid == liste->vrf_id) {
194 return (liste);
195 }
196 }
197 return (NULL);
198}
199
200void
201sctp_free_ifa(struct sctp_ifa *sctp_ifap)
202{
203 int ret;
204
205 ret = atomic_fetchadd_int(&sctp_ifap->refcount, -1);
206 if (ret == 1) {
207 /* We zero'd the count */
208 SCTP_FREE(sctp_ifap);
209 }
210}
211
212struct sctp_ifa *
213sctp_add_addr_to_vrf(uint32_t vrfid, void *ifn, uint32_t ifn_index,
214 uint32_t ifn_type, const char *if_name,
215 void *ifa, struct sockaddr *addr, uint32_t ifa_flags)
216{
217 struct sctp_vrf *vrf;
218 struct sctp_ifn *sctp_ifnp = NULL;
219 struct sctp_ifa *sctp_ifap = NULL;
220
221 /* How granular do we need the locks to be here? */
222 SCTP_IPI_ADDR_LOCK();
223 vrf = sctp_find_vrf(vrfid);
224 if (vrf == NULL) {
225 vrf = sctp_allocate_vrf(vrfid);
226 if (vrf == NULL) {
227 SCTP_IPI_ADDR_UNLOCK();
228 return (NULL);
229 }
230 }
231 sctp_ifnp = sctp_find_ifn(vrf, ifn, ifn_index);
232 if (sctp_ifnp == NULL) {
233 /*
234 * build one and add it, can't hold lock until after malloc
235 * done though.
236 */
237 SCTP_IPI_ADDR_UNLOCK();
238 SCTP_MALLOC(sctp_ifnp, struct sctp_ifn *, sizeof(struct sctp_ifn), "SCTP_IFN");
239 if (sctp_ifnp == NULL) {
240#ifdef INVARIANTS
241 panic("No memory for IFN:%u", sctp_ifnp->ifn_index);
242#endif
243 return (NULL);
244 }
245 sctp_ifnp->ifn_index = ifn_index;
246 sctp_ifnp->ifn_p = ifn;
247 sctp_ifnp->ifn_type = ifn_type;
248 sctp_ifnp->ifa_count = 0;
249 sctp_ifnp->refcount = 0;
250 sctp_ifnp->vrf = vrf;
251 memcpy(sctp_ifnp->ifn_name, if_name, SCTP_IFNAMSIZ);
252 LIST_INIT(&sctp_ifnp->ifalist);
253 SCTP_IPI_ADDR_LOCK();
254 LIST_INSERT_HEAD(&vrf->ifnlist, sctp_ifnp, next_ifn);
255 }
256 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, 1);
257 if (sctp_ifap) {
258 /* Hmm, it already exists? */
259 if ((sctp_ifap->ifn_p) &&
260 (sctp_ifap->ifn_p->ifn_index == ifn_index)) {
261 if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) {
262 /* easy to solve, just switch back to active */
263 sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
264 sctp_ifap->ifn_p = sctp_ifnp;
265 exit_stage_left:
266 SCTP_IPI_ADDR_UNLOCK();
267 return (sctp_ifap);
268 } else {
269 goto exit_stage_left;
270 }
271 } else {
272 if (sctp_ifap->ifn_p) {
273 /*
274 * The first IFN gets the address,
275 * duplicates are ignored.
276 */
277 goto exit_stage_left;
278 } else {
279 /* repair ifnp which was NULL ? */
280 sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
281 sctp_ifap->ifn_p = sctp_ifnp;
282 atomic_add_int(&sctp_ifnp->refcount, 1);
283 }
284 goto exit_stage_left;
285 }
286 }
287 SCTP_IPI_ADDR_UNLOCK();
288 SCTP_MALLOC(sctp_ifap, struct sctp_ifa *, sizeof(struct sctp_ifa), "SCTP_IFA");
289 if (sctp_ifap == NULL) {
290#ifdef INVARIANTS
291 panic("No memory for IFA");
292#endif
293 return (NULL);
294 }
295 memset(sctp_ifap, 0, sizeof(sctp_ifap));
296 sctp_ifap->ifn_p = sctp_ifnp;
297 atomic_add_int(&sctp_ifnp->refcount, 1);
298
299 sctp_ifap->ifa = ifa;
300 memcpy(&sctp_ifap->address, addr, addr->sa_len);
301 sctp_ifap->localifa_flags = SCTP_ADDR_VALID | SCTP_ADDR_DEFER_USE;
302 sctp_ifap->flags = ifa_flags;
303 /* Set scope */
304 if (sctp_ifap->address.sa.sa_family == AF_INET) {
305 struct sockaddr_in *sin;
306
307 sin = (struct sockaddr_in *)&sctp_ifap->address.sin;
308 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
309 (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) {
310 sctp_ifap->src_is_loop = 1;
311 }
312 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
313 sctp_ifap->src_is_priv = 1;
314 }
315 } else if (sctp_ifap->address.sa.sa_family == AF_INET6) {
316 /* ok to use deprecated addresses? */
317 struct sockaddr_in6 *sin6;
318
319 sin6 = (struct sockaddr_in6 *)&sctp_ifap->address.sin6;
320 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
321 (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) {
322 sctp_ifap->src_is_loop = 1;
323 }
324 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
325 sctp_ifap->src_is_priv = 1;
326 }
327 }
328 if ((sctp_ifap->src_is_priv == 0) &&
329 (sctp_ifap->src_is_loop == 0)) {
330 sctp_ifap->src_is_glob = 1;
331 }
332 SCTP_IPI_ADDR_LOCK();
333 sctp_ifap->refcount = 1;
334 LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa);
335 sctp_ifnp->ifa_count++;
336 vrf->total_ifa_count++;
337 SCTP_IPI_ADDR_UNLOCK();
338 return (sctp_ifap);
339}
340
341struct sctp_ifa *
342sctp_del_addr_from_vrf(uint32_t vrfid, struct sockaddr *addr,
343 uint32_t ifn_index)
344{
345 struct sctp_vrf *vrf;
346 struct sctp_ifa *sctp_ifap = NULL;
347 struct sctp_ifn *sctp_ifnp = NULL;
348
349 SCTP_IPI_ADDR_LOCK();
350
351 vrf = sctp_find_vrf(vrfid);
352 if (vrf == NULL) {
353 printf("Can't find vrfid:%d\n", vrfid);
354 goto out_now;
355 }
356 sctp_ifnp = sctp_find_ifn(vrf, (void *)NULL, ifn_index);
357 if (sctp_ifnp == NULL) {
358 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, 1);
359 } else {
360 sctp_ifap = sctp_find_ifa_in_ifn(sctp_ifnp, addr, 1);
361 }
362
363 if (sctp_ifap) {
364 sctp_ifap->localifa_flags &= SCTP_ADDR_VALID;
365 sctp_ifap->localifa_flags |= SCTP_BEING_DELETED;
366 sctp_ifnp->ifa_count--;
367 vrf->total_ifa_count--;
368 LIST_REMOVE(sctp_ifap, next_ifa);
369 atomic_add_int(&sctp_ifnp->refcount, -1);
370 } else {
371 printf("Del Addr-ifn:%d Could not find address:",
372 ifn_index);
373 sctp_print_address(addr);
374 }
375out_now:
376 SCTP_IPI_ADDR_UNLOCK();
377 return (sctp_ifap);
378}
379
97/*
98 * Notes on locks for FreeBSD 5 and up. All association lookups that have a
99 * definte ep, the INP structure is assumed to be locked for reading. If we
100 * need to go find the INP (ususally when a **inp is passed) then we must
101 * lock the INFO structure first and if needed lock the INP too. Note that if
102 * we lock it we must
103 *
104 */

--- 67 unchanged lines hidden (view full) ---

172 if (laddr->ifa == NULL) {
173#ifdef SCTP_DEBUG
174 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
175 printf("An ounce of prevention is worth a pound of cure\n");
176 }
177#endif
178 continue;
179 }
380/*
381 * Notes on locks for FreeBSD 5 and up. All association lookups that have a
382 * definte ep, the INP structure is assumed to be locked for reading. If we
383 * need to go find the INP (ususally when a **inp is passed) then we must
384 * lock the INFO structure first and if needed lock the INP too. Note that if
385 * we lock it we must
386 *
387 */

--- 67 unchanged lines hidden (view full) ---

455 if (laddr->ifa == NULL) {
456#ifdef SCTP_DEBUG
457 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
458 printf("An ounce of prevention is worth a pound of cure\n");
459 }
460#endif
461 continue;
462 }
180 if (laddr->ifa->ifa_addr == NULL) {
463 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
181#ifdef SCTP_DEBUG
182 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
464#ifdef SCTP_DEBUG
465 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
183 printf("ifa with a NULL address\n");
466 printf("ifa being deleted\n");
184 }
185#endif
186 continue;
187 }
467 }
468#endif
469 continue;
470 }
188 if (laddr->ifa->ifa_addr->sa_family ==
471 if (laddr->ifa->address.sa.sa_family ==
189 to->sa_family) {
190 /* see if it matches */
191 struct sockaddr_in *intf_addr, *sin;
192
472 to->sa_family) {
473 /* see if it matches */
474 struct sockaddr_in *intf_addr, *sin;
475
193 intf_addr = (struct sockaddr_in *)
194 laddr->ifa->ifa_addr;
476 intf_addr = &laddr->ifa->address.sin;
195 sin = (struct sockaddr_in *)to;
196 if (from->sa_family == AF_INET) {
197 if (sin->sin_addr.s_addr ==
198 intf_addr->sin_addr.s_addr) {
199 match = 1;
200 break;
201 }
202 } else {
203 struct sockaddr_in6 *intf_addr6;
204 struct sockaddr_in6 *sin6;
205
206 sin6 = (struct sockaddr_in6 *)
207 to;
477 sin = (struct sockaddr_in *)to;
478 if (from->sa_family == AF_INET) {
479 if (sin->sin_addr.s_addr ==
480 intf_addr->sin_addr.s_addr) {
481 match = 1;
482 break;
483 }
484 } else {
485 struct sockaddr_in6 *intf_addr6;
486 struct sockaddr_in6 *sin6;
487
488 sin6 = (struct sockaddr_in6 *)
489 to;
208 intf_addr6 = (struct sockaddr_in6 *)
209 laddr->ifa->ifa_addr;
490 intf_addr6 = &laddr->ifa->address.sin6;
210
211 if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
212 &intf_addr6->sin6_addr)) {
213 match = 1;
214 break;
215 }
216 }
217 }

--- 372 unchanged lines hidden (view full) ---

590 }
591 SCTP_INP_INFO_RUNLOCK();
592 return (NULL);
593}
594
595
596static struct sctp_inpcb *
597sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
491
492 if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
493 &intf_addr6->sin6_addr)) {
494 match = 1;
495 break;
496 }
497 }
498 }

--- 372 unchanged lines hidden (view full) ---

871 }
872 SCTP_INP_INFO_RUNLOCK();
873 return (NULL);
874}
875
876
877static struct sctp_inpcb *
878sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
598 uint16_t lport)
879 uint16_t lport, uint32_t vrf_id)
599{
600 struct sctp_inpcb *inp;
601 struct sockaddr_in *sin;
602 struct sockaddr_in6 *sin6;
603 struct sctp_laddr *laddr;
880{
881 struct sctp_inpcb *inp;
882 struct sockaddr_in *sin;
883 struct sockaddr_in6 *sin6;
884 struct sctp_laddr *laddr;
885 int fnd;
604
605 /*
606 * Endpoing probe expects that the INP_INFO is locked.
607 */
608 if (nam->sa_family == AF_INET) {
609 sin = (struct sockaddr_in *)nam;
610 sin6 = NULL;
611 } else if (nam->sa_family == AF_INET6) {

--- 22 unchanged lines hidden (view full) ---

634 continue;
635 }
636 /* A V6 address and the endpoint is NOT bound V6 */
637 if (nam->sa_family == AF_INET6 &&
638 (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
639 SCTP_INP_RUNLOCK(inp);
640 continue;
641 }
886
887 /*
888 * Endpoing probe expects that the INP_INFO is locked.
889 */
890 if (nam->sa_family == AF_INET) {
891 sin = (struct sockaddr_in *)nam;
892 sin6 = NULL;
893 } else if (nam->sa_family == AF_INET6) {

--- 22 unchanged lines hidden (view full) ---

916 continue;
917 }
918 /* A V6 address and the endpoint is NOT bound V6 */
919 if (nam->sa_family == AF_INET6 &&
920 (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
921 SCTP_INP_RUNLOCK(inp);
922 continue;
923 }
924 /* does a VRF id match? */
925 fnd = 0;
926 if (inp->def_vrf_id == vrf_id)
927 fnd = 1;
928
642 SCTP_INP_RUNLOCK(inp);
929 SCTP_INP_RUNLOCK(inp);
930 if (!fnd)
931 continue;
643 return (inp);
644 }
645 SCTP_INP_RUNLOCK(inp);
646 }
647
648 if ((nam->sa_family == AF_INET) &&
649 (sin->sin_addr.s_addr == INADDR_ANY)) {
650 /* Can't hunt for one that has no address specified */

--- 20 unchanged lines hidden (view full) ---

671 /*
672 * Ok this could be a likely candidate, look at all of its
673 * addresses
674 */
675 if (inp->sctp_lport != lport) {
676 SCTP_INP_RUNLOCK(inp);
677 continue;
678 }
932 return (inp);
933 }
934 SCTP_INP_RUNLOCK(inp);
935 }
936
937 if ((nam->sa_family == AF_INET) &&
938 (sin->sin_addr.s_addr == INADDR_ANY)) {
939 /* Can't hunt for one that has no address specified */

--- 20 unchanged lines hidden (view full) ---

960 /*
961 * Ok this could be a likely candidate, look at all of its
962 * addresses
963 */
964 if (inp->sctp_lport != lport) {
965 SCTP_INP_RUNLOCK(inp);
966 continue;
967 }
968 /* does a VRF id match? */
969 fnd = 0;
970 if (inp->def_vrf_id == vrf_id)
971 fnd = 1;
972
973 if (!fnd) {
974 SCTP_INP_RUNLOCK(inp);
975 continue;
976 }
679 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
680 if (laddr->ifa == NULL) {
681#ifdef SCTP_DEBUG
682 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
683 printf("An ounce of prevention is worth a pound of cure\n");
684 }
685#endif
686 continue;
687 }
688#ifdef SCTP_DEBUG
689 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
690 printf("Ok laddr->ifa:%p is possible, ",
691 laddr->ifa);
692 }
693#endif
977 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
978 if (laddr->ifa == NULL) {
979#ifdef SCTP_DEBUG
980 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
981 printf("An ounce of prevention is worth a pound of cure\n");
982 }
983#endif
984 continue;
985 }
986#ifdef SCTP_DEBUG
987 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
988 printf("Ok laddr->ifa:%p is possible, ",
989 laddr->ifa);
990 }
991#endif
694 if (laddr->ifa->ifa_addr == NULL) {
992 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
695#ifdef SCTP_DEBUG
696 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
993#ifdef SCTP_DEBUG
994 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
697 printf("Huh IFA as an ifa_addr=NULL, ");
995 printf("Huh IFA being deleted\n");
698 }
699#endif
700 continue;
701 }
996 }
997#endif
998 continue;
999 }
702 if (laddr->ifa->ifa_addr->sa_family == nam->sa_family) {
1000 if (laddr->ifa->address.sa.sa_family == nam->sa_family) {
703 /* possible, see if it matches */
704 struct sockaddr_in *intf_addr;
705
1001 /* possible, see if it matches */
1002 struct sockaddr_in *intf_addr;
1003
706 intf_addr = (struct sockaddr_in *)
707 laddr->ifa->ifa_addr;
1004 intf_addr = &laddr->ifa->address.sin;
708 if (nam->sa_family == AF_INET) {
709 if (sin->sin_addr.s_addr ==
710 intf_addr->sin_addr.s_addr) {
711 SCTP_INP_RUNLOCK(inp);
712 return (inp);
713 }
714 } else if (nam->sa_family == AF_INET6) {
715 struct sockaddr_in6 *intf_addr6;
716
1005 if (nam->sa_family == AF_INET) {
1006 if (sin->sin_addr.s_addr ==
1007 intf_addr->sin_addr.s_addr) {
1008 SCTP_INP_RUNLOCK(inp);
1009 return (inp);
1010 }
1011 } else if (nam->sa_family == AF_INET6) {
1012 struct sockaddr_in6 *intf_addr6;
1013
717 intf_addr6 = (struct sockaddr_in6 *)
718 laddr->ifa->ifa_addr;
1014 intf_addr6 = &laddr->ifa->address.sin6;
719 if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
720 &intf_addr6->sin6_addr)) {
721 SCTP_INP_RUNLOCK(inp);
722 return (inp);
723 }
724 }
725 }
726 }
727 SCTP_INP_RUNLOCK(inp);
728 }
729 return (NULL);
730}
731
732
733struct sctp_inpcb *
1015 if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
1016 &intf_addr6->sin6_addr)) {
1017 SCTP_INP_RUNLOCK(inp);
1018 return (inp);
1019 }
1020 }
1021 }
1022 }
1023 SCTP_INP_RUNLOCK(inp);
1024 }
1025 return (NULL);
1026}
1027
1028
1029struct sctp_inpcb *
734sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock)
1030sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock, uint32_t vrf_id)
735{
736 /*
737 * First we check the hash table to see if someone has this port
738 * bound with just the port.
739 */
740 struct sctp_inpcb *inp;
741 struct sctppcbhead *head;
742 struct sockaddr_in *sin;

--- 17 unchanged lines hidden (view full) ---

760 */
761 /* Find the head of the ALLADDR chain */
762 if (have_lock == 0) {
763 SCTP_INP_INFO_RLOCK();
764
765 }
766 head = &sctppcbinfo.sctp_ephash[SCTP_PCBHASH_ALLADDR(lport,
767 sctppcbinfo.hashmark)];
1031{
1032 /*
1033 * First we check the hash table to see if someone has this port
1034 * bound with just the port.
1035 */
1036 struct sctp_inpcb *inp;
1037 struct sctppcbhead *head;
1038 struct sockaddr_in *sin;

--- 17 unchanged lines hidden (view full) ---

1056 */
1057 /* Find the head of the ALLADDR chain */
1058 if (have_lock == 0) {
1059 SCTP_INP_INFO_RLOCK();
1060
1061 }
1062 head = &sctppcbinfo.sctp_ephash[SCTP_PCBHASH_ALLADDR(lport,
1063 sctppcbinfo.hashmark)];
768 inp = sctp_endpoint_probe(nam, head, lport);
1064 inp = sctp_endpoint_probe(nam, head, lport, vrf_id);
769
770 /*
771 * If the TCP model exists it could be that the main listening
772 * endpoint is gone but there exists a connected socket for this guy
773 * yet. If so we can return the first one that we find. This may NOT
774 * be the correct one but the sctp_findassociation_ep_addr has
775 * further code to look at all TCP models.
776 */

--- 4 unchanged lines hidden (view full) ---

781 /*
782 * This is real gross, but we do NOT have a remote
783 * port at this point depending on who is calling.
784 * We must therefore look for ANY one that matches
785 * our local port :/
786 */
787 head = &sctppcbinfo.sctp_tcpephash[i];
788 if (LIST_FIRST(head)) {
1065
1066 /*
1067 * If the TCP model exists it could be that the main listening
1068 * endpoint is gone but there exists a connected socket for this guy
1069 * yet. If so we can return the first one that we find. This may NOT
1070 * be the correct one but the sctp_findassociation_ep_addr has
1071 * further code to look at all TCP models.
1072 */

--- 4 unchanged lines hidden (view full) ---

1077 /*
1078 * This is real gross, but we do NOT have a remote
1079 * port at this point depending on who is calling.
1080 * We must therefore look for ANY one that matches
1081 * our local port :/
1082 */
1083 head = &sctppcbinfo.sctp_tcpephash[i];
1084 if (LIST_FIRST(head)) {
789 inp = sctp_endpoint_probe(nam, head, lport);
1085 inp = sctp_endpoint_probe(nam, head, lport, vrf_id);
790 if (inp) {
791 /* Found one */
792 break;
793 }
794 }
795 }
796 }
797 if (inp) {

--- 7 unchanged lines hidden (view full) ---

805
806/*
807 * Find an association for an endpoint with the pointer to whom you want to
808 * send to and the endpoint pointer. The address can be IPv4 or IPv6. We may
809 * need to change the *to to some other struct like a mbuf...
810 */
811struct sctp_tcb *
812sctp_findassociation_addr_sa(struct sockaddr *to, struct sockaddr *from,
1086 if (inp) {
1087 /* Found one */
1088 break;
1089 }
1090 }
1091 }
1092 }
1093 if (inp) {

--- 7 unchanged lines hidden (view full) ---

1101
1102/*
1103 * Find an association for an endpoint with the pointer to whom you want to
1104 * send to and the endpoint pointer. The address can be IPv4 or IPv6. We may
1105 * need to change the *to to some other struct like a mbuf...
1106 */
1107struct sctp_tcb *
1108sctp_findassociation_addr_sa(struct sockaddr *to, struct sockaddr *from,
813 struct sctp_inpcb **inp_p, struct sctp_nets **netp, int find_tcp_pool)
1109 struct sctp_inpcb **inp_p, struct sctp_nets **netp, int find_tcp_pool, uint32_t vrf_id)
814{
815 struct sctp_inpcb *inp;
816 struct sctp_tcb *retval;
817
818 SCTP_INP_INFO_RLOCK();
819 if (find_tcp_pool) {
820 if (inp_p != NULL) {
821 retval = sctp_tcb_special_locate(inp_p, from, to, netp);
822 } else {
823 retval = sctp_tcb_special_locate(&inp, from, to, netp);
824 }
825 if (retval != NULL) {
826 SCTP_INP_INFO_RUNLOCK();
827 return (retval);
828 }
829 }
1110{
1111 struct sctp_inpcb *inp;
1112 struct sctp_tcb *retval;
1113
1114 SCTP_INP_INFO_RLOCK();
1115 if (find_tcp_pool) {
1116 if (inp_p != NULL) {
1117 retval = sctp_tcb_special_locate(inp_p, from, to, netp);
1118 } else {
1119 retval = sctp_tcb_special_locate(&inp, from, to, netp);
1120 }
1121 if (retval != NULL) {
1122 SCTP_INP_INFO_RUNLOCK();
1123 return (retval);
1124 }
1125 }
830 inp = sctp_pcb_findep(to, 0, 1);
1126 inp = sctp_pcb_findep(to, 0, 1, vrf_id);
831 if (inp_p != NULL) {
832 *inp_p = inp;
833 }
834 SCTP_INP_INFO_RUNLOCK();
835
836 if (inp == NULL) {
837 return (NULL);
838 }

--- 183 unchanged lines hidden (view full) ---

1022{
1023 int find_tcp_pool;
1024 struct ip *iph;
1025 struct sctp_tcb *retval;
1026 struct sockaddr_storage to_store, from_store;
1027 struct sockaddr *to = (struct sockaddr *)&to_store;
1028 struct sockaddr *from = (struct sockaddr *)&from_store;
1029 struct sctp_inpcb *inp;
1127 if (inp_p != NULL) {
1128 *inp_p = inp;
1129 }
1130 SCTP_INP_INFO_RUNLOCK();
1131
1132 if (inp == NULL) {
1133 return (NULL);
1134 }

--- 183 unchanged lines hidden (view full) ---

1318{
1319 int find_tcp_pool;
1320 struct ip *iph;
1321 struct sctp_tcb *retval;
1322 struct sockaddr_storage to_store, from_store;
1323 struct sockaddr *to = (struct sockaddr *)&to_store;
1324 struct sockaddr *from = (struct sockaddr *)&from_store;
1325 struct sctp_inpcb *inp;
1326 uint32_t vrf_id;
1030
1327
1031
1328 vrf_id = SCTP_DEFAULT_VRFID;
1032 iph = mtod(m, struct ip *);
1033 if (iph->ip_v == IPVERSION) {
1034 /* its IPv4 */
1035 struct sockaddr_in *from4;
1036
1037 from4 = (struct sockaddr_in *)&from_store;
1038 bzero(from4, sizeof(*from4));
1039 from4->sin_family = AF_INET;

--- 66 unchanged lines hidden (view full) ---

1106 (ch->chunk_type != SCTP_INITIATION_ACK) &&
1107 (ch->chunk_type != SCTP_COOKIE_ACK) &&
1108 (ch->chunk_type != SCTP_COOKIE_ECHO)) {
1109 /* Other chunk types go to the tcp pool. */
1110 find_tcp_pool = 1;
1111 }
1112 if (inp_p) {
1113 retval = sctp_findassociation_addr_sa(to, from, inp_p, netp,
1329 iph = mtod(m, struct ip *);
1330 if (iph->ip_v == IPVERSION) {
1331 /* its IPv4 */
1332 struct sockaddr_in *from4;
1333
1334 from4 = (struct sockaddr_in *)&from_store;
1335 bzero(from4, sizeof(*from4));
1336 from4->sin_family = AF_INET;

--- 66 unchanged lines hidden (view full) ---

1403 (ch->chunk_type != SCTP_INITIATION_ACK) &&
1404 (ch->chunk_type != SCTP_COOKIE_ACK) &&
1405 (ch->chunk_type != SCTP_COOKIE_ECHO)) {
1406 /* Other chunk types go to the tcp pool. */
1407 find_tcp_pool = 1;
1408 }
1409 if (inp_p) {
1410 retval = sctp_findassociation_addr_sa(to, from, inp_p, netp,
1114 find_tcp_pool);
1411 find_tcp_pool, vrf_id);
1115 inp = *inp_p;
1116 } else {
1117 retval = sctp_findassociation_addr_sa(to, from, &inp, netp,
1412 inp = *inp_p;
1413 } else {
1414 retval = sctp_findassociation_addr_sa(to, from, &inp, netp,
1118 find_tcp_pool);
1415 find_tcp_pool, vrf_id);
1119 }
1120#ifdef SCTP_DEBUG
1121 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
1122 printf("retval:%p inp:%p\n", retval, inp);
1123 }
1124#endif
1125 if (retval == NULL && inp) {
1126 /* Found a EP but not this address */

--- 150 unchanged lines hidden (view full) ---

1277 stcb = sctp_findassociation_ep_addr(inp_p,
1278 (struct sockaddr *)&remote_store, netp,
1279 (struct sockaddr *)&local_store, NULL);
1280 }
1281 return (stcb);
1282}
1283
1284
1416 }
1417#ifdef SCTP_DEBUG
1418 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
1419 printf("retval:%p inp:%p\n", retval, inp);
1420 }
1421#endif
1422 if (retval == NULL && inp) {
1423 /* Found a EP but not this address */

--- 150 unchanged lines hidden (view full) ---

1574 stcb = sctp_findassociation_ep_addr(inp_p,
1575 (struct sockaddr *)&remote_store, netp,
1576 (struct sockaddr *)&local_store, NULL);
1577 }
1578 return (stcb);
1579}
1580
1581
1285extern int sctp_max_burst_default;
1286
1287extern unsigned int sctp_delayed_sack_time_default;
1288extern unsigned int sctp_heartbeat_interval_default;
1289extern unsigned int sctp_pmtu_raise_time_default;
1290extern unsigned int sctp_shutdown_guard_time_default;
1291extern unsigned int sctp_secret_lifetime_default;
1292
1293extern unsigned int sctp_rto_max_default;
1294extern unsigned int sctp_rto_min_default;
1295extern unsigned int sctp_rto_initial_default;
1296extern unsigned int sctp_init_rto_max_default;
1297extern unsigned int sctp_valid_cookie_life_default;
1298extern unsigned int sctp_init_rtx_max_default;
1299extern unsigned int sctp_assoc_rtx_max_default;
1300extern unsigned int sctp_path_rtx_max_default;
1301extern unsigned int sctp_nr_outgoing_streams_default;
1302
1303/*
1304 * allocate a sctp_inpcb and setup a temporary binding to a port/all
1305 * addresses. This way if we don't get a bind we by default pick a ephemeral
1306 * port with all addresses bound.
1307 */
1308int
1309sctp_inpcb_alloc(struct socket *so)
1310{

--- 48 unchanged lines hidden (view full) ---

1359 }
1360#endif /* IPSEC */
1361 SCTP_INCR_EP_COUNT();
1362 inp->ip_inp.inp.inp_ip_ttl = ip_defttl;
1363 SCTP_INP_INFO_WUNLOCK();
1364
1365 so->so_pcb = (caddr_t)inp;
1366
1582/*
1583 * allocate a sctp_inpcb and setup a temporary binding to a port/all
1584 * addresses. This way if we don't get a bind we by default pick a ephemeral
1585 * port with all addresses bound.
1586 */
1587int
1588sctp_inpcb_alloc(struct socket *so)
1589{

--- 48 unchanged lines hidden (view full) ---

1638 }
1639#endif /* IPSEC */
1640 SCTP_INCR_EP_COUNT();
1641 inp->ip_inp.inp.inp_ip_ttl = ip_defttl;
1642 SCTP_INP_INFO_WUNLOCK();
1643
1644 so->so_pcb = (caddr_t)inp;
1645
1367 if ((so->so_type == SOCK_DGRAM) ||
1368 (so->so_type == SOCK_SEQPACKET)) {
1646 if ((SCTP_SO_TYPE(so) == SOCK_DGRAM) ||
1647 (SCTP_SO_TYPE(so) == SOCK_SEQPACKET)) {
1369 /* UDP style socket */
1370 inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |
1371 SCTP_PCB_FLAGS_UNBOUND);
1372 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT);
1373 /* Be sure it is NON-BLOCKING IO for UDP */
1648 /* UDP style socket */
1649 inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |
1650 SCTP_PCB_FLAGS_UNBOUND);
1651 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT);
1652 /* Be sure it is NON-BLOCKING IO for UDP */
1374 /* so->so_state |= SS_NBIO; */
1375 } else if (so->so_type == SOCK_STREAM) {
1653 /* SCTP_SET_SO_NBIO(so); */
1654 } else if (SCTP_SO_TYPE(so) == SOCK_STREAM) {
1376 /* TCP style socket */
1377 inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE |
1378 SCTP_PCB_FLAGS_UNBOUND);
1379 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT);
1380 /* Be sure we have blocking IO by default */
1655 /* TCP style socket */
1656 inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE |
1657 SCTP_PCB_FLAGS_UNBOUND);
1658 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT);
1659 /* Be sure we have blocking IO by default */
1381 so->so_state &= ~SS_NBIO;
1660 SCTP_CLEAR_SO_NBIO(so);
1382 } else {
1383 /*
1384 * unsupported socket type (RAW, etc)- in case we missed it
1385 * in protosw
1386 */
1387 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp);
1388 return (EOPNOTSUPP);
1389 }
1390 inp->sctp_tcbhash = SCTP_HASH_INIT(sctp_pcbtblsize,
1391 &inp->sctp_hashmark);
1392 if (inp->sctp_tcbhash == NULL) {
1393 printf("Out of SCTP-INPCB->hashinit - no resources\n");
1394 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp);
1395 return (ENOBUFS);
1396 }
1661 } else {
1662 /*
1663 * unsupported socket type (RAW, etc)- in case we missed it
1664 * in protosw
1665 */
1666 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp);
1667 return (EOPNOTSUPP);
1668 }
1669 inp->sctp_tcbhash = SCTP_HASH_INIT(sctp_pcbtblsize,
1670 &inp->sctp_hashmark);
1671 if (inp->sctp_tcbhash == NULL) {
1672 printf("Out of SCTP-INPCB->hashinit - no resources\n");
1673 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp);
1674 return (ENOBUFS);
1675 }
1676 inp->def_vrf_id = SCTP_DEFAULT_VRFID;
1677
1397 SCTP_INP_INFO_WLOCK();
1398 SCTP_INP_LOCK_INIT(inp);
1399 SCTP_INP_READ_INIT(inp);
1400 SCTP_ASOC_CREATE_LOCK_INIT(inp);
1401 /* lock the new ep */
1402 SCTP_INP_WLOCK(inp);
1403
1404 /* add it to the info area */
1405 LIST_INSERT_HEAD(&sctppcbinfo.listhead, inp, sctp_list);
1406 SCTP_INP_INFO_WUNLOCK();
1407
1408 TAILQ_INIT(&inp->read_queue);
1409 LIST_INIT(&inp->sctp_addr_list);
1678 SCTP_INP_INFO_WLOCK();
1679 SCTP_INP_LOCK_INIT(inp);
1680 SCTP_INP_READ_INIT(inp);
1681 SCTP_ASOC_CREATE_LOCK_INIT(inp);
1682 /* lock the new ep */
1683 SCTP_INP_WLOCK(inp);
1684
1685 /* add it to the info area */
1686 LIST_INSERT_HEAD(&sctppcbinfo.listhead, inp, sctp_list);
1687 SCTP_INP_INFO_WUNLOCK();
1688
1689 TAILQ_INIT(&inp->read_queue);
1690 LIST_INIT(&inp->sctp_addr_list);
1691
1410 LIST_INIT(&inp->sctp_asoc_list);
1411
1412#ifdef SCTP_TRACK_FREED_ASOCS
1413 /* TEMP CODE */
1414 LIST_INIT(&inp->sctp_asoc_free_list);
1415#endif
1416 /* Init the timer structure for signature change */
1417 SCTP_OS_TIMER_INIT(&inp->sctp_ep.signature_change.timer);

--- 10 unchanged lines hidden (view full) ---

1428 m->sctp_timeoutticks[SCTP_TIMER_PMTU] = SEC_TO_TICKS(sctp_pmtu_raise_time_default);
1429 m->sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] = SEC_TO_TICKS(sctp_shutdown_guard_time_default);
1430 m->sctp_timeoutticks[SCTP_TIMER_SIGNATURE] = SEC_TO_TICKS(sctp_secret_lifetime_default);
1431 /* all max/min max are in ms */
1432 m->sctp_maxrto = sctp_rto_max_default;
1433 m->sctp_minrto = sctp_rto_min_default;
1434 m->initial_rto = sctp_rto_initial_default;
1435 m->initial_init_rto_max = sctp_init_rto_max_default;
1692 LIST_INIT(&inp->sctp_asoc_list);
1693
1694#ifdef SCTP_TRACK_FREED_ASOCS
1695 /* TEMP CODE */
1696 LIST_INIT(&inp->sctp_asoc_free_list);
1697#endif
1698 /* Init the timer structure for signature change */
1699 SCTP_OS_TIMER_INIT(&inp->sctp_ep.signature_change.timer);

--- 10 unchanged lines hidden (view full) ---

1710 m->sctp_timeoutticks[SCTP_TIMER_PMTU] = SEC_TO_TICKS(sctp_pmtu_raise_time_default);
1711 m->sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] = SEC_TO_TICKS(sctp_shutdown_guard_time_default);
1712 m->sctp_timeoutticks[SCTP_TIMER_SIGNATURE] = SEC_TO_TICKS(sctp_secret_lifetime_default);
1713 /* all max/min max are in ms */
1714 m->sctp_maxrto = sctp_rto_max_default;
1715 m->sctp_minrto = sctp_rto_min_default;
1716 m->initial_rto = sctp_rto_initial_default;
1717 m->initial_init_rto_max = sctp_init_rto_max_default;
1718 m->sctp_sack_freq = sctp_sack_freq_default;
1436
1437 m->max_open_streams_intome = MAX_SCTP_STREAMS;
1438
1439 m->max_init_times = sctp_init_rtx_max_default;
1440 m->max_send_times = sctp_assoc_rtx_max_default;
1441 m->def_net_failure = sctp_path_rtx_max_default;
1442 m->sctp_sws_sender = SCTP_SWS_SENDER_DEF;
1443 m->sctp_sws_receiver = SCTP_SWS_RECEIVER_DEF;

--- 21 unchanged lines hidden (view full) ---

1465
1466 for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) {
1467 m->secret_key[0][i] = sctp_select_initial_TSN(m);
1468 }
1469 sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL);
1470
1471 /* How long is a cookie good for ? */
1472 m->def_cookie_life = sctp_valid_cookie_life_default;
1719
1720 m->max_open_streams_intome = MAX_SCTP_STREAMS;
1721
1722 m->max_init_times = sctp_init_rtx_max_default;
1723 m->max_send_times = sctp_assoc_rtx_max_default;
1724 m->def_net_failure = sctp_path_rtx_max_default;
1725 m->sctp_sws_sender = SCTP_SWS_SENDER_DEF;
1726 m->sctp_sws_receiver = SCTP_SWS_RECEIVER_DEF;

--- 21 unchanged lines hidden (view full) ---

1748
1749 for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) {
1750 m->secret_key[0][i] = sctp_select_initial_TSN(m);
1751 }
1752 sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL);
1753
1754 /* How long is a cookie good for ? */
1755 m->def_cookie_life = sctp_valid_cookie_life_default;
1473
1474 /*
1475 * Initialize authentication parameters
1476 */
1477 m->local_hmacs = sctp_default_supported_hmaclist();
1478 m->local_auth_chunks = sctp_alloc_chunklist();
1479 sctp_auth_set_default_chunks(m->local_auth_chunks);
1480 LIST_INIT(&m->shared_keys);
1481 /* add default NULL key as key id 0 */

--- 114 unchanged lines hidden (view full) ---

1596 net->rxt_timer.ep = (void *)new_inp;
1597 net->fr_timer.ep = (void *)new_inp;
1598 }
1599 SCTP_INP_WUNLOCK(new_inp);
1600 SCTP_INP_WUNLOCK(old_inp);
1601}
1602
1603static int
1756 /*
1757 * Initialize authentication parameters
1758 */
1759 m->local_hmacs = sctp_default_supported_hmaclist();
1760 m->local_auth_chunks = sctp_alloc_chunklist();
1761 sctp_auth_set_default_chunks(m->local_auth_chunks);
1762 LIST_INIT(&m->shared_keys);
1763 /* add default NULL key as key id 0 */

--- 114 unchanged lines hidden (view full) ---

1878 net->rxt_timer.ep = (void *)new_inp;
1879 net->fr_timer.ep = (void *)new_inp;
1880 }
1881 SCTP_INP_WUNLOCK(new_inp);
1882 SCTP_INP_WUNLOCK(old_inp);
1883}
1884
1885static int
1604sctp_isport_inuse(struct sctp_inpcb *inp, uint16_t lport)
1886sctp_isport_inuse(struct sctp_inpcb *inp, uint16_t lport, uint32_t vrf_id)
1605{
1606 struct sctppcbhead *head;
1607 struct sctp_inpcb *t_inp;
1887{
1888 struct sctppcbhead *head;
1889 struct sctp_inpcb *t_inp;
1890 int fnd;
1608
1609 head = &sctppcbinfo.sctp_ephash[SCTP_PCBHASH_ALLADDR(lport,
1610 sctppcbinfo.hashmark)];
1611
1612 LIST_FOREACH(t_inp, head, sctp_hash) {
1613 if (t_inp->sctp_lport != lport) {
1614 continue;
1615 }
1891
1892 head = &sctppcbinfo.sctp_ephash[SCTP_PCBHASH_ALLADDR(lport,
1893 sctppcbinfo.hashmark)];
1894
1895 LIST_FOREACH(t_inp, head, sctp_hash) {
1896 if (t_inp->sctp_lport != lport) {
1897 continue;
1898 }
1899 /* is it in the VRF in question */
1900 fnd = 0;
1901 if (t_inp->def_vrf_id == vrf_id)
1902 fnd = 1;
1903 if (!fnd)
1904 continue;
1905
1616 /* This one is in use. */
1617 /* check the v6/v4 binding issue */
1618 if ((t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
1619 SCTP_IPV6_V6ONLY(t_inp)) {
1620 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1621 /* collision in V6 space */
1622 return (1);
1623 } else {

--- 24 unchanged lines hidden (view full) ---

1648{
1649 /* bind a ep to a socket address */
1650 struct sctppcbhead *head;
1651 struct sctp_inpcb *inp, *inp_tmp;
1652 struct inpcb *ip_inp;
1653 int bindall;
1654 uint16_t lport;
1655 int error;
1906 /* This one is in use. */
1907 /* check the v6/v4 binding issue */
1908 if ((t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
1909 SCTP_IPV6_V6ONLY(t_inp)) {
1910 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1911 /* collision in V6 space */
1912 return (1);
1913 } else {

--- 24 unchanged lines hidden (view full) ---

1938{
1939 /* bind a ep to a socket address */
1940 struct sctppcbhead *head;
1941 struct sctp_inpcb *inp, *inp_tmp;
1942 struct inpcb *ip_inp;
1943 int bindall;
1944 uint16_t lport;
1945 int error;
1946 uint32_t vrf_id;
1656
1657 lport = 0;
1658 error = 0;
1659 bindall = 1;
1660 inp = (struct sctp_inpcb *)so->so_pcb;
1661 ip_inp = (struct inpcb *)so->so_pcb;
1662#ifdef SCTP_DEBUG
1663 if (sctp_debug_on & SCTP_DEBUG_PCB1) {

--- 43 unchanged lines hidden (view full) ---

1707 return (EINVAL);
1708 }
1709 /* this must be cleared for ifa_ifwithaddr() */
1710 sin6->sin6_scope_id = 0;
1711 } else {
1712 return (EAFNOSUPPORT);
1713 }
1714 }
1947
1948 lport = 0;
1949 error = 0;
1950 bindall = 1;
1951 inp = (struct sctp_inpcb *)so->so_pcb;
1952 ip_inp = (struct inpcb *)so->so_pcb;
1953#ifdef SCTP_DEBUG
1954 if (sctp_debug_on & SCTP_DEBUG_PCB1) {

--- 43 unchanged lines hidden (view full) ---

1998 return (EINVAL);
1999 }
2000 /* this must be cleared for ifa_ifwithaddr() */
2001 sin6->sin6_scope_id = 0;
2002 } else {
2003 return (EAFNOSUPPORT);
2004 }
2005 }
2006 /*
2007 * Setup a vrf_id to be the default for the non-bind-all case.
2008 */
2009 vrf_id = inp->def_vrf_id;
2010
1715 SCTP_INP_INFO_WLOCK();
1716 SCTP_INP_WLOCK(inp);
1717 /* increase our count due to the unlock we do */
1718 SCTP_INP_INCR_REF(inp);
1719 if (lport) {
1720 /*
1721 * Did the caller specify a port? if so we must see if a ep
1722 * already has this one bound.
1723 */
1724 /* got to be root to get at low ports */
1725 if (ntohs(lport) < IPPORT_RESERVED) {
1726 if (p && (error =
2011 SCTP_INP_INFO_WLOCK();
2012 SCTP_INP_WLOCK(inp);
2013 /* increase our count due to the unlock we do */
2014 SCTP_INP_INCR_REF(inp);
2015 if (lport) {
2016 /*
2017 * Did the caller specify a port? if so we must see if a ep
2018 * already has this one bound.
2019 */
2020 /* got to be root to get at low ports */
2021 if (ntohs(lport) < IPPORT_RESERVED) {
2022 if (p && (error =
1727 priv_check(p,
1728 PRIV_NETINET_RESERVEDPORT)
2023 priv_check_cred(p->td_ucred,
2024 PRIV_NETINET_RESERVEDPORT,
2025 SUSER_ALLOWJAIL
2026 )
1729 )) {
1730 SCTP_INP_DECR_REF(inp);
1731 SCTP_INP_WUNLOCK(inp);
1732 SCTP_INP_INFO_WUNLOCK();
1733 return (error);
1734 }
1735 }
1736 if (p == NULL) {
1737 SCTP_INP_DECR_REF(inp);
1738 SCTP_INP_WUNLOCK(inp);
1739 SCTP_INP_INFO_WUNLOCK();
1740 return (error);
1741 }
1742 SCTP_INP_WUNLOCK(inp);
2027 )) {
2028 SCTP_INP_DECR_REF(inp);
2029 SCTP_INP_WUNLOCK(inp);
2030 SCTP_INP_INFO_WUNLOCK();
2031 return (error);
2032 }
2033 }
2034 if (p == NULL) {
2035 SCTP_INP_DECR_REF(inp);
2036 SCTP_INP_WUNLOCK(inp);
2037 SCTP_INP_INFO_WUNLOCK();
2038 return (error);
2039 }
2040 SCTP_INP_WUNLOCK(inp);
1743 inp_tmp = sctp_pcb_findep(addr, 0, 1);
1744 if (inp_tmp != NULL) {
1745 /*
1746 * lock guy returned and lower count note that we
1747 * are not bound so inp_tmp should NEVER be inp. And
1748 * it is this inp (inp_tmp) that gets the reference
1749 * bump, so we must lower it.
1750 */
1751 SCTP_INP_DECR_REF(inp_tmp);
1752 SCTP_INP_DECR_REF(inp);
1753 /* unlock info */
1754 SCTP_INP_INFO_WUNLOCK();
1755 return (EADDRNOTAVAIL);
2041 if (bindall) {
2042 vrf_id = inp->def_vrf_id;
2043 inp_tmp = sctp_pcb_findep(addr, 0, 1, vrf_id);
2044 if (inp_tmp != NULL) {
2045 /*
2046 * lock guy returned and lower count note
2047 * that we are not bound so inp_tmp should
2048 * NEVER be inp. And it is this inp
2049 * (inp_tmp) that gets the reference bump,
2050 * so we must lower it.
2051 */
2052 SCTP_INP_DECR_REF(inp_tmp);
2053 SCTP_INP_DECR_REF(inp);
2054 /* unlock info */
2055 SCTP_INP_INFO_WUNLOCK();
2056 return (EADDRNOTAVAIL);
2057 }
2058 } else {
2059 inp_tmp = sctp_pcb_findep(addr, 0, 1, vrf_id);
2060 if (inp_tmp != NULL) {
2061 /*
2062 * lock guy returned and lower count note
2063 * that we are not bound so inp_tmp should
2064 * NEVER be inp. And it is this inp
2065 * (inp_tmp) that gets the reference bump,
2066 * so we must lower it.
2067 */
2068 SCTP_INP_DECR_REF(inp_tmp);
2069 SCTP_INP_DECR_REF(inp);
2070 /* unlock info */
2071 SCTP_INP_INFO_WUNLOCK();
2072 return (EADDRNOTAVAIL);
2073 }
1756 }
1757 SCTP_INP_WLOCK(inp);
1758 if (bindall) {
1759 /* verify that no lport is not used by a singleton */
2074 }
2075 SCTP_INP_WLOCK(inp);
2076 if (bindall) {
2077 /* verify that no lport is not used by a singleton */
1760 if (sctp_isport_inuse(inp, lport)) {
2078 if (sctp_isport_inuse(inp, lport, vrf_id)) {
1761 /* Sorry someone already has this one bound */
1762 SCTP_INP_DECR_REF(inp);
1763 SCTP_INP_WUNLOCK(inp);
1764 SCTP_INP_INFO_WUNLOCK();
1765 return (EADDRNOTAVAIL);
1766 }
1767 }
1768 } else {

--- 4 unchanged lines hidden (view full) ---

1773
1774 /*
1775 * setup the inp to the top (I could use the union but this
1776 * is just as easy
1777 */
1778 uint32_t port_guess;
1779 uint16_t port_attempt;
1780 int not_done = 1;
2079 /* Sorry someone already has this one bound */
2080 SCTP_INP_DECR_REF(inp);
2081 SCTP_INP_WUNLOCK(inp);
2082 SCTP_INP_INFO_WUNLOCK();
2083 return (EADDRNOTAVAIL);
2084 }
2085 }
2086 } else {

--- 4 unchanged lines hidden (view full) ---

2091
2092 /*
2093 * setup the inp to the top (I could use the union but this
2094 * is just as easy
2095 */
2096 uint32_t port_guess;
2097 uint16_t port_attempt;
2098 int not_done = 1;
2099 int not_found = 1;
1781
1782 while (not_done) {
1783 port_guess = sctp_select_initial_TSN(&inp->sctp_ep);
1784 port_attempt = (port_guess & 0x0000ffff);
1785 if (port_attempt == 0) {
1786 goto next_half;
1787 }
1788 if (port_attempt < IPPORT_RESERVED) {
1789 port_attempt += IPPORT_RESERVED;
1790 }
2100
2101 while (not_done) {
2102 port_guess = sctp_select_initial_TSN(&inp->sctp_ep);
2103 port_attempt = (port_guess & 0x0000ffff);
2104 if (port_attempt == 0) {
2105 goto next_half;
2106 }
2107 if (port_attempt < IPPORT_RESERVED) {
2108 port_attempt += IPPORT_RESERVED;
2109 }
1791 if (sctp_isport_inuse(inp, htons(port_attempt)) == 0) {
2110 vrf_id = inp->def_vrf_id;
2111 if (sctp_isport_inuse(inp, htons(port_attempt), vrf_id) == 1) {
1792 /* got a port we can use */
2112 /* got a port we can use */
2113 not_found = 0;
2114 break;
2115 }
2116 if (not_found == 1) {
2117 /* We can use this port */
1793 not_done = 0;
1794 continue;
1795 }
1796 /* try upper half */
1797 next_half:
1798 port_attempt = ((port_guess >> 16) & 0x0000ffff);
1799 if (port_attempt == 0) {
1800 goto last_try;
1801 }
1802 if (port_attempt < IPPORT_RESERVED) {
1803 port_attempt += IPPORT_RESERVED;
1804 }
2118 not_done = 0;
2119 continue;
2120 }
2121 /* try upper half */
2122 next_half:
2123 port_attempt = ((port_guess >> 16) & 0x0000ffff);
2124 if (port_attempt == 0) {
2125 goto last_try;
2126 }
2127 if (port_attempt < IPPORT_RESERVED) {
2128 port_attempt += IPPORT_RESERVED;
2129 }
1805 if (sctp_isport_inuse(inp, htons(port_attempt)) == 0) {
2130 vrf_id = inp->def_vrf_id;
2131 if (sctp_isport_inuse(inp, htons(port_attempt), vrf_id) == 1) {
1806 /* got a port we can use */
2132 /* got a port we can use */
2133 not_found = 0;
2134 break;
2135 }
2136 if (not_found == 1) {
2137 /* We can use this port */
1807 not_done = 0;
1808 continue;
1809 }
1810 /* try two half's added together */
1811 last_try:
1812 port_attempt = (((port_guess >> 16) & 0x0000ffff) +
1813 (port_guess & 0x0000ffff));
1814 if (port_attempt == 0) {
1815 /* get a new random number */
1816 continue;
1817 }
1818 if (port_attempt < IPPORT_RESERVED) {
1819 port_attempt += IPPORT_RESERVED;
1820 }
2138 not_done = 0;
2139 continue;
2140 }
2141 /* try two half's added together */
2142 last_try:
2143 port_attempt = (((port_guess >> 16) & 0x0000ffff) +
2144 (port_guess & 0x0000ffff));
2145 if (port_attempt == 0) {
2146 /* get a new random number */
2147 continue;
2148 }
2149 if (port_attempt < IPPORT_RESERVED) {
2150 port_attempt += IPPORT_RESERVED;
2151 }
1821 if (sctp_isport_inuse(inp, htons(port_attempt)) == 0) {
2152 vrf_id = inp->def_vrf_id;
2153 if (sctp_isport_inuse(inp, htons(port_attempt), vrf_id) == 1) {
1822 /* got a port we can use */
2154 /* got a port we can use */
2155 not_found = 0;
2156 break;
2157 }
2158 if (not_found == 1) {
2159 /* We can use this port */
1823 not_done = 0;
1824 continue;
1825 }
1826 }
1827 /* we don't get out of the loop until we have a port */
1828 lport = htons(port_attempt);
1829 }
1830 SCTP_INP_DECR_REF(inp);

--- 24 unchanged lines hidden (view full) ---

1855 * address structure to the sctp_addr_list inside the ep
1856 * structure.
1857 *
1858 * We will need to allocate one and insert it at the head. The
1859 * socketopt call can just insert new addresses in there as
1860 * well. It will also have to do the embed scope kame hack
1861 * too (before adding).
1862 */
2160 not_done = 0;
2161 continue;
2162 }
2163 }
2164 /* we don't get out of the loop until we have a port */
2165 lport = htons(port_attempt);
2166 }
2167 SCTP_INP_DECR_REF(inp);

--- 24 unchanged lines hidden (view full) ---

2192 * address structure to the sctp_addr_list inside the ep
2193 * structure.
2194 *
2195 * We will need to allocate one and insert it at the head. The
2196 * socketopt call can just insert new addresses in there as
2197 * well. It will also have to do the embed scope kame hack
2198 * too (before adding).
2199 */
1863 struct ifaddr *ifa;
2200 struct sctp_ifa *ifa;
1864 struct sockaddr_storage store_sa;
1865
1866 memset(&store_sa, 0, sizeof(store_sa));
1867 if (addr->sa_family == AF_INET) {
1868 struct sockaddr_in *sin;
1869
1870 sin = (struct sockaddr_in *)&store_sa;
1871 memcpy(sin, addr, sizeof(struct sockaddr_in));

--- 5 unchanged lines hidden (view full) ---

1877 memcpy(sin6, addr, sizeof(struct sockaddr_in6));
1878 sin6->sin6_port = 0;
1879 }
1880 /*
1881 * first find the interface with the bound address need to
1882 * zero out the port to find the address! yuck! can't do
1883 * this earlier since need port for sctp_pcb_findep()
1884 */
2201 struct sockaddr_storage store_sa;
2202
2203 memset(&store_sa, 0, sizeof(store_sa));
2204 if (addr->sa_family == AF_INET) {
2205 struct sockaddr_in *sin;
2206
2207 sin = (struct sockaddr_in *)&store_sa;
2208 memcpy(sin, addr, sizeof(struct sockaddr_in));

--- 5 unchanged lines hidden (view full) ---

2214 memcpy(sin6, addr, sizeof(struct sockaddr_in6));
2215 sin6->sin6_port = 0;
2216 }
2217 /*
2218 * first find the interface with the bound address need to
2219 * zero out the port to find the address! yuck! can't do
2220 * this earlier since need port for sctp_pcb_findep()
2221 */
1885 ifa = sctp_find_ifa_by_addr((struct sockaddr *)&store_sa);
2222 ifa = sctp_find_ifa_by_addr((struct sockaddr *)&store_sa, vrf_id, 0);
1886 if (ifa == NULL) {
1887 /* Can't find an interface with that address */
1888 SCTP_INP_WUNLOCK(inp);
1889 SCTP_INP_INFO_WUNLOCK();
1890 return (EADDRNOTAVAIL);
1891 }
1892 if (addr->sa_family == AF_INET6) {
2223 if (ifa == NULL) {
2224 /* Can't find an interface with that address */
2225 SCTP_INP_WUNLOCK(inp);
2226 SCTP_INP_INFO_WUNLOCK();
2227 return (EADDRNOTAVAIL);
2228 }
2229 if (addr->sa_family == AF_INET6) {
1893 struct in6_ifaddr *ifa6;
1894
1895 ifa6 = (struct in6_ifaddr *)ifa;
1896 /*
1897 * allow binding of deprecated addresses as per RFC
1898 * 2462 and ipng discussion
1899 */
1900 if (ifa6->ia6_flags & (IN6_IFF_DETACHED |
1901 IN6_IFF_ANYCAST |
1902 IN6_IFF_NOTREADY)) {
2230 /* GAK, more FIXME IFA lock? */
2231 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
1903 /* Can't bind a non-existent addr. */
1904 SCTP_INP_WUNLOCK(inp);
1905 SCTP_INP_INFO_WUNLOCK();
1906 return (EINVAL);
1907 }
1908 }
1909 /* we're not bound all */
1910 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUNDALL;
1911 /* set the automatic addr changes from kernel flag */
2232 /* Can't bind a non-existent addr. */
2233 SCTP_INP_WUNLOCK(inp);
2234 SCTP_INP_INFO_WUNLOCK();
2235 return (EINVAL);
2236 }
2237 }
2238 /* we're not bound all */
2239 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUNDALL;
2240 /* set the automatic addr changes from kernel flag */
2241 sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF);
1912 if (sctp_auto_asconf == 0) {
1913 sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
1914 } else {
2242 if (sctp_auto_asconf == 0) {
2243 sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
2244 } else {
2245 /*
2246 * allow bindx() to send ASCONF's for binding
2247 * changes
2248 */
1915 sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
1916 }
2249 sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
2250 }
1917 /* allow bindx() to send ASCONF's for binding changes */
1918 sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF);
2251
1919 /* add this address to the endpoint list */
2252 /* add this address to the endpoint list */
1920 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa);
2253 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, 0);
1921 if (error != 0) {
1922 SCTP_INP_WUNLOCK(inp);
1923 SCTP_INP_INFO_WUNLOCK();
1924 return (error);
1925 }
1926 inp->laddr_count++;
1927 }
1928 /* find the bucket */

--- 30 unchanged lines hidden (view full) ---

1959 /*
1960 * Go through all iterators, we must do this since it is possible
1961 * that some iterator does NOT have the lock, but is waiting for it.
1962 * And the one that had the lock has either moved in the last
1963 * iteration or we just cleared it above. We need to find all of
1964 * those guys. The list of iterators should never be very big
1965 * though.
1966 */
2254 if (error != 0) {
2255 SCTP_INP_WUNLOCK(inp);
2256 SCTP_INP_INFO_WUNLOCK();
2257 return (error);
2258 }
2259 inp->laddr_count++;
2260 }
2261 /* find the bucket */

--- 30 unchanged lines hidden (view full) ---

2292 /*
2293 * Go through all iterators, we must do this since it is possible
2294 * that some iterator does NOT have the lock, but is waiting for it.
2295 * And the one that had the lock has either moved in the last
2296 * iteration or we just cleared it above. We need to find all of
2297 * those guys. The list of iterators should never be very big
2298 * though.
2299 */
1967 LIST_FOREACH(it, &sctppcbinfo.iteratorhead, sctp_nxt_itr) {
2300 TAILQ_FOREACH(it, &sctppcbinfo.iteratorhead, sctp_nxt_itr) {
1968 if (it == inp->inp_starting_point_for_iterator)
1969 /* skip this guy, he's special */
1970 continue;
1971 if (it->inp == inp) {
1972 /*
1973 * This is tricky and we DON'T lock the iterator.
1974 * Reason is he's running but waiting for me since
1975 * inp->inp_starting_point_for_iterator has the lock

--- 412 unchanged lines hidden (view full) ---

2388 /*
2389 * if we have an address list the following will free the list of
2390 * ifaddr's that are set into this ep. Again macro limitations here,
2391 * since the LIST_FOREACH could be a bad idea.
2392 */
2393 for ((laddr = LIST_FIRST(&inp->sctp_addr_list)); laddr != NULL;
2394 laddr = nladdr) {
2395 nladdr = LIST_NEXT(laddr, sctp_nxt_addr);
2301 if (it == inp->inp_starting_point_for_iterator)
2302 /* skip this guy, he's special */
2303 continue;
2304 if (it->inp == inp) {
2305 /*
2306 * This is tricky and we DON'T lock the iterator.
2307 * Reason is he's running but waiting for me since
2308 * inp->inp_starting_point_for_iterator has the lock

--- 412 unchanged lines hidden (view full) ---

2721 /*
2722 * if we have an address list the following will free the list of
2723 * ifaddr's that are set into this ep. Again macro limitations here,
2724 * since the LIST_FOREACH could be a bad idea.
2725 */
2726 for ((laddr = LIST_FIRST(&inp->sctp_addr_list)); laddr != NULL;
2727 laddr = nladdr) {
2728 nladdr = LIST_NEXT(laddr, sctp_nxt_addr);
2396 LIST_REMOVE(laddr, sctp_nxt_addr);
2397 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_laddr, laddr);
2398 SCTP_DECR_LADDR_COUNT();
2729 sctp_remove_laddr(laddr);
2399 }
2400
2401#ifdef SCTP_TRACK_FREED_ASOCS
2402 /* TEMP CODE */
2403 for ((asoc = LIST_FIRST(&inp->sctp_asoc_free_list)); asoc != NULL;
2404 asoc = nasoc) {
2405 nasoc = LIST_NEXT(asoc, sctp_tcblist);
2406 LIST_REMOVE(asoc, sctp_tcblist);

--- 36 unchanged lines hidden (view full) ---

2443
2444
2445/*
2446 * add's a remote endpoint address, done with the INIT/INIT-ACK as well as
2447 * when a ASCONF arrives that adds it. It will also initialize all the cwnd
2448 * stats of stuff.
2449 */
2450int
2730 }
2731
2732#ifdef SCTP_TRACK_FREED_ASOCS
2733 /* TEMP CODE */
2734 for ((asoc = LIST_FIRST(&inp->sctp_asoc_free_list)); asoc != NULL;
2735 asoc = nasoc) {
2736 nasoc = LIST_NEXT(asoc, sctp_tcblist);
2737 LIST_REMOVE(asoc, sctp_tcblist);

--- 36 unchanged lines hidden (view full) ---

2774
2775
2776/*
2777 * add's a remote endpoint address, done with the INIT/INIT-ACK as well as
2778 * when a ASCONF arrives that adds it. It will also initialize all the cwnd
2779 * stats of stuff.
2780 */
2781int
2451sctp_is_address_on_local_host(struct sockaddr *addr)
2782sctp_is_address_on_local_host(struct sockaddr *addr, uint32_t vrf_id)
2452{
2783{
2453 struct ifnet *ifn;
2454 struct ifaddr *ifa;
2784 struct sctp_ifa *sctp_ifa;
2455
2785
2456 TAILQ_FOREACH(ifn, &ifnet, if_list) {
2457 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
2458 if (addr->sa_family == ifa->ifa_addr->sa_family) {
2459 /* same family */
2460 if (addr->sa_family == AF_INET) {
2461 struct sockaddr_in *sin, *sin_c;
2786 sctp_ifa = sctp_find_ifa_by_addr(addr, vrf_id, 0);
2787 if (sctp_ifa) {
2788 return (1);
2789 } else {
2790 return (0);
2791 }
2792}
2462
2793
2463 sin = (struct sockaddr_in *)addr;
2464 sin_c = (struct sockaddr_in *)
2465 ifa->ifa_addr;
2466 if (sin->sin_addr.s_addr ==
2467 sin_c->sin_addr.s_addr) {
2468 /*
2469 * we are on the same
2470 * machine
2471 */
2472 return (1);
2473 }
2474 } else if (addr->sa_family == AF_INET6) {
2475 struct sockaddr_in6 *sin6, *sin_c6;
2476
2477 sin6 = (struct sockaddr_in6 *)addr;
2478 sin_c6 = (struct sockaddr_in6 *)
2479 ifa->ifa_addr;
2480 if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
2481 &sin_c6->sin6_addr)) {
2482 /*
2483 * we are on the same
2484 * machine
2485 */
2486 return (1);
2487 }
2488 }
2489 }
2490 }
2794void
2795sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net)
2796{
2797 net->cwnd = min((net->mtu * 4), max((2 * net->mtu), SCTP_INITIAL_CWND));
2798 /* we always get at LEAST 2 MTU's */
2799 if (net->cwnd < (2 * net->mtu)) {
2800 net->cwnd = 2 * net->mtu;
2491 }
2801 }
2492 return (0);
2802 net->ssthresh = stcb->asoc.peers_rwnd;
2493}
2494
2495int
2496sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
2497 int set_scope, int from)
2498{
2499 /*
2500 * The following is redundant to the same lines in the

--- 48 unchanged lines hidden (view full) ---

2549 if (set_scope) {
2550#ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
2551 stcb->ipv4_local_scope = 1;
2552#else
2553 if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
2554 stcb->asoc.ipv4_local_scope = 1;
2555 }
2556#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */
2803}
2804
2805int
2806sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
2807 int set_scope, int from)
2808{
2809 /*
2810 * The following is redundant to the same lines in the

--- 48 unchanged lines hidden (view full) ---

2859 if (set_scope) {
2860#ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
2861 stcb->ipv4_local_scope = 1;
2862#else
2863 if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
2864 stcb->asoc.ipv4_local_scope = 1;
2865 }
2866#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */
2557
2558 if (sctp_is_address_on_local_host(newaddr)) {
2559 stcb->asoc.loopback_scope = 1;
2560 stcb->asoc.ipv4_local_scope = 1;
2561 stcb->asoc.local_scope = 1;
2562 stcb->asoc.site_scope = 1;
2563 }
2564 } else {
2867 } else {
2565 if (from == SCTP_ADDR_IS_CONFIRMED) {
2566 /* From connectx */
2567 if (sctp_is_address_on_local_host(newaddr)) {
2568 stcb->asoc.loopback_scope = 1;
2569 stcb->asoc.ipv4_local_scope = 1;
2570 stcb->asoc.local_scope = 1;
2571 stcb->asoc.site_scope = 1;
2572 }
2573 }
2574 /* Validate the address is in scope */
2575 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) &&
2576 (stcb->asoc.ipv4_local_scope == 0)) {
2577 addr_inscope = 0;
2578 }
2579 }
2580 } else if (newaddr->sa_family == AF_INET6) {
2581 struct sockaddr_in6 *sin6;
2582
2583 sin6 = (struct sockaddr_in6 *)newaddr;
2584 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2585 /* Invalid address */
2586 return (-1);
2587 }
2588 /* assure len is set */
2589 sin6->sin6_len = sizeof(struct sockaddr_in6);
2590 if (set_scope) {
2868 /* Validate the address is in scope */
2869 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) &&
2870 (stcb->asoc.ipv4_local_scope == 0)) {
2871 addr_inscope = 0;
2872 }
2873 }
2874 } else if (newaddr->sa_family == AF_INET6) {
2875 struct sockaddr_in6 *sin6;
2876
2877 sin6 = (struct sockaddr_in6 *)newaddr;
2878 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2879 /* Invalid address */
2880 return (-1);
2881 }
2882 /* assure len is set */
2883 sin6->sin6_len = sizeof(struct sockaddr_in6);
2884 if (set_scope) {
2591 if (sctp_is_address_on_local_host(newaddr)) {
2885 if (sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id)) {
2592 stcb->asoc.loopback_scope = 1;
2886 stcb->asoc.loopback_scope = 1;
2593 stcb->asoc.local_scope = 1;
2887 stcb->asoc.local_scope = 0;
2594 stcb->asoc.ipv4_local_scope = 1;
2595 stcb->asoc.site_scope = 1;
2596 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
2597 /*
2598 * If the new destination is a LINK_LOCAL we
2599 * must have common site scope. Don't set
2600 * the local scope since we may not share
2601 * all links, only loopback can do this.

--- 5 unchanged lines hidden (view full) ---

2607 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
2608 /*
2609 * If the new destination is SITE_LOCAL then
2610 * we must have site scope in common.
2611 */
2612 stcb->asoc.site_scope = 1;
2613 }
2614 } else {
2888 stcb->asoc.ipv4_local_scope = 1;
2889 stcb->asoc.site_scope = 1;
2890 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
2891 /*
2892 * If the new destination is a LINK_LOCAL we
2893 * must have common site scope. Don't set
2894 * the local scope since we may not share
2895 * all links, only loopback can do this.

--- 5 unchanged lines hidden (view full) ---

2901 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
2902 /*
2903 * If the new destination is SITE_LOCAL then
2904 * we must have site scope in common.
2905 */
2906 stcb->asoc.site_scope = 1;
2907 }
2908 } else {
2615 if (from == SCTP_ADDR_IS_CONFIRMED) {
2616 /* From connectx so we check for localhost. */
2617 if (sctp_is_address_on_local_host(newaddr)) {
2618 stcb->asoc.loopback_scope = 1;
2619 stcb->asoc.ipv4_local_scope = 1;
2620 stcb->asoc.local_scope = 1;
2621 stcb->asoc.site_scope = 1;
2622 }
2623 }
2624 /* Validate the address is in scope */
2625 if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) &&
2626 (stcb->asoc.loopback_scope == 0)) {
2627 addr_inscope = 0;
2628 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
2629 (stcb->asoc.local_scope == 0)) {
2630 addr_inscope = 0;
2631 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&

--- 13 unchanged lines hidden (view full) ---

2645 bzero(net, sizeof(*net));
2646 SCTP_GETTIME_TIMEVAL(&net->start_time);
2647 memcpy(&net->ro._l_addr, newaddr, newaddr->sa_len);
2648 if (newaddr->sa_family == AF_INET) {
2649 ((struct sockaddr_in *)&net->ro._l_addr)->sin_port = stcb->rport;
2650 } else if (newaddr->sa_family == AF_INET6) {
2651 ((struct sockaddr_in6 *)&net->ro._l_addr)->sin6_port = stcb->rport;
2652 }
2909 /* Validate the address is in scope */
2910 if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) &&
2911 (stcb->asoc.loopback_scope == 0)) {
2912 addr_inscope = 0;
2913 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
2914 (stcb->asoc.local_scope == 0)) {
2915 addr_inscope = 0;
2916 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&

--- 13 unchanged lines hidden (view full) ---

2930 bzero(net, sizeof(*net));
2931 SCTP_GETTIME_TIMEVAL(&net->start_time);
2932 memcpy(&net->ro._l_addr, newaddr, newaddr->sa_len);
2933 if (newaddr->sa_family == AF_INET) {
2934 ((struct sockaddr_in *)&net->ro._l_addr)->sin_port = stcb->rport;
2935 } else if (newaddr->sa_family == AF_INET6) {
2936 ((struct sockaddr_in6 *)&net->ro._l_addr)->sin6_port = stcb->rport;
2937 }
2653 net->addr_is_local = sctp_is_address_on_local_host(newaddr);
2938 net->addr_is_local = sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id);
2939 if (net->addr_is_local && ((set_scope || (from == SCTP_ADDR_IS_CONFIRMED)))) {
2940 stcb->asoc.loopback_scope = 1;
2941 stcb->asoc.ipv4_local_scope = 1;
2942 stcb->asoc.local_scope = 0;
2943 stcb->asoc.site_scope = 1;
2944 addr_inscope = 1;
2945 }
2654 net->failure_threshold = stcb->asoc.def_net_failure;
2655 if (addr_inscope == 0) {
2656 net->dest_state = (SCTP_ADDR_REACHABLE |
2657 SCTP_ADDR_OUT_OF_SCOPE);
2658 } else {
2659 if (from == SCTP_ADDR_IS_CONFIRMED)
2660 /* SCTP_ADDR_IS_CONFIRMED is passed by connect_x */
2661 net->dest_state = SCTP_ADDR_REACHABLE;
2662 else
2663 net->dest_state = SCTP_ADDR_REACHABLE |
2664 SCTP_ADDR_UNCONFIRMED;
2665 }
2666 net->RTO = stcb->asoc.initial_rto;
2667 stcb->asoc.numnets++;
2668 *(&net->ref_count) = 1;
2669 net->tos_flowlabel = 0;
2946 net->failure_threshold = stcb->asoc.def_net_failure;
2947 if (addr_inscope == 0) {
2948 net->dest_state = (SCTP_ADDR_REACHABLE |
2949 SCTP_ADDR_OUT_OF_SCOPE);
2950 } else {
2951 if (from == SCTP_ADDR_IS_CONFIRMED)
2952 /* SCTP_ADDR_IS_CONFIRMED is passed by connect_x */
2953 net->dest_state = SCTP_ADDR_REACHABLE;
2954 else
2955 net->dest_state = SCTP_ADDR_REACHABLE |
2956 SCTP_ADDR_UNCONFIRMED;
2957 }
2958 net->RTO = stcb->asoc.initial_rto;
2959 stcb->asoc.numnets++;
2960 *(&net->ref_count) = 1;
2961 net->tos_flowlabel = 0;
2670#ifdef AF_INET
2962#ifdef INET
2671 if (newaddr->sa_family == AF_INET)
2672 net->tos_flowlabel = stcb->asoc.default_tos;
2673#endif
2963 if (newaddr->sa_family == AF_INET)
2964 net->tos_flowlabel = stcb->asoc.default_tos;
2965#endif
2674#ifdef AF_INET6
2966#ifdef INET6
2675 if (newaddr->sa_family == AF_INET6)
2676 net->tos_flowlabel = stcb->asoc.default_flowlabel;
2677#endif
2678 /* Init the timer structure */
2679 SCTP_OS_TIMER_INIT(&net->rxt_timer.timer);
2680 SCTP_OS_TIMER_INIT(&net->fr_timer.timer);
2681 SCTP_OS_TIMER_INIT(&net->pmtu_timer.timer);
2682

--- 27 unchanged lines hidden (view full) ---

2710
2711 if (stcb->asoc.smallest_mtu > net->mtu) {
2712 stcb->asoc.smallest_mtu = net->mtu;
2713 }
2714 /*
2715 * We take the max of the burst limit times a MTU or the
2716 * INITIAL_CWND. We then limit this to 4 MTU's of sending.
2717 */
2967 if (newaddr->sa_family == AF_INET6)
2968 net->tos_flowlabel = stcb->asoc.default_flowlabel;
2969#endif
2970 /* Init the timer structure */
2971 SCTP_OS_TIMER_INIT(&net->rxt_timer.timer);
2972 SCTP_OS_TIMER_INIT(&net->fr_timer.timer);
2973 SCTP_OS_TIMER_INIT(&net->pmtu_timer.timer);
2974

--- 27 unchanged lines hidden (view full) ---

3002
3003 if (stcb->asoc.smallest_mtu > net->mtu) {
3004 stcb->asoc.smallest_mtu = net->mtu;
3005 }
3006 /*
3007 * We take the max of the burst limit times a MTU or the
3008 * INITIAL_CWND. We then limit this to 4 MTU's of sending.
3009 */
2718 net->cwnd = min((net->mtu * 4), max((2 * net->mtu), SCTP_INITIAL_CWND));
3010 sctp_set_initial_cc_param(stcb, net);
2719
3011
2720 /* we always get at LEAST 2 MTU's */
2721 if (net->cwnd < (2 * net->mtu)) {
2722 net->cwnd = 2 * net->mtu;
2723 }
2724 net->ssthresh = stcb->asoc.peers_rwnd;
2725
2726#if defined(SCTP_CWND_MONITOR) || defined(SCTP_CWND_LOGGING)
2727 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_INITIALIZATION);
2728#endif
2729
2730 /*
2731 * CMT: CUC algo - set find_pseudo_cumack to TRUE (1) at beginning
2732 * of assoc (2005/06/27, iyengar@cis.udel.edu)

--- 82 unchanged lines hidden (view full) ---

2815
2816/*
2817 * allocate an association and add it to the endpoint. The caller must be
2818 * careful to add all additional addresses once they are know right away or
2819 * else the assoc will be may experience a blackout scenario.
2820 */
2821struct sctp_tcb *
2822sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
3012
3013#if defined(SCTP_CWND_MONITOR) || defined(SCTP_CWND_LOGGING)
3014 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_INITIALIZATION);
3015#endif
3016
3017 /*
3018 * CMT: CUC algo - set find_pseudo_cumack to TRUE (1) at beginning
3019 * of assoc (2005/06/27, iyengar@cis.udel.edu)

--- 82 unchanged lines hidden (view full) ---

3102
3103/*
3104 * allocate an association and add it to the endpoint. The caller must be
3105 * careful to add all additional addresses once they are know right away or
3106 * else the assoc will be may experience a blackout scenario.
3107 */
3108struct sctp_tcb *
3109sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
2823 int for_a_init, int *error, uint32_t override_tag)
3110 int for_a_init, int *error, uint32_t override_tag, uint32_t vrf)
2824{
2825 struct sctp_tcb *stcb;
2826 struct sctp_association *asoc;
2827 struct sctpasochead *head;
2828 uint16_t rport;
2829 int err;
2830
2831 /*

--- 83 unchanged lines hidden (view full) ---

2915
2916 bzero(stcb, sizeof(*stcb));
2917 asoc = &stcb->asoc;
2918 SCTP_TCB_LOCK_INIT(stcb);
2919 SCTP_TCB_SEND_LOCK_INIT(stcb);
2920 /* setup back pointer's */
2921 stcb->sctp_ep = inp;
2922 stcb->sctp_socket = inp->sctp_socket;
3111{
3112 struct sctp_tcb *stcb;
3113 struct sctp_association *asoc;
3114 struct sctpasochead *head;
3115 uint16_t rport;
3116 int err;
3117
3118 /*

--- 83 unchanged lines hidden (view full) ---

3202
3203 bzero(stcb, sizeof(*stcb));
3204 asoc = &stcb->asoc;
3205 SCTP_TCB_LOCK_INIT(stcb);
3206 SCTP_TCB_SEND_LOCK_INIT(stcb);
3207 /* setup back pointer's */
3208 stcb->sctp_ep = inp;
3209 stcb->sctp_socket = inp->sctp_socket;
2923 if ((err = sctp_init_asoc(inp, asoc, for_a_init, override_tag))) {
3210 if ((err = sctp_init_asoc(inp, asoc, for_a_init, override_tag, vrf))) {
2924 /* failed */
2925 SCTP_TCB_LOCK_DESTROY(stcb);
2926 SCTP_TCB_SEND_LOCK_DESTROY(stcb);
2927 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_asoc, stcb);
2928 SCTP_DECR_ASOC_COUNT();
2929 *error = err;
2930 return (NULL);
2931 }

--- 64 unchanged lines hidden (view full) ---

2996void
2997sctp_remove_net(struct sctp_tcb *stcb, struct sctp_nets *net)
2998{
2999 struct sctp_association *asoc;
3000
3001 asoc = &stcb->asoc;
3002 asoc->numnets--;
3003 TAILQ_REMOVE(&asoc->nets, net, sctp_next);
3211 /* failed */
3212 SCTP_TCB_LOCK_DESTROY(stcb);
3213 SCTP_TCB_SEND_LOCK_DESTROY(stcb);
3214 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_asoc, stcb);
3215 SCTP_DECR_ASOC_COUNT();
3216 *error = err;
3217 return (NULL);
3218 }

--- 64 unchanged lines hidden (view full) ---

3283void
3284sctp_remove_net(struct sctp_tcb *stcb, struct sctp_nets *net)
3285{
3286 struct sctp_association *asoc;
3287
3288 asoc = &stcb->asoc;
3289 asoc->numnets--;
3290 TAILQ_REMOVE(&asoc->nets, net, sctp_next);
3004 sctp_free_remote_addr(net);
3005 if (net == asoc->primary_destination) {
3006 /* Reset primary */
3007 struct sctp_nets *lnet;
3008
3009 lnet = TAILQ_FIRST(&asoc->nets);
3010 /* Try to find a confirmed primary */
3291 if (net == asoc->primary_destination) {
3292 /* Reset primary */
3293 struct sctp_nets *lnet;
3294
3295 lnet = TAILQ_FIRST(&asoc->nets);
3296 /* Try to find a confirmed primary */
3011 asoc->primary_destination = sctp_find_alternate_net(stcb, lnet,
3012 0);
3297 asoc->primary_destination = sctp_find_alternate_net(stcb, lnet, 0);
3013 }
3014 if (net == asoc->last_data_chunk_from) {
3015 /* Reset primary */
3016 asoc->last_data_chunk_from = TAILQ_FIRST(&asoc->nets);
3017 }
3018 if (net == asoc->last_control_chunk_from) {
3019 /* Clear net */
3020 asoc->last_control_chunk_from = NULL;
3021 }
3298 }
3299 if (net == asoc->last_data_chunk_from) {
3300 /* Reset primary */
3301 asoc->last_data_chunk_from = TAILQ_FIRST(&asoc->nets);
3302 }
3303 if (net == asoc->last_control_chunk_from) {
3304 /* Clear net */
3305 asoc->last_control_chunk_from = NULL;
3306 }
3022/* if (net == asoc->asconf_last_sent_to) {*/
3023 /* Reset primary */
3024/* asoc->asconf_last_sent_to = TAILQ_FIRST(&asoc->nets);*/
3025/* }*/
3307 sctp_free_remote_addr(net);
3026}
3027
3028/*
3029 * remove a remote endpoint address from an association, it will fail if the
3030 * address does not exist.
3031 */
3032int
3033sctp_del_remote_addr(struct sctp_tcb *stcb, struct sockaddr *remaddr)

--- 592 unchanged lines hidden (view full) ---

3626#endif
3627 break;
3628 }
3629 prev = net;
3630 TAILQ_REMOVE(&asoc->nets, net, sctp_next);
3631 sctp_free_remote_addr(net);
3632 }
3633
3308}
3309
3310/*
3311 * remove a remote endpoint address from an association, it will fail if the
3312 * address does not exist.
3313 */
3314int
3315sctp_del_remote_addr(struct sctp_tcb *stcb, struct sockaddr *remaddr)

--- 592 unchanged lines hidden (view full) ---

3908#endif
3909 break;
3910 }
3911 prev = net;
3912 TAILQ_REMOVE(&asoc->nets, net, sctp_next);
3913 sctp_free_remote_addr(net);
3914 }
3915
3634 /* local addresses, if any */
3635 while (!SCTP_LIST_EMPTY(&asoc->sctp_local_addr_list)) {
3636 laddr = LIST_FIRST(&asoc->sctp_local_addr_list);
3637 LIST_REMOVE(laddr, sctp_nxt_addr);
3638 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_laddr, laddr);
3639 SCTP_DECR_LADDR_COUNT();
3916 while (!SCTP_LIST_EMPTY(&asoc->sctp_restricted_addrs)) {
3917 laddr = LIST_FIRST(&asoc->sctp_restricted_addrs);
3918 sctp_remove_laddr(laddr);
3640 }
3919 }
3920
3641 /* pending asconf (address) parameters */
3642 while (!TAILQ_EMPTY(&asoc->asconf_queue)) {
3643 aparam = TAILQ_FIRST(&asoc->asconf_queue);
3644 TAILQ_REMOVE(&asoc->asconf_queue, aparam, next);
3645 SCTP_FREE(aparam);
3646 }
3647 if (asoc->last_asconf_ack_sent != NULL) {
3648 sctp_m_freem(asoc->last_asconf_ack_sent);

--- 137 unchanged lines hidden (view full) ---

3786 if (laddr->ifa == NULL) {
3787#ifdef SCTP_DEBUG
3788 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
3789 printf("An ounce of prevention is worth a pound of cure\n");
3790 }
3791#endif /* SCTP_DEBUG */
3792 continue;
3793 }
3921 /* pending asconf (address) parameters */
3922 while (!TAILQ_EMPTY(&asoc->asconf_queue)) {
3923 aparam = TAILQ_FIRST(&asoc->asconf_queue);
3924 TAILQ_REMOVE(&asoc->asconf_queue, aparam, next);
3925 SCTP_FREE(aparam);
3926 }
3927 if (asoc->last_asconf_ack_sent != NULL) {
3928 sctp_m_freem(asoc->last_asconf_ack_sent);

--- 137 unchanged lines hidden (view full) ---

4066 if (laddr->ifa == NULL) {
4067#ifdef SCTP_DEBUG
4068 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
4069 printf("An ounce of prevention is worth a pound of cure\n");
4070 }
4071#endif /* SCTP_DEBUG */
4072 continue;
4073 }
3794 if (laddr->ifa->ifa_addr) {
4074 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
3795 continue;
3796 }
4075 continue;
4076 }
3797 if (laddr->ifa->ifa_addr->sa_family == AF_INET6) {
4077 if (laddr->ifa->address.sa.sa_family == AF_INET6) {
3798 inp->ip_inp.inp.inp_vflag |= INP_IPV6;
4078 inp->ip_inp.inp.inp_vflag |= INP_IPV6;
3799 } else if (laddr->ifa->ifa_addr->sa_family == AF_INET) {
4079 } else if (laddr->ifa->address.sa.sa_family == AF_INET) {
3800 inp->ip_inp.inp.inp_vflag |= INP_IPV4;
3801 }
3802 }
3803}
3804
3805/*
3806 * Add the address to the endpoint local address list There is nothing to be
3807 * done if we are bound to all addresses
3808 */
3809int
4080 inp->ip_inp.inp.inp_vflag |= INP_IPV4;
4081 }
4082 }
4083}
4084
4085/*
4086 * Add the address to the endpoint local address list There is nothing to be
4087 * done if we are bound to all addresses
4088 */
4089int
3810sctp_add_local_addr_ep(struct sctp_inpcb *inp, struct ifaddr *ifa)
4090sctp_add_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa, uint32_t action)
3811{
3812 struct sctp_laddr *laddr;
3813 int fnd, error;
3814
3815 fnd = 0;
3816
3817 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3818 /* You are already bound to all. You have it already */
3819 return (0);
3820 }
4091{
4092 struct sctp_laddr *laddr;
4093 int fnd, error;
4094
4095 fnd = 0;
4096
4097 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
4098 /* You are already bound to all. You have it already */
4099 return (0);
4100 }
3821 if (ifa->ifa_addr->sa_family == AF_INET6) {
3822 struct in6_ifaddr *ifa6;
3823
3824 ifa6 = (struct in6_ifaddr *)ifa;
3825 if (ifa6->ia6_flags & (IN6_IFF_DETACHED |
3826 IN6_IFF_DEPRECATED | IN6_IFF_ANYCAST | IN6_IFF_NOTREADY))
3827 /* Can't bind a non-existent addr. */
4101 if (ifa->address.sa.sa_family == AF_INET6) {
4102 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
4103 /* Can't bind a non-useable addr. */
3828 return (-1);
4104 return (-1);
4105 }
3829 }
3830 /* first, is it already present? */
3831 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
3832 if (laddr->ifa == ifa) {
3833 fnd = 1;
3834 break;
3835 }
3836 }
3837
4106 }
4107 /* first, is it already present? */
4108 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
4109 if (laddr->ifa == ifa) {
4110 fnd = 1;
4111 break;
4112 }
4113 }
4114
3838 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) && (fnd == 0)) {
3839 /* Not bound to all */
3840 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa);
4115 if (fnd == 0) {
4116 /* Not in the ep list */
4117 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, action);
3841 if (error != 0)
3842 return (error);
3843 inp->laddr_count++;
3844 /* update inp_vflag flags */
4118 if (error != 0)
4119 return (error);
4120 inp->laddr_count++;
4121 /* update inp_vflag flags */
3845 if (ifa->ifa_addr->sa_family == AF_INET6) {
4122 if (ifa->address.sa.sa_family == AF_INET6) {
3846 inp->ip_inp.inp.inp_vflag |= INP_IPV6;
4123 inp->ip_inp.inp.inp_vflag |= INP_IPV6;
3847 } else if (ifa->ifa_addr->sa_family == AF_INET) {
4124 } else if (ifa->address.sa.sa_family == AF_INET) {
3848 inp->ip_inp.inp.inp_vflag |= INP_IPV4;
3849 }
3850 }
3851 return (0);
3852}
3853
3854
3855/*

--- 20 unchanged lines hidden (view full) ---

3876}
3877
3878
3879/*
3880 * Delete the address from the endpoint local address list There is nothing
3881 * to be done if we are bound to all addresses
3882 */
3883int
4125 inp->ip_inp.inp.inp_vflag |= INP_IPV4;
4126 }
4127 }
4128 return (0);
4129}
4130
4131
4132/*

--- 20 unchanged lines hidden (view full) ---

4153}
4154
4155
4156/*
4157 * Delete the address from the endpoint local address list There is nothing
4158 * to be done if we are bound to all addresses
4159 */
4160int
3884sctp_del_local_addr_ep(struct sctp_inpcb *inp, struct ifaddr *ifa)
4161sctp_del_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa)
3885{
3886 struct sctp_laddr *laddr;
3887 int fnd;
3888
3889 fnd = 0;
3890 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3891 /* You are already bound to all. You have it already */
3892 return (EINVAL);
3893 }
3894 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
3895 if (laddr->ifa == ifa) {
3896 fnd = 1;
3897 break;
3898 }
3899 }
3900 if (fnd && (inp->laddr_count < 2)) {
3901 /* can't delete unless there are at LEAST 2 addresses */
3902 return (-1);
3903 }
4162{
4163 struct sctp_laddr *laddr;
4164 int fnd;
4165
4166 fnd = 0;
4167 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
4168 /* You are already bound to all. You have it already */
4169 return (EINVAL);
4170 }
4171 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
4172 if (laddr->ifa == ifa) {
4173 fnd = 1;
4174 break;
4175 }
4176 }
4177 if (fnd && (inp->laddr_count < 2)) {
4178 /* can't delete unless there are at LEAST 2 addresses */
4179 return (-1);
4180 }
3904 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) && (fnd)) {
4181 if (fnd) {
3905 /*
3906 * clean up any use of this address go through our
3907 * associations and clear any last_used_address that match
3908 * this one for each assoc, see if a new primary_destination
3909 * is needed
3910 */
3911 struct sctp_tcb *stcb;
3912
3913 /* clean up "next_addr_touse" */
3914 if (inp->next_addr_touse == laddr)
3915 /* delete this address */
3916 inp->next_addr_touse = NULL;
3917
3918 /* clean up "last_used_address" */
3919 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
4182 /*
4183 * clean up any use of this address go through our
4184 * associations and clear any last_used_address that match
4185 * this one for each assoc, see if a new primary_destination
4186 * is needed
4187 */
4188 struct sctp_tcb *stcb;
4189
4190 /* clean up "next_addr_touse" */
4191 if (inp->next_addr_touse == laddr)
4192 /* delete this address */
4193 inp->next_addr_touse = NULL;
4194
4195 /* clean up "last_used_address" */
4196 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
4197 struct sctp_nets *net;
4198
4199 SCTP_TCB_LOCK(stcb);
3920 if (stcb->asoc.last_used_address == laddr)
3921 /* delete this address */
3922 stcb->asoc.last_used_address = NULL;
4200 if (stcb->asoc.last_used_address == laddr)
4201 /* delete this address */
4202 stcb->asoc.last_used_address = NULL;
3923 } /* for each tcb */
4203 /*
4204 * Now spin through all the nets and purge any ref
4205 * to laddr
4206 */
4207 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
4208 if (net->ro._s_addr &&
4209 (net->ro._s_addr->ifa == laddr->ifa)) {
4210 /* Yep, purge src address selected */
4211 struct rtentry *rt;
3924
4212
4213 /* delete this address if cached */
4214 rt = net->ro.ro_rt;
4215 if (rt != NULL) {
4216 RTFREE(rt);
4217 net->ro.ro_rt = NULL;
4218 }
4219 sctp_free_ifa(net->ro._s_addr);
4220 net->ro._s_addr = NULL;
4221 net->src_addr_selected = 0;
4222 }
4223 }
4224 SCTP_TCB_UNLOCK(stcb);
4225 } /* for each tcb */
3925 /* remove it from the ep list */
3926 sctp_remove_laddr(laddr);
3927 inp->laddr_count--;
3928 /* update inp_vflag flags */
3929 sctp_update_ep_vflag(inp);
4226 /* remove it from the ep list */
4227 sctp_remove_laddr(laddr);
4228 inp->laddr_count--;
4229 /* update inp_vflag flags */
4230 sctp_update_ep_vflag(inp);
3930 /* select a new primary destination if needed */
3931 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
3932 /*
3933 * presume caller (sctp_asconf.c) already owns INP
3934 * lock
3935 */
3936 SCTP_TCB_LOCK(stcb);
3937 if (sctp_destination_is_reachable(stcb,
3938 (struct sockaddr *)&stcb->asoc.primary_destination->ro._l_addr) == 0) {
3939 sctp_select_primary_destination(stcb);
3940 }
3941 SCTP_TCB_UNLOCK(stcb);
3942 } /* for each tcb */
3943 }
3944 return (0);
3945}
3946
3947/*
3948 * Add the addr to the TCB local address list For the BOUNDALL or dynamic
3949 * case, this is a "pending" address list (eg. addresses waiting for an
3950 * ASCONF-ACK response) For the subset binding, static case, this is a
3951 * "valid" address list
3952 */
3953int
4231 }
4232 return (0);
4233}
4234
4235/*
4236 * Add the addr to the TCB local address list For the BOUNDALL or dynamic
4237 * case, this is a "pending" address list (eg. addresses waiting for an
4238 * ASCONF-ACK response) For the subset binding, static case, this is a
4239 * "valid" address list
4240 */
4241int
3954sctp_add_local_addr_assoc(struct sctp_tcb *stcb, struct ifaddr *ifa)
4242sctp_add_local_addr_assoc(struct sctp_tcb *stcb, struct sctp_ifa *ifa, int restricted_list)
3955{
3956 struct sctp_inpcb *inp;
3957 struct sctp_laddr *laddr;
4243{
4244 struct sctp_inpcb *inp;
4245 struct sctp_laddr *laddr;
4246 struct sctpladdr *list;
3958 int error;
3959
3960 /*
4247 int error;
4248
4249 /*
3961 * Assumes TCP is locked.. and possiblye the INP. May need to
4250 * Assumes TCB is locked.. and possibly the INP. May need to
3962 * confirm/fix that if we need it and is not the case.
3963 */
4251 * confirm/fix that if we need it and is not the case.
4252 */
3964 inp = stcb->sctp_ep;
3965 if (ifa->ifa_addr->sa_family == AF_INET6) {
3966 struct in6_ifaddr *ifa6;
4253 list = &stcb->asoc.sctp_restricted_addrs;
3967
4254
3968 ifa6 = (struct in6_ifaddr *)ifa;
3969 if (ifa6->ia6_flags & (IN6_IFF_DETACHED |
3970 /* IN6_IFF_DEPRECATED | */
3971 IN6_IFF_ANYCAST |
3972 IN6_IFF_NOTREADY))
4255 inp = stcb->sctp_ep;
4256 if (ifa->address.sa.sa_family == AF_INET6) {
4257 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
3973 /* Can't bind a non-existent addr. */
3974 return (-1);
4258 /* Can't bind a non-existent addr. */
4259 return (-1);
4260 }
3975 }
3976 /* does the address already exist? */
4261 }
4262 /* does the address already exist? */
3977 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) {
4263 LIST_FOREACH(laddr, list, sctp_nxt_addr) {
3978 if (laddr->ifa == ifa) {
3979 return (-1);
3980 }
3981 }
3982
3983 /* add to the list */
4264 if (laddr->ifa == ifa) {
4265 return (-1);
4266 }
4267 }
4268
4269 /* add to the list */
3984 error = sctp_insert_laddr(&stcb->asoc.sctp_local_addr_list, ifa);
4270 error = sctp_insert_laddr(list, ifa, 0);
3985 if (error != 0)
3986 return (error);
3987 return (0);
3988}
3989
3990/*
3991 * insert an laddr entry with the given ifa for the desired list
3992 */
3993int
4271 if (error != 0)
4272 return (error);
4273 return (0);
4274}
4275
4276/*
4277 * insert an laddr entry with the given ifa for the desired list
4278 */
4279int
3994sctp_insert_laddr(struct sctpladdr *list, struct ifaddr *ifa)
4280sctp_insert_laddr(struct sctpladdr *list, struct sctp_ifa *ifa, uint32_t act)
3995{
3996 struct sctp_laddr *laddr;
3997
3998 laddr = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_laddr, struct sctp_laddr);
3999 if (laddr == NULL) {
4000 /* out of memory? */
4001 return (EINVAL);
4002 }
4003 SCTP_INCR_LADDR_COUNT();
4004 bzero(laddr, sizeof(*laddr));
4005 laddr->ifa = ifa;
4281{
4282 struct sctp_laddr *laddr;
4283
4284 laddr = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_laddr, struct sctp_laddr);
4285 if (laddr == NULL) {
4286 /* out of memory? */
4287 return (EINVAL);
4288 }
4289 SCTP_INCR_LADDR_COUNT();
4290 bzero(laddr, sizeof(*laddr));
4291 laddr->ifa = ifa;
4292 laddr->action = act;
4293 atomic_add_int(&ifa->refcount, 1);
4006 /* insert it */
4007 LIST_INSERT_HEAD(list, laddr, sctp_nxt_addr);
4008
4009 return (0);
4010}
4011
4012/*
4013 * Remove an laddr entry from the local address list (on an assoc)
4014 */
4015void
4016sctp_remove_laddr(struct sctp_laddr *laddr)
4017{
4018
4019 /* remove from the list */
4020 LIST_REMOVE(laddr, sctp_nxt_addr);
4294 /* insert it */
4295 LIST_INSERT_HEAD(list, laddr, sctp_nxt_addr);
4296
4297 return (0);
4298}
4299
4300/*
4301 * Remove an laddr entry from the local address list (on an assoc)
4302 */
4303void
4304sctp_remove_laddr(struct sctp_laddr *laddr)
4305{
4306
4307 /* remove from the list */
4308 LIST_REMOVE(laddr, sctp_nxt_addr);
4309 sctp_free_ifa(laddr->ifa);
4021 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_laddr, laddr);
4022 SCTP_DECR_LADDR_COUNT();
4023}
4024
4025/*
4026 * Remove an address from the TCB local address list
4027 */
4028int
4310 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_laddr, laddr);
4311 SCTP_DECR_LADDR_COUNT();
4312}
4313
4314/*
4315 * Remove an address from the TCB local address list
4316 */
4317int
4029sctp_del_local_addr_assoc(struct sctp_tcb *stcb, struct ifaddr *ifa)
4318sctp_del_local_addr_assoc(struct sctp_tcb *stcb, struct sctp_ifa *ifa)
4030{
4031 struct sctp_inpcb *inp;
4032 struct sctp_laddr *laddr;
4033
4034 /*
4035 * This is called by asconf work. It is assumed that a) The TCB is
4036 * locked and b) The INP is locked. This is true in as much as I can
4037 * trace through the entry asconf code where I did these locks.

--- 7 unchanged lines hidden (view full) ---

4045 /* if subset bound and don't allow ASCONF's, can't delete last */
4046 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) &&
4047 (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF) == 0)) {
4048 if (stcb->asoc.numnets < 2) {
4049 /* can't delete last address */
4050 return (-1);
4051 }
4052 }
4319{
4320 struct sctp_inpcb *inp;
4321 struct sctp_laddr *laddr;
4322
4323 /*
4324 * This is called by asconf work. It is assumed that a) The TCB is
4325 * locked and b) The INP is locked. This is true in as much as I can
4326 * trace through the entry asconf code where I did these locks.

--- 7 unchanged lines hidden (view full) ---

4334 /* if subset bound and don't allow ASCONF's, can't delete last */
4335 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) &&
4336 (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF) == 0)) {
4337 if (stcb->asoc.numnets < 2) {
4338 /* can't delete last address */
4339 return (-1);
4340 }
4341 }
4053 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) {
4342 LIST_FOREACH(laddr, &stcb->asoc.sctp_restricted_addrs, sctp_nxt_addr) {
4054 /* remove the address if it exists */
4055 if (laddr->ifa == NULL)
4056 continue;
4057 if (laddr->ifa == ifa) {
4058 sctp_remove_laddr(laddr);
4059 return (0);
4060 }
4061 }
4062
4063 /* address not found! */
4064 return (-1);
4065}
4066
4343 /* remove the address if it exists */
4344 if (laddr->ifa == NULL)
4345 continue;
4346 if (laddr->ifa == ifa) {
4347 sctp_remove_laddr(laddr);
4348 return (0);
4349 }
4350 }
4351
4352 /* address not found! */
4353 return (-1);
4354}
4355
4067/*
4068 * Remove an address from the TCB local address list lookup using a sockaddr
4069 * addr
4070 */
4071int
4072sctp_del_local_addr_assoc_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
4073{
4074 struct sctp_inpcb *inp;
4075 struct sctp_laddr *laddr;
4076 struct sockaddr *l_sa;
4077
4078 /*
4079 * This function I find does not seem to have a caller. As such we
4080 * NEED TO DELETE this code. If we do find a caller, the caller MUST
4081 * have locked the TCB at the least and probably the INP as well.
4082 */
4083 inp = stcb->sctp_ep;
4084 /* if subset bound and don't allow ASCONF's, can't delete last */
4085 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) &&
4086 (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF) == 0)) {
4087 if (stcb->asoc.numnets < 2) {
4088 /* can't delete last address */
4089 return (-1);
4090 }
4091 }
4092 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) {
4093 /* make sure the address exists */
4094 if (laddr->ifa == NULL)
4095 continue;
4096 if (laddr->ifa->ifa_addr == NULL)
4097 continue;
4098
4099 l_sa = laddr->ifa->ifa_addr;
4100 if (l_sa->sa_family == AF_INET6) {
4101 /* IPv6 address */
4102 struct sockaddr_in6 *sin1, *sin2;
4103
4104 sin1 = (struct sockaddr_in6 *)l_sa;
4105 sin2 = (struct sockaddr_in6 *)sa;
4106 if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
4107 sizeof(struct in6_addr)) == 0) {
4108 /* matched */
4109 sctp_remove_laddr(laddr);
4110 return (0);
4111 }
4112 } else if (l_sa->sa_family == AF_INET) {
4113 /* IPv4 address */
4114 struct sockaddr_in *sin1, *sin2;
4115
4116 sin1 = (struct sockaddr_in *)l_sa;
4117 sin2 = (struct sockaddr_in *)sa;
4118 if (sin1->sin_addr.s_addr == sin2->sin_addr.s_addr) {
4119 /* matched */
4120 sctp_remove_laddr(laddr);
4121 return (0);
4122 }
4123 } else {
4124 /* invalid family */
4125 return (-1);
4126 }
4127 } /* end foreach */
4128 /* address not found! */
4129 return (-1);
4130}
4131
4132static char sctp_pcb_initialized = 0;
4133
4134/*
4135 * Temporarily remove for __APPLE__ until we use the Tiger equivalents
4136 */
4137/* sysctl */
4138static int sctp_max_number_of_assoc = SCTP_MAX_NUM_OF_ASOC;
4139static int sctp_scale_up_for_address = SCTP_SCALE_FOR_ADDR;

--- 14 unchanged lines hidden (view full) ---

4154 sctp_pcb_initialized = 1;
4155
4156 bzero(&sctpstat, sizeof(struct sctpstat));
4157 SCTP_GETTIME_TIMEVAL(&sctpstat.sctps_discontinuitytime);
4158 /* init the empty list of (All) Endpoints */
4159 LIST_INIT(&sctppcbinfo.listhead);
4160
4161 /* init the iterator head */
4356static char sctp_pcb_initialized = 0;
4357
4358/*
4359 * Temporarily remove for __APPLE__ until we use the Tiger equivalents
4360 */
4361/* sysctl */
4362static int sctp_max_number_of_assoc = SCTP_MAX_NUM_OF_ASOC;
4363static int sctp_scale_up_for_address = SCTP_SCALE_FOR_ADDR;

--- 14 unchanged lines hidden (view full) ---

4378 sctp_pcb_initialized = 1;
4379
4380 bzero(&sctpstat, sizeof(struct sctpstat));
4381 SCTP_GETTIME_TIMEVAL(&sctpstat.sctps_discontinuitytime);
4382 /* init the empty list of (All) Endpoints */
4383 LIST_INIT(&sctppcbinfo.listhead);
4384
4385 /* init the iterator head */
4162 LIST_INIT(&sctppcbinfo.iteratorhead);
4386 TAILQ_INIT(&sctppcbinfo.iteratorhead);
4163
4164 /* init the hash table of endpoints */
4165 TUNABLE_INT_FETCH("net.inet.sctp.tcbhashsize", &sctp_hashtblsize);
4166 TUNABLE_INT_FETCH("net.inet.sctp.pcbhashsize", &sctp_pcbtblsize);
4167 TUNABLE_INT_FETCH("net.inet.sctp.chunkscale", &sctp_chunkscale);
4168 sctppcbinfo.sctp_asochash = SCTP_HASH_INIT((sctp_hashtblsize * 31),
4169 &sctppcbinfo.hashasocmark);
4170 sctppcbinfo.sctp_ephash = SCTP_HASH_INIT(sctp_hashtblsize,
4171 &sctppcbinfo.hashmark);
4172 sctppcbinfo.sctp_tcpephash = SCTP_HASH_INIT(sctp_hashtblsize,
4173 &sctppcbinfo.hashtcpmark);
4174 sctppcbinfo.hashtblsize = sctp_hashtblsize;
4175
4176 /* init the small hash table we use to track restarted asoc's */
4177 sctppcbinfo.sctp_restarthash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE,
4178 &sctppcbinfo.hashrestartmark);
4179
4387
4388 /* init the hash table of endpoints */
4389 TUNABLE_INT_FETCH("net.inet.sctp.tcbhashsize", &sctp_hashtblsize);
4390 TUNABLE_INT_FETCH("net.inet.sctp.pcbhashsize", &sctp_pcbtblsize);
4391 TUNABLE_INT_FETCH("net.inet.sctp.chunkscale", &sctp_chunkscale);
4392 sctppcbinfo.sctp_asochash = SCTP_HASH_INIT((sctp_hashtblsize * 31),
4393 &sctppcbinfo.hashasocmark);
4394 sctppcbinfo.sctp_ephash = SCTP_HASH_INIT(sctp_hashtblsize,
4395 &sctppcbinfo.hashmark);
4396 sctppcbinfo.sctp_tcpephash = SCTP_HASH_INIT(sctp_hashtblsize,
4397 &sctppcbinfo.hashtcpmark);
4398 sctppcbinfo.hashtblsize = sctp_hashtblsize;
4399
4400 /* init the small hash table we use to track restarted asoc's */
4401 sctppcbinfo.sctp_restarthash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE,
4402 &sctppcbinfo.hashrestartmark);
4403
4404
4405 sctppcbinfo.sctp_vrfhash = SCTP_HASH_INIT(SCTP_SIZE_OF_VRF_HASH,
4406 &sctppcbinfo.hashvrfmark);
4407
4180 /* init the zones */
4181 /*
4182 * FIX ME: Should check for NULL returns, but if it does fail we are
4183 * doomed to panic anyways... add later maybe.
4184 */
4185 SCTP_ZONE_INIT(sctppcbinfo.ipi_zone_ep, "sctp_ep",
4186 sizeof(struct sctp_inpcb), maxsockets);
4187

--- 22 unchanged lines hidden (view full) ---

4210
4211 /* Master Lock INIT for info structure */
4212 SCTP_INP_INFO_LOCK_INIT();
4213 SCTP_STATLOG_INIT_LOCK();
4214 SCTP_ITERATOR_LOCK_INIT();
4215
4216 SCTP_IPI_COUNT_INIT();
4217 SCTP_IPI_ADDR_INIT();
4408 /* init the zones */
4409 /*
4410 * FIX ME: Should check for NULL returns, but if it does fail we are
4411 * doomed to panic anyways... add later maybe.
4412 */
4413 SCTP_ZONE_INIT(sctppcbinfo.ipi_zone_ep, "sctp_ep",
4414 sizeof(struct sctp_inpcb), maxsockets);
4415

--- 22 unchanged lines hidden (view full) ---

4438
4439 /* Master Lock INIT for info structure */
4440 SCTP_INP_INFO_LOCK_INIT();
4441 SCTP_STATLOG_INIT_LOCK();
4442 SCTP_ITERATOR_LOCK_INIT();
4443
4444 SCTP_IPI_COUNT_INIT();
4445 SCTP_IPI_ADDR_INIT();
4446 SCTP_IPI_ITERATOR_WQ_INIT();
4447
4218 LIST_INIT(&sctppcbinfo.addr_wq);
4219
4220 /* not sure if we need all the counts */
4221 sctppcbinfo.ipi_count_ep = 0;
4222 /* assoc/tcb zone info */
4223 sctppcbinfo.ipi_count_asoc = 0;
4224 /* local addrlist zone info */
4225 sctppcbinfo.ipi_count_laddr = 0;

--- 13 unchanged lines hidden (view full) ---

4239
4240 SCTP_OS_TIMER_INIT(&sctppcbinfo.addr_wq_timer.timer);
4241
4242 /* Init the TIMEWAIT list */
4243 for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
4244 LIST_INIT(&sctppcbinfo.vtag_timewait[i]);
4245 }
4246
4448 LIST_INIT(&sctppcbinfo.addr_wq);
4449
4450 /* not sure if we need all the counts */
4451 sctppcbinfo.ipi_count_ep = 0;
4452 /* assoc/tcb zone info */
4453 sctppcbinfo.ipi_count_asoc = 0;
4454 /* local addrlist zone info */
4455 sctppcbinfo.ipi_count_laddr = 0;

--- 13 unchanged lines hidden (view full) ---

4469
4470 SCTP_OS_TIMER_INIT(&sctppcbinfo.addr_wq_timer.timer);
4471
4472 /* Init the TIMEWAIT list */
4473 for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
4474 LIST_INIT(&sctppcbinfo.vtag_timewait[i]);
4475 }
4476
4477#if defined(SCTP_USE_THREAD_BASED_ITERATOR)
4478 sctppcbinfo.iterator_running = 0;
4479 sctp_startup_iterator();
4480#endif
4481
4482 /*
4483 * INIT the default VRF which for BSD is the only one, other O/S's
4484 * may have more. But initially they must start with one and then
4485 * add the VRF's as addresses are added.
4486 */
4487 sctp_init_vrf_list(SCTP_DEFAULT_VRF);
4488
4247}
4248
4249
4250int
4251sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
4252 int iphlen, int offset, int limit, struct sctphdr *sh,
4253 struct sockaddr *altsa)
4254{

--- 554 unchanged lines hidden (view full) ---

4809 net = sctp_findnet(stcb, sa);
4810
4811 if (net == NULL) {
4812 /* didn't find the requested primary address! */
4813 return (-1);
4814 } else {
4815 /* set the primary address */
4816 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
4489}
4490
4491
4492int
4493sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
4494 int iphlen, int offset, int limit, struct sctphdr *sh,
4495 struct sockaddr *altsa)
4496{

--- 554 unchanged lines hidden (view full) ---

5051 net = sctp_findnet(stcb, sa);
5052
5053 if (net == NULL) {
5054 /* didn't find the requested primary address! */
5055 return (-1);
5056 } else {
5057 /* set the primary address */
5058 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
4817 /* Must be confirmed */
4818 return (-1);
5059 /* Must be confirmed, so queue to set */
5060 net->dest_state |= SCTP_ADDR_REQ_PRIMARY;
5061 return (0);
4819 }
4820 stcb->asoc.primary_destination = net;
4821 net->dest_state &= ~SCTP_ADDR_WAS_PRIMARY;
4822 net = TAILQ_FIRST(&stcb->asoc.nets);
4823 if (net != stcb->asoc.primary_destination) {
4824 /*
4825 * first one on the list is NOT the primary
4826 * sctp_cmpaddr() is much more efficent if the

--- 90 unchanged lines hidden (view full) ---

4917 }
4918 }
4919 /* Not found, ok to use the tag */
4920 SCTP_INP_INFO_WUNLOCK();
4921 return (1);
4922}
4923
4924
5062 }
5063 stcb->asoc.primary_destination = net;
5064 net->dest_state &= ~SCTP_ADDR_WAS_PRIMARY;
5065 net = TAILQ_FIRST(&stcb->asoc.nets);
5066 if (net != stcb->asoc.primary_destination) {
5067 /*
5068 * first one on the list is NOT the primary
5069 * sctp_cmpaddr() is much more efficent if the

--- 90 unchanged lines hidden (view full) ---

5160 }
5161 }
5162 /* Not found, ok to use the tag */
5163 SCTP_INP_INFO_WUNLOCK();
5164 return (1);
5165}
5166
5167
4925/*
4926 * Delete the address from the endpoint local address list Lookup using a
4927 * sockaddr address (ie. not an ifaddr)
4928 */
4929int
4930sctp_del_local_addr_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa)
4931{
4932 struct sctp_laddr *laddr;
4933 struct sockaddr *l_sa;
4934 int found = 0;
4935
4936 /*
4937 * Here is another function I cannot find a caller for. As such we
4938 * SHOULD delete it if we have no users. If we find a user that user
4939 * MUST have the INP locked.
4940 *
4941 */
4942
4943 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
4944 /* You are already bound to all. You have it already */
4945 return (EINVAL);
4946 }
4947 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
4948 /* make sure the address exists */
4949 if (laddr->ifa == NULL)
4950 continue;
4951 if (laddr->ifa->ifa_addr == NULL)
4952 continue;
4953
4954 l_sa = laddr->ifa->ifa_addr;
4955 if (l_sa->sa_family == AF_INET6) {
4956 /* IPv6 address */
4957 struct sockaddr_in6 *sin1, *sin2;
4958
4959 sin1 = (struct sockaddr_in6 *)l_sa;
4960 sin2 = (struct sockaddr_in6 *)sa;
4961 if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
4962 sizeof(struct in6_addr)) == 0) {
4963 /* matched */
4964 found = 1;
4965 break;
4966 }
4967 } else if (l_sa->sa_family == AF_INET) {
4968 /* IPv4 address */
4969 struct sockaddr_in *sin1, *sin2;
4970
4971 sin1 = (struct sockaddr_in *)l_sa;
4972 sin2 = (struct sockaddr_in *)sa;
4973 if (sin1->sin_addr.s_addr == sin2->sin_addr.s_addr) {
4974 /* matched */
4975 found = 1;
4976 break;
4977 }
4978 } else {
4979 /* invalid family */
4980 return (-1);
4981 }
4982 }
4983
4984 if (found && inp->laddr_count < 2) {
4985 /* can't delete unless there are at LEAST 2 addresses */
4986 return (-1);
4987 }
4988 if (found && (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
4989 /*
4990 * remove it from the ep list, this should NOT be done until
4991 * its really gone from the interface list and we won't be
4992 * receiving more of these. Probably right away. If we do
4993 * allow a removal of an address from an association
4994 * (sub-set bind) than this should NOT be called until the
4995 * all ASCONF come back from this association.
4996 */
4997 sctp_remove_laddr(laddr);
4998 return (0);
4999 } else {
5000 return (-1);
5001 }
5002}
5003
5004static sctp_assoc_t reneged_asoc_ids[256];
5005static uint8_t reneged_at = 0;
5006
5168static sctp_assoc_t reneged_asoc_ids[256];
5169static uint8_t reneged_at = 0;
5170
5007extern int sctp_do_drain;
5008
5009static void
5010sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
5011{
5012 /*
5013 * We must hunt this association for MBUF's past the cumack (i.e.
5014 * out of order data that we can renege on).
5015 */

--- 139 unchanged lines hidden (view full) ---

5155 /* Nothing left in map */
5156 memset(asoc->mapping_array, 0, asoc->mapping_array_size);
5157 asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1;
5158 asoc->highest_tsn_inside_map = asoc->cumulative_tsn;
5159 }
5160 asoc->last_revoke_count = cnt;
5161 SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
5162 sctp_send_sack(stcb);
5171
5172static void
5173sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
5174{
5175 /*
5176 * We must hunt this association for MBUF's past the cumack (i.e.
5177 * out of order data that we can renege on).
5178 */

--- 139 unchanged lines hidden (view full) ---

5318 /* Nothing left in map */
5319 memset(asoc->mapping_array, 0, asoc->mapping_array_size);
5320 asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1;
5321 asoc->highest_tsn_inside_map = asoc->cumulative_tsn;
5322 }
5323 asoc->last_revoke_count = cnt;
5324 SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
5325 sctp_send_sack(stcb);
5326 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_DRAIN);
5163 reneged_asoc_ids[reneged_at] = sctp_get_associd(stcb);
5164 reneged_at++;
5165 }
5166 /*
5167 * Another issue, in un-setting the TSN's in the mapping array we
5168 * DID NOT adjust the higest_tsn marker. This will cause one of two
5169 * things to occur. It may cause us to do extra work in checking for
5170 * our mapping array movement. More importantly it may cause us to

--- 33 unchanged lines hidden (view full) ---

5204 * start a new iterator
5205 * iterates through all endpoints and associations based on the pcb_state
5206 * flags and asoc_state. "af" (mandatory) is executed for all matching
5207 * assocs and "ef" (optional) is executed when the iterator completes.
5208 * "inpf" (optional) is executed for each new endpoint as it is being
5209 * iterated through.
5210 */
5211int
5327 reneged_asoc_ids[reneged_at] = sctp_get_associd(stcb);
5328 reneged_at++;
5329 }
5330 /*
5331 * Another issue, in un-setting the TSN's in the mapping array we
5332 * DID NOT adjust the higest_tsn marker. This will cause one of two
5333 * things to occur. It may cause us to do extra work in checking for
5334 * our mapping array movement. More importantly it may cause us to

--- 33 unchanged lines hidden (view full) ---

5368 * start a new iterator
5369 * iterates through all endpoints and associations based on the pcb_state
5370 * flags and asoc_state. "af" (mandatory) is executed for all matching
5371 * assocs and "ef" (optional) is executed when the iterator completes.
5372 * "inpf" (optional) is executed for each new endpoint as it is being
5373 * iterated through.
5374 */
5375int
5212sctp_initiate_iterator(inp_func inpf, asoc_func af, uint32_t pcb_state,
5213 uint32_t pcb_features, uint32_t asoc_state, void *argp, uint32_t argi,
5214 end_func ef, struct sctp_inpcb *s_inp, uint8_t chunk_output_off)
5376sctp_initiate_iterator(inp_func inpf,
5377 asoc_func af,
5378 inp_func inpe,
5379 uint32_t pcb_state,
5380 uint32_t pcb_features,
5381 uint32_t asoc_state,
5382 void *argp,
5383 uint32_t argi,
5384 end_func ef,
5385 struct sctp_inpcb *s_inp,
5386 uint8_t chunk_output_off)
5215{
5216 struct sctp_iterator *it = NULL;
5217
5218 if (af == NULL) {
5219 return (-1);
5220 }
5221 SCTP_MALLOC(it, struct sctp_iterator *, sizeof(struct sctp_iterator),
5222 "Iterator");
5223 if (it == NULL) {
5224 return (ENOMEM);
5225 }
5226 memset(it, 0, sizeof(*it));
5227 it->function_assoc = af;
5228 it->function_inp = inpf;
5387{
5388 struct sctp_iterator *it = NULL;
5389
5390 if (af == NULL) {
5391 return (-1);
5392 }
5393 SCTP_MALLOC(it, struct sctp_iterator *, sizeof(struct sctp_iterator),
5394 "Iterator");
5395 if (it == NULL) {
5396 return (ENOMEM);
5397 }
5398 memset(it, 0, sizeof(*it));
5399 it->function_assoc = af;
5400 it->function_inp = inpf;
5401 if (inpf)
5402 it->done_current_ep = 0;
5403 else
5404 it->done_current_ep = 1;
5229 it->function_atend = ef;
5230 it->pointer = argp;
5231 it->val = argi;
5232 it->pcb_flags = pcb_state;
5233 it->pcb_features = pcb_features;
5234 it->asoc_state = asoc_state;
5405 it->function_atend = ef;
5406 it->pointer = argp;
5407 it->val = argi;
5408 it->pcb_flags = pcb_state;
5409 it->pcb_features = pcb_features;
5410 it->asoc_state = asoc_state;
5411 it->function_inp_end = inpe;
5235 it->no_chunk_output = chunk_output_off;
5236 if (s_inp) {
5237 it->inp = s_inp;
5238 it->iterator_flags = SCTP_ITERATOR_DO_SINGLE_INP;
5239 } else {
5240 SCTP_INP_INFO_RLOCK();
5241 it->inp = LIST_FIRST(&sctppcbinfo.listhead);
5412 it->no_chunk_output = chunk_output_off;
5413 if (s_inp) {
5414 it->inp = s_inp;
5415 it->iterator_flags = SCTP_ITERATOR_DO_SINGLE_INP;
5416 } else {
5417 SCTP_INP_INFO_RLOCK();
5418 it->inp = LIST_FIRST(&sctppcbinfo.listhead);
5419
5242 SCTP_INP_INFO_RUNLOCK();
5243 it->iterator_flags = SCTP_ITERATOR_DO_ALL_INP;
5244
5245 }
5420 SCTP_INP_INFO_RUNLOCK();
5421 it->iterator_flags = SCTP_ITERATOR_DO_ALL_INP;
5422
5423 }
5424 SCTP_IPI_ITERATOR_WQ_LOCK();
5425 if (it->inp)
5426 SCTP_INP_INCR_REF(it->inp);
5427 TAILQ_INSERT_TAIL(&sctppcbinfo.iteratorhead, it, sctp_nxt_itr);
5428#if defined(SCTP_USE_THREAD_BASED_ITERATOR)
5429 if (sctppcbinfo.iterator_running == 0) {
5430 sctp_wakeup_iterator();
5431 }
5432 SCTP_IPI_ITERATOR_WQ_UNLOCK();
5433#else
5434 if (it->inp)
5435 SCTP_INP_DECR_REF(it->inp);
5436 SCTP_IPI_ITERATOR_WQ_UNLOCK();
5246 /* Init the timer */
5247 SCTP_OS_TIMER_INIT(&it->tmr.timer);
5248 /* add to the list of all iterators */
5437 /* Init the timer */
5438 SCTP_OS_TIMER_INIT(&it->tmr.timer);
5439 /* add to the list of all iterators */
5249 SCTP_INP_INFO_WLOCK();
5250 LIST_INSERT_HEAD(&sctppcbinfo.iteratorhead, it, sctp_nxt_itr);
5251 SCTP_INP_INFO_WUNLOCK();
5252 sctp_timer_start(SCTP_TIMER_TYPE_ITERATOR, (struct sctp_inpcb *)it,
5253 NULL, NULL);
5440 sctp_timer_start(SCTP_TIMER_TYPE_ITERATOR, (struct sctp_inpcb *)it,
5441 NULL, NULL);
5442#endif
5254 return (0);
5255}
5443 return (0);
5444}