1b735c0f45be3595abe0c88e2b5667780be2e27dctuexen/*- 2829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * Copyright (c) 2009-2010 Brad Penoff 3829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * Copyright (c) 2009-2010 Humaira Kamal 4829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * Copyright (c) 2011-2012 Irene Ruengeler 5829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * Copyright (c) 2011-2012 Michael Tuexen 6b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * All rights reserved. 7b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * 8b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * Redistribution and use in source and binary forms, with or without 9b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * modification, are permitted provided that the following conditions 10b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * are met: 11b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * 1. Redistributions of source code must retain the above copyright 12b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * notice, this list of conditions and the following disclaimer. 13b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * 2. Redistributions in binary form must reproduce the above copyright 14b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * notice, this list of conditions and the following disclaimer in the 15b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * documentation and/or other materials provided with the distribution. 16b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * 17b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * SUCH DAMAGE. 28b735c0f45be3595abe0c88e2b5667780be2e27dctuexen * 29b735c0f45be3595abe0c88e2b5667780be2e27dctuexen */ 30b735c0f45be3595abe0c88e2b5667780be2e27dctuexen 31a4fb576fabdb7d366af0e6ed880c0176a5b3a4e3tuexen#if defined(INET) || defined(INET6) 32bca1dae6587a640359abee04337c0463b0a3893tuexen#include <sys/types.h> 3307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if !defined(__Userspace_os_Windows) 34bca1dae6587a640359abee04337c0463b0a3893tuexen#include <sys/socket.h> 352356c9c75abdcc735cfcc8f9cb7c023375dac7b6t#include <netinet/in.h> 36587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#include <unistd.h> 37587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#include <pthread.h> 3822a33a1debfe70529be4aa018a2912bfe5dcd8dat#if !defined(__Userspace_os_DragonFly) && !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_NetBSD) 39bca1dae6587a640359abee04337c0463b0a3893tuexen#include <sys/uio.h> 403a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#else 413a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#include <user_ip6_var.h> 42ebe006254bc340627d5cdc106f4524aac98d46a9tuexen#endif 4307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 44bca1dae6587a640359abee04337c0463b0a3893tuexen#include <netinet/sctp_os.h> 45bca1dae6587a640359abee04337c0463b0a3893tuexen#include <netinet/sctp_var.h> 46bca1dae6587a640359abee04337c0463b0a3893tuexen#include <netinet/sctp_pcb.h> 47968138a650335b8836df7433026face9535f9641t#include <netinet/sctp_input.h> 487943a5e518ee0e8d37d70b5637430137cedc918dt#if 0 493a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#if defined(__Userspace_os_Linux) 503a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#include <linux/netlink.h> 512356c9c75abdcc735cfcc8f9cb7c023375dac7b6t#ifdef HAVE_LINUX_IF_ADDR_H 523a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#include <linux/if_addr.h> 533a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#endif 542356c9c75abdcc735cfcc8f9cb7c023375dac7b6t#ifdef HAVE_LINUX_RTNETLINK_H 552356c9c75abdcc735cfcc8f9cb7c023375dac7b6t#include <linux/rtnetlink.h> 562356c9c75abdcc735cfcc8f9cb7c023375dac7b6t#endif 572356c9c75abdcc735cfcc8f9cb7c023375dac7b6t#endif 587943a5e518ee0e8d37d70b5637430137cedc918dt#endif 5922a33a1debfe70529be4aa018a2912bfe5dcd8dat#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) 602356c9c75abdcc735cfcc8f9cb7c023375dac7b6t#include <net/route.h> 612356c9c75abdcc735cfcc8f9cb7c023375dac7b6t#endif 62bca1dae6587a640359abee04337c0463b0a3893tuexen/* local macros and datatypes used to get IP addresses system independently */ 632e9986e0a84ab51dee01167310708e598b5b9994t#if !defined(IP_PKTINFO ) && ! defined(IP_RECVDSTADDR) 642e9986e0a84ab51dee01167310708e598b5b9994t# error "Can't determine socket option to use to get UDP IP" 65bca1dae6587a640359abee04337c0463b0a3893tuexen#endif 66bca1dae6587a640359abee04337c0463b0a3893tuexen 673a33bc97bd0dd721a91035f5cf26c1956f264d3etuexenvoid recv_thread_destroy(void); 68587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#define MAXLEN_MBUF_CHAIN 32 /* What should this value be? */ 693a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#define ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a)) 7022a33a1debfe70529be4aa018a2912bfe5dcd8dat#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) 713a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#define NEXT_SA(ap) ap = (struct sockaddr *) \ 723a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen ((caddr_t) ap + (ap->sa_len ? ROUNDUP(ap->sa_len, sizeof (uint32_t)) : sizeof(uint32_t))) 733a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#endif 743a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 7522a33a1debfe70529be4aa018a2912bfe5dcd8dat#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) 763a33bc97bd0dd721a91035f5cf26c1956f264d3etuexenstatic void 773a33bc97bd0dd721a91035f5cf26c1956f264d3etuexensctp_get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) 783a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen{ 793a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen int i; 803a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 813a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen for (i = 0; i < RTAX_MAX; i++) { 823a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen if (addrs & (1 << i)) { 833a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen rti_info[i] = sa; 843a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen NEXT_SA(sa); 853a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } else { 863a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen rti_info[i] = NULL; 873a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 883a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 893a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen} 903a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 913a33bc97bd0dd721a91035f5cf26c1956f264d3etuexenstatic void 923a33bc97bd0dd721a91035f5cf26c1956f264d3etuexensctp_handle_ifamsg(unsigned char type, unsigned short index, struct sockaddr *sa) 933a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen{ 943a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen int rc; 953a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen struct ifaddrs *ifa, *found_ifa = NULL; 963a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 973a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen /* handle only the types we want */ 983a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen if ((type != RTM_NEWADDR) && (type != RTM_DELADDR)) { 993a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen return; 1003a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 1013a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 1023a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen rc = getifaddrs(&g_interfaces); 1033a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen if (rc != 0) { 1043a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen return; 1053a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 1063a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen for (ifa = g_interfaces; ifa; ifa = ifa->ifa_next) { 1073a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen if (index == if_nametoindex(ifa->ifa_name)) { 1083a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen found_ifa = ifa; 1093a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen break; 1103a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 1113a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 1123a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen if (found_ifa == NULL) { 1133a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen return; 1143a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 1153a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 1163a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen switch (sa->sa_family) { 1173a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#ifdef INET 1183a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen case AF_INET: 1193a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen ifa->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in)); 1203a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen memcpy(ifa->ifa_addr, sa, sizeof(struct sockaddr_in)); 1213a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen break; 1223a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#endif 1233a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#ifdef INET6 1243a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen case AF_INET6: 1253a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen ifa->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in6)); 1263a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen memcpy(ifa->ifa_addr, sa, sizeof(struct sockaddr_in6)); 1273a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen break; 1283a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#endif 1293a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen default: 130a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen SCTPDBG(SCTP_DEBUG_USR, "Address family %d not supported.\n", sa->sa_family); 1313a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 1323a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 1333a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen /* relay the appropriate address change to the base code */ 1343a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen if (type == RTM_NEWADDR) { 1353a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen (void)sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID, ifa, if_nametoindex(ifa->ifa_name), 1363a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 0, 1373a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen ifa->ifa_name, 1383a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen (void *)ifa, 1393a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen ifa->ifa_addr, 1403a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 0, 1413a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 1); 1423a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } else { 1433a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr, 1443a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen if_nametoindex(ifa->ifa_name), 1453a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen ifa->ifa_name); 1463a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 1473a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen} 1483a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 1493a33bc97bd0dd721a91035f5cf26c1956f264d3etuexenstatic void * 1503a33bc97bd0dd721a91035f5cf26c1956f264d3etuexenrecv_function_route(void *arg) 1513a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen{ 1523a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen ssize_t ret; 1533a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen struct ifa_msghdr *ifa; 1543a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen char rt_buffer[1024]; 1553a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen struct sockaddr *sa, *rti_info[RTAX_MAX]; 1563a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 157b735c0f45be3595abe0c88e2b5667780be2e27dctuexen while (1) { 1583a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen bzero(rt_buffer, sizeof(rt_buffer)); 159b735c0f45be3595abe0c88e2b5667780be2e27dctuexen ret = recv(SCTP_BASE_VAR(userspace_route), rt_buffer, sizeof(rt_buffer), 0); 1603a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 1613a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen if (ret > 0) { 1623a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen ifa = (struct ifa_msghdr *) rt_buffer; 1633a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen if (ifa->ifam_type != RTM_DELADDR && ifa->ifam_type != RTM_NEWADDR) { 1643a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen continue; 1653a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 1663a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen sa = (struct sockaddr *) (ifa + 1); 1673a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen sctp_get_rtaddrs(ifa->ifam_addrs, sa, rti_info); 1683a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen switch (ifa->ifam_type) { 1693a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen case RTM_DELADDR: 1703a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen case RTM_NEWADDR: 1713a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen sctp_handle_ifamsg(ifa->ifam_type, ifa->ifam_index, rti_info[RTAX_IFA]); 1723a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen break; 1733a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen default: 1743a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen /* ignore this routing event */ 1753a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen break; 1763a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 1773a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 178b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (ret < 0) { 179b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (errno == EAGAIN) { 180b735c0f45be3595abe0c88e2b5667780be2e27dctuexen continue; 181b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 182b735c0f45be3595abe0c88e2b5667780be2e27dctuexen break; 183b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 184b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 1853a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 18690c82b7f9b4290337239cf31926a8b87879f0357t return (NULL); 1873a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen} 1887943a5e518ee0e8d37d70b5637430137cedc918dt#endif 1897943a5e518ee0e8d37d70b5637430137cedc918dt 1907943a5e518ee0e8d37d70b5637430137cedc918dt#if 0 1917943a5e518ee0e8d37d70b5637430137cedc918dt/* This does not yet work on Linux */ 1923a33bc97bd0dd721a91035f5cf26c1956f264d3etuexenstatic void * 1933a33bc97bd0dd721a91035f5cf26c1956f264d3etuexenrecv_function_route(void *arg) 1943a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen{ 1953a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen int len; 1963a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen char buf[4096]; 1973a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen struct iovec iov = { buf, sizeof(buf) }; 1983a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen struct msghdr msg; 1993a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen struct nlmsghdr *nh; 2003a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen struct ifaddrmsg *rtmsg; 201b735c0f45be3595abe0c88e2b5667780be2e27dctuexen struct rtattr *rtatp; 2023a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen struct in_addr *inp; 203a29d53bfbc46f125218c86f5271187b7b9ea497btuexen struct sockaddr_nl sanl; 2043a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#ifdef INET 2053a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen struct sockaddr_in *sa; 2063a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#endif 2073a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#ifdef INET6 2083a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen struct sockaddr_in6 *sa6; 2093a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#endif 2103a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 211a29d53bfbc46f125218c86f5271187b7b9ea497btuexen for (;;) { 212a29d53bfbc46f125218c86f5271187b7b9ea497btuexen memset(&sanl, 0, sizeof(sanl)); 213a29d53bfbc46f125218c86f5271187b7b9ea497btuexen sanl.nl_family = AF_NETLINK; 214a29d53bfbc46f125218c86f5271187b7b9ea497btuexen sanl.nl_groups = RTMGRP_IPV6_IFADDR | RTMGRP_IPV4_IFADDR; 2153a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen memset(&msg, 0, sizeof(struct msghdr)); 2163a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen msg.msg_name = (void *)&sanl; 2173a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen msg.msg_namelen = sizeof(sanl); 2183a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen msg.msg_iov = &iov; 2193a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen msg.msg_iovlen = 1; 2203a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen msg.msg_control = NULL; 2213a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen msg.msg_controllen = 0; 2223a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 223b735c0f45be3595abe0c88e2b5667780be2e27dctuexen len = recvmsg(SCTP_BASE_VAR(userspace_route), &msg, 0); 2243a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 225b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (len < 0) { 226b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (errno == EAGAIN) { 227b735c0f45be3595abe0c88e2b5667780be2e27dctuexen continue; 228b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 229b735c0f45be3595abe0c88e2b5667780be2e27dctuexen break; 230b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 231b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 2323a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen for (nh = (struct nlmsghdr *) buf; NLMSG_OK (nh, len); 2333a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen nh = NLMSG_NEXT (nh, len)) { 2343a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen if (nh->nlmsg_type == NLMSG_DONE) 235b735c0f45be3595abe0c88e2b5667780be2e27dctuexen break; 2363a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 2373a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen if (nh->nlmsg_type == RTM_NEWADDR || nh->nlmsg_type == RTM_DELADDR) { 2383a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen rtmsg = (struct ifaddrmsg *)NLMSG_DATA(nh); 2393a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen rtatp = (struct rtattr *)IFA_RTA(rtmsg); 2403a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen if(rtatp->rta_type == IFA_ADDRESS) { 2413a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen inp = (struct in_addr *)RTA_DATA(rtatp); 2423a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen switch (rtmsg->ifa_family) { 2433a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#ifdef INET 2443a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen case AF_INET: 2453a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen sa = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); 2463a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen sa->sin_family = rtmsg->ifa_family; 2473a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen sa->sin_port = 0; 2483a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen memcpy(&sa->sin_addr, inp, sizeof(struct in_addr)); 2493a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen sctp_handle_ifamsg(nh->nlmsg_type, rtmsg->ifa_index, (struct sockaddr *)sa); 2503a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen break; 2513a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#endif 2523a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#ifdef INET6 2533a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen case AF_INET6: 2543a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen sa6 = (struct sockaddr_in6 *)malloc(sizeof(struct sockaddr_in6)); 2553a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen sa6->sin6_family = rtmsg->ifa_family; 2563a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen sa6->sin6_port = 0; 2573a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen memcpy(&sa6->sin6_addr, inp, sizeof(struct in6_addr)); 2583a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen sctp_handle_ifamsg(nh->nlmsg_type, rtmsg->ifa_index, (struct sockaddr *)sa6); 2593a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen break; 2603a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#endif 2613a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen default: 26208da49d4f59189260e186f37275bddab6c148ad8ruengeler SCTPDBG(SCTP_DEBUG_USR, "Address family %d not supported.\n", rtmsg->ifa_family); 263b735c0f45be3595abe0c88e2b5667780be2e27dctuexen break; 2643a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 2653a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 2663a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 2673a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 2683a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 26990c82b7f9b4290337239cf31926a8b87879f0357t return (NULL); 2703a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen} 2713a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#endif 272bca1dae6587a640359abee04337c0463b0a3893tuexen 273656fe4c72b7f60bbbee48b00610b20c70edf8f32tuexen#ifdef INET 274bca1dae6587a640359abee04337c0463b0a3893tuexenstatic void * 275bca1dae6587a640359abee04337c0463b0a3893tuexenrecv_function_raw(void *arg) 276bca1dae6587a640359abee04337c0463b0a3893tuexen{ 277b735c0f45be3595abe0c88e2b5667780be2e27dctuexen struct mbuf **recvmbuf; 2786fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler struct ip *iphdr; 2796fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler struct sctphdr *sh; 2806fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler uint16_t port; 281890e1a3b80e879f0a3d527173d7922aa8da54064t int offset, ecn = 0; 282890e1a3b80e879f0a3d527173d7922aa8da54064t#if !defined(SCTP_WITH_NO_CSUM) 283890e1a3b80e879f0a3d527173d7922aa8da54064t int compute_crc = 1; 284890e1a3b80e879f0a3d527173d7922aa8da54064t#endif 2856fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler struct sctp_chunkhdr *ch; 2866fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler struct sockaddr_in src, dst; 28707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if !defined(__Userspace_os_Windows) 288b21b4a1e7685ebf4b404727a184da403dff77bd3t struct msghdr msg; 289bca1dae6587a640359abee04337c0463b0a3893tuexen struct iovec recv_iovec[MAXLEN_MBUF_CHAIN]; 290587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#else 291587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen WSABUF recv_iovec[MAXLEN_MBUF_CHAIN]; 292587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen int nResult, m_ErrorCode; 293587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen DWORD flags; 29459caa502fe5258530a6f6eab10155a6dac5d8d5atuexen struct sockaddr_in from; 295587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen int fromlen; 296587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#endif 297587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen 298bca1dae6587a640359abee04337c0463b0a3893tuexen /*Initially the entire set of mbufs is to be allocated. 299bca1dae6587a640359abee04337c0463b0a3893tuexen to_fill indicates this amount. */ 300bca1dae6587a640359abee04337c0463b0a3893tuexen int to_fill = MAXLEN_MBUF_CHAIN; 301bca1dae6587a640359abee04337c0463b0a3893tuexen /* iovlen is the size of each mbuf in the chain */ 302587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen int i, n, ncounter = 0; 303bca1dae6587a640359abee04337c0463b0a3893tuexen int iovlen = MCLBYTES; 304bca1dae6587a640359abee04337c0463b0a3893tuexen int want_ext = (iovlen > MLEN)? 1 : 0; 305bca1dae6587a640359abee04337c0463b0a3893tuexen int want_header = 0; 3066fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler 3076fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler bzero((void *)&src, sizeof(struct sockaddr_in)); 3086fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler bzero((void *)&dst, sizeof(struct sockaddr_in)); 309bca1dae6587a640359abee04337c0463b0a3893tuexen 310587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen recvmbuf = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN); 311587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen 312bca1dae6587a640359abee04337c0463b0a3893tuexen while (1) { 313bca1dae6587a640359abee04337c0463b0a3893tuexen for (i = 0; i < to_fill; i++) { 314bca1dae6587a640359abee04337c0463b0a3893tuexen /* Not getting the packet header. Tests with chain of one run 315bca1dae6587a640359abee04337c0463b0a3893tuexen as usual without having the packet header. 316bca1dae6587a640359abee04337c0463b0a3893tuexen Have tried both sending and receiving 317bca1dae6587a640359abee04337c0463b0a3893tuexen */ 318218d5d0df143e859e241afb12d6aaa1e4969d714t recvmbuf[i] = sctp_get_mbuf_for_msg(iovlen, want_header, M_NOWAIT, want_ext, MT_DATA); 31907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if !defined(__Userspace_os_Windows) 320bca1dae6587a640359abee04337c0463b0a3893tuexen recv_iovec[i].iov_base = (caddr_t)recvmbuf[i]->m_data; 321bca1dae6587a640359abee04337c0463b0a3893tuexen recv_iovec[i].iov_len = iovlen; 322587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#else 323587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen recv_iovec[i].buf = (caddr_t)recvmbuf[i]->m_data; 324587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen recv_iovec[i].len = iovlen; 325587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#endif 326bca1dae6587a640359abee04337c0463b0a3893tuexen } 327bca1dae6587a640359abee04337c0463b0a3893tuexen to_fill = 0; 32807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if defined(__Userspace_os_Windows) 329587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen flags = 0; 330587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen ncounter = 0; 33159caa502fe5258530a6f6eab10155a6dac5d8d5atuexen fromlen = sizeof(struct sockaddr_in); 33259caa502fe5258530a6f6eab10155a6dac5d8d5atuexen bzero((void *)&from, sizeof(struct sockaddr_in)); 333587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen 334b735c0f45be3595abe0c88e2b5667780be2e27dctuexen nResult = WSARecvFrom(SCTP_BASE_VAR(userspace_rawsctp), recv_iovec, MAXLEN_MBUF_CHAIN, (LPDWORD)&ncounter, (LPDWORD)&flags, (struct sockaddr*)&from, &fromlen, NULL, NULL); 335587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen if (nResult != 0) { 336587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen m_ErrorCode = WSAGetLastError(); 337f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen if (m_ErrorCode == WSAETIMEDOUT) { 338f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen continue; 339f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen } 340f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen if ((m_ErrorCode == WSAENOTSOCK) || (m_ErrorCode == WSAEINTR)) { 341f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen break; 342f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen } 343587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen } 3443ab67fee2e89498e06d10f12109b818bdc49ddc3tuexen n = ncounter; 345587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#else 346b21b4a1e7685ebf4b404727a184da403dff77bd3t bzero((void *)&msg, sizeof(struct msghdr)); 347b21b4a1e7685ebf4b404727a184da403dff77bd3t msg.msg_name = NULL; 348b21b4a1e7685ebf4b404727a184da403dff77bd3t msg.msg_namelen = 0; 349b21b4a1e7685ebf4b404727a184da403dff77bd3t msg.msg_iov = recv_iovec; 350b21b4a1e7685ebf4b404727a184da403dff77bd3t msg.msg_iovlen = MAXLEN_MBUF_CHAIN; 351b21b4a1e7685ebf4b404727a184da403dff77bd3t msg.msg_control = NULL; 352b21b4a1e7685ebf4b404727a184da403dff77bd3t msg.msg_controllen = 0; 353b21b4a1e7685ebf4b404727a184da403dff77bd3t ncounter = n = recvmsg(SCTP_BASE_VAR(userspace_rawsctp), &msg, 0); 35467a1a0842895b84f6665b31c4a299ec2c1e182c9tuexen if (n < 0) { 355b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (errno == EAGAIN) { 356b735c0f45be3595abe0c88e2b5667780be2e27dctuexen continue; 357b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 358b735c0f45be3595abe0c88e2b5667780be2e27dctuexen break; 359b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 36067a1a0842895b84f6665b31c4a299ec2c1e182c9tuexen } 361587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#endif 362bca1dae6587a640359abee04337c0463b0a3893tuexen SCTP_HEADER_LEN(recvmbuf[0]) = n; /* length of total packet */ 3636b5474dec62bc128acb56d0ad4ae413b91fedb09t SCTP_STAT_INCR(sctps_recvpackets); 3646b5474dec62bc128acb56d0ad4ae413b91fedb09t SCTP_STAT_INCR_COUNTER64(sctps_inpackets); 365b735c0f45be3595abe0c88e2b5667780be2e27dctuexen 366bca1dae6587a640359abee04337c0463b0a3893tuexen if (n <= iovlen) { 367bca1dae6587a640359abee04337c0463b0a3893tuexen SCTP_BUF_LEN(recvmbuf[0]) = n; 368bca1dae6587a640359abee04337c0463b0a3893tuexen (to_fill)++; 369bca1dae6587a640359abee04337c0463b0a3893tuexen } else { 370bca1dae6587a640359abee04337c0463b0a3893tuexen i = 0; 371bca1dae6587a640359abee04337c0463b0a3893tuexen SCTP_BUF_LEN(recvmbuf[0]) = iovlen; 372bca1dae6587a640359abee04337c0463b0a3893tuexen 373bca1dae6587a640359abee04337c0463b0a3893tuexen ncounter -= iovlen; 374bca1dae6587a640359abee04337c0463b0a3893tuexen (to_fill)++; 375bca1dae6587a640359abee04337c0463b0a3893tuexen do { 376bca1dae6587a640359abee04337c0463b0a3893tuexen recvmbuf[i]->m_next = recvmbuf[i+1]; 377bca1dae6587a640359abee04337c0463b0a3893tuexen SCTP_BUF_LEN(recvmbuf[i]->m_next) = min(ncounter, iovlen); 378bca1dae6587a640359abee04337c0463b0a3893tuexen i++; 379bca1dae6587a640359abee04337c0463b0a3893tuexen ncounter -= iovlen; 380bca1dae6587a640359abee04337c0463b0a3893tuexen (to_fill)++; 381bca1dae6587a640359abee04337c0463b0a3893tuexen } while (ncounter > 0); 382bca1dae6587a640359abee04337c0463b0a3893tuexen } 3836fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler 3846fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler iphdr = mtod(recvmbuf[0], struct ip *); 3856fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler sh = (struct sctphdr *)((caddr_t)iphdr + sizeof(struct ip)); 3866fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr)); 3876fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler offset = sizeof(struct ip) + sizeof(struct sctphdr); 3886fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler 3896fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler if (iphdr->ip_tos != 0) { 3906fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler ecn = iphdr->ip_tos & 0x02; 3916fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler } 3926fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler 3936fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler dst.sin_family = AF_INET; 3946fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#ifdef HAVE_SIN_LEN 3956fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler dst.sin_len = sizeof(struct sockaddr_in); 3966fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#endif 3976fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler dst.sin_addr = iphdr->ip_dst; 3986fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler dst.sin_port = sh->dest_port; 3996fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler 4006fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler src.sin_family = AF_INET; 4016fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#ifdef HAVE_SIN_LEN 4026fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler src.sin_len = sizeof(struct sockaddr_in); 4036fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#endif 4046fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler src.sin_addr = iphdr->ip_src; 4056fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler src.sin_port = sh->src_port; 4066fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler 4076fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler /* SCTP does not allow broadcasts or multicasts */ 4086fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) { 40990c82b7f9b4290337239cf31926a8b87879f0357t return (NULL); 4106fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler } 4116fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler if (SCTP_IS_IT_BROADCAST(dst.sin_addr, recvmbuf[0])) { 41290c82b7f9b4290337239cf31926a8b87879f0357t return (NULL); 4136fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler } 4146fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler 4156fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler port = 0; 416890e1a3b80e879f0a3d527173d7922aa8da54064t 417a84e47fce6e5dd47a37cce19c040652bd9cc2ecat#if defined(SCTP_WITH_NO_CSUM) 418a84e47fce6e5dd47a37cce19c040652bd9cc2ecat SCTP_STAT_INCR(sctps_recvnocrc); 419a84e47fce6e5dd47a37cce19c040652bd9cc2ecat#else 420890e1a3b80e879f0a3d527173d7922aa8da54064t if (src.sin_addr.s_addr == dst.sin_addr.s_addr) { 4216fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler compute_crc = 0; 422a84e47fce6e5dd47a37cce19c040652bd9cc2ecat SCTP_STAT_INCR(sctps_recvnocrc); 423a84e47fce6e5dd47a37cce19c040652bd9cc2ecat } else { 424a84e47fce6e5dd47a37cce19c040652bd9cc2ecat SCTP_STAT_INCR(sctps_recvswcrc); 4256fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler } 426890e1a3b80e879f0a3d527173d7922aa8da54064t#endif 427a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n); 4282356c9c75abdcc735cfcc8f9cb7c023375dac7b6t SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", offset); 4296fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler sctp_common_input_processing(&recvmbuf[0], sizeof(struct ip), offset, n, 4306fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler (struct sockaddr *)&src, 4316fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler (struct sockaddr *)&dst, 4326fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler sh, ch, 433890e1a3b80e879f0a3d527173d7922aa8da54064t#if !defined(SCTP_WITH_NO_CSUM) 4346fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler compute_crc, 435890e1a3b80e879f0a3d527173d7922aa8da54064t#endif 4366fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler ecn, 4376fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTP_DEFAULT_VRFID, port); 438efdae3619f066b0a23c163043bf1a26f4ba0504ct if (recvmbuf[0]) { 439efdae3619f066b0a23c163043bf1a26f4ba0504ct m_freem(recvmbuf[0]); 440efdae3619f066b0a23c163043bf1a26f4ba0504ct } 441bca1dae6587a640359abee04337c0463b0a3893tuexen } 442b735c0f45be3595abe0c88e2b5667780be2e27dctuexen for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) { 443b735c0f45be3595abe0c88e2b5667780be2e27dctuexen m_free(recvmbuf[i]); 444b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 445b735c0f45be3595abe0c88e2b5667780be2e27dctuexen /* free the array itself */ 446b735c0f45be3595abe0c88e2b5667780be2e27dctuexen free(recvmbuf); 447f2c34c37a0bf05f900b2b316559ce4ae9c7be287t return (NULL); 448bca1dae6587a640359abee04337c0463b0a3893tuexen} 449656fe4c72b7f60bbbee48b00610b20c70edf8f32tuexen#endif 450bca1dae6587a640359abee04337c0463b0a3893tuexen 45107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if defined(INET6) 45207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexenstatic void * 45307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexenrecv_function_raw6(void *arg) 45407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen{ 455b735c0f45be3595abe0c88e2b5667780be2e27dctuexen struct mbuf **recvmbuf6; 45607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if !defined(__Userspace_os_Windows) 45707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen struct iovec recv_iovec[MAXLEN_MBUF_CHAIN]; 45807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen struct msghdr msg; 45907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen struct cmsghdr *cmsgptr; 46007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen char cmsgbuf[CMSG_SPACE(sizeof (struct in6_pktinfo))]; 46107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#else 46207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen WSABUF recv_iovec[MAXLEN_MBUF_CHAIN]; 46307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen int nResult, m_ErrorCode; 46407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen DWORD flags; 46559caa502fe5258530a6f6eab10155a6dac5d8d5atuexen struct sockaddr_in6 from; 46607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen int fromlen; 46759caa502fe5258530a6f6eab10155a6dac5d8d5atuexen GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; 46859caa502fe5258530a6f6eab10155a6dac5d8d5atuexen LPFN_WSARECVMSG WSARecvMsg; 4692e9986e0a84ab51dee01167310708e598b5b9994t WSACMSGHDR *cmsgptr; 4702e9986e0a84ab51dee01167310708e598b5b9994t WSAMSG msg; 47159caa502fe5258530a6f6eab10155a6dac5d8d5atuexen char ControlBuffer[1024]; 47207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 47359caa502fe5258530a6f6eab10155a6dac5d8d5atuexen struct sockaddr_in6 src, dst; 4746fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler struct sctphdr *sh; 47559caa502fe5258530a6f6eab10155a6dac5d8d5atuexen int offset; 4766fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler struct sctp_chunkhdr *ch; 47707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 47807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen /*Initially the entire set of mbufs is to be allocated. 47907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen to_fill indicates this amount. */ 48007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen int to_fill = MAXLEN_MBUF_CHAIN; 48107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen /* iovlen is the size of each mbuf in the chain */ 482890e1a3b80e879f0a3d527173d7922aa8da54064t int i, n, ncounter = 0; 483890e1a3b80e879f0a3d527173d7922aa8da54064t#if !defined(SCTP_WITH_NO_CSUM) 484890e1a3b80e879f0a3d527173d7922aa8da54064t int compute_crc = 1; 485890e1a3b80e879f0a3d527173d7922aa8da54064t#endif 48607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen int iovlen = MCLBYTES; 48707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen int want_ext = (iovlen > MLEN)? 1 : 0; 48807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen int want_header = 0; 48907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 49007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen recvmbuf6 = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN); 49107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 49207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen for (;;) { 49307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen for (i = 0; i < to_fill; i++) { 49407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen /* Not getting the packet header. Tests with chain of one run 49507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen as usual without having the packet header. 49607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen Have tried both sending and receiving 49707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen */ 498218d5d0df143e859e241afb12d6aaa1e4969d714t recvmbuf6[i] = sctp_get_mbuf_for_msg(iovlen, want_header, M_NOWAIT, want_ext, MT_DATA); 49907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if !defined(__Userspace_os_Windows) 50007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen recv_iovec[i].iov_base = (caddr_t)recvmbuf6[i]->m_data; 50107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen recv_iovec[i].iov_len = iovlen; 50207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#else 50307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen recv_iovec[i].buf = (caddr_t)recvmbuf6[i]->m_data; 50407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen recv_iovec[i].len = iovlen; 50507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 50607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 50707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen to_fill = 0; 50807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if defined(__Userspace_os_Windows) 50907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen flags = 0; 51007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen ncounter = 0; 51159caa502fe5258530a6f6eab10155a6dac5d8d5atuexen fromlen = sizeof(struct sockaddr_in6); 51259caa502fe5258530a6f6eab10155a6dac5d8d5atuexen bzero((void *)&from, sizeof(struct sockaddr_in6)); 513b735c0f45be3595abe0c88e2b5667780be2e27dctuexen nResult = WSAIoctl(SCTP_BASE_VAR(userspace_rawsctp6), SIO_GET_EXTENSION_FUNCTION_POINTER, 51459caa502fe5258530a6f6eab10155a6dac5d8d5atuexen &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, 51559caa502fe5258530a6f6eab10155a6dac5d8d5atuexen &WSARecvMsg, sizeof WSARecvMsg, 51659caa502fe5258530a6f6eab10155a6dac5d8d5atuexen &ncounter, NULL, NULL); 517f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen if (nResult == 0) { 5182e9986e0a84ab51dee01167310708e598b5b9994t msg.name = (void *)&src; 5192e9986e0a84ab51dee01167310708e598b5b9994t msg.namelen = sizeof(struct sockaddr_in6); 5202e9986e0a84ab51dee01167310708e598b5b9994t msg.lpBuffers = recv_iovec; 5212e9986e0a84ab51dee01167310708e598b5b9994t msg.dwBufferCount = MAXLEN_MBUF_CHAIN; 5222e9986e0a84ab51dee01167310708e598b5b9994t msg.Control.len = sizeof ControlBuffer; 5232e9986e0a84ab51dee01167310708e598b5b9994t msg.Control.buf = ControlBuffer; 5242e9986e0a84ab51dee01167310708e598b5b9994t msg.dwFlags = 0; 5252e9986e0a84ab51dee01167310708e598b5b9994t nResult = WSARecvMsg(SCTP_BASE_VAR(userspace_rawsctp6), &msg, &ncounter, NULL, NULL); 52659caa502fe5258530a6f6eab10155a6dac5d8d5atuexen } 52707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen if (nResult != 0) { 52807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen m_ErrorCode = WSAGetLastError(); 529f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen if (m_ErrorCode == WSAETIMEDOUT) 530f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen continue; 531f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen if (m_ErrorCode == WSAENOTSOCK || m_ErrorCode == WSAEINTR) 532f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen break; 53307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 53407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen n = ncounter; 53507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#else 53607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen bzero((void *)&msg, sizeof(struct msghdr)); 53707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen bzero((void *)&src, sizeof(struct sockaddr_in6)); 53807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen bzero((void *)&dst, sizeof(struct sockaddr_in6)); 53907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen bzero((void *)cmsgbuf, CMSG_SPACE(sizeof (struct in6_pktinfo))); 54007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen msg.msg_name = (void *)&src; 54107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen msg.msg_namelen = sizeof(struct sockaddr_in6); 54207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen msg.msg_iov = recv_iovec; 54307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen msg.msg_iovlen = MAXLEN_MBUF_CHAIN; 54407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen msg.msg_control = (void *)cmsgbuf; 54507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen msg.msg_controllen = (socklen_t)CMSG_LEN(sizeof (struct in6_pktinfo)); 54607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen msg.msg_flags = 0; 54707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 548b735c0f45be3595abe0c88e2b5667780be2e27dctuexen ncounter = n = recvmsg(SCTP_BASE_VAR(userspace_rawsctp6), &msg, 0); 54967a1a0842895b84f6665b31c4a299ec2c1e182c9tuexen if (n < 0) { 550b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (errno == EAGAIN) { 551b735c0f45be3595abe0c88e2b5667780be2e27dctuexen continue; 552b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 553b735c0f45be3595abe0c88e2b5667780be2e27dctuexen break; 554b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 55567a1a0842895b84f6665b31c4a299ec2c1e182c9tuexen } 55607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 55707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen SCTP_HEADER_LEN(recvmbuf6[0]) = n; /* length of total packet */ 5586b5474dec62bc128acb56d0ad4ae413b91fedb09t SCTP_STAT_INCR(sctps_recvpackets); 5596b5474dec62bc128acb56d0ad4ae413b91fedb09t SCTP_STAT_INCR_COUNTER64(sctps_inpackets); 56007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 56107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen if (n <= iovlen) { 56207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen SCTP_BUF_LEN(recvmbuf6[0]) = n; 56307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen (to_fill)++; 56407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } else { 56507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen i = 0; 56607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen SCTP_BUF_LEN(recvmbuf6[0]) = iovlen; 56707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 56807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen ncounter -= iovlen; 56907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen (to_fill)++; 57007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen do { 57107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen recvmbuf6[i]->m_next = recvmbuf6[i+1]; 57207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen SCTP_BUF_LEN(recvmbuf6[i]->m_next) = min(ncounter, iovlen); 57307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen i++; 57407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen ncounter -= iovlen; 57507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen (to_fill)++; 57607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } while (ncounter > 0); 57707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 57807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 57907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { 58007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen if ((cmsgptr->cmsg_level == IPPROTO_IPV6) && (cmsgptr->cmsg_type == IPV6_PKTINFO)) { 5812e9986e0a84ab51dee01167310708e598b5b9994t struct in6_pktinfo * info; 5822e9986e0a84ab51dee01167310708e598b5b9994t 5832e9986e0a84ab51dee01167310708e598b5b9994t info = (struct in6_pktinfo *)CMSG_DATA(cmsgptr); 5842e9986e0a84ab51dee01167310708e598b5b9994t memcpy((void *)&dst.sin6_addr, (const void *) &(info->ipi6_addr), sizeof(struct in6_addr)); 5852e9986e0a84ab51dee01167310708e598b5b9994t break; 58659caa502fe5258530a6f6eab10155a6dac5d8d5atuexen } 58759caa502fe5258530a6f6eab10155a6dac5d8d5atuexen } 58807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 5896fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler sh = mtod(recvmbuf6[0], struct sctphdr *); 5906fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr)); 5916fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler offset = sizeof(struct sctphdr); 5926fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler 5936fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler dst.sin6_family = AF_INET6; 5947b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN 5956fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler dst.sin6_len = sizeof(struct sockaddr_in6); 5966fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#endif 5976fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler dst.sin6_port = sh->dest_port; 5986fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler 5996fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler src.sin6_family = AF_INET6; 6007b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN 6016fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler src.sin6_len = sizeof(struct sockaddr_in6); 6026fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#endif 6036fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler src.sin6_port = sh->src_port; 604a84e47fce6e5dd47a37cce19c040652bd9cc2ecat#if defined(SCTP_WITH_NO_CSUM) 605a84e47fce6e5dd47a37cce19c040652bd9cc2ecat SCTP_STAT_INCR(sctps_recvnocrc); 606a84e47fce6e5dd47a37cce19c040652bd9cc2ecat#else 607890e1a3b80e879f0a3d527173d7922aa8da54064t if (memcmp(&src.sin6_addr, &dst.sin6_addr, sizeof(struct in6_addr)) == 0) { 6086fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler compute_crc = 0; 609a84e47fce6e5dd47a37cce19c040652bd9cc2ecat SCTP_STAT_INCR(sctps_recvnocrc); 610a84e47fce6e5dd47a37cce19c040652bd9cc2ecat } else { 611a84e47fce6e5dd47a37cce19c040652bd9cc2ecat SCTP_STAT_INCR(sctps_recvswcrc); 6126fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler } 613890e1a3b80e879f0a3d527173d7922aa8da54064t#endif 614a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n); 6152356c9c75abdcc735cfcc8f9cb7c023375dac7b6t SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", offset); 6166fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler sctp_common_input_processing(&recvmbuf6[0], 0, offset, n, 6176fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler (struct sockaddr *)&src, 6186fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler (struct sockaddr *)&dst, 6196fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler sh, ch, 620890e1a3b80e879f0a3d527173d7922aa8da54064t#if !defined(SCTP_WITH_NO_CSUM) 621890e1a3b80e879f0a3d527173d7922aa8da54064t compute_crc, 622890e1a3b80e879f0a3d527173d7922aa8da54064t#endif 6236fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler 0, 6246fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTP_DEFAULT_VRFID, 0); 625efdae3619f066b0a23c163043bf1a26f4ba0504ct if (recvmbuf6[0]) { 626efdae3619f066b0a23c163043bf1a26f4ba0504ct m_freem(recvmbuf6[0]); 627efdae3619f066b0a23c163043bf1a26f4ba0504ct } 62807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 629b735c0f45be3595abe0c88e2b5667780be2e27dctuexen for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) { 630b735c0f45be3595abe0c88e2b5667780be2e27dctuexen m_free(recvmbuf6[i]); 631b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 632b735c0f45be3595abe0c88e2b5667780be2e27dctuexen /* free the array itself */ 633b735c0f45be3595abe0c88e2b5667780be2e27dctuexen free(recvmbuf6); 634f2c34c37a0bf05f900b2b316559ce4ae9c7be287t return (NULL); 63507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen} 63607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 63707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 638656fe4c72b7f60bbbee48b00610b20c70edf8f32tuexen#ifdef INET 639bca1dae6587a640359abee04337c0463b0a3893tuexenstatic void * 640bca1dae6587a640359abee04337c0463b0a3893tuexenrecv_function_udp(void *arg) 641bca1dae6587a640359abee04337c0463b0a3893tuexen{ 642b735c0f45be3595abe0c88e2b5667780be2e27dctuexen struct mbuf **udprecvmbuf; 643bca1dae6587a640359abee04337c0463b0a3893tuexen /*Initially the entire set of mbufs is to be allocated. 644bca1dae6587a640359abee04337c0463b0a3893tuexen to_fill indicates this amount. */ 645bca1dae6587a640359abee04337c0463b0a3893tuexen int to_fill = MAXLEN_MBUF_CHAIN; 646bca1dae6587a640359abee04337c0463b0a3893tuexen /* iovlen is the size of each mbuf in the chain */ 6476fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler int i, n, ncounter, offset; 648bca1dae6587a640359abee04337c0463b0a3893tuexen int iovlen = MCLBYTES; 649bca1dae6587a640359abee04337c0463b0a3893tuexen int want_ext = (iovlen > MLEN)? 1 : 0; 650bca1dae6587a640359abee04337c0463b0a3893tuexen int want_header = 0; 6516fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler struct sctphdr *sh; 6526fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler uint16_t port; 6536fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler struct sctp_chunkhdr *ch; 654bca1dae6587a640359abee04337c0463b0a3893tuexen struct sockaddr_in src, dst; 65526dd10ff80a0682f81d8bcad6017143f8a508a3dt#if defined(IP_PKTINFO) 6562e9986e0a84ab51dee01167310708e598b5b9994t char cmsgbuf[CMSG_SPACE(sizeof(struct in_pktinfo))]; 65726dd10ff80a0682f81d8bcad6017143f8a508a3dt#else 65826dd10ff80a0682f81d8bcad6017143f8a508a3dt char cmsgbuf[CMSG_SPACE(sizeof(struct in_addr))]; 6592e9986e0a84ab51dee01167310708e598b5b9994t#endif 660890e1a3b80e879f0a3d527173d7922aa8da54064t#if !defined(SCTP_WITH_NO_CSUM) 661890e1a3b80e879f0a3d527173d7922aa8da54064t int compute_crc = 1; 662890e1a3b80e879f0a3d527173d7922aa8da54064t#endif 66307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if !defined(__Userspace_os_Windows) 664587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen struct iovec iov[MAXLEN_MBUF_CHAIN]; 665587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen struct msghdr msg; 666bca1dae6587a640359abee04337c0463b0a3893tuexen struct cmsghdr *cmsgptr; 667587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#else 668587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; 669587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen LPFN_WSARECVMSG WSARecvMsg; 670587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen char ControlBuffer[1024]; 671587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen WSABUF iov[MAXLEN_MBUF_CHAIN]; 6722e9986e0a84ab51dee01167310708e598b5b9994t WSAMSG msg; 673587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen int nResult, m_ErrorCode; 6742e9986e0a84ab51dee01167310708e598b5b9994t WSACMSGHDR *cmsgptr; 675bca1dae6587a640359abee04337c0463b0a3893tuexen#endif 676587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen 677587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen udprecvmbuf = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN); 678587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen 679bca1dae6587a640359abee04337c0463b0a3893tuexen while (1) { 680bca1dae6587a640359abee04337c0463b0a3893tuexen for (i = 0; i < to_fill; i++) { 681bca1dae6587a640359abee04337c0463b0a3893tuexen /* Not getting the packet header. Tests with chain of one run 682bca1dae6587a640359abee04337c0463b0a3893tuexen as usual without having the packet header. 683bca1dae6587a640359abee04337c0463b0a3893tuexen Have tried both sending and receiving 684bca1dae6587a640359abee04337c0463b0a3893tuexen */ 685218d5d0df143e859e241afb12d6aaa1e4969d714t udprecvmbuf[i] = sctp_get_mbuf_for_msg(iovlen, want_header, M_NOWAIT, want_ext, MT_DATA); 68607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if !defined(__Userspace_os_Windows) 687bca1dae6587a640359abee04337c0463b0a3893tuexen iov[i].iov_base = (caddr_t)udprecvmbuf[i]->m_data; 688bca1dae6587a640359abee04337c0463b0a3893tuexen iov[i].iov_len = iovlen; 689587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#else 690587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen iov[i].buf = (caddr_t)udprecvmbuf[i]->m_data; 691587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen iov[i].len = iovlen; 692587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#endif 693bca1dae6587a640359abee04337c0463b0a3893tuexen } 694bca1dae6587a640359abee04337c0463b0a3893tuexen to_fill = 0; 69507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if !defined(__Userspace_os_Windows) 696bca1dae6587a640359abee04337c0463b0a3893tuexen bzero((void *)&msg, sizeof(struct msghdr)); 697587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#else 6982e9986e0a84ab51dee01167310708e598b5b9994t bzero((void *)&msg, sizeof(WSAMSG)); 699587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#endif 700bca1dae6587a640359abee04337c0463b0a3893tuexen bzero((void *)&src, sizeof(struct sockaddr_in)); 701bca1dae6587a640359abee04337c0463b0a3893tuexen bzero((void *)&dst, sizeof(struct sockaddr_in)); 7022e9986e0a84ab51dee01167310708e598b5b9994t bzero((void *)cmsgbuf, sizeof(cmsgbuf)); 703587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen 70407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if !defined(__Userspace_os_Windows) 705bca1dae6587a640359abee04337c0463b0a3893tuexen msg.msg_name = (void *)&src; 706bca1dae6587a640359abee04337c0463b0a3893tuexen msg.msg_namelen = sizeof(struct sockaddr_in); 707bca1dae6587a640359abee04337c0463b0a3893tuexen msg.msg_iov = iov; 708bca1dae6587a640359abee04337c0463b0a3893tuexen msg.msg_iovlen = MAXLEN_MBUF_CHAIN; 709bca1dae6587a640359abee04337c0463b0a3893tuexen msg.msg_control = (void *)cmsgbuf; 7102e9986e0a84ab51dee01167310708e598b5b9994t msg.msg_controllen = sizeof(cmsgbuf); 711bca1dae6587a640359abee04337c0463b0a3893tuexen msg.msg_flags = 0; 712bca1dae6587a640359abee04337c0463b0a3893tuexen 713b735c0f45be3595abe0c88e2b5667780be2e27dctuexen ncounter = n = recvmsg(SCTP_BASE_VAR(userspace_udpsctp), &msg, 0); 71467a1a0842895b84f6665b31c4a299ec2c1e182c9tuexen if (n < 0) { 715b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (errno == EAGAIN) { 716b735c0f45be3595abe0c88e2b5667780be2e27dctuexen continue; 717b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 718b735c0f45be3595abe0c88e2b5667780be2e27dctuexen break; 719b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 72067a1a0842895b84f6665b31c4a299ec2c1e182c9tuexen } 721587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#else 722b735c0f45be3595abe0c88e2b5667780be2e27dctuexen nResult = WSAIoctl(SCTP_BASE_VAR(userspace_udpsctp), SIO_GET_EXTENSION_FUNCTION_POINTER, 723587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, 724587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen &WSARecvMsg, sizeof WSARecvMsg, 725587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen &ncounter, NULL, NULL); 726f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen if (nResult == 0) { 7272e9986e0a84ab51dee01167310708e598b5b9994t msg.name = (void *)&src; 7282e9986e0a84ab51dee01167310708e598b5b9994t msg.namelen = sizeof(struct sockaddr_in); 7292e9986e0a84ab51dee01167310708e598b5b9994t msg.lpBuffers = iov; 7302e9986e0a84ab51dee01167310708e598b5b9994t msg.dwBufferCount = MAXLEN_MBUF_CHAIN; 7312e9986e0a84ab51dee01167310708e598b5b9994t msg.Control.len = sizeof ControlBuffer; 7322e9986e0a84ab51dee01167310708e598b5b9994t msg.Control.buf = ControlBuffer; 7332e9986e0a84ab51dee01167310708e598b5b9994t msg.dwFlags = 0; 7342e9986e0a84ab51dee01167310708e598b5b9994t nResult = WSARecvMsg(SCTP_BASE_VAR(userspace_udpsctp), &msg, &ncounter, NULL, NULL); 735587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen } 736587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen if (nResult != 0) { 737587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen m_ErrorCode = WSAGetLastError(); 738f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen if (m_ErrorCode == WSAETIMEDOUT) { 739f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen continue; 740f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen } 741f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen if ((m_ErrorCode == WSAENOTSOCK) || (m_ErrorCode == WSAEINTR)) { 742f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen break; 743f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen } 744587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen } 745587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen n = ncounter; 746587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#endif 747bca1dae6587a640359abee04337c0463b0a3893tuexen SCTP_HEADER_LEN(udprecvmbuf[0]) = n; /* length of total packet */ 7486b5474dec62bc128acb56d0ad4ae413b91fedb09t SCTP_STAT_INCR(sctps_recvpackets); 7496b5474dec62bc128acb56d0ad4ae413b91fedb09t SCTP_STAT_INCR_COUNTER64(sctps_inpackets); 750587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen 751bca1dae6587a640359abee04337c0463b0a3893tuexen if (n <= iovlen) { 752bca1dae6587a640359abee04337c0463b0a3893tuexen SCTP_BUF_LEN(udprecvmbuf[0]) = n; 753bca1dae6587a640359abee04337c0463b0a3893tuexen (to_fill)++; 754bca1dae6587a640359abee04337c0463b0a3893tuexen } else { 755bca1dae6587a640359abee04337c0463b0a3893tuexen i = 0; 756bca1dae6587a640359abee04337c0463b0a3893tuexen SCTP_BUF_LEN(udprecvmbuf[0]) = iovlen; 757bca1dae6587a640359abee04337c0463b0a3893tuexen 758bca1dae6587a640359abee04337c0463b0a3893tuexen ncounter -= iovlen; 759bca1dae6587a640359abee04337c0463b0a3893tuexen (to_fill)++; 760bca1dae6587a640359abee04337c0463b0a3893tuexen do { 761bca1dae6587a640359abee04337c0463b0a3893tuexen udprecvmbuf[i]->m_next = udprecvmbuf[i+1]; 762bca1dae6587a640359abee04337c0463b0a3893tuexen SCTP_BUF_LEN(udprecvmbuf[i]->m_next) = min(ncounter, iovlen); 763bca1dae6587a640359abee04337c0463b0a3893tuexen i++; 764bca1dae6587a640359abee04337c0463b0a3893tuexen ncounter -= iovlen; 765bca1dae6587a640359abee04337c0463b0a3893tuexen (to_fill)++; 766bca1dae6587a640359abee04337c0463b0a3893tuexen } while (ncounter > 0); 767bca1dae6587a640359abee04337c0463b0a3893tuexen } 768bca1dae6587a640359abee04337c0463b0a3893tuexen 769bca1dae6587a640359abee04337c0463b0a3893tuexen for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { 77026dd10ff80a0682f81d8bcad6017143f8a508a3dt#if defined(IP_PKTINFO) 7712e9986e0a84ab51dee01167310708e598b5b9994t if ((cmsgptr->cmsg_level == IPPROTO_IP) && (cmsgptr->cmsg_type == IP_PKTINFO)) { 7722e9986e0a84ab51dee01167310708e598b5b9994t struct in_pktinfo *info; 7732e9986e0a84ab51dee01167310708e598b5b9994t 774bca1dae6587a640359abee04337c0463b0a3893tuexen dst.sin_family = AF_INET; 775bca1dae6587a640359abee04337c0463b0a3893tuexen#ifdef HAVE_SIN_LEN 776bca1dae6587a640359abee04337c0463b0a3893tuexen dst.sin_len = sizeof(struct sockaddr_in); 777bca1dae6587a640359abee04337c0463b0a3893tuexen#endif 7782e9986e0a84ab51dee01167310708e598b5b9994t info = (struct in_pktinfo *)CMSG_DATA(cmsgptr); 7792e9986e0a84ab51dee01167310708e598b5b9994t memcpy((void *)&dst.sin_addr, (const void *)&(info->ipi_addr), sizeof(struct in_addr)); 7802e9986e0a84ab51dee01167310708e598b5b9994t break; 781bca1dae6587a640359abee04337c0463b0a3893tuexen } 78233bf9a0eb4b1aa87412b2dffbced5c322f300ddbt#else 7832e9986e0a84ab51dee01167310708e598b5b9994t if ((cmsgptr->cmsg_level == IPPROTO_IP) && (cmsgptr->cmsg_type == IP_RECVDSTADDR)) { 7842e9986e0a84ab51dee01167310708e598b5b9994t struct in_addr *addr; 7852e9986e0a84ab51dee01167310708e598b5b9994t 786587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen dst.sin_family = AF_INET; 7872e9986e0a84ab51dee01167310708e598b5b9994t#ifdef HAVE_SIN_LEN 7882e9986e0a84ab51dee01167310708e598b5b9994t dst.sin_len = sizeof(struct sockaddr_in); 7892e9986e0a84ab51dee01167310708e598b5b9994t#endif 7902e9986e0a84ab51dee01167310708e598b5b9994t addr = (struct in_addr *)CMSG_DATA(cmsgptr); 7912e9986e0a84ab51dee01167310708e598b5b9994t memcpy((void *)&dst.sin_addr, (const void *)addr, sizeof(struct in_addr)); 7922e9986e0a84ab51dee01167310708e598b5b9994t break; 793587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen } 794587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#endif 7952e9986e0a84ab51dee01167310708e598b5b9994t } 796bca1dae6587a640359abee04337c0463b0a3893tuexen 797890e1a3b80e879f0a3d527173d7922aa8da54064t /* SCTP does not allow broadcasts or multicasts */ 798890e1a3b80e879f0a3d527173d7922aa8da54064t if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) { 79990c82b7f9b4290337239cf31926a8b87879f0357t return (NULL); 800890e1a3b80e879f0a3d527173d7922aa8da54064t } 801890e1a3b80e879f0a3d527173d7922aa8da54064t if (SCTP_IS_IT_BROADCAST(dst.sin_addr, udprecvmbuf[0])) { 80290c82b7f9b4290337239cf31926a8b87879f0357t return (NULL); 803890e1a3b80e879f0a3d527173d7922aa8da54064t } 804bca1dae6587a640359abee04337c0463b0a3893tuexen 8056fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler /*offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);*/ 8066fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler sh = mtod(udprecvmbuf[0], struct sctphdr *); 8076fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr)); 8086fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler offset = sizeof(struct sctphdr); 8096fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler port = src.sin_port; 8106fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler src.sin_port = sh->src_port; 8116fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler dst.sin_port = sh->dest_port; 812a84e47fce6e5dd47a37cce19c040652bd9cc2ecat#if defined(SCTP_WITH_NO_CSUM) 813a84e47fce6e5dd47a37cce19c040652bd9cc2ecat SCTP_STAT_INCR(sctps_recvnocrc); 814a84e47fce6e5dd47a37cce19c040652bd9cc2ecat#else 815890e1a3b80e879f0a3d527173d7922aa8da54064t if (src.sin_addr.s_addr == dst.sin_addr.s_addr) { 816890e1a3b80e879f0a3d527173d7922aa8da54064t compute_crc = 0; 817a84e47fce6e5dd47a37cce19c040652bd9cc2ecat SCTP_STAT_INCR(sctps_recvnocrc); 818a84e47fce6e5dd47a37cce19c040652bd9cc2ecat } else { 819a84e47fce6e5dd47a37cce19c040652bd9cc2ecat SCTP_STAT_INCR(sctps_recvswcrc); 820890e1a3b80e879f0a3d527173d7922aa8da54064t } 821890e1a3b80e879f0a3d527173d7922aa8da54064t#endif 822a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n); 8232356c9c75abdcc735cfcc8f9cb7c023375dac7b6t SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", offset); 8246fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler sctp_common_input_processing(&udprecvmbuf[0], 0, offset, n, 8256fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler (struct sockaddr *)&src, 8266fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler (struct sockaddr *)&dst, 8276fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler sh, ch, 8286fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#if !defined(SCTP_WITH_NO_CSUM) 829890e1a3b80e879f0a3d527173d7922aa8da54064t compute_crc, 8306fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#endif 8316fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler 0, 8326fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTP_DEFAULT_VRFID, port); 833efdae3619f066b0a23c163043bf1a26f4ba0504ct if (udprecvmbuf[0]) { 834efdae3619f066b0a23c163043bf1a26f4ba0504ct m_freem(udprecvmbuf[0]); 835efdae3619f066b0a23c163043bf1a26f4ba0504ct } 836bca1dae6587a640359abee04337c0463b0a3893tuexen } 837b735c0f45be3595abe0c88e2b5667780be2e27dctuexen for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) { 838b735c0f45be3595abe0c88e2b5667780be2e27dctuexen m_free(udprecvmbuf[i]); 839b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 840b735c0f45be3595abe0c88e2b5667780be2e27dctuexen /* free the array itself */ 841b735c0f45be3595abe0c88e2b5667780be2e27dctuexen free(udprecvmbuf); 842f2c34c37a0bf05f900b2b316559ce4ae9c7be287t return (NULL); 843bca1dae6587a640359abee04337c0463b0a3893tuexen} 844656fe4c72b7f60bbbee48b00610b20c70edf8f32tuexen#endif 845bca1dae6587a640359abee04337c0463b0a3893tuexen 84607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if defined(INET6) 84707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexenstatic void * 84807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexenrecv_function_udp6(void *arg) 84907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen{ 850b735c0f45be3595abe0c88e2b5667780be2e27dctuexen struct mbuf **udprecvmbuf6; 85107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen /*Initially the entire set of mbufs is to be allocated. 85207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen to_fill indicates this amount. */ 85307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen int to_fill = MAXLEN_MBUF_CHAIN; 85407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen /* iovlen is the size of each mbuf in the chain */ 85507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen int i, n, ncounter, offset; 85607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen int iovlen = MCLBYTES; 85707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen int want_ext = (iovlen > MLEN)? 1 : 0; 85807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen int want_header = 0; 85907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen struct sockaddr_in6 src, dst; 8606fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler struct sctphdr *sh; 8616fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler uint16_t port; 8626fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler struct sctp_chunkhdr *ch; 86307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen char cmsgbuf[CMSG_SPACE(sizeof (struct in6_pktinfo))]; 864890e1a3b80e879f0a3d527173d7922aa8da54064t#if !defined(SCTP_WITH_NO_CSUM) 865890e1a3b80e879f0a3d527173d7922aa8da54064t int compute_crc = 1; 866890e1a3b80e879f0a3d527173d7922aa8da54064t#endif 86707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if !defined(__Userspace_os_Windows) 86807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen struct iovec iov[MAXLEN_MBUF_CHAIN]; 86907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen struct msghdr msg; 87007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen struct cmsghdr *cmsgptr; 87107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#else 87207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; 87307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen LPFN_WSARECVMSG WSARecvMsg; 87407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen char ControlBuffer[1024]; 87507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen WSABUF iov[MAXLEN_MBUF_CHAIN]; 8762e9986e0a84ab51dee01167310708e598b5b9994t WSAMSG msg; 87707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen int nResult, m_ErrorCode; 8782e9986e0a84ab51dee01167310708e598b5b9994t WSACMSGHDR *cmsgptr; 87907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 88007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 88107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen udprecvmbuf6 = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN); 8826fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler while (1) { 88307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen for (i = 0; i < to_fill; i++) { 88407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen /* Not getting the packet header. Tests with chain of one run 88507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen as usual without having the packet header. 88607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen Have tried both sending and receiving 88707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen */ 888218d5d0df143e859e241afb12d6aaa1e4969d714t udprecvmbuf6[i] = sctp_get_mbuf_for_msg(iovlen, want_header, M_NOWAIT, want_ext, MT_DATA); 88907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if !defined(__Userspace_os_Windows) 89007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen iov[i].iov_base = (caddr_t)udprecvmbuf6[i]->m_data; 89107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen iov[i].iov_len = iovlen; 89207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#else 89307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen iov[i].buf = (caddr_t)udprecvmbuf6[i]->m_data; 89459caa502fe5258530a6f6eab10155a6dac5d8d5atuexen iov[i].len = iovlen; 89507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 89607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 89707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen to_fill = 0; 89807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 89907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if !defined(__Userspace_os_Windows) 90007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen bzero((void *)&msg, sizeof(struct msghdr)); 90107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#else 9022e9986e0a84ab51dee01167310708e598b5b9994t bzero((void *)&msg, sizeof(WSAMSG)); 90307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 90407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen bzero((void *)&src, sizeof(struct sockaddr_in6)); 90507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen bzero((void *)&dst, sizeof(struct sockaddr_in6)); 90607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen bzero((void *)cmsgbuf, CMSG_SPACE(sizeof (struct in6_pktinfo))); 90707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 90807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if !defined(__Userspace_os_Windows) 90907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen msg.msg_name = (void *)&src; 91007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen msg.msg_namelen = sizeof(struct sockaddr_in6); 91107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen msg.msg_iov = iov; 91207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen msg.msg_iovlen = MAXLEN_MBUF_CHAIN; 91307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen msg.msg_control = (void *)cmsgbuf; 91407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen msg.msg_controllen = (socklen_t)CMSG_LEN(sizeof (struct in6_pktinfo)); 91507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen msg.msg_flags = 0; 91607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 917b735c0f45be3595abe0c88e2b5667780be2e27dctuexen ncounter = n = recvmsg(SCTP_BASE_VAR(userspace_udpsctp6), &msg, 0); 91867a1a0842895b84f6665b31c4a299ec2c1e182c9tuexen if (n < 0) { 919b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (errno == EAGAIN) { 920b735c0f45be3595abe0c88e2b5667780be2e27dctuexen continue; 921b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 922b735c0f45be3595abe0c88e2b5667780be2e27dctuexen break; 923b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 92467a1a0842895b84f6665b31c4a299ec2c1e182c9tuexen } 92507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#else 926b735c0f45be3595abe0c88e2b5667780be2e27dctuexen nResult = WSAIoctl(SCTP_BASE_VAR(userspace_udpsctp6), SIO_GET_EXTENSION_FUNCTION_POINTER, 92707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, 92807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen &WSARecvMsg, sizeof WSARecvMsg, 92907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen &ncounter, NULL, NULL); 9306fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler if (nResult == SOCKET_ERROR) { 9316fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler m_ErrorCode = WSAGetLastError(); 9326fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler WSARecvMsg = NULL; 9336fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler } 934f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen if (nResult == 0) { 9352e9986e0a84ab51dee01167310708e598b5b9994t msg.name = (void *)&src; 9362e9986e0a84ab51dee01167310708e598b5b9994t msg.namelen = sizeof(struct sockaddr_in6); 9372e9986e0a84ab51dee01167310708e598b5b9994t msg.lpBuffers = iov; 9382e9986e0a84ab51dee01167310708e598b5b9994t msg.dwBufferCount = MAXLEN_MBUF_CHAIN; 9392e9986e0a84ab51dee01167310708e598b5b9994t msg.Control.len = sizeof ControlBuffer; 9402e9986e0a84ab51dee01167310708e598b5b9994t msg.Control.buf = ControlBuffer; 9412e9986e0a84ab51dee01167310708e598b5b9994t msg.dwFlags = 0; 9422e9986e0a84ab51dee01167310708e598b5b9994t nResult = WSARecvMsg(SCTP_BASE_VAR(userspace_udpsctp6), &msg, &ncounter, NULL, NULL); 94307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 94407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen if (nResult != 0) { 94507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen m_ErrorCode = WSAGetLastError(); 946f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen if (m_ErrorCode == WSAETIMEDOUT) { 947f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen continue; 948f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen } 949f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen if ((m_ErrorCode == WSAENOTSOCK) || (m_ErrorCode == WSAEINTR)) { 950f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen break; 951f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen } 95207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 95307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen n = ncounter; 95407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 95507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen SCTP_HEADER_LEN(udprecvmbuf6[0]) = n; /* length of total packet */ 9566b5474dec62bc128acb56d0ad4ae413b91fedb09t SCTP_STAT_INCR(sctps_recvpackets); 9576b5474dec62bc128acb56d0ad4ae413b91fedb09t SCTP_STAT_INCR_COUNTER64(sctps_inpackets); 95807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 95907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen if (n <= iovlen) { 96007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen SCTP_BUF_LEN(udprecvmbuf6[0]) = n; 96107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen (to_fill)++; 96207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } else { 96307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen i = 0; 96407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen SCTP_BUF_LEN(udprecvmbuf6[0]) = iovlen; 96507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 96607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen ncounter -= iovlen; 96707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen (to_fill)++; 96807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen do { 96907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen udprecvmbuf6[i]->m_next = udprecvmbuf6[i+1]; 97007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen SCTP_BUF_LEN(udprecvmbuf6[i]->m_next) = min(ncounter, iovlen); 97107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen i++; 97207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen ncounter -= iovlen; 97307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen (to_fill)++; 97407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } while (ncounter > 0); 97507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 97607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 97707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { 97807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen if ((cmsgptr->cmsg_level == IPPROTO_IPV6) && (cmsgptr->cmsg_type == IPV6_PKTINFO)) { 9792e9986e0a84ab51dee01167310708e598b5b9994t struct in6_pktinfo *info; 9802e9986e0a84ab51dee01167310708e598b5b9994t 98107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen dst.sin6_family = AF_INET6; 9827b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN 98307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen dst.sin6_len = sizeof(struct sockaddr_in6); 98407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 9852e9986e0a84ab51dee01167310708e598b5b9994t info = (struct in6_pktinfo *)CMSG_DATA(cmsgptr); 9866fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler /*dst.sin6_port = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));*/ 9872e9986e0a84ab51dee01167310708e598b5b9994t memcpy((void *)&dst.sin6_addr, (const void *)&(info->ipi6_addr), sizeof(struct in6_addr)); 98807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 98907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 99007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 991890e1a3b80e879f0a3d527173d7922aa8da54064t /* SCTP does not allow broadcasts or multicasts */ 992890e1a3b80e879f0a3d527173d7922aa8da54064t if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) { 99390c82b7f9b4290337239cf31926a8b87879f0357t return (NULL); 994890e1a3b80e879f0a3d527173d7922aa8da54064t } 9956fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler 9966fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler sh = mtod(udprecvmbuf6[0], struct sctphdr *); 9976fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr)); 9986fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler offset = sizeof(struct sctphdr); 9996fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler 10006fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler port = src.sin6_port; 10016fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler src.sin6_port = sh->src_port; 10026fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler dst.sin6_port = sh->dest_port; 1003a84e47fce6e5dd47a37cce19c040652bd9cc2ecat#if defined(SCTP_WITH_NO_CSUM) 1004a84e47fce6e5dd47a37cce19c040652bd9cc2ecat SCTP_STAT_INCR(sctps_recvnocrc); 1005a84e47fce6e5dd47a37cce19c040652bd9cc2ecat#else 1006890e1a3b80e879f0a3d527173d7922aa8da54064t if ((memcmp(&src.sin6_addr, &dst.sin6_addr, sizeof(struct in6_addr)) == 0)) { 1007890e1a3b80e879f0a3d527173d7922aa8da54064t compute_crc = 0; 1008a84e47fce6e5dd47a37cce19c040652bd9cc2ecat SCTP_STAT_INCR(sctps_recvnocrc); 1009a84e47fce6e5dd47a37cce19c040652bd9cc2ecat } else { 1010a84e47fce6e5dd47a37cce19c040652bd9cc2ecat SCTP_STAT_INCR(sctps_recvswcrc); 1011890e1a3b80e879f0a3d527173d7922aa8da54064t } 1012890e1a3b80e879f0a3d527173d7922aa8da54064t#endif 1013a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n); 10142356c9c75abdcc735cfcc8f9cb7c023375dac7b6t SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", (int)sizeof(struct sctphdr)); 10152356c9c75abdcc735cfcc8f9cb7c023375dac7b6t sctp_common_input_processing(&udprecvmbuf6[0], 0, offset, n, 10166fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler (struct sockaddr *)&src, 10176fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler (struct sockaddr *)&dst, 10186fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler sh, ch, 10196fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#if !defined(SCTP_WITH_NO_CSUM) 1020890e1a3b80e879f0a3d527173d7922aa8da54064t compute_crc, 10216fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#endif 10226fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler 0, 10236fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTP_DEFAULT_VRFID, port); 1024efdae3619f066b0a23c163043bf1a26f4ba0504ct if (udprecvmbuf6[0]) { 1025efdae3619f066b0a23c163043bf1a26f4ba0504ct m_freem(udprecvmbuf6[0]); 1026efdae3619f066b0a23c163043bf1a26f4ba0504ct } 102707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 1028b735c0f45be3595abe0c88e2b5667780be2e27dctuexen for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) { 1029b735c0f45be3595abe0c88e2b5667780be2e27dctuexen m_free(udprecvmbuf6[i]); 1030b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 1031b735c0f45be3595abe0c88e2b5667780be2e27dctuexen /* free the array itself */ 1032b735c0f45be3595abe0c88e2b5667780be2e27dctuexen free(udprecvmbuf6); 1033f2c34c37a0bf05f900b2b316559ce4ae9c7be287t return (NULL); 103407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen} 103507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 1036bca1dae6587a640359abee04337c0463b0a3893tuexen 10370622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexenstatic void 1038bca1dae6587a640359abee04337c0463b0a3893tuexensetReceiveBufferSize(int sfd, int new_size) 1039bca1dae6587a640359abee04337c0463b0a3893tuexen{ 1040bca1dae6587a640359abee04337c0463b0a3893tuexen int ch = new_size; 10410622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexen 1042bca1dae6587a640359abee04337c0463b0a3893tuexen if (setsockopt (sfd, SOL_SOCKET, SO_RCVBUF, (void*)&ch, sizeof(ch)) < 0) { 10436fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#if defined (__Userspace_os_Windows) 10446fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set recv-buffers size (errno = %d).\n", WSAGetLastError()); 10456fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#else 10460622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't set recv-buffers size (errno = %d).\n", errno); 10476fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#endif 1048bca1dae6587a640359abee04337c0463b0a3893tuexen } 10490622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexen return; 1050bca1dae6587a640359abee04337c0463b0a3893tuexen} 1051bca1dae6587a640359abee04337c0463b0a3893tuexen 10520622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexenstatic void 1053bca1dae6587a640359abee04337c0463b0a3893tuexensetSendBufferSize(int sfd, int new_size) 1054bca1dae6587a640359abee04337c0463b0a3893tuexen{ 1055bca1dae6587a640359abee04337c0463b0a3893tuexen int ch = new_size; 1056b735c0f45be3595abe0c88e2b5667780be2e27dctuexen 1057bca1dae6587a640359abee04337c0463b0a3893tuexen if (setsockopt (sfd, SOL_SOCKET, SO_SNDBUF, (void*)&ch, sizeof(ch)) < 0) { 10586fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#if defined (__Userspace_os_Windows) 10596fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set send-buffers size (errno = %d).\n", WSAGetLastError()); 10606fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#else 10616fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set send-buffers size (errno = %d).\n", errno); 10626fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#endif 1063bca1dae6587a640359abee04337c0463b0a3893tuexen } 10640622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexen return; 1065bca1dae6587a640359abee04337c0463b0a3893tuexen} 1066bca1dae6587a640359abee04337c0463b0a3893tuexen 1067f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen#define SOCKET_TIMEOUT 100 /* in ms */ 1068b735c0f45be3595abe0c88e2b5667780be2e27dctuexenvoid 10693a33bc97bd0dd721a91035f5cf26c1956f264d3etuexenrecv_thread_init(void) 1070bca1dae6587a640359abee04337c0463b0a3893tuexen{ 1071b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#if defined(INET) 1072bca1dae6587a640359abee04337c0463b0a3893tuexen struct sockaddr_in addr_ipv4; 1073b735c0f45be3595abe0c88e2b5667780be2e27dctuexen const int hdrincl = 1; 1074b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 107507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if defined(INET6) 107607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen struct sockaddr_in6 addr_ipv6; 107707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 1078b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#if defined(INET) || defined(INET6) 1079b735c0f45be3595abe0c88e2b5667780be2e27dctuexen const int on = 1; 1080b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 10811b9c2d28d9c82d0ef42cc20d5274016d8060785ctuexen#if !defined(__Userspace_os_Windows) 10821b9c2d28d9c82d0ef42cc20d5274016d8060785ctuexen struct timeval timeout; 1083bca1dae6587a640359abee04337c0463b0a3893tuexen 1084f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen timeout.tv_sec = (SOCKET_TIMEOUT / 1000); 1085f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen timeout.tv_usec = (SOCKET_TIMEOUT % 1000) * 1000; 1086f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen#else 1087f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen unsigned int timeout = SOCKET_TIMEOUT; /* Timeout in milliseconds */ 10881b9c2d28d9c82d0ef42cc20d5274016d8060785ctuexen#endif 108922a33a1debfe70529be4aa018a2912bfe5dcd8dat#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) 1090b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_route) == -1) { 1091b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if ((SCTP_BASE_VAR(userspace_route) = socket(AF_ROUTE, SOCK_RAW, 0)) < 0) { 10920622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't create routing socket (errno = %d).\n", errno); 1093b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 1094c48387a1b77565240a8a488026d3d550c9823caft#if 0 1095b735c0f45be3595abe0c88e2b5667780be2e27dctuexen struct sockaddr_nl sanl; 10963a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 1097b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if ((SCTP_BASE_VAR(userspace_route) = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) { 10980622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't create routing socket (errno = %d.\n", errno); 10993a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 1100b735c0f45be3595abe0c88e2b5667780be2e27dctuexen memset(&sanl, 0, sizeof(sanl)); 1101b735c0f45be3595abe0c88e2b5667780be2e27dctuexen sanl.nl_family = AF_NETLINK; 1102b735c0f45be3595abe0c88e2b5667780be2e27dctuexen sanl.nl_groups = 0; 1103b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#ifdef INET 1104b735c0f45be3595abe0c88e2b5667780be2e27dctuexen sanl.nl_groups |= RTMGRP_IPV4_IFADDR; 1105b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 1106b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#ifdef INET6 1107b735c0f45be3595abe0c88e2b5667780be2e27dctuexen sanl.nl_groups |= RTMGRP_IPV6_IFADDR; 1108b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 1109b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (bind(SCTP_BASE_VAR(userspace_route), (struct sockaddr *) &sanl, sizeof(sanl)) < 0) { 11100622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't bind routing socket (errno = %d).\n", errno); 1111b735c0f45be3595abe0c88e2b5667780be2e27dctuexen close(SCTP_BASE_VAR(userspace_route)); 1112b735c0f45be3595abe0c88e2b5667780be2e27dctuexen SCTP_BASE_VAR(userspace_route) = -1; 1113b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 1114b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 1115ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen if (SCTP_BASE_VAR(userspace_route) != -1) { 1116ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen if (setsockopt(SCTP_BASE_VAR(userspace_route), SOL_SOCKET, SO_RCVTIMEO,(const void*)&timeout, sizeof(struct timeval)) < 0) { 11170622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on routing socket (errno = %d).\n", errno); 1118ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen#if defined(__Userspace_os_Windows) 1119f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_route)); 1120ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen#else 1121ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen close(SCTP_BASE_VAR(userspace_route)); 1122ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen#endif 1123ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen SCTP_BASE_VAR(userspace_route) = -1; 1124ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen } 1125ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen } 11263a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 11273a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#endif 1128b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#if defined(INET) 1129b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_rawsctp) == -1) { 1130b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if ((SCTP_BASE_VAR(userspace_rawsctp) = socket(AF_INET, SOCK_RAW, IPPROTO_SCTP)) < 0) { 11316fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#if defined(__Userspace_os_Windows) 11326fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't create raw socket for IPv4 (errno = %d).\n", WSAGetLastError()); 11336fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#else 11340622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't create raw socket for IPv4 (errno = %d).\n", errno); 11356fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#endif 1136e2c40ae4fa585324830f2e0ba98ef24eb9332246tuexen } else { 1137e2c40ae4fa585324830f2e0ba98ef24eb9332246tuexen /* complete setting up the raw SCTP socket */ 1138b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp), IPPROTO_IP, IP_HDRINCL,(const void*)&hdrincl, sizeof(int)) < 0) { 1139b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#if defined(__Userspace_os_Windows) 11406fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_HDRINCL (errno = %d).\n", WSAGetLastError()); 1141f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_rawsctp)); 1142b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#else 11436fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_HDRINCL (errno = %d).\n", errno); 1144b735c0f45be3595abe0c88e2b5667780be2e27dctuexen close(SCTP_BASE_VAR(userspace_rawsctp)); 1145b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 11461b9c2d28d9c82d0ef42cc20d5274016d8060785ctuexen SCTP_BASE_VAR(userspace_rawsctp) = -1; 1147f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen } else if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp), SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(timeout)) < 0) { 11481b9c2d28d9c82d0ef42cc20d5274016d8060785ctuexen#if defined(__Userspace_os_Windows) 11496fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/IPv4 (errno = %d).\n", WSAGetLastError()); 1150f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_rawsctp)); 11511b9c2d28d9c82d0ef42cc20d5274016d8060785ctuexen#else 11526fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/IPv4 (errno = %d).\n", errno); 11531b9c2d28d9c82d0ef42cc20d5274016d8060785ctuexen close(SCTP_BASE_VAR(userspace_rawsctp)); 11541b9c2d28d9c82d0ef42cc20d5274016d8060785ctuexen#endif 1155b735c0f45be3595abe0c88e2b5667780be2e27dctuexen SCTP_BASE_VAR(userspace_rawsctp) = -1; 1156b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 1157b735c0f45be3595abe0c88e2b5667780be2e27dctuexen memset((void *)&addr_ipv4, 0, sizeof(struct sockaddr_in)); 1158587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#ifdef HAVE_SIN_LEN 1159b735c0f45be3595abe0c88e2b5667780be2e27dctuexen addr_ipv4.sin_len = sizeof(struct sockaddr_in); 1160587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#endif 1161b735c0f45be3595abe0c88e2b5667780be2e27dctuexen addr_ipv4.sin_family = AF_INET; 1162b735c0f45be3595abe0c88e2b5667780be2e27dctuexen addr_ipv4.sin_port = htons(0); 1163b735c0f45be3595abe0c88e2b5667780be2e27dctuexen addr_ipv4.sin_addr.s_addr = htonl(INADDR_ANY); 1164b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (bind(SCTP_BASE_VAR(userspace_rawsctp), (const struct sockaddr *)&addr_ipv4, sizeof(struct sockaddr_in)) < 0) { 1165b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#if defined(__Userspace_os_Windows) 11666fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/IPv4 (errno = %d).\n", WSAGetLastError()); 1167f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_rawsctp)); 1168b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#else 11696fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/IPv4 (errno = %d).\n", errno); 1170b735c0f45be3595abe0c88e2b5667780be2e27dctuexen close(SCTP_BASE_VAR(userspace_rawsctp)); 1171b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 1172b735c0f45be3595abe0c88e2b5667780be2e27dctuexen SCTP_BASE_VAR(userspace_rawsctp) = -1; 1173b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 1174b735c0f45be3595abe0c88e2b5667780be2e27dctuexen setReceiveBufferSize(SCTP_BASE_VAR(userspace_rawsctp), SB_RAW); /* 128K */ 1175b735c0f45be3595abe0c88e2b5667780be2e27dctuexen setSendBufferSize(SCTP_BASE_VAR(userspace_rawsctp), SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */ 1176b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 117759caa502fe5258530a6f6eab10155a6dac5d8d5atuexen } 1178e2c40ae4fa585324830f2e0ba98ef24eb9332246tuexen } 1179bca1dae6587a640359abee04337c0463b0a3893tuexen } 1180b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_udpsctp) == -1) { 1181b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if ((SCTP_BASE_VAR(userspace_udpsctp) = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { 11826fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#if defined(__Userspace_os_Windows) 11836fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError()); 11846fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#else 11850622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv4 (errno = %d).\n", errno); 11866fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#endif 1187b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 118826dd10ff80a0682f81d8bcad6017143f8a508a3dt#if defined(IP_PKTINFO) 11892e9986e0a84ab51dee01167310708e598b5b9994t if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp), IPPROTO_IP, IP_PKTINFO, (const void *)&on, (int)sizeof(int)) < 0) { 119026dd10ff80a0682f81d8bcad6017143f8a508a3dt#else 119126dd10ff80a0682f81d8bcad6017143f8a508a3dt if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp), IPPROTO_IP, IP_RECVDSTADDR, (const void *)&on, (int)sizeof(int)) < 0) { 11922e9986e0a84ab51dee01167310708e598b5b9994t#endif 1193b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#if defined(__Userspace_os_Windows) 119426dd10ff80a0682f81d8bcad6017143f8a508a3dt#if defined(IP_PKTINFO) 11952e9986e0a84ab51dee01167310708e598b5b9994t SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_PKTINFO on socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError()); 119626dd10ff80a0682f81d8bcad6017143f8a508a3dt#else 119726dd10ff80a0682f81d8bcad6017143f8a508a3dt SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_RECVDSTADDR on socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError()); 11982e9986e0a84ab51dee01167310708e598b5b9994t#endif 1199f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_udpsctp)); 1200b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#else 120126dd10ff80a0682f81d8bcad6017143f8a508a3dt#if defined(IP_PKTINFO) 12022e9986e0a84ab51dee01167310708e598b5b9994t SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_PKTINFO on socket for SCTP/UDP/IPv4 (errno = %d).\n", errno); 120326dd10ff80a0682f81d8bcad6017143f8a508a3dt#else 120426dd10ff80a0682f81d8bcad6017143f8a508a3dt SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_RECVDSTADDR on socket for SCTP/UDP/IPv4 (errno = %d).\n", errno); 12052e9986e0a84ab51dee01167310708e598b5b9994t#endif 1206b735c0f45be3595abe0c88e2b5667780be2e27dctuexen close(SCTP_BASE_VAR(userspace_udpsctp)); 12071b9c2d28d9c82d0ef42cc20d5274016d8060785ctuexen#endif 12081b9c2d28d9c82d0ef42cc20d5274016d8060785ctuexen SCTP_BASE_VAR(userspace_udpsctp) = -1; 1209f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen } else if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp), SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(timeout)) < 0) { 12101b9c2d28d9c82d0ef42cc20d5274016d8060785ctuexen#if defined(__Userspace_os_Windows) 12116fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError()); 1212f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_udpsctp)); 12131b9c2d28d9c82d0ef42cc20d5274016d8060785ctuexen#else 12146fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/UDP/IPv4 (errno = %d).\n", errno); 12151b9c2d28d9c82d0ef42cc20d5274016d8060785ctuexen close(SCTP_BASE_VAR(userspace_udpsctp)); 1216b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 1217b735c0f45be3595abe0c88e2b5667780be2e27dctuexen SCTP_BASE_VAR(userspace_udpsctp) = -1; 1218b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 1219b735c0f45be3595abe0c88e2b5667780be2e27dctuexen memset((void *)&addr_ipv4, 0, sizeof(struct sockaddr_in)); 1220bca1dae6587a640359abee04337c0463b0a3893tuexen#ifdef HAVE_SIN_LEN 1221b735c0f45be3595abe0c88e2b5667780be2e27dctuexen addr_ipv4.sin_len = sizeof(struct sockaddr_in); 1222bca1dae6587a640359abee04337c0463b0a3893tuexen#endif 1223b735c0f45be3595abe0c88e2b5667780be2e27dctuexen addr_ipv4.sin_family = AF_INET; 1224b735c0f45be3595abe0c88e2b5667780be2e27dctuexen addr_ipv4.sin_port = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)); 1225b735c0f45be3595abe0c88e2b5667780be2e27dctuexen addr_ipv4.sin_addr.s_addr = htonl(INADDR_ANY); 1226b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (bind(SCTP_BASE_VAR(userspace_udpsctp), (const struct sockaddr *)&addr_ipv4, sizeof(struct sockaddr_in)) < 0) { 1227b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#if defined(__Userspace_os_Windows) 12286fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError()); 1229f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_udpsctp)); 1230b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#else 12316fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/UDP/IPv4 (errno = %d).\n", errno); 1232b735c0f45be3595abe0c88e2b5667780be2e27dctuexen close(SCTP_BASE_VAR(userspace_udpsctp)); 1233b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 1234b735c0f45be3595abe0c88e2b5667780be2e27dctuexen SCTP_BASE_VAR(userspace_udpsctp) = -1; 1235b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 1236b735c0f45be3595abe0c88e2b5667780be2e27dctuexen setReceiveBufferSize(SCTP_BASE_VAR(userspace_udpsctp), SB_RAW); /* 128K */ 1237b735c0f45be3595abe0c88e2b5667780be2e27dctuexen setSendBufferSize(SCTP_BASE_VAR(userspace_udpsctp), SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */ 1238b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 1239b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 1240bca1dae6587a640359abee04337c0463b0a3893tuexen } 1241bca1dae6587a640359abee04337c0463b0a3893tuexen } 1242b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 124307961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if defined(INET6) 1244b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_rawsctp6) == -1) { 1245b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if ((SCTP_BASE_VAR(userspace_rawsctp6) = socket(AF_INET6, SOCK_RAW, IPPROTO_SCTP)) < 0) { 12466fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#if defined(__Userspace_os_Windows) 12476fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError()); 12486fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#else 12490622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/IPv6 (errno = %d).\n", errno); 12506fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#endif 125107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } else { 125207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen /* complete setting up the raw SCTP socket */ 12539cf61baf77a644c6a5ab2dff61d0d78e2ea94fb2tuexen#if defined(IPV6_RECVPKTINFO) 12546fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp6), IPPROTO_IPV6, IPV6_RECVPKTINFO, (const void *)&on, sizeof(on)) < 0) { 1255b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#if defined(__Userspace_os_Windows) 12566fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_RECVPKTINFO on socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError()); 1257f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_rawsctp6)); 125807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#else 12596fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_RECVPKTINFO on socket for SCTP/IPv6 (errno = %d).\n", errno); 1260b735c0f45be3595abe0c88e2b5667780be2e27dctuexen close(SCTP_BASE_VAR(userspace_rawsctp6)); 1261b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 1262b735c0f45be3595abe0c88e2b5667780be2e27dctuexen SCTP_BASE_VAR(userspace_rawsctp6) = -1; 1263b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 1264b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#else 1265b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp6), IPPROTO_IPV6, IPV6_PKTINFO,(const void*)&on, sizeof(on)) < 0) { 1266b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#if defined(__Userspace_os_Windows) 12676fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_PKTINFO on socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError()); 1268f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_rawsctp6)); 1269b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#else 12706fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_PKTINFO on socket for SCTP/IPv6 (errno = %d).\n", errno); 1271b735c0f45be3595abe0c88e2b5667780be2e27dctuexen close(SCTP_BASE_VAR(userspace_rawsctp6)); 127207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 1273b735c0f45be3595abe0c88e2b5667780be2e27dctuexen SCTP_BASE_VAR(userspace_rawsctp6) = -1; 1274b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 1275b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 1276b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp6), IPPROTO_IPV6, IPV6_V6ONLY, (const void*)&on, (socklen_t)sizeof(on)) < 0) { 12776fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#if defined(__Userspace_os_Windows) 12786fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_V6ONLY on socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError()); 12796fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#else 12800622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_V6ONLY on socket for SCTP/IPv6 (errno = %d).\n", errno); 12816fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#endif 1282b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 1283f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp6), SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(timeout)) < 0) { 1284ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen#if defined(__Userspace_os_Windows) 12856fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError()); 1286f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_rawsctp6)); 1287ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen#else 12886fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/IPv6 (errno = %d).\n", errno); 1289f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen close(SCTP_BASE_VAR(userspace_rawsctp6)); 1290ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen#endif 1291f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen SCTP_BASE_VAR(userspace_rawsctp6) = -1; 1292ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen } else { 1293ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen memset((void *)&addr_ipv6, 0, sizeof(struct sockaddr_in6)); 12947b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN 1295ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen addr_ipv6.sin6_len = sizeof(struct sockaddr_in6); 129607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 1297ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen addr_ipv6.sin6_family = AF_INET6; 1298ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen addr_ipv6.sin6_port = htons(0); 1299ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen addr_ipv6.sin6_addr = in6addr_any; 1300ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen if (bind(SCTP_BASE_VAR(userspace_rawsctp6), (const struct sockaddr *)&addr_ipv6, sizeof(struct sockaddr_in6)) < 0) { 1301b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#if defined(__Userspace_os_Windows) 13026fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError()); 1303f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_rawsctp6)); 1304b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#else 13056fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/IPv6 (errno = %d).\n", errno); 1306ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen close(SCTP_BASE_VAR(userspace_rawsctp6)); 1307b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 1308ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen SCTP_BASE_VAR(userspace_rawsctp6) = -1; 1309ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen } else { 1310ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen setReceiveBufferSize(SCTP_BASE_VAR(userspace_rawsctp6), SB_RAW); /* 128K */ 1311ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen setSendBufferSize(SCTP_BASE_VAR(userspace_rawsctp6), SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */ 1312ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen } 1313b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 1314b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 131507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 131607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 1317b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_udpsctp6) == -1) { 1318b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if ((SCTP_BASE_VAR(userspace_udpsctp6) = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) { 13196fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#if defined(__Userspace_os_Windows) 13206fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError()); 13216fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#else 13220622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv6 (errno = %d).\n", errno); 13236fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#endif 132407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 13259cf61baf77a644c6a5ab2dff61d0d78e2ea94fb2tuexen#if defined(IPV6_RECVPKTINFO) 1326b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), IPPROTO_IPV6, IPV6_RECVPKTINFO, (const void *)&on, (int)sizeof(int)) < 0) { 1327f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen#if defined(__Userspace_os_Windows) 13286fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_RECVPKTINFO on socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError()); 1329f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_udpsctp6)); 1330f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen#else 13316fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_RECVPKTINFO on socket for SCTP/UDP/IPv6 (errno = %d).\n", errno); 1332b735c0f45be3595abe0c88e2b5667780be2e27dctuexen close(SCTP_BASE_VAR(userspace_udpsctp6)); 1333f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen#endif 1334b735c0f45be3595abe0c88e2b5667780be2e27dctuexen SCTP_BASE_VAR(userspace_udpsctp6) = -1; 1335b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 133607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#else 1337b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), IPPROTO_IPV6, IPV6_PKTINFO, (const void *)&on, (int)sizeof(int)) < 0) { 1338f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen#if defined(__Userspace_os_Windows) 13396fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_PKTINFO on socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError()); 1340f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_udpsctp6)); 1341f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen#else 13426fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_PKTINFO on socket for SCTP/UDP/IPv6 (errno = %d).\n", errno); 1343b735c0f45be3595abe0c88e2b5667780be2e27dctuexen close(SCTP_BASE_VAR(userspace_udpsctp6)); 1344f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen#endif 1345b735c0f45be3595abe0c88e2b5667780be2e27dctuexen SCTP_BASE_VAR(userspace_udpsctp6) = -1; 1346b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 134707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 1348f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), IPPROTO_IPV6, IPV6_V6ONLY, (const void *)&on, (socklen_t)sizeof(on)) < 0) { 13496fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#if defined(__Userspace_os_Windows) 13506fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_V6ONLY on socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError()); 13516fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#else 13520622a9e51f1ec476ccf5d038c4e3b11fdfc07197tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_V6ONLY on socket for SCTP/UDP/IPv6 (errno = %d).\n", errno); 13536fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler#endif 1354b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 1355f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(timeout)) < 0) { 1356ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen#if defined(__Userspace_os_Windows) 13576fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError()); 1358f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_udpsctp6)); 1359f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen#else 13606fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/UDP/IPv6 (errno = %d).\n", errno); 1361f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen close(SCTP_BASE_VAR(userspace_udpsctp6)); 1362ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen#endif 1363f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen SCTP_BASE_VAR(userspace_udpsctp6) = -1; 1364b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } else { 1365ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen memset((void *)&addr_ipv6, 0, sizeof(struct sockaddr_in6)); 13667b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN 1367ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen addr_ipv6.sin6_len = sizeof(struct sockaddr_in6); 1368ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen#endif 1369ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen addr_ipv6.sin6_family = AF_INET6; 1370ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen addr_ipv6.sin6_port = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)); 1371ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen addr_ipv6.sin6_addr = in6addr_any; 13726fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler if (bind(SCTP_BASE_VAR(userspace_udpsctp6), (const struct sockaddr *)&addr_ipv6, sizeof(struct sockaddr_in6)) < 0) { 1373f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen#if defined(__Userspace_os_Windows) 13746fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError()); 1375f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_udpsctp6)); 1376f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen#else 13776fc7a71fd6b23541e3f5c9ab85f089ded5ad2e49ruengeler SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/UDP/IPv6 (errno = %d).\n", errno); 1378ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen close(SCTP_BASE_VAR(userspace_udpsctp6)); 1379f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen#endif 1380ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen SCTP_BASE_VAR(userspace_udpsctp6) = -1; 1381ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen } else { 1382ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen setReceiveBufferSize(SCTP_BASE_VAR(userspace_udpsctp6), SB_RAW); /* 128K */ 1383ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen setSendBufferSize(SCTP_BASE_VAR(userspace_udpsctp6), SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */ 1384ba1ce00b85a38f8276850a5fd7bbc14c1dfdeff7tuexen } 1385b735c0f45be3595abe0c88e2b5667780be2e27dctuexen } 138607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 138707961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 138807961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#endif 138907961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen#if !defined(__Userspace_os_Windows) 139022a33a1debfe70529be4aa018a2912bfe5dcd8dat#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) 1391b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#if defined(INET) || defined(INET6) 1392b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_route) != -1) { 13933a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen int rc; 13943a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen 1395b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadroute), NULL, &recv_function_route, NULL))) { 1396a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't start routing thread (%d).\n", rc); 1397d93dfec9706e00ca6d9ceeb72462367b22d74ccetuexen close(SCTP_BASE_VAR(userspace_route)); 1398d93dfec9706e00ca6d9ceeb72462367b22d74ccetuexen SCTP_BASE_VAR(userspace_route) = -1; 13993a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 14003a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 1401b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 14027943a5e518ee0e8d37d70b5637430137cedc918dt#endif 1403085a50552dced389ab59174355a4ec1ee478be97tuexen#if defined(INET) 1404b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_rawsctp) != -1) { 1405587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen int rc; 1406587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen 1407b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadraw), NULL, &recv_function_raw, NULL))) { 1408a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv4 recv thread (%d).\n", rc); 1409d93dfec9706e00ca6d9ceeb72462367b22d74ccetuexen close(SCTP_BASE_VAR(userspace_rawsctp)); 1410d93dfec9706e00ca6d9ceeb72462367b22d74ccetuexen SCTP_BASE_VAR(userspace_rawsctp) = -1; 1411bca1dae6587a640359abee04337c0463b0a3893tuexen } 1412bca1dae6587a640359abee04337c0463b0a3893tuexen } 1413b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_udpsctp) != -1) { 1414587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen int rc; 1415587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen 1416b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadudp), NULL, &recv_function_udp, NULL))) { 1417a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv4 recv thread (%d).\n", rc); 1418d93dfec9706e00ca6d9ceeb72462367b22d74ccetuexen close(SCTP_BASE_VAR(userspace_udpsctp)); 1419d93dfec9706e00ca6d9ceeb72462367b22d74ccetuexen SCTP_BASE_VAR(userspace_udpsctp) = -1; 142007961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 142107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 1422085a50552dced389ab59174355a4ec1ee478be97tuexen#endif 1423085a50552dced389ab59174355a4ec1ee478be97tuexen#if defined(INET6) 1424b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) { 142507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen int rc; 142607961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 1427b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadraw6), NULL, &recv_function_raw6, NULL))) { 1428a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv6 recv thread (%d).\n", rc); 1429d93dfec9706e00ca6d9ceeb72462367b22d74ccetuexen close(SCTP_BASE_VAR(userspace_rawsctp6)); 1430d93dfec9706e00ca6d9ceeb72462367b22d74ccetuexen SCTP_BASE_VAR(userspace_rawsctp6) = -1; 143107961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 143207961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen } 1433b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) { 143407961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen int rc; 143507961c43dc77daf1aa2b3258312d943f0eaa8b38tuexen 1436b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadudp6), NULL, &recv_function_udp6, NULL))) { 1437a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv6 recv thread (%d).\n", rc); 1438d93dfec9706e00ca6d9ceeb72462367b22d74ccetuexen close(SCTP_BASE_VAR(userspace_udpsctp6)); 1439d93dfec9706e00ca6d9ceeb72462367b22d74ccetuexen SCTP_BASE_VAR(userspace_udpsctp6) = -1; 1440bca1dae6587a640359abee04337c0463b0a3893tuexen } 1441bca1dae6587a640359abee04337c0463b0a3893tuexen } 1442085a50552dced389ab59174355a4ec1ee478be97tuexen#endif 1443587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#else 1444085a50552dced389ab59174355a4ec1ee478be97tuexen#if defined(INET) 1445b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_rawsctp) != -1) { 1446b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if ((SCTP_BASE_VAR(recvthreadraw) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_raw, NULL, 0, NULL)) == NULL) { 1447a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv4 recv thread.\n"); 1448f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_rawsctp)); 1449d93dfec9706e00ca6d9ceeb72462367b22d74ccetuexen SCTP_BASE_VAR(userspace_rawsctp) = -1; 1450587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen } 1451587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen } 1452b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_udpsctp) != -1) { 1453a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen if ((SCTP_BASE_VAR(recvthreadudp) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_udp, NULL, 0, NULL)) == NULL) { 1454a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv4 recv thread.\n"); 1455f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_udpsctp)); 1456d93dfec9706e00ca6d9ceeb72462367b22d74ccetuexen SCTP_BASE_VAR(userspace_udpsctp) = -1; 1457587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen } 1458587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen } 1459085a50552dced389ab59174355a4ec1ee478be97tuexen#endif 1460085a50552dced389ab59174355a4ec1ee478be97tuexen#if defined(INET6) 1461b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) { 1462a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen if ((SCTP_BASE_VAR(recvthreadraw6) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_raw6, NULL, 0, NULL)) == NULL) { 1463a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv6 recv thread.\n"); 1464f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_rawsctp6)); 1465d93dfec9706e00ca6d9ceeb72462367b22d74ccetuexen SCTP_BASE_VAR(userspace_rawsctp6) = -1; 146659caa502fe5258530a6f6eab10155a6dac5d8d5atuexen } 146759caa502fe5258530a6f6eab10155a6dac5d8d5atuexen } 1468b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) { 1469a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen if ((SCTP_BASE_VAR(recvthreadudp6) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_udp6, NULL, 0, NULL)) == NULL) { 1470a1d7a8516e4d5b2136c5bb3d49aeac80271a36b0tuexen SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv6 recv thread.\n"); 1471f83a7fabb73ab722cdbd1ee394eb24237dfe5c33tuexen closesocket(SCTP_BASE_VAR(userspace_udpsctp6)); 1472d93dfec9706e00ca6d9ceeb72462367b22d74ccetuexen SCTP_BASE_VAR(userspace_udpsctp6) = -1; 147359caa502fe5258530a6f6eab10155a6dac5d8d5atuexen } 147459caa502fe5258530a6f6eab10155a6dac5d8d5atuexen } 1475587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen#endif 1476085a50552dced389ab59174355a4ec1ee478be97tuexen#endif 1477bca1dae6587a640359abee04337c0463b0a3893tuexen} 1478bca1dae6587a640359abee04337c0463b0a3893tuexen 1479bca1dae6587a640359abee04337c0463b0a3893tuexenvoid 14803a33bc97bd0dd721a91035f5cf26c1956f264d3etuexenrecv_thread_destroy(void) 1481587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen{ 148222a33a1debfe70529be4aa018a2912bfe5dcd8dat#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) 1483b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#if defined(INET) || defined(INET6) 1484b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_route) != -1) { 1485b735c0f45be3595abe0c88e2b5667780be2e27dctuexen close(SCTP_BASE_VAR(userspace_route)); 14863a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 1487b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 1488b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 1489b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#if defined(INET) 1490b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_rawsctp) != -1) { 14913a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#if defined(__Userspace_os_Windows) 1492b735c0f45be3595abe0c88e2b5667780be2e27dctuexen closesocket(SCTP_BASE_VAR(userspace_rawsctp)); 14933a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#else 1494b735c0f45be3595abe0c88e2b5667780be2e27dctuexen close(SCTP_BASE_VAR(userspace_rawsctp)); 1495c5fa57e95fcabaa1ab0fcbd4ccab1e68487798c4tuexen#endif 1496587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen } 1497b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_udpsctp) != -1) { 14983a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#if defined(__Userspace_os_Windows) 1499b735c0f45be3595abe0c88e2b5667780be2e27dctuexen closesocket(SCTP_BASE_VAR(userspace_udpsctp)); 15003a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#else 1501b735c0f45be3595abe0c88e2b5667780be2e27dctuexen close(SCTP_BASE_VAR(userspace_udpsctp)); 15023a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#endif 1503587a0a600ce5ed1f37d26deeabb0fe9be27da00etuexen } 1504b735c0f45be3595abe0c88e2b5667780be2e27dctuexen#endif 15053a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#if defined(INET6) 1506b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) { 15073a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#if defined(__Userspace_os_Windows) 1508b735c0f45be3595abe0c88e2b5667780be2e27dctuexen closesocket(SCTP_BASE_VAR(userspace_rawsctp6)); 15093a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#else 1510b735c0f45be3595abe0c88e2b5667780be2e27dctuexen close(SCTP_BASE_VAR(userspace_rawsctp6)); 15113a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#endif 15123a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 1513b735c0f45be3595abe0c88e2b5667780be2e27dctuexen if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) { 15143a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#if defined(__Userspace_os_Windows) 1515b735c0f45be3595abe0c88e2b5667780be2e27dctuexen closesocket(SCTP_BASE_VAR(userspace_udpsctp6)); 15163a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#else 1517b735c0f45be3595abe0c88e2b5667780be2e27dctuexen close(SCTP_BASE_VAR(userspace_udpsctp6)); 15183a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#endif 15193a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen } 15203a33bc97bd0dd721a91035f5cf26c1956f264d3etuexen#endif 1521bca1dae6587a640359abee04337c0463b0a3893tuexen} 15226b5474dec62bc128acb56d0ad4ae413b91fedb09t#else 15236b5474dec62bc128acb56d0ad4ae413b91fedb09tint foo; 152400e1eea74e46d1a26092bf75dc0147015547aaf8tuexen#endif 1525