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);
86 spcb->asoc_count = SCTP_BASE_INFO(ipi_count_asoc);
87 spcb->laddr_count = SCTP_BASE_INFO(ipi_count_laddr);
88 spcb->raddr_count = SCTP_BASE_INFO(ipi_count_raddr);
89 spcb->chk_count = SCTP_BASE_INFO(ipi_count_chunk);
90 spcb->readq_count = SCTP_BASE_INFO(ipi_count_readq);
91 spcb->stream_oque = SCTP_BASE_INFO(ipi_count_strmoq);
92 spcb->free_chunks = SCTP_BASE_INFO(ipi_free_chunks);
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;
165 LIST_INIT(&vrf->ifnlist);
166 vrf->total_ifa_count = 0;
167 vrf->refcount = 0;
171 vrf->vrf_addr_hash = SCTP_HASH_INIT(SCTP_VRF_ADDR_HASH_SIZE,
172 &vrf->vrf_addr_hashmark);
173 if (vrf->vrf_addr_hash == NULL) {
199 if (sctp_ifnp->ifn_index == ifn_index &&
200 sctp_ifnp->ifn_p == ifn) {
215 if (vrf_id == liste->vrf_id) {
225 if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&vrf->refcount)) {
226 if (vrf->vrf_addr_hash) {
227 SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark);
228 vrf->vrf_addr_hash = NULL;
240 if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&sctp_ifnp->refcount)) {
242 if (sctp_ifnp->vrf) {
243 sctp_free_vrf(sctp_ifnp->vrf);
253 if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&sctp_ifap->refcount)) {
255 if (sctp_ifap->ifn_p) {
256 sctp_free_ifn(sctp_ifap->ifn_p);
268 if (sctp_find_ifn(sctp_ifnp->ifn_p, sctp_ifnp->ifn_index) == NULL) {
278 /*-
288 LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa);
289 sctp_ifap->ifn_p = sctp_ifnp;
290 atomic_add_int(&sctp_ifap->ifn_p->refcount, 1);
292 sctp_ifnp->ifa_count++;
293 ifa_af = sctp_ifap->address.sa.sa_family;
297 sctp_ifnp->num_v4++;
302 sctp_ifnp->num_v6++;
308 if (sctp_ifnp->ifa_count == 1) {
310 sctp_ifnp->registered_af = ifa_af;
314 /*-
316 * If no more addresses exist, remove the ifn too. Otherwise, re-register
324 if (sctp_ifap->ifn_p) {
326 sctp_ifap->ifn_p->ifa_count--;
327 switch (sctp_ifap->address.sa.sa_family) {
330 sctp_ifap->ifn_p->num_v4--;
335 sctp_ifap->ifn_p->num_v6--;
342 if (LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) {
344 sctp_delete_ifn(sctp_ifap->ifn_p);
346 /* re-register address family type, if needed */
347 if ((sctp_ifap->ifn_p->num_v6 == 0) &&
348 (sctp_ifap->ifn_p->registered_af == AF_INET6)) {
349 sctp_ifap->ifn_p->registered_af = AF_INET;
350 } else if ((sctp_ifap->ifn_p->num_v4 == 0) &&
351 (sctp_ifap->ifn_p->registered_af == AF_INET)) {
352 sctp_ifap->ifn_p->registered_af = AF_INET6;
355 sctp_free_ifn(sctp_ifap->ifn_p);
357 sctp_ifap->ifn_p = NULL;
398 vrf = sctp_ifnp->vrf;
419 sctp_ifnp->ifn_index = ifn_index;
420 sctp_ifnp->ifn_p = ifn;
421 sctp_ifnp->ifn_type = ifn_type;
422 sctp_ifnp->refcount = 0;
423 sctp_ifnp->vrf = vrf;
424 atomic_add_int(&vrf->refcount, 1);
425 sctp_ifnp->ifn_mtu = SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index);
427 SCTP_SNPRINTF(sctp_ifnp->ifn_name, SCTP_IFNAMSIZ, "%s", if_name);
429 SCTP_SNPRINTF(sctp_ifnp->ifn_name, SCTP_IFNAMSIZ, "%s", "unknown");
432 LIST_INIT(&sctp_ifnp->ifalist);
434 LIST_INSERT_HEAD(&vrf->ifnlist, sctp_ifnp, next_ifn);
437 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
440 if (sctp_ifap->ifn_p != NULL) {
441 if (sctp_ifap->ifn_p->ifn_index == ifn_index &&
442 sctp_ifap->ifn_p->ifn_p == ifn) {
445 sctp_ifap->ifn_p->ifn_name, ifn_index,
451 if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) {
455 sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
456 sctp_ifap->ifn_p = sctp_ifnp;
457 atomic_add_int(&sctp_ifap->ifn_p->refcount, 1);
467 sctp_ifap->ifn_p->ifn_name,
468 sctp_ifap->ifn_p->ifn_index, if_name,
477 sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
496 sctp_ifap->ifn_p = sctp_ifnp;
497 atomic_add_int(&sctp_ifnp->refcount, 1);
498 sctp_ifap->vrf_id = vrf_id;
499 sctp_ifap->ifa = ifa;
500 memcpy(&sctp_ifap->address, addr, addr->sa_len);
501 sctp_ifap->localifa_flags = SCTP_ADDR_VALID | SCTP_ADDR_DEFER_USE;
502 sctp_ifap->flags = ifa_flags;
504 switch (sctp_ifap->address.sa.sa_family) {
510 sin = &sctp_ifap->address.sin;
511 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
512 (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) {
513 sctp_ifap->src_is_loop = 1;
515 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
516 sctp_ifap->src_is_priv = 1;
518 sctp_ifnp->num_v4++;
520 sctp_ifnp->registered_af = AF_INET;
530 sin6 = &sctp_ifap->address.sin6;
531 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
532 (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) {
533 sctp_ifap->src_is_loop = 1;
535 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
536 sctp_ifap->src_is_priv = 1;
538 sctp_ifnp->num_v6++;
540 sctp_ifnp->registered_af = AF_INET6;
547 hash_of_addr = sctp_get_ifa_hash_val(&sctp_ifap->address.sa);
549 if ((sctp_ifap->src_is_priv == 0) &&
550 (sctp_ifap->src_is_loop == 0)) {
551 sctp_ifap->src_is_glob = 1;
553 hash_addr_head = &vrf->vrf_addr_hash[(hash_of_addr & vrf->vrf_addr_hashmark)];
555 sctp_ifap->refcount = 1;
556 LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa);
557 sctp_ifnp->ifa_count++;
558 vrf->total_ifa_count++;
567 * Bump up the refcount so that when the timer completes it
572 atomic_add_int(&sctp_ifap->refcount, 1);
586 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time);
587 wi->ifa = sctp_ifap;
588 wi->action = SCTP_ADD_IP_ADDRESS;
599 sctp_ifap->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
623 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED);
626 if (sctp_ifap->ifn_p) {
627 if (ifn_index != sctp_ifap->ifn_p->ifn_index ||
628 ifn != sctp_ifap->ifn_p->ifn_p) {
629 SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d (%p) ifname:%s - ignoring delete\n",
630 sctp_ifap->ifn_p->ifn_index,
631 sctp_ifap->ifn_p->ifn_p,
632 sctp_ifap->ifn_p->ifn_name);
638 sctp_ifap->localifa_flags &= SCTP_ADDR_VALID;
646 /* sctp_ifap->localifa_flags |= SCTP_BEING_DELETED; */
647 vrf->total_ifa_count--;
653 SCTPDBG(SCTP_DEBUG_PCB4, "Del Addr-ifn:%d Could not find address:",
677 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time);
678 wi->ifa = sctp_ifap;
679 wi->action = SCTP_DEL_IP_ADDRESS;
683 * the newest first :-0
709 loopback_scope = stcb->asoc.scope.loopback_scope;
711 ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
712 ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
715 local_scope = stcb->asoc.scope.local_scope;
716 site_scope = stcb->asoc.scope.site_scope;
717 ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
721 vrf = sctp_find_vrf(stcb->asoc.vrf_id);
728 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
729 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
734 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
739 * we have sent an asconf-add to be
744 if (sctp_ifa->address.sa.sa_family != to->sa_family) {
747 switch (sctp_ifa->address.sa.sa_family) {
754 sin = &sctp_ifa->address.sin;
757 IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
760 if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
761 &sin->sin_addr) != 0) {
764 if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) {
777 sin6 = &sctp_ifa->address.sin6;
779 if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
780 &sin6->sin6_addr) != 0) {
783 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
786 if (sin6->sin6_scope_id == 0) {
792 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
811 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
812 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
816 if (sctp_is_addr_restricted(stcb, laddr->ifa) &&
817 (!sctp_is_addr_pending(stcb, laddr->ifa))) {
820 * sent an asconf-add to be considered
825 if (laddr->ifa->address.sa.sa_family != to->sa_family) {
828 switch (to->sa_family) {
834 sin = &laddr->ifa->address.sin;
836 if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) {
848 sin6 = &laddr->ifa->address.sin6;
888 switch (to->sa_family) {
891 if (from->sa_family == AF_INET) {
892 lport = ((struct sockaddr_in *)to)->sin_port;
893 rport = ((struct sockaddr_in *)from)->sin_port;
901 if (from->sa_family == AF_INET6) {
902 lport = ((struct sockaddr_in6 *)to)->sin6_port;
903 rport = ((struct sockaddr_in6 *)from)->sin6_port;
915 * - Does the remote port match. - Does there single association's
921 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
925 if (lport != inp->sctp_lport) {
929 switch (to->sa_family) {
936 if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
937 &sin->sin_addr) != 0) {
950 if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
951 &sin6->sin6_addr) != 0) {
962 if (inp->def_vrf_id != vrf_id) {
967 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
971 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
972 if (laddr->ifa == NULL) {
976 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
980 if (laddr->ifa->address.sa.sa_family ==
981 to->sa_family) {
984 if (from->sa_family == AF_INET) {
988 intf_addr = &laddr->ifa->address.sin;
990 if (sin->sin_addr.s_addr ==
991 intf_addr->sin_addr.s_addr) {
998 if (from->sa_family == AF_INET6) {
1004 intf_addr6 = &laddr->ifa->address.sin6;
1026 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1037 if (stcb->rport != rport) {
1043 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
1054 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1055 if (net->ro._l_addr.sa.sa_family != from->sa_family) {
1059 switch (from->sa_family) {
1065 sin = (struct sockaddr_in *)&net->ro._l_addr;
1067 if (sin->sin_addr.s_addr ==
1068 rsin->sin_addr.s_addr) {
1089 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
1139 switch (remote->sa_family) {
1142 rport = (((struct sockaddr_in *)remote)->sin_port);
1147 rport = (((struct sockaddr_in6 *)remote)->sin6_port);
1155 * UN-lock so we can do proper locking here this occurs when
1158 atomic_add_int(&locked_tcb->asoc.refcnt, 1);
1162 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
1163 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
1164 /*-
1171 if ((inp->sctp_socket) && SCTP_IS_LISTENING(inp)) {
1174 netp, inp->def_vrf_id);
1180 SCTP_INP_RLOCK(locked_tcb->sctp_ep);
1182 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1183 SCTP_INP_RUNLOCK(locked_tcb->sctp_ep);
1189 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
1192 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1198 if (stcb->rport != rport) {
1203 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
1212 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1218 if (net->ro._l_addr.sa.sa_family !=
1219 remote->sa_family) {
1223 switch (remote->sa_family) {
1231 &net->ro._l_addr;
1233 if (sin->sin_addr.s_addr ==
1234 rsin->sin_addr.s_addr) {
1245 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1261 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
1275 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1293 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
1296 head = &inp->sctp_tcbhash[SCTP_PCBHASH_ALLADDR(rport,
1297 inp->sctp_hashmark)];
1299 if (stcb->rport != rport) {
1304 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
1313 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1319 if (net->ro._l_addr.sa.sa_family !=
1320 remote->sa_family) {
1324 switch (remote->sa_family) {
1332 &net->ro._l_addr;
1334 if (sin->sin_addr.s_addr ==
1335 rsin->sin_addr.s_addr) {
1346 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1362 &net->ro._l_addr;
1376 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1397 atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
1419 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
1424 head = &inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(id, inp->hashasocidmark)];
1431 if (stcb->asoc.assoc_id == id) {
1432 if (inp != stcb->sctp_ep) {
1440 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
1487 switch (nam->sa_family) {
1508 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
1512 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) &&
1513 (inp->sctp_lport == lport)) {
1515 switch (nam->sa_family) {
1518 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
1527 if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
1528 &sin->sin_addr) != 0) {
1540 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
1544 if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
1545 &sin6->sin6_addr) != 0) {
1556 if (inp->def_vrf_id == vrf_id)
1566 switch (nam->sa_family) {
1569 if (sin->sin_addr.s_addr == INADDR_ANY) {
1577 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1592 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
1596 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL)) {
1604 if (inp->sctp_lport != lport) {
1610 if (inp->def_vrf_id == vrf_id)
1617 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
1618 if (laddr->ifa == NULL) {
1623 SCTPDBG(SCTP_DEBUG_PCB1, "Ok laddr->ifa:%p is possible, ",
1624 (void *)laddr->ifa);
1625 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
1629 if (laddr->ifa->address.sa.sa_family == nam->sa_family) {
1631 switch (nam->sa_family) {
1634 if (sin->sin_addr.s_addr ==
1635 laddr->ifa->address.sin.sin_addr.s_addr) {
1643 intf_addr6 = &laddr->ifa->address.sin6;
1669 if (t_inp->sctp_lport != lport) {
1674 if (t_inp->def_vrf_id == vrf_id)
1681 if ((t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
1683 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1690 } else if (t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1695 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
1710 /* For 1-2-1 with port reuse */
1719 return (-1);
1721 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) {
1725 head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(inp->sctp_lport,
1727 /* Kick out all non-listeners to the TCP hash */
1729 if (tinp->sctp_lport != inp->sctp_lport) {
1732 if (tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
1735 if (tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
1743 head = &SCTP_BASE_INFO(sctp_tcpephash)[SCTP_PCBHASH_ALLADDR(tinp->sctp_lport, SCTP_BASE_INFO(hashtcpmark))];
1744 tinp->sctp_flags |= SCTP_PCB_FLAGS_IN_TCPPOOL;
1751 inp->sctp_flags &= ~SCTP_PCB_FLAGS_IN_TCPPOOL;
1752 head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(inp->sctp_lport, SCTP_BASE_INFO(hashmark))];
1776 switch (nam->sa_family) {
1780 lport = sin->sin_port;
1786 lport = sin6->sin6_port;
1885 * This routine will grub through the mbuf that is a INIT or INIT-ACK and
1911 sin4.sin_port = sh->src_port;
1917 sin6.sin6_port = sh->src_port;
1926 ptype = ntohs(phdr->param_type);
1928 plen = ntohs(phdr->param_length);
1944 memcpy(&sin4.sin_addr, &p4->addr, sizeof(p4->addr));
1965 memcpy(&sin6.sin6_addr, &p6->addr, sizeof(p6->addr));
1999 SCTP_INP_RLOCK(stcb->sctp_ep);
2000 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
2001 SCTP_INP_RUNLOCK(stcb->sctp_ep);
2004 if (stcb->sctp_ep->def_vrf_id != vrf_id) {
2005 SCTP_INP_RUNLOCK(stcb->sctp_ep);
2009 SCTP_INP_RUNLOCK(stcb->sctp_ep);
2010 if (stcb->asoc.my_vtag == vtag) {
2012 if (stcb->rport != rport) {
2016 if (stcb->sctp_ep->sctp_lport != lport) {
2020 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
2035 if (stcb->asoc.peer_vtag == remote_tag) {
2052 *inp_p = stcb->sctp_ep;
2061 *inp_p = stcb->sctp_ep;
2091 if (sh->v_tag) {
2092 /* we only go down this path if vtag is non-zero */
2093 stcb = sctp_findassoc_by_vtag(src, dst, ntohl(sh->v_tag),
2094 inp_p, netp, sh->src_port, sh->dest_port, 0, vrf_id, 0);
2111 if ((ch->chunk_type == SCTP_INITIATION) ||
2112 (ch->chunk_type == SCTP_INITIATION_ACK)) {
2113 /*-
2121 if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) {
2167 ptype = (int)((uint32_t)ntohs(phdr->param_type));
2176 if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv6addr_param)) {
2188 sin6->sin6_family = AF_INET6;
2189 sin6->sin6_len = sizeof(*sin6);
2190 sin6->sin6_port = sh->src_port;
2191 memcpy(&sin6->sin6_addr, &p6->addr, sizeof(struct in6_addr));
2192 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
2203 if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv4addr_param)) {
2215 sin->sin_family = AF_INET;
2216 sin->sin_len = sizeof(*sin);
2217 sin->sin_port = sh->src_port;
2218 memcpy(&sin->sin_addr, &p4->addr, sizeof(struct in_addr));
2219 if (sin->sin_addr.s_addr == INADDR_ANY)
2230 stcb = sctp_findassoc_by_vtag(NULL, dst, ntohl(sh->v_tag), inp_p,
2231 netp, sh->src_port, sh->dest_port, 1, vrf_id, 0);
2270 SCTP_PRINTF("Out of SCTP-INPCB structures - no resources\n");
2280 inp->sctp_socket = so;
2281 inp->ip_inp.inp.inp_socket = so;
2282 inp->ip_inp.inp.inp_cred = crhold(so->so_cred);
2286 inp->ip_inp.inp.inp_flags |= IN6P_AUTOFLOWLABEL;
2289 inp->ip_inp.inp.inp_flags |= IN6P_IPV6_V6ONLY;
2293 inp->sctp_associd_counter = 1;
2294 inp->partial_delivery_point = SCTP_SB_LIMIT_RCV(so) >> SCTP_PARTIAL_DELIVERY_SHIFT;
2295 inp->sctp_frag_point = 0;
2296 inp->max_cwnd = 0;
2297 inp->sctp_cmt_on_off = SCTP_BASE_SYSCTL(sctp_cmt_on_off);
2298 inp->ecn_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_ecn_enable);
2299 inp->prsctp_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pr_enable);
2300 inp->auth_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_auth_enable);
2301 inp->asconf_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_asconf_enable);
2302 inp->reconfig_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_reconfig_enable);
2303 inp->nrsack_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_nrsack_enable);
2304 inp->pktdrop_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pktdrop_enable);
2305 inp->idata_supported = 0;
2306 inp->rcv_edmid = SCTP_EDMID_NONE;
2308 inp->fibnum = so->so_fibnum;
2309 /* init the small hash table we use to track asocid <-> tcb */
2310 inp->sctp_asocidhash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, &inp->hashasocidmark);
2311 if (inp->sctp_asocidhash == NULL) {
2312 crfree(inp->ip_inp.inp.inp_cred);
2318 inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
2321 so->so_pcb = (caddr_t)inp;
2325 inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |
2327 /* Be sure it is NON-BLOCKING IO for UDP */
2331 inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE |
2339 * unsupported socket type (RAW, etc)- in case we missed it
2343 so->so_pcb = NULL;
2344 crfree(inp->ip_inp.inp.inp_cred);
2358 inp->sctp_tcbhash = SCTP_HASH_INIT(SCTP_BASE_SYSCTL(sctp_pcbtblsize),
2359 &inp->sctp_hashmark);
2360 if (inp->sctp_tcbhash == NULL) {
2361 SCTP_PRINTF("Out of SCTP-INPCB->hashinit - no resources\n");
2363 so->so_pcb = NULL;
2364 crfree(inp->ip_inp.inp.inp_cred);
2368 inp->def_vrf_id = vrf_id;
2372 rw_init_flags(&inp->ip_inp.inp.inp_lock, "sctpinp",
2383 TAILQ_INIT(&inp->read_queue);
2384 LIST_INIT(&inp->sctp_addr_list);
2386 LIST_INIT(&inp->sctp_asoc_list);
2390 LIST_INIT(&inp->sctp_asoc_free_list);
2392 /* Init the timer structure for signature change */
2393 SCTP_OS_TIMER_INIT(&inp->sctp_ep.signature_change.timer);
2394 inp->sctp_ep.signature_change.type = SCTP_TIMER_TYPE_NEWCOOKIE;
2397 m = &inp->sctp_ep;
2400 m->sctp_timeoutticks[SCTP_TIMER_SEND] = sctp_secs_to_ticks(SCTP_SEND_SEC); /* needed ? */
2401 m->sctp_timeoutticks[SCTP_TIMER_INIT] = sctp_secs_to_ticks(SCTP_INIT_SEC); /* needed ? */
2402 m->sctp_timeoutticks[SCTP_TIMER_RECV] = sctp_msecs_to_ticks(SCTP_BASE_SYSCTL(sctp_delayed_sack_time_default));
2403 m->sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_msecs_to_ticks(SCTP_BASE_SYSCTL(sctp_heartbeat_interval_default));
2404 m->sctp_timeoutticks[SCTP_TIMER_PMTU] = sctp_secs_to_ticks(SCTP_BASE_SYSCTL(sctp_pmtu_raise_time_default));
2405 m->sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] = sctp_secs_to_ticks(SCTP_BASE_SYSCTL(sctp_shutdown_guard_time_default));
2406 m->sctp_timeoutticks[SCTP_TIMER_SIGNATURE] = sctp_secs_to_ticks(SCTP_BASE_SYSCTL(sctp_secret_lifetime_default));
2408 m->sctp_maxrto = SCTP_BASE_SYSCTL(sctp_rto_max_default);
2409 m->sctp_minrto = SCTP_BASE_SYSCTL(sctp_rto_min_default);
2410 m->initial_rto = SCTP_BASE_SYSCTL(sctp_rto_initial_default);
2411 m->initial_init_rto_max = SCTP_BASE_SYSCTL(sctp_init_rto_max_default);
2412 m->sctp_sack_freq = SCTP_BASE_SYSCTL(sctp_sack_freq_default);
2413 m->max_init_times = SCTP_BASE_SYSCTL(sctp_init_rtx_max_default);
2414 m->max_send_times = SCTP_BASE_SYSCTL(sctp_assoc_rtx_max_default);
2415 m->def_net_failure = SCTP_BASE_SYSCTL(sctp_path_rtx_max_default);
2416 m->def_net_pf_threshold = SCTP_BASE_SYSCTL(sctp_path_pf_threshold);
2417 m->sctp_sws_sender = SCTP_SWS_SENDER_DEF;
2418 m->sctp_sws_receiver = SCTP_SWS_RECEIVER_DEF;
2419 m->max_burst = SCTP_BASE_SYSCTL(sctp_max_burst_default);
2420 m->fr_max_burst = SCTP_BASE_SYSCTL(sctp_fr_max_burst_default);
2422 m->sctp_default_cc_module = SCTP_BASE_SYSCTL(sctp_default_cc_module);
2423 m->sctp_default_ss_module = SCTP_BASE_SYSCTL(sctp_default_ss_module);
2424 m->max_open_streams_intome = SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default);
2425 /* number of streams to pre-open on a association */
2426 m->pre_open_stream_count = SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default);
2428 m->default_mtu = 0;
2430 m->adaptation_layer_indicator = 0;
2431 m->adaptation_layer_indicator_provided = 0;
2434 m->random_counter = 1;
2435 m->store_at = SCTP_SIGNATURE_SIZE;
2436 SCTP_READ_RANDOM(m->random_numbers, sizeof(m->random_numbers));
2440 m->size_of_a_cookie = (sizeof(struct sctp_init_msg) * 2) +
2442 m->size_of_a_cookie += SCTP_SIGNATURE_SIZE;
2446 m->time_of_secret_change = time.tv_sec;
2449 m->secret_key[0][i] = sctp_select_initial_TSN(m);
2454 m->def_cookie_life = sctp_msecs_to_ticks(SCTP_BASE_SYSCTL(sctp_valid_cookie_life_default));
2458 m->local_hmacs = sctp_default_supported_hmaclist();
2459 m->local_auth_chunks = sctp_alloc_chunklist();
2460 if (inp->asconf_supported) {
2461 sctp_auth_add_chunk(SCTP_ASCONF, m->local_auth_chunks);
2462 sctp_auth_add_chunk(SCTP_ASCONF_ACK, m->local_auth_chunks);
2464 m->default_dscp = 0;
2466 m->default_flowlabel = 0;
2468 m->port = 0; /* encapsulation disabled by default */
2469 LIST_INIT(&m->shared_keys);
2472 sctp_insert_sharedkey(&m->shared_keys, null_key);
2489 atomic_add_int(&stcb->asoc.refcnt, 1);
2495 atomic_subtract_int(&stcb->asoc.refcnt, 1);
2498 if (old_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2499 new_inp->ip_inp.inp.inp_flags |= old_inp->ip_inp.inp.inp_flags & INP_CONTROLOPTS;
2500 if (old_inp->ip_inp.inp.in6p_outputopts) {
2501 new_inp->ip_inp.inp.in6p_outputopts = ip6_copypktopts(old_inp->ip_inp.inp.in6p_outputopts, M_NOWAIT);
2510 new_inp->ip_inp.inp.inp_ip_tos = old_inp->ip_inp.inp.inp_ip_tos;
2511 new_inp->ip_inp.inp.inp_ip_ttl = old_inp->ip_inp.inp.inp_ip_ttl;
2514 new_inp->sctp_ep.time_of_secret_change =
2515 old_inp->sctp_ep.time_of_secret_change;
2516 memcpy(new_inp->sctp_ep.secret_key, old_inp->sctp_ep.secret_key,
2517 sizeof(old_inp->sctp_ep.secret_key));
2518 new_inp->sctp_ep.current_secret_number =
2519 old_inp->sctp_ep.current_secret_number;
2520 new_inp->sctp_ep.last_secret_number =
2521 old_inp->sctp_ep.last_secret_number;
2522 new_inp->sctp_ep.size_of_a_cookie = old_inp->sctp_ep.size_of_a_cookie;
2525 stcb->sctp_socket = new_inp->sctp_socket;
2526 stcb->sctp_ep = new_inp;
2529 lport = new_inp->sctp_lport = old_inp->sctp_lport;
2530 rport = stcb->rport;
2534 if (stcb->asoc.in_asocid_hash) {
2542 new_inp->sctp_flags &= ~SCTP_PCB_FLAGS_UNBOUND;
2545 LIST_INSERT_HEAD(&new_inp->sctp_asoc_list, stcb, sctp_tcblist);
2547 * Question, do we even need to worry about the ep-hash since we
2551 if (stcb->asoc.in_asocid_hash) {
2554 lhd = &new_inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(stcb->asoc.assoc_id,
2555 new_inp->hashasocidmark)];
2558 /* Ok. Let's restart timer. */
2559 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
2565 if (new_inp->sctp_tcbhash != NULL) {
2566 SCTP_HASH_FREE(new_inp->sctp_tcbhash, new_inp->sctp_hashmark);
2567 new_inp->sctp_tcbhash = NULL;
2569 if ((new_inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
2571 LIST_FOREACH(oladdr, &old_inp->sctp_addr_list, sctp_nxt_addr) {
2584 (void)SCTP_GETTIME_TIMEVAL(&laddr->start_time);
2585 laddr->ifa = oladdr->ifa;
2586 atomic_add_int(&laddr->ifa->refcount, 1);
2587 LIST_INSERT_HEAD(&new_inp->sctp_addr_list, laddr,
2589 new_inp->laddr_count++;
2590 if (oladdr == stcb->asoc.last_used_address) {
2591 stcb->asoc.last_used_address = laddr;
2596 if (stcb->asoc.dack_timer.ep == old_inp) {
2598 stcb->asoc.dack_timer.ep = new_inp;
2601 if (stcb->asoc.asconf_timer.ep == old_inp) {
2603 stcb->asoc.asconf_timer.ep = new_inp;
2606 if (stcb->asoc.strreset_timer.ep == old_inp) {
2608 stcb->asoc.strreset_timer.ep = new_inp;
2611 if (stcb->asoc.shut_guard_timer.ep == old_inp) {
2613 stcb->asoc.shut_guard_timer.ep = new_inp;
2616 if (stcb->asoc.autoclose_timer.ep == old_inp) {
2618 stcb->asoc.autoclose_timer.ep = new_inp;
2621 if (stcb->asoc.delete_prim_timer.ep == old_inp) {
2623 stcb->asoc.delete_prim_timer.ep = new_inp;
2627 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
2628 if (net->pmtu_timer.ep == old_inp) {
2630 net->pmtu_timer.ep = new_inp;
2633 if (net->hb_timer.ep == old_inp) {
2635 net->hb_timer.ep = new_inp;
2638 if (net->rxt_timer.ep == old_inp) {
2640 net->rxt_timer.ep = new_inp;
2664 (void)SCTP_GETTIME_TIMEVAL(&laddr->start_time);
2665 laddr->ifa = ifa;
2666 laddr->action = act;
2667 atomic_add_int(&ifa->refcount, 1);
2683 sctp_free_ifa(laddr->ifa);
2690 * socket address is specified, the PCB lock may be dropped and re-acquired.
2713 ip_inp = &inp->ip_inp.inp;
2721 ntohs(((struct sockaddr_in *)addr)->sin_port));
2726 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) {
2733 switch (addr->sa_family) {
2745 if (addr->sa_len != sizeof(*sin)) {
2752 lport = sin->sin_port;
2758 if ((error = prison_local_ip4(td->td_ucred, &sin->sin_addr)) != 0) {
2762 if (sin->sin_addr.s_addr != INADDR_ANY) {
2778 if (addr->sa_len != sizeof(*sin6)) {
2783 lport = sin6->sin6_port;
2789 if ((error = prison_local_ip6(td->td_ucred, &sin6->sin6_addr,
2794 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2804 sin6->sin6_scope_id = 0;
2814 /* Setup a vrf_id to be the default for the non-bind-all case. */
2815 vrf_id = inp->def_vrf_id;
2830 vrf_id = inp->def_vrf_id;
2845 * Ok, must be one-2-one and
2846 * allowing port re-use
2872 * Ok, must be one-2-one and
2873 * allowing port re-use
2907 if (ip_inp->inp_flags & INP_HIGHPORT) {
2910 } else if (ip_inp->inp_flags & INP_LOWPORT) {
2928 count = last - first + 1; /* number of candidates */
2929 candidate = first + sctp_select_initial_TSN(&inp->sctp_ep) % (count);
2932 if (sctp_isport_inuse(inp, htons(candidate), inp->def_vrf_id) == NULL) {
2936 if (--count == 0) {
2947 if (inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE |
2950 * this really should not happen. The guy did a non-blocking
2960 inp->sctp_flags |= SCTP_PCB_FLAGS_BOUNDALL;
3011 switch (addr->sa_family) {
3049 if (addr->sa_family == AF_INET6) {
3051 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
3052 /* Can't bind a non-existent addr. */
3060 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUNDALL;
3067 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, 0);
3070 inp->laddr_count++;
3074 /* Put it into tcp 1-2-1 hash */
3076 inp->sctp_flags |= SCTP_PCB_FLAGS_IN_TCPPOOL;
3082 SCTPDBG(SCTP_DEBUG_PCB1, "Main hash to bind at head:%p, bound port:%d - in tcp_pool=%d\n",
3085 inp->sctp_lport = lport;
3088 KASSERT((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) != 0,
3090 inp->sctp_flags &= ~SCTP_PCB_FLAGS_UNBOUND;
3102 inp = so->so_pcb;
3121 if (it && (it->vn != curvnet)) {
3125 if (it && (it->inp == inp)) {
3139 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
3151 if (it->vn != curvnet) {
3154 if (it->inp == inp) {
3156 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
3160 if (it->function_atend != NULL) {
3161 (*it->function_atend) (it->pointer, it->val);
3165 it->inp = LIST_NEXT(it->inp, sctp_list);
3166 if (it->inp) {
3167 SCTP_INP_INCR_REF(it->inp);
3188 * complete then any timer has to be stopped. Then start the actual
3212 so = inp->sctp_socket;
3213 KASSERT((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) != 0,
3215 KASSERT((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0,
3218 inp->sctp_flags &= ~SCTP_PCB_FLAGS_CLOSE_IP;
3220 inp->sctp_flags |= SCTP_PCB_FLAGS_DONT_WAKE;
3221 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT;
3222 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT;
3228 if (inp->control) {
3229 sctp_m_freem(inp->control);
3230 inp->control = NULL;
3232 if (inp->pkt) {
3233 sctp_m_freem(inp->pkt);
3234 inp->pkt = NULL;
3236 ip_pcb = &inp->ip_inp.inp; /* we could just cast the main pointer
3243 LIST_FOREACH_SAFE(stcb, &inp->sctp_asoc_list, sctp_tcblist, nstcb) {
3246 stcb->sctp_socket = NULL;
3248 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
3251 if (stcb->asoc.state & SCTP_STATE_IN_ACCEPT_QUEUE) {
3253 * Special case - we did not start a
3254 * kill timer on the asoc due to it
3266 (stcb->asoc.total_output_queue_size == 0)) {
3280 if ((stcb->asoc.size_on_reasm_queue > 0) ||
3281 (stcb->asoc.size_on_all_streams > 0) ||
3282 ((so != NULL) && (SCTP_SBAVAIL(&so->so_rcv) > 0))) {
3287 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_3;
3299 } else if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
3300 TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
3301 (stcb->asoc.stream_queue_cnt == 0)) {
3302 if ((*stcb->asoc.ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, &stcb->asoc)) {
3319 if (stcb->asoc.alternate) {
3320 netp = stcb->asoc.alternate;
3322 netp = stcb->asoc.primary_destination;
3325 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb,
3327 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, NULL);
3333 if ((*stcb->asoc.ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, &stcb->asoc)) {
3336 if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
3337 TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
3338 (stcb->asoc.state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
3343 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_5;
3368 inp->sctp_socket = NULL;
3375 inp->sctp_socket = NULL;
3376 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) {
3382 inp->sctp_flags |= SCTP_PCB_FLAGS_UNBOUND;
3386 * If there is a timer running to kill us, forget it, since it may
3390 LIST_FOREACH_SAFE(stcb, &inp->sctp_asoc_list, sctp_tcblist, nstcb) {
3394 stcb->sctp_socket = NULL;
3397 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
3398 if (stcb->asoc.state & SCTP_STATE_IN_ACCEPT_QUEUE) {
3408 ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) {
3412 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB + SCTP_LOC_7;
3415 } else if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
3446 if ((inp->refcount) ||
3448 (inp->sctp_flags & SCTP_PCB_FLAGS_CLOSE_IP)) {
3458 inp->sctp_ep.signature_change.type = 0;
3459 inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_ALLGONE;
3471 if ((inp->sctp_asocidhash) != NULL) {
3472 SCTP_HASH_FREE(inp->sctp_asocidhash, inp->hashasocidmark);
3473 inp->sctp_asocidhash = NULL;
3476 TAILQ_FOREACH_SAFE(sq, &inp->read_queue, next, nsq) {
3478 if (sq->length)
3481 TAILQ_REMOVE(&inp->read_queue, sq, next);
3482 sctp_free_remote_addr(sq->whoFrom);
3484 SCTP_SB_DECR(&so->so_rcv, sq->length);
3485 if (sq->data) {
3486 sctp_m_freem(sq->data);
3487 sq->data = NULL;
3501 if (ip_pcb->inp_options) {
3502 (void)sctp_m_free(ip_pcb->inp_options);
3503 ip_pcb->inp_options = 0;
3506 if (ip_pcb->inp_vflag & INP_IPV6) {
3507 ip6_freepcbopts(ip_pcb->in6p_outputopts);
3510 ip_pcb->inp_vflag = 0;
3512 if (inp->sctp_ep.local_auth_chunks != NULL)
3513 sctp_free_chunklist(inp->sctp_ep.local_auth_chunks);
3514 if (inp->sctp_ep.local_hmacs != NULL)
3515 sctp_free_hmaclist(inp->sctp_ep.local_hmacs);
3517 LIST_FOREACH_SAFE(shared_key, &inp->sctp_ep.shared_keys, next, nshared_key) {
3528 LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
3534 LIST_FOREACH_SAFE(stcb, &inp->sctp_asoc_free_list, sctp_tcblist, nstcb) {
3542 if (inp->sctp_tcbhash != NULL) {
3543 SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark);
3544 inp->sctp_tcbhash = NULL;
3547 crfree(inp->ip_inp.inp.inp_cred);
3548 INP_LOCK_DESTROY(&inp->ip_inp.inp);
3562 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
3563 if (sctp_cmpaddr(addr, (struct sockaddr *)&net->ro._l_addr))
3583 * add's a remote endpoint address, done with the INIT/INIT-ACK as well as
3615 if (netfirst->dest_state & SCTP_ADDR_UNCONFIRMED) {
3616 netfirst->dest_state = (SCTP_ADDR_REACHABLE |
3619 netfirst->dest_state = SCTP_ADDR_REACHABLE;
3625 switch (newaddr->sa_family) {
3632 if (sin->sin_addr.s_addr == 0) {
3634 return (-1);
3637 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
3640 sin->sin_len = sizeof(struct sockaddr_in);
3642 if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
3643 stcb->asoc.scope.ipv4_local_scope = 1;
3647 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) &&
3648 (stcb->asoc.scope.ipv4_local_scope == 0)) {
3661 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
3663 return (-1);
3666 sin6->sin6_len = sizeof(struct sockaddr_in6);
3668 if (sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id)) {
3669 stcb->asoc.scope.loopback_scope = 1;
3670 stcb->asoc.scope.local_scope = 0;
3671 stcb->asoc.scope.ipv4_local_scope = 1;
3672 stcb->asoc.scope.site_scope = 1;
3673 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
3684 stcb->asoc.scope.ipv4_local_scope = 1;
3685 stcb->asoc.scope.site_scope = 1;
3686 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
3692 stcb->asoc.scope.site_scope = 1;
3696 if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) &&
3697 (stcb->asoc.scope.loopback_scope == 0)) {
3699 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
3700 (stcb->asoc.scope.local_scope == 0)) {
3702 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&
3703 (stcb->asoc.scope.site_scope == 0)) {
3712 return (-1);
3716 return (-1);
3720 (void)SCTP_GETTIME_TIMEVAL(&net->start_time);
3721 memcpy(&net->ro._l_addr, newaddr, newaddr->sa_len);
3722 switch (newaddr->sa_family) {
3725 ((struct sockaddr_in *)&net->ro._l_addr)->sin_port = stcb->rport;
3730 ((struct sockaddr_in6 *)&net->ro._l_addr)->sin6_port = stcb->rport;
3736 net->addr_is_local = sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id);
3737 if (net->addr_is_local && ((set_scope || (from == SCTP_ADDR_IS_CONFIRMED)))) {
3738 stcb->asoc.scope.loopback_scope = 1;
3739 stcb->asoc.scope.ipv4_local_scope = 1;
3740 stcb->asoc.scope.local_scope = 0;
3741 stcb->asoc.scope.site_scope = 1;
3744 net->failure_threshold = stcb->asoc.def_net_failure;
3745 net->pf_threshold = stcb->asoc.def_net_pf_threshold;
3747 net->dest_state = (SCTP_ADDR_REACHABLE |
3752 net->dest_state = SCTP_ADDR_REACHABLE;
3754 net->dest_state = SCTP_ADDR_REACHABLE |
3758 * We set this to 0, the timer code knows that this means its an
3761 net->rto_needed = 1;
3762 net->RTO = 0;
3763 net->RTO_measured = 0;
3764 stcb->asoc.numnets++;
3765 net->ref_count = 1;
3766 net->cwr_window_tsn = net->last_cwr_tsn = stcb->asoc.sending_seq - 1;
3767 net->port = port;
3768 net->dscp = stcb->asoc.default_dscp;
3770 net->flowlabel = stcb->asoc.default_flowlabel;
3772 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) {
3773 net->dest_state |= SCTP_ADDR_NOHB;
3775 net->dest_state &= ~SCTP_ADDR_NOHB;
3777 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) {
3778 net->dest_state |= SCTP_ADDR_NO_PMTUD;
3780 net->dest_state &= ~SCTP_ADDR_NO_PMTUD;
3782 net->heart_beat_delay = stcb->asoc.heart_beat_delay;
3783 /* Init the timer structure */
3784 SCTP_OS_TIMER_INIT(&net->rxt_timer.timer);
3785 SCTP_OS_TIMER_INIT(&net->pmtu_timer.timer);
3786 SCTP_OS_TIMER_INIT(&net->hb_timer.timer);
3791 if (newaddr->sa_family == AF_INET6) {
3794 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
3796 sin6->sin6_scope_id = 0;
3799 SCTP_RTALLOC((sctp_route_t *)&net->ro,
3800 stcb->asoc.vrf_id,
3801 stcb->sctp_ep->fibnum);
3803 net->src_addr_selected = 0;
3804 if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) {
3806 net->ro._s_addr = sctp_source_address_selection(stcb->sctp_ep,
3808 (sctp_route_t *)&net->ro,
3811 stcb->asoc.vrf_id);
3812 if (stcb->asoc.default_mtu > 0) {
3813 net->mtu = stcb->asoc.default_mtu;
3814 switch (net->ro._l_addr.sa.sa_family) {
3817 net->mtu += SCTP_MIN_V4_OVERHEAD;
3822 net->mtu += SCTP_MIN_OVERHEAD;
3829 if (net->port) {
3830 net->mtu += (uint32_t)sizeof(struct udphdr);
3833 } else if (net->ro._s_addr != NULL) {
3836 net->src_addr_selected = 1;
3838 if (net->ro._s_addr->ifn_p != NULL) {
3841 * net->ro._s_addr->ifn_p->ifn_mtu
3843 imtu = SCTP_GATHER_MTU_FROM_IFN_INFO(net->ro._s_addr->ifn_p->ifn_p,
3844 net->ro._s_addr->ifn_p->ifn_index);
3848 rmtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, net->ro.ro_nh);
3849 hcmtu = sctp_hc_get_mtu(&net->ro._l_addr, stcb->sctp_ep->fibnum);
3850 net->mtu = sctp_min_mtu(hcmtu, rmtu, imtu);
3853 if (net->mtu == 0) {
3854 if (stcb->asoc.default_mtu > 0) {
3855 net->mtu = stcb->asoc.default_mtu;
3856 switch (net->ro._l_addr.sa.sa_family) {
3859 net->mtu += SCTP_MIN_V4_OVERHEAD;
3864 net->mtu += SCTP_MIN_OVERHEAD;
3871 if (net->port) {
3872 net->mtu += (uint32_t)sizeof(struct udphdr);
3876 switch (newaddr->sa_family) {
3879 net->mtu = SCTP_DEFAULT_MTU;
3884 net->mtu = 1280;
3893 if (net->port) {
3894 net->mtu -= (uint32_t)sizeof(struct udphdr);
3898 stcb->asoc.smallest_mtu = net->mtu;
3900 if (stcb->asoc.smallest_mtu > net->mtu) {
3901 sctp_pathmtu_adjustment(stcb, net->mtu, true);
3904 if (newaddr->sa_family == AF_INET6) {
3907 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
3912 /* JRS - Use the congestion control given in the CC module */
3913 if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL)
3914 (*stcb->asoc.cc_functions.sctp_set_initial_cc_param) (stcb, net);
3917 * CMT: CUC algo - set find_pseudo_cumack to TRUE (1) at beginning
3920 net->find_pseudo_cumack = 1;
3921 net->find_rtx_pseudo_cumack = 1;
3923 net->flowid = stcb->asoc.my_vtag ^
3924 ntohs(stcb->rport) ^
3925 ntohs(stcb->sctp_ep->sctp_lport);
3926 net->flowtype = M_HASHTYPE_OPAQUE_HASH;
3930 netfirst = TAILQ_FIRST(&stcb->asoc.nets);
3931 if (net->ro.ro_nh == NULL) {
3933 TAILQ_INSERT_TAIL(&stcb->asoc.nets, net, sctp_next);
3936 TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next);
3937 } else if (netfirst->ro.ro_nh == NULL) {
3942 TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next);
3943 } else if (net->ro.ro_nh->nh_ifp != netfirst->ro.ro_nh->nh_ifp) {
3948 TAILQ_INSERT_HEAD(&stcb->asoc.nets, net, sctp_next);
3962 TAILQ_INSERT_TAIL(&stcb->asoc.nets, net, sctp_next);
3964 } else if (netlook->ro.ro_nh == NULL) {
3968 } else if (netlook->ro.ro_nh->nh_ifp != net->ro.ro_nh->nh_ifp) {
3969 TAILQ_INSERT_AFTER(&stcb->asoc.nets, netlook,
3979 if (stcb->asoc.primary_destination == 0) {
3980 stcb->asoc.primary_destination = net;
3981 } else if ((stcb->asoc.primary_destination->ro.ro_nh == NULL) &&
3982 (net->ro.ro_nh) &&
3983 ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0)) {
3985 stcb->asoc.primary_destination = net;
3988 net = TAILQ_FIRST(&stcb->asoc.nets);
3989 if ((net != stcb->asoc.primary_destination) &&
3990 (stcb->asoc.primary_destination)) {
3996 TAILQ_REMOVE(&stcb->asoc.nets,
3997 stcb->asoc.primary_destination, sctp_next);
3998 TAILQ_INSERT_HEAD(&stcb->asoc.nets,
3999 stcb->asoc.primary_destination, sctp_next);
4012 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
4020 if (inp->sctp_associd_counter <= SCTP_ALL_ASSOC) {
4021 inp->sctp_associd_counter = SCTP_ALL_ASSOC + 1;
4023 id = inp->sctp_associd_counter;
4024 inp->sctp_associd_counter++;
4029 head = &inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(id, inp->hashasocidmark)];
4031 stcb->asoc.in_asocid_hash = 1;
4074 if (inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
4079 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) &&
4081 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) {
4085 * sctp_aloc_assoc.. or the one-2-many socket. If a peeled
4092 if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
4093 (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)) {
4094 if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) ||
4095 (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED)) {
4105 switch (firstaddr->sa_family) {
4109 ntohs(((struct sockaddr_in *)firstaddr)->sin_port));
4115 ntohs(((struct sockaddr_in6 *)firstaddr)->sin6_port));
4125 switch (firstaddr->sa_family) {
4132 if ((ntohs(sin->sin_port) == 0) ||
4133 (sin->sin_addr.s_addr == INADDR_ANY) ||
4134 (sin->sin_addr.s_addr == INADDR_BROADCAST) ||
4135 IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) ||
4136 ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
4143 rport = sin->sin_port;
4153 if ((ntohs(sin6->sin6_port) == 0) ||
4154 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
4155 IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) ||
4156 ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0)) {
4162 rport = sin6->sin6_port;
4172 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
4193 asoc = &stcb->asoc;
4196 stcb->rport = rport;
4198 stcb->sctp_ep = inp;
4199 stcb->sctp_socket = inp->sctp_socket;
4210 asoc->assoc_id = sctp_aloc_a_assoc_id(inp, stcb);
4212 head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
4218 if (asoc->strmout) {
4219 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
4220 asoc->strmout = NULL;
4222 if (asoc->mapping_array) {
4223 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
4224 asoc->mapping_array = NULL;
4226 if (asoc->nr_mapping_array) {
4227 SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
4228 asoc->nr_mapping_array = NULL;
4242 SCTP_OS_TIMER_INIT(&asoc->dack_timer.timer);
4243 SCTP_OS_TIMER_INIT(&asoc->strreset_timer.timer);
4244 SCTP_OS_TIMER_INIT(&asoc->asconf_timer.timer);
4245 SCTP_OS_TIMER_INIT(&asoc->shut_guard_timer.timer);
4246 SCTP_OS_TIMER_INIT(&asoc->autoclose_timer.timer);
4247 SCTP_OS_TIMER_INIT(&asoc->delete_prim_timer.timer);
4249 LIST_INSERT_HEAD(&inp->sctp_asoc_list, stcb, sctp_tcblist);
4251 if (inp->sctp_tcbhash != NULL) {
4252 head = &inp->sctp_tcbhash[SCTP_PCBHASH_ALLADDR(stcb->rport,
4253 inp->sctp_hashmark)];
4292 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
4302 if (stcb != NULL && (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)) {
4303 inp->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
4304 soisconnecting(inp->sctp_socket);
4316 inp = stcb->sctp_ep;
4317 asoc = &stcb->asoc;
4318 asoc->numnets--;
4319 TAILQ_REMOVE(&asoc->nets, net, sctp_next);
4320 if (net == asoc->primary_destination) {
4324 lnet = TAILQ_FIRST(&asoc->nets);
4330 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
4332 sctp_is_mobility_feature_on(stcb->sctp_ep,
4335 if (asoc->deleted_primary != NULL) {
4339 asoc->deleted_primary = net;
4340 atomic_add_int(&net->ref_count, 1);
4341 memset(&net->lastsa, 0, sizeof(net->lastsa));
4342 memset(&net->lastsv, 0, sizeof(net->lastsv));
4343 sctp_mobility_feature_on(stcb->sctp_ep,
4346 stcb->sctp_ep, stcb, NULL);
4350 asoc->primary_destination = sctp_find_alternate_net(stcb, lnet, 0);
4352 if (net == asoc->last_data_chunk_from) {
4354 asoc->last_data_chunk_from = TAILQ_FIRST(&asoc->nets);
4356 if (net == asoc->last_control_chunk_from) {
4358 asoc->last_control_chunk_from = NULL;
4360 if (net == asoc->last_net_cmt_send_started) {
4362 asoc->last_net_cmt_send_started = NULL;
4364 if (net == stcb->asoc.alternate) {
4365 sctp_free_remote_addr(stcb->asoc.alternate);
4366 stcb->asoc.alternate = NULL;
4372 net->dest_state |= SCTP_ADDR_BEING_DELETED;
4386 * (tasoc->asoc.nets) and then if it is there, we do a LIST_REMOVE
4393 asoc = &stcb->asoc;
4396 TAILQ_FOREACH_SAFE(net, &asoc->nets, sctp_next, nnet) {
4397 if (net->ro._l_addr.sa.sa_family != remaddr->sa_family) {
4400 if (sctp_cmpaddr((struct sockaddr *)&net->ro._l_addr,
4403 if (asoc->numnets < 2) {
4405 return (-1);
4413 return (-2);
4427 if ((twait_block->vtag_block[i].tv_sec_at_expire >= now) &&
4428 (twait_block->vtag_block[i].v_tag == tag) &&
4429 (twait_block->vtag_block[i].lport == lport) &&
4430 (twait_block->vtag_block[i].rport == rport)) {
4442 vtag_block->tv_sec_at_expire = time;
4443 vtag_block->v_tag = tag;
4444 vtag_block->lport = lport;
4445 vtag_block->rport = rport;
4466 if ((twait_block->vtag_block[i].v_tag == 0) && !set) {
4467 sctp_set_vtag_block(twait_block->vtag_block + i, time, tag, lport, rport);
4471 if ((twait_block->vtag_block[i].v_tag != 0) &&
4472 (twait_block->vtag_block[i].tv_sec_at_expire < now.tv_sec)) {
4475 sctp_set_vtag_block(twait_block->vtag_block + i, 0, 0, 0, 0);
4478 sctp_set_vtag_block(twait_block->vtag_block + i, time, tag, lport, rport);
4500 sctp_set_vtag_block(twait_block->vtag_block, time, tag, lport, rport);
4512 control->on_strm_q = 0;
4513 if (control->on_read_q == 0) {
4514 sctp_free_remote_addr(control->whoFrom);
4515 if (control->data) {
4516 sctp_m_freem(control->data);
4517 control->data = NULL;
4521 TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, nchk) {
4522 TAILQ_REMOVE(&control->reasm, chk, sctp_next);
4523 if (chk->data) {
4524 sctp_m_freem(chk->data);
4525 chk->data = NULL;
4527 if (chk->holds_key_ref)
4528 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
4529 sctp_free_remote_addr(chk->whoTo);
4538 if (control->on_read_q == 0) {
4544 /*-
4545 * Free the association after un-hashing the remote port. This
4549 * it unlocks it. It will return NON-zero if it either destroyed the
4574 if (stcb->asoc.state == 0) {
4578 /* there is no asoc, really TSNH :-0 */
4581 if (stcb->asoc.alternate) {
4582 sctp_free_remote_addr(stcb->asoc.alternate);
4583 stcb->asoc.alternate = NULL;
4586 if (stcb->freed_from_where == 0) {
4588 stcb->freed_from_where = from_location;
4592 asoc = &stcb->asoc;
4593 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
4594 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
4598 so = inp->sctp_socket;
4601 * We used timer based freeing if a reader or writer is in the way.
4602 * So we first check if we are actually being called from a timer,
4605 if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) &&
4608 * is it the timer driving us? if so are the reader/writers
4611 if (stcb->asoc.refcnt) {
4625 if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0) {
4628 TAILQ_FOREACH(sq, &inp->read_queue, next) {
4629 if (sq->stcb == stcb) {
4630 sq->do_not_ref_stcb = 1;
4631 sq->sinfo_cumtsn = stcb->asoc.cumulative_tsn;
4636 if (sq->end_added == 0) {
4637 /* Held for PD-API, clear that. */
4638 sq->pdapi_aborted = 1;
4639 sq->held_length = 0;
4647 /* Add an end to wake them */
4648 sq->end_added = 1;
4653 if (stcb->block_entry) {
4655 stcb->block_entry->error = ECONNRESET;
4656 stcb->block_entry = NULL;
4659 if ((stcb->asoc.refcnt) || (stcb->asoc.state & SCTP_STATE_IN_ACCEPT_QUEUE)) {
4664 if ((stcb->asoc.refcnt) ||
4665 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
4666 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
4670 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
4671 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
4675 /* Wake any reader/writers */
4695 * timer and blow out above thus assuring us that we hold exclusive
4698 * timer a passing stranger may have started :-S
4701 atomic_add_int(&stcb->asoc.refcnt, 1);
4709 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
4710 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
4714 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
4715 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
4720 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
4721 inp->sctp_flags &= ~SCTP_PCB_FLAGS_CONNECTED;
4722 inp->sctp_flags |= SCTP_PCB_FLAGS_WAS_CONNECTED;
4724 SOCKBUF_LOCK(&so->so_rcv);
4725 so->so_state &= ~(SS_ISCONNECTING |
4728 so->so_state |= SS_ISDISCONNECTED;
4742 /* re-increment the lock */
4744 atomic_subtract_int(&stcb->asoc.refcnt, 1);
4746 if (stcb->asoc.refcnt) {
4756 asoc->state = 0;
4757 if (inp->sctp_tcbhash) {
4760 if (stcb->asoc.in_asocid_hash) {
4763 if (inp->sctp_socket == NULL) {
4764 stcb->sctp_socket = NULL;
4774 sctp_add_vtag_to_timewait(asoc->my_vtag, inp->sctp_lport, stcb->rport);
4786 for (i = 0; i < asoc->streamoutcnt; i++) {
4789 outs = &asoc->strmout[i];
4791 TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) {
4792 atomic_subtract_int(&asoc->stream_queue_cnt, 1);
4793 TAILQ_REMOVE(&outs->outqueue, sp, next);
4794 stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, outs, sp);
4796 if (sp->data) {
4798 /* Still an open socket - report */
4802 if (sp->data) {
4803 sctp_m_freem(sp->data);
4804 sp->data = NULL;
4805 sp->tail_mbuf = NULL;
4806 sp->length = 0;
4809 if (sp->net) {
4810 sctp_free_remote_addr(sp->net);
4811 sp->net = NULL;
4817 TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) {
4818 TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp);
4821 TAILQ_FOREACH_SAFE(sq, &asoc->pending_reply_queue, next, nsq) {
4822 TAILQ_REMOVE(&asoc->pending_reply_queue, sq, next);
4823 if (sq->data) {
4824 sctp_m_freem(sq->data);
4825 sq->data = NULL;
4827 sctp_free_remote_addr(sq->whoFrom);
4828 sq->whoFrom = NULL;
4829 sq->stcb = NULL;
4834 TAILQ_FOREACH_SAFE(chk, &asoc->free_chunks, sctp_next, nchk) {
4835 TAILQ_REMOVE(&asoc->free_chunks, chk, sctp_next);
4836 if (chk->data) {
4837 sctp_m_freem(chk->data);
4838 chk->data = NULL;
4840 if (chk->holds_key_ref)
4841 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
4845 asoc->free_chunk_cnt--;
4849 TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
4850 if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
4851 asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
4854 panic("No chunks on the queues for sid %u.", chk->rec.data.sid);
4857 TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
4858 if (chk->data) {
4864 if (chk->data) {
4865 sctp_m_freem(chk->data);
4866 chk->data = NULL;
4869 if (chk->holds_key_ref)
4870 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
4871 if (chk->whoTo) {
4872 sctp_free_remote_addr(chk->whoTo);
4873 chk->whoTo = NULL;
4880 TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
4881 if (chk->sent != SCTP_DATAGRAM_NR_ACKED) {
4882 if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
4883 asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
4886 panic("No chunks on the queues for sid %u.", chk->rec.data.sid);
4890 TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
4891 if (chk->data) {
4897 if (chk->data) {
4898 sctp_m_freem(chk->data);
4899 chk->data = NULL;
4902 if (chk->holds_key_ref)
4903 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
4904 sctp_free_remote_addr(chk->whoTo);
4910 for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
4911 if (stcb->asoc.strmout[i].chunks_on_queues > 0) {
4912 panic("%u chunks left for stream %u.", stcb->asoc.strmout[i].chunks_on_queues, i);
4917 TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) {
4918 TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
4919 if (chk->data) {
4920 sctp_m_freem(chk->data);
4921 chk->data = NULL;
4923 if (chk->holds_key_ref)
4924 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
4925 sctp_free_remote_addr(chk->whoTo);
4931 TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) {
4932 TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next);
4933 if (chk->data) {
4934 sctp_m_freem(chk->data);
4935 chk->data = NULL;
4937 if (chk->holds_key_ref)
4938 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
4939 sctp_free_remote_addr(chk->whoTo);
4944 if (asoc->mapping_array) {
4945 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
4946 asoc->mapping_array = NULL;
4948 if (asoc->nr_mapping_array) {
4949 SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
4950 asoc->nr_mapping_array = NULL;
4953 if (asoc->strmout) {
4954 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
4955 asoc->strmout = NULL;
4957 asoc->strm_realoutsize = asoc->streamoutcnt = 0;
4958 if (asoc->strmin) {
4959 for (i = 0; i < asoc->streamincnt; i++) {
4960 sctp_clean_up_stream(stcb, &asoc->strmin[i].inqueue);
4961 sctp_clean_up_stream(stcb, &asoc->strmin[i].uno_inqueue);
4963 SCTP_FREE(asoc->strmin, SCTP_M_STRMI);
4964 asoc->strmin = NULL;
4966 asoc->streamincnt = 0;
4967 TAILQ_FOREACH_SAFE(net, &asoc->nets, sctp_next, nnet) {
4973 TAILQ_REMOVE(&asoc->nets, net, sctp_next);
4976 LIST_FOREACH_SAFE(laddr, &asoc->sctp_restricted_addrs, sctp_nxt_addr, naddr) {
4982 TAILQ_FOREACH_SAFE(aparam, &asoc->asconf_queue, next, naparam) {
4984 TAILQ_REMOVE(&asoc->asconf_queue, aparam, next);
4987 TAILQ_FOREACH_SAFE(aack, &asoc->asconf_ack_sent, next, naack) {
4989 TAILQ_REMOVE(&asoc->asconf_ack_sent, aack, next);
4990 if (aack->data != NULL) {
4991 sctp_m_freem(aack->data);
4996 if (asoc->local_hmacs)
4997 sctp_free_hmaclist(asoc->local_hmacs);
4998 if (asoc->peer_hmacs)
4999 sctp_free_hmaclist(asoc->peer_hmacs);
5001 if (asoc->local_auth_chunks)
5002 sctp_free_chunklist(asoc->local_auth_chunks);
5003 if (asoc->peer_auth_chunks)
5004 sctp_free_chunklist(asoc->peer_auth_chunks);
5006 sctp_free_authinfo(&asoc->authinfo);
5008 LIST_FOREACH_SAFE(shared_key, &asoc->shared_keys, next, nshared_key) {
5024 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
5029 LIST_INSERT_HEAD(&inp->sctp_asoc_free_list, stcb, sctp_tcblist);
5036 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
5043 * This will start the kill timer (if we are the
5071 * FIX: if we allow assoc-level bindx(), then this needs to be fixed to use
5087 * only want to read the sctp_flags, which is either bound-all or
5091 inp = stcb->sctp_ep;
5092 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
5096 * are bound-all you still might need to obey the V4--V6
5097 * flags??? IMO this bound-all stuff needs to be removed!
5102 switch (destaddr->sa_family) {
5105 answer = inp->ip_inp.inp.inp_vflag & INP_IPV6;
5110 answer = inp->ip_inp.inp.inp_vflag & INP_IPV4;
5130 inp->ip_inp.inp.inp_vflag = 0;
5132 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
5133 if (laddr->ifa == NULL) {
5139 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
5142 switch (laddr->ifa->address.sa.sa_family) {
5145 inp->ip_inp.inp.inp_vflag |= INP_IPV6;
5150 inp->ip_inp.inp.inp_vflag |= INP_IPV4;
5172 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
5177 if (ifa->address.sa.sa_family == AF_INET6) {
5178 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
5179 /* Can't bind a non-useable addr. */
5185 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
5186 if (laddr->ifa == ifa) {
5194 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, action);
5197 inp->laddr_count++;
5199 switch (ifa->address.sa.sa_family) {
5202 inp->ip_inp.inp.inp_vflag |= INP_IPV6;
5207 inp->ip_inp.inp.inp_vflag |= INP_IPV4;
5213 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
5230 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
5232 if (net->dest_state & SCTP_ADDR_UNCONFIRMED)
5235 (struct sockaddr *)&net->ro._l_addr)) {
5237 stcb->asoc.primary_destination = net;
5254 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
5258 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
5259 if (laddr->ifa == ifa) {
5264 if (fnd && (inp->laddr_count < 2)) {
5278 if (inp->next_addr_touse == laddr)
5280 inp->next_addr_touse = NULL;
5283 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
5287 if (stcb->asoc.last_used_address == laddr)
5289 stcb->asoc.last_used_address = NULL;
5294 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
5295 if (net->ro._s_addr == laddr->ifa) {
5297 RO_NHFREE(&net->ro);
5298 sctp_free_ifa(net->ro._s_addr);
5299 net->ro._s_addr = NULL;
5300 net->src_addr_selected = 0;
5307 inp->laddr_count--;
5317 * ASCONF-ACK response) and cannot be used as a valid source address.
5329 list = &stcb->asoc.sctp_restricted_addrs;
5332 if (ifa->address.sa.sa_family == AF_INET6) {
5333 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
5334 /* Can't bind a non-existent addr. */
5341 if (laddr->ifa == ifa) {
5367 * up is changing :-D
5370 inp = stcb->sctp_ep;
5372 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) &&
5374 if (stcb->sctp_ep->laddr_count < 2) {
5379 LIST_FOREACH(laddr, &stcb->asoc.sctp_restricted_addrs, sctp_nxt_addr) {
5381 if (laddr->ifa == NULL)
5383 if (laddr->ifa == ifa) {
5422 qent->vn = curvnet;
5423 qent->m = m;
5424 qent->off = off;
5425 qent->v6 = 0;
5429 TAILQ_INSERT_TAIL(&wkq->que, qent, next);
5430 if (wkq->running == 0) {
5435 wakeup(&wkq->running);
5452 wkq->running = 0;
5453 msleep(&wkq->running,
5454 &wkq->core_mtx,
5458 /* Bind to our cpu */
5460 sched_bind(curthread, wkq->cpuid);
5469 wkq->running = 1;
5470 qent = TAILQ_FIRST(&wkq->que);
5472 TAILQ_REMOVE(&wkq->que, qent, next);
5474 CURVNET_SET(qent->vn);
5475 m = qent->m;
5476 off = qent->off;
5477 v6 = qent->v6;
5488 wkq->running = 0;
5489 if (!TAILQ_EMPTY(&wkq->que)) {
5493 msleep(&wkq->running,
5494 &wkq->core_mtx,
5502 int i, cpu;
5534 CPU_FOREACH(cpu) {
5535 sctp_cpuarry[i] = cpu;
5540 CPU_FOREACH(cpu) {
5542 (void *)&sctp_mcore_workers[cpu],
5543 &sctp_mcore_workers[cpu].thread_proc,
5683 SCTP_OS_TIMER_INIT(&SCTP_BASE_INFO(addr_wq_timer.timer));
5736 * wait to re-acquire the lock.
5746 if (it->vn != curvnet) {
5750 if (it->function_atend != NULL) {
5751 (*it->function_atend) (it->pointer, it->val);
5758 (sctp_it_ctl.cur_it->vn == curvnet)) {
5762 SCTP_OS_TIMER_STOP_DRAIN(&SCTP_BASE_INFO(addr_wq_timer.timer));
5767 if (wi->action == SCTP_DEL_IP_ADDRESS) {
5768 SCTP_FREE(wi->ifa, SCTP_M_IFA);
5781 LIST_FOREACH_SAFE(ifn, &vrf->ifnlist, next_ifn, nifn) {
5782 LIST_FOREACH_SAFE(ifa, &ifn->ifalist, next_ifa, nifa) {
5793 SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark);
5863 * with either INIT or INIT-ACK's as long as the m points to the IP
5907 sin.sin_port = stcb->rport;
5913 sin6.sin6_port = stcb->rport;
5929 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
5931 net->dest_state |= SCTP_ADDR_NOT_IN_ASSOC;
5934 inp = stcb->sctp_ep;
5935 atomic_add_int(&stcb->asoc.refcnt, 1);
5937 atomic_subtract_int(&stcb->asoc.refcnt, 1);
5939 if ((stcb_tmp == NULL && inp == stcb->sctp_ep) || inp == NULL) {
5942 switch (sa->sa_family) {
5945 if (stcb->asoc.scope.ipv4_addr_legal) {
5947 return (-1);
5954 if (stcb->asoc.scope.ipv6_addr_legal) {
5956 return (-2);
5966 net_tmp->dest_state &= ~SCTP_ADDR_NOT_IN_ASSOC;
5971 return (-3);
5974 if (stcb->asoc.state == 0) {
5976 return (-4);
5981 ptype = ntohs(phdr->param_type);
5982 plen = ntohs(phdr->param_length);
5995 if (stcb->asoc.scope.ipv4_addr_legal) {
6004 return (-5);
6007 sin.sin_addr.s_addr = p4->addr;
6009 /* Skip multi-cast addresses */
6017 inp = stcb->sctp_ep;
6018 atomic_add_int(&stcb->asoc.refcnt, 1);
6021 atomic_subtract_int(&stcb->asoc.refcnt, 1);
6023 if ((stcb_tmp == NULL && inp == stcb->sctp_ep) ||
6036 if (stcb->asoc.state == 0) {
6038 return (-7);
6041 return (-8);
6044 if (stcb->asoc.state == 0) {
6046 return (-10);
6050 net->dest_state &=
6071 sctp_abort_an_association(stcb_tmp->sctp_ep,
6079 if (stcb->asoc.state == 0) {
6081 return (-12);
6083 return (-13);
6090 if (stcb->asoc.scope.ipv6_addr_legal) {
6099 return (-14);
6102 memcpy((caddr_t)&sin6.sin6_addr, p6->addr,
6103 sizeof(p6->addr));
6105 /* Skip multi-cast addresses */
6116 inp = stcb->sctp_ep;
6117 atomic_add_int(&stcb->asoc.refcnt, 1);
6120 atomic_subtract_int(&stcb->asoc.refcnt, 1);
6122 (inp == stcb->sctp_ep || inp == NULL)) {
6128 if (stcb->asoc.state == 0) {
6130 return (-16);
6137 return (-17);
6144 if (stcb->asoc.state == 0) {
6146 return (-19);
6150 net->dest_state &=
6171 sctp_abort_an_association(stcb_tmp->sctp_ep,
6178 if (stcb->asoc.state == 0) {
6180 return (-21);
6182 return (-22);
6190 if (stcb->asoc.state != SCTP_STATE_OPEN) {
6198 stcb->asoc.peers_adaptation = ntohl(aip->indication);
6199 stcb->asoc.adaptation_needed = 1;
6210 if (stcb->asoc.asconf_supported == 0) {
6211 return (-100);
6214 return (-23);
6217 return (-101);
6223 return (-24);
6226 lptype = ntohs(fee->addrp.ph.param_type);
6232 SCTP_PRINTF("Sizeof setprim in init/init ack not %d but %d - ignored\n",
6237 sin.sin_addr.s_addr = fii->addrp.addr;
6246 SCTP_PRINTF("Sizeof setprim (v6) in init/init ack not %d but %d - ignored\n",
6251 fee->addrp.addr,
6252 sizeof(fee->addrp.addr));
6264 stcb->asoc.peer_supports_nat = 1;
6266 /* Peer supports pr-sctp */
6282 if ((ntohl(zero_chksum_p->edmid) != SCTP_EDMID_NONE) &&
6283 (ntohl(zero_chksum_p->edmid) == stcb->asoc.rcv_edmid)) {
6284 stcb->asoc.snd_edmid = stcb->asoc.rcv_edmid;
6294 return (-35);
6299 return (-25);
6302 num_ent = plen - sizeof(struct sctp_paramhdr);
6304 switch (pr_supported->chunk_types[i]) {
6345 return (-26);
6347 random_len = plen - sizeof(*p_random);
6351 return (-27);
6368 return (-28);
6370 hmacs_len = plen - sizeof(*hmacs);
6371 num_hmacs = hmacs_len / sizeof(hmacs->hmac_ids[0]);
6374 return (-29);
6376 if (stcb->asoc.peer_hmacs != NULL)
6377 sctp_free_hmaclist(stcb->asoc.peer_hmacs);
6378 stcb->asoc.peer_hmacs = sctp_alloc_hmaclist(num_hmacs);
6379 if (stcb->asoc.peer_hmacs != NULL) {
6381 (void)sctp_auth_add_hmacid(stcb->asoc.peer_hmacs,
6382 ntohs(hmacs->hmac_ids[i]));
6399 return (-30);
6401 num_chunks = plen - sizeof(*chunks);
6402 if (stcb->asoc.peer_auth_chunks != NULL)
6403 sctp_clear_chunklist(stcb->asoc.peer_auth_chunks);
6405 stcb->asoc.peer_auth_chunks = sctp_alloc_chunklist();
6407 (void)sctp_auth_add_chunk(chunks->chunk_types[i],
6408 stcb->asoc.peer_auth_chunks);
6409 /* record asconf/asconf-ack if listed */
6410 if (chunks->chunk_types[i] == SCTP_ASCONF)
6412 if (chunks->chunk_types[i] == SCTP_ASCONF_ACK)
6433 * when the INIT or INIT-ACK was first seen.
6448 TAILQ_FOREACH_SAFE(net, &stcb->asoc.nets, sctp_next, nnet) {
6449 if ((net->dest_state & SCTP_ADDR_NOT_IN_ASSOC) ==
6453 stcb->asoc.numnets--;
6454 TAILQ_REMOVE(&stcb->asoc.nets, net, sctp_next);
6455 if (net == stcb->asoc.alternate) {
6456 sctp_free_remote_addr(stcb->asoc.alternate);
6457 stcb->asoc.alternate = NULL;
6459 if (net == stcb->asoc.primary_destination) {
6460 stcb->asoc.primary_destination = NULL;
6466 if ((stcb->asoc.ecn_supported == 1) &&
6468 stcb->asoc.ecn_supported = 0;
6470 if ((stcb->asoc.prsctp_supported == 1) &&
6472 stcb->asoc.prsctp_supported = 0;
6474 if ((stcb->asoc.auth_supported == 1) &&
6477 stcb->asoc.auth_supported = 0;
6479 if ((stcb->asoc.asconf_supported == 1) &&
6481 (stcb->asoc.auth_supported == 0) ||
6483 stcb->asoc.asconf_supported = 0;
6485 if ((stcb->asoc.reconfig_supported == 1) &&
6487 stcb->asoc.reconfig_supported = 0;
6489 if ((stcb->asoc.idata_supported == 1) &&
6491 stcb->asoc.idata_supported = 0;
6493 if ((stcb->asoc.nrsack_supported == 1) &&
6495 stcb->asoc.nrsack_supported = 0;
6497 if ((stcb->asoc.pktdrop_supported == 1) &&
6499 stcb->asoc.pktdrop_supported = 0;
6504 return (-31);
6508 return (-32);
6512 return (-33);
6524 memcpy(new_key->key, p_random, keylen);
6530 memcpy(new_key->key + keylen, chunks,
6536 memcpy(new_key->key + keylen, hmacs,
6541 return (-34);
6543 if (stcb->asoc.authinfo.peer_random != NULL)
6544 sctp_free_key(stcb->asoc.authinfo.peer_random);
6545 stcb->asoc.authinfo.peer_random = new_key;
6546 sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.assoc_keyid);
6547 sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.recv_keyid);
6562 return (-1);
6565 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
6567 net->dest_state |= SCTP_ADDR_REQ_PRIMARY;
6570 stcb->asoc.primary_destination = net;
6571 if (((net->dest_state & SCTP_ADDR_PF) == 0) &&
6572 (stcb->asoc.alternate != NULL)) {
6573 sctp_free_remote_addr(stcb->asoc.alternate);
6574 stcb->asoc.alternate = NULL;
6576 net = TAILQ_FIRST(&stcb->asoc.nets);
6577 if (net != stcb->asoc.primary_destination) {
6583 TAILQ_REMOVE(&stcb->asoc.nets, stcb->asoc.primary_destination, sctp_next);
6584 TAILQ_INSERT_HEAD(&stcb->asoc.nets, stcb->asoc.primary_destination, sctp_next);
6604 * this assumption, but we will go with it for now :-)
6606 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
6609 if (stcb->asoc.my_vtag == tag) {
6611 if (stcb->rport != rport) {
6614 if (stcb->sctp_ep->sctp_lport != lport) {
6621 return (!sctp_is_in_timewait(tag, lport, rport, now->tv_sec));
6639 /* We look for anything larger than the cum-ack + 1 */
6641 asoc = &stcb->asoc;
6642 if (asoc->cumulative_tsn == asoc->highest_tsn_inside_map) {
6647 cumulative_tsn_p1 = asoc->cumulative_tsn + 1;
6650 for (strmat = 0; strmat < asoc->streamincnt; strmat++) {
6651 TAILQ_FOREACH_SAFE(control, &asoc->strmin[strmat].inqueue, next_instrm, ncontrol) {
6653 if (control->on_strm_q != SCTP_ON_ORDERED) {
6654 panic("Huh control: %p on_q: %d -- not ordered?",
6655 control, control->on_strm_q);
6658 if (SCTP_TSN_GT(control->sinfo_tsn, cumulative_tsn_p1)) {
6659 /* Yep it is above cum-ack */
6661 SCTP_CALC_TSN_TO_GAP(gap, control->sinfo_tsn, asoc->mapping_array_base_tsn);
6662 KASSERT(control->length > 0, ("control has zero length"));
6663 if (asoc->size_on_all_streams >= control->length) {
6664 asoc->size_on_all_streams -= control->length;
6667 panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length);
6669 asoc->size_on_all_streams = 0;
6672 sctp_ucount_decr(asoc->cnt_on_all_streams);
6673 SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
6674 if (control->on_read_q) {
6675 TAILQ_REMOVE(&stcb->sctp_ep->read_queue, control, next);
6676 control->on_read_q = 0;
6678 TAILQ_REMOVE(&asoc->strmin[strmat].inqueue, control, next_instrm);
6679 control->on_strm_q = 0;
6680 if (control->data) {
6681 sctp_m_freem(control->data);
6682 control->data = NULL;
6684 sctp_free_remote_addr(control->whoFrom);
6686 TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, nchk) {
6688 SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.tsn, asoc->mapping_array_base_tsn);
6689 KASSERT(chk->send_size > 0, ("chunk has zero length"));
6690 if (asoc->size_on_reasm_queue >= chk->send_size) {
6691 asoc->size_on_reasm_queue -= chk->send_size;
6694 panic("size_on_reasm_queue = %u smaller than chunk length %u", asoc->size_on_reasm_queue, chk->send_size);
6696 asoc->size_on_reasm_queue = 0;
6699 sctp_ucount_decr(asoc->cnt_on_reasm_queue);
6700 SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
6701 TAILQ_REMOVE(&control->reasm, chk, sctp_next);
6702 if (chk->data) {
6703 sctp_m_freem(chk->data);
6704 chk->data = NULL;
6711 TAILQ_FOREACH_SAFE(control, &asoc->strmin[strmat].uno_inqueue, next_instrm, ncontrol) {
6713 if (control->on_strm_q != SCTP_ON_UNORDERED) {
6714 panic("Huh control: %p on_q: %d -- not unordered?",
6715 control, control->on_strm_q);
6718 if (SCTP_TSN_GT(control->sinfo_tsn, cumulative_tsn_p1)) {
6719 /* Yep it is above cum-ack */
6721 SCTP_CALC_TSN_TO_GAP(gap, control->sinfo_tsn, asoc->mapping_array_base_tsn);
6722 KASSERT(control->length > 0, ("control has zero length"));
6723 if (asoc->size_on_all_streams >= control->length) {
6724 asoc->size_on_all_streams -= control->length;
6727 panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length);
6729 asoc->size_on_all_streams = 0;
6732 sctp_ucount_decr(asoc->cnt_on_all_streams);
6733 SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
6734 if (control->on_read_q) {
6735 TAILQ_REMOVE(&stcb->sctp_ep->read_queue, control, next);
6736 control->on_read_q = 0;
6738 TAILQ_REMOVE(&asoc->strmin[strmat].uno_inqueue, control, next_instrm);
6739 control->on_strm_q = 0;
6740 if (control->data) {
6741 sctp_m_freem(control->data);
6742 control->data = NULL;
6744 sctp_free_remote_addr(control->whoFrom);
6746 TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, nchk) {
6748 SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.tsn, asoc->mapping_array_base_tsn);
6749 KASSERT(chk->send_size > 0, ("chunk has zero length"));
6750 if (asoc->size_on_reasm_queue >= chk->send_size) {
6751 asoc->size_on_reasm_queue -= chk->send_size;
6754 panic("size_on_reasm_queue = %u smaller than chunk length %u", asoc->size_on_reasm_queue, chk->send_size);
6756 asoc->size_on_reasm_queue = 0;
6759 sctp_ucount_decr(asoc->cnt_on_reasm_queue);
6760 SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
6761 TAILQ_REMOVE(&control->reasm, chk, sctp_next);
6762 if (chk->data) {
6763 sctp_m_freem(chk->data);
6764 chk->data = NULL;
6774 for (i = asoc->highest_tsn_inside_map; SCTP_TSN_GE(i, asoc->mapping_array_base_tsn); i--) {
6775 SCTP_CALC_TSN_TO_GAP(gap, i, asoc->mapping_array_base_tsn);
6776 if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
6777 asoc->highest_tsn_inside_map = i;
6783 asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1;
6789 * a p-d-api up. An attacker COULD send enough in to
6790 * initiate the PD-API and then send a bunch of stuff to
6793 * to do this I then have to back-track and un-deliver
6794 * sequence numbers in streams.. el-yucko. I think for now
6797 * abort the P-D-API with a notification and then deliver
6807 * asoc->highest_tsn_inside_map?
6809 asoc->last_revoke_count = cnt;
6810 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL,
6814 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_DRAIN, SCTP_SO_NOT_LOCKED);
6817 * Another issue, in un-setting the TSN's in the mapping array we
6822 * we will recover once we get our cum-ack above and all this stuff
6859 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
6902 return (-1);
6907 return (-1);
6913 return (-1);
6916 it->function_assoc = af;
6917 it->function_inp = inpf;
6919 it->done_current_ep = 0;
6921 it->done_current_ep = 1;
6922 it->function_atend = ef;
6923 it->pointer = argp;
6924 it->val = argi;
6925 it->pcb_flags = pcb_state;
6926 it->pcb_features = pcb_features;
6927 it->asoc_state = asoc_state;
6928 it->function_inp_end = inpe;
6929 it->no_chunk_output = chunk_output_off;
6930 it->vn = curvnet;
6933 it->inp = s_inp;
6934 SCTP_INP_INCR_REF(it->inp);
6935 it->iterator_flags = SCTP_ITERATOR_DO_SINGLE_INP;
6938 it->inp = LIST_FIRST(&SCTP_BASE_INFO(listhead));
6939 if (it->inp) {
6940 SCTP_INP_INCR_REF(it->inp);
6943 it->iterator_flags = SCTP_ITERATOR_DO_ALL_INP;
6951 return (-1);
6972 old_flags = inp->sctp_flags;
6974 } while (atomic_cmpset_int(&inp->sctp_flags, old_flags, new_flags) == 0);