コード例 #1
0
	/* free the array itself */
	free(udprecvmbuf6);
	return (NULL);
}
#endif

static void
setReceiveBufferSize(int sfd, int new_size)
{
	int ch = new_size;

	if (setsockopt (sfd, SOL_SOCKET, SO_RCVBUF, (void*)&ch, sizeof(ch)) < 0) {
#if defined (__Userspace_os_Windows)
		SCTPDBG(SCTP_DEBUG_USR, "Can't set recv-buffers size (errno = %d).\n", WSAGetLastError());
#else
		SCTPDBG(SCTP_DEBUG_USR, "Can't set recv-buffers size (errno = %d).\n", errno);
#endif
	}
	return;
}

static void
setSendBufferSize(int sfd, int new_size)
{
	int ch = new_size;

	if (setsockopt (sfd, SOL_SOCKET, SO_SNDBUF, (void*)&ch, sizeof(ch)) < 0) {
#if defined (__Userspace_os_Windows)
		SCTPDBG(SCTP_DEBUG_USR, "Can't set send-buffers size (errno = %d).\n", WSAGetLastError());
#else
		SCTPDBG(SCTP_DEBUG_USR, "Can't set send-buffers size (errno = %d).\n", errno);
#endif
	}
	return;
}

#define SOCKET_TIMEOUT 100 /* in ms */
void
recv_thread_init(void)
{
#if defined(INET)
	struct sockaddr_in addr_ipv4;
	const int hdrincl = 1;
#endif
#if defined(INET6)
	struct sockaddr_in6 addr_ipv6;
#endif
#if defined(INET) || defined(INET6)
	const int on = 1;
#endif
#if !defined(__Userspace_os_Windows)
	struct timeval timeout;

	timeout.tv_sec  = (SOCKET_TIMEOUT / 1000);
	timeout.tv_usec = (SOCKET_TIMEOUT % 1000) * 1000;
#else
	unsigned int timeout = SOCKET_TIMEOUT; /* Timeout in milliseconds */
#endif
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
	if (SCTP_BASE_VAR(userspace_route) == -1) {
		if ((SCTP_BASE_VAR(userspace_route) = socket(AF_ROUTE, SOCK_RAW, 0)) < 0) {
			SCTPDBG(SCTP_DEBUG_USR, "Can't create routing socket (errno = %d).\n", errno);
		}
#if 0
		struct sockaddr_nl sanl;

		if ((SCTP_BASE_VAR(userspace_route) = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) {
			SCTPDBG(SCTP_DEBUG_USR, "Can't create routing socket (errno = %d.\n", errno);
		}
		memset(&sanl, 0, sizeof(sanl));
		sanl.nl_family = AF_NETLINK;
		sanl.nl_groups = 0;
#ifdef INET
		sanl.nl_groups |= RTMGRP_IPV4_IFADDR;
#endif
#ifdef INET6
		sanl.nl_groups |= RTMGRP_IPV6_IFADDR;
#endif
		if (bind(SCTP_BASE_VAR(userspace_route), (struct sockaddr *) &sanl, sizeof(sanl)) < 0) {
			SCTPDBG(SCTP_DEBUG_USR, "Can't bind routing socket (errno = %d).\n", errno);
			close(SCTP_BASE_VAR(userspace_route));
			SCTP_BASE_VAR(userspace_route) = -1;
		}
#endif
		if (SCTP_BASE_VAR(userspace_route) != -1) {
			if (setsockopt(SCTP_BASE_VAR(userspace_route), SOL_SOCKET, SO_RCVTIMEO,(const void*)&timeout, sizeof(struct timeval)) < 0) {
				SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on routing socket (errno = %d).\n", errno);
#if defined(__Userspace_os_Windows)
				closesocket(SCTP_BASE_VAR(userspace_route));
#else
				close(SCTP_BASE_VAR(userspace_route));
#endif
				SCTP_BASE_VAR(userspace_route) = -1;
			}
		}
	}
#endif
#if defined(INET)
	if (SCTP_BASE_VAR(userspace_rawsctp) == -1) {
		if ((SCTP_BASE_VAR(userspace_rawsctp) = socket(AF_INET, SOCK_RAW, IPPROTO_SCTP)) < 0) {
#if defined(__Userspace_os_Windows)
			SCTPDBG(SCTP_DEBUG_USR, "Can't create raw socket for IPv4 (errno = %d).\n", WSAGetLastError());
#else
			SCTPDBG(SCTP_DEBUG_USR, "Can't create raw socket for IPv4 (errno = %d).\n", errno);
#endif
		} else {
			/* complete setting up the raw SCTP socket */
			if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp), IPPROTO_IP, IP_HDRINCL,(const void*)&hdrincl, sizeof(int)) < 0) {
#if defined(__Userspace_os_Windows)
				SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_HDRINCL (errno = %d).\n", WSAGetLastError());
				closesocket(SCTP_BASE_VAR(userspace_rawsctp));
#else
				SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_HDRINCL (errno = %d).\n", errno);
				close(SCTP_BASE_VAR(userspace_rawsctp));
#endif
				SCTP_BASE_VAR(userspace_rawsctp) = -1;
			} else if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp), SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(timeout)) < 0) {
#if defined(__Userspace_os_Windows)
				SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/IPv4 (errno = %d).\n", WSAGetLastError());
				closesocket(SCTP_BASE_VAR(userspace_rawsctp));
#else
				SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/IPv4 (errno = %d).\n", errno);
				close(SCTP_BASE_VAR(userspace_rawsctp));
#endif
				SCTP_BASE_VAR(userspace_rawsctp) = -1;
			} else {
				memset((void *)&addr_ipv4, 0, sizeof(struct sockaddr_in));
#ifdef HAVE_SIN_LEN
				addr_ipv4.sin_len         = sizeof(struct sockaddr_in);
#endif
				addr_ipv4.sin_family      = AF_INET;
				addr_ipv4.sin_port        = htons(0);
				addr_ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
				if (bind(SCTP_BASE_VAR(userspace_rawsctp), (const struct sockaddr *)&addr_ipv4, sizeof(struct sockaddr_in)) < 0) {
#if defined(__Userspace_os_Windows)
					SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/IPv4 (errno = %d).\n", WSAGetLastError());
					closesocket(SCTP_BASE_VAR(userspace_rawsctp));
#else
					SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/IPv4 (errno = %d).\n", errno);
					close(SCTP_BASE_VAR(userspace_rawsctp));
#endif
					SCTP_BASE_VAR(userspace_rawsctp) = -1;
				} else {
					setReceiveBufferSize(SCTP_BASE_VAR(userspace_rawsctp), SB_RAW); /* 128K */
					setSendBufferSize(SCTP_BASE_VAR(userspace_rawsctp), SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */
				}
			}
		}
	}
	if (SCTP_BASE_VAR(userspace_udpsctp) == -1) {
		if ((SCTP_BASE_VAR(userspace_udpsctp) = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
#if defined(__Userspace_os_Windows)
			SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError());
#else
			SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv4 (errno = %d).\n", errno);
#endif
		} else {
#if defined(IP_PKTINFO)
			if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp), IPPROTO_IP, IP_PKTINFO, (const void *)&on, (int)sizeof(int)) < 0) {
#else
			if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp), IPPROTO_IP, IP_RECVDSTADDR, (const void *)&on, (int)sizeof(int)) < 0) {
#endif
#if defined(__Userspace_os_Windows)
#if defined(IP_PKTINFO)
				SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_PKTINFO on socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError());
#else
				SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_RECVDSTADDR on socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError());
#endif
				closesocket(SCTP_BASE_VAR(userspace_udpsctp));
#else
#if defined(IP_PKTINFO)
				SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_PKTINFO on socket for SCTP/UDP/IPv4 (errno = %d).\n", errno);
#else
				SCTPDBG(SCTP_DEBUG_USR, "Can't set IP_RECVDSTADDR on socket for SCTP/UDP/IPv4 (errno = %d).\n", errno);
#endif
				close(SCTP_BASE_VAR(userspace_udpsctp));
#endif
				SCTP_BASE_VAR(userspace_udpsctp) = -1;
			} else if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp), SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(timeout)) < 0) {
#if defined(__Userspace_os_Windows)
				SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError());
				closesocket(SCTP_BASE_VAR(userspace_udpsctp));
#else
				SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/UDP/IPv4 (errno = %d).\n", errno);
				close(SCTP_BASE_VAR(userspace_udpsctp));
#endif
				SCTP_BASE_VAR(userspace_udpsctp) = -1;
			} else {
				memset((void *)&addr_ipv4, 0, sizeof(struct sockaddr_in));
#ifdef HAVE_SIN_LEN
				addr_ipv4.sin_len         = sizeof(struct sockaddr_in);
#endif
				addr_ipv4.sin_family      = AF_INET;
				addr_ipv4.sin_port        = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
				addr_ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
				if (bind(SCTP_BASE_VAR(userspace_udpsctp), (const struct sockaddr *)&addr_ipv4, sizeof(struct sockaddr_in)) < 0) {
#if defined(__Userspace_os_Windows)
					SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/UDP/IPv4 (errno = %d).\n", WSAGetLastError());
					closesocket(SCTP_BASE_VAR(userspace_udpsctp));
#else
					SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/UDP/IPv4 (errno = %d).\n", errno);
					close(SCTP_BASE_VAR(userspace_udpsctp));
#endif
					SCTP_BASE_VAR(userspace_udpsctp) = -1;
				} else {
					setReceiveBufferSize(SCTP_BASE_VAR(userspace_udpsctp), SB_RAW); /* 128K */
					setSendBufferSize(SCTP_BASE_VAR(userspace_udpsctp), SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */
				}
			}
		}
	}
#endif
#if defined(INET6)
	if (SCTP_BASE_VAR(userspace_rawsctp6) == -1) {
		if ((SCTP_BASE_VAR(userspace_rawsctp6) = socket(AF_INET6, SOCK_RAW, IPPROTO_SCTP)) < 0) {
#if defined(__Userspace_os_Windows)
			SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError());
#else
			SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/IPv6 (errno = %d).\n", errno);
#endif
		} else {
			/* complete setting up the raw SCTP socket */
#if defined(IPV6_RECVPKTINFO)
			if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp6), IPPROTO_IPV6, IPV6_RECVPKTINFO, (const void *)&on, sizeof(on)) < 0) {
#if defined(__Userspace_os_Windows)
				SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_RECVPKTINFO on socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError());
				closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
#else
				SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_RECVPKTINFO on socket for SCTP/IPv6 (errno = %d).\n", errno);
				close(SCTP_BASE_VAR(userspace_rawsctp6));
#endif
				SCTP_BASE_VAR(userspace_rawsctp6) = -1;
			} else {
#else
			if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp6), IPPROTO_IPV6, IPV6_PKTINFO,(const void*)&on, sizeof(on)) < 0) {
#if defined(__Userspace_os_Windows)
				SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_PKTINFO on socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError());
				closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
#else
				SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_PKTINFO on socket for SCTP/IPv6 (errno = %d).\n", errno);
				close(SCTP_BASE_VAR(userspace_rawsctp6));
#endif
				SCTP_BASE_VAR(userspace_rawsctp6) = -1;
			} else {
#endif
				if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp6), IPPROTO_IPV6, IPV6_V6ONLY, (const void*)&on, (socklen_t)sizeof(on)) < 0) {
#if defined(__Userspace_os_Windows)
					SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_V6ONLY on socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError());
#else
					SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_V6ONLY on socket for SCTP/IPv6 (errno = %d).\n", errno);
#endif
				}
				if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp6), SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(timeout)) < 0) {
#if defined(__Userspace_os_Windows)
					SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError());
					closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
#else
					SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/IPv6 (errno = %d).\n", errno);
					close(SCTP_BASE_VAR(userspace_rawsctp6));
#endif
					SCTP_BASE_VAR(userspace_rawsctp6) = -1;
				} else {
					memset((void *)&addr_ipv6, 0, sizeof(struct sockaddr_in6));
#ifdef HAVE_SIN6_LEN
					addr_ipv6.sin6_len         = sizeof(struct sockaddr_in6);
#endif
					addr_ipv6.sin6_family      = AF_INET6;
					addr_ipv6.sin6_port        = htons(0);
					addr_ipv6.sin6_addr        = in6addr_any;
					if (bind(SCTP_BASE_VAR(userspace_rawsctp6), (const struct sockaddr *)&addr_ipv6, sizeof(struct sockaddr_in6)) < 0) {
#if defined(__Userspace_os_Windows)
						SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/IPv6 (errno = %d).\n", WSAGetLastError());
						closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
#else
						SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/IPv6 (errno = %d).\n", errno);
						close(SCTP_BASE_VAR(userspace_rawsctp6));
#endif
						SCTP_BASE_VAR(userspace_rawsctp6) = -1;
					} else {
						setReceiveBufferSize(SCTP_BASE_VAR(userspace_rawsctp6), SB_RAW); /* 128K */
						setSendBufferSize(SCTP_BASE_VAR(userspace_rawsctp6), SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */
					}
				}
			}
		}
	}
	if (SCTP_BASE_VAR(userspace_udpsctp6) == -1) {
		if ((SCTP_BASE_VAR(userspace_udpsctp6) = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
#if defined(__Userspace_os_Windows)
			SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError());
#else
			SCTPDBG(SCTP_DEBUG_USR, "Can't create socket for SCTP/UDP/IPv6 (errno = %d).\n", errno);
#endif
		}
#if defined(IPV6_RECVPKTINFO)
		if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), IPPROTO_IPV6, IPV6_RECVPKTINFO, (const void *)&on, (int)sizeof(int)) < 0) {
#if defined(__Userspace_os_Windows)
			SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_RECVPKTINFO on socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError());
			closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
#else
			SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_RECVPKTINFO on socket for SCTP/UDP/IPv6 (errno = %d).\n", errno);
			close(SCTP_BASE_VAR(userspace_udpsctp6));
#endif
			SCTP_BASE_VAR(userspace_udpsctp6) = -1;
		} else {
#else
		if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), IPPROTO_IPV6, IPV6_PKTINFO, (const void *)&on, (int)sizeof(int)) < 0) {
#if defined(__Userspace_os_Windows)
			SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_PKTINFO on socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError());
			closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
#else
			SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_PKTINFO on socket for SCTP/UDP/IPv6 (errno = %d).\n", errno);
			close(SCTP_BASE_VAR(userspace_udpsctp6));
#endif
			SCTP_BASE_VAR(userspace_udpsctp6) = -1;
		} else {
#endif
			if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), IPPROTO_IPV6, IPV6_V6ONLY, (const void *)&on, (socklen_t)sizeof(on)) < 0) {
#if defined(__Userspace_os_Windows)
				SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_V6ONLY on socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError());
#else
				SCTPDBG(SCTP_DEBUG_USR, "Can't set IPV6_V6ONLY on socket for SCTP/UDP/IPv6 (errno = %d).\n", errno);
#endif
			}
			if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(timeout)) < 0) {
#if defined(__Userspace_os_Windows)
				SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError());
				closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
#else
				SCTPDBG(SCTP_DEBUG_USR, "Can't set timeout on socket for SCTP/UDP/IPv6 (errno = %d).\n", errno);
				close(SCTP_BASE_VAR(userspace_udpsctp6));
#endif
				SCTP_BASE_VAR(userspace_udpsctp6) = -1;
			} else {
				memset((void *)&addr_ipv6, 0, sizeof(struct sockaddr_in6));
#ifdef HAVE_SIN6_LEN
				addr_ipv6.sin6_len         = sizeof(struct sockaddr_in6);
#endif
				addr_ipv6.sin6_family      = AF_INET6;
				addr_ipv6.sin6_port        = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
				addr_ipv6.sin6_addr        = in6addr_any;
				if (bind(SCTP_BASE_VAR(userspace_udpsctp6), (const struct sockaddr *)&addr_ipv6, sizeof(struct sockaddr_in6)) < 0) {				
#if defined(__Userspace_os_Windows)
					SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/UDP/IPv6 (errno = %d).\n", WSAGetLastError());
					closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
#else
					SCTPDBG(SCTP_DEBUG_USR, "Can't bind socket for SCTP/UDP/IPv6 (errno = %d).\n", errno);
					close(SCTP_BASE_VAR(userspace_udpsctp6));
#endif
					SCTP_BASE_VAR(userspace_udpsctp6) = -1;
				} else {
					setReceiveBufferSize(SCTP_BASE_VAR(userspace_udpsctp6), SB_RAW); /* 128K */
					setSendBufferSize(SCTP_BASE_VAR(userspace_udpsctp6), SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */
				}
			}
		}
	}
#endif
#if !defined(__Userspace_os_Windows)
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
#if defined(INET) || defined(INET6)
	if (SCTP_BASE_VAR(userspace_route) != -1) {
		int rc;

		if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadroute), NULL, &recv_function_route, NULL))) {
			SCTPDBG(SCTP_DEBUG_USR, "Can't start routing thread (%d).\n", rc);
			close(SCTP_BASE_VAR(userspace_route));
			SCTP_BASE_VAR(userspace_route) = -1;
		}
	}
#endif
#endif
#if defined(INET)
	if (SCTP_BASE_VAR(userspace_rawsctp) != -1) {
		int rc;

		if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadraw), NULL, &recv_function_raw, NULL))) {
			SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv4 recv thread (%d).\n", rc);
			close(SCTP_BASE_VAR(userspace_rawsctp));
			SCTP_BASE_VAR(userspace_rawsctp) = -1;
		}
	}
	if (SCTP_BASE_VAR(userspace_udpsctp) != -1) {
		int rc;

		if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadudp), NULL, &recv_function_udp, NULL))) {
			SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv4 recv thread (%d).\n", rc);
			close(SCTP_BASE_VAR(userspace_udpsctp));
			SCTP_BASE_VAR(userspace_udpsctp) = -1;
		}
	}
#endif
#if defined(INET6)
	if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
		int rc;

		if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadraw6), NULL, &recv_function_raw6, NULL))) {
			SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv6 recv thread (%d).\n", rc);
			close(SCTP_BASE_VAR(userspace_rawsctp6));
			SCTP_BASE_VAR(userspace_rawsctp6) = -1;
		}
	}
	if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) {
		int rc;

		if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadudp6), NULL, &recv_function_udp6, NULL))) {
			SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv6 recv thread (%d).\n", rc);
			close(SCTP_BASE_VAR(userspace_udpsctp6));
			SCTP_BASE_VAR(userspace_udpsctp6) = -1;
		}
	}
#endif
#else
#if defined(INET)
	if (SCTP_BASE_VAR(userspace_rawsctp) != -1) {
		if ((SCTP_BASE_VAR(recvthreadraw) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_raw, NULL, 0, NULL)) == NULL) {
			SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv4 recv thread.\n");
			closesocket(SCTP_BASE_VAR(userspace_rawsctp));
			SCTP_BASE_VAR(userspace_rawsctp) = -1;
		}
	}
	if (SCTP_BASE_VAR(userspace_udpsctp) != -1) {
		if ((SCTP_BASE_VAR(recvthreadudp) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_udp, NULL, 0, NULL)) == NULL) {
			SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv4 recv thread.\n");
			closesocket(SCTP_BASE_VAR(userspace_udpsctp));
			SCTP_BASE_VAR(userspace_udpsctp) = -1;
		}
	}
#endif
#if defined(INET6)
	if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
		if ((SCTP_BASE_VAR(recvthreadraw6) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_raw6, NULL, 0, NULL)) == NULL) {
			SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv6 recv thread.\n");
			closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
			SCTP_BASE_VAR(userspace_rawsctp6) = -1;
		}
	}
	if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) {
		if ((SCTP_BASE_VAR(recvthreadudp6) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_udp6, NULL, 0, NULL)) == NULL) {
			SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv6 recv thread.\n");
			closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
			SCTP_BASE_VAR(userspace_udpsctp6) = -1;
		}
	}
#endif
#endif
}

void
recv_thread_destroy(void)
{
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
#if defined(INET) || defined(INET6)
	if (SCTP_BASE_VAR(userspace_route) != -1) {
		close(SCTP_BASE_VAR(userspace_route));
	}
#endif
#endif
#if defined(INET)
	if (SCTP_BASE_VAR(userspace_rawsctp) != -1) {
#if defined(__Userspace_os_Windows)
		closesocket(SCTP_BASE_VAR(userspace_rawsctp));
#else
		close(SCTP_BASE_VAR(userspace_rawsctp));
#endif
	}
	if (SCTP_BASE_VAR(userspace_udpsctp) != -1) {
#if defined(__Userspace_os_Windows)
		closesocket(SCTP_BASE_VAR(userspace_udpsctp));
#else
		close(SCTP_BASE_VAR(userspace_udpsctp));
#endif
	}
#endif
#if defined(INET6)
	if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
#if defined(__Userspace_os_Windows)
		closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
#else
		close(SCTP_BASE_VAR(userspace_rawsctp6));
#endif
	}
	if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) {
#if defined(__Userspace_os_Windows)
		closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
#else
		close(SCTP_BASE_VAR(userspace_udpsctp6));
#endif
	}
#endif
}
#else
int foo;
コード例 #2
0
struct socket *
sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error)
{
	struct socket *newso;
	struct sctp_inpcb *inp, *n_inp;
	struct sctp_tcb *stcb;

	SCTPDBG(SCTP_DEBUG_PEEL1, "SCTP peel-off called\n");
	inp = (struct sctp_inpcb *)head->so_pcb;
	if (inp == NULL) {
		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PEELOFF, EFAULT);
		*error = EFAULT;
		return (NULL);
	}
	stcb = sctp_findassociation_ep_asocid(inp, assoc_id, 1);
	if (stcb == NULL) {
		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PEELOFF, ENOTCONN);
		*error = ENOTCONN;
		return (NULL);
	}
	atomic_add_int(&stcb->asoc.refcnt, 1);
	SCTP_TCB_UNLOCK(stcb);
	newso = sonewconn(head, SS_ISCONNECTED
	    );
	if (newso == NULL) {
		SCTPDBG(SCTP_DEBUG_PEEL1, "sctp_peeloff:sonewconn failed\n");
		SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_PEELOFF, ENOMEM);
		*error = ENOMEM;
		atomic_subtract_int(&stcb->asoc.refcnt, 1);
		return (NULL);

	}
	SCTP_TCB_LOCK(stcb);
	atomic_subtract_int(&stcb->asoc.refcnt, 1);
	n_inp = (struct sctp_inpcb *)newso->so_pcb;
	SOCK_LOCK(head);
	n_inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |
	    SCTP_PCB_FLAGS_CONNECTED |
	    SCTP_PCB_FLAGS_IN_TCPPOOL |	/* Turn on Blocking IO */
	    (SCTP_PCB_COPY_FLAGS & inp->sctp_flags));
	n_inp->sctp_features = inp->sctp_features;
	n_inp->sctp_frag_point = inp->sctp_frag_point;
	n_inp->partial_delivery_point = inp->partial_delivery_point;
	n_inp->sctp_context = inp->sctp_context;
	n_inp->inp_starting_point_for_iterator = NULL;

	/* copy in the authentication parameters from the original endpoint */
	if (n_inp->sctp_ep.local_hmacs)
		sctp_free_hmaclist(n_inp->sctp_ep.local_hmacs);
	n_inp->sctp_ep.local_hmacs =
	    sctp_copy_hmaclist(inp->sctp_ep.local_hmacs);
	if (n_inp->sctp_ep.local_auth_chunks)
		sctp_free_chunklist(n_inp->sctp_ep.local_auth_chunks);
	n_inp->sctp_ep.local_auth_chunks =
	    sctp_copy_chunklist(inp->sctp_ep.local_auth_chunks);
	(void)sctp_copy_skeylist(&inp->sctp_ep.shared_keys,
	    &n_inp->sctp_ep.shared_keys);

	n_inp->sctp_socket = newso;
	if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) {
		sctp_feature_off(n_inp, SCTP_PCB_FLAGS_AUTOCLOSE);
		n_inp->sctp_ep.auto_close_time = 0;
		sctp_timer_stop(SCTP_TIMER_TYPE_AUTOCLOSE, n_inp, stcb, NULL,
		    SCTP_FROM_SCTP_PEELOFF + SCTP_LOC_1);
	}
	/* Turn off any non-blocking semantic. */
	SCTP_CLEAR_SO_NBIO(newso);
	newso->so_state |= SS_ISCONNECTED;
	/* We remove it right away */

#ifdef SCTP_LOCK_LOGGING
	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) {
		sctp_log_lock(inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_SOCK);
	}
#endif
	TAILQ_REMOVE(&head->so_comp, newso, so_list);
	head->so_qlen--;
	SOCK_UNLOCK(head);
	/*
	 * Now we must move it from one hash table to another and get the
	 * stcb in the right place.
	 */
	sctp_move_pcb_and_assoc(inp, n_inp, stcb);
	atomic_add_int(&stcb->asoc.refcnt, 1);
	SCTP_TCB_UNLOCK(stcb);
	/*
	 * And now the final hack. We move data in the pending side i.e.
	 * head to the new socket buffer. Let the GRUBBING begin :-0
	 */
	sctp_pull_off_control_to_new_inp(inp, n_inp, stcb, SBL_WAIT);
	atomic_subtract_int(&stcb->asoc.refcnt, 1);
	return (newso);
}
コード例 #3
0
int main(int argc, char **argv) {
    int i, j;
    int size, align_size;
    char *s_buf, *r_buf;
    double t_start = 0.0, t_end = 0.0, t = 0.0;


    struct sockaddr_in *dest = malloc(sizeof(struct sockaddr_in));
    struct sctp_sndrcvinfo sri;
    struct sockaddr_in cli;
    socklen_t s = sizeof(struct sockaddr_in);
    int msg_flags = 0;
    int n=-1;
    char mode[15];


    struct timeval start, end;
    struct dp datapoints[DATAPOINTS];
    int num_dp = 0;
    FILE *file;
    char filename[PRINTARRAY];
    char ascii_size[PRINTARRAY];
    int name[] = {CTL_KERN, KERN_OSTYPE};
    int namelen = 2;
    char oldval[15];
    size_t len = sizeof(oldval);
    int  error;    


    if (argc < 3) {
	printf("Usage: %s dst-ip dest-port\n", argv[0]);
	exit(1);
    }
    
#if defined(SCTP_USERMODE)
    uint32_t optval=1;
    struct socket *psock = NULL;
    strcpy(mode, "Userspace");
#else //kernel mode
    int sock_fd;
    strcpy(mode, "Kernel");
#endif


    align_size = getpagesize();
    assert(align_size <= MAX_ALIGNMENT);

    s_buf =
        (char *) (((unsigned long) s_buf1 + (align_size - 1)) /
                  align_size * align_size);
    r_buf =
        (char *) (((unsigned long) r_buf1 + (align_size - 1)) /
                  align_size * align_size);

    
    error = sysctl (name, namelen,
                    (void *)oldval, &len, NULL
                    /* newval */, 0 /* newlen */);
    if (error) {
        printf("sysctl() error\n");
        exit(1);
    }

    strcpy(filename, "BWbenchmark");
    sprintf(ascii_size,"%s%smode",oldval,mode);
    strcat(filename, ascii_size);
    strcat(filename,".txt");

    
#if defined(SCTP_USERMODE)
    sctp_init(); 
    SCTP_BASE_SYSCTL(sctp_udp_tunneling_for_client_enable)=1; 
    
    if( !(psock = userspace_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) ){
        printf("user_socket() returned NULL\n");
        exit(1);
    }
#else //Kernel mode
    if((sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1) {
        printf("socket error\n");
        exit(1);
    }
#endif
    
    /* prepare destination adddress */
    bzero(dest, sizeof(struct sockaddr_in));
    dest->sin_family = AF_INET;
    dest->sin_addr.s_addr = inet_addr(argv[1]);
    dest->sin_port = htons((unsigned short) atoi(argv[2]));
#if defined(__Userspace_os_FreeBSD)
    dest->sin_len = sizeof(struct sockaddr);
#endif

#if defined(SCTP_USERMODE)
    /* call userspace_connect which eventually calls sctp_send_initiate */
    if( userspace_connect(psock, (struct sockaddr *) dest, sizeof(struct sockaddr_in)) == -1 ) {
        printf("userspace_connect failed.  exiting...\n");
        exit(1);        
    }

    sctp_setopt(psock, SCTP_NODELAY, &optval, sizeof(uint32_t), NULL);

#else //Kernel mode
    if((connect(sock_fd, (struct sockaddr *) dest, sizeof(struct sockaddr_in))) == -1) {
        perror("connect error\n");
        exit(1);
    }
    /* Setting the send and receive socket buffer sizes */
    const int maxbufsize = 65536 * 3;
    int sndrcvbufsize = maxbufsize;
    int sndrcvbufsize_len;
    int rc;
    sndrcvbufsize_len = sizeof(sndrcvbufsize);
    rc = setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &sndrcvbufsize, sndrcvbufsize_len);
    
    if (rc == -1) {
        perror("can't set the socket send size to requested one");
        exit(1);
    }
    
    rc = setsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &sndrcvbufsize, sndrcvbufsize_len);
    
    if (rc == -1) {
        perror("can't set the socket receive size to requested one");
        exit(1);
    }
    
    /* turning nagle off */
    int no_nagle = 1;
    if (setsockopt(sock_fd, IPPROTO_SCTP,
                   SCTP_NODELAY, (char *) &no_nagle, sizeof(no_nagle)) < 0){
        perror("can't setsockopt to no_nagle\n");
        exit(1);
    }
#endif



    num_dp = 0;
    int retval = 0;

    printf("\nRunning in %s mode\nStoring results in file %s\n\n", mode, filename);

    fprintf(stdout, "# %s %s\n", mode, "Mode: Bandwidth Benchmark Similar to OSU");
    fprintf(stdout, "%-*s%*s\n", 10, "# Size", FIELD_WIDTH,
            "Bandwidth (MB/s)");
    fflush(stdout);


    /* Bandwidth test */
    for(size = 1; size <= MAX_MSG_SIZE; size *= 2) {
        /* touch the data */
        for(i = 0; i < size; i++) {
            s_buf[i] = 'a';
            r_buf[i] = 'b';
        }
        
        if(size > large_message_size) {
            loop = loop_large;
            skip = skip_large;
            window_size = window_size_large;
        }
        

        for(i = 0; i < loop + skip; i++) {
            if(i == skip) {
                gettimeofday(&start, NULL);
                t_start = (double) start.tv_sec + .000001 * (double) start.tv_usec;
            }
            
            for(j = 0; j < window_size; j++) {
#if defined(SCTP_USERMODE)
                if((retval = userspace_sctp_sendmsg(psock /* struct socket *so */,
                                                    s_buf /* const void *data */,
                                                    size /* size_t len */,
                                                    (struct sockaddr *)dest /* const struct sockaddr *to */,
                                                    sizeof(struct sockaddr_in) /* socklen_t tolen */,
                                                    0 /* u_int32_t ppid */,
                                                    0 /* u_int32_t flags */,
                                                    3 /* u_int16_t stream_no */,
                                                    0 /* u_int32_t timetolive */,
                                                    0 /* u_int32_t context */))<=0)
                    {
                        printf("userspace_sctp_sendmsg returned retval=%d errno=%d\n", retval, errno);
                        exit(1);
                        
                    }
#else //Kernel mode
                
                if ((retval = sctp_sendmsg(sock_fd, (void *)s_buf, (size_t)size, NULL, 0, 0, 0, 3, 0, 0)) <=0 )
                    {
                        printf("sctp_sendmsg returned retval=%d errno=%d\n", retval, errno);
                        exit(1);
                    }
#endif        
                
                
            }


#if defined(SCTP_USERMODE)
            if ((n = userspace_sctp_recvmsg(psock, r_buf, 4, (struct sockaddr *) &cli, &s, &sri, &msg_flags)) <=0 )
                {
                    printf(".....userspace_sctp_recvmsg returned n=%d errno=%d\n", n, errno);
                    break;
                }
#else  //Kernel mode
            if ((n = sctp_recvmsg(sock_fd, r_buf, 4, (struct sockaddr *) &cli, &s, &sri, &msg_flags)) <=0 )
                {
                    printf("sctp_recvmsg returned n=%d errno=%d\n", n, errno);
                    break;
                }
#endif
            
        }
        
        gettimeofday(&end, NULL);
        t_end = (double) end.tv_sec + .000001 * (double) end.tv_usec;
        
        t = t_end - t_start;
        
        double tmp = size / 1e6 * loop * window_size;
        
        fprintf(stdout, "%-*d%*.*f\n", 10, size, FIELD_WIDTH,
                FLOAT_PRECISION, tmp / t);
        fflush(stdout);
        datapoints[num_dp].msg_size = size;
        datapoints[num_dp].tottime = t;
        datapoints[num_dp].bw = tmp/t;
        num_dp++;
        
    }
    
    
    printf("Client closing socket...errno=%d\n", errno);
    free(dest);
#if defined(SCTP_USERMODE)
    userspace_close(psock);
#else
    close(sock_fd);
#endif
    
    printf("Sleeping for 60 secs\n");
    sleep(60);
    
    file = fopen(filename, "w+");
    if(file == NULL) {
        perror("could not open results file");
    } else {        
        for (j=0; j<num_dp; j++)
        {
            fprintf(file,"%d , %.2f , %.2f\n",datapoints[j].msg_size, datapoints[j].tottime, datapoints[j].bw); /*write datapoints to file*/
        }
        fclose(file);
    }


#if defined(SCTP_USERMODE)
    sctp_finish();
    //    pthread_exit(NULL);
#endif

    return 0;
        
}