aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortuexen <tuexen@9df1edf5-d72c-5b5f-11c0-5f5209eb73f7>2012-04-28 16:43:56 +0000
committertuexen <tuexen@9df1edf5-d72c-5b5f-11c0-5f5209eb73f7>2012-04-28 16:43:56 +0000
commit9df6f84e85726943ad1c17b99045bf58e1b3296f (patch)
treea86d7a73671041169ed8ab4af8cd607590a664cb
parent852c79699d3d814b641a8dd35be50ce50a9f576c (diff)
downloadusrsctp-9df6f84e85726943ad1c17b99045bf58e1b3296f.tar.gz
Clean teardown of the stack (wait for threads to terminate).
-rwxr-xr-xusrsctplib/user_recv_thread.c556
-rwxr-xr-xusrsctplib/user_recv_thread.h44
-rwxr-xr-xusrsctplib/user_sctp_timer_iterate.c61
-rwxr-xr-xusrsctplib/user_socket.c65
4 files changed, 470 insertions, 256 deletions
diff --git a/usrsctplib/user_recv_thread.c b/usrsctplib/user_recv_thread.c
index b4479858..406faa5c 100755
--- a/usrsctplib/user_recv_thread.c
+++ b/usrsctplib/user_recv_thread.c
@@ -1,3 +1,31 @@
+/*-
+ * Copyright (c) 2012 Michael Tuexen
+ * Copyright (c) 2012 Irene Ruengeler
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
#include <sys/types.h>
#if !defined(__Userspace_os_Windows)
#include <sys/socket.h>
@@ -16,14 +44,6 @@
#include <linux/netlink.h>
#include <linux/if_addr.h>
#endif
-/* extern __Userspace__ variable in user_recv_thread.h */
-int userspace_rawsctp = -1; /* needs to be declared = -1 */
-int userspace_udpsctp = -1;
-#if defined(INET6)
-int userspace_rawsctp6 = -1;
-int userspace_udpsctp6 = -1;
-#endif
-int userspace_route = -1;
/* local macros and datatypes used to get IP addresses system independently */
#if defined IP_RECVDSTADDR
@@ -134,9 +154,9 @@ recv_function_route(void *arg)
char rt_buffer[1024];
struct sockaddr *sa, *rti_info[RTAX_MAX];
- while(1) {
+ while (1) {
bzero(rt_buffer, sizeof(rt_buffer));
- ret = recv(userspace_route, rt_buffer, sizeof(rt_buffer), 0);
+ ret = recv(SCTP_BASE_VAR(userspace_route), rt_buffer, sizeof(rt_buffer), 0);
if (ret > 0) {
ifa = (struct ifa_msghdr *) rt_buffer;
@@ -155,8 +175,15 @@ recv_function_route(void *arg)
break;
}
}
+ if (ret < 0) {
+ if (errno == EAGAIN) {
+ continue;
+ } else {
+ break;
+ }
+ }
}
- return NULL;
+ pthread_exit(NULL);
}
#else /*Userspace_os_Linux*/
static void *
@@ -168,9 +195,8 @@ recv_function_route(void *arg)
struct iovec iov = { buf, sizeof(buf) };
struct msghdr msg;
struct nlmsghdr *nh;
- struct sockaddr_nl sanl;
struct ifaddrmsg *rtmsg;
- struct rtattr *rtatp;
+ struct rtattr *rtatp;
struct in_addr *inp;
#ifdef INET
struct sockaddr_in *sa;
@@ -178,12 +204,6 @@ recv_function_route(void *arg)
#ifdef INET6
struct sockaddr_in6 *sa6;
#endif
- memset(&sanl, 0, sizeof(sanl));
- sanl.nl_family = AF_NETLINK;
- sanl.nl_groups = RTMGRP_IPV6_IFADDR | RTMGRP_IPV4_IFADDR;
-
- fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
- bind(fd, (struct sockaddr *) &sanl, sizeof(sanl));
while (1) {
memset(&msg, 0, sizeof(struct msghdr));
@@ -194,12 +214,19 @@ recv_function_route(void *arg)
msg.msg_control = NULL;
msg.msg_controllen = 0;
- len = recvmsg(fd, &msg, 0);
+ len = recvmsg(SCTP_BASE_VAR(userspace_route), &msg, 0);
+ if (len < 0) {
+ if (errno == EAGAIN) {
+ continue;
+ } else {
+ break;
+ }
+ }
for (nh = (struct nlmsghdr *) buf; NLMSG_OK (nh, len);
nh = NLMSG_NEXT (nh, len)) {
if (nh->nlmsg_type == NLMSG_DONE)
- return NULL;
+ break;
if (nh->nlmsg_type == RTM_NEWADDR || nh->nlmsg_type == RTM_DELADDR) {
rtmsg = (struct ifaddrmsg *)NLMSG_DATA(nh);
@@ -227,23 +254,21 @@ recv_function_route(void *arg)
#endif
default:
printf("Address family not supported\n");
+ break;
}
}
}
}
}
pthread_exit(NULL);
- return NULL;
}
#endif
#endif
-/* need ref to this for destroy... */
-struct mbuf **recvmbuf;
-
static void *
recv_function_raw(void *arg)
{
+ struct mbuf **recvmbuf;
#if !defined(__Userspace_os_Windows)
struct iovec recv_iovec[MAXLEN_MBUF_CHAIN];
int iovcnt = MAXLEN_MBUF_CHAIN;
@@ -288,21 +313,25 @@ recv_function_raw(void *arg)
fromlen = sizeof(struct sockaddr_in);
bzero((void *)&from, sizeof(struct sockaddr_in));
- nResult = WSARecvFrom(userspace_rawsctp, recv_iovec, MAXLEN_MBUF_CHAIN, (LPDWORD)&ncounter, (LPDWORD)&flags, (struct sockaddr*)&from, &fromlen, NULL, NULL);
+ nResult = WSARecvFrom(SCTP_BASE_VAR(userspace_rawsctp), recv_iovec, MAXLEN_MBUF_CHAIN, (LPDWORD)&ncounter, (LPDWORD)&flags, (struct sockaddr*)&from, &fromlen, NULL, NULL);
if (nResult != 0) {
m_ErrorCode = WSAGetLastError();
printf("error: %d\n", m_ErrorCode);
}
n = ncounter;
#else
- ncounter = n = readv(userspace_rawsctp, recv_iovec, iovcnt);
+ ncounter = n = readv(SCTP_BASE_VAR(userspace_rawsctp), recv_iovec, iovcnt);
if (n < 0) {
- continue;
+ if (errno == EAGAIN) {
+ continue;
+ } else {
+ break;
+ }
}
#endif
assert (n <= (MAXLEN_MBUF_CHAIN * iovlen));
SCTP_HEADER_LEN(recvmbuf[0]) = n; /* length of total packet */
-
+
if (n <= iovlen) {
SCTP_BUF_LEN(recvmbuf[0]) = n;
(to_fill)++;
@@ -323,20 +352,28 @@ recv_function_raw(void *arg)
assert(to_fill <= MAXLEN_MBUF_CHAIN);
SCTPDBG(SCTP_DEBUG_INPUT1, "%s: Received %d bytes.", __func__, n);
SCTPDBG(SCTP_DEBUG_INPUT1, " - calling sctp_input with off=%d\n", (int)sizeof(struct ip));
-
+
/* process incoming data */
/* sctp_input frees this mbuf. */
sctp_input_with_port(recvmbuf[0], sizeof(struct ip), 0);
}
- return NULL;
+ for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
+ m_free(recvmbuf[i]);
+ }
+ /* free the array itself */
+ free(recvmbuf);
+#if defined (__Userspace_os_Windows)
+ ExitThread(0);
+#else
+ pthread_exit(NULL);
+#endif
}
#if defined(INET6)
-struct mbuf **recvmbuf6;
-
static void *
recv_function_raw6(void *arg)
{
+ struct mbuf **recvmbuf6;
#if !defined(__Userspace_os_Windows)
struct iovec recv_iovec[MAXLEN_MBUF_CHAIN];
struct msghdr msg;
@@ -391,7 +428,7 @@ recv_function_raw6(void *arg)
ncounter = 0;
fromlen = sizeof(struct sockaddr_in6);
bzero((void *)&from, sizeof(struct sockaddr_in6));
- nResult = WSAIoctl(userspace_rawsctp6, SIO_GET_EXTENSION_FUNCTION_POINTER,
+ nResult = WSAIoctl(SCTP_BASE_VAR(userspace_rawsctp6), SIO_GET_EXTENSION_FUNCTION_POINTER,
&WSARecvMsg_GUID, sizeof WSARecvMsg_GUID,
&WSARecvMsg, sizeof WSARecvMsg,
&ncounter, NULL, NULL);
@@ -406,7 +443,7 @@ recv_function_raw6(void *arg)
win_msg.Control.len = sizeof ControlBuffer;
win_msg.Control.buf = ControlBuffer;
win_msg.dwFlags = 0;
- nResult = WSARecvMsg(userspace_rawsctp6, &win_msg, &ncounter, NULL, NULL);
+ nResult = WSARecvMsg(SCTP_BASE_VAR(userspace_rawsctp6), &win_msg, &ncounter, NULL, NULL);
if (nResult != 0) {
m_ErrorCode = WSAGetLastError();
}
@@ -424,9 +461,13 @@ recv_function_raw6(void *arg)
msg.msg_controllen = (socklen_t)CMSG_LEN(sizeof (struct in6_pktinfo));
msg.msg_flags = 0;
- ncounter = n = recvmsg(userspace_rawsctp6, &msg, 0);
+ ncounter = n = recvmsg(SCTP_BASE_VAR(userspace_rawsctp6), &msg, 0);
if (n < 0) {
- continue;
+ if (errno == EAGAIN) {
+ continue;
+ } else {
+ break;
+ }
}
#endif
assert (n <= (MAXLEN_MBUF_CHAIN * iovlen));
@@ -483,16 +524,23 @@ recv_function_raw6(void *arg)
offset = sizeof(struct ip6_hdr);
sctp6_input_with_port(&ip6_m, &offset, 0);
}
- return NULL;
+ for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
+ m_free(recvmbuf6[i]);
+ }
+ /* free the array itself */
+ free(recvmbuf6);
+#if defined (__Userspace_os_Windows)
+ ExitThread(0);
+#else
+ pthread_exit(NULL);
+#endif
}
#endif
-/* need ref to this for destroy... */
-struct mbuf **udprecvmbuf;
-
static void *
recv_function_udp(void *arg)
{
+ struct mbuf **udprecvmbuf;
/*Initially the entire set of mbufs is to be allocated.
to_fill indicates this amount. */
int to_fill = MAXLEN_MBUF_CHAIN;
@@ -555,12 +603,16 @@ recv_function_udp(void *arg)
msg.msg_controllen = DSTADDR_DATASIZE;
msg.msg_flags = 0;
- ncounter = n = recvmsg(userspace_udpsctp, &msg, 0);
+ ncounter = n = recvmsg(SCTP_BASE_VAR(userspace_udpsctp), &msg, 0);
if (n < 0) {
- continue;
+ if (errno == EAGAIN) {
+ continue;
+ } else {
+ break;
+ }
}
#else
- nResult = WSAIoctl(userspace_udpsctp, SIO_GET_EXTENSION_FUNCTION_POINTER,
+ nResult = WSAIoctl(SCTP_BASE_VAR(userspace_udpsctp), SIO_GET_EXTENSION_FUNCTION_POINTER,
&WSARecvMsg_GUID, sizeof WSARecvMsg_GUID,
&WSARecvMsg, sizeof WSARecvMsg,
&ncounter, NULL, NULL);
@@ -575,7 +627,7 @@ recv_function_udp(void *arg)
win_msg.Control.len = sizeof ControlBuffer;
win_msg.Control.buf = ControlBuffer;
win_msg.dwFlags = 0;
- nResult = WSARecvMsg(userspace_udpsctp, &win_msg, &ncounter, NULL, NULL);
+ nResult = WSARecvMsg(SCTP_BASE_VAR(userspace_udpsctp), &win_msg, &ncounter, NULL, NULL);
if (nResult != 0) {
m_ErrorCode = WSAGetLastError();
}
@@ -649,14 +701,23 @@ recv_function_udp(void *arg)
/* sctp_input frees this mbuf. */
sctp_input_with_port(ip_m, sizeof(struct ip), src.sin_port);
}
- return NULL;
+ for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
+ m_free(udprecvmbuf[i]);
+ }
+ /* free the array itself */
+ free(udprecvmbuf);
+#if defined (__Userspace_os_Windows)
+ ExitThread(0);
+#else
+ pthread_exit(NULL);
+#endif
}
#if defined(INET6)
-struct mbuf **udprecvmbuf6;
static void *
recv_function_udp6(void *arg)
{
+ struct mbuf **udprecvmbuf6;
/*Initially the entire set of mbufs is to be allocated.
to_fill indicates this amount. */
int to_fill = MAXLEN_MBUF_CHAIN;
@@ -720,12 +781,16 @@ recv_function_udp6(void *arg)
msg.msg_controllen = (socklen_t)CMSG_LEN(sizeof (struct in6_pktinfo));
msg.msg_flags = 0;
- ncounter = n = recvmsg(userspace_udpsctp6, &msg, 0);
+ ncounter = n = recvmsg(SCTP_BASE_VAR(userspace_udpsctp6), &msg, 0);
if (n < 0) {
- continue;
+ if (errno == EAGAIN) {
+ continue;
+ } else {
+ break;
+ }
}
#else
- nResult = WSAIoctl(userspace_udpsctp6, SIO_GET_EXTENSION_FUNCTION_POINTER,
+ nResult = WSAIoctl(SCTP_BASE_VAR(userspace_udpsctp6), SIO_GET_EXTENSION_FUNCTION_POINTER,
&WSARecvMsg_GUID, sizeof WSARecvMsg_GUID,
&WSARecvMsg, sizeof WSARecvMsg,
&ncounter, NULL, NULL);
@@ -740,7 +805,7 @@ recv_function_udp6(void *arg)
win_msg.Control.len = sizeof ControlBuffer;
win_msg.Control.buf = ControlBuffer;
win_msg.dwFlags = 0;
- nResult = WSARecvMsg(userspace_udpsctp6, &win_msg, &ncounter, NULL, NULL);
+ nResult = WSARecvMsg(SCTP_BASE_VAR(userspace_udpsctp6), &win_msg, &ncounter, NULL, NULL);
if (nResult != 0) {
m_ErrorCode = WSAGetLastError();
}
@@ -809,7 +874,16 @@ recv_function_udp6(void *arg)
offset = sizeof(struct ip6_hdr);
sctp6_input_with_port(&ip6_m, &offset, src.sin6_port);
}
- return NULL;
+ for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
+ m_free(udprecvmbuf6[i]);
+ }
+ /* free the array itself */
+ free(udprecvmbuf6);
+#if defined (__Userspace_os_Windows)
+ ExitThread(0);
+#else
+ pthread_exit(NULL);
+#endif
}
#endif
@@ -828,6 +902,7 @@ static int
setSendBufferSize(int sfd, int new_size)
{
int ch = new_size;
+
if (setsockopt (sfd, SOL_SOCKET, SO_SNDBUF, (void*)&ch, sizeof(ch)) < 0) {
perror("setSendBufferSize setsockopt: SO_RCVBUF failed !\n");
exit(1);
@@ -835,227 +910,304 @@ setSendBufferSize(int sfd, int new_size)
return 0;
}
-void
+void
recv_thread_init(void)
{
- userland_thread_t recvthreadraw , recvthreadudp;
- const int hdrincl = 1;
- const int on = 1;
+#if defined(INET)
struct sockaddr_in addr_ipv4;
+ const int hdrincl = 1;
+#endif
#if defined(INET6)
- userland_thread_t recvthreadraw6, recvthreadudp6;
struct sockaddr_in6 addr_ipv6;
#endif
+#if defined(INET) || defined(INET6)
+ const int on = 1;
+#endif
#if !defined(__Userspace_os_Windows)
- userland_thread_t recvthreadroute;
+ if (SCTP_BASE_VAR(userspace_route) == -1) {
+#if !defined(__Userspace_os_Linux)
+ if ((SCTP_BASE_VAR(userspace_route) = socket(AF_ROUTE, SOCK_RAW, 0)) < 0) {
+ perror("routing socket failure\n");
+ }
+#else
+ struct sockaddr_nl sanl;
- if (userspace_route == -1) {
- if ((userspace_route = socket(AF_ROUTE, SOCK_RAW, 0)) < 0) {
+ if ((SCTP_BASE_VAR(userspace_route) = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) {
perror("routing socket failure\n");
}
+ 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) {
+ perror("bind");
+ close(SCTP_BASE_VAR(userspace_route));
+ SCTP_BASE_VAR(userspace_route) = -1;
+ }
+#endif
}
#endif
- /* use raw socket, create if not initialized */
- if (userspace_rawsctp == -1) {
- if ((userspace_rawsctp = socket(AF_INET, SOCK_RAW, IPPROTO_SCTP)) < 0) {
+#if defined(INET)
+ if (SCTP_BASE_VAR(userspace_rawsctp) == -1) {
+ if ((SCTP_BASE_VAR(userspace_rawsctp) = socket(AF_INET, SOCK_RAW, IPPROTO_SCTP)) < 0) {
perror("raw socket failure. continue with only UDP socket...\n");
} else {
/* complete setting up the raw SCTP socket */
- if (setsockopt(userspace_rawsctp, IPPROTO_IP, IP_HDRINCL,(const void*)&hdrincl, sizeof(int)) < 0) {
+ if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp), IPPROTO_IP, IP_HDRINCL,(const void*)&hdrincl, sizeof(int)) < 0) {
perror("raw setsockopt failure\n");
- exit(1);
- }
+#if defined(__Userspace_os_Windows)
+ close_socket(SCTP_BASE_VAR(userspace_rawsctp));
+#else
+ close(SCTP_BASE_VAR(userspace_rawsctp));
+#endif
- memset((void *)&addr_ipv4, 0, sizeof(struct sockaddr_in));
+ 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);
+ 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(userspace_rawsctp, (const struct sockaddr *)&addr_ipv4, sizeof(struct sockaddr_in)) < 0) {
- perror("bind");
- exit(1);
+ 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) {
+ perror("bind");
+#if defined(__Userspace_os_Windows)
+ close_socket(SCTP_BASE_VAR(userspace_rawsctp));
+#else
+ 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? */
+ }
}
-
- setReceiveBufferSize(userspace_rawsctp, SB_RAW); /* 128K */
- setSendBufferSize(userspace_rawsctp, SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */
}
}
-
- /* use UDP socket, create if not initialized */
- if (userspace_udpsctp == -1) {
- if ((userspace_udpsctp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ if (SCTP_BASE_VAR(userspace_udpsctp) == -1) {
+ if ((SCTP_BASE_VAR(userspace_udpsctp) = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("UDP socket failure");
- }
- if (setsockopt(userspace_udpsctp, IPPROTO_IP, DSTADDR_SOCKOPT, (const void *)&on, (int)sizeof(int)) < 0) {
- perror("setsockopt: DSTADDR_SOCKOPT");
- exit(1);
- }
- memset((void *)&addr_ipv4, 0, sizeof(struct sockaddr_in));
+ } else {
+ if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp), IPPROTO_IP, DSTADDR_SOCKOPT, (const void *)&on, (int)sizeof(int)) < 0) {
+ perror("setsockopt: DSTADDR_SOCKOPT");
+#if defined(__Userspace_os_Windows)
+ close_socket(SCTP_BASE_VAR(userspace_udpsctp));
+#else
+ 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);
+ 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(userspace_udpsctp, (const struct sockaddr *)&addr_ipv4, sizeof(struct sockaddr_in)) < 0) {
- perror("bind");
- close(userspace_udpsctp);
- userspace_udpsctp = -1;
- } else {
- setReceiveBufferSize(userspace_udpsctp, SB_RAW); /* 128K */
- setSendBufferSize(userspace_udpsctp, SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */
+ 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) {
+ perror("bind");
+#if defined(__Userspace_os_Windows)
+ close_socket(SCTP_BASE_VAR(userspace_udpsctp));
+#else
+ 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 (userspace_rawsctp6 == -1) {
- if ((userspace_rawsctp6 = socket(AF_INET6, SOCK_RAW, IPPROTO_SCTP)) < 0) {
+ if (SCTP_BASE_VAR(userspace_rawsctp6) == -1) {
+ if ((SCTP_BASE_VAR(userspace_rawsctp6) = socket(AF_INET6, SOCK_RAW, IPPROTO_SCTP)) < 0) {
perror("raw ipv6 socket failure. continue with only UDP6 socket...\n");
} else {
/* complete setting up the raw SCTP socket */
#if defined(IPV6_RECVPKTINFO)
- if (setsockopt(userspace_rawsctp6, IPPROTO_IPV6, IPV6_RECVPKTINFO, (const void *)&on, (int)sizeof(int)) < 0) {
+ if (setsockopt(SCTP_BASE_VAR(userspace_rawsctp6), IPPROTO_IPV6, IPV6_RECVPKTINFO, (const void *)&on, (int)sizeof(int)) < 0) {
perror("raw6 setsockopt: IPV6_RECVPKTINFO");
- exit(1);
- }
+#if defined(__Userspace_os_Windows)
+ close_socket(SCTP_BASE_VAR(userspace_rawsctp6));
#else
- if (setsockopt(userspace_rawsctp6, IPPROTO_IPV6, IPV6_PKTINFO,(const void*)&on, sizeof(on)) < 0) {
+ 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) {
perror("raw6 setsockopt: IPV6_PKTINFO\n");
- exit(1);
- }
+#if defined(__Userspace_os_Windows)
+ close_socket(SCTP_BASE_VAR(userspace_rawsctp6));
+#else
+ close(SCTP_BASE_VAR(userspace_rawsctp6));
#endif
- if (setsockopt(userspace_rawsctp6, IPPROTO_IPV6, IPV6_V6ONLY, (const void*)&on, (socklen_t)sizeof(on)) < 0) {
- perror("ipv6only");
- }
+ 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) {
+ perror("ipv6only");
+ }
- memset((void *)&addr_ipv6, 0, sizeof(struct sockaddr_in6));
+ memset((void *)&addr_ipv6, 0, sizeof(struct sockaddr_in6));
#if !defined(__Userspace_os_Linux) && !defined(__Userspace_os_Windows)
- addr_ipv6.sin6_len = sizeof(struct sockaddr_in6);
+ 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(userspace_rawsctp6, (const struct sockaddr *)&addr_ipv6, sizeof(struct sockaddr_in6)) < 0) {
- perror("bind");
- exit(1);
- }
+ 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) {
+ perror("bind");
+#if defined(__Userspace_os_Windows)
+ close_socket(SCTP_BASE_VAR(userspace_rawsctp6));
+#else
+ close(SCTP_BASE_VAR(userspace_rawsctp6));
+#endif
+ SCTP_BASE_VAR(userspace_rawsctp6) = -1;
+ } else {
- setReceiveBufferSize(userspace_rawsctp6, SB_RAW); /* 128K */
- setSendBufferSize(userspace_rawsctp6, SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */
+ 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 (userspace_udpsctp6 == -1) {
- if ((userspace_udpsctp6 = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ if (SCTP_BASE_VAR(userspace_udpsctp6) == -1) {
+ if ((SCTP_BASE_VAR(userspace_udpsctp6) = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("UDP ipv6 socket failure");
}
#if defined(IPV6_RECVPKTINFO)
- if (setsockopt(userspace_udpsctp6, IPPROTO_IPV6, IPV6_RECVPKTINFO, (const void *)&on, (int)sizeof(int)) < 0) {
+ if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), IPPROTO_IPV6, IPV6_RECVPKTINFO, (const void *)&on, (int)sizeof(int)) < 0) {
perror("udp6 setsockopt: IPV6_RECVPKTINFO");
- exit(1);
- }
+ close(SCTP_BASE_VAR(userspace_udpsctp6));
+ SCTP_BASE_VAR(userspace_udpsctp6) = -1;
+ } else {
#else
- if (setsockopt(userspace_udpsctp6, IPPROTO_IPV6, IPV6_PKTINFO, (const void *)&on, (int)sizeof(int)) < 0) {
+ if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), IPPROTO_IPV6, IPV6_PKTINFO, (const void *)&on, (int)sizeof(int)) < 0) {
perror("udp6 setsockopt: IPV6_PKTINFO");
- exit(1);
- }
+ close(SCTP_BASE_VAR(userspace_udpsctp6));
+ SCTP_BASE_VAR(userspace_udpsctp6) = -1;
+ } else {
#endif
- if (setsockopt(userspace_udpsctp6, IPPROTO_IPV6, IPV6_V6ONLY, (const void*)&on, (socklen_t)sizeof(on)) < 0) {
- perror("ipv6only");
- }
- memset((void *)&addr_ipv6, 0, sizeof(struct sockaddr_in6));
+ if (setsockopt(SCTP_BASE_VAR(userspace_udpsctp6), IPPROTO_IPV6, IPV6_V6ONLY, (const void*)&on, (socklen_t)sizeof(on)) < 0) {
+ perror("ipv6only");
+ }
+ memset((void *)&addr_ipv6, 0, sizeof(struct sockaddr_in6));
#if !defined(__Userspace_os_Linux) && !defined(__Userspace_os_Windows)
- addr_ipv6.sin6_len = sizeof(struct sockaddr_in6);
+ 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(userspace_udpsctp6, (const struct sockaddr *)&addr_ipv6, sizeof(struct sockaddr_in6)) < 0) {
- perror("bind");
- close(userspace_udpsctp6);
- userspace_udpsctp6 = -1;
- } else {
- setReceiveBufferSize(userspace_udpsctp6, SB_RAW); /* 128K */
- setSendBufferSize(userspace_udpsctp6, SB_RAW); /* 128K Is this setting net.inet.raw.maxdgram value? Should it be set to 64K? */
+ 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) {
+ perror("bind");
+ close(SCTP_BASE_VAR(userspace_udpsctp6));
+ 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
- /* start threads here for receiving incoming messages */
#if !defined(__Userspace_os_Windows)
- if (userspace_route != -1) {
+#if defined(INET) || defined(INET6)
+ if (SCTP_BASE_VAR(userspace_route) != -1) {
int rc;
- if ((rc = pthread_create(&recvthreadroute, NULL, &recv_function_route, NULL))) {
- printf("ERROR; return code from recvthread route pthread_create() is %d\n", rc);
- exit(1);
+ if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadroute), NULL, &recv_function_route, NULL))) {
+ printf("Can't start routing thread (%d).\n", rc);
+ SCTP_BASE_VAR(recvthreadroute) = NULL;
}
+ } else {
+ SCTP_BASE_VAR(recvthreadroute) = NULL;
}
+#endif
#if defined(INET)
- if (userspace_rawsctp != -1) {
+ if (SCTP_BASE_VAR(userspace_rawsctp) != -1) {
int rc;
- if ((rc = pthread_create(&recvthreadraw, NULL, &recv_function_raw, NULL))) {
+ if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadraw), NULL, &recv_function_raw, NULL))) {
printf("ERROR; return code from recvthread pthread_create() is %d\n", rc);
- exit(1);
+ SCTP_BASE_VAR(recvthreadraw) = NULL;
}
+ } else {
+ SCTP_BASE_VAR(recvthreadraw) = NULL;
}
- if (userspace_udpsctp != -1) {
+ if (SCTP_BASE_VAR(userspace_udpsctp) != -1) {
int rc;
- if ((rc = pthread_create(&recvthreadudp, NULL, &recv_function_udp, NULL))) {
+ if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadudp), NULL, &recv_function_udp, NULL))) {
printf("ERROR; return code from recvthread pthread_create() is %d\n", rc);
- exit(1);
+ SCTP_BASE_VAR(recvthreadudp) = NULL;
}
+ } else {
+ SCTP_BASE_VAR(recvthreadudp) = NULL;
}
#endif
#if defined(INET6)
- if (userspace_rawsctp6 != -1) {
+ if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
int rc;
- if ((rc = pthread_create(&recvthreadraw6, NULL, &recv_function_raw6, NULL))) {
+ if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadraw6), NULL, &recv_function_raw6, NULL))) {
printf("ERROR; return code from recvthread pthread_create() is %d\n", rc);
- exit(1);
+ SCTP_BASE_VAR(recvthreadraw6) = NULL;
}
+ } else {
+ SCTP_BASE_VAR(recvthreadraw6) = NULL;
}
- if (userspace_udpsctp6 != -1) {
+ if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) {
int rc;
- if ((rc = pthread_create(&recvthreadudp6, NULL, &recv_function_udp6, NULL))) {
+ if ((rc = pthread_create(&SCTP_BASE_VAR(recvthreadudp6), NULL, &recv_function_udp6, NULL))) {
printf("ERROR; return code from recvthread pthread_create() is %d\n", rc);
- exit(1);
+ SCTP_BASE_VAR(recvthreadudp6) = NULL;
}
+ } else {
+ SCTP_BASE_VAR(recvthreadudp6) = NULL;
}
#endif
#else
#if defined(INET)
- if (userspace_rawsctp != -1) {
- if ((recvthreadraw = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_raw, NULL, 0, NULL))==NULL) {
+ 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) {
printf("ERROR; Creating recvthreadraw failed\n");
- exit(1);
}
+ } else {
+ SCTP_BASE_VAR(recvthreadraw) = NULL;
}
- if (userspace_udpsctp != -1) {
- if ((recvthreadudp = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_udp, NULL, 0, NULL))==NULL) {
+ 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) {
printf("ERROR; Creating recvthreadudp failed\n");
- exit(1);
}
+ } else {
+ SCTP_BASE_VAR(recvthreadudp) = NULL;
}
#endif
#if defined(INET6)
- if (userspace_rawsctp6 != -1) {
- if ((recvthreadraw6 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_raw6, NULL, 0, NULL))==NULL) {
+ 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) {
printf("ERROR; Creating recvthreadraw6 failed\n");
- exit(1);
}
+ } else {
+ SCTP_BASE_VAR(recvthreadraw6) = NULL;
}
- if (userspace_udpsctp6 != -1) {
- if ((recvthreadudp6 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&recv_function_udp6, NULL, 0, NULL))==NULL) {
+ 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) {
printf("ERROR; Creating recvthreadudp6 failed\n");
- exit(1);
}
+ } else {
+ SCTP_BASE_VAR(userspace_udpsctp6) = NULL;
}
#endif
#endif
@@ -1064,63 +1216,47 @@ recv_thread_init(void)
void
recv_thread_destroy(void)
{
- int i;
-
- if (userspace_route != -1) {
+#if !defined(__Userspace_os_Windows)
+#if defined(INET) || defined(INET6)
+ if (SCTP_BASE_VAR(userspace_route) != -1) {
#if defined(__Userspace_os_Windows)
- closesocket(userspace_route);
+ closesocket(SCTP_BASE_VAR(userspace_route));
#else
- close(userspace_route);
+ close(SCTP_BASE_VAR(userspace_route));
#endif
}
- if (userspace_rawsctp != -1) {
+#endif
+#endif
+#if defined(INET)
+ if (SCTP_BASE_VAR(userspace_rawsctp) != -1) {
#if defined(__Userspace_os_Windows)
- closesocket(userspace_rawsctp);
+ closesocket(SCTP_BASE_VAR(userspace_rawsctp));
#else
- close(userspace_rawsctp);
+ close(SCTP_BASE_VAR(userspace_rawsctp));
#endif
- for(i=0; i < MAXLEN_MBUF_CHAIN; i++) {
- m_free(recvmbuf[i]);
- }
- /* free the array itself */
- free(recvmbuf);
}
- if (userspace_udpsctp != -1) {
+ if (SCTP_BASE_VAR(userspace_udpsctp) != -1) {
#if defined(__Userspace_os_Windows)
- closesocket(userspace_udpsctp);
+ closesocket(SCTP_BASE_VAR(userspace_udpsctp));
#else
- close(userspace_udpsctp);
+ close(SCTP_BASE_VAR(userspace_udpsctp));
#endif
- for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
- m_free(udprecvmbuf[i]);
- }
- /* free the array itself */
- free(udprecvmbuf);
}
+#endif
#if defined(INET6)
- if (userspace_rawsctp6 != -1) {
+ if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
#if defined(__Userspace_os_Windows)
- closesocket(userspace_rawsctp6);
+ closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
#else
- close(userspace_rawsctp6);
+ close(SCTP_BASE_VAR(userspace_rawsctp6));
#endif
- for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
- m_free(recvmbuf6[i]);
- }
- /* free the array itself */
- free(recvmbuf6);
}
- if (userspace_udpsctp6 != -1) {
+ if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) {
#if defined(__Userspace_os_Windows)
- closesocket(userspace_udpsctp6);
+ closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
#else
- close(userspace_udpsctp6);
+ close(SCTP_BASE_VAR(userspace_udpsctp6));
#endif
- for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
- m_free(udprecvmbuf6[i]);
- }
- /* free the array itself */
- free(udprecvmbuf6);
}
#endif
}
diff --git a/usrsctplib/user_recv_thread.h b/usrsctplib/user_recv_thread.h
index e2021d2f..ee0a5978 100755
--- a/usrsctplib/user_recv_thread.h
+++ b/usrsctplib/user_recv_thread.h
@@ -1,20 +1,32 @@
-/* __Userspace__ user_recv_thread.h header file for creating recv thread */
-
-
-
-/* raw socket to be used for both incoming and outgoing packets */
-extern int userspace_rawsctp; /* needs to be declared = -1 */
-extern int userspace_rawsctp6;
-
-/* udp socket to be used for both incoming and outgoing packets */
-extern int userspace_udpsctp; /* needs to be declared = -1 */
-extern int userspace_udpsctp6;
-
-/* routing socket used for route lookups */
-extern int userspace_route;
+/*-
+ * Copyright (c) 2012 Michael Tuexen
+ * Copyright (c) 2012 Irene Ruengeler
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * [id for your version control system, if any]
+ */
void recv_thread_init(void);
void recv_thread_destroy(void);
-#define RECV_THREAD_INIT recv_thread_init
-
diff --git a/usrsctplib/user_sctp_timer_iterate.c b/usrsctplib/user_sctp_timer_iterate.c
index bfd02160..a0d771cd 100755
--- a/usrsctplib/user_sctp_timer_iterate.c
+++ b/usrsctplib/user_sctp_timer_iterate.c
@@ -1,12 +1,39 @@
-#include <sys/types.h>
+/*-
+ * Copyright (c) 2012 Michael Tuexen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/types.h>
#if !defined (__Userspace_os_Windows)
-#include <sys/wait.h>
+#include <sys/wait.h>
#include <unistd.h>
#include <pthread.h>
#endif
#include <stdlib.h>
#include <string.h>
-#include <stdio.h>
+#include <stdio.h>
#include <errno.h>
#include <netinet/sctp_pcb.h>
#include <netinet/sctp_sysctl.h>
@@ -24,9 +51,9 @@ void * (*timerFunction)(void *) = {&user_sctp_timer_iterate};
extern int ticks;
userland_mutex_t timer_mtx;
-void
-timer_init(void) {
- userland_thread_t ithread;
+void
+sctp_start_timer(void)
+{
#if !defined (__Userspace_os_Windows)
int rc;
#endif
@@ -35,12 +62,12 @@ timer_init(void) {
/* No need to do SCTP_TIMERQ_LOCK_INIT(); here, it is being done in sctp_pcb_init() */
/* start one thread here */
#if defined (__Userspace_os_Windows)
- if ((ithread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)timerFunction, (void *)tn, 0, NULL))==NULL) {
+ if ((SCTP_BASE_VAR(timer_thread) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)timerFunction, (void *)tn, 0, NULL))==NULL) {
printf("ERROR; Creating ithread failed\n");
exit(1);
}
#else
- rc = pthread_create(&ithread, NULL, timerFunction, (void *)tn);
+ rc = pthread_create(&SCTP_BASE_VAR(timer_thread), NULL, timerFunction, (void *)tn);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(1);
@@ -62,16 +89,19 @@ user_sctp_timer_iterate(void *threadname)
* and further to_ticks level off at 60000 i.e. 60 seconds.
* If hz=100 then for multiple INIT the to_ticks are 200, 400, 800 and so-on.
*/
- struct timeval timeout;
-
- while(1) {
- timeout.tv_sec = 0;
- timeout.tv_usec = 1000 * TIMEOUT_INTERVAL;
+ for (;;) {
#if defined (__Userspace_os_Windows)
Sleep(TIMEOUT_INTERVAL);
#else
+ struct timeval timeout;
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 1000 * TIMEOUT_INTERVAL;
select(0, NULL, NULL, NULL, &timeout);
#endif
+ if (SCTP_BASE_VAR(timer_thread_should_exit)) {
+ break;
+ }
/* update our tick count */
ticks += MSEC_TO_TICKS(TIMEOUT_INTERVAL);
SCTP_TIMERQ_LOCK();
@@ -93,6 +123,11 @@ user_sctp_timer_iterate(void *threadname)
}
SCTP_TIMERQ_UNLOCK();
}
+#if defined (__Userspace_os_Windows)
+ ExitThread(0);
+#else
+ pthread_exit(NULL);
+#endif
return NULL;
}
diff --git a/usrsctplib/user_socket.c b/usrsctplib/user_socket.c
index b04c1029..fa493531 100755
--- a/usrsctplib/user_socket.c
+++ b/usrsctplib/user_socket.c
@@ -1,3 +1,34 @@
+/*-
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993
+ * The Regents of the University of California.
+ * Copyright (c) 2004 The FreeBSD Foundation
+ * Copyright (c) 2004-2008 Robert N. M. Watson
+ * Copyright (c) 2012 Michael Tuexen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
#include <netinet/sctp_os.h>
#include <netinet/sctp_pcb.h>
#include <netinet/sctputil.h>
@@ -2292,13 +2323,13 @@ sctp_userspace_ip_output(int *result, struct mbuf *o_pak,
msg_hdr.msg_controllen = 0;
msg_hdr.msg_flags = 0;
- if ((!use_udp_tunneling) && (userspace_rawsctp > -1)) {
- if ((res = sendmsg(userspace_rawsctp, &msg_hdr, MSG_DONTWAIT)) != send_len) {
+ if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp) > -1)) {
+ if ((res = sendmsg(SCTP_BASE_VAR(userspace_rawsctp), &msg_hdr, MSG_DONTWAIT)) != send_len) {
*result = errno;
}
}
- if ((use_udp_tunneling) && (userspace_udpsctp > -1)) {
- if ((res = sendmsg(userspace_udpsctp, &msg_hdr, MSG_DONTWAIT)) != send_len) {
+ if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp) > -1)) {
+ if ((res = sendmsg(SCTP_BASE_VAR(userspace_udpsctp), &msg_hdr, MSG_DONTWAIT)) != send_len) {
*result = errno;
}
}
@@ -2312,15 +2343,15 @@ sctp_userspace_ip_output(int *result, struct mbuf *o_pak,
win_msg_hdr.Control = winbuf;
win_msg_hdr.dwFlags = 0;
- if ((!use_udp_tunneling) && (userspace_rawsctp > -1)) {
- if (WSASendMsg(userspace_rawsctp, &win_msg_hdr, 0, &win_sent_len, NULL, NULL) != 0) {
+ if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp) > -1)) {
+ if (WSASendMsg(SCTP_BASE_VAR(userspace_rawsctp), &win_msg_hdr, 0, &win_sent_len, NULL, NULL) != 0) {
*result = WSAGetLastError();
} else if (win_sent_len != send_len) {
*result = WSAGetLastError();
}
}
- if ((use_udp_tunneling) && (userspace_udpsctp > -1)) {
- if ((res = WSASendMsg(userspace_udpsctp, &win_msg_hdr, 0, &win_sent_len, NULL, NULL)) != 0) {
+ if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp) > -1)) {
+ if ((res = WSASendMsg(SCTP_BASE_VAR(userspace_udpsctp), &win_msg_hdr, 0, &win_sent_len, NULL, NULL)) != 0) {
*result = WSAGetLastError();
} else if (win_sent_len != send_len) {
*result = WSAGetLastError();
@@ -2433,7 +2464,7 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
#endif
}
if (m != NULL) {
- printf("mbuf chain couldn't be copied completely\n");
+ printf("mbuf chain couldn't be copied completely\n");
goto free_mbuf;
}
@@ -2446,13 +2477,13 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
msg_hdr.msg_controllen = 0;
msg_hdr.msg_flags = 0;
- if ((!use_udp_tunneling) && (userspace_rawsctp6 > -1)) {
- if ((res = sendmsg(userspace_rawsctp6, &msg_hdr, MSG_DONTWAIT)) != send_len) {
+ if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp6) > -1)) {
+ if ((res = sendmsg(SCTP_BASE_VAR(userspace_rawsctp6), &msg_hdr, MSG_DONTWAIT)) != send_len) {
*result = errno;
}
}
- if ((use_udp_tunneling) && (userspace_udpsctp6 > -1)) {
- if ((res = sendmsg(userspace_udpsctp6, &msg_hdr, MSG_DONTWAIT)) != send_len) {
+ if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp6) > -1)) {
+ if ((res = sendmsg(SCTP_BASE_VAR(userspace_udpsctp6), &msg_hdr, MSG_DONTWAIT)) != send_len) {
*result = errno;
}
}
@@ -2466,15 +2497,15 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
win_msg_hdr.Control = winbuf;
win_msg_hdr.dwFlags = 0;
- if ((!use_udp_tunneling) && (userspace_rawsctp6 > -1)) {
- if (WSASendMsg(userspace_rawsctp6, &win_msg_hdr, 0, &win_sent_len, NULL, NULL) != 0) {
+ if ((!use_udp_tunneling) && (SCTP_BASE_VAR(userspace_rawsctp6) > -1)) {
+ if (WSASendMsg(SCTP_BASE_VAR(userspace_rawsctp6), &win_msg_hdr, 0, &win_sent_len, NULL, NULL) != 0) {
*result = WSAGetLastError();
} else if (win_sent_len != send_len) {
*result = WSAGetLastError();
}
}
- if ((use_udp_tunneling) && (userspace_udpsctp6 > -1)) {
- if ((res = WSASendMsg(userspace_udpsctp6, &win_msg_hdr, 0, &win_sent_len, NULL, NULL)) != 0) {
+ if ((use_udp_tunneling) && (SCTP_BASE_VAR(userspace_udpsctp6) > -1)) {
+ if ((res = WSASendMsg(SCTP_BASE_VAR(userspace_udpsctp6), &win_msg_hdr, 0, &win_sent_len, NULL, NULL)) != 0) {
*result = WSAGetLastError();
} else if (win_sent_len != send_len) {
*result = WSAGetLastError();