netwerk/sctp/src/user_recv_thread.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rwxr-xr-x

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial