Lines Matching +full:timer +full:- +full:cannot +full:- +full:wake +full:- +full:cpu

1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
5 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
6 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
85 spcb->ep_count = SCTP_BASE_INFO(ipi_count_ep); in sctp_fill_pcbinfo()
86 spcb->asoc_count = SCTP_BASE_INFO(ipi_count_asoc); in sctp_fill_pcbinfo()
87 spcb->laddr_count = SCTP_BASE_INFO(ipi_count_laddr); in sctp_fill_pcbinfo()
88 spcb->raddr_count = SCTP_BASE_INFO(ipi_count_raddr); in sctp_fill_pcbinfo()
89 spcb->chk_count = SCTP_BASE_INFO(ipi_count_chunk); in sctp_fill_pcbinfo()
90 spcb->readq_count = SCTP_BASE_INFO(ipi_count_readq); in sctp_fill_pcbinfo()
91 spcb->stream_oque = SCTP_BASE_INFO(ipi_count_strmoq); in sctp_fill_pcbinfo()
92 spcb->free_chunks = SCTP_BASE_INFO(ipi_free_chunks); in sctp_fill_pcbinfo()
96 /*-
106 * hash-vrf-table
107 * vrf-> ifn-> ifn -> ifn
109 * ... +--ifa-> ifa -> ifa
126 * - An endpoint can be in multiple VRF's
127 * - An association lives within a VRF and only one VRF.
128 * - Any incoming packet we can deduce the VRF for by
130 * - Any downward send call or connect call must supply the
134 * - An endpoint may add multiple VRF's to it.
135 * - Listening sockets can accept associations in any
164 vrf->vrf_id = vrf_id; in sctp_allocate_vrf()
165 LIST_INIT(&vrf->ifnlist); in sctp_allocate_vrf()
166 vrf->total_ifa_count = 0; in sctp_allocate_vrf()
167 vrf->refcount = 0; in sctp_allocate_vrf()
171 vrf->vrf_addr_hash = SCTP_HASH_INIT(SCTP_VRF_ADDR_HASH_SIZE, in sctp_allocate_vrf()
172 &vrf->vrf_addr_hashmark); in sctp_allocate_vrf()
173 if (vrf->vrf_addr_hash == NULL) { in sctp_allocate_vrf()
199 if (sctp_ifnp->ifn_index == ifn_index && in sctp_find_ifn()
200 sctp_ifnp->ifn_p == ifn) { in sctp_find_ifn()
215 if (vrf_id == liste->vrf_id) { in sctp_find_vrf()
225 if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&vrf->refcount)) { in sctp_free_vrf()
226 if (vrf->vrf_addr_hash) { in sctp_free_vrf()
227 SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark); in sctp_free_vrf()
228 vrf->vrf_addr_hash = NULL; in sctp_free_vrf()
240 if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&sctp_ifnp->refcount)) { in sctp_free_ifn()
242 if (sctp_ifnp->vrf) { in sctp_free_ifn()
243 sctp_free_vrf(sctp_ifnp->vrf); in sctp_free_ifn()
253 if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&sctp_ifap->refcount)) { in sctp_free_ifa()
255 if (sctp_ifap->ifn_p) { in sctp_free_ifa()
256 sctp_free_ifn(sctp_ifap->ifn_p); in sctp_free_ifa()
268 if (sctp_find_ifn(sctp_ifnp->ifn_p, sctp_ifnp->ifn_index) == NULL) { in sctp_delete_ifn()
278 /*-
288 LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa); in sctp_add_ifa_to_ifn()
289 sctp_ifap->ifn_p = sctp_ifnp; in sctp_add_ifa_to_ifn()
290 atomic_add_int(&sctp_ifap->ifn_p->refcount, 1); in sctp_add_ifa_to_ifn()
292 sctp_ifnp->ifa_count++; in sctp_add_ifa_to_ifn()
293 ifa_af = sctp_ifap->address.sa.sa_family; in sctp_add_ifa_to_ifn()
297 sctp_ifnp->num_v4++; in sctp_add_ifa_to_ifn()
302 sctp_ifnp->num_v6++; in sctp_add_ifa_to_ifn()
308 if (sctp_ifnp->ifa_count == 1) { in sctp_add_ifa_to_ifn()
310 sctp_ifnp->registered_af = ifa_af; in sctp_add_ifa_to_ifn()
314 /*-
316 * If no more addresses exist, remove the ifn too. Otherwise, re-register
324 if (sctp_ifap->ifn_p) { in sctp_remove_ifa_from_ifn()
326 sctp_ifap->ifn_p->ifa_count--; in sctp_remove_ifa_from_ifn()
327 switch (sctp_ifap->address.sa.sa_family) { in sctp_remove_ifa_from_ifn()
330 sctp_ifap->ifn_p->num_v4--; in sctp_remove_ifa_from_ifn()
335 sctp_ifap->ifn_p->num_v6--; in sctp_remove_ifa_from_ifn()
342 if (LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) { in sctp_remove_ifa_from_ifn()
344 sctp_delete_ifn(sctp_ifap->ifn_p); in sctp_remove_ifa_from_ifn()
346 /* re-register address family type, if needed */ in sctp_remove_ifa_from_ifn()
347 if ((sctp_ifap->ifn_p->num_v6 == 0) && in sctp_remove_ifa_from_ifn()
348 (sctp_ifap->ifn_p->registered_af == AF_INET6)) { in sctp_remove_ifa_from_ifn()
349 sctp_ifap->ifn_p->registered_af = AF_INET; in sctp_remove_ifa_from_ifn()
350 } else if ((sctp_ifap->ifn_p->num_v4 == 0) && in sctp_remove_ifa_from_ifn()
351 (sctp_ifap->ifn_p->registered_af == AF_INET)) { in sctp_remove_ifa_from_ifn()
352 sctp_ifap->ifn_p->registered_af = AF_INET6; in sctp_remove_ifa_from_ifn()
355 sctp_free_ifn(sctp_ifap->ifn_p); in sctp_remove_ifa_from_ifn()
357 sctp_ifap->ifn_p = NULL; in sctp_remove_ifa_from_ifn()
398 vrf = sctp_ifnp->vrf; in sctp_add_addr_to_vrf()
419 sctp_ifnp->ifn_index = ifn_index; in sctp_add_addr_to_vrf()
420 sctp_ifnp->ifn_p = ifn; in sctp_add_addr_to_vrf()
421 sctp_ifnp->ifn_type = ifn_type; in sctp_add_addr_to_vrf()
422 sctp_ifnp->refcount = 0; in sctp_add_addr_to_vrf()
423 sctp_ifnp->vrf = vrf; in sctp_add_addr_to_vrf()
424 atomic_add_int(&vrf->refcount, 1); in sctp_add_addr_to_vrf()
425 sctp_ifnp->ifn_mtu = SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index); in sctp_add_addr_to_vrf()
427 SCTP_SNPRINTF(sctp_ifnp->ifn_name, SCTP_IFNAMSIZ, "%s", if_name); in sctp_add_addr_to_vrf()
429 SCTP_SNPRINTF(sctp_ifnp->ifn_name, SCTP_IFNAMSIZ, "%s", "unknown"); in sctp_add_addr_to_vrf()
432 LIST_INIT(&sctp_ifnp->ifalist); in sctp_add_addr_to_vrf()
434 LIST_INSERT_HEAD(&vrf->ifnlist, sctp_ifnp, next_ifn); in sctp_add_addr_to_vrf()
437 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED); in sctp_add_addr_to_vrf()
440 if (sctp_ifap->ifn_p != NULL) { in sctp_add_addr_to_vrf()
441 if (sctp_ifap->ifn_p->ifn_index == ifn_index && in sctp_add_addr_to_vrf()
442 sctp_ifap->ifn_p->ifn_p == ifn) { in sctp_add_addr_to_vrf()
445 sctp_ifap->ifn_p->ifn_name, ifn_index, in sctp_add_addr_to_vrf()
451 if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) { in sctp_add_addr_to_vrf()
455 sctp_ifap->localifa_flags = SCTP_ADDR_VALID; in sctp_add_addr_to_vrf()
457 if (sctp_ifap->address.sa.sa_family == AF_INET6) { in sctp_add_addr_to_vrf()
461 sctp_ifap->ifn_p = sctp_ifnp; in sctp_add_addr_to_vrf()
462 atomic_add_int(&sctp_ifap->ifn_p->refcount, 1); in sctp_add_addr_to_vrf()
472 sctp_ifap->ifn_p->ifn_name, in sctp_add_addr_to_vrf()
473 sctp_ifap->ifn_p->ifn_index, if_name, in sctp_add_addr_to_vrf()
482 sctp_ifap->localifa_flags = SCTP_ADDR_VALID; in sctp_add_addr_to_vrf()
484 if (sctp_ifap->address.sa.sa_family == AF_INET6) { in sctp_add_addr_to_vrf()
506 sctp_ifap->ifn_p = sctp_ifnp; in sctp_add_addr_to_vrf()
507 atomic_add_int(&sctp_ifnp->refcount, 1); in sctp_add_addr_to_vrf()
508 sctp_ifap->vrf_id = vrf_id; in sctp_add_addr_to_vrf()
509 sctp_ifap->ifa = ifa; in sctp_add_addr_to_vrf()
510 memcpy(&sctp_ifap->address, addr, addr->sa_len); in sctp_add_addr_to_vrf()
511 sctp_ifap->localifa_flags = SCTP_ADDR_VALID | SCTP_ADDR_DEFER_USE; in sctp_add_addr_to_vrf()
512 sctp_ifap->flags = ifa_flags; in sctp_add_addr_to_vrf()
514 if (addr->sa_family == AF_INET6) { in sctp_add_addr_to_vrf()
519 switch (sctp_ifap->address.sa.sa_family) { in sctp_add_addr_to_vrf()
525 sin = &sctp_ifap->address.sin; in sctp_add_addr_to_vrf()
526 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) || in sctp_add_addr_to_vrf()
527 (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) { in sctp_add_addr_to_vrf()
528 sctp_ifap->src_is_loop = 1; in sctp_add_addr_to_vrf()
530 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { in sctp_add_addr_to_vrf()
531 sctp_ifap->src_is_priv = 1; in sctp_add_addr_to_vrf()
533 sctp_ifnp->num_v4++; in sctp_add_addr_to_vrf()
535 sctp_ifnp->registered_af = AF_INET; in sctp_add_addr_to_vrf()
545 sin6 = &sctp_ifap->address.sin6; in sctp_add_addr_to_vrf()
546 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) || in sctp_add_addr_to_vrf()
547 (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) { in sctp_add_addr_to_vrf()
548 sctp_ifap->src_is_loop = 1; in sctp_add_addr_to_vrf()
550 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { in sctp_add_addr_to_vrf()
551 sctp_ifap->src_is_priv = 1; in sctp_add_addr_to_vrf()
553 sctp_ifnp->num_v6++; in sctp_add_addr_to_vrf()
555 sctp_ifnp->registered_af = AF_INET6; in sctp_add_addr_to_vrf()
562 hash_of_addr = sctp_get_ifa_hash_val(&sctp_ifap->address.sa); in sctp_add_addr_to_vrf()
564 if ((sctp_ifap->src_is_priv == 0) && in sctp_add_addr_to_vrf()
565 (sctp_ifap->src_is_loop == 0)) { in sctp_add_addr_to_vrf()
566 sctp_ifap->src_is_glob = 1; in sctp_add_addr_to_vrf()
568 hash_addr_head = &vrf->vrf_addr_hash[(hash_of_addr & vrf->vrf_addr_hashmark)]; in sctp_add_addr_to_vrf()
570 sctp_ifap->refcount = 1; in sctp_add_addr_to_vrf()
571 LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa); in sctp_add_addr_to_vrf()
572 sctp_ifnp->ifa_count++; in sctp_add_addr_to_vrf()
573 vrf->total_ifa_count++; in sctp_add_addr_to_vrf()
582 * Bump up the refcount so that when the timer completes it in sctp_add_addr_to_vrf()
587 atomic_add_int(&sctp_ifap->refcount, 1); in sctp_add_addr_to_vrf()
601 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time); in sctp_add_addr_to_vrf()
602 wi->ifa = sctp_ifap; in sctp_add_addr_to_vrf()
603 wi->action = SCTP_ADD_IP_ADDRESS; in sctp_add_addr_to_vrf()
614 sctp_ifap->localifa_flags &= ~SCTP_ADDR_DEFER_USE; in sctp_add_addr_to_vrf()
638 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED); in sctp_del_addr_from_vrf()
641 if (sctp_ifap->ifn_p) { in sctp_del_addr_from_vrf()
642 if (ifn_index != sctp_ifap->ifn_p->ifn_index || in sctp_del_addr_from_vrf()
643 ifn != sctp_ifap->ifn_p->ifn_p) { in sctp_del_addr_from_vrf()
644 SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d (%p) ifname:%s - ignoring delete\n", in sctp_del_addr_from_vrf()
645 sctp_ifap->ifn_p->ifn_index, in sctp_del_addr_from_vrf()
646 sctp_ifap->ifn_p->ifn_p, in sctp_del_addr_from_vrf()
647 sctp_ifap->ifn_p->ifn_name); in sctp_del_addr_from_vrf()
653 sctp_ifap->localifa_flags &= ~SCTP_ADDR_VALID; in sctp_del_addr_from_vrf()
661 /* sctp_ifap->localifa_flags |= SCTP_BEING_DELETED; */ in sctp_del_addr_from_vrf()
662 vrf->total_ifa_count--; in sctp_del_addr_from_vrf()
668 SCTPDBG(SCTP_DEBUG_PCB4, "Del Addr-ifn:%d Could not find address:", in sctp_del_addr_from_vrf()
692 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time); in sctp_del_addr_from_vrf()
693 wi->ifa = sctp_ifap; in sctp_del_addr_from_vrf()
694 wi->action = SCTP_DEL_IP_ADDRESS; in sctp_del_addr_from_vrf()
698 * the newest first :-0 in sctp_del_addr_from_vrf()
724 loopback_scope = stcb->asoc.scope.loopback_scope; in sctp_does_stcb_own_this_addr()
726 ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; in sctp_does_stcb_own_this_addr()
727 ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; in sctp_does_stcb_own_this_addr()
730 local_scope = stcb->asoc.scope.local_scope; in sctp_does_stcb_own_this_addr()
731 site_scope = stcb->asoc.scope.site_scope; in sctp_does_stcb_own_this_addr()
732 ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; in sctp_does_stcb_own_this_addr()
736 vrf = sctp_find_vrf(stcb->asoc.vrf_id); in sctp_does_stcb_own_this_addr()
743 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { in sctp_does_stcb_own_this_addr()
744 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { in sctp_does_stcb_own_this_addr()
749 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { in sctp_does_stcb_own_this_addr()
754 * we have sent an asconf-add to be in sctp_does_stcb_own_this_addr()
759 if (sctp_ifa->address.sa.sa_family != to->sa_family) { in sctp_does_stcb_own_this_addr()
762 switch (sctp_ifa->address.sa.sa_family) { in sctp_does_stcb_own_this_addr()
769 sin = &sctp_ifa->address.sin; in sctp_does_stcb_own_this_addr()
772 IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { in sctp_does_stcb_own_this_addr()
775 if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred, in sctp_does_stcb_own_this_addr()
776 &sin->sin_addr) != 0) { in sctp_does_stcb_own_this_addr()
779 if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) { in sctp_does_stcb_own_this_addr()
792 sin6 = &sctp_ifa->address.sin6; in sctp_does_stcb_own_this_addr()
794 if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred, in sctp_does_stcb_own_this_addr()
795 &sin6->sin6_addr) != 0) { in sctp_does_stcb_own_this_addr()
798 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { in sctp_does_stcb_own_this_addr()
801 if (sin6->sin6_scope_id == 0) { in sctp_does_stcb_own_this_addr()
807 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) { in sctp_does_stcb_own_this_addr()
826 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) { in sctp_does_stcb_own_this_addr()
827 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) { in sctp_does_stcb_own_this_addr()
831 if (sctp_is_addr_restricted(stcb, laddr->ifa) && in sctp_does_stcb_own_this_addr()
832 (!sctp_is_addr_pending(stcb, laddr->ifa))) { in sctp_does_stcb_own_this_addr()
835 * sent an asconf-add to be considered in sctp_does_stcb_own_this_addr()
840 if (laddr->ifa->address.sa.sa_family != to->sa_family) { in sctp_does_stcb_own_this_addr()
843 switch (to->sa_family) { in sctp_does_stcb_own_this_addr()
849 sin = &laddr->ifa->address.sin; in sctp_does_stcb_own_this_addr()
851 if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) { in sctp_does_stcb_own_this_addr()
863 sin6 = &laddr->ifa->address.sin6; in sctp_does_stcb_own_this_addr()
903 switch (to->sa_family) { in sctp_tcb_special_locate()
906 if (from->sa_family == AF_INET) { in sctp_tcb_special_locate()
907 lport = ((struct sockaddr_in *)to)->sin_port; in sctp_tcb_special_locate()
908 rport = ((struct sockaddr_in *)from)->sin_port; in sctp_tcb_special_locate()
916 if (from->sa_family == AF_INET6) { in sctp_tcb_special_locate()
917 lport = ((struct sockaddr_in6 *)to)->sin6_port; in sctp_tcb_special_locate()
918 rport = ((struct sockaddr_in6 *)from)->sin6_port; in sctp_tcb_special_locate()
930 * - Does the remote port match. - Does there single association's in sctp_tcb_special_locate()
936 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { in sctp_tcb_special_locate()
940 if (lport != inp->sctp_lport) { in sctp_tcb_special_locate()
944 switch (to->sa_family) { in sctp_tcb_special_locate()
951 if (prison_check_ip4(inp->ip_inp.inp.inp_cred, in sctp_tcb_special_locate()
952 &sin->sin_addr) != 0) { in sctp_tcb_special_locate()
965 if (prison_check_ip6(inp->ip_inp.inp.inp_cred, in sctp_tcb_special_locate()
966 &sin6->sin6_addr) != 0) { in sctp_tcb_special_locate()
977 if (inp->def_vrf_id != vrf_id) { in sctp_tcb_special_locate()
982 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { in sctp_tcb_special_locate()
986 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { in sctp_tcb_special_locate()
987 if (laddr->ifa == NULL) { in sctp_tcb_special_locate()
991 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) { in sctp_tcb_special_locate()
995 if (laddr->ifa->address.sa.sa_family == in sctp_tcb_special_locate()
996 to->sa_family) { in sctp_tcb_special_locate()
999 if (from->sa_family == AF_INET) { in sctp_tcb_special_locate()
1003 intf_addr = &laddr->ifa->address.sin; in sctp_tcb_special_locate()
1005 if (sin->sin_addr.s_addr == in sctp_tcb_special_locate()
1006 intf_addr->sin_addr.s_addr) { in sctp_tcb_special_locate()
1013 if (from->sa_family == AF_INET6) { in sctp_tcb_special_locate()
1019 intf_addr6 = &laddr->ifa->address.sin6; in sctp_tcb_special_locate()
1041 stcb = LIST_FIRST(&inp->sctp_asoc_list); in sctp_tcb_special_locate()
1052 if (stcb->rport != rport) { in sctp_tcb_special_locate()
1058 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { in sctp_tcb_special_locate()
1069 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { in sctp_tcb_special_locate()
1070 if (net->ro._l_addr.sa.sa_family != from->sa_family) { in sctp_tcb_special_locate()
1074 switch (from->sa_family) { in sctp_tcb_special_locate()
1080 sin = (struct sockaddr_in *)&net->ro._l_addr; in sctp_tcb_special_locate()
1082 if (sin->sin_addr.s_addr == in sctp_tcb_special_locate()
1083 rsin->sin_addr.s_addr) { in sctp_tcb_special_locate()
1104 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr; in sctp_tcb_special_locate()
1154 switch (remote->sa_family) { in sctp_findassociation_ep_addr()
1157 rport = (((struct sockaddr_in *)remote)->sin_port); in sctp_findassociation_ep_addr()
1162 rport = (((struct sockaddr_in6 *)remote)->sin6_port); in sctp_findassociation_ep_addr()
1170 * UN-lock so we can do proper locking here this occurs when in sctp_findassociation_ep_addr()
1173 atomic_add_int(&locked_tcb->asoc.refcnt, 1); in sctp_findassociation_ep_addr()
1177 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || in sctp_findassociation_ep_addr()
1178 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { in sctp_findassociation_ep_addr()
1179 /*- in sctp_findassociation_ep_addr()
1186 if ((inp->sctp_socket) && SCTP_IS_LISTENING(inp)) { in sctp_findassociation_ep_addr()
1189 netp, inp->def_vrf_id); in sctp_findassociation_ep_addr()
1195 SCTP_INP_RLOCK(locked_tcb->sctp_ep); in sctp_findassociation_ep_addr()
1197 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1); in sctp_findassociation_ep_addr()
1198 SCTP_INP_RUNLOCK(locked_tcb->sctp_ep); in sctp_findassociation_ep_addr()
1204 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { in sctp_findassociation_ep_addr()
1207 stcb = LIST_FIRST(&inp->sctp_asoc_list); in sctp_findassociation_ep_addr()
1213 if (stcb->rport != rport) { in sctp_findassociation_ep_addr()
1218 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { in sctp_findassociation_ep_addr()
1227 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { in sctp_findassociation_ep_addr()
1233 if (net->ro._l_addr.sa.sa_family != in sctp_findassociation_ep_addr()
1234 remote->sa_family) { in sctp_findassociation_ep_addr()
1238 switch (remote->sa_family) { in sctp_findassociation_ep_addr()
1246 &net->ro._l_addr; in sctp_findassociation_ep_addr()
1248 if (sin->sin_addr.s_addr == in sctp_findassociation_ep_addr()
1249 rsin->sin_addr.s_addr) { in sctp_findassociation_ep_addr()
1260 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1); in sctp_findassociation_ep_addr()
1276 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr; in sctp_findassociation_ep_addr()
1290 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1); in sctp_findassociation_ep_addr()
1308 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { in sctp_findassociation_ep_addr()
1311 head = &inp->sctp_tcbhash[SCTP_PCBHASH_ALLADDR(rport, in sctp_findassociation_ep_addr()
1312 inp->sctp_hashmark)]; in sctp_findassociation_ep_addr()
1314 if (stcb->rport != rport) { in sctp_findassociation_ep_addr()
1319 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { in sctp_findassociation_ep_addr()
1328 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { in sctp_findassociation_ep_addr()
1334 if (net->ro._l_addr.sa.sa_family != in sctp_findassociation_ep_addr()
1335 remote->sa_family) { in sctp_findassociation_ep_addr()
1339 switch (remote->sa_family) { in sctp_findassociation_ep_addr()
1347 &net->ro._l_addr; in sctp_findassociation_ep_addr()
1349 if (sin->sin_addr.s_addr == in sctp_findassociation_ep_addr()
1350 rsin->sin_addr.s_addr) { in sctp_findassociation_ep_addr()
1361 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1); in sctp_findassociation_ep_addr()
1377 &net->ro._l_addr; in sctp_findassociation_ep_addr()
1391 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1); in sctp_findassociation_ep_addr()
1412 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1); in sctp_findassociation_ep_addr()
1434 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { in sctp_findasoc_ep_asocid_locked()
1439 head = &inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(id, inp->hashasocidmark)]; in sctp_findasoc_ep_asocid_locked()
1446 if (stcb->asoc.assoc_id == id) { in sctp_findasoc_ep_asocid_locked()
1447 if (inp != stcb->sctp_ep) { in sctp_findasoc_ep_asocid_locked()
1455 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { in sctp_findasoc_ep_asocid_locked()
1502 switch (nam->sa_family) { in sctp_endpoint_probe()
1523 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { in sctp_endpoint_probe()
1527 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) && in sctp_endpoint_probe()
1528 (inp->sctp_lport == lport)) { in sctp_endpoint_probe()
1530 switch (nam->sa_family) { in sctp_endpoint_probe()
1533 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && in sctp_endpoint_probe()
1542 if (prison_check_ip4(inp->ip_inp.inp.inp_cred, in sctp_endpoint_probe()
1543 &sin->sin_addr) != 0) { in sctp_endpoint_probe()
1555 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { in sctp_endpoint_probe()
1559 if (prison_check_ip6(inp->ip_inp.inp.inp_cred, in sctp_endpoint_probe()
1560 &sin6->sin6_addr) != 0) { in sctp_endpoint_probe()
1571 if (inp->def_vrf_id == vrf_id) in sctp_endpoint_probe()
1581 switch (nam->sa_family) { in sctp_endpoint_probe()
1584 if (sin->sin_addr.s_addr == INADDR_ANY) { in sctp_endpoint_probe()
1592 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { in sctp_endpoint_probe()
1607 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { in sctp_endpoint_probe()
1611 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL)) { in sctp_endpoint_probe()
1619 if (inp->sctp_lport != lport) { in sctp_endpoint_probe()
1625 if (inp->def_vrf_id == vrf_id) in sctp_endpoint_probe()
1632 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { in sctp_endpoint_probe()
1633 if (laddr->ifa == NULL) { in sctp_endpoint_probe()
1638 SCTPDBG(SCTP_DEBUG_PCB1, "Ok laddr->ifa:%p is possible, ", in sctp_endpoint_probe()
1639 (void *)laddr->ifa); in sctp_endpoint_probe()
1640 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) { in sctp_endpoint_probe()
1644 if (laddr->ifa->address.sa.sa_family == nam->sa_family) { in sctp_endpoint_probe()
1646 switch (nam->sa_family) { in sctp_endpoint_probe()
1649 if (sin->sin_addr.s_addr == in sctp_endpoint_probe()
1650 laddr->ifa->address.sin.sin_addr.s_addr) { in sctp_endpoint_probe()
1658 intf_addr6 = &laddr->ifa->address.sin6; in sctp_endpoint_probe()
1684 if (t_inp->sctp_lport != lport) { in sctp_isport_inuse()
1689 if (t_inp->def_vrf_id == vrf_id) in sctp_isport_inuse()
1696 if ((t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && in sctp_isport_inuse()
1698 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { in sctp_isport_inuse()
1705 } else if (t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { in sctp_isport_inuse()
1710 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && in sctp_isport_inuse()
1725 /* For 1-2-1 with port reuse */ in sctp_swap_inpcb_for_listen()
1734 return (-1); in sctp_swap_inpcb_for_listen()
1736 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) { in sctp_swap_inpcb_for_listen()
1740 head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(inp->sctp_lport, in sctp_swap_inpcb_for_listen()
1742 /* Kick out all non-listeners to the TCP hash */ in sctp_swap_inpcb_for_listen()
1744 if (tinp->sctp_lport != inp->sctp_lport) { in sctp_swap_inpcb_for_listen()
1747 if (tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { in sctp_swap_inpcb_for_listen()
1750 if (tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { in sctp_swap_inpcb_for_listen()
1758 …head = &SCTP_BASE_INFO(sctp_tcpephash)[SCTP_PCBHASH_ALLADDR(tinp->sctp_lport, SCTP_BASE_INFO(hasht… in sctp_swap_inpcb_for_listen()
1759 tinp->sctp_flags |= SCTP_PCB_FLAGS_IN_TCPPOOL; in sctp_swap_inpcb_for_listen()
1766 inp->sctp_flags &= ~SCTP_PCB_FLAGS_IN_TCPPOOL; in sctp_swap_inpcb_for_listen()
1767 …head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(inp->sctp_lport, SCTP_BASE_INFO(hashmark)… in sctp_swap_inpcb_for_listen()
1791 switch (nam->sa_family) { in sctp_pcb_findep()
1795 lport = sin->sin_port; in sctp_pcb_findep()
1801 lport = sin6->sin6_port; in sctp_pcb_findep()
1900 * This routine will grub through the mbuf that is a INIT or INIT-ACK and
1926 sin4.sin_port = sh->src_port; in sctp_findassociation_special_addr()
1932 sin6.sin6_port = sh->src_port; in sctp_findassociation_special_addr()
1941 ptype = ntohs(phdr->param_type); in sctp_findassociation_special_addr()
1943 plen = ntohs(phdr->param_length); in sctp_findassociation_special_addr()
1959 memcpy(&sin4.sin_addr, &p4->addr, sizeof(p4->addr)); in sctp_findassociation_special_addr()
1980 memcpy(&sin6.sin6_addr, &p6->addr, sizeof(p6->addr)); in sctp_findassociation_special_addr()
2014 SCTP_INP_RLOCK(stcb->sctp_ep); in sctp_findassoc_by_vtag()
2015 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { in sctp_findassoc_by_vtag()
2016 SCTP_INP_RUNLOCK(stcb->sctp_ep); in sctp_findassoc_by_vtag()
2019 if (stcb->sctp_ep->def_vrf_id != vrf_id) { in sctp_findassoc_by_vtag()
2020 SCTP_INP_RUNLOCK(stcb->sctp_ep); in sctp_findassoc_by_vtag()
2024 SCTP_INP_RUNLOCK(stcb->sctp_ep); in sctp_findassoc_by_vtag()
2025 if (stcb->asoc.my_vtag == vtag) { in sctp_findassoc_by_vtag()
2027 if (stcb->rport != rport) { in sctp_findassoc_by_vtag()
2031 if (stcb->sctp_ep->sctp_lport != lport) { in sctp_findassoc_by_vtag()
2035 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { in sctp_findassoc_by_vtag()
2050 if (stcb->asoc.peer_vtag == remote_tag) { in sctp_findassoc_by_vtag()
2067 *inp_p = stcb->sctp_ep; in sctp_findassoc_by_vtag()
2076 *inp_p = stcb->sctp_ep; in sctp_findassoc_by_vtag()
2106 if (sh->v_tag) { in sctp_findassociation_addr()
2107 /* we only go down this path if vtag is non-zero */ in sctp_findassociation_addr()
2108 stcb = sctp_findassoc_by_vtag(src, dst, ntohl(sh->v_tag), in sctp_findassociation_addr()
2109 inp_p, netp, sh->src_port, sh->dest_port, 0, vrf_id, 0); in sctp_findassociation_addr()
2126 if ((ch->chunk_type == SCTP_INITIATION) || in sctp_findassociation_addr()
2127 (ch->chunk_type == SCTP_INITIATION_ACK)) { in sctp_findassociation_addr()
2128 /*- in sctp_findassociation_addr()
2136 if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) { in sctp_findassociation_addr()
2182 ptype = (int)((uint32_t)ntohs(phdr->param_type)); in sctp_findassociation_ep_asconf()
2191 if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv6addr_param)) { in sctp_findassociation_ep_asconf()
2203 sin6->sin6_family = AF_INET6; in sctp_findassociation_ep_asconf()
2204 sin6->sin6_len = sizeof(*sin6); in sctp_findassociation_ep_asconf()
2205 sin6->sin6_port = sh->src_port; in sctp_findassociation_ep_asconf()
2206 memcpy(&sin6->sin6_addr, &p6->addr, sizeof(struct in6_addr)); in sctp_findassociation_ep_asconf()
2207 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) in sctp_findassociation_ep_asconf()
2218 if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv4addr_param)) { in sctp_findassociation_ep_asconf()
2230 sin->sin_family = AF_INET; in sctp_findassociation_ep_asconf()
2231 sin->sin_len = sizeof(*sin); in sctp_findassociation_ep_asconf()
2232 sin->sin_port = sh->src_port; in sctp_findassociation_ep_asconf()
2233 memcpy(&sin->sin_addr, &p4->addr, sizeof(struct in_addr)); in sctp_findassociation_ep_asconf()
2234 if (sin->sin_addr.s_addr == INADDR_ANY) in sctp_findassociation_ep_asconf()
2245 stcb = sctp_findassoc_by_vtag(NULL, dst, ntohl(sh->v_tag), inp_p, in sctp_findassociation_ep_asconf()
2246 netp, sh->src_port, sh->dest_port, 1, vrf_id, 0); in sctp_findassociation_ep_asconf()
2285 SCTP_PRINTF("Out of SCTP-INPCB structures - no resources\n"); in sctp_inpcb_alloc()
2295 inp->sctp_socket = so; in sctp_inpcb_alloc()
2296 inp->ip_inp.inp.inp_socket = so; in sctp_inpcb_alloc()
2297 inp->ip_inp.inp.inp_cred = crhold(so->so_cred); in sctp_inpcb_alloc()
2301 inp->ip_inp.inp.inp_flags |= IN6P_AUTOFLOWLABEL; in sctp_inpcb_alloc()
2304 inp->ip_inp.inp.inp_flags |= IN6P_IPV6_V6ONLY; in sctp_inpcb_alloc()
2308 inp->sctp_associd_counter = 1; in sctp_inpcb_alloc()
2309 inp->partial_delivery_point = SCTP_SB_LIMIT_RCV(so) >> SCTP_PARTIAL_DELIVERY_SHIFT; in sctp_inpcb_alloc()
2310 inp->sctp_frag_point = 0; in sctp_inpcb_alloc()
2311 inp->max_cwnd = 0; in sctp_inpcb_alloc()
2312 inp->sctp_cmt_on_off = SCTP_BASE_SYSCTL(sctp_cmt_on_off); in sctp_inpcb_alloc()
2313 inp->ecn_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_ecn_enable); in sctp_inpcb_alloc()
2314 inp->prsctp_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pr_enable); in sctp_inpcb_alloc()
2315 inp->auth_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_auth_enable); in sctp_inpcb_alloc()
2316 inp->asconf_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_asconf_enable); in sctp_inpcb_alloc()
2317 inp->reconfig_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_reconfig_enable); in sctp_inpcb_alloc()
2318 inp->nrsack_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_nrsack_enable); in sctp_inpcb_alloc()
2319 inp->pktdrop_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pktdrop_enable); in sctp_inpcb_alloc()
2320 inp->idata_supported = 0; in sctp_inpcb_alloc()
2321 inp->rcv_edmid = SCTP_EDMID_NONE; in sctp_inpcb_alloc()
2323 inp->fibnum = so->so_fibnum; in sctp_inpcb_alloc()
2324 /* init the small hash table we use to track asocid <-> tcb */ in sctp_inpcb_alloc()
2325 inp->sctp_asocidhash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, &inp->hashasocidmark); in sctp_inpcb_alloc()
2326 if (inp->sctp_asocidhash == NULL) { in sctp_inpcb_alloc()
2327 crfree(inp->ip_inp.inp.inp_cred); in sctp_inpcb_alloc()
2333 inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl); in sctp_inpcb_alloc()
2336 so->so_pcb = (caddr_t)inp; in sctp_inpcb_alloc()
2340 inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE | in sctp_inpcb_alloc()
2342 /* Be sure it is NON-BLOCKING IO for UDP */ in sctp_inpcb_alloc()
2346 inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE | in sctp_inpcb_alloc()
2354 * unsupported socket type (RAW, etc)- in case we missed it in sctp_inpcb_alloc()
2358 so->so_pcb = NULL; in sctp_inpcb_alloc()
2359 crfree(inp->ip_inp.inp.inp_cred); in sctp_inpcb_alloc()
2373 inp->sctp_tcbhash = SCTP_HASH_INIT(SCTP_BASE_SYSCTL(sctp_pcbtblsize), in sctp_inpcb_alloc()
2374 &inp->sctp_hashmark); in sctp_inpcb_alloc()
2375 if (inp->sctp_tcbhash == NULL) { in sctp_inpcb_alloc()
2376 SCTP_PRINTF("Out of SCTP-INPCB->hashinit - no resources\n"); in sctp_inpcb_alloc()
2378 so->so_pcb = NULL; in sctp_inpcb_alloc()
2379 crfree(inp->ip_inp.inp.inp_cred); in sctp_inpcb_alloc()
2383 inp->def_vrf_id = vrf_id; in sctp_inpcb_alloc()
2387 rw_init_flags(&inp->ip_inp.inp.inp_lock, "sctpinp", in sctp_inpcb_alloc()
2398 TAILQ_INIT(&inp->read_queue); in sctp_inpcb_alloc()
2399 LIST_INIT(&inp->sctp_addr_list); in sctp_inpcb_alloc()
2401 LIST_INIT(&inp->sctp_asoc_list); in sctp_inpcb_alloc()
2405 LIST_INIT(&inp->sctp_asoc_free_list); in sctp_inpcb_alloc()
2407 /* Init the timer structure for signature change */ in sctp_inpcb_alloc()
2408 SCTP_OS_TIMER_INIT(&inp->sctp_ep.signature_change.timer); in sctp_inpcb_alloc()
2409 inp->sctp_ep.signature_change.type = SCTP_TIMER_TYPE_NEWCOOKIE; in sctp_inpcb_alloc()
2412 m = &inp->sctp_ep; in sctp_inpcb_alloc()
2415 m->sctp_timeoutticks[SCTP_TIMER_SEND] = sctp_secs_to_ticks(SCTP_SEND_SEC); /* needed ? */ in sctp_inpcb_alloc()
2416 m->sctp_timeoutticks[SCTP_TIMER_INIT] = sctp_secs_to_ticks(SCTP_INIT_SEC); /* needed ? */ in sctp_inpcb_alloc()
2417 …m->sctp_timeoutticks[SCTP_TIMER_RECV] = sctp_msecs_to_ticks(SCTP_BASE_SYSCTL(sctp_delayed_sack_tim… in sctp_inpcb_alloc()
2418 …m->sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_msecs_to_ticks(SCTP_BASE_SYSCTL(sctp_heartbeat_i… in sctp_inpcb_alloc()
2419 …m->sctp_timeoutticks[SCTP_TIMER_PMTU] = sctp_secs_to_ticks(SCTP_BASE_SYSCTL(sctp_pmtu_raise_time_d… in sctp_inpcb_alloc()
2420 …m->sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] = sctp_secs_to_ticks(SCTP_BASE_SYSCTL(sctp_shutdown_g… in sctp_inpcb_alloc()
2421 …m->sctp_timeoutticks[SCTP_TIMER_SIGNATURE] = sctp_secs_to_ticks(SCTP_BASE_SYSCTL(sctp_secret_lifet… in sctp_inpcb_alloc()
2423 m->sctp_maxrto = SCTP_BASE_SYSCTL(sctp_rto_max_default); in sctp_inpcb_alloc()
2424 m->sctp_minrto = SCTP_BASE_SYSCTL(sctp_rto_min_default); in sctp_inpcb_alloc()
2425 m->initial_rto = SCTP_BASE_SYSCTL(sctp_rto_initial_default); in sctp_inpcb_alloc()
2426 m->initial_init_rto_max = SCTP_BASE_SYSCTL(sctp_init_rto_max_default); in sctp_inpcb_alloc()
2427 m->sctp_sack_freq = SCTP_BASE_SYSCTL(sctp_sack_freq_default); in sctp_inpcb_alloc()
2428 m->max_init_times = SCTP_BASE_SYSCTL(sctp_init_rtx_max_default); in sctp_inpcb_alloc()
2429 m->max_send_times = SCTP_BASE_SYSCTL(sctp_assoc_rtx_max_default); in sctp_inpcb_alloc()
2430 m->def_net_failure = SCTP_BASE_SYSCTL(sctp_path_rtx_max_default); in sctp_inpcb_alloc()
2431 m->def_net_pf_threshold = SCTP_BASE_SYSCTL(sctp_path_pf_threshold); in sctp_inpcb_alloc()
2432 m->sctp_sws_sender = SCTP_SWS_SENDER_DEF; in sctp_inpcb_alloc()
2433 m->sctp_sws_receiver = SCTP_SWS_RECEIVER_DEF; in sctp_inpcb_alloc()
2434 m->max_burst = SCTP_BASE_SYSCTL(sctp_max_burst_default); in sctp_inpcb_alloc()
2435 m->fr_max_burst = SCTP_BASE_SYSCTL(sctp_fr_max_burst_default); in sctp_inpcb_alloc()
2437 m->sctp_default_cc_module = SCTP_BASE_SYSCTL(sctp_default_cc_module); in sctp_inpcb_alloc()
2438 m->sctp_default_ss_module = SCTP_BASE_SYSCTL(sctp_default_ss_module); in sctp_inpcb_alloc()
2439 m->max_open_streams_intome = SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default); in sctp_inpcb_alloc()
2440 /* number of streams to pre-open on a association */ in sctp_inpcb_alloc()
2441 m->pre_open_stream_count = SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default); in sctp_inpcb_alloc()
2443 m->default_mtu = 0; in sctp_inpcb_alloc()
2445 m->adaptation_layer_indicator = 0; in sctp_inpcb_alloc()
2446 m->adaptation_layer_indicator_provided = 0; in sctp_inpcb_alloc()
2449 m->random_counter = 1; in sctp_inpcb_alloc()
2450 m->store_at = SCTP_SIGNATURE_SIZE; in sctp_inpcb_alloc()
2451 SCTP_READ_RANDOM(m->random_numbers, sizeof(m->random_numbers)); in sctp_inpcb_alloc()
2455 m->size_of_a_cookie = (sizeof(struct sctp_init_msg) * 2) + in sctp_inpcb_alloc()
2457 m->size_of_a_cookie += SCTP_SIGNATURE_SIZE; in sctp_inpcb_alloc()
2461 m->time_of_secret_change = time.tv_sec; in sctp_inpcb_alloc()
2464 m->secret_key[0][i] = sctp_select_initial_TSN(m); in sctp_inpcb_alloc()
2469 m->def_cookie_life = sctp_msecs_to_ticks(SCTP_BASE_SYSCTL(sctp_valid_cookie_life_default)); in sctp_inpcb_alloc()
2473 m->local_hmacs = sctp_default_supported_hmaclist(); in sctp_inpcb_alloc()
2474 m->local_auth_chunks = sctp_alloc_chunklist(); in sctp_inpcb_alloc()
2475 if (inp->asconf_supported) { in sctp_inpcb_alloc()
2476 sctp_auth_add_chunk(SCTP_ASCONF, m->local_auth_chunks); in sctp_inpcb_alloc()
2477 sctp_auth_add_chunk(SCTP_ASCONF_ACK, m->local_auth_chunks); in sctp_inpcb_alloc()
2479 m->default_dscp = 0; in sctp_inpcb_alloc()
2481 m->default_flowlabel = 0; in sctp_inpcb_alloc()
2483 m->port = 0; /* encapsulation disabled by default */ in sctp_inpcb_alloc()
2484 LIST_INIT(&m->shared_keys); in sctp_inpcb_alloc()
2487 sctp_insert_sharedkey(&m->shared_keys, null_key); in sctp_inpcb_alloc()
2504 atomic_add_int(&stcb->asoc.refcnt, 1); in sctp_move_pcb_and_assoc()
2510 atomic_subtract_int(&stcb->asoc.refcnt, 1); in sctp_move_pcb_and_assoc()
2513 if (old_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { in sctp_move_pcb_and_assoc()
2514 new_inp->ip_inp.inp.inp_flags |= old_inp->ip_inp.inp.inp_flags & INP_CONTROLOPTS; in sctp_move_pcb_and_assoc()
2515 if (old_inp->ip_inp.inp.in6p_outputopts) { in sctp_move_pcb_and_assoc()
2516 …new_inp->ip_inp.inp.in6p_outputopts = ip6_copypktopts(old_inp->ip_inp.inp.in6p_outputopts, M_NOWAI… in sctp_move_pcb_and_assoc()
2525 new_inp->ip_inp.inp.inp_ip_tos = old_inp->ip_inp.inp.inp_ip_tos; in sctp_move_pcb_and_assoc()
2526 new_inp->ip_inp.inp.inp_ip_ttl = old_inp->ip_inp.inp.inp_ip_ttl; in sctp_move_pcb_and_assoc()
2529 new_inp->sctp_ep.time_of_secret_change = in sctp_move_pcb_and_assoc()
2530 old_inp->sctp_ep.time_of_secret_change; in sctp_move_pcb_and_assoc()
2531 memcpy(new_inp->sctp_ep.secret_key, old_inp->sctp_ep.secret_key, in sctp_move_pcb_and_assoc()
2532 sizeof(old_inp->sctp_ep.secret_key)); in sctp_move_pcb_and_assoc()
2533 new_inp->sctp_ep.current_secret_number = in sctp_move_pcb_and_assoc()
2534 old_inp->sctp_ep.current_secret_number; in sctp_move_pcb_and_assoc()
2535 new_inp->sctp_ep.last_secret_number = in sctp_move_pcb_and_assoc()
2536 old_inp->sctp_ep.last_secret_number; in sctp_move_pcb_and_assoc()
2537 new_inp->sctp_ep.size_of_a_cookie = old_inp->sctp_ep.size_of_a_cookie; in sctp_move_pcb_and_assoc()
2540 stcb->sctp_socket = new_inp->sctp_socket; in sctp_move_pcb_and_assoc()
2541 stcb->sctp_ep = new_inp; in sctp_move_pcb_and_assoc()
2544 lport = new_inp->sctp_lport = old_inp->sctp_lport; in sctp_move_pcb_and_assoc()
2545 rport = stcb->rport; in sctp_move_pcb_and_assoc()
2549 if (stcb->asoc.in_asocid_hash) { in sctp_move_pcb_and_assoc()
2557 new_inp->sctp_flags &= ~SCTP_PCB_FLAGS_UNBOUND; in sctp_move_pcb_and_assoc()
2560 LIST_INSERT_HEAD(&new_inp->sctp_asoc_list, stcb, sctp_tcblist); in sctp_move_pcb_and_assoc()
2562 * Question, do we even need to worry about the ep-hash since we in sctp_move_pcb_and_assoc()
2566 if (stcb->asoc.in_asocid_hash) { in sctp_move_pcb_and_assoc()
2569 lhd = &new_inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(stcb->asoc.assoc_id, in sctp_move_pcb_and_assoc()
2570 new_inp->hashasocidmark)]; in sctp_move_pcb_and_assoc()
2573 /* Ok. Let's restart timer. */ in sctp_move_pcb_and_assoc()
2574 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { in sctp_move_pcb_and_assoc()
2580 if (new_inp->sctp_tcbhash != NULL) { in sctp_move_pcb_and_assoc()
2581 SCTP_HASH_FREE(new_inp->sctp_tcbhash, new_inp->sctp_hashmark); in sctp_move_pcb_and_assoc()
2582 new_inp->sctp_tcbhash = NULL; in sctp_move_pcb_and_assoc()
2584 if ((new_inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { in sctp_move_pcb_and_assoc()
2586 LIST_FOREACH(oladdr, &old_inp->sctp_addr_list, sctp_nxt_addr) { in sctp_move_pcb_and_assoc()
2599 (void)SCTP_GETTIME_TIMEVAL(&laddr->start_time); in sctp_move_pcb_and_assoc()
2600 laddr->ifa = oladdr->ifa; in sctp_move_pcb_and_assoc()
2601 atomic_add_int(&laddr->ifa->refcount, 1); in sctp_move_pcb_and_assoc()
2602 LIST_INSERT_HEAD(&new_inp->sctp_addr_list, laddr, in sctp_move_pcb_and_assoc()
2604 new_inp->laddr_count++; in sctp_move_pcb_and_assoc()
2605 if (oladdr == stcb->asoc.last_used_address) { in sctp_move_pcb_and_assoc()
2606 stcb->asoc.last_used_address = laddr; in sctp_move_pcb_and_assoc()
2611 if (stcb->asoc.dack_timer.ep == old_inp) { in sctp_move_pcb_and_assoc()
2613 stcb->asoc.dack_timer.ep = new_inp; in sctp_move_pcb_and_assoc()
2616 if (stcb->asoc.asconf_timer.ep == old_inp) { in sctp_move_pcb_and_assoc()
2618 stcb->asoc.asconf_timer.ep = new_inp; in sctp_move_pcb_and_assoc()
2621 if (stcb->asoc.strreset_timer.ep == old_inp) { in sctp_move_pcb_and_assoc()
2623 stcb->asoc.strreset_timer.ep = new_inp; in sctp_move_pcb_and_assoc()
2626 if (stcb->asoc.shut_guard_timer.ep == old_inp) { in sctp_move_pcb_and_assoc()
2628 stcb->asoc.shut_guard_timer.ep = new_inp; in sctp_move_pcb_and_assoc()
2631 if (stcb->asoc.autoclose_timer.ep == old_inp) { in sctp_move_pcb_and_assoc()
2633 stcb->asoc.autoclose_timer.ep = new_inp; in sctp_move_pcb_and_assoc()
2636 if (stcb->asoc.delete_prim_timer.ep == old_inp) { in sctp_move_pcb_and_assoc()
2638 stcb->asoc.delete_prim_timer.ep = new_inp; in sctp_move_pcb_and_assoc()
2642 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { in sctp_move_pcb_and_assoc()
2643 if (net->pmtu_timer.ep == old_inp) { in sctp_move_pcb_and_assoc()
2645 net->pmtu_timer.ep = new_inp; in sctp_move_pcb_and_assoc()
2648 if (net->hb_timer.ep == old_inp) { in sctp_move_pcb_and_assoc()
2650 net->hb_timer.ep = new_inp; in sctp_move_pcb_and_assoc()
2653 if (net->rxt_timer.ep == old_inp) { in sctp_move_pcb_and_assoc()
2655 net->rxt_timer.ep = new_inp; in sctp_move_pcb_and_assoc()
2679 (void)SCTP_GETTIME_TIMEVAL(&laddr->start_time); in sctp_insert_laddr()
2680 laddr->ifa = ifa; in sctp_insert_laddr()
2681 laddr->action = act; in sctp_insert_laddr()
2682 atomic_add_int(&ifa->refcount, 1); in sctp_insert_laddr()
2698 sctp_free_ifa(laddr->ifa); in sctp_remove_laddr()
2705 * socket address is specified, the PCB lock may be dropped and re-acquired.
2728 ip_inp = &inp->ip_inp.inp; in sctp_inpcb_bind_locked()
2736 ntohs(((struct sockaddr_in *)addr)->sin_port)); in sctp_inpcb_bind_locked()
2741 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) { in sctp_inpcb_bind_locked()
2748 switch (addr->sa_family) { in sctp_inpcb_bind_locked()
2760 if (addr->sa_len != sizeof(*sin)) { in sctp_inpcb_bind_locked()
2767 lport = sin->sin_port; in sctp_inpcb_bind_locked()
2773 if ((error = prison_local_ip4(td->td_ucred, &sin->sin_addr)) != 0) { in sctp_inpcb_bind_locked()
2777 if (sin->sin_addr.s_addr != INADDR_ANY) { in sctp_inpcb_bind_locked()
2793 if (addr->sa_len != sizeof(*sin6)) { in sctp_inpcb_bind_locked()
2798 lport = sin6->sin6_port; in sctp_inpcb_bind_locked()
2804 if ((error = prison_local_ip6(td->td_ucred, &sin6->sin6_addr, in sctp_inpcb_bind_locked()
2809 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { in sctp_inpcb_bind_locked()
2819 sin6->sin6_scope_id = 0; in sctp_inpcb_bind_locked()
2829 /* Setup a vrf_id to be the default for the non-bind-all case. */ in sctp_inpcb_bind_locked()
2830 vrf_id = inp->def_vrf_id; in sctp_inpcb_bind_locked()
2845 vrf_id = inp->def_vrf_id; in sctp_inpcb_bind_locked()
2860 * Ok, must be one-2-one and in sctp_inpcb_bind_locked()
2861 * allowing port re-use in sctp_inpcb_bind_locked()
2887 * Ok, must be one-2-one and in sctp_inpcb_bind_locked()
2888 * allowing port re-use in sctp_inpcb_bind_locked()
2922 if (ip_inp->inp_flags & INP_HIGHPORT) { in sctp_inpcb_bind_locked()
2925 } else if (ip_inp->inp_flags & INP_LOWPORT) { in sctp_inpcb_bind_locked()
2943 count = last - first + 1; /* number of candidates */ in sctp_inpcb_bind_locked()
2944 candidate = first + sctp_select_initial_TSN(&inp->sctp_ep) % (count); in sctp_inpcb_bind_locked()
2947 if (sctp_isport_inuse(inp, htons(candidate), inp->def_vrf_id) == NULL) { in sctp_inpcb_bind_locked()
2951 if (--count == 0) { in sctp_inpcb_bind_locked()
2962 if (inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE | in sctp_inpcb_bind_locked()
2965 * this really should not happen. The guy did a non-blocking in sctp_inpcb_bind_locked()
2975 inp->sctp_flags |= SCTP_PCB_FLAGS_BOUNDALL; in sctp_inpcb_bind_locked()
3026 switch (addr->sa_family) { in sctp_inpcb_bind_locked()
3064 if (addr->sa_family == AF_INET6) { in sctp_inpcb_bind_locked()
3066 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) { in sctp_inpcb_bind_locked()
3067 /* Can't bind a non-existent addr. */ in sctp_inpcb_bind_locked()
3075 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUNDALL; in sctp_inpcb_bind_locked()
3082 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, 0); in sctp_inpcb_bind_locked()
3085 inp->laddr_count++; in sctp_inpcb_bind_locked()
3089 /* Put it into tcp 1-2-1 hash */ in sctp_inpcb_bind_locked()
3091 inp->sctp_flags |= SCTP_PCB_FLAGS_IN_TCPPOOL; in sctp_inpcb_bind_locked()
3097 SCTPDBG(SCTP_DEBUG_PCB1, "Main hash to bind at head:%p, bound port:%d - in tcp_pool=%d\n", in sctp_inpcb_bind_locked()
3100 inp->sctp_lport = lport; in sctp_inpcb_bind_locked()
3103 KASSERT((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) != 0, in sctp_inpcb_bind_locked()
3105 inp->sctp_flags &= ~SCTP_PCB_FLAGS_UNBOUND; in sctp_inpcb_bind_locked()
3117 inp = so->so_pcb; in sctp_inpcb_bind()
3136 if (it && (it->vn != curvnet)) { in sctp_iterator_inp_being_freed()
3140 if (it && (it->inp == inp)) { in sctp_iterator_inp_being_freed()
3154 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) { in sctp_iterator_inp_being_freed()
3166 if (it->vn != curvnet) { in sctp_iterator_inp_being_freed()
3169 if (it->inp == inp) { in sctp_iterator_inp_being_freed()
3171 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) { in sctp_iterator_inp_being_freed()
3175 if (it->function_atend != NULL) { in sctp_iterator_inp_being_freed()
3176 (*it->function_atend) (it->pointer, it->val); in sctp_iterator_inp_being_freed()
3180 it->inp = LIST_NEXT(it->inp, sctp_list); in sctp_iterator_inp_being_freed()
3181 if (it->inp) { in sctp_iterator_inp_being_freed()
3182 SCTP_INP_INCR_REF(it->inp); in sctp_iterator_inp_being_freed()
3203 * complete then any timer has to be stopped. Then start the actual in sctp_inpcb_free()
3227 so = inp->sctp_socket; in sctp_inpcb_free()
3228 KASSERT((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) != 0, in sctp_inpcb_free()
3230 KASSERT((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0, in sctp_inpcb_free()
3233 inp->sctp_flags &= ~SCTP_PCB_FLAGS_CLOSE_IP; in sctp_inpcb_free()
3235 inp->sctp_flags |= SCTP_PCB_FLAGS_DONT_WAKE; in sctp_inpcb_free()
3236 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT; in sctp_inpcb_free()
3237 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT; in sctp_inpcb_free()
3243 if (inp->control) { in sctp_inpcb_free()
3244 sctp_m_freem(inp->control); in sctp_inpcb_free()
3245 inp->control = NULL; in sctp_inpcb_free()
3247 if (inp->pkt) { in sctp_inpcb_free()
3248 sctp_m_freem(inp->pkt); in sctp_inpcb_free()
3249 inp->pkt = NULL; in sctp_inpcb_free()
3251 ip_pcb = &inp->ip_inp.inp; /* we could just cast the main pointer in sctp_inpcb_free()
3258 LIST_FOREACH_SAFE(stcb, &inp->sctp_asoc_list, sctp_tcblist, nstcb) { in sctp_inpcb_free()
3261 stcb->sctp_socket = NULL; in sctp_inpcb_free()
3263 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { in sctp_inpcb_free()
3266 if (stcb->asoc.state & SCTP_STATE_IN_ACCEPT_QUEUE) { in sctp_inpcb_free()
3268 * Special case - we did not start a in sctp_inpcb_free()
3269 * kill timer on the asoc due to it in sctp_inpcb_free()
3281 (stcb->asoc.total_output_queue_size == 0)) { in sctp_inpcb_free()
3295 if ((stcb->asoc.size_on_reasm_queue > 0) || in sctp_inpcb_free()
3296 (stcb->asoc.size_on_all_streams > 0) || in sctp_inpcb_free()
3297 ((so != NULL) && (SCTP_SBAVAIL(&so->so_rcv) > 0))) { in sctp_inpcb_free()
3302 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_3; in sctp_inpcb_free()
3314 } else if (TAILQ_EMPTY(&stcb->asoc.send_queue) && in sctp_inpcb_free()
3315 TAILQ_EMPTY(&stcb->asoc.sent_queue) && in sctp_inpcb_free()
3316 (stcb->asoc.stream_queue_cnt == 0)) { in sctp_inpcb_free()
3317 if ((*stcb->asoc.ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, &stcb->asoc)) { in sctp_inpcb_free()
3334 if (stcb->asoc.alternate) { in sctp_inpcb_free()
3335 netp = stcb->asoc.alternate; in sctp_inpcb_free()
3337 netp = stcb->asoc.primary_destination; in sctp_inpcb_free()
3340 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, in sctp_inpcb_free()
3342 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, NULL); in sctp_inpcb_free()
3348 if ((*stcb->asoc.ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, &stcb->asoc)) { in sctp_inpcb_free()
3351 if (TAILQ_EMPTY(&stcb->asoc.send_queue) && in sctp_inpcb_free()
3352 TAILQ_EMPTY(&stcb->asoc.sent_queue) && in sctp_inpcb_free()
3353 (stcb->asoc.state & SCTP_STATE_PARTIAL_MSG_LEFT)) { in sctp_inpcb_free()
3358 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_5; in sctp_inpcb_free()
3383 inp->sctp_socket = NULL; in sctp_inpcb_free()
3390 inp->sctp_socket = NULL; in sctp_inpcb_free()
3391 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) { in sctp_inpcb_free()
3397 inp->sctp_flags |= SCTP_PCB_FLAGS_UNBOUND; in sctp_inpcb_free()
3401 * If there is a timer running to kill us, forget it, since it may in sctp_inpcb_free()
3405 LIST_FOREACH_SAFE(stcb, &inp->sctp_asoc_list, sctp_tcblist, nstcb) { in sctp_inpcb_free()
3409 stcb->sctp_socket = NULL; in sctp_inpcb_free()
3412 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { in sctp_inpcb_free()
3413 if (stcb->asoc.state & SCTP_STATE_IN_ACCEPT_QUEUE) { in sctp_inpcb_free()
3423 ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) { in sctp_inpcb_free()
3427 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_7; in sctp_inpcb_free()
3430 } else if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { in sctp_inpcb_free()
3461 if ((inp->refcount) || in sctp_inpcb_free()
3463 (inp->sctp_flags & SCTP_PCB_FLAGS_CLOSE_IP)) { in sctp_inpcb_free()
3473 inp->sctp_ep.signature_change.type = 0; in sctp_inpcb_free()
3474 inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_ALLGONE; in sctp_inpcb_free()
3486 if ((inp->sctp_asocidhash) != NULL) { in sctp_inpcb_free()
3487 SCTP_HASH_FREE(inp->sctp_asocidhash, inp->hashasocidmark); in sctp_inpcb_free()
3488 inp->sctp_asocidhash = NULL; in sctp_inpcb_free()
3491 TAILQ_FOREACH_SAFE(sq, &inp->read_queue, next, nsq) { in sctp_inpcb_free()
3493 if (sq->length) in sctp_inpcb_free()
3496 TAILQ_REMOVE(&inp->read_queue, sq, next); in sctp_inpcb_free()
3497 sctp_free_remote_addr(sq->whoFrom); in sctp_inpcb_free()
3499 SCTP_SB_DECR(&so->so_rcv, sq->length); in sctp_inpcb_free()
3500 if (sq->data) { in sctp_inpcb_free()
3501 sctp_m_freem(sq->data); in sctp_inpcb_free()
3502 sq->data = NULL; in sctp_inpcb_free()
3516 if (ip_pcb->inp_options) { in sctp_inpcb_free()
3517 (void)sctp_m_free(ip_pcb->inp_options); in sctp_inpcb_free()
3518 ip_pcb->inp_options = 0; in sctp_inpcb_free()
3521 if (ip_pcb->inp_vflag & INP_IPV6) { in sctp_inpcb_free()
3522 ip6_freepcbopts(ip_pcb->in6p_outputopts); in sctp_inpcb_free()
3525 ip_pcb->inp_vflag = 0; in sctp_inpcb_free()
3527 if (inp->sctp_ep.local_auth_chunks != NULL) in sctp_inpcb_free()
3528 sctp_free_chunklist(inp->sctp_ep.local_auth_chunks); in sctp_inpcb_free()
3529 if (inp->sctp_ep.local_hmacs != NULL) in sctp_inpcb_free()
3530 sctp_free_hmaclist(inp->sctp_ep.local_hmacs); in sctp_inpcb_free()
3532 LIST_FOREACH_SAFE(shared_key, &inp->sctp_ep.shared_keys, next, nshared_key) { in sctp_inpcb_free()
3543 LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) { in sctp_inpcb_free()
3549 LIST_FOREACH_SAFE(stcb, &inp->sctp_asoc_free_list, sctp_tcblist, nstcb) { in sctp_inpcb_free()
3557 if (inp->sctp_tcbhash != NULL) { in sctp_inpcb_free()
3558 SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark); in sctp_inpcb_free()
3559 inp->sctp_tcbhash = NULL; in sctp_inpcb_free()
3562 crfree(inp->ip_inp.inp.inp_cred); in sctp_inpcb_free()
3563 INP_LOCK_DESTROY(&inp->ip_inp.inp); in sctp_inpcb_free()
3577 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { in sctp_findnet()
3578 if (sctp_cmpaddr(addr, (struct sockaddr *)&net->ro._l_addr)) in sctp_findnet()
3598 * add's a remote endpoint address, done with the INIT/INIT-ACK as well as
3630 if (netfirst->dest_state & SCTP_ADDR_UNCONFIRMED) { in sctp_add_remote_addr()
3631 netfirst->dest_state = (SCTP_ADDR_REACHABLE | in sctp_add_remote_addr()
3634 netfirst->dest_state = SCTP_ADDR_REACHABLE; in sctp_add_remote_addr()
3640 switch (newaddr->sa_family) { in sctp_add_remote_addr()
3647 if (sin->sin_addr.s_addr == 0) { in sctp_add_remote_addr()
3649 return (-1); in sctp_add_remote_addr()
3652 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); in sctp_add_remote_addr()
3655 sin->sin_len = sizeof(struct sockaddr_in); in sctp_add_remote_addr()
3657 if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { in sctp_add_remote_addr()
3658 stcb->asoc.scope.ipv4_local_scope = 1; in sctp_add_remote_addr()
3662 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) && in sctp_add_remote_addr()
3663 (stcb->asoc.scope.ipv4_local_scope == 0)) { in sctp_add_remote_addr()
3676 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { in sctp_add_remote_addr()
3678 return (-1); in sctp_add_remote_addr()
3681 sin6->sin6_len = sizeof(struct sockaddr_in6); in sctp_add_remote_addr()
3683 if (sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id)) { in sctp_add_remote_addr()
3684 stcb->asoc.scope.loopback_scope = 1; in sctp_add_remote_addr()
3685 stcb->asoc.scope.local_scope = 0; in sctp_add_remote_addr()
3686 stcb->asoc.scope.ipv4_local_scope = 1; in sctp_add_remote_addr()
3687 stcb->asoc.scope.site_scope = 1; in sctp_add_remote_addr()
3688 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { in sctp_add_remote_addr()
3699 stcb->asoc.scope.ipv4_local_scope = 1; in sctp_add_remote_addr()
3700 stcb->asoc.scope.site_scope = 1; in sctp_add_remote_addr()
3701 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { in sctp_add_remote_addr()
3707 stcb->asoc.scope.site_scope = 1; in sctp_add_remote_addr()
3711 if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) && in sctp_add_remote_addr()
3712 (stcb->asoc.scope.loopback_scope == 0)) { in sctp_add_remote_addr()
3714 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && in sctp_add_remote_addr()
3715 (stcb->asoc.scope.local_scope == 0)) { in sctp_add_remote_addr()
3717 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) && in sctp_add_remote_addr()
3718 (stcb->asoc.scope.site_scope == 0)) { in sctp_add_remote_addr()
3727 return (-1); in sctp_add_remote_addr()
3731 return (-1); in sctp_add_remote_addr()
3735 (void)SCTP_GETTIME_TIMEVAL(&net->start_time); in sctp_add_remote_addr()
3736 memcpy(&net->ro._l_addr, newaddr, newaddr->sa_len); in sctp_add_remote_addr()
3737 switch (newaddr->sa_family) { in sctp_add_remote_addr()
3740 ((struct sockaddr_in *)&net->ro._l_addr)->sin_port = stcb->rport; in sctp_add_remote_addr()
3745 ((struct sockaddr_in6 *)&net->ro._l_addr)->sin6_port = stcb->rport; in sctp_add_remote_addr()
3751 net->addr_is_local = sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id); in sctp_add_remote_addr()
3752 if (net->addr_is_local && ((set_scope || (from == SCTP_ADDR_IS_CONFIRMED)))) { in sctp_add_remote_addr()
3753 stcb->asoc.scope.loopback_scope = 1; in sctp_add_remote_addr()
3754 stcb->asoc.scope.ipv4_local_scope = 1; in sctp_add_remote_addr()
3755 stcb->asoc.scope.local_scope = 0; in sctp_add_remote_addr()
3756 stcb->asoc.scope.site_scope = 1; in sctp_add_remote_addr()
3759 net->failure_threshold = stcb->asoc.def_net_failure; in sctp_add_remote_addr()
3760 net->pf_threshold = stcb->asoc.def_net_pf_threshold; in sctp_add_remote_addr()
3762 net->dest_state = (SCTP_ADDR_REACHABLE | in sctp_add_remote_addr()
3767 net->dest_state = SCTP_ADDR_REACHABLE; in sctp_add_remote_addr()
3769 net->dest_state = SCTP_ADDR_REACHABLE | in sctp_add_remote_addr()
3773 * We set this to 0, the timer code knows that this means its an in sctp_add_remote_addr()
3776 net->rto_needed = 1; in sctp_add_remote_addr()
3777 net->RTO = 0; in sctp_add_remote_addr()
3778 net->RTO_measured = 0; in sctp_add_remote_addr()
3779 stcb->asoc.numnets++; in sctp_add_remote_addr()
3780 net->ref_count = 1; in sctp_add_remote_addr()
3781 net->cwr_window_tsn = net->last_cwr_tsn = stcb->asoc.sending_seq - 1; in sctp_add_remote_addr()
3782 net->port = port; in sctp_add_remote_addr()
3783 net->dscp = stcb->asoc.default_dscp; in sctp_add_remote_addr()
3785 net->flowlabel = stcb->asoc.default_flowlabel; in sctp_add_remote_addr()
3787 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) { in sctp_add_remote_addr()
3788 net->dest_state |= SCTP_ADDR_NOHB; in sctp_add_remote_addr()
3790 net->dest_state &= ~SCTP_ADDR_NOHB; in sctp_add_remote_addr()
3792 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) { in sctp_add_remote_addr()
3793 net->dest_state |= SCTP_ADDR_NO_PMTUD; in sctp_add_remote_addr()
3795 net->dest_state &= ~SCTP_ADDR_NO_PMTUD; in sctp_add_remote_addr()
3797 net->heart_beat_delay = stcb->asoc.heart_beat_delay; in sctp_add_remote_addr()
3798 /* Init the timer structure */ in sctp_add_remote_addr()
3799 SCTP_OS_TIMER_INIT(&net->rxt_timer.timer); in sctp_add_remote_addr()
3800 SCTP_OS_TIMER_INIT(&net->pmtu_timer.timer); in sctp_add_remote_addr()
3801 SCTP_OS_TIMER_INIT(&net->hb_timer.timer); in sctp_add_remote_addr()
3806 if (newaddr->sa_family == AF_INET6) { in sctp_add_remote_addr()
3809 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr; in sctp_add_remote_addr()
3811 sin6->sin6_scope_id = 0; in sctp_add_remote_addr()
3814 SCTP_RTALLOC((sctp_route_t *)&net->ro, in sctp_add_remote_addr()
3815 stcb->asoc.vrf_id, in sctp_add_remote_addr()
3816 stcb->sctp_ep->fibnum); in sctp_add_remote_addr()
3818 net->src_addr_selected = 0; in sctp_add_remote_addr()
3819 if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) { in sctp_add_remote_addr()
3821 net->ro._s_addr = sctp_source_address_selection(stcb->sctp_ep, in sctp_add_remote_addr()
3823 (sctp_route_t *)&net->ro, in sctp_add_remote_addr()
3826 stcb->asoc.vrf_id); in sctp_add_remote_addr()
3827 if (stcb->asoc.default_mtu > 0) { in sctp_add_remote_addr()
3828 net->mtu = stcb->asoc.default_mtu; in sctp_add_remote_addr()
3829 switch (net->ro._l_addr.sa.sa_family) { in sctp_add_remote_addr()
3832 net->mtu += SCTP_MIN_V4_OVERHEAD; in sctp_add_remote_addr()
3837 net->mtu += SCTP_MIN_OVERHEAD; in sctp_add_remote_addr()
3844 if (net->port) { in sctp_add_remote_addr()
3845 net->mtu += (uint32_t)sizeof(struct udphdr); in sctp_add_remote_addr()
3848 } else if (net->ro._s_addr != NULL) { in sctp_add_remote_addr()
3851 net->src_addr_selected = 1; in sctp_add_remote_addr()
3853 if (net->ro._s_addr->ifn_p != NULL) { in sctp_add_remote_addr()
3856 * net->ro._s_addr->ifn_p->ifn_mtu in sctp_add_remote_addr()
3858 imtu = SCTP_GATHER_MTU_FROM_IFN_INFO(net->ro._s_addr->ifn_p->ifn_p, in sctp_add_remote_addr()
3859 net->ro._s_addr->ifn_p->ifn_index); in sctp_add_remote_addr()
3863 rmtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, net->ro.ro_nh); in sctp_add_remote_addr()
3864 hcmtu = sctp_hc_get_mtu(&net->ro._l_addr, stcb->sctp_ep->fibnum); in sctp_add_remote_addr()
3865 net->mtu = sctp_min_mtu(hcmtu, rmtu, imtu); in sctp_add_remote_addr()
3868 if (net->mtu == 0) { in sctp_add_remote_addr()
3869 if (stcb->asoc.default_mtu > 0) { in sctp_add_remote_addr()
3870 net->mtu = stcb->asoc.default_mtu; in sctp_add_remote_addr()
3871 switch (net->ro._l_addr.sa.sa_family) { in sctp_add_remote_addr()
3874 net->mtu += SCTP_MIN_V4_OVERHEAD; in sctp_add_remote_addr()
3879 net->mtu += SCTP_MIN_OVERHEAD; in sctp_add_remote_addr()
3886 if (net->port) { in sctp_add_remote_addr()
3887 net->mtu += (uint32_t)sizeof(struct udphdr); in sctp_add_remote_addr()
3891 switch (newaddr->sa_family) { in sctp_add_remote_addr()
3894 net->mtu = SCTP_DEFAULT_MTU; in sctp_add_remote_addr()
3899 net->mtu = 1280; in sctp_add_remote_addr()
3908 if (net->port) { in sctp_add_remote_addr()
3909 net->mtu -= (uint32_t)sizeof(struct udphdr); in sctp_add_remote_addr()
3913 stcb->asoc.smallest_mtu = net->mtu; in sctp_add_remote_addr()
3915 if (stcb->asoc.smallest_mtu > net->mtu) { in sctp_add_remote_addr()
3916 sctp_pathmtu_adjustment(stcb, net->mtu, true); in sctp_add_remote_addr()
3919 if (newaddr->sa_family == AF_INET6) { in sctp_add_remote_addr()
3922 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr; in sctp_add_remote_addr()
3927 /* JRS - Use the congestion control given in the CC module */ in sctp_add_remote_addr()
3928 if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL) in sctp_add_remote_addr()
3929 (*stcb->asoc.cc_functions.sctp_set_initial_cc_param) (stcb, net); in sctp_add_remote_addr()
3932 * CMT: CUC algo - set find_pseudo_cumack to TRUE (1) at beginning in sctp_add_remote_addr()
3935 net->find_pseudo_cumack = 1; in sctp_add_remote_addr()
3936 net->find_rtx_pseudo_cumack = 1; in sctp_add_remote_addr()
3938 net->flowid = stcb->asoc.my_vtag ^ in sctp_add_remote_addr()
3939 ntohs(stcb->rport) ^ in sctp_add_remote_addr()
3940 ntohs(stcb->sctp_ep->sctp_lport); in sctp_add_remote_addr()
3941 net->flowtype = M_HASHTYPE_OPAQUE_HASH; in sctp_add_remote_addr()
3945 netfirst = TAILQ_FIRST(&stcb->asoc.nets); in sctp_add_remote_addr()
3946 if (net->ro.ro_nh == NULL) { in sctp_add_remote_addr()
3948 TAILQ_INSERT_TAIL(&stcb->asoc.nets, net, sctp_next); in sctp_add_remote_addr()
3951 TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next); in sctp_add_remote_addr()
3952 } else if (netfirst->ro.ro_nh == NULL) { in sctp_add_remote_addr()
3957 TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next); in sctp_add_remote_addr()
3958 } else if (net->ro.ro_nh->nh_ifp != netfirst->ro.ro_nh->nh_ifp) { in sctp_add_remote_addr()
3963 TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next); in sctp_add_remote_addr()
3977 TAILQ_INSERT_TAIL(&stcb->asoc.nets, net, sctp_next); in sctp_add_remote_addr()
3979 } else if (netlook->ro.ro_nh == NULL) { in sctp_add_remote_addr()
3983 } else if (netlook->ro.ro_nh->nh_ifp != net->ro.ro_nh->nh_ifp) { in sctp_add_remote_addr()
3984 TAILQ_INSERT_AFTER(&stcb->asoc.nets, netlook, in sctp_add_remote_addr()
3994 if (stcb->asoc.primary_destination == 0) { in sctp_add_remote_addr()
3995 stcb->asoc.primary_destination = net; in sctp_add_remote_addr()
3996 } else if ((stcb->asoc.primary_destination->ro.ro_nh == NULL) && in sctp_add_remote_addr()
3997 (net->ro.ro_nh) && in sctp_add_remote_addr()
3998 ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0)) { in sctp_add_remote_addr()
4000 stcb->asoc.primary_destination = net; in sctp_add_remote_addr()
4003 net = TAILQ_FIRST(&stcb->asoc.nets); in sctp_add_remote_addr()
4004 if ((net != stcb->asoc.primary_destination) && in sctp_add_remote_addr()
4005 (stcb->asoc.primary_destination)) { in sctp_add_remote_addr()
4011 TAILQ_REMOVE(&stcb->asoc.nets, in sctp_add_remote_addr()
4012 stcb->asoc.primary_destination, sctp_next); in sctp_add_remote_addr()
4013 TAILQ_INSERT_HEAD(&stcb->asoc.nets, in sctp_add_remote_addr()
4014 stcb->asoc.primary_destination, sctp_next); in sctp_add_remote_addr()
4027 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { in sctp_aloc_a_assoc_id()
4035 if (inp->sctp_associd_counter <= SCTP_ALL_ASSOC) { in sctp_aloc_a_assoc_id()
4036 inp->sctp_associd_counter = SCTP_ALL_ASSOC + 1; in sctp_aloc_a_assoc_id()
4038 id = inp->sctp_associd_counter; in sctp_aloc_a_assoc_id()
4039 inp->sctp_associd_counter++; in sctp_aloc_a_assoc_id()
4044 head = &inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(id, inp->hashasocidmark)]; in sctp_aloc_a_assoc_id()
4046 stcb->asoc.in_asocid_hash = 1; in sctp_aloc_a_assoc_id()
4089 if (inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_SOCKET_ALLGONE)) { in sctp_aloc_assoc_locked()
4094 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) && in sctp_aloc_assoc_locked()
4096 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) { in sctp_aloc_assoc_locked()
4100 * sctp_aloc_assoc.. or the one-2-many socket. If a peeled in sctp_aloc_assoc_locked()
4107 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || in sctp_aloc_assoc_locked()
4108 (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)) { in sctp_aloc_assoc_locked()
4109 if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) || in sctp_aloc_assoc_locked()
4110 (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED)) { in sctp_aloc_assoc_locked()
4120 switch (firstaddr->sa_family) { in sctp_aloc_assoc_locked()
4124 ntohs(((struct sockaddr_in *)firstaddr)->sin_port)); in sctp_aloc_assoc_locked()
4130 ntohs(((struct sockaddr_in6 *)firstaddr)->sin6_port)); in sctp_aloc_assoc_locked()
4140 switch (firstaddr->sa_family) { in sctp_aloc_assoc_locked()
4147 if ((ntohs(sin->sin_port) == 0) || in sctp_aloc_assoc_locked()
4148 in_broadcast(sin->sin_addr) || in sctp_aloc_assoc_locked()
4149 IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) || in sctp_aloc_assoc_locked()
4150 ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && in sctp_aloc_assoc_locked()
4157 rport = sin->sin_port; in sctp_aloc_assoc_locked()
4167 if ((ntohs(sin6->sin6_port) == 0) || in sctp_aloc_assoc_locked()
4168 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) || in sctp_aloc_assoc_locked()
4169 IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) || in sctp_aloc_assoc_locked()
4170 ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0)) { in sctp_aloc_assoc_locked()
4176 rport = sin6->sin6_port; in sctp_aloc_assoc_locked()
4186 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) { in sctp_aloc_assoc_locked()
4207 asoc = &stcb->asoc; in sctp_aloc_assoc_locked()
4210 stcb->rport = rport; in sctp_aloc_assoc_locked()
4212 stcb->sctp_ep = inp; in sctp_aloc_assoc_locked()
4213 stcb->sctp_socket = inp->sctp_socket; in sctp_aloc_assoc_locked()
4224 asoc->assoc_id = sctp_aloc_a_assoc_id(inp, stcb); in sctp_aloc_assoc_locked()
4226 …head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashaso… in sctp_aloc_assoc_locked()
4232 if (asoc->strmout) { in sctp_aloc_assoc_locked()
4233 SCTP_FREE(asoc->strmout, SCTP_M_STRMO); in sctp_aloc_assoc_locked()
4234 asoc->strmout = NULL; in sctp_aloc_assoc_locked()
4236 if (asoc->mapping_array) { in sctp_aloc_assoc_locked()
4237 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP); in sctp_aloc_assoc_locked()
4238 asoc->mapping_array = NULL; in sctp_aloc_assoc_locked()
4240 if (asoc->nr_mapping_array) { in sctp_aloc_assoc_locked()
4241 SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP); in sctp_aloc_assoc_locked()
4242 asoc->nr_mapping_array = NULL; in sctp_aloc_assoc_locked()
4255 SCTP_OS_TIMER_INIT(&asoc->dack_timer.timer); in sctp_aloc_assoc_locked()
4256 SCTP_OS_TIMER_INIT(&asoc->strreset_timer.timer); in sctp_aloc_assoc_locked()
4257 SCTP_OS_TIMER_INIT(&asoc->asconf_timer.timer); in sctp_aloc_assoc_locked()
4258 SCTP_OS_TIMER_INIT(&asoc->shut_guard_timer.timer); in sctp_aloc_assoc_locked()
4259 SCTP_OS_TIMER_INIT(&asoc->autoclose_timer.timer); in sctp_aloc_assoc_locked()
4260 SCTP_OS_TIMER_INIT(&asoc->delete_prim_timer.timer); in sctp_aloc_assoc_locked()
4262 LIST_INSERT_HEAD(&inp->sctp_asoc_list, stcb, sctp_tcblist); in sctp_aloc_assoc_locked()
4264 if (inp->sctp_tcbhash != NULL) { in sctp_aloc_assoc_locked()
4265 head = &inp->sctp_tcbhash[SCTP_PCBHASH_ALLADDR(stcb->rport, in sctp_aloc_assoc_locked()
4266 inp->sctp_hashmark)]; in sctp_aloc_assoc_locked()
4305 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && in sctp_aloc_assoc_connected()
4315 if (stcb != NULL && (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)) { in sctp_aloc_assoc_connected()
4316 inp->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; in sctp_aloc_assoc_connected()
4317 soisconnecting(inp->sctp_socket); in sctp_aloc_assoc_connected()
4329 inp = stcb->sctp_ep; in sctp_remove_net()
4330 asoc = &stcb->asoc; in sctp_remove_net()
4331 asoc->numnets--; in sctp_remove_net()
4332 TAILQ_REMOVE(&asoc->nets, net, sctp_next); in sctp_remove_net()
4333 if (net == asoc->primary_destination) { in sctp_remove_net()
4337 lnet = TAILQ_FIRST(&asoc->nets); in sctp_remove_net()
4343 if (sctp_is_mobility_feature_on(stcb->sctp_ep, in sctp_remove_net()
4345 sctp_is_mobility_feature_on(stcb->sctp_ep, in sctp_remove_net()
4348 if (asoc->deleted_primary != NULL) { in sctp_remove_net()
4352 asoc->deleted_primary = net; in sctp_remove_net()
4353 atomic_add_int(&net->ref_count, 1); in sctp_remove_net()
4354 memset(&net->lastsa, 0, sizeof(net->lastsa)); in sctp_remove_net()
4355 memset(&net->lastsv, 0, sizeof(net->lastsv)); in sctp_remove_net()
4356 sctp_mobility_feature_on(stcb->sctp_ep, in sctp_remove_net()
4359 stcb->sctp_ep, stcb, NULL); in sctp_remove_net()
4363 asoc->primary_destination = sctp_find_alternate_net(stcb, lnet, 0); in sctp_remove_net()
4365 if (net == asoc->last_data_chunk_from) { in sctp_remove_net()
4367 asoc->last_data_chunk_from = TAILQ_FIRST(&asoc->nets); in sctp_remove_net()
4369 if (net == asoc->last_control_chunk_from) { in sctp_remove_net()
4371 asoc->last_control_chunk_from = NULL; in sctp_remove_net()
4373 if (net == asoc->last_net_cmt_send_started) { in sctp_remove_net()
4375 asoc->last_net_cmt_send_started = NULL; in sctp_remove_net()
4377 if (net == stcb->asoc.alternate) { in sctp_remove_net()
4378 sctp_free_remote_addr(stcb->asoc.alternate); in sctp_remove_net()
4379 stcb->asoc.alternate = NULL; in sctp_remove_net()
4385 net->dest_state |= SCTP_ADDR_BEING_DELETED; in sctp_remove_net()
4399 * (tasoc->asoc.nets) and then if it is there, we do a LIST_REMOVE in sctp_del_remote_addr()
4406 asoc = &stcb->asoc; in sctp_del_remote_addr()
4409 TAILQ_FOREACH_SAFE(net, &asoc->nets, sctp_next, nnet) { in sctp_del_remote_addr()
4410 if (net->ro._l_addr.sa.sa_family != remaddr->sa_family) { in sctp_del_remote_addr()
4413 if (sctp_cmpaddr((struct sockaddr *)&net->ro._l_addr, in sctp_del_remote_addr()
4416 if (asoc->numnets < 2) { in sctp_del_remote_addr()
4418 return (-1); in sctp_del_remote_addr()
4426 return (-2); in sctp_del_remote_addr()
4440 if ((twait_block->vtag_block[i].tv_sec_at_expire >= now) && in sctp_is_in_timewait()
4441 (twait_block->vtag_block[i].v_tag == tag) && in sctp_is_in_timewait()
4442 (twait_block->vtag_block[i].lport == lport) && in sctp_is_in_timewait()
4443 (twait_block->vtag_block[i].rport == rport)) { in sctp_is_in_timewait()
4455 vtag_block->tv_sec_at_expire = time; in sctp_set_vtag_block()
4456 vtag_block->v_tag = tag; in sctp_set_vtag_block()
4457 vtag_block->lport = lport; in sctp_set_vtag_block()
4458 vtag_block->rport = rport; in sctp_set_vtag_block()
4479 if ((twait_block->vtag_block[i].v_tag == 0) && !set) { in sctp_add_vtag_to_timewait()
4480 sctp_set_vtag_block(twait_block->vtag_block + i, time, tag, lport, rport); in sctp_add_vtag_to_timewait()
4484 if ((twait_block->vtag_block[i].v_tag != 0) && in sctp_add_vtag_to_timewait()
4485 (twait_block->vtag_block[i].tv_sec_at_expire < now.tv_sec)) { in sctp_add_vtag_to_timewait()
4488 sctp_set_vtag_block(twait_block->vtag_block + i, 0, 0, 0, 0); in sctp_add_vtag_to_timewait()
4491 sctp_set_vtag_block(twait_block->vtag_block + i, time, tag, lport, rport); in sctp_add_vtag_to_timewait()
4513 sctp_set_vtag_block(twait_block->vtag_block, time, tag, lport, rport); in sctp_add_vtag_to_timewait()
4525 control->on_strm_q = 0; in sctp_clean_up_stream()
4526 if (control->on_read_q == 0) { in sctp_clean_up_stream()
4527 sctp_free_remote_addr(control->whoFrom); in sctp_clean_up_stream()
4528 if (control->data) { in sctp_clean_up_stream()
4529 sctp_m_freem(control->data); in sctp_clean_up_stream()
4530 control->data = NULL; in sctp_clean_up_stream()
4534 TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, nchk) { in sctp_clean_up_stream()
4535 TAILQ_REMOVE(&control->reasm, chk, sctp_next); in sctp_clean_up_stream()
4536 if (chk->data) { in sctp_clean_up_stream()
4537 sctp_m_freem(chk->data); in sctp_clean_up_stream()
4538 chk->data = NULL; in sctp_clean_up_stream()
4540 if (chk->holds_key_ref) in sctp_clean_up_stream()
4541 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED); in sctp_clean_up_stream()
4542 sctp_free_remote_addr(chk->whoTo); in sctp_clean_up_stream()
4551 if (control->on_read_q == 0) { in sctp_clean_up_stream()
4557 /*-
4558 * Free the association after un-hashing the remote port. This
4562 * it unlocks it. It will return NON-zero if it either destroyed the
4587 if (stcb->asoc.state == 0) { in sctp_free_assoc()
4591 /* there is no asoc, really TSNH :-0 */ in sctp_free_assoc()
4594 if (stcb->asoc.alternate) { in sctp_free_assoc()
4595 sctp_free_remote_addr(stcb->asoc.alternate); in sctp_free_assoc()
4596 stcb->asoc.alternate = NULL; in sctp_free_assoc()
4599 if (stcb->freed_from_where == 0) { in sctp_free_assoc()
4601 stcb->freed_from_where = from_location; in sctp_free_assoc()
4605 asoc = &stcb->asoc; in sctp_free_assoc()
4606 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || in sctp_free_assoc()
4607 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) in sctp_free_assoc()
4611 so = inp->sctp_socket; in sctp_free_assoc()
4614 * We used timer based freeing if a reader or writer is in the way. in sctp_free_assoc()
4615 * So we first check if we are actually being called from a timer, in sctp_free_assoc()
4618 if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) && in sctp_free_assoc()
4621 * is it the timer driving us? if so are the reader/writers in sctp_free_assoc()
4624 if (stcb->asoc.refcnt) { in sctp_free_assoc()
4638 if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0) { in sctp_free_assoc()
4641 TAILQ_FOREACH(sq, &inp->read_queue, next) { in sctp_free_assoc()
4642 if (sq->stcb == stcb) { in sctp_free_assoc()
4643 sq->do_not_ref_stcb = 1; in sctp_free_assoc()
4644 sq->sinfo_cumtsn = stcb->asoc.cumulative_tsn; in sctp_free_assoc()
4649 if (sq->end_added == 0) { in sctp_free_assoc()
4650 /* Held for PD-API, clear that. */ in sctp_free_assoc()
4651 sq->pdapi_aborted = 1; in sctp_free_assoc()
4652 sq->held_length = 0; in sctp_free_assoc()
4660 /* Add an end to wake them */ in sctp_free_assoc()
4661 sq->end_added = 1; in sctp_free_assoc()
4666 if (stcb->block_entry) { in sctp_free_assoc()
4668 stcb->block_entry->error = ECONNRESET; in sctp_free_assoc()
4669 stcb->block_entry = NULL; in sctp_free_assoc()
4672 if ((stcb->asoc.refcnt) || (stcb->asoc.state & SCTP_STATE_IN_ACCEPT_QUEUE)) { in sctp_free_assoc()
4677 if ((stcb->asoc.refcnt) || in sctp_free_assoc()
4678 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || in sctp_free_assoc()
4679 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { in sctp_free_assoc()
4683 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || in sctp_free_assoc()
4684 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) in sctp_free_assoc()
4688 /* Wake any reader/writers */ in sctp_free_assoc()
4708 * timer and blow out above thus assuring us that we hold exclusive in sctp_free_assoc()
4711 * timer a passing stranger may have started :-S in sctp_free_assoc()
4714 atomic_add_int(&stcb->asoc.refcnt, 1); in sctp_free_assoc()
4722 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || in sctp_free_assoc()
4723 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) in sctp_free_assoc()
4727 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || in sctp_free_assoc()
4728 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { in sctp_free_assoc()
4733 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { in sctp_free_assoc()
4734 inp->sctp_flags &= ~SCTP_PCB_FLAGS_CONNECTED; in sctp_free_assoc()
4735 inp->sctp_flags |= SCTP_PCB_FLAGS_WAS_CONNECTED; in sctp_free_assoc()
4737 SOCKBUF_LOCK(&so->so_rcv); in sctp_free_assoc()
4738 so->so_state &= ~(SS_ISCONNECTING | in sctp_free_assoc()
4741 so->so_state |= SS_ISDISCONNECTED; in sctp_free_assoc()
4755 /* re-increment the lock */ in sctp_free_assoc()
4757 atomic_subtract_int(&stcb->asoc.refcnt, 1); in sctp_free_assoc()
4759 if (stcb->asoc.refcnt) { in sctp_free_assoc()
4769 asoc->state = 0; in sctp_free_assoc()
4770 if (inp->sctp_tcbhash) { in sctp_free_assoc()
4773 if (stcb->asoc.in_asocid_hash) { in sctp_free_assoc()
4776 if (inp->sctp_socket == NULL) { in sctp_free_assoc()
4777 stcb->sctp_socket = NULL; in sctp_free_assoc()
4787 sctp_add_vtag_to_timewait(asoc->my_vtag, inp->sctp_lport, stcb->rport); in sctp_free_assoc()
4799 for (i = 0; i < asoc->streamoutcnt; i++) { in sctp_free_assoc()
4802 outs = &asoc->strmout[i]; in sctp_free_assoc()
4804 TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) { in sctp_free_assoc()
4805 atomic_subtract_int(&asoc->stream_queue_cnt, 1); in sctp_free_assoc()
4806 TAILQ_REMOVE(&outs->outqueue, sp, next); in sctp_free_assoc()
4807 stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, outs, sp); in sctp_free_assoc()
4809 if (sp->data) { in sctp_free_assoc()
4811 /* Still an open socket - report */ in sctp_free_assoc()
4815 if (sp->data) { in sctp_free_assoc()
4816 sctp_m_freem(sp->data); in sctp_free_assoc()
4817 sp->data = NULL; in sctp_free_assoc()
4818 sp->tail_mbuf = NULL; in sctp_free_assoc()
4819 sp->length = 0; in sctp_free_assoc()
4822 if (sp->net) { in sctp_free_assoc()
4823 sctp_free_remote_addr(sp->net); in sctp_free_assoc()
4824 sp->net = NULL; in sctp_free_assoc()
4830 TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) { in sctp_free_assoc()
4831 TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp); in sctp_free_assoc()
4834 TAILQ_FOREACH_SAFE(sq, &asoc->pending_reply_queue, next, nsq) { in sctp_free_assoc()
4835 TAILQ_REMOVE(&asoc->pending_reply_queue, sq, next); in sctp_free_assoc()
4836 if (sq->data) { in sctp_free_assoc()
4837 sctp_m_freem(sq->data); in sctp_free_assoc()
4838 sq->data = NULL; in sctp_free_assoc()
4840 sctp_free_remote_addr(sq->whoFrom); in sctp_free_assoc()
4841 sq->whoFrom = NULL; in sctp_free_assoc()
4842 sq->stcb = NULL; in sctp_free_assoc()
4847 TAILQ_FOREACH_SAFE(chk, &asoc->free_chunks, sctp_next, nchk) { in sctp_free_assoc()
4848 TAILQ_REMOVE(&asoc->free_chunks, chk, sctp_next); in sctp_free_assoc()
4849 if (chk->data) { in sctp_free_assoc()
4850 sctp_m_freem(chk->data); in sctp_free_assoc()
4851 chk->data = NULL; in sctp_free_assoc()
4853 if (chk->holds_key_ref) in sctp_free_assoc()
4854 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED); in sctp_free_assoc()
4858 asoc->free_chunk_cnt--; in sctp_free_assoc()
4862 TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) { in sctp_free_assoc()
4863 if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) { in sctp_free_assoc()
4864 asoc->strmout[chk->rec.data.sid].chunks_on_queues--; in sctp_free_assoc()
4867 panic("No chunks on the queues for sid %u.", chk->rec.data.sid); in sctp_free_assoc()
4870 TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next); in sctp_free_assoc()
4871 if (chk->data) { in sctp_free_assoc()
4877 if (chk->data) { in sctp_free_assoc()
4878 sctp_m_freem(chk->data); in sctp_free_assoc()
4879 chk->data = NULL; in sctp_free_assoc()
4882 if (chk->holds_key_ref) in sctp_free_assoc()
4883 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED); in sctp_free_assoc()
4884 if (chk->whoTo) { in sctp_free_assoc()
4885 sctp_free_remote_addr(chk->whoTo); in sctp_free_assoc()
4886 chk->whoTo = NULL; in sctp_free_assoc()
4893 TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) { in sctp_free_assoc()
4894 if (chk->sent != SCTP_DATAGRAM_NR_ACKED) { in sctp_free_assoc()
4895 if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) { in sctp_free_assoc()
4896 asoc->strmout[chk->rec.data.sid].chunks_on_queues--; in sctp_free_assoc()
4899 panic("No chunks on the queues for sid %u.", chk->rec.data.sid); in sctp_free_assoc()
4903 TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); in sctp_free_assoc()
4904 if (chk->data) { in sctp_free_assoc()
4910 if (chk->data) { in sctp_free_assoc()
4911 sctp_m_freem(chk->data); in sctp_free_assoc()
4912 chk->data = NULL; in sctp_free_assoc()
4915 if (chk->holds_key_ref) in sctp_free_assoc()
4916 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED); in sctp_free_assoc()
4917 sctp_free_remote_addr(chk->whoTo); in sctp_free_assoc()
4923 for (i = 0; i < stcb->asoc.streamoutcnt; i++) { in sctp_free_assoc()
4924 if (stcb->asoc.strmout[i].chunks_on_queues > 0) { in sctp_free_assoc()
4925 panic("%u chunks left for stream %u.", stcb->asoc.strmout[i].chunks_on_queues, i); in sctp_free_assoc()
4930 TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) { in sctp_free_assoc()
4931 TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); in sctp_free_assoc()
4932 if (chk->data) { in sctp_free_assoc()
4933 sctp_m_freem(chk->data); in sctp_free_assoc()
4934 chk->data = NULL; in sctp_free_assoc()
4936 if (chk->holds_key_ref) in sctp_free_assoc()
4937 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED); in sctp_free_assoc()
4938 sctp_free_remote_addr(chk->whoTo); in sctp_free_assoc()
4944 TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) { in sctp_free_assoc()
4945 TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next); in sctp_free_assoc()
4946 if (chk->data) { in sctp_free_assoc()
4947 sctp_m_freem(chk->data); in sctp_free_assoc()
4948 chk->data = NULL; in sctp_free_assoc()
4950 if (chk->holds_key_ref) in sctp_free_assoc()
4951 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED); in sctp_free_assoc()
4952 sctp_free_remote_addr(chk->whoTo); in sctp_free_assoc()
4957 if (asoc->mapping_array) { in sctp_free_assoc()
4958 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP); in sctp_free_assoc()
4959 asoc->mapping_array = NULL; in sctp_free_assoc()
4961 if (asoc->nr_mapping_array) { in sctp_free_assoc()
4962 SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP); in sctp_free_assoc()
4963 asoc->nr_mapping_array = NULL; in sctp_free_assoc()
4966 if (asoc->strmout) { in sctp_free_assoc()
4967 SCTP_FREE(asoc->strmout, SCTP_M_STRMO); in sctp_free_assoc()
4968 asoc->strmout = NULL; in sctp_free_assoc()
4970 asoc->strm_realoutsize = asoc->streamoutcnt = 0; in sctp_free_assoc()
4971 if (asoc->strmin) { in sctp_free_assoc()
4972 for (i = 0; i < asoc->streamincnt; i++) { in sctp_free_assoc()
4973 sctp_clean_up_stream(stcb, &asoc->strmin[i].inqueue); in sctp_free_assoc()
4974 sctp_clean_up_stream(stcb, &asoc->strmin[i].uno_inqueue); in sctp_free_assoc()
4976 SCTP_FREE(asoc->strmin, SCTP_M_STRMI); in sctp_free_assoc()
4977 asoc->strmin = NULL; in sctp_free_assoc()
4979 asoc->streamincnt = 0; in sctp_free_assoc()
4980 TAILQ_FOREACH_SAFE(net, &asoc->nets, sctp_next, nnet) { in sctp_free_assoc()
4986 TAILQ_REMOVE(&asoc->nets, net, sctp_next); in sctp_free_assoc()
4989 LIST_FOREACH_SAFE(laddr, &asoc->sctp_restricted_addrs, sctp_nxt_addr, naddr) { in sctp_free_assoc()
4995 TAILQ_FOREACH_SAFE(aparam, &asoc->asconf_queue, next, naparam) { in sctp_free_assoc()
4997 TAILQ_REMOVE(&asoc->asconf_queue, aparam, next); in sctp_free_assoc()
5000 TAILQ_FOREACH_SAFE(aack, &asoc->asconf_ack_sent, next, naack) { in sctp_free_assoc()
5002 TAILQ_REMOVE(&asoc->asconf_ack_sent, aack, next); in sctp_free_assoc()
5003 if (aack->data != NULL) { in sctp_free_assoc()
5004 sctp_m_freem(aack->data); in sctp_free_assoc()
5009 if (asoc->local_hmacs) in sctp_free_assoc()
5010 sctp_free_hmaclist(asoc->local_hmacs); in sctp_free_assoc()
5011 if (asoc->peer_hmacs) in sctp_free_assoc()
5012 sctp_free_hmaclist(asoc->peer_hmacs); in sctp_free_assoc()
5014 if (asoc->local_auth_chunks) in sctp_free_assoc()
5015 sctp_free_chunklist(asoc->local_auth_chunks); in sctp_free_assoc()
5016 if (asoc->peer_auth_chunks) in sctp_free_assoc()
5017 sctp_free_chunklist(asoc->peer_auth_chunks); in sctp_free_assoc()
5019 sctp_free_authinfo(&asoc->authinfo); in sctp_free_assoc()
5021 LIST_FOREACH_SAFE(shared_key, &asoc->shared_keys, next, nshared_key) { in sctp_free_assoc()
5037 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { in sctp_free_assoc()
5042 LIST_INSERT_HEAD(&inp->sctp_asoc_free_list, stcb, sctp_tcblist); in sctp_free_assoc()
5049 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { in sctp_free_assoc()
5056 * This will start the kill timer (if we are the in sctp_free_assoc()
5084 * FIX: if we allow assoc-level bindx(), then this needs to be fixed to use
5100 * only want to read the sctp_flags, which is either bound-all or in sctp_destination_is_reachable()
5104 inp = stcb->sctp_ep; in sctp_destination_is_reachable()
5105 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { in sctp_destination_is_reachable()
5109 * are bound-all you still might need to obey the V4--V6 in sctp_destination_is_reachable()
5110 * flags??? IMO this bound-all stuff needs to be removed! in sctp_destination_is_reachable()
5115 switch (destaddr->sa_family) { in sctp_destination_is_reachable()
5118 answer = inp->ip_inp.inp.inp_vflag & INP_IPV6; in sctp_destination_is_reachable()
5123 answer = inp->ip_inp.inp.inp_vflag & INP_IPV4; in sctp_destination_is_reachable()
5143 inp->ip_inp.inp.inp_vflag = 0; in sctp_update_ep_vflag()
5145 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { in sctp_update_ep_vflag()
5146 if (laddr->ifa == NULL) { in sctp_update_ep_vflag()
5152 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) { in sctp_update_ep_vflag()
5155 switch (laddr->ifa->address.sa.sa_family) { in sctp_update_ep_vflag()
5158 inp->ip_inp.inp.inp_vflag |= INP_IPV6; in sctp_update_ep_vflag()
5163 inp->ip_inp.inp.inp_vflag |= INP_IPV4; in sctp_update_ep_vflag()
5185 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { in sctp_add_local_addr_ep()
5190 if (ifa->address.sa.sa_family == AF_INET6) { in sctp_add_local_addr_ep()
5191 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) { in sctp_add_local_addr_ep()
5192 /* Can't bind a non-useable addr. */ in sctp_add_local_addr_ep()
5198 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { in sctp_add_local_addr_ep()
5199 if (laddr->ifa == ifa) { in sctp_add_local_addr_ep()
5207 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, action); in sctp_add_local_addr_ep()
5210 inp->laddr_count++; in sctp_add_local_addr_ep()
5212 switch (ifa->address.sa.sa_family) { in sctp_add_local_addr_ep()
5215 inp->ip_inp.inp.inp_vflag |= INP_IPV6; in sctp_add_local_addr_ep()
5220 inp->ip_inp.inp.inp_vflag |= INP_IPV4; in sctp_add_local_addr_ep()
5226 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { in sctp_add_local_addr_ep()
5243 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { in sctp_select_primary_destination()
5245 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) in sctp_select_primary_destination()
5248 (struct sockaddr *)&net->ro._l_addr)) { in sctp_select_primary_destination()
5250 stcb->asoc.primary_destination = net; in sctp_select_primary_destination()
5267 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { in sctp_del_local_addr_ep()
5271 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { in sctp_del_local_addr_ep()
5272 if (laddr->ifa == ifa) { in sctp_del_local_addr_ep()
5277 if (fnd && (inp->laddr_count < 2)) { in sctp_del_local_addr_ep()
5291 if (inp->next_addr_touse == laddr) in sctp_del_local_addr_ep()
5293 inp->next_addr_touse = NULL; in sctp_del_local_addr_ep()
5296 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { in sctp_del_local_addr_ep()
5300 if (stcb->asoc.last_used_address == laddr) in sctp_del_local_addr_ep()
5302 stcb->asoc.last_used_address = NULL; in sctp_del_local_addr_ep()
5307 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { in sctp_del_local_addr_ep()
5308 if (net->ro._s_addr == laddr->ifa) { in sctp_del_local_addr_ep()
5310 RO_NHFREE(&net->ro); in sctp_del_local_addr_ep()
5311 sctp_free_ifa(net->ro._s_addr); in sctp_del_local_addr_ep()
5312 net->ro._s_addr = NULL; in sctp_del_local_addr_ep()
5313 net->src_addr_selected = 0; in sctp_del_local_addr_ep()
5320 inp->laddr_count--; in sctp_del_local_addr_ep()
5330 * ASCONF-ACK response) and cannot be used as a valid source address.
5342 list = &stcb->asoc.sctp_restricted_addrs; in sctp_add_local_addr_restricted()
5345 if (ifa->address.sa.sa_family == AF_INET6) { in sctp_add_local_addr_restricted()
5346 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) { in sctp_add_local_addr_restricted()
5347 /* Can't bind a non-existent addr. */ in sctp_add_local_addr_restricted()
5354 if (laddr->ifa == ifa) { in sctp_add_local_addr_restricted()
5380 * up is changing :-D in sctp_del_local_addr_restricted()
5383 inp = stcb->sctp_ep; in sctp_del_local_addr_restricted()
5385 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) && in sctp_del_local_addr_restricted()
5387 if (stcb->sctp_ep->laddr_count < 2) { in sctp_del_local_addr_restricted()
5392 LIST_FOREACH(laddr, &stcb->asoc.sctp_restricted_addrs, sctp_nxt_addr) { in sctp_del_local_addr_restricted()
5394 if (laddr->ifa == NULL) in sctp_del_local_addr_restricted()
5396 if (laddr->ifa == ifa) { in sctp_del_local_addr_restricted()
5435 qent->vn = curvnet; in sctp_queue_to_mcore()
5436 qent->m = m; in sctp_queue_to_mcore()
5437 qent->off = off; in sctp_queue_to_mcore()
5438 qent->v6 = 0; in sctp_queue_to_mcore()
5442 TAILQ_INSERT_TAIL(&wkq->que, qent, next); in sctp_queue_to_mcore()
5443 if (wkq->running == 0) { in sctp_queue_to_mcore()
5448 wakeup(&wkq->running); in sctp_queue_to_mcore()
5465 wkq->running = 0; in sctp_mcore_thread()
5466 msleep(&wkq->running, in sctp_mcore_thread()
5467 &wkq->core_mtx, in sctp_mcore_thread()
5471 /* Bind to our cpu */ in sctp_mcore_thread()
5473 sched_bind(curthread, wkq->cpuid); in sctp_mcore_thread()
5482 wkq->running = 1; in sctp_mcore_thread()
5483 qent = TAILQ_FIRST(&wkq->que); in sctp_mcore_thread()
5485 TAILQ_REMOVE(&wkq->que, qent, next); in sctp_mcore_thread()
5487 CURVNET_SET(qent->vn); in sctp_mcore_thread()
5488 m = qent->m; in sctp_mcore_thread()
5489 off = qent->off; in sctp_mcore_thread()
5490 v6 = qent->v6; in sctp_mcore_thread()
5501 wkq->running = 0; in sctp_mcore_thread()
5502 if (!TAILQ_EMPTY(&wkq->que)) { in sctp_mcore_thread()
5506 msleep(&wkq->running, in sctp_mcore_thread()
5507 &wkq->core_mtx, in sctp_mcore_thread()
5515 int i, cpu; in sctp_startup_mcore_threads() local
5547 CPU_FOREACH(cpu) { in sctp_startup_mcore_threads()
5548 sctp_cpuarry[i] = cpu; in sctp_startup_mcore_threads()
5553 CPU_FOREACH(cpu) { in sctp_startup_mcore_threads()
5555 (void *)&sctp_mcore_workers[cpu], in sctp_startup_mcore_threads()
5556 &sctp_mcore_workers[cpu].thread_proc, in sctp_startup_mcore_threads()
5696 SCTP_OS_TIMER_INIT(&SCTP_BASE_INFO(addr_wq_timer.timer)); in sctp_pcb_init()
5749 * wait to re-acquire the lock. in sctp_pcb_finish()
5759 if (it->vn != curvnet) { in sctp_pcb_finish()
5763 if (it->function_atend != NULL) { in sctp_pcb_finish()
5764 (*it->function_atend) (it->pointer, it->val); in sctp_pcb_finish()
5771 (sctp_it_ctl.cur_it->vn == curvnet)) { in sctp_pcb_finish()
5775 SCTP_OS_TIMER_STOP_DRAIN(&SCTP_BASE_INFO(addr_wq_timer.timer)); in sctp_pcb_finish()
5780 if (wi->action == SCTP_DEL_IP_ADDRESS) { in sctp_pcb_finish()
5781 SCTP_FREE(wi->ifa, SCTP_M_IFA); in sctp_pcb_finish()
5794 LIST_FOREACH_SAFE(ifn, &vrf->ifnlist, next_ifn, nifn) { in sctp_pcb_finish()
5795 LIST_FOREACH_SAFE(ifa, &ifn->ifalist, next_ifa, nifa) { in sctp_pcb_finish()
5806 SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark); in sctp_pcb_finish()
5876 * with either INIT or INIT-ACK's as long as the m points to the IP in sctp_load_addresses_from_init()
5920 sin.sin_port = stcb->rport; in sctp_load_addresses_from_init()
5926 sin6.sin6_port = stcb->rport; in sctp_load_addresses_from_init()
5942 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { in sctp_load_addresses_from_init()
5944 net->dest_state |= SCTP_ADDR_NOT_IN_ASSOC; in sctp_load_addresses_from_init()
5947 inp = stcb->sctp_ep; in sctp_load_addresses_from_init()
5948 atomic_add_int(&stcb->asoc.refcnt, 1); in sctp_load_addresses_from_init()
5950 atomic_subtract_int(&stcb->asoc.refcnt, 1); in sctp_load_addresses_from_init()
5952 if ((stcb_tmp == NULL && inp == stcb->sctp_ep) || inp == NULL) { in sctp_load_addresses_from_init()
5955 switch (sa->sa_family) { in sctp_load_addresses_from_init()
5958 if (stcb->asoc.scope.ipv4_addr_legal) { in sctp_load_addresses_from_init()
5960 return (-1); in sctp_load_addresses_from_init()
5967 if (stcb->asoc.scope.ipv6_addr_legal) { in sctp_load_addresses_from_init()
5969 return (-2); in sctp_load_addresses_from_init()
5979 net_tmp->dest_state &= ~SCTP_ADDR_NOT_IN_ASSOC; in sctp_load_addresses_from_init()
5984 return (-3); in sctp_load_addresses_from_init()
5987 if (stcb->asoc.state == 0) { in sctp_load_addresses_from_init()
5989 return (-4); in sctp_load_addresses_from_init()
5994 ptype = ntohs(phdr->param_type); in sctp_load_addresses_from_init()
5995 plen = ntohs(phdr->param_length); in sctp_load_addresses_from_init()
6008 if (stcb->asoc.scope.ipv4_addr_legal) { in sctp_load_addresses_from_init()
6017 return (-5); in sctp_load_addresses_from_init()
6020 sin.sin_addr.s_addr = p4->addr; in sctp_load_addresses_from_init()
6022 /* Skip multi-cast addresses */ in sctp_load_addresses_from_init()
6029 inp = stcb->sctp_ep; in sctp_load_addresses_from_init()
6030 atomic_add_int(&stcb->asoc.refcnt, 1); in sctp_load_addresses_from_init()
6033 atomic_subtract_int(&stcb->asoc.refcnt, 1); in sctp_load_addresses_from_init()
6035 if ((stcb_tmp == NULL && inp == stcb->sctp_ep) || in sctp_load_addresses_from_init()
6048 if (stcb->asoc.state == 0) { in sctp_load_addresses_from_init()
6050 return (-7); in sctp_load_addresses_from_init()
6053 return (-8); in sctp_load_addresses_from_init()
6056 if (stcb->asoc.state == 0) { in sctp_load_addresses_from_init()
6058 return (-10); in sctp_load_addresses_from_init()
6062 net->dest_state &= in sctp_load_addresses_from_init()
6083 sctp_abort_an_association(stcb_tmp->sctp_ep, in sctp_load_addresses_from_init()
6091 if (stcb->asoc.state == 0) { in sctp_load_addresses_from_init()
6093 return (-12); in sctp_load_addresses_from_init()
6095 return (-13); in sctp_load_addresses_from_init()
6102 if (stcb->asoc.scope.ipv6_addr_legal) { in sctp_load_addresses_from_init()
6111 return (-14); in sctp_load_addresses_from_init()
6114 memcpy((caddr_t)&sin6.sin6_addr, p6->addr, in sctp_load_addresses_from_init()
6115 sizeof(p6->addr)); in sctp_load_addresses_from_init()
6117 /* Skip multi-cast addresses */ in sctp_load_addresses_from_init()
6128 inp = stcb->sctp_ep; in sctp_load_addresses_from_init()
6129 atomic_add_int(&stcb->asoc.refcnt, 1); in sctp_load_addresses_from_init()
6132 atomic_subtract_int(&stcb->asoc.refcnt, 1); in sctp_load_addresses_from_init()
6134 (inp == stcb->sctp_ep || inp == NULL)) { in sctp_load_addresses_from_init()
6140 if (stcb->asoc.state == 0) { in sctp_load_addresses_from_init()
6142 return (-16); in sctp_load_addresses_from_init()
6149 return (-17); in sctp_load_addresses_from_init()
6156 if (stcb->asoc.state == 0) { in sctp_load_addresses_from_init()
6158 return (-19); in sctp_load_addresses_from_init()
6162 net->dest_state &= in sctp_load_addresses_from_init()
6183 sctp_abort_an_association(stcb_tmp->sctp_ep, in sctp_load_addresses_from_init()
6190 if (stcb->asoc.state == 0) { in sctp_load_addresses_from_init()
6192 return (-21); in sctp_load_addresses_from_init()
6194 return (-22); in sctp_load_addresses_from_init()
6202 if (stcb->asoc.state != SCTP_STATE_OPEN) { in sctp_load_addresses_from_init()
6210 stcb->asoc.peers_adaptation = ntohl(aip->indication); in sctp_load_addresses_from_init()
6211 stcb->asoc.adaptation_needed = 1; in sctp_load_addresses_from_init()
6222 if (stcb->asoc.asconf_supported == 0) { in sctp_load_addresses_from_init()
6223 return (-100); in sctp_load_addresses_from_init()
6226 return (-23); in sctp_load_addresses_from_init()
6229 return (-101); in sctp_load_addresses_from_init()
6235 return (-24); in sctp_load_addresses_from_init()
6238 lptype = ntohs(fee->addrp.ph.param_type); in sctp_load_addresses_from_init()
6244 SCTP_PRINTF("Sizeof setprim in init/init ack not %d but %d - ignored\n", in sctp_load_addresses_from_init()
6249 sin.sin_addr.s_addr = fii->addrp.addr; in sctp_load_addresses_from_init()
6258 SCTP_PRINTF("Sizeof setprim (v6) in init/init ack not %d but %d - ignored\n", in sctp_load_addresses_from_init()
6263 fee->addrp.addr, in sctp_load_addresses_from_init()
6264 sizeof(fee->addrp.addr)); in sctp_load_addresses_from_init()
6276 stcb->asoc.peer_supports_nat = 1; in sctp_load_addresses_from_init()
6278 /* Peer supports pr-sctp */ in sctp_load_addresses_from_init()
6294 if ((ntohl(zero_chksum_p->edmid) != SCTP_EDMID_NONE) && in sctp_load_addresses_from_init()
6295 (ntohl(zero_chksum_p->edmid) == stcb->asoc.rcv_edmid)) { in sctp_load_addresses_from_init()
6296 stcb->asoc.snd_edmid = stcb->asoc.rcv_edmid; in sctp_load_addresses_from_init()
6306 return (-35); in sctp_load_addresses_from_init()
6311 return (-25); in sctp_load_addresses_from_init()
6314 num_ent = plen - sizeof(struct sctp_paramhdr); in sctp_load_addresses_from_init()
6316 switch (pr_supported->chunk_types[i]) { in sctp_load_addresses_from_init()
6357 return (-26); in sctp_load_addresses_from_init()
6359 random_len = plen - sizeof(*p_random); in sctp_load_addresses_from_init()
6363 return (-27); in sctp_load_addresses_from_init()
6380 return (-28); in sctp_load_addresses_from_init()
6382 hmacs_len = plen - sizeof(*hmacs); in sctp_load_addresses_from_init()
6383 num_hmacs = hmacs_len / sizeof(hmacs->hmac_ids[0]); in sctp_load_addresses_from_init()
6386 return (-29); in sctp_load_addresses_from_init()
6388 if (stcb->asoc.peer_hmacs != NULL) in sctp_load_addresses_from_init()
6389 sctp_free_hmaclist(stcb->asoc.peer_hmacs); in sctp_load_addresses_from_init()
6390 stcb->asoc.peer_hmacs = sctp_alloc_hmaclist(num_hmacs); in sctp_load_addresses_from_init()
6391 if (stcb->asoc.peer_hmacs != NULL) { in sctp_load_addresses_from_init()
6393 (void)sctp_auth_add_hmacid(stcb->asoc.peer_hmacs, in sctp_load_addresses_from_init()
6394 ntohs(hmacs->hmac_ids[i])); in sctp_load_addresses_from_init()
6411 return (-30); in sctp_load_addresses_from_init()
6413 num_chunks = plen - sizeof(*chunks); in sctp_load_addresses_from_init()
6414 if (stcb->asoc.peer_auth_chunks != NULL) in sctp_load_addresses_from_init()
6415 sctp_clear_chunklist(stcb->asoc.peer_auth_chunks); in sctp_load_addresses_from_init()
6417 stcb->asoc.peer_auth_chunks = sctp_alloc_chunklist(); in sctp_load_addresses_from_init()
6419 (void)sctp_auth_add_chunk(chunks->chunk_types[i], in sctp_load_addresses_from_init()
6420 stcb->asoc.peer_auth_chunks); in sctp_load_addresses_from_init()
6421 /* record asconf/asconf-ack if listed */ in sctp_load_addresses_from_init()
6422 if (chunks->chunk_types[i] == SCTP_ASCONF) in sctp_load_addresses_from_init()
6424 if (chunks->chunk_types[i] == SCTP_ASCONF_ACK) in sctp_load_addresses_from_init()
6445 * when the INIT or INIT-ACK was first seen. in sctp_load_addresses_from_init()
6460 TAILQ_FOREACH_SAFE(net, &stcb->asoc.nets, sctp_next, nnet) { in sctp_load_addresses_from_init()
6461 if ((net->dest_state & SCTP_ADDR_NOT_IN_ASSOC) == in sctp_load_addresses_from_init()
6465 stcb->asoc.numnets--; in sctp_load_addresses_from_init()
6466 TAILQ_REMOVE(&stcb->asoc.nets, net, sctp_next); in sctp_load_addresses_from_init()
6467 if (net == stcb->asoc.alternate) { in sctp_load_addresses_from_init()
6468 sctp_free_remote_addr(stcb->asoc.alternate); in sctp_load_addresses_from_init()
6469 stcb->asoc.alternate = NULL; in sctp_load_addresses_from_init()
6471 if (net == stcb->asoc.primary_destination) { in sctp_load_addresses_from_init()
6472 stcb->asoc.primary_destination = NULL; in sctp_load_addresses_from_init()
6478 if ((stcb->asoc.ecn_supported == 1) && in sctp_load_addresses_from_init()
6480 stcb->asoc.ecn_supported = 0; in sctp_load_addresses_from_init()
6482 if ((stcb->asoc.prsctp_supported == 1) && in sctp_load_addresses_from_init()
6484 stcb->asoc.prsctp_supported = 0; in sctp_load_addresses_from_init()
6486 if ((stcb->asoc.auth_supported == 1) && in sctp_load_addresses_from_init()
6489 stcb->asoc.auth_supported = 0; in sctp_load_addresses_from_init()
6491 if ((stcb->asoc.asconf_supported == 1) && in sctp_load_addresses_from_init()
6493 (stcb->asoc.auth_supported == 0) || in sctp_load_addresses_from_init()
6495 stcb->asoc.asconf_supported = 0; in sctp_load_addresses_from_init()
6497 if ((stcb->asoc.reconfig_supported == 1) && in sctp_load_addresses_from_init()
6499 stcb->asoc.reconfig_supported = 0; in sctp_load_addresses_from_init()
6501 if ((stcb->asoc.idata_supported == 1) && in sctp_load_addresses_from_init()
6503 stcb->asoc.idata_supported = 0; in sctp_load_addresses_from_init()
6505 if ((stcb->asoc.nrsack_supported == 1) && in sctp_load_addresses_from_init()
6507 stcb->asoc.nrsack_supported = 0; in sctp_load_addresses_from_init()
6509 if ((stcb->asoc.pktdrop_supported == 1) && in sctp_load_addresses_from_init()
6511 stcb->asoc.pktdrop_supported = 0; in sctp_load_addresses_from_init()
6516 return (-31); in sctp_load_addresses_from_init()
6520 return (-32); in sctp_load_addresses_from_init()
6524 return (-33); in sctp_load_addresses_from_init()
6536 memcpy(new_key->key, p_random, keylen); in sctp_load_addresses_from_init()
6542 memcpy(new_key->key + keylen, chunks, in sctp_load_addresses_from_init()
6548 memcpy(new_key->key + keylen, hmacs, in sctp_load_addresses_from_init()
6553 return (-34); in sctp_load_addresses_from_init()
6555 if (stcb->asoc.authinfo.peer_random != NULL) in sctp_load_addresses_from_init()
6556 sctp_free_key(stcb->asoc.authinfo.peer_random); in sctp_load_addresses_from_init()
6557 stcb->asoc.authinfo.peer_random = new_key; in sctp_load_addresses_from_init()
6558 sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.assoc_keyid); in sctp_load_addresses_from_init()
6559 sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.recv_keyid); in sctp_load_addresses_from_init()
6574 return (-1); in sctp_set_primary_addr()
6577 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) { in sctp_set_primary_addr()
6579 net->dest_state |= SCTP_ADDR_REQ_PRIMARY; in sctp_set_primary_addr()
6582 stcb->asoc.primary_destination = net; in sctp_set_primary_addr()
6583 if (((net->dest_state & SCTP_ADDR_PF) == 0) && in sctp_set_primary_addr()
6584 (stcb->asoc.alternate != NULL)) { in sctp_set_primary_addr()
6585 sctp_free_remote_addr(stcb->asoc.alternate); in sctp_set_primary_addr()
6586 stcb->asoc.alternate = NULL; in sctp_set_primary_addr()
6588 net = TAILQ_FIRST(&stcb->asoc.nets); in sctp_set_primary_addr()
6589 if (net != stcb->asoc.primary_destination) { in sctp_set_primary_addr()
6595 TAILQ_REMOVE(&stcb->asoc.nets, stcb->asoc.primary_destination, sctp_next); in sctp_set_primary_addr()
6596 TAILQ_INSERT_HEAD(&stcb->asoc.nets, stcb->asoc.primary_destination, sctp_next); in sctp_set_primary_addr()
6616 * this assumption, but we will go with it for now :-) in sctp_is_vtag_good()
6618 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { in sctp_is_vtag_good()
6621 if (stcb->asoc.my_vtag == tag) { in sctp_is_vtag_good()
6623 if (stcb->rport != rport) { in sctp_is_vtag_good()
6626 if (stcb->sctp_ep->sctp_lport != lport) { in sctp_is_vtag_good()
6633 return (!sctp_is_in_timewait(tag, lport, rport, now->tv_sec)); in sctp_is_vtag_good()
6651 /* We look for anything larger than the cum-ack + 1 */ in sctp_drain_mbufs()
6653 asoc = &stcb->asoc; in sctp_drain_mbufs()
6654 if (asoc->cumulative_tsn == asoc->highest_tsn_inside_map) { in sctp_drain_mbufs()
6659 cumulative_tsn_p1 = asoc->cumulative_tsn + 1; in sctp_drain_mbufs()
6662 for (strmat = 0; strmat < asoc->streamincnt; strmat++) { in sctp_drain_mbufs()
6663 TAILQ_FOREACH_SAFE(control, &asoc->strmin[strmat].inqueue, next_instrm, ncontrol) { in sctp_drain_mbufs()
6665 if (control->on_strm_q != SCTP_ON_ORDERED) { in sctp_drain_mbufs()
6666 panic("Huh control: %p on_q: %d -- not ordered?", in sctp_drain_mbufs()
6667 control, control->on_strm_q); in sctp_drain_mbufs()
6670 if (SCTP_TSN_GT(control->sinfo_tsn, cumulative_tsn_p1)) { in sctp_drain_mbufs()
6671 /* Yep it is above cum-ack */ in sctp_drain_mbufs()
6673 SCTP_CALC_TSN_TO_GAP(gap, control->sinfo_tsn, asoc->mapping_array_base_tsn); in sctp_drain_mbufs()
6674 KASSERT(control->length > 0, ("control has zero length")); in sctp_drain_mbufs()
6675 if (asoc->size_on_all_streams >= control->length) { in sctp_drain_mbufs()
6676 asoc->size_on_all_streams -= control->length; in sctp_drain_mbufs()
6679 …ize_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->lengt… in sctp_drain_mbufs()
6681 asoc->size_on_all_streams = 0; in sctp_drain_mbufs()
6684 sctp_ucount_decr(asoc->cnt_on_all_streams); in sctp_drain_mbufs()
6685 SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap); in sctp_drain_mbufs()
6686 if (control->on_read_q) { in sctp_drain_mbufs()
6687 TAILQ_REMOVE(&stcb->sctp_ep->read_queue, control, next); in sctp_drain_mbufs()
6688 control->on_read_q = 0; in sctp_drain_mbufs()
6690 TAILQ_REMOVE(&asoc->strmin[strmat].inqueue, control, next_instrm); in sctp_drain_mbufs()
6691 control->on_strm_q = 0; in sctp_drain_mbufs()
6692 if (control->data) { in sctp_drain_mbufs()
6693 sctp_m_freem(control->data); in sctp_drain_mbufs()
6694 control->data = NULL; in sctp_drain_mbufs()
6696 sctp_free_remote_addr(control->whoFrom); in sctp_drain_mbufs()
6698 TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, nchk) { in sctp_drain_mbufs()
6700 SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.tsn, asoc->mapping_array_base_tsn); in sctp_drain_mbufs()
6701 KASSERT(chk->send_size > 0, ("chunk has zero length")); in sctp_drain_mbufs()
6702 if (asoc->size_on_reasm_queue >= chk->send_size) { in sctp_drain_mbufs()
6703 asoc->size_on_reasm_queue -= chk->send_size; in sctp_drain_mbufs()
6706 …c("size_on_reasm_queue = %u smaller than chunk length %u", asoc->size_on_reasm_queue, chk->send_si… in sctp_drain_mbufs()
6708 asoc->size_on_reasm_queue = 0; in sctp_drain_mbufs()
6711 sctp_ucount_decr(asoc->cnt_on_reasm_queue); in sctp_drain_mbufs()
6712 SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap); in sctp_drain_mbufs()
6713 TAILQ_REMOVE(&control->reasm, chk, sctp_next); in sctp_drain_mbufs()
6714 if (chk->data) { in sctp_drain_mbufs()
6715 sctp_m_freem(chk->data); in sctp_drain_mbufs()
6716 chk->data = NULL; in sctp_drain_mbufs()
6723 TAILQ_FOREACH_SAFE(control, &asoc->strmin[strmat].uno_inqueue, next_instrm, ncontrol) { in sctp_drain_mbufs()
6725 if (control->on_strm_q != SCTP_ON_UNORDERED) { in sctp_drain_mbufs()
6726 panic("Huh control: %p on_q: %d -- not unordered?", in sctp_drain_mbufs()
6727 control, control->on_strm_q); in sctp_drain_mbufs()
6730 if (SCTP_TSN_GT(control->sinfo_tsn, cumulative_tsn_p1)) { in sctp_drain_mbufs()
6731 /* Yep it is above cum-ack */ in sctp_drain_mbufs()
6733 SCTP_CALC_TSN_TO_GAP(gap, control->sinfo_tsn, asoc->mapping_array_base_tsn); in sctp_drain_mbufs()
6734 KASSERT(control->length > 0, ("control has zero length")); in sctp_drain_mbufs()
6735 if (asoc->size_on_all_streams >= control->length) { in sctp_drain_mbufs()
6736 asoc->size_on_all_streams -= control->length; in sctp_drain_mbufs()
6739 …ize_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->lengt… in sctp_drain_mbufs()
6741 asoc->size_on_all_streams = 0; in sctp_drain_mbufs()
6744 sctp_ucount_decr(asoc->cnt_on_all_streams); in sctp_drain_mbufs()
6745 SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap); in sctp_drain_mbufs()
6746 if (control->on_read_q) { in sctp_drain_mbufs()
6747 TAILQ_REMOVE(&stcb->sctp_ep->read_queue, control, next); in sctp_drain_mbufs()
6748 control->on_read_q = 0; in sctp_drain_mbufs()
6750 TAILQ_REMOVE(&asoc->strmin[strmat].uno_inqueue, control, next_instrm); in sctp_drain_mbufs()
6751 control->on_strm_q = 0; in sctp_drain_mbufs()
6752 if (control->data) { in sctp_drain_mbufs()
6753 sctp_m_freem(control->data); in sctp_drain_mbufs()
6754 control->data = NULL; in sctp_drain_mbufs()
6756 sctp_free_remote_addr(control->whoFrom); in sctp_drain_mbufs()
6758 TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, nchk) { in sctp_drain_mbufs()
6760 SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.tsn, asoc->mapping_array_base_tsn); in sctp_drain_mbufs()
6761 KASSERT(chk->send_size > 0, ("chunk has zero length")); in sctp_drain_mbufs()
6762 if (asoc->size_on_reasm_queue >= chk->send_size) { in sctp_drain_mbufs()
6763 asoc->size_on_reasm_queue -= chk->send_size; in sctp_drain_mbufs()
6766 …c("size_on_reasm_queue = %u smaller than chunk length %u", asoc->size_on_reasm_queue, chk->send_si… in sctp_drain_mbufs()
6768 asoc->size_on_reasm_queue = 0; in sctp_drain_mbufs()
6771 sctp_ucount_decr(asoc->cnt_on_reasm_queue); in sctp_drain_mbufs()
6772 SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap); in sctp_drain_mbufs()
6773 TAILQ_REMOVE(&control->reasm, chk, sctp_next); in sctp_drain_mbufs()
6774 if (chk->data) { in sctp_drain_mbufs()
6775 sctp_m_freem(chk->data); in sctp_drain_mbufs()
6776 chk->data = NULL; in sctp_drain_mbufs()
6786 for (i = asoc->highest_tsn_inside_map; SCTP_TSN_GE(i, asoc->mapping_array_base_tsn); i--) { in sctp_drain_mbufs()
6787 SCTP_CALC_TSN_TO_GAP(gap, i, asoc->mapping_array_base_tsn); in sctp_drain_mbufs()
6788 if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) { in sctp_drain_mbufs()
6789 asoc->highest_tsn_inside_map = i; in sctp_drain_mbufs()
6795 asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1; in sctp_drain_mbufs()
6801 * a p-d-api up. An attacker COULD send enough in to in sctp_drain_mbufs()
6802 * initiate the PD-API and then send a bunch of stuff to in sctp_drain_mbufs()
6805 * to do this I then have to back-track and un-deliver in sctp_drain_mbufs()
6806 * sequence numbers in streams.. el-yucko. I think for now in sctp_drain_mbufs()
6809 * abort the P-D-API with a notification and then deliver in sctp_drain_mbufs()
6819 * asoc->highest_tsn_inside_map? in sctp_drain_mbufs()
6821 asoc->last_revoke_count = cnt; in sctp_drain_mbufs()
6822 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL, in sctp_drain_mbufs()
6826 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_DRAIN, SCTP_SO_NOT_LOCKED); in sctp_drain_mbufs()
6829 * Another issue, in un-setting the TSN's in the mapping array we in sctp_drain_mbufs()
6834 * we will recover once we get our cum-ack above and all this stuff in sctp_drain_mbufs()
6871 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { in sctp_drain()
6914 return (-1); in sctp_initiate_iterator()
6919 return (-1); in sctp_initiate_iterator()
6925 return (-1); in sctp_initiate_iterator()
6928 it->function_assoc = af; in sctp_initiate_iterator()
6929 it->function_inp = inpf; in sctp_initiate_iterator()
6931 it->done_current_ep = 0; in sctp_initiate_iterator()
6933 it->done_current_ep = 1; in sctp_initiate_iterator()
6934 it->function_atend = ef; in sctp_initiate_iterator()
6935 it->pointer = argp; in sctp_initiate_iterator()
6936 it->val = argi; in sctp_initiate_iterator()
6937 it->pcb_flags = pcb_state; in sctp_initiate_iterator()
6938 it->pcb_features = pcb_features; in sctp_initiate_iterator()
6939 it->asoc_state = asoc_state; in sctp_initiate_iterator()
6940 it->function_inp_end = inpe; in sctp_initiate_iterator()
6941 it->no_chunk_output = chunk_output_off; in sctp_initiate_iterator()
6942 it->vn = curvnet; in sctp_initiate_iterator()
6945 it->inp = s_inp; in sctp_initiate_iterator()
6946 SCTP_INP_INCR_REF(it->inp); in sctp_initiate_iterator()
6947 it->iterator_flags = SCTP_ITERATOR_DO_SINGLE_INP; in sctp_initiate_iterator()
6950 it->inp = LIST_FIRST(&SCTP_BASE_INFO(listhead)); in sctp_initiate_iterator()
6951 if (it->inp) { in sctp_initiate_iterator()
6952 SCTP_INP_INCR_REF(it->inp); in sctp_initiate_iterator()
6955 it->iterator_flags = SCTP_ITERATOR_DO_ALL_INP; in sctp_initiate_iterator()
6963 return (-1); in sctp_initiate_iterator()
6984 old_flags = inp->sctp_flags; in sctp_pcb_add_flags()
6986 } while (atomic_cmpset_int(&inp->sctp_flags, old_flags, new_flags) == 0); in sctp_pcb_add_flags()