diff --git a/netwerk/sctp/src/moz.yaml b/netwerk/sctp/src/moz.yaml --- a/netwerk/sctp/src/moz.yaml +++ b/netwerk/sctp/src/moz.yaml @@ -8,12 +8,12 @@ name: sctp description: userland SCTP stack url: https://github.com/sctplab/usrsctp/blob/master/Manual.md - release: 1330843b6ffd0c5c2d7483b07050049eedda8077 (2024-08-03T12:00:29Z). - revision: 1330843b6ffd0c5c2d7483b07050049eedda8077 + release: fd070e05a7474f38c7fecdf4d4b6005d2547ee00 (2025-10-16T18:51:48Z). + revision: fd070e05a7474f38c7fecdf4d4b6005d2547ee00 license: BSD-3-Clause vendoring: url: https://github.com/sctplab/usrsctp diff --git a/netwerk/sctp/src/netinet/sctp.h b/netwerk/sctp/src/netinet/sctp.h --- a/netwerk/sctp/src/netinet/sctp.h +++ b/netwerk/sctp/src/netinet/sctp.h @@ -36,13 +36,10 @@ #define _NETINET_SCTP_H_ #if defined(__APPLE__) || defined(__linux__) #include #endif -#if defined(__FreeBSD__) && !defined(__Userspace__) -#include -#endif #include #if !defined(_WIN32) #define SCTP_PACKED __attribute__((packed)) #else diff --git a/netwerk/sctp/src/netinet/sctp_asconf.c b/netwerk/sctp/src/netinet/sctp_asconf.c --- a/netwerk/sctp/src/netinet/sctp_asconf.c +++ b/netwerk/sctp/src/netinet/sctp_asconf.c @@ -1345,17 +1345,17 @@ TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next); #ifdef SCTP_DEBUG if (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_ASCONF2) { if (type == SCTP_ADD_IP_ADDRESS) { - SCTP_PRINTF("asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: "); + SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: "); SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa); } else if (type == SCTP_DEL_IP_ADDRESS) { - SCTP_PRINTF("asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: "); + SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: "); SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa); } else { - SCTP_PRINTF("asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: "); + SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: "); SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa); } } #endif diff --git a/netwerk/sctp/src/netinet/sctp_bsd_addr.c b/netwerk/sctp/src/netinet/sctp_bsd_addr.c --- a/netwerk/sctp/src/netinet/sctp_bsd_addr.c +++ b/netwerk/sctp/src/netinet/sctp_bsd_addr.c @@ -711,16 +711,15 @@ ifa->ifa_ifp->if_index, ifa->ifa_ifp->if_type, ifa->ifa_ifp->if_xname, #endif (void *)ifa, ifa->ifa_addr, ifa_flags, 1); } else { sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr, + (void *)ifa->ifa_ifp, #if defined(__APPLE__) && !defined(__Userspace__) - ifnet_index(ifa->ifa_ifp), - ifnet_name(ifa->ifa_ifp)); + ifnet_index(ifa->ifa_ifp)); #else - ifa->ifa_ifp->if_index, - ifa->ifa_ifp->if_xname); + ifa->ifa_ifp->if_index); #endif /* We don't bump refcount here so when it completes * the final delete will happen. */ diff --git a/netwerk/sctp/src/netinet/sctp_cc_functions.c b/netwerk/sctp/src/netinet/sctp_cc_functions.c --- a/netwerk/sctp/src/netinet/sctp_cc_functions.c +++ b/netwerk/sctp/src/netinet/sctp_cc_functions.c @@ -47,10 +47,14 @@ #include #if defined(__FreeBSD__) && !defined(__Userspace__) #include #endif +#if defined(_WIN32) && defined(__MINGW32__) +#include +#endif + #define SHIFT_MPTCP_MULTI_N 40 #define SHIFT_MPTCP_MULTI_Z 16 #define SHIFT_MPTCP_MULTI 8 #ifdef KDTRACE_HOOKS diff --git a/netwerk/sctp/src/netinet/sctp_indata.c b/netwerk/sctp/src/netinet/sctp_indata.c --- a/netwerk/sctp/src/netinet/sctp_indata.c +++ b/netwerk/sctp/src/netinet/sctp_indata.c @@ -51,10 +51,13 @@ #include #include #if defined(__FreeBSD__) && !defined(__Userspace__) #include #endif +#if defined(_WIN32) && defined(__MINGW32__) +#include +#endif /* * NOTES: On the outbound side of things I need to check the sack timer to * see if I should generate a sack into the chunk queue (if I have data to * send that is and will be sending it .. for bundling. * diff --git a/netwerk/sctp/src/netinet/sctp_input.c b/netwerk/sctp/src/netinet/sctp_input.c --- a/netwerk/sctp/src/netinet/sctp_input.c +++ b/netwerk/sctp/src/netinet/sctp_input.c @@ -55,10 +55,13 @@ #endif #endif #if defined(__FreeBSD__) && !defined(__Userspace__) #include #endif +#if defined(_WIN32) && defined(__MINGW32__) +#include +#endif static void sctp_stop_all_cookie_timers(struct sctp_tcb *stcb) { struct sctp_nets *net; @@ -6340,11 +6343,15 @@ if (SCTP_IS_IT_BROADCAST(dst.sin_addr, m)) { goto out; } ecn_bits = ip->ip_tos; #if defined(__FreeBSD__) && !defined(__Userspace__) - if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) { + if (m->m_pkthdr.csum_flags & (CSUM_SCTP_VALID | CSUM_IP_SCTP)) { + /* + * Packet with CSUM_IP_SCTP were sent from local host using + * checksum offloading. Checksum not required. + */ SCTP_STAT_INCR(sctps_recvhwcrc); compute_crc = 0; } else { #else if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) && diff --git a/netwerk/sctp/src/netinet/sctp_os_userspace.h b/netwerk/sctp/src/netinet/sctp_os_userspace.h --- a/netwerk/sctp/src/netinet/sctp_os_userspace.h +++ b/netwerk/sctp/src/netinet/sctp_os_userspace.h @@ -273,10 +273,16 @@ ((ro)->ro_rt && (ro)->ro_rt->rt_ifp) /******************************************/ #define SCTP_GET_IF_INDEX_FROM_ROUTE(ro) 1 /* compiles... TODO use routing socket to determine */ +#if defined(__APPLE__) && defined(__POWERPC__) +#ifndef WORDS_BIGENDIAN +#define WORDS_BIGENDIAN +#endif +#endif + #define BIG_ENDIAN 1 #define LITTLE_ENDIAN 0 #ifdef WORDS_BIGENDIAN #define BYTE_ORDER BIG_ENDIAN #else @@ -1143,10 +1149,17 @@ ((tvp)->tv_sec cmp (uvp)->tv_sec)) #endif #define SCTP_IS_LISTENING(inp) ((inp->sctp_flags & SCTP_PCB_FLAGS_ACCEPTING) != 0) +static inline bool +in_broadcast(struct in_addr in) +{ + return (in.s_addr == htonl(INADDR_BROADCAST) || + in.s_addr == htonl(INADDR_ANY)); +} + #if defined(__APPLE__) || defined(__DragonFly__) || defined(__linux__) || defined(__native_client__) || defined(__NetBSD__) || defined(_WIN32) || defined(__Fuchsia__) || defined(__EMSCRIPTEN__) int timingsafe_bcmp(const void *, const void *, size_t); #endif diff --git a/netwerk/sctp/src/netinet/sctp_output.c b/netwerk/sctp/src/netinet/sctp_output.c --- a/netwerk/sctp/src/netinet/sctp_output.c +++ b/netwerk/sctp/src/netinet/sctp_output.c @@ -72,10 +72,13 @@ #endif #endif #if defined(__Userspace__) && defined(INET6) #include #endif +#if defined(_WIN32) && defined(__MINGW32__) +#include +#endif #if defined(__APPLE__) && !defined(__Userspace__) #if !(defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)) #define SCTP_MAX_LINKHDR 16 #endif #endif @@ -3760,12 +3763,11 @@ #ifdef HAVE_SIN_LEN sin.sin_len = sizeof(struct sockaddr_in); #endif sin.sin_port = stcb->rport; m_copydata(control, cmsg_data_off, sizeof(struct in_addr), (caddr_t)&sin.sin_addr); - if ((sin.sin_addr.s_addr == INADDR_ANY) || - (sin.sin_addr.s_addr == INADDR_BROADCAST) || + if (in_broadcast(sin.sin_addr) || IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) { *error = EINVAL; return (1); } if (sctp_add_remote_addr(stcb, (struct sockaddr *)&sin, NULL, stcb->asoc.port, @@ -3794,12 +3796,11 @@ return (1); } #ifdef INET if (IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) { in6_sin6_2_sin(&sin, &sin6); - if ((sin.sin_addr.s_addr == INADDR_ANY) || - (sin.sin_addr.s_addr == INADDR_BROADCAST) || + if (in_broadcast(sin.sin_addr) || IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) { *error = EINVAL; return (1); } if (sctp_add_remote_addr(stcb, (struct sockaddr *)&sin, NULL, stcb->asoc.port, @@ -4215,11 +4216,11 @@ } #if defined(__Userspace__) ip->ip_id = htons(SCTP_IP_ID(inp)++); #elif defined(__FreeBSD__) /* FreeBSD has a function for ip_id's */ - ip_fillid(ip); + ip_fillid(ip, V_ip_random_id); #elif defined(__APPLE__) #if RANDOM_IP_ID ip->ip_id = ip_randomid(); #else ip->ip_id = htons(ip_id++); @@ -11856,11 +11857,11 @@ ip->ip_off = htons(IP_DF); #endif #if defined(__Userspace__) ip->ip_id = htons(ip_id++); #elif defined(__FreeBSD__) - ip_fillid(ip); + ip_fillid(ip, V_ip_random_id); #elif defined(__APPLE__) #if RANDOM_IP_ID ip->ip_id = ip_randomid(); #else ip->ip_id = htons(ip_id++); @@ -15072,27 +15073,27 @@ } ifa = (struct ifaddr *)sifa->ifa; mask = (struct sockaddr_in *)(ifa->ifa_netmask); sin = &sifa->address.sin; srcnetaddr.s_addr = (sin->sin_addr.s_addr & mask->sin_addr.s_addr); - SCTPDBG(SCTP_DEBUG_OUTPUT1, "match_nexthop4: src address is "); + SCTPDBG(SCTP_DEBUG_OUTPUT2, "match_nexthop4: src address is "); SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, &sifa->address.sa); - SCTPDBG(SCTP_DEBUG_OUTPUT1, "network address is %x\n", srcnetaddr.s_addr); + SCTPDBG(SCTP_DEBUG_OUTPUT2, "network address is %x\n", srcnetaddr.s_addr); #if defined(__FreeBSD__) sin = &ro->ro_nh->gw4_sa; #else sin = (struct sockaddr_in *)ro->ro_rt->rt_gateway; #endif gwnetaddr.s_addr = (sin->sin_addr.s_addr & mask->sin_addr.s_addr); - SCTPDBG(SCTP_DEBUG_OUTPUT1, "match_nexthop4: nexthop is "); + SCTPDBG(SCTP_DEBUG_OUTPUT2, "match_nexthop4: nexthop is "); #if defined(__FreeBSD__) SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, &ro->ro_nh->gw_sa); #else SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, ro->ro_rt->rt_gateway); #endif - SCTPDBG(SCTP_DEBUG_OUTPUT1, "network address is %x\n", gwnetaddr.s_addr); + SCTPDBG(SCTP_DEBUG_OUTPUT2, "network address is %x\n", gwnetaddr.s_addr); if (srcnetaddr.s_addr == gwnetaddr.s_addr) { return (1); } #endif return (0); diff --git a/netwerk/sctp/src/netinet/sctp_pcb.h b/netwerk/sctp/src/netinet/sctp_pcb.h --- a/netwerk/sctp/src/netinet/sctp_pcb.h +++ b/netwerk/sctp/src/netinet/sctp_pcb.h @@ -679,36 +679,21 @@ struct sctp_vrf *sctp_allocate_vrf(int vrfid); struct sctp_vrf *sctp_find_vrf(uint32_t vrfid); void sctp_free_vrf(struct sctp_vrf *vrf); -/*- - * Change address state, can be used if - * O/S supports telling transports about - * changes to IFA/IFN's (link layer triggers). - * If a ifn goes down, we will do src-addr-selection - * and NOT use that, as a source address. This does - * not stop the routing system from routing out - * that interface, but we won't put it as a source. - */ -void sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr, const char *if_name, uint32_t ifn_index); -void sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr, const char *if_name, uint32_t ifn_index); - struct sctp_ifa * sctp_add_addr_to_vrf(uint32_t vrfid, void *ifn, uint32_t ifn_index, uint32_t ifn_type, const char *if_name, void *ifa, struct sockaddr *addr, uint32_t ifa_flags, int dynamic_add); -void sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu); - -void sctp_free_ifn(struct sctp_ifn *sctp_ifnp); void sctp_free_ifa(struct sctp_ifa *sctp_ifap); void sctp_del_addr_from_vrf(uint32_t vrfid, struct sockaddr *addr, - uint32_t ifn_index, const char *if_name); + void *ifn, uint32_t ifn_index); struct sctp_nets *sctp_findnet(struct sctp_tcb *, struct sockaddr *); struct sctp_inpcb *sctp_pcb_findep(struct sockaddr *, int, int, uint32_t); diff --git a/netwerk/sctp/src/netinet/sctp_pcb.c b/netwerk/sctp/src/netinet/sctp_pcb.c --- a/netwerk/sctp/src/netinet/sctp_pcb.c +++ b/netwerk/sctp/src/netinet/sctp_pcb.c @@ -249,24 +249,22 @@ sctp_find_ifn(void *ifn, uint32_t ifn_index) { struct sctp_ifn *sctp_ifnp; struct sctp_ifnlist *hash_ifn_head; - /* We assume the lock is held for the addresses - * if that's wrong problems could occur :-) - */ SCTP_IPI_ADDR_LOCK_ASSERT(); +#if defined(__FreeBSD__) && !defined(__Userspace__) + KASSERT(ifn != NULL, ("sctp_find_ifn(NULL, %u) called", ifn_index)); +#endif hash_ifn_head = &SCTP_BASE_INFO(vrf_ifn_hash)[(ifn_index & SCTP_BASE_INFO(vrf_ifn_hashmark))]; LIST_FOREACH(sctp_ifnp, hash_ifn_head, next_bucket) { - if (sctp_ifnp->ifn_index == ifn_index) { - return (sctp_ifnp); - } - if (sctp_ifnp->ifn_p && ifn && (sctp_ifnp->ifn_p == ifn)) { - return (sctp_ifnp); - } - } - return (NULL); + if (sctp_ifnp->ifn_index == ifn_index && + sctp_ifnp->ifn_p == ifn) { + break; + } + } + return (sctp_ifnp); } struct sctp_vrf * sctp_find_vrf(uint32_t vrf_id) { @@ -284,22 +282,22 @@ void sctp_free_vrf(struct sctp_vrf *vrf) { if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&vrf->refcount)) { - if (vrf->vrf_addr_hash) { - SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark); - vrf->vrf_addr_hash = NULL; - } + if (vrf->vrf_addr_hash) { + SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark); + vrf->vrf_addr_hash = NULL; + } /* We zero'd the count */ LIST_REMOVE(vrf, next_vrf); SCTP_FREE(vrf, SCTP_M_VRF); atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_vrfs), 1); } } -void +static void sctp_free_ifn(struct sctp_ifn *sctp_ifnp) { if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&sctp_ifnp->refcount)) { /* We zero'd the count */ if (sctp_ifnp->vrf) { @@ -309,21 +307,10 @@ atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ifns), 1); } } void -sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu) -{ - struct sctp_ifn *sctp_ifnp; - - sctp_ifnp = sctp_find_ifn((void *)NULL, ifn_index); - if (sctp_ifnp != NULL) { - sctp_ifnp->ifn_mtu = mtu; - } -} - -void sctp_free_ifa(struct sctp_ifa *sctp_ifap) { if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&sctp_ifap->refcount)) { /* We zero'd the count */ if (sctp_ifap->ifn_p) { @@ -333,127 +320,34 @@ atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ifas), 1); } } static void -sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock) +sctp_delete_ifn(struct sctp_ifn *sctp_ifnp) { - struct sctp_ifn *found; - - found = sctp_find_ifn(sctp_ifnp->ifn_p, sctp_ifnp->ifn_index); - if (found == NULL) { + + SCTP_IPI_ADDR_WLOCK_ASSERT(); + if (sctp_find_ifn(sctp_ifnp->ifn_p, sctp_ifnp->ifn_index) == NULL) { /* Not in the list.. sorry */ return; } - if (hold_addr_lock == 0) { - SCTP_IPI_ADDR_WLOCK(); - } else { - SCTP_IPI_ADDR_WLOCK_ASSERT(); - } LIST_REMOVE(sctp_ifnp, next_bucket); LIST_REMOVE(sctp_ifnp, next_ifn); - if (hold_addr_lock == 0) { - SCTP_IPI_ADDR_WUNLOCK(); - } /* Take away the reference, and possibly free it */ sctp_free_ifn(sctp_ifnp); } -void -sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr, - const char *if_name, uint32_t ifn_index) -{ - struct sctp_vrf *vrf; - struct sctp_ifa *sctp_ifap; - - SCTP_IPI_ADDR_RLOCK(); - vrf = sctp_find_vrf(vrf_id); - if (vrf == NULL) { - SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id); - goto out; - } - sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED); - if (sctp_ifap == NULL) { - SCTPDBG(SCTP_DEBUG_PCB4, "Can't find sctp_ifap for address\n"); - goto out; - } - if (sctp_ifap->ifn_p == NULL) { - SCTPDBG(SCTP_DEBUG_PCB4, "IFA has no IFN - can't mark unusable\n"); - goto out; - } - if (if_name) { - if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) != 0) { - SCTPDBG(SCTP_DEBUG_PCB4, "IFN %s of IFA not the same as %s\n", - sctp_ifap->ifn_p->ifn_name, if_name); - goto out; - } - } else { - if (sctp_ifap->ifn_p->ifn_index != ifn_index) { - SCTPDBG(SCTP_DEBUG_PCB4, "IFA owned by ifn_index:%d down command for ifn_index:%d - ignored\n", - sctp_ifap->ifn_p->ifn_index, ifn_index); - goto out; - } - } - - sctp_ifap->localifa_flags &= (~SCTP_ADDR_VALID); - sctp_ifap->localifa_flags |= SCTP_ADDR_IFA_UNUSEABLE; - out: - SCTP_IPI_ADDR_RUNLOCK(); -} - -void -sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr, - const char *if_name, uint32_t ifn_index) -{ - struct sctp_vrf *vrf; - struct sctp_ifa *sctp_ifap; - - SCTP_IPI_ADDR_RLOCK(); - vrf = sctp_find_vrf(vrf_id); - if (vrf == NULL) { - SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id); - goto out; - } - sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED); - if (sctp_ifap == NULL) { - SCTPDBG(SCTP_DEBUG_PCB4, "Can't find sctp_ifap for address\n"); - goto out; - } - if (sctp_ifap->ifn_p == NULL) { - SCTPDBG(SCTP_DEBUG_PCB4, "IFA has no IFN - can't mark unusable\n"); - goto out; - } - if (if_name) { - if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) != 0) { - SCTPDBG(SCTP_DEBUG_PCB4, "IFN %s of IFA not the same as %s\n", - sctp_ifap->ifn_p->ifn_name, if_name); - goto out; - } - } else { - if (sctp_ifap->ifn_p->ifn_index != ifn_index) { - SCTPDBG(SCTP_DEBUG_PCB4, "IFA owned by ifn_index:%d down command for ifn_index:%d - ignored\n", - sctp_ifap->ifn_p->ifn_index, ifn_index); - goto out; - } - } - - sctp_ifap->localifa_flags &= (~SCTP_ADDR_IFA_UNUSEABLE); - sctp_ifap->localifa_flags |= SCTP_ADDR_VALID; - out: - SCTP_IPI_ADDR_RUNLOCK(); -} - /*- * Add an ifa to an ifn. * Register the interface as necessary. - * NOTE: ADDR write lock MUST be held. */ static void sctp_add_ifa_to_ifn(struct sctp_ifn *sctp_ifnp, struct sctp_ifa *sctp_ifap) { int ifa_af; + SCTP_IPI_ADDR_WLOCK_ASSERT(); LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa); sctp_ifap->ifn_p = sctp_ifnp; atomic_add_int(&sctp_ifap->ifn_p->refcount, 1); /* update address counts */ sctp_ifnp->ifa_count++; @@ -480,15 +374,15 @@ /*- * Remove an ifa from its ifn. * If no more addresses exist, remove the ifn too. Otherwise, re-register * the interface based on the remaining address families left. - * NOTE: ADDR write lock MUST be held. */ static void sctp_remove_ifa_from_ifn(struct sctp_ifa *sctp_ifap) { + SCTP_IPI_ADDR_WLOCK_ASSERT(); LIST_REMOVE(sctp_ifap, next_ifa); if (sctp_ifap->ifn_p) { /* update address counts */ sctp_ifap->ifn_p->ifa_count--; switch (sctp_ifap->address.sa.sa_family) { @@ -506,11 +400,11 @@ break; } if (LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) { /* remove the ifn, possibly freeing it */ - sctp_delete_ifn(sctp_ifap->ifn_p, SCTP_ADDR_LOCKED); + sctp_delete_ifn(sctp_ifap->ifn_p); } else { /* re-register address family type, if needed */ if ((sctp_ifap->ifn_p->num_v6 == 0) && (sctp_ifap->ifn_p->registered_af == AF_INET6)) { sctp_ifap->ifn_p->registered_af = AF_INET; @@ -525,21 +419,20 @@ } } struct sctp_ifa * sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, - uint32_t ifn_type, const char *if_name, void *ifa, - struct sockaddr *addr, uint32_t ifa_flags, - int dynamic_add) + uint32_t ifn_type, const char *if_name, void *ifa, + struct sockaddr *addr, uint32_t ifa_flags, + int dynamic_add) { struct sctp_vrf *vrf; struct sctp_ifn *sctp_ifnp, *new_sctp_ifnp; struct sctp_ifa *sctp_ifap, *new_sctp_ifap; struct sctp_ifalist *hash_addr_head; struct sctp_ifnlist *hash_ifn_head; uint32_t hash_of_addr; - int new_ifn_af = 0; #ifdef SCTP_DEBUG SCTPDBG(SCTP_DEBUG_PCB4, "vrf_id 0x%x: adding address: ", vrf_id); SCTPDBG_ADDR(SCTP_DEBUG_PCB4, addr); #endif @@ -598,63 +491,68 @@ hash_ifn_head = &SCTP_BASE_INFO(vrf_ifn_hash)[(ifn_index & SCTP_BASE_INFO(vrf_ifn_hashmark))]; LIST_INIT(&sctp_ifnp->ifalist); LIST_INSERT_HEAD(hash_ifn_head, sctp_ifnp, next_bucket); LIST_INSERT_HEAD(&vrf->ifnlist, sctp_ifnp, next_ifn); atomic_add_int(&SCTP_BASE_INFO(ipi_count_ifns), 1); - new_ifn_af = 1; } sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED); - if (sctp_ifap) { - /* Hmm, it already exists? */ - if ((sctp_ifap->ifn_p) && - (sctp_ifap->ifn_p->ifn_index == ifn_index)) { - SCTPDBG(SCTP_DEBUG_PCB4, "Using existing ifn %s (0x%x) for ifa %p\n", - sctp_ifap->ifn_p->ifn_name, ifn_index, - (void *)sctp_ifap); - if (new_ifn_af) { - /* Remove the created one that we don't want */ - sctp_delete_ifn(sctp_ifnp, SCTP_ADDR_LOCKED); - } - if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) { - /* easy to solve, just switch back to active */ - SCTPDBG(SCTP_DEBUG_PCB4, "Clearing deleted ifa flag\n"); - sctp_ifap->localifa_flags = SCTP_ADDR_VALID; - sctp_ifap->ifn_p = sctp_ifnp; - atomic_add_int(&sctp_ifap->ifn_p->refcount, 1); - } - exit_stage_left: - SCTP_IPI_ADDR_WUNLOCK(); - if (new_sctp_ifnp != NULL) { - SCTP_FREE(new_sctp_ifnp, SCTP_M_IFN); - } - SCTP_FREE(new_sctp_ifap, SCTP_M_IFA); - return (sctp_ifap); - } else { - if (sctp_ifap->ifn_p) { + if (sctp_ifap != NULL) { + /* The address being added is already or still known. */ + if (sctp_ifap->ifn_p != NULL) { + if (sctp_ifap->ifn_p->ifn_index == ifn_index && + sctp_ifap->ifn_p->ifn_p == ifn) { + SCTPDBG(SCTP_DEBUG_PCB4, + "Using existing ifn %s (0x%x) for ifa %p\n", + sctp_ifap->ifn_p->ifn_name, ifn_index, + (void *)sctp_ifap); + if (new_sctp_ifnp == NULL) { + /* Remove the created one not used. */ + sctp_delete_ifn(sctp_ifnp); + } + if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) { + /* Switch back to active. */ + SCTPDBG(SCTP_DEBUG_PCB4, + "Clearing deleted ifa flag\n"); + sctp_ifap->localifa_flags = SCTP_ADDR_VALID; + sctp_ifap->ifn_p = sctp_ifnp; + atomic_add_int(&sctp_ifap->ifn_p->refcount, 1); + } + } else { /* * The last IFN gets the address, remove the - * old one + * old one. */ - SCTPDBG(SCTP_DEBUG_PCB4, "Moving ifa %p from %s (0x%x) to %s (0x%x)\n", - (void *)sctp_ifap, sctp_ifap->ifn_p->ifn_name, - sctp_ifap->ifn_p->ifn_index, if_name, - ifn_index); + SCTPDBG(SCTP_DEBUG_PCB4, + "Moving ifa %p from %s (0x%x) to %s (0x%x)\n", + (void *)sctp_ifap, + sctp_ifap->ifn_p->ifn_name, + sctp_ifap->ifn_p->ifn_index, if_name, + ifn_index); /* remove the address from the old ifn */ sctp_remove_ifa_from_ifn(sctp_ifap); /* move the address over to the new ifn */ sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap); - goto exit_stage_left; - } else { - /* repair ifnp which was NULL ? */ - sctp_ifap->localifa_flags = SCTP_ADDR_VALID; - SCTPDBG(SCTP_DEBUG_PCB4, "Repairing ifn %p for ifa %p\n", - (void *)sctp_ifnp, (void *)sctp_ifap); - sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap); - } - goto exit_stage_left; - } - } + } + } else { + /* Repair ifn_p, which was NULL... */ + sctp_ifap->localifa_flags = SCTP_ADDR_VALID; + SCTPDBG(SCTP_DEBUG_PCB4, + "Repairing ifn %p for ifa %p\n", + (void *)sctp_ifnp, (void *)sctp_ifap); + sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap); + } + SCTP_IPI_ADDR_WUNLOCK(); + if (new_sctp_ifnp != NULL) { + SCTP_FREE(new_sctp_ifnp, SCTP_M_IFN); + } + SCTP_FREE(new_sctp_ifap, SCTP_M_IFA); + return (sctp_ifap); + } + KASSERT(sctp_ifnp != NULL, + ("sctp_add_addr_to_vrf: sctp_ifnp == NULL")); + KASSERT(sctp_ifap == NULL, + ("sctp_add_addr_to_vrf: sctp_ifap (%p) != NULL", sctp_ifap)); sctp_ifap = new_sctp_ifap; memset(sctp_ifap, 0, sizeof(struct sctp_ifa)); sctp_ifap->ifn_p = sctp_ifnp; atomic_add_int(&sctp_ifnp->refcount, 1); sctp_ifap->vrf_id = vrf_id; @@ -699,12 +597,12 @@ } if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { sctp_ifap->src_is_priv = 1; } sctp_ifnp->num_v4++; - if (new_ifn_af) - new_ifn_af = AF_INET; + if (new_sctp_ifnp == NULL) + sctp_ifnp->registered_af = AF_INET; break; } #endif #ifdef INET6 case AF_INET6: @@ -719,23 +617,22 @@ } if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { sctp_ifap->src_is_priv = 1; } sctp_ifnp->num_v6++; - if (new_ifn_af) - new_ifn_af = AF_INET6; + if (new_sctp_ifnp == NULL) + sctp_ifnp->registered_af = AF_INET6; break; } #endif #if defined(__Userspace__) case AF_CONN: - if (new_ifn_af) - new_ifn_af = AF_CONN; + if (new_sctp_ifnp == NULL) + sctp_ifnp->registered_af = AF_CONN; break; #endif default: - new_ifn_af = 0; break; } hash_of_addr = sctp_get_ifa_hash_val(&sctp_ifap->address.sa); if ((sctp_ifap->src_is_priv == 0) && @@ -747,13 +644,10 @@ sctp_ifap->refcount = 1; LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa); sctp_ifnp->ifa_count++; vrf->total_ifa_count++; atomic_add_int(&SCTP_BASE_INFO(ipi_count_ifas), 1); - if (new_ifn_af) { - sctp_ifnp->registered_af = new_ifn_af; - } SCTP_IPI_ADDR_WUNLOCK(); if (new_sctp_ifnp != NULL) { SCTP_FREE(new_sctp_ifnp, SCTP_M_IFN); } @@ -770,12 +664,11 @@ * Gak, what can we do? We have lost an address * change can you say HOSED? */ SCTPDBG(SCTP_DEBUG_PCB4, "Lost an address change?\n"); /* Opps, must decrement the count */ - sctp_del_addr_from_vrf(vrf_id, addr, ifn_index, - if_name); + sctp_del_addr_from_vrf(vrf_id, addr, ifn, ifn_index); return (NULL); } SCTP_INCR_LADDR_COUNT(); memset(wi, 0, sizeof(*wi)); (void)SCTP_GETTIME_TIMEVAL(&wi->start_time); @@ -796,52 +689,37 @@ return (sctp_ifap); } void sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr, - uint32_t ifn_index, const char *if_name) + void *ifn, uint32_t ifn_index) { struct sctp_vrf *vrf; - struct sctp_ifa *sctp_ifap = NULL; + struct sctp_ifa *sctp_ifap; SCTP_IPI_ADDR_WLOCK(); vrf = sctp_find_vrf(vrf_id); if (vrf == NULL) { SCTPDBG(SCTP_DEBUG_PCB4, "Can't find vrf_id 0x%x\n", vrf_id); - goto out_now; + SCTP_IPI_ADDR_WUNLOCK(); + return; } #ifdef SCTP_DEBUG SCTPDBG(SCTP_DEBUG_PCB4, "vrf_id 0x%x: deleting address:", vrf_id); SCTPDBG_ADDR(SCTP_DEBUG_PCB4, addr); #endif sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, SCTP_ADDR_LOCKED); - if (sctp_ifap) { + if (sctp_ifap != NULL) { /* Validate the delete */ if (sctp_ifap->ifn_p) { - int valid = 0; - /*- - * The name has priority over the ifn_index - * if its given. - */ - if (if_name) { - if (strncmp(if_name, sctp_ifap->ifn_p->ifn_name, SCTP_IFNAMSIZ) == 0) { - /* They match its a correct delete */ - valid = 1; - } - } - if (!valid) { - /* last ditch check ifn_index */ - if (ifn_index == sctp_ifap->ifn_p->ifn_index) { - valid = 1; - } - } - if (!valid) { - SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d ifname:%s does not match addresses\n", - ifn_index, ((if_name == NULL) ? "NULL" : if_name)); - SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d ifname:%s - ignoring delete\n", - sctp_ifap->ifn_p->ifn_index, sctp_ifap->ifn_p->ifn_name); + if (ifn_index != sctp_ifap->ifn_p->ifn_index || + ifn != sctp_ifap->ifn_p->ifn_p) { + SCTPDBG(SCTP_DEBUG_PCB4, "ifn:%d (%p) ifname:%s - ignoring delete\n", + sctp_ifap->ifn_p->ifn_index, + sctp_ifap->ifn_p->ifn_p, + sctp_ifap->ifn_p->ifn_name); SCTP_IPI_ADDR_WUNLOCK(); return; } } SCTPDBG(SCTP_DEBUG_PCB4, "Deleting ifa %p\n", (void *)sctp_ifap); @@ -859,17 +737,16 @@ } #ifdef SCTP_DEBUG else { SCTPDBG(SCTP_DEBUG_PCB4, "Del Addr-ifn:%d Could not find address:", ifn_index); - SCTPDBG_ADDR(SCTP_DEBUG_PCB1, addr); - } -#endif - - out_now: + SCTPDBG_ADDR(SCTP_DEBUG_PCB4, addr); + } +#endif + SCTP_IPI_ADDR_WUNLOCK(); - if (sctp_ifap) { + if (sctp_ifap != NULL) { struct sctp_laddr *wi; wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr); if (wi == NULL) { /* @@ -4981,12 +4858,11 @@ { struct sockaddr_in *sin; sin = (struct sockaddr_in *)firstaddr; if ((ntohs(sin->sin_port) == 0) || - (sin->sin_addr.s_addr == INADDR_ANY) || - (sin->sin_addr.s_addr == INADDR_BROADCAST) || + in_broadcast(sin->sin_addr) || IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) || #if defined(__Userspace__) ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) || ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && (SCTP_IPV6_V6ONLY(inp) != 0)))) { @@ -5108,11 +4984,10 @@ SCTP_TCB_UNLOCK(stcb); SCTP_TCB_LOCK_DESTROY(stcb); LIST_REMOVE(stcb, sctp_asocs); LIST_REMOVE(stcb, sctp_tcbasocidhash); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb); - SCTP_INP_WUNLOCK(inp); SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS); *error = ENOBUFS; return (NULL); } /* Init all the timers */ @@ -7160,12 +7035,11 @@ sin.sin_addr.s_addr = p4->addr; if (IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) { /* Skip multi-cast addresses */ goto next_param; } - if ((sin.sin_addr.s_addr == INADDR_BROADCAST) || - (sin.sin_addr.s_addr == INADDR_ANY)) { + if (in_broadcast(sin.sin_addr)) { goto next_param; } sa = (struct sockaddr *)&sin; inp = stcb->sctp_ep; atomic_add_int(&stcb->asoc.refcnt, 1); @@ -7964,14 +7838,15 @@ */ } #if defined(__FreeBSD__) && !defined(__Userspace__) static void +sctp_drain(void *arg __unused, int flags __unused) #else void -#endif sctp_drain(void) +#endif { #if defined(__FreeBSD__) && !defined(__Userspace__) struct epoch_tracker et; VNET_ITERATOR_DECL(vnet_iter); diff --git a/netwerk/sctp/src/netinet/sctp_sysctl.c b/netwerk/sctp/src/netinet/sctp_sysctl.c --- a/netwerk/sctp/src/netinet/sctp_sysctl.c +++ b/netwerk/sctp/src/netinet/sctp_sysctl.c @@ -1130,11 +1130,11 @@ } \ } \ return (error); \ } \ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mib_name, flags, NULL, 0, \ - sctp_sysctl_handle_##mib_name, "UI", prefix##_DESC) + sctp_sysctl_handle_##mib_name, "IU", prefix##_DESC) #define SCTP_UINT_SYSCTL_RDTUN(mib_name, var_name, prefix) \ SYSCTL_UINT(_net_inet_sctp, OID_AUTO, mib_name, \ CTLFLAG_VNET|CTLFLAG_RDTUN|CTLFLAG_NOFETCH, \ &VNET_NAME(system_base_info.sctpsysctl.var_name), 0, \ diff --git a/netwerk/sctp/src/netinet/sctp_timer.c b/netwerk/sctp/src/netinet/sctp_timer.c --- a/netwerk/sctp/src/netinet/sctp_timer.c +++ b/netwerk/sctp/src/netinet/sctp_timer.c @@ -33,12 +33,12 @@ */ #define _IP_VHL #include #include +#if defined(__FreeBSD__) && defined(__Userspace__) #ifdef INET6 -#if defined(__FreeBSD__) && defined(__Userspace__) #include #endif #endif #include #include diff --git a/netwerk/sctp/src/netinet/sctp_usrreq.c b/netwerk/sctp/src/netinet/sctp_usrreq.c --- a/netwerk/sctp/src/netinet/sctp_usrreq.c +++ b/netwerk/sctp/src/netinet/sctp_usrreq.c @@ -60,10 +60,13 @@ #include #endif #if defined(HAVE_SCTP_PEELOFF_SOCKOPT) #include #endif /* HAVE_SCTP_PEELOFF_SOCKOPT */ +#if defined(_WIN32) && defined(__MINGW32__) +#include +#endif extern const struct sctp_cc_functions sctp_cc_functions[]; extern const struct sctp_ss_functions sctp_ss_functions[]; #if defined(__Userspace__) @@ -602,12 +605,13 @@ uint32_t vrf_id; /* FIX, for non-bsd is this right? */ vrf_id = SCTP_DEFAULT_VRFID; + if (req->newptr == NULL) + return (EINVAL); error = priv_check(req->td, PRIV_NETINET_GETCRED); - if (error) return (error); error = SYSCTL_IN(req, addrs, sizeof(addrs)); if (error) @@ -8889,11 +8893,10 @@ .pr_bind = sctp_bind, \ .pr_connect = sctp_connect, \ .pr_control = in_control, \ .pr_close = sctp_close, \ .pr_detach = sctp_close, \ - .pr_sopoll = sopoll_generic, \ .pr_flush = sctp_flush, \ .pr_disconnect = sctp_disconnect, \ .pr_listen = sctp_listen, \ .pr_peeraddr = sctp_peeraddr, \ .pr_send = sctp_sendm, \ diff --git a/netwerk/sctp/src/netinet/sctputil.c b/netwerk/sctp/src/netinet/sctputil.c --- a/netwerk/sctp/src/netinet/sctputil.c +++ b/netwerk/sctp/src/netinet/sctputil.c @@ -63,10 +63,13 @@ #include #ifdef INET6 #include #endif #endif +#if defined(_WIN32) && defined(__MINGW32__) +#include +#endif #if defined(_WIN32) && !defined(__Userspace__) #if !defined(SCTP_LOCAL_TRACE_BUF) #include "eventrace_netinet.h" #include "sctputil.tmh" /* this is the file that will be auto generated */ @@ -7486,12 +7489,11 @@ switch (sa->sa_family) { #ifdef INET case AF_INET: incr = sizeof(struct sockaddr_in); sin = (struct sockaddr_in *)sa; - if ((sin->sin_addr.s_addr == INADDR_ANY) || - (sin->sin_addr.s_addr == INADDR_BROADCAST) || + if (in_broadcast(sin->sin_addr) || IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, EINVAL); (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_7); *error = EINVAL; diff --git a/netwerk/sctp/src/netinet6/sctp6_usrreq.c b/netwerk/sctp/src/netinet6/sctp6_usrreq.c --- a/netwerk/sctp/src/netinet6/sctp6_usrreq.c +++ b/netwerk/sctp/src/netinet6/sctp6_usrreq.c @@ -663,15 +663,13 @@ int error; uint32_t vrf_id; vrf_id = SCTP_DEFAULT_VRFID; -#if defined(__FreeBSD__) && !defined(__Userspace__) + if (req->newptr == NULL) + return (EINVAL); error = priv_check(req->td, PRIV_NETINET_GETCRED); -#else - error = suser(req->p); -#endif if (error) return (error); if (req->newlen != sizeof(addrs)) { SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); diff --git a/netwerk/sctp/src/user_mbuf.c b/netwerk/sctp/src/user_mbuf.c --- a/netwerk/sctp/src/user_mbuf.c +++ b/netwerk/sctp/src/user_mbuf.c @@ -33,10 +33,14 @@ * __Userspace__ version of /usr/src/sys/kern/kern_mbuf.c * We are initializing two zones for Mbufs and Clusters. * */ +#if defined(_WIN32) && defined(__MINGW32__) +#include +#endif + #include #include /* #include This defines MSIZE 256 */ #if !defined(SCTP_SIMPLE_ALLOCATOR) #include "umem.h" diff --git a/netwerk/sctp/src/user_recv_thread.c b/netwerk/sctp/src/user_recv_thread.c --- a/netwerk/sctp/src/user_recv_thread.c +++ b/netwerk/sctp/src/user_recv_thread.c @@ -133,12 +133,11 @@ sa, 0, 1); } else { sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr, - if_nametoindex(ifa->ifa_name), - ifa->ifa_name); + NULL, if_nametoindex(ifa->ifa_name)); } freeifaddrs(ifas); } static void * diff --git a/netwerk/sctp/src/user_socket.c b/netwerk/sctp/src/user_socket.c --- a/netwerk/sctp/src/user_socket.c +++ b/netwerk/sctp/src/user_socket.c @@ -58,13 +58,16 @@ #else #include #endif userland_mutex_t accept_mtx; userland_cond_t accept_cond; -#ifdef _WIN32 +#if defined(_WIN32) #include #include +#if !defined(_MSC_VER) +#include +#endif #endif MALLOC_DEFINE(M_PCB, "sctp_pcb", "sctp pcb"); MALLOC_DEFINE(M_SONAME, "sctp_soname", "sctp soname"); #define MAXLEN_MBUF_CHAIN 32 @@ -3152,12 +3155,11 @@ #endif sconn.sconn_port = 0; sconn.sconn_addr = addr; sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, (struct sockaddr *)&sconn, - 0xffffffff, - "conn"); + NULL, 0xffffffff); } #define PREAMBLE_FORMAT "\n%c %02d:%02d:%02d.%06ld " #define PREAMBLE_LENGTH 19 #define HEADER "0000 "