tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

user_recv_thread.c (50537B)


      1 /*-
      2 * Copyright (c) 2009-2010 Brad Penoff
      3 * Copyright (c) 2009-2010 Humaira Kamal
      4 * Copyright (c) 2011-2012 Irene Ruengeler
      5 * Copyright (c) 2011-2012 Michael Tuexen
      6 * All rights reserved.
      7 *
      8 * Redistribution and use in source and binary forms, with or without
      9 * modification, are permitted provided that the following conditions
     10 * are met:
     11 * 1. Redistributions of source code must retain the above copyright
     12 *    notice, this list of conditions and the following disclaimer.
     13 * 2. Redistributions in binary form must reproduce the above copyright
     14 *    notice, this list of conditions and the following disclaimer in the
     15 *    documentation and/or other materials provided with the distribution.
     16 *
     17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27 * SUCH DAMAGE.
     28 *
     29 */
     30 
     31 #if defined(INET) || defined(INET6)
     32 #include <sys/types.h>
     33 #if !defined(_WIN32)
     34 #include <sys/socket.h>
     35 #include <netinet/in.h>
     36 #include <unistd.h>
     37 #include <pthread.h>
     38 #if !defined(__DragonFly__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
     39 #include <sys/uio.h>
     40 #else
     41 #include <user_ip6_var.h>
     42 #endif
     43 #endif
     44 #include <netinet/sctp_os.h>
     45 #include <netinet/sctp_var.h>
     46 #include <netinet/sctp_pcb.h>
     47 #include <netinet/sctp_input.h>
     48 #if 0
     49 #if defined(__linux__)
     50 #include <linux/netlink.h>
     51 #ifdef HAVE_LINUX_IF_ADDR_H
     52 #include <linux/if_addr.h>
     53 #endif
     54 #ifdef HAVE_LINUX_RTNETLINK_H
     55 #include <linux/rtnetlink.h>
     56 #endif
     57 #endif
     58 #endif
     59 #if defined(HAVE_NET_ROUTE_H)
     60 # include <net/route.h>
     61 #elif defined(__APPLE__)
     62 /* Apple SDKs for iOS, tvOS, watchOS, etc. don't ship this header */
     63 # define RTM_NEWADDR 0xc
     64 # define RTM_DELADDR 0xd
     65 # define RTAX_IFA 5
     66 # define RTAX_MAX 8
     67 #endif
     68 /* local macros and datatypes used to get IP addresses system independently */
     69 #if !defined(IP_PKTINFO) && !defined(IP_RECVDSTADDR)
     70 # error "Can't determine socket option to use to get UDP IP"
     71 #endif
     72 
     73 void recv_thread_destroy(void);
     74 
     75 #define MAXLEN_MBUF_CHAIN 128
     76 
     77 #define ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
     78 
     79 #if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__)
     80 #define NEXT_SA(ap) ap = (struct sockaddr *) \
     81 ((caddr_t) ap + (ap->sa_len ? ROUNDUP(ap->sa_len, sizeof (uint32_t)) : sizeof(uint32_t)))
     82 #endif
     83 
     84 #if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__)
     85 static void
     86 sctp_get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
     87 {
     88 int i;
     89 
     90 for (i = 0; i < RTAX_MAX; i++) {
     91 	if (addrs & (1 << i)) {
     92 		rti_info[i] = sa;
     93 		NEXT_SA(sa);
     94 	} else {
     95 		rti_info[i] = NULL;
     96 	}
     97 }
     98 }
     99 
    100 static void
    101 sctp_handle_ifamsg(unsigned char type, unsigned short index, struct sockaddr *sa)
    102 {
    103 int rc;
    104 struct ifaddrs *ifa, *ifas;
    105 
    106 /* handle only the types we want */
    107 if ((type != RTM_NEWADDR) && (type != RTM_DELADDR)) {
    108 	return;
    109 }
    110 
    111 rc = getifaddrs(&ifas);
    112 if (rc != 0) {
    113 	return;
    114 }
    115 for (ifa = ifas; ifa; ifa = ifa->ifa_next) {
    116 	if (index == if_nametoindex(ifa->ifa_name)) {
    117 		break;
    118 	}
    119 }
    120 if (ifa == NULL) {
    121 	freeifaddrs(ifas);
    122 	return;
    123 }
    124 
    125 /* relay the appropriate address change to the base code */
    126 if (type == RTM_NEWADDR) {
    127 	(void)sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID,
    128 	                           NULL,
    129 	                           if_nametoindex(ifa->ifa_name),
    130 	                           0,
    131 	                           ifa->ifa_name,
    132 	                           NULL,
    133 	                           sa,
    134 	                           0,
    135 	                           1);
    136 } else {
    137 	sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr,
    138 	                       if_nametoindex(ifa->ifa_name),
    139 	                       ifa->ifa_name);
    140 }
    141 freeifaddrs(ifas);
    142 }
    143 
    144 static void *
    145 recv_function_route(void *arg)
    146 {
    147 ssize_t ret;
    148 struct ifa_msghdr *ifa;
    149 char rt_buffer[1024];
    150 struct sockaddr *sa, *rti_info[RTAX_MAX];
    151 
    152 sctp_userspace_set_threadname("SCTP addr mon");
    153 
    154 while (1) {
    155 	memset(rt_buffer, 0, sizeof(rt_buffer));
    156 	ret = recv(SCTP_BASE_VAR(userspace_route), rt_buffer, sizeof(rt_buffer), 0);
    157 
    158 	if (ret > 0) {
    159 		ifa = (struct ifa_msghdr *) rt_buffer;
    160 		if (ifa->ifam_type != RTM_DELADDR && ifa->ifam_type != RTM_NEWADDR) {
    161 			continue;
    162 		}
    163 		sa = (struct sockaddr *) (ifa + 1);
    164 		sctp_get_rtaddrs(ifa->ifam_addrs, sa, rti_info);
    165 		switch (ifa->ifam_type) {
    166 		case RTM_DELADDR:
    167 		case RTM_NEWADDR:
    168 			sctp_handle_ifamsg(ifa->ifam_type, ifa->ifam_index, rti_info[RTAX_IFA]);
    169 			break;
    170 		default:
    171 			/* ignore this routing event */
    172 			break;
    173 		}
    174 	}
    175 	if (ret < 0) {
    176 		if (errno == EAGAIN || errno == EINTR) {
    177 			continue;
    178 		} else {
    179 			break;
    180 		}
    181 	}
    182 }
    183 return (NULL);
    184 }
    185 #endif
    186 
    187 #if 0
    188 /* This does not yet work on Linux */
    189 static void *
    190 recv_function_route(void *arg)
    191 {
    192 int len;
    193 char buf[4096];
    194 struct iovec iov = { buf, sizeof(buf) };
    195 struct msghdr msg;
    196 struct nlmsghdr *nh;
    197 struct ifaddrmsg *rtmsg;
    198 struct rtattr *rtatp;
    199 struct in_addr *inp;
    200 struct sockaddr_nl sanl;
    201 #ifdef INET
    202 struct sockaddr_in *sa;
    203 #endif
    204 #ifdef INET6
    205 struct sockaddr_in6 *sa6;
    206 #endif
    207 
    208 for (;;) {
    209 	memset(&sanl, 0, sizeof(sanl));
    210 	sanl.nl_family = AF_NETLINK;
    211 	sanl.nl_groups = RTMGRP_IPV6_IFADDR | RTMGRP_IPV4_IFADDR;
    212 	memset(&msg, 0, sizeof(struct msghdr));
    213 	msg.msg_name = (void *)&sanl;
    214 	msg.msg_namelen = sizeof(sanl);
    215 	msg.msg_iov = &iov;
    216 	msg.msg_iovlen = 1;
    217 	msg.msg_control = NULL;
    218 	msg.msg_controllen = 0;
    219 
    220 	len = recvmsg(SCTP_BASE_VAR(userspace_route), &msg, 0);
    221 
    222 	if (len < 0) {
    223 		if (errno == EAGAIN || errno == EINTR) {
    224 			continue;
    225 		} else {
    226 			break;
    227 		}
    228 	}
    229 	for (nh = (struct nlmsghdr *) buf; NLMSG_OK (nh, len);
    230 		nh = NLMSG_NEXT (nh, len)) {
    231 		if (nh->nlmsg_type == NLMSG_DONE)
    232 			break;
    233 
    234 		if (nh->nlmsg_type == RTM_NEWADDR || nh->nlmsg_type == RTM_DELADDR) {
    235 			rtmsg = (struct ifaddrmsg *)NLMSG_DATA(nh);
    236 			rtatp = (struct rtattr *)IFA_RTA(rtmsg);
    237 			if (rtatp->rta_type == IFA_ADDRESS) {
    238 				inp = (struct in_addr *)RTA_DATA(rtatp);
    239 				switch (rtmsg->ifa_family) {
    240 #ifdef INET
    241 				case AF_INET:
    242 					sa = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
    243 					sa->sin_family = rtmsg->ifa_family;
    244 					sa->sin_port = 0;
    245 					memcpy(&sa->sin_addr, inp, sizeof(struct in_addr));
    246 					sctp_handle_ifamsg(nh->nlmsg_type, rtmsg->ifa_index, (struct sockaddr *)sa);
    247 					break;
    248 #endif
    249 #ifdef INET6
    250 				case AF_INET6:
    251 					sa6 = (struct sockaddr_in6 *)malloc(sizeof(struct sockaddr_in6));
    252 					sa6->sin6_family = rtmsg->ifa_family;
    253 					sa6->sin6_port = 0;
    254 					memcpy(&sa6->sin6_addr, inp, sizeof(struct in6_addr));
    255 					sctp_handle_ifamsg(nh->nlmsg_type, rtmsg->ifa_index, (struct sockaddr *)sa6);
    256 					break;
    257 #endif
    258 				default:
    259 					SCTPDBG(SCTP_DEBUG_USR, "Address family %d not supported.\n", rtmsg->ifa_family);
    260 					break;
    261 				}
    262 			}
    263 		}
    264 	}
    265 }
    266 return (NULL);
    267 }
    268 #endif
    269 
    270 #ifdef INET
    271 static void *
    272 recv_function_raw(void *arg)
    273 {
    274 struct mbuf **recvmbuf;
    275 struct ip *iphdr;
    276 struct sctphdr *sh;
    277 uint16_t port;
    278 int offset, ecn = 0;
    279 int compute_crc = 1;
    280 struct sctp_chunkhdr *ch;
    281 struct sockaddr_in src, dst;
    282 #if !defined(_WIN32)
    283 ssize_t res;
    284 unsigned int ncounter;
    285 struct msghdr msg;
    286 struct iovec recv_iovec[MAXLEN_MBUF_CHAIN];
    287 #else
    288 WSABUF recv_iovec[MAXLEN_MBUF_CHAIN];
    289 int nResult, m_ErrorCode;
    290 DWORD flags;
    291 DWORD ncounter;
    292 struct sockaddr_in from;
    293 int fromlen;
    294 #endif
    295 /*Initially the entire set of mbufs is to be allocated.
    296   to_fill indicates this amount. */
    297 int to_fill = MAXLEN_MBUF_CHAIN;
    298 /* iovlen is the size of each mbuf in the chain */
    299 int i, n;
    300 unsigned int iovlen = MCLBYTES;
    301 int want_ext = (iovlen > MLEN)? 1 : 0;
    302 int want_header = 0;
    303 
    304 sctp_userspace_set_threadname("SCTP/IP4 rcv");
    305 
    306 memset(&src, 0, sizeof(struct sockaddr_in));
    307 memset(&dst, 0, sizeof(struct sockaddr_in));
    308 
    309 recvmbuf = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN);
    310 
    311 while (1) {
    312 	for (i = 0; i < to_fill; i++) {
    313 		/* Not getting the packet header. Tests with chain of one run
    314 		   as usual without having the packet header.
    315 		   Have tried both sending and receiving
    316 		 */
    317 		recvmbuf[i] = sctp_get_mbuf_for_msg(iovlen, want_header, M_NOWAIT, want_ext, MT_DATA);
    318 #if !defined(_WIN32)
    319 		recv_iovec[i].iov_base = (caddr_t)recvmbuf[i]->m_data;
    320 		recv_iovec[i].iov_len = iovlen;
    321 #else
    322 		recv_iovec[i].buf = (caddr_t)recvmbuf[i]->m_data;
    323 		recv_iovec[i].len = iovlen;
    324 #endif
    325 	}
    326 	to_fill = 0;
    327 #if defined(_WIN32)
    328 	flags = 0;
    329 	ncounter = 0;
    330 	fromlen = sizeof(struct sockaddr_in);
    331 	memset(&from, 0, sizeof(struct sockaddr_in));
    332 
    333 	nResult = WSARecvFrom(SCTP_BASE_VAR(userspace_rawsctp), recv_iovec, MAXLEN_MBUF_CHAIN, &ncounter, &flags, (struct sockaddr *)&from, &fromlen, NULL, NULL);
    334 	if (nResult != 0) {
    335 		m_ErrorCode = WSAGetLastError();
    336 		if ((m_ErrorCode == WSAENOTSOCK) || (m_ErrorCode == WSAEINTR)) {
    337 			break;
    338 		}
    339 		continue;
    340 	}
    341 	n = ncounter;
    342 #else
    343 	memset(&msg, 0, sizeof(struct msghdr));
    344 	msg.msg_name = NULL;
    345 	msg.msg_namelen = 0;
    346 	msg.msg_iov = recv_iovec;
    347 	msg.msg_iovlen = MAXLEN_MBUF_CHAIN;
    348 	msg.msg_control = NULL;
    349 	msg.msg_controllen = 0;
    350 	res = recvmsg(SCTP_BASE_VAR(userspace_rawsctp), &msg, 0);
    351 	if (res < 0) {
    352 		if (errno == EAGAIN || errno == EINTR) {
    353 			continue;
    354 		} else {
    355 			break;
    356 		}
    357 	}
    358 	ncounter = (unsigned int)res;
    359 	n = (int)res;
    360 #endif
    361 	SCTP_HEADER_LEN(recvmbuf[0]) = n; /* length of total packet */
    362 	SCTP_STAT_INCR(sctps_recvpackets);
    363 	SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
    364 
    365 	if ((unsigned int)n <= iovlen) {
    366 		SCTP_BUF_LEN(recvmbuf[0]) = n;
    367 		(to_fill)++;
    368 	} else {
    369 		i = 0;
    370 		SCTP_BUF_LEN(recvmbuf[0]) = iovlen;
    371 
    372 		ncounter -= min(ncounter, iovlen);
    373 		(to_fill)++;
    374 		do {
    375 			recvmbuf[i]->m_next = recvmbuf[i+1];
    376 			SCTP_BUF_LEN(recvmbuf[i]->m_next) = min(ncounter, iovlen);
    377 			i++;
    378 			ncounter -= min(ncounter, iovlen);
    379 			(to_fill)++;
    380 		} while (ncounter > 0);
    381 	}
    382 
    383 	offset = sizeof(struct ip) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
    384 	if (SCTP_BUF_LEN(recvmbuf[0]) < offset) {
    385 			if ((recvmbuf[0] = m_pullup(recvmbuf[0], offset)) == NULL) {
    386 			SCTP_STAT_INCR(sctps_hdrops);
    387 			continue;
    388 		}
    389 	}
    390 	iphdr = mtod(recvmbuf[0], struct ip *);
    391 	sh = (struct sctphdr *)((caddr_t)iphdr + sizeof(struct ip));
    392 	ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
    393 	offset -= sizeof(struct sctp_chunkhdr);
    394 
    395 	if (iphdr->ip_tos != 0) {
    396 		ecn = iphdr->ip_tos & 0x03;
    397 	}
    398 
    399 	dst.sin_family = AF_INET;
    400 #ifdef HAVE_SIN_LEN
    401 	dst.sin_len = sizeof(struct sockaddr_in);
    402 #endif
    403 	dst.sin_addr = iphdr->ip_dst;
    404 	dst.sin_port = sh->dest_port;
    405 
    406 	src.sin_family = AF_INET;
    407 #ifdef HAVE_SIN_LEN
    408 	src.sin_len = sizeof(struct sockaddr_in);
    409 #endif
    410 	src.sin_addr = iphdr->ip_src;
    411 	src.sin_port = sh->src_port;
    412 
    413 	/* SCTP does not allow broadcasts or multicasts */
    414 	if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
    415 		m_freem(recvmbuf[0]);
    416 		continue;
    417 	}
    418 	if (SCTP_IS_IT_BROADCAST(dst.sin_addr, recvmbuf[0])) {
    419 		m_freem(recvmbuf[0]);
    420 		continue;
    421 	}
    422 
    423 	port = 0;
    424 
    425 	if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
    426 	    ((IN4_ISLOOPBACK_ADDRESS(&src.sin_addr) &&
    427 	      IN4_ISLOOPBACK_ADDRESS(&dst.sin_addr)) ||
    428 	     (src.sin_addr.s_addr == dst.sin_addr.s_addr))) {
    429 		compute_crc = 0;
    430 		SCTP_STAT_INCR(sctps_recvhwcrc);
    431 	} else {
    432 		SCTP_STAT_INCR(sctps_recvswcrc);
    433 	}
    434 	SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
    435 	SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", offset);
    436 	sctp_common_input_processing(&recvmbuf[0], sizeof(struct ip), offset, n,
    437 	                             (struct sockaddr *)&src,
    438 	                             (struct sockaddr *)&dst,
    439 	                             sh, ch,
    440 	                             compute_crc,
    441 	                             ecn,
    442 	                             SCTP_DEFAULT_VRFID, port);
    443 	if (recvmbuf[0]) {
    444 		m_freem(recvmbuf[0]);
    445 	}
    446 }
    447 for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
    448 	m_free(recvmbuf[i]);
    449 }
    450 /* free the array itself */
    451 free(recvmbuf);
    452 SCTPDBG(SCTP_DEBUG_USR, "%s: Exiting SCTP/IP4 rcv\n", __func__);
    453 return (NULL);
    454 }
    455 #endif
    456 
    457 #if defined(INET6)
    458 static void *
    459 recv_function_raw6(void *arg)
    460 {
    461 struct mbuf **recvmbuf6;
    462 #if !defined(_WIN32)
    463 ssize_t res;
    464 unsigned int ncounter;
    465 struct iovec recv_iovec[MAXLEN_MBUF_CHAIN];
    466 struct msghdr msg;
    467 struct cmsghdr *cmsgptr;
    468 char cmsgbuf[CMSG_SPACE(sizeof (struct in6_pktinfo))];
    469 #else
    470 WSABUF recv_iovec[MAXLEN_MBUF_CHAIN];
    471 int nResult, m_ErrorCode;
    472 DWORD ncounter = 0;
    473 struct sockaddr_in6 from;
    474 GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
    475 LPFN_WSARECVMSG WSARecvMsg;
    476 WSACMSGHDR *cmsgptr;
    477 WSAMSG msg;
    478 char ControlBuffer[1024];
    479 #endif
    480 struct sockaddr_in6 src, dst;
    481 struct sctphdr *sh;
    482 int offset;
    483 struct sctp_chunkhdr *ch;
    484 /*Initially the entire set of mbufs is to be allocated.
    485   to_fill indicates this amount. */
    486 int to_fill = MAXLEN_MBUF_CHAIN;
    487 /* iovlen is the size of each mbuf in the chain */
    488 int i, n;
    489 int compute_crc = 1;
    490 unsigned int iovlen = MCLBYTES;
    491 int want_ext = (iovlen > MLEN)? 1 : 0;
    492 int want_header = 0;
    493 
    494 sctp_userspace_set_threadname("SCTP/IP6 rcv");
    495 
    496 recvmbuf6 = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN);
    497 
    498 for (;;) {
    499 	for (i = 0; i < to_fill; i++) {
    500 		/* Not getting the packet header. Tests with chain of one run
    501 		   as usual without having the packet header.
    502 		   Have tried both sending and receiving
    503 		 */
    504 		recvmbuf6[i] = sctp_get_mbuf_for_msg(iovlen, want_header, M_NOWAIT, want_ext, MT_DATA);
    505 #if !defined(_WIN32)
    506 		recv_iovec[i].iov_base = (caddr_t)recvmbuf6[i]->m_data;
    507 		recv_iovec[i].iov_len = iovlen;
    508 #else
    509 		recv_iovec[i].buf = (caddr_t)recvmbuf6[i]->m_data;
    510 		recv_iovec[i].len = iovlen;
    511 #endif
    512 	}
    513 	to_fill = 0;
    514 #if defined(_WIN32)
    515 	ncounter = 0;
    516 	memset(&from, 0, sizeof(struct sockaddr_in6));
    517 	nResult = WSAIoctl(SCTP_BASE_VAR(userspace_rawsctp6), SIO_GET_EXTENSION_FUNCTION_POINTER,
    518 	                   &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID,
    519 	                   &WSARecvMsg, sizeof WSARecvMsg,
    520 	                   &ncounter, NULL, NULL);
    521 	if (nResult == 0) {
    522 		msg.name = (void *)&src;
    523 		msg.namelen = sizeof(struct sockaddr_in6);
    524 		msg.lpBuffers = recv_iovec;
    525 		msg.dwBufferCount = MAXLEN_MBUF_CHAIN;
    526 		msg.Control.len = sizeof ControlBuffer;
    527 		msg.Control.buf = ControlBuffer;
    528 		msg.dwFlags = 0;
    529 		nResult = WSARecvMsg(SCTP_BASE_VAR(userspace_rawsctp6), &msg, &ncounter, NULL, NULL);
    530 	}
    531 	if (nResult != 0) {
    532 		m_ErrorCode = WSAGetLastError();
    533 		if ((m_ErrorCode == WSAENOTSOCK) || (m_ErrorCode == WSAEINTR)) {
    534 			break;
    535 		}
    536 		continue;
    537 	}
    538 	n = ncounter;
    539 #else
    540 	memset(&msg, 0, sizeof(struct msghdr));
    541 	memset(&src, 0, sizeof(struct sockaddr_in6));
    542 	memset(&dst, 0, sizeof(struct sockaddr_in6));
    543 	memset(cmsgbuf, 0, CMSG_SPACE(sizeof (struct in6_pktinfo)));
    544 	msg.msg_name = (void *)&src;
    545 	msg.msg_namelen = sizeof(struct sockaddr_in6);
    546 	msg.msg_iov = recv_iovec;
    547 	msg.msg_iovlen = MAXLEN_MBUF_CHAIN;
    548 	msg.msg_control = (void *)cmsgbuf;
    549 	msg.msg_controllen = (socklen_t)CMSG_SPACE(sizeof (struct in6_pktinfo));
    550 	msg.msg_flags = 0;
    551 	res = recvmsg(SCTP_BASE_VAR(userspace_rawsctp6), &msg, 0);
    552 	if (res < 0) {
    553 		if (errno == EAGAIN || errno == EINTR) {
    554 			continue;
    555 		} else {
    556 			break;
    557 		}
    558 	}
    559 	ncounter = (unsigned int)res;
    560 	n = (int)res;
    561 #endif
    562 	SCTP_HEADER_LEN(recvmbuf6[0]) = n; /* length of total packet */
    563 	SCTP_STAT_INCR(sctps_recvpackets);
    564 	SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
    565 
    566 	if ((unsigned int)n <= iovlen) {
    567 		SCTP_BUF_LEN(recvmbuf6[0]) = n;
    568 		(to_fill)++;
    569 	} else {
    570 		i = 0;
    571 		SCTP_BUF_LEN(recvmbuf6[0]) = iovlen;
    572 
    573 		ncounter -= min(ncounter, iovlen);
    574 		(to_fill)++;
    575 		do {
    576 			recvmbuf6[i]->m_next = recvmbuf6[i+1];
    577 			SCTP_BUF_LEN(recvmbuf6[i]->m_next) = min(ncounter, iovlen);
    578 			i++;
    579 			ncounter -= min(ncounter, iovlen);
    580 			(to_fill)++;
    581 		} while (ncounter > 0);
    582 	}
    583 
    584 	for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
    585 		if ((cmsgptr->cmsg_level == IPPROTO_IPV6) && (cmsgptr->cmsg_type == IPV6_PKTINFO)) {
    586 			struct in6_pktinfo * info;
    587 
    588 			info = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
    589 			memcpy((void *)&dst.sin6_addr, (const void *) &(info->ipi6_addr), sizeof(struct in6_addr));
    590 			break;
    591 		}
    592 	}
    593 
    594 	/* SCTP does not allow broadcasts or multicasts */
    595 	if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) {
    596 		m_freem(recvmbuf6[0]);
    597 		continue;
    598 	}
    599 
    600 	offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
    601 	if (SCTP_BUF_LEN(recvmbuf6[0]) < offset) {
    602 		if ((recvmbuf6[0] = m_pullup(recvmbuf6[0], offset)) == NULL) {
    603 			SCTP_STAT_INCR(sctps_hdrops);
    604 			continue;
    605 		}
    606 	}
    607 	sh = mtod(recvmbuf6[0], struct sctphdr *);
    608 	ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
    609 	offset -= sizeof(struct sctp_chunkhdr);
    610 
    611 	dst.sin6_family = AF_INET6;
    612 #ifdef HAVE_SIN6_LEN
    613 	dst.sin6_len = sizeof(struct sockaddr_in6);
    614 #endif
    615 	dst.sin6_port = sh->dest_port;
    616 
    617 	src.sin6_family = AF_INET6;
    618 #ifdef HAVE_SIN6_LEN
    619 	src.sin6_len = sizeof(struct sockaddr_in6);
    620 #endif
    621 	src.sin6_port = sh->src_port;
    622 	if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
    623 	    (memcmp(&src.sin6_addr, &dst.sin6_addr, sizeof(struct in6_addr)) == 0)) {
    624 		compute_crc = 0;
    625 		SCTP_STAT_INCR(sctps_recvhwcrc);
    626 	} else {
    627 		SCTP_STAT_INCR(sctps_recvswcrc);
    628 	}
    629 	SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
    630 	SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", offset);
    631 	sctp_common_input_processing(&recvmbuf6[0], 0, offset, n,
    632 	                             (struct sockaddr *)&src,
    633 	                             (struct sockaddr *)&dst,
    634 	                             sh, ch,
    635 	                             compute_crc,
    636 	                             0,
    637 	                             SCTP_DEFAULT_VRFID, 0);
    638 	if (recvmbuf6[0]) {
    639 		m_freem(recvmbuf6[0]);
    640 	}
    641 }
    642 for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
    643 	m_free(recvmbuf6[i]);
    644 }
    645 /* free the array itself */
    646 free(recvmbuf6);
    647 SCTPDBG(SCTP_DEBUG_USR, "%s: Exiting SCTP/IP6 rcv\n", __func__);
    648 return (NULL);
    649 }
    650 #endif
    651 
    652 #ifdef INET
    653 static void *
    654 recv_function_udp(void *arg)
    655 {
    656 struct mbuf **udprecvmbuf;
    657 /*Initially the entire set of mbufs is to be allocated.
    658   to_fill indicates this amount. */
    659 int to_fill = MAXLEN_MBUF_CHAIN;
    660 /* iovlen is the size of each mbuf in the chain */
    661 int i, n, offset;
    662 unsigned int iovlen = MCLBYTES;
    663 int want_ext = (iovlen > MLEN)? 1 : 0;
    664 int want_header = 0;
    665 struct sctphdr *sh;
    666 uint16_t port;
    667 struct sctp_chunkhdr *ch;
    668 struct sockaddr_in src, dst;
    669 #if defined(IP_PKTINFO)
    670 char cmsgbuf[CMSG_SPACE(sizeof(struct in_pktinfo))];
    671 #else
    672 char cmsgbuf[CMSG_SPACE(sizeof(struct in_addr))];
    673 #endif
    674 int compute_crc = 1;
    675 #if !defined(_WIN32)
    676 ssize_t res;
    677 unsigned int ncounter;
    678 struct iovec iov[MAXLEN_MBUF_CHAIN];
    679 struct msghdr msg;
    680 struct cmsghdr *cmsgptr;
    681 #else
    682 GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
    683 LPFN_WSARECVMSG WSARecvMsg;
    684 char ControlBuffer[1024];
    685 WSABUF iov[MAXLEN_MBUF_CHAIN];
    686 WSAMSG msg;
    687 int nResult, m_ErrorCode;
    688 WSACMSGHDR *cmsgptr;
    689 DWORD ncounter;
    690 #endif
    691 
    692 sctp_userspace_set_threadname("SCTP/UDP/IP4 rcv");
    693 
    694 udprecvmbuf = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN);
    695 
    696 while (1) {
    697 	for (i = 0; i < to_fill; i++) {
    698 		/* Not getting the packet header. Tests with chain of one run
    699 		   as usual without having the packet header.
    700 		   Have tried both sending and receiving
    701 		 */
    702 		udprecvmbuf[i] = sctp_get_mbuf_for_msg(iovlen, want_header, M_NOWAIT, want_ext, MT_DATA);
    703 #if !defined(_WIN32)
    704 		iov[i].iov_base = (caddr_t)udprecvmbuf[i]->m_data;
    705 		iov[i].iov_len = iovlen;
    706 #else
    707 		iov[i].buf = (caddr_t)udprecvmbuf[i]->m_data;
    708 		iov[i].len = iovlen;
    709 #endif
    710 	}
    711 	to_fill = 0;
    712 #if !defined(_WIN32)
    713 	memset(&msg, 0, sizeof(struct msghdr));
    714 #else
    715 	memset(&msg, 0, sizeof(WSAMSG));
    716 #endif
    717 	memset(&src, 0, sizeof(struct sockaddr_in));
    718 	memset(&dst, 0, sizeof(struct sockaddr_in));
    719 	memset(cmsgbuf, 0, sizeof(cmsgbuf));
    720 
    721 #if !defined(_WIN32)
    722 	msg.msg_name = (void *)&src;
    723 	msg.msg_namelen = sizeof(struct sockaddr_in);
    724 	msg.msg_iov = iov;
    725 	msg.msg_iovlen = MAXLEN_MBUF_CHAIN;
    726 	msg.msg_control = (void *)cmsgbuf;
    727 	msg.msg_controllen = sizeof(cmsgbuf);
    728 	msg.msg_flags = 0;
    729 
    730 	res = recvmsg(SCTP_BASE_VAR(userspace_udpsctp), &msg, 0);
    731 	if (res < 0) {
    732 		if (errno == EAGAIN || errno == EINTR) {
    733 			continue;
    734 		} else {
    735 			break;
    736 		}
    737 	}
    738 	ncounter = (unsigned int)res;
    739 	n = (int)res;
    740 #else
    741 	nResult = WSAIoctl(SCTP_BASE_VAR(userspace_udpsctp), SIO_GET_EXTENSION_FUNCTION_POINTER,
    742 	 &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID,
    743 	 &WSARecvMsg, sizeof WSARecvMsg,
    744 	 &ncounter, NULL, NULL);
    745 	if (nResult == 0) {
    746 		msg.name = (void *)&src;
    747 		msg.namelen = sizeof(struct sockaddr_in);
    748 		msg.lpBuffers = iov;
    749 		msg.dwBufferCount = MAXLEN_MBUF_CHAIN;
    750 		msg.Control.len = sizeof ControlBuffer;
    751 		msg.Control.buf = ControlBuffer;
    752 		msg.dwFlags = 0;
    753 		nResult = WSARecvMsg(SCTP_BASE_VAR(userspace_udpsctp), &msg, &ncounter, NULL, NULL);
    754 	}
    755 	if (nResult != 0) {
    756 		m_ErrorCode = WSAGetLastError();
    757 		if ((m_ErrorCode == WSAENOTSOCK) || (m_ErrorCode == WSAEINTR)) {
    758 			break;
    759 		}
    760 		continue;
    761 	}
    762 	n = ncounter;
    763 #endif
    764 	SCTP_HEADER_LEN(udprecvmbuf[0]) = n; /* length of total packet */
    765 	SCTP_STAT_INCR(sctps_recvpackets);
    766 	SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
    767 
    768 	if ((unsigned int)n <= iovlen) {
    769 		SCTP_BUF_LEN(udprecvmbuf[0]) = n;
    770 		(to_fill)++;
    771 	} else {
    772 		i = 0;
    773 		SCTP_BUF_LEN(udprecvmbuf[0]) = iovlen;
    774 
    775 		ncounter -= min(ncounter, iovlen);
    776 		(to_fill)++;
    777 		do {
    778 			udprecvmbuf[i]->m_next = udprecvmbuf[i+1];
    779 			SCTP_BUF_LEN(udprecvmbuf[i]->m_next) = min(ncounter, iovlen);
    780 			i++;
    781 			ncounter -= min(ncounter, iovlen);
    782 			(to_fill)++;
    783 		} while (ncounter > 0);
    784 	}
    785 
    786 	for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
    787 #if defined(IP_PKTINFO)
    788 		if ((cmsgptr->cmsg_level == IPPROTO_IP) && (cmsgptr->cmsg_type == IP_PKTINFO)) {
    789 			struct in_pktinfo *info;
    790 
    791 			dst.sin_family = AF_INET;
    792 #ifdef HAVE_SIN_LEN
    793 			dst.sin_len = sizeof(struct sockaddr_in);
    794 #endif
    795 			info = (struct in_pktinfo *)CMSG_DATA(cmsgptr);
    796 			memcpy((void *)&dst.sin_addr, (const void *)&(info->ipi_addr), sizeof(struct in_addr));
    797 			break;
    798 		}
    799 #else
    800 		if ((cmsgptr->cmsg_level == IPPROTO_IP) && (cmsgptr->cmsg_type == IP_RECVDSTADDR)) {
    801 			struct in_addr *addr;
    802 
    803 			dst.sin_family = AF_INET;
    804 #ifdef HAVE_SIN_LEN
    805 			dst.sin_len = sizeof(struct sockaddr_in);
    806 #endif
    807 			addr = (struct in_addr *)CMSG_DATA(cmsgptr);
    808 			memcpy((void *)&dst.sin_addr, (const void *)addr, sizeof(struct in_addr));
    809 			break;
    810 		}
    811 #endif
    812 	}
    813 
    814 	/* SCTP does not allow broadcasts or multicasts */
    815 	if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
    816 		m_freem(udprecvmbuf[0]);
    817 		continue;
    818 	}
    819 	if (SCTP_IS_IT_BROADCAST(dst.sin_addr, udprecvmbuf[0])) {
    820 		m_freem(udprecvmbuf[0]);
    821 		continue;
    822 	}
    823 
    824 	offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
    825 	if (SCTP_BUF_LEN(udprecvmbuf[0]) < offset) {
    826 		if ((udprecvmbuf[0] = m_pullup(udprecvmbuf[0], offset)) == NULL) {
    827 			SCTP_STAT_INCR(sctps_hdrops);
    828 			continue;
    829 		}
    830 	}
    831 	sh = mtod(udprecvmbuf[0], struct sctphdr *);
    832 	ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
    833 	offset -= sizeof(struct sctp_chunkhdr);
    834 
    835 	port = src.sin_port;
    836 	src.sin_port = sh->src_port;
    837 	dst.sin_port = sh->dest_port;
    838 	if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
    839 	    (src.sin_addr.s_addr == dst.sin_addr.s_addr)) {
    840 		compute_crc = 0;
    841 		SCTP_STAT_INCR(sctps_recvhwcrc);
    842 	} else {
    843 		SCTP_STAT_INCR(sctps_recvswcrc);
    844 	}
    845 	SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
    846 	SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", offset);
    847 	sctp_common_input_processing(&udprecvmbuf[0], 0, offset, n,
    848 	                             (struct sockaddr *)&src,
    849 	                             (struct sockaddr *)&dst,
    850 	                             sh, ch,
    851 	                             compute_crc,
    852 	                             0,
    853 	                             SCTP_DEFAULT_VRFID, port);
    854 	if (udprecvmbuf[0]) {
    855 		m_freem(udprecvmbuf[0]);
    856 	}
    857 }
    858 for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
    859 	m_free(udprecvmbuf[i]);
    860 }
    861 /* free the array itself */
    862 free(udprecvmbuf);
    863 SCTPDBG(SCTP_DEBUG_USR, "%s: Exiting SCTP/UDP/IP4 rcv\n", __func__);
    864 return (NULL);
    865 }
    866 #endif
    867 
    868 #if defined(INET6)
    869 static void *
    870 recv_function_udp6(void *arg)
    871 {
    872 struct mbuf **udprecvmbuf6;
    873 /*Initially the entire set of mbufs is to be allocated.
    874   to_fill indicates this amount. */
    875 int to_fill = MAXLEN_MBUF_CHAIN;
    876 /* iovlen is the size of each mbuf in the chain */
    877 int i, n, offset;
    878 unsigned int iovlen = MCLBYTES;
    879 int want_ext = (iovlen > MLEN)? 1 : 0;
    880 int want_header = 0;
    881 struct sockaddr_in6 src, dst;
    882 struct sctphdr *sh;
    883 uint16_t port;
    884 struct sctp_chunkhdr *ch;
    885 char cmsgbuf[CMSG_SPACE(sizeof (struct in6_pktinfo))];
    886 int compute_crc = 1;
    887 #if !defined(_WIN32)
    888 struct iovec iov[MAXLEN_MBUF_CHAIN];
    889 struct msghdr msg;
    890 struct cmsghdr *cmsgptr;
    891 ssize_t res;
    892 unsigned int ncounter;
    893 #else
    894 GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
    895 LPFN_WSARECVMSG WSARecvMsg;
    896 char ControlBuffer[1024];
    897 WSABUF iov[MAXLEN_MBUF_CHAIN];
    898 WSAMSG msg;
    899 int nResult, m_ErrorCode;
    900 WSACMSGHDR *cmsgptr;
    901 DWORD ncounter;
    902 #endif
    903 
    904 sctp_userspace_set_threadname("SCTP/UDP/IP6 rcv");
    905 
    906 udprecvmbuf6 = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN);
    907 while (1) {
    908 	for (i = 0; i < to_fill; i++) {
    909 		/* Not getting the packet header. Tests with chain of one run
    910 		   as usual without having the packet header.
    911 		   Have tried both sending and receiving
    912 		 */
    913 		udprecvmbuf6[i] = sctp_get_mbuf_for_msg(iovlen, want_header, M_NOWAIT, want_ext, MT_DATA);
    914 #if !defined(_WIN32)
    915 		iov[i].iov_base = (caddr_t)udprecvmbuf6[i]->m_data;
    916 		iov[i].iov_len = iovlen;
    917 #else
    918 		iov[i].buf = (caddr_t)udprecvmbuf6[i]->m_data;
    919 		iov[i].len = iovlen;
    920 #endif
    921 	}
    922 	to_fill = 0;
    923 
    924 #if !defined(_WIN32)
    925 	memset(&msg, 0, sizeof(struct msghdr));
    926 #else
    927 	memset(&msg, 0, sizeof(WSAMSG));
    928 #endif
    929 	memset(&src, 0, sizeof(struct sockaddr_in6));
    930 	memset(&dst, 0, sizeof(struct sockaddr_in6));
    931 	memset(cmsgbuf, 0, CMSG_SPACE(sizeof (struct in6_pktinfo)));
    932 
    933 #if !defined(_WIN32)
    934 	msg.msg_name = (void *)&src;
    935 	msg.msg_namelen = sizeof(struct sockaddr_in6);
    936 	msg.msg_iov = iov;
    937 	msg.msg_iovlen = MAXLEN_MBUF_CHAIN;
    938 	msg.msg_control = (void *)cmsgbuf;
    939 	msg.msg_controllen = (socklen_t)CMSG_SPACE(sizeof (struct in6_pktinfo));
    940 	msg.msg_flags = 0;
    941 
    942 	res = recvmsg(SCTP_BASE_VAR(userspace_udpsctp6), &msg, 0);
    943 	if (res < 0) {
    944 		if (errno == EAGAIN || errno == EINTR) {
    945 			continue;
    946 		} else {
    947 			break;
    948 		}
    949 	}
    950 	ncounter = (unsigned int)res;
    951 	n = (int)res;
    952 #else
    953 	nResult = WSAIoctl(SCTP_BASE_VAR(userspace_udpsctp6), SIO_GET_EXTENSION_FUNCTION_POINTER,
    954 	                   &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID,
    955 	                   &WSARecvMsg, sizeof WSARecvMsg,
    956 	                   &ncounter, NULL, NULL);
    957 	if (nResult == SOCKET_ERROR) {
    958 		m_ErrorCode = WSAGetLastError();
    959 		WSARecvMsg = NULL;
    960 	}
    961 	if (nResult == 0) {
    962 		msg.name = (void *)&src;
    963 		msg.namelen = sizeof(struct sockaddr_in6);
    964 		msg.lpBuffers = iov;
    965 		msg.dwBufferCount = MAXLEN_MBUF_CHAIN;
    966 		msg.Control.len = sizeof ControlBuffer;
    967 		msg.Control.buf = ControlBuffer;
    968 		msg.dwFlags = 0;
    969 		nResult = WSARecvMsg(SCTP_BASE_VAR(userspace_udpsctp6), &msg, &ncounter, NULL, NULL);
    970 	}
    971 	if (nResult != 0) {
    972 		m_ErrorCode = WSAGetLastError();
    973 		if ((m_ErrorCode == WSAENOTSOCK) || (m_ErrorCode == WSAEINTR)) {
    974 			break;
    975 		}
    976 		continue;
    977 	}
    978 	n = ncounter;
    979 #endif
    980 	SCTP_HEADER_LEN(udprecvmbuf6[0]) = n; /* length of total packet */
    981 	SCTP_STAT_INCR(sctps_recvpackets);
    982 	SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
    983 
    984 	if ((unsigned int)n <= iovlen) {
    985 		SCTP_BUF_LEN(udprecvmbuf6[0]) = n;
    986 		(to_fill)++;
    987 	} else {
    988 		i = 0;
    989 		SCTP_BUF_LEN(udprecvmbuf6[0]) = iovlen;
    990 
    991 		ncounter -= min(ncounter, iovlen);
    992 		(to_fill)++;
    993 		do {
    994 			udprecvmbuf6[i]->m_next = udprecvmbuf6[i+1];
    995 			SCTP_BUF_LEN(udprecvmbuf6[i]->m_next) = min(ncounter, iovlen);
    996 			i++;
    997 			ncounter -= min(ncounter, iovlen);
    998 			(to_fill)++;
    999 		} while (ncounter > 0);
   1000 	}
   1001 
   1002 	for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
   1003 		if ((cmsgptr->cmsg_level == IPPROTO_IPV6) && (cmsgptr->cmsg_type == IPV6_PKTINFO)) {
   1004 			struct in6_pktinfo *info;
   1005 
   1006 			dst.sin6_family = AF_INET6;
   1007 #ifdef HAVE_SIN6_LEN
   1008 			dst.sin6_len = sizeof(struct sockaddr_in6);
   1009 #endif
   1010 			info = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
   1011 			/*dst.sin6_port = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));*/
   1012 			memcpy((void *)&dst.sin6_addr, (const void *)&(info->ipi6_addr), sizeof(struct in6_addr));
   1013 		}
   1014 	}
   1015 
   1016 	/* SCTP does not allow broadcasts or multicasts */
   1017 	if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) {
   1018 		m_freem(udprecvmbuf6[0]);
   1019 		continue;
   1020 	}
   1021 
   1022 	offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
   1023 	if (SCTP_BUF_LEN(udprecvmbuf6[0]) < offset) {
   1024 		if ((udprecvmbuf6[0] = m_pullup(udprecvmbuf6[0], offset)) == NULL) {
   1025 			SCTP_STAT_INCR(sctps_hdrops);
   1026 			continue;
   1027 		}
   1028 	}
   1029 	sh = mtod(udprecvmbuf6[0], struct sctphdr *);
   1030 	ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
   1031 	offset -= sizeof(struct sctp_chunkhdr);
   1032 
   1033 	port = src.sin6_port;
   1034 	src.sin6_port = sh->src_port;
   1035 	dst.sin6_port = sh->dest_port;
   1036 	if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
   1037 	    (memcmp(&src.sin6_addr, &dst.sin6_addr, sizeof(struct in6_addr)) == 0)) {
   1038 		compute_crc = 0;
   1039 		SCTP_STAT_INCR(sctps_recvhwcrc);
   1040 	} else {
   1041 		SCTP_STAT_INCR(sctps_recvswcrc);
   1042 	}
   1043 	SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
   1044 	SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", (int)sizeof(struct sctphdr));
   1045 	sctp_common_input_processing(&udprecvmbuf6[0], 0, offset, n,
   1046 	                             (struct sockaddr *)&src,
   1047 	                             (struct sockaddr *)&dst,
   1048 	                             sh, ch,
   1049 	                             compute_crc,
   1050 	                             0,
   1051 	                             SCTP_DEFAULT_VRFID, port);
   1052 	if (udprecvmbuf6[0]) {
   1053 		m_freem(udprecvmbuf6[0]);
   1054 	}
   1055 }
   1056 for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
   1057 	m_free(udprecvmbuf6[i]);
   1058 }
   1059 /* free the array itself */
   1060 free(udprecvmbuf6);
   1061 SCTPDBG(SCTP_DEBUG_USR, "%s: Exiting SCTP/UDP/IP6 rcv\n", __func__);
   1062 return (NULL);
   1063 }
   1064 #endif
   1065 
   1066 #if defined(_WIN32)
   1067 static void
   1068 setReceiveBufferSize(SOCKET sfd, int new_size)
   1069 #else
   1070 static void
   1071 setReceiveBufferSize(int sfd, int new_size)
   1072 #endif
   1073 {
   1074 int ch = new_size;
   1075 
   1076 if (setsockopt (sfd, SOL_SOCKET, SO_RCVBUF, (void*)&ch, sizeof(ch)) < 0) {
   1077 #if defined(_WIN32)
   1078 	SCTPDBG(SCTP_DEBUG_USR, "Can't set recv-buffers size (errno = %d).\n", WSAGetLastError());
   1079 #else
   1080 	SCTPDBG(SCTP_DEBUG_USR, "Can't set recv-buffers size (errno = %d).\n", errno);
   1081 #endif
   1082 }
   1083 return;
   1084 }
   1085 
   1086 #if defined(_WIN32)
   1087 static void
   1088 setSendBufferSize(SOCKET sfd, int new_size)
   1089 #else
   1090 static void
   1091 setSendBufferSize(int sfd, int new_size)
   1092 #endif
   1093 {
   1094 int ch = new_size;
   1095 
   1096 if (setsockopt (sfd, SOL_SOCKET, SO_SNDBUF, (void*)&ch, sizeof(ch)) < 0) {
   1097 #if defined(_WIN32)
   1098 	SCTPDBG(SCTP_DEBUG_USR, "Can't set send-buffers size (errno = %d).\n", WSAGetLastError());
   1099 #else
   1100 	SCTPDBG(SCTP_DEBUG_USR, "Can't set send-buffers size (errno = %d).\n", errno);
   1101 #endif
   1102 }
   1103 return;
   1104 }
   1105 
   1106 #define SOCKET_TIMEOUT 100 /* in ms */
   1107 void
   1108 recv_thread_init(void)
   1109 {
   1110 #if defined(INET)
   1111 struct sockaddr_in addr_ipv4;
   1112 const int hdrincl = 1;
   1113 #endif
   1114 #if defined(INET6)
   1115 struct sockaddr_in6 addr_ipv6;
   1116 #endif
   1117 #if defined(INET) || defined(INET6)
   1118 const int on = 1;
   1119 #endif
   1120 #if !defined(_WIN32)
   1121 struct timeval timeout;
   1122 
   1123 memset(&timeout, 0, sizeof(struct timeval));
   1124 timeout.tv_sec  = (SOCKET_TIMEOUT / 1000);
   1125 timeout.tv_usec = (SOCKET_TIMEOUT % 1000) * 1000;
   1126 #else
   1127 unsigned int timeout = SOCKET_TIMEOUT; /* Timeout in milliseconds */
   1128 #endif
   1129 #if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__)
   1130 if (SCTP_BASE_VAR(userspace_route) == -1) {
   1131 	if ((SCTP_BASE_VAR(userspace_route) = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) {
   1132 		SCTPDBG(SCTP_DEBUG_USR, "Can't create routing socket (errno = %d).\n", errno);
   1133 	}
   1134 #if 0
   1135 	struct sockaddr_nl sanl;
   1136 
   1137 	if ((SCTP_BASE_VAR(userspace_route) = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) {
   1138 		SCTPDBG(SCTP_DEBUG_USR, "Can't create routing socket (errno = %d.\n", errno);
   1139 	}
   1140 	memset(&sanl, 0, sizeof(sanl));
   1141 	sanl.nl_family = AF_NETLINK;
   1142 	sanl.nl_groups = 0;
   1143 #ifdef INET
   1144 	sanl.nl_groups |= RTMGRP_IPV4_IFADDR;
   1145 #endif
   1146 #ifdef INET6
   1147 	sanl.nl_groups |= RTMGRP_IPV6_IFADDR;
   1148 #endif
   1149 	if (bind(SCTP_BASE_VAR(userspace_route), (struct sockaddr *) &sanl, sizeof(sanl)) < 0) {
   1150 		SCTPDBG(SCTP_DEBUG_USR, "Can't bind routing socket (errno = %d).\n", errno);
   1151 		close(SCTP_BASE_VAR(userspace_route));
   1152 		SCTP_BASE_VAR(userspace_route) = -1;
   1153 	}
   1154 #endif
   1155 	if (SCTP_BASE_VAR(userspace_route) != -1) {
   1156 		if (setsockopt(SCTP_BASE_VAR(userspace_route), SOL_SOCKET, SO_RCVTIMEO,(const void*)&timeout, sizeof(struct timeval)) < 0) {
   1157 			SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on routing socket (errno = %d).\n", errno);
   1158 #if defined(_WIN32)
   1159 			closesocket(SCTP_BASE_VAR(userspace_route));
   1160 #else
   1161 			close(SCTP_BASE_VAR(userspace_route));
   1162 #endif
   1163 			SCTP_BASE_VAR(userspace_route) = -1;
   1164 		}
   1165 	}
   1166 }
   1167 #endif
   1168 #if defined(INET)
   1169 if (SCTP_BASE_VAR(userspace_rawsctp) == -1) {
   1170 	if ((SCTP_BASE_VAR(userspace_rawsctp) = socket(AF_INET, SOCK_RAW, IPPROTO_SCTP)) == -1) {
   1171 #if defined(_WIN32)
   1172 		SCTPDBG(SCTP_DEBUG_USR, "Can't create raw socket for IPv4 (errno = %d).\n", WSAGetLastError());
   1173 #else
   1174 		SCTPDBG(SCTP_DEBUG_USR, "Can't create raw socket for IPv4 (errno = %d).\n", errno);
   1175 #endif
   1176 	} else {
   1177 		/* complete setting up the raw SCTP socket */
   1178 		if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp), IPPROTO_IP, IP_HDRINCL,(const void*)&hdrincl, sizeof(int)) < 0) {
   1179 #if defined(_WIN32)
   1180 			SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_HDRINCL (errno = %d).\n", WSAGetLastError());
   1181 			closesocket(SCTP_BASE_VAR(userspace_rawsctp));
   1182 #else
   1183 			SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_HDRINCL (errno = %d).\n", errno);
   1184 			close(SCTP_BASE_VAR(userspace_rawsctp));
   1185 #endif
   1186 			SCTP_BASE_VAR(userspace_rawsctp) = -1;
   1187 		} else if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp), SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(timeout)) < 0) {
   1188 #if defined(_WIN32)
   1189 			SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/IPv4 (errno = %d).\n", WSAGetLastError());
   1190 			closesocket(SCTP_BASE_VAR(userspace_rawsctp));
   1191 #else
   1192 			SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/IPv4 (errno = %d).\n", errno);
   1193 			close(SCTP_BASE_VAR(userspace_rawsctp));
   1194 #endif
   1195 			SCTP_BASE_VAR(userspace_rawsctp) = -1;
   1196 		} else {
   1197 			memset((void *)&addr_ipv4, 0, sizeof(struct sockaddr_in));
   1198 #ifdef HAVE_SIN_LEN
   1199 			addr_ipv4.sin_len         = sizeof(struct sockaddr_in);
   1200 #endif
   1201 			addr_ipv4.sin_family      = AF_INET;
   1202 			addr_ipv4.sin_port        = htons(0);
   1203 			addr_ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
   1204 			if (bind(SCTP_BASE_VAR(userspace_rawsctp), (const struct sockaddr *)&addr_ipv4, sizeof(struct sockaddr_in)) < 0) {
   1205 #if defined(_WIN32)
   1206 				SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/IPv4 (errno = %d).\n", WSAGetLastError());
   1207 				closesocket(SCTP_BASE_VAR(userspace_rawsctp));
   1208 #else
   1209 				SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/IPv4 (errno = %d).\n", errno);
   1210 				close(SCTP_BASE_VAR(userspace_rawsctp));
   1211 #endif
   1212 				SCTP_BASE_VAR(userspace_rawsctp) = -1;
   1213 			} else {
   1214 				setReceiveBufferSize(SCTP_BASE_VAR(userspace_rawsctp), SB_RAW); /* 128K */
   1215 				setSendBufferSize(SCTP_BASE_VAR(userspace_rawsctp), SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */
   1216 			}
   1217 		}
   1218 	}
   1219 }
   1220 if ((SCTP_BASE_VAR(userspace_udpsctp) == -1) && (SCTP_BASE_SYSCTL(sctp_udp_tunneling_port) != 0)) {
   1221 	if ((SCTP_BASE_VAR(userspace_udpsctp) = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
   1222 #if defined(_WIN32)
   1223 		SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError());
   1224 #else
   1225 		SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv4 (errno = %d).\n", errno);
   1226 #endif
   1227 	} else {
   1228 #if defined(IP_PKTINFO)
   1229 		if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp), IPPROTO_IP, IP_PKTINFO, (const void *)&on, (int)sizeof(int)) < 0) {
   1230 #else
   1231 		if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp), IPPROTO_IP, IP_RECVDSTADDR, (const void *)&on, (int)sizeof(int)) < 0) {
   1232 #endif
   1233 #if defined(_WIN32)
   1234 #if defined(IP_PKTINFO)
   1235 			SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_PKTINFO on socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError());
   1236 #else
   1237 			SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_RECVDSTADDR on socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError());
   1238 #endif
   1239 			closesocket(SCTP_BASE_VAR(userspace_udpsctp));
   1240 #else
   1241 #if defined(IP_PKTINFO)
   1242 			SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_PKTINFO on socket for SCTP/UDP/IPv4 (errno = %d).\n", errno);
   1243 #else
   1244 			SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_RECVDSTADDR on socket for SCTP/UDP/IPv4 (errno = %d).\n", errno);
   1245 #endif
   1246 			close(SCTP_BASE_VAR(userspace_udpsctp));
   1247 #endif
   1248 			SCTP_BASE_VAR(userspace_udpsctp) = -1;
   1249 		} else if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp), SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(timeout)) < 0) {
   1250 #if defined(_WIN32)
   1251 			SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError());
   1252 			closesocket(SCTP_BASE_VAR(userspace_udpsctp));
   1253 #else
   1254 			SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/UDP/IPv4 (errno = %d).\n", errno);
   1255 			close(SCTP_BASE_VAR(userspace_udpsctp));
   1256 #endif
   1257 			SCTP_BASE_VAR(userspace_udpsctp) = -1;
   1258 		} else {
   1259 			memset((void *)&addr_ipv4, 0, sizeof(struct sockaddr_in));
   1260 #ifdef HAVE_SIN_LEN
   1261 			addr_ipv4.sin_len         = sizeof(struct sockaddr_in);
   1262 #endif
   1263 			addr_ipv4.sin_family      = AF_INET;
   1264 			addr_ipv4.sin_port        = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
   1265 			addr_ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
   1266 			if (bind(SCTP_BASE_VAR(userspace_udpsctp), (const struct sockaddr *)&addr_ipv4, sizeof(struct sockaddr_in)) < 0) {
   1267 #if defined(_WIN32)
   1268 				SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError());
   1269 				closesocket(SCTP_BASE_VAR(userspace_udpsctp));
   1270 #else
   1271 				SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/UDP/IPv4 (errno = %d).\n", errno);
   1272 				close(SCTP_BASE_VAR(userspace_udpsctp));
   1273 #endif
   1274 				SCTP_BASE_VAR(userspace_udpsctp) = -1;
   1275 			} else {
   1276 				setReceiveBufferSize(SCTP_BASE_VAR(userspace_udpsctp), SB_RAW); /* 128K */
   1277 				setSendBufferSize(SCTP_BASE_VAR(userspace_udpsctp), SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */
   1278 			}
   1279 		}
   1280 	}
   1281 }
   1282 #endif
   1283 #if defined(INET6)
   1284 if (SCTP_BASE_VAR(userspace_rawsctp6) == -1) {
   1285 	if ((SCTP_BASE_VAR(userspace_rawsctp6) = socket(AF_INET6, SOCK_RAW, IPPROTO_SCTP)) == -1) {
   1286 #if defined(_WIN32)
   1287 		SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError());
   1288 #else
   1289 		SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/IPv6 (errno = %d).\n", errno);
   1290 #endif
   1291 	} else {
   1292 		/* complete setting up the raw SCTP socket */
   1293 #if defined(IPV6_RECVPKTINFO)
   1294 		if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp6), IPPROTO_IPV6, IPV6_RECVPKTINFO, (const void *)&on, sizeof(on)) < 0) {
   1295 #if defined(_WIN32)
   1296 			SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_RECVPKTINFO on socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError());
   1297 			closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
   1298 #else
   1299 			SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_RECVPKTINFO on socket for SCTP/IPv6 (errno = %d).\n", errno);
   1300 			close(SCTP_BASE_VAR(userspace_rawsctp6));
   1301 #endif
   1302 			SCTP_BASE_VAR(userspace_rawsctp6) = -1;
   1303 		} else {
   1304 #else
   1305 		if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp6), IPPROTO_IPV6, IPV6_PKTINFO,(const void*)&on, sizeof(on)) < 0) {
   1306 #if defined(_WIN32)
   1307 			SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_PKTINFO on socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError());
   1308 			closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
   1309 #else
   1310 			SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_PKTINFO on socket for SCTP/IPv6 (errno = %d).\n", errno);
   1311 			close(SCTP_BASE_VAR(userspace_rawsctp6));
   1312 #endif
   1313 			SCTP_BASE_VAR(userspace_rawsctp6) = -1;
   1314 		} else {
   1315 #endif
   1316 			if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp6), IPPROTO_IPV6, IPV6_V6ONLY, (const void*)&on, (socklen_t)sizeof(on)) < 0) {
   1317 #if defined(_WIN32)
   1318 				SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_V6ONLY on socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError());
   1319 #else
   1320 				SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_V6ONLY on socket for SCTP/IPv6 (errno = %d).\n", errno);
   1321 #endif
   1322 			}
   1323 			if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp6), SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(timeout)) < 0) {
   1324 #if defined(_WIN32)
   1325 				SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError());
   1326 				closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
   1327 #else
   1328 				SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/IPv6 (errno = %d).\n", errno);
   1329 				close(SCTP_BASE_VAR(userspace_rawsctp6));
   1330 #endif
   1331 				SCTP_BASE_VAR(userspace_rawsctp6) = -1;
   1332 			} else {
   1333 				memset((void *)&addr_ipv6, 0, sizeof(struct sockaddr_in6));
   1334 #ifdef HAVE_SIN6_LEN
   1335 				addr_ipv6.sin6_len         = sizeof(struct sockaddr_in6);
   1336 #endif
   1337 				addr_ipv6.sin6_family      = AF_INET6;
   1338 				addr_ipv6.sin6_port        = htons(0);
   1339 				addr_ipv6.sin6_addr        = in6addr_any;
   1340 				if (bind(SCTP_BASE_VAR(userspace_rawsctp6), (const struct sockaddr *)&addr_ipv6, sizeof(struct sockaddr_in6)) < 0) {
   1341 #if defined(_WIN32)
   1342 					SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError());
   1343 					closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
   1344 #else
   1345 					SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/IPv6 (errno = %d).\n", errno);
   1346 					close(SCTP_BASE_VAR(userspace_rawsctp6));
   1347 #endif
   1348 					SCTP_BASE_VAR(userspace_rawsctp6) = -1;
   1349 				} else {
   1350 					setReceiveBufferSize(SCTP_BASE_VAR(userspace_rawsctp6), SB_RAW); /* 128K */
   1351 					setSendBufferSize(SCTP_BASE_VAR(userspace_rawsctp6), SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */
   1352 				}
   1353 			}
   1354 		}
   1355 	}
   1356 }
   1357 if ((SCTP_BASE_VAR(userspace_udpsctp6) == -1) && (SCTP_BASE_SYSCTL(sctp_udp_tunneling_port) != 0)) {
   1358 	if ((SCTP_BASE_VAR(userspace_udpsctp6) = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
   1359 #if defined(_WIN32)
   1360 		SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError());
   1361 #else
   1362 		SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv6 (errno = %d).\n", errno);
   1363 #endif
   1364 	}
   1365 #if defined(IPV6_RECVPKTINFO)
   1366 	if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), IPPROTO_IPV6, IPV6_RECVPKTINFO, (const void *)&on, (int)sizeof(int)) < 0) {
   1367 #if defined(_WIN32)
   1368 		SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_RECVPKTINFO on socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError());
   1369 		closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
   1370 #else
   1371 		SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_RECVPKTINFO on socket for SCTP/UDP/IPv6 (errno = %d).\n", errno);
   1372 		close(SCTP_BASE_VAR(userspace_udpsctp6));
   1373 #endif
   1374 		SCTP_BASE_VAR(userspace_udpsctp6) = -1;
   1375 	} else {
   1376 #else
   1377 	if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), IPPROTO_IPV6, IPV6_PKTINFO, (const void *)&on, (int)sizeof(int)) < 0) {
   1378 #if defined(_WIN32)
   1379 		SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_PKTINFO on socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError());
   1380 		closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
   1381 #else
   1382 		SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_PKTINFO on socket for SCTP/UDP/IPv6 (errno = %d).\n", errno);
   1383 		close(SCTP_BASE_VAR(userspace_udpsctp6));
   1384 #endif
   1385 		SCTP_BASE_VAR(userspace_udpsctp6) = -1;
   1386 	} else {
   1387 #endif
   1388 		if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), IPPROTO_IPV6, IPV6_V6ONLY, (const void *)&on, (socklen_t)sizeof(on)) < 0) {
   1389 #if defined(_WIN32)
   1390 			SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_V6ONLY on socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError());
   1391 #else
   1392 			SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_V6ONLY on socket for SCTP/UDP/IPv6 (errno = %d).\n", errno);
   1393 #endif
   1394 		}
   1395 		if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(timeout)) < 0) {
   1396 #if defined(_WIN32)
   1397 			SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError());
   1398 			closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
   1399 #else
   1400 			SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/UDP/IPv6 (errno = %d).\n", errno);
   1401 			close(SCTP_BASE_VAR(userspace_udpsctp6));
   1402 #endif
   1403 			SCTP_BASE_VAR(userspace_udpsctp6) = -1;
   1404 		} else {
   1405 			memset((void *)&addr_ipv6, 0, sizeof(struct sockaddr_in6));
   1406 #ifdef HAVE_SIN6_LEN
   1407 			addr_ipv6.sin6_len         = sizeof(struct sockaddr_in6);
   1408 #endif
   1409 			addr_ipv6.sin6_family      = AF_INET6;
   1410 			addr_ipv6.sin6_port        = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
   1411 			addr_ipv6.sin6_addr        = in6addr_any;
   1412 			if (bind(SCTP_BASE_VAR(userspace_udpsctp6), (const struct sockaddr *)&addr_ipv6, sizeof(struct sockaddr_in6)) < 0) {
   1413 #if defined(_WIN32)
   1414 				SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError());
   1415 				closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
   1416 #else
   1417 				SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/UDP/IPv6 (errno = %d).\n", errno);
   1418 				close(SCTP_BASE_VAR(userspace_udpsctp6));
   1419 #endif
   1420 				SCTP_BASE_VAR(userspace_udpsctp6) = -1;
   1421 			} else {
   1422 				setReceiveBufferSize(SCTP_BASE_VAR(userspace_udpsctp6), SB_RAW); /* 128K */
   1423 				setSendBufferSize(SCTP_BASE_VAR(userspace_udpsctp6), SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */
   1424 			}
   1425 		}
   1426 	}
   1427 }
   1428 #endif
   1429 #if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__)
   1430 #if defined(INET) || defined(INET6)
   1431 if (SCTP_BASE_VAR(userspace_route) != -1) {
   1432 	int rc;
   1433 
   1434 	if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadroute), &recv_function_route))) {
   1435 		SCTPDBG(SCTP_DEBUG_USR, "Can't start routing thread (%d).\n", rc);
   1436 		close(SCTP_BASE_VAR(userspace_route));
   1437 		SCTP_BASE_VAR(userspace_route) = -1;
   1438 	}
   1439 }
   1440 #endif
   1441 #endif
   1442 #if defined(INET)
   1443 if (SCTP_BASE_VAR(userspace_rawsctp) != -1) {
   1444 	int rc;
   1445 
   1446 	if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadraw), &recv_function_raw))) {
   1447 		SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv4 recv thread (%d).\n", rc);
   1448 #if defined(_WIN32)
   1449 		closesocket(SCTP_BASE_VAR(userspace_rawsctp));
   1450 #else
   1451 		close(SCTP_BASE_VAR(userspace_rawsctp));
   1452 #endif
   1453 		SCTP_BASE_VAR(userspace_rawsctp) = -1;
   1454 	}
   1455 }
   1456 if (SCTP_BASE_VAR(userspace_udpsctp) != -1) {
   1457 	int rc;
   1458 
   1459 	if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadudp), &recv_function_udp))) {
   1460 		SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv4 recv thread (%d).\n", rc);
   1461 #if defined(_WIN32)
   1462 		closesocket(SCTP_BASE_VAR(userspace_udpsctp));
   1463 #else
   1464 		close(SCTP_BASE_VAR(userspace_udpsctp));
   1465 #endif
   1466 		SCTP_BASE_VAR(userspace_udpsctp) = -1;
   1467 	}
   1468 }
   1469 #endif
   1470 #if defined(INET6)
   1471 if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
   1472 	int rc;
   1473 
   1474 	if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadraw6), &recv_function_raw6))) {
   1475 		SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv6 recv thread (%d).\n", rc);
   1476 #if defined(_WIN32)
   1477 		closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
   1478 #else
   1479 		close(SCTP_BASE_VAR(userspace_rawsctp6));
   1480 #endif
   1481 		SCTP_BASE_VAR(userspace_rawsctp6) = -1;
   1482 	}
   1483 }
   1484 if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) {
   1485 	int rc;
   1486 
   1487 	if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadudp6), &recv_function_udp6))) {
   1488 		SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv6 recv thread (%d).\n", rc);
   1489 #if defined(_WIN32)
   1490 		closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
   1491 #else
   1492 		close(SCTP_BASE_VAR(userspace_udpsctp6));
   1493 #endif
   1494 		SCTP_BASE_VAR(userspace_udpsctp6) = -1;
   1495 	}
   1496 }
   1497 #endif
   1498 }
   1499 
   1500 void
   1501 recv_thread_destroy(void)
   1502 {
   1503 #if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__)
   1504 #if defined(INET) || defined(INET6)
   1505 if (SCTP_BASE_VAR(userspace_route) != -1) {
   1506 	close(SCTP_BASE_VAR(userspace_route));
   1507 	pthread_join(SCTP_BASE_VAR(recvthreadroute), NULL);
   1508 }
   1509 #endif
   1510 #endif
   1511 #if defined(INET)
   1512 if (SCTP_BASE_VAR(userspace_rawsctp) != -1) {
   1513 #if defined(_WIN32)
   1514 	closesocket(SCTP_BASE_VAR(userspace_rawsctp));
   1515 	SCTP_BASE_VAR(userspace_rawsctp) = -1;
   1516 	WaitForSingleObject(SCTP_BASE_VAR(recvthreadraw), INFINITE);
   1517 	CloseHandle(SCTP_BASE_VAR(recvthreadraw));
   1518 #else
   1519 	close(SCTP_BASE_VAR(userspace_rawsctp));
   1520 	SCTP_BASE_VAR(userspace_rawsctp) = -1;
   1521 	pthread_join(SCTP_BASE_VAR(recvthreadraw), NULL);
   1522 #endif
   1523 }
   1524 if (SCTP_BASE_VAR(userspace_udpsctp) != -1) {
   1525 #if defined(_WIN32)
   1526 	closesocket(SCTP_BASE_VAR(userspace_udpsctp));
   1527 	SCTP_BASE_VAR(userspace_udpsctp) = -1;
   1528 	WaitForSingleObject(SCTP_BASE_VAR(recvthreadudp), INFINITE);
   1529 	CloseHandle(SCTP_BASE_VAR(recvthreadudp));
   1530 #else
   1531 	close(SCTP_BASE_VAR(userspace_udpsctp));
   1532 	SCTP_BASE_VAR(userspace_udpsctp) = -1;
   1533 	pthread_join(SCTP_BASE_VAR(recvthreadudp), NULL);
   1534 #endif
   1535 }
   1536 #endif
   1537 #if defined(INET6)
   1538 if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
   1539 #if defined(_WIN32)
   1540 	closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
   1541 	SCTP_BASE_VAR(userspace_rawsctp6) = -1;
   1542 	WaitForSingleObject(SCTP_BASE_VAR(recvthreadraw6), INFINITE);
   1543 	CloseHandle(SCTP_BASE_VAR(recvthreadraw6));
   1544 #else
   1545 	close(SCTP_BASE_VAR(userspace_rawsctp6));
   1546 	SCTP_BASE_VAR(userspace_rawsctp6) = -1;
   1547 	pthread_join(SCTP_BASE_VAR(recvthreadraw6), NULL);
   1548 #endif
   1549 }
   1550 if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) {
   1551 #if defined(_WIN32)
   1552 	SCTP_BASE_VAR(userspace_udpsctp6) = -1;
   1553 	closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
   1554 	WaitForSingleObject(SCTP_BASE_VAR(recvthreadudp6), INFINITE);
   1555 	CloseHandle(SCTP_BASE_VAR(recvthreadudp6));
   1556 #else
   1557 	close(SCTP_BASE_VAR(userspace_udpsctp6));
   1558 	SCTP_BASE_VAR(userspace_udpsctp6) = -1;
   1559 	pthread_join(SCTP_BASE_VAR(recvthreadudp6), NULL);
   1560 #endif
   1561 }
   1562 #endif
   1563 }
   1564 #else
   1565 int foo;
   1566 #endif