| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566 |
- /*-
- * Copyright (c) 2009-2010 Brad Penoff
- * Copyright (c) 2009-2010 Humaira Kamal
- * Copyright (c) 2011-2012 Irene Ruengeler
- * Copyright (c) 2011-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.
- *
- */
- #if defined(INET) || defined(INET6)
- #include <sys/types.h>
- #if !defined(_WIN32)
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <unistd.h>
- #include <pthread.h>
- #if !defined(__DragonFly__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
- #include <sys/uio.h>
- #else
- #include <user_ip6_var.h>
- #endif
- #endif
- #include <netinet/sctp_os.h>
- #include <netinet/sctp_var.h>
- #include <netinet/sctp_pcb.h>
- #include <netinet/sctp_input.h>
- #if 0
- #if defined(__linux__)
- #include <linux/netlink.h>
- #ifdef HAVE_LINUX_IF_ADDR_H
- #include <linux/if_addr.h>
- #endif
- #ifdef HAVE_LINUX_RTNETLINK_H
- #include <linux/rtnetlink.h>
- #endif
- #endif
- #endif
- #if defined(HAVE_NET_ROUTE_H)
- # include <net/route.h>
- #elif defined(__APPLE__)
- /* Apple SDKs for iOS, tvOS, watchOS, etc. don't ship this header */
- # define RTM_NEWADDR 0xc
- # define RTM_DELADDR 0xd
- # define RTAX_IFA 5
- # define RTAX_MAX 8
- #endif
- /* local macros and datatypes used to get IP addresses system independently */
- #if !defined(IP_PKTINFO) && !defined(IP_RECVDSTADDR)
- # error "Can't determine socket option to use to get UDP IP"
- #endif
- void recv_thread_destroy(void);
- #define MAXLEN_MBUF_CHAIN 128
- #define ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
- #if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__)
- #define NEXT_SA(ap) ap = (struct sockaddr *) \
- ((caddr_t) ap + (ap->sa_len ? ROUNDUP(ap->sa_len, sizeof (uint32_t)) : sizeof(uint32_t)))
- #endif
- #if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__)
- static void
- sctp_get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
- {
- int i;
- for (i = 0; i < RTAX_MAX; i++) {
- if (addrs & (1 << i)) {
- rti_info[i] = sa;
- NEXT_SA(sa);
- } else {
- rti_info[i] = NULL;
- }
- }
- }
- static void
- sctp_handle_ifamsg(unsigned char type, unsigned short index, struct sockaddr *sa)
- {
- int rc;
- struct ifaddrs *ifa, *ifas;
- /* handle only the types we want */
- if ((type != RTM_NEWADDR) && (type != RTM_DELADDR)) {
- return;
- }
- rc = getifaddrs(&ifas);
- if (rc != 0) {
- return;
- }
- for (ifa = ifas; ifa; ifa = ifa->ifa_next) {
- if (index == if_nametoindex(ifa->ifa_name)) {
- break;
- }
- }
- if (ifa == NULL) {
- freeifaddrs(ifas);
- return;
- }
- /* relay the appropriate address change to the base code */
- if (type == RTM_NEWADDR) {
- (void)sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID,
- NULL,
- if_nametoindex(ifa->ifa_name),
- 0,
- ifa->ifa_name,
- NULL,
- sa,
- 0,
- 1);
- } else {
- sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr,
- if_nametoindex(ifa->ifa_name),
- ifa->ifa_name);
- }
- freeifaddrs(ifas);
- }
- static void *
- recv_function_route(void *arg)
- {
- ssize_t ret;
- struct ifa_msghdr *ifa;
- char rt_buffer[1024];
- struct sockaddr *sa, *rti_info[RTAX_MAX];
- sctp_userspace_set_threadname("SCTP addr mon");
- while (1) {
- memset(rt_buffer, 0, sizeof(rt_buffer));
- ret = recv(SCTP_BASE_VAR(userspace_route), rt_buffer, sizeof(rt_buffer), 0);
- if (ret > 0) {
- ifa = (struct ifa_msghdr *) rt_buffer;
- if (ifa->ifam_type != RTM_DELADDR && ifa->ifam_type != RTM_NEWADDR) {
- continue;
- }
- sa = (struct sockaddr *) (ifa + 1);
- sctp_get_rtaddrs(ifa->ifam_addrs, sa, rti_info);
- switch (ifa->ifam_type) {
- case RTM_DELADDR:
- case RTM_NEWADDR:
- sctp_handle_ifamsg(ifa->ifam_type, ifa->ifam_index, rti_info[RTAX_IFA]);
- break;
- default:
- /* ignore this routing event */
- break;
- }
- }
- if (ret < 0) {
- if (errno == EAGAIN || errno == EINTR) {
- continue;
- } else {
- break;
- }
- }
- }
- return (NULL);
- }
- #endif
- #if 0
- /* This does not yet work on Linux */
- static void *
- recv_function_route(void *arg)
- {
- int len;
- char buf[4096];
- struct iovec iov = { buf, sizeof(buf) };
- struct msghdr msg;
- struct nlmsghdr *nh;
- struct ifaddrmsg *rtmsg;
- struct rtattr *rtatp;
- struct in_addr *inp;
- struct sockaddr_nl sanl;
- #ifdef INET
- struct sockaddr_in *sa;
- #endif
- #ifdef INET6
- struct sockaddr_in6 *sa6;
- #endif
- for (;;) {
- memset(&sanl, 0, sizeof(sanl));
- sanl.nl_family = AF_NETLINK;
- sanl.nl_groups = RTMGRP_IPV6_IFADDR | RTMGRP_IPV4_IFADDR;
- memset(&msg, 0, sizeof(struct msghdr));
- msg.msg_name = (void *)&sanl;
- msg.msg_namelen = sizeof(sanl);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- len = recvmsg(SCTP_BASE_VAR(userspace_route), &msg, 0);
- if (len < 0) {
- if (errno == EAGAIN || errno == EINTR) {
- continue;
- } else {
- break;
- }
- }
- for (nh = (struct nlmsghdr *) buf; NLMSG_OK (nh, len);
- nh = NLMSG_NEXT (nh, len)) {
- if (nh->nlmsg_type == NLMSG_DONE)
- break;
- if (nh->nlmsg_type == RTM_NEWADDR || nh->nlmsg_type == RTM_DELADDR) {
- rtmsg = (struct ifaddrmsg *)NLMSG_DATA(nh);
- rtatp = (struct rtattr *)IFA_RTA(rtmsg);
- if (rtatp->rta_type == IFA_ADDRESS) {
- inp = (struct in_addr *)RTA_DATA(rtatp);
- switch (rtmsg->ifa_family) {
- #ifdef INET
- case AF_INET:
- sa = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
- sa->sin_family = rtmsg->ifa_family;
- sa->sin_port = 0;
- memcpy(&sa->sin_addr, inp, sizeof(struct in_addr));
- sctp_handle_ifamsg(nh->nlmsg_type, rtmsg->ifa_index, (struct sockaddr *)sa);
- break;
- #endif
- #ifdef INET6
- case AF_INET6:
- sa6 = (struct sockaddr_in6 *)malloc(sizeof(struct sockaddr_in6));
- sa6->sin6_family = rtmsg->ifa_family;
- sa6->sin6_port = 0;
- memcpy(&sa6->sin6_addr, inp, sizeof(struct in6_addr));
- sctp_handle_ifamsg(nh->nlmsg_type, rtmsg->ifa_index, (struct sockaddr *)sa6);
- break;
- #endif
- default:
- SCTPDBG(SCTP_DEBUG_USR, "Address family %d not supported.\n", rtmsg->ifa_family);
- break;
- }
- }
- }
- }
- }
- return (NULL);
- }
- #endif
- #ifdef INET
- static void *
- recv_function_raw(void *arg)
- {
- struct mbuf **recvmbuf;
- struct ip *iphdr;
- struct sctphdr *sh;
- uint16_t port;
- int offset, ecn = 0;
- int compute_crc = 1;
- struct sctp_chunkhdr *ch;
- struct sockaddr_in src, dst;
- #if !defined(_WIN32)
- ssize_t res;
- unsigned int ncounter;
- struct msghdr msg;
- struct iovec recv_iovec[MAXLEN_MBUF_CHAIN];
- #else
- WSABUF recv_iovec[MAXLEN_MBUF_CHAIN];
- int nResult, m_ErrorCode;
- DWORD flags;
- DWORD ncounter;
- struct sockaddr_in from;
- int fromlen;
- #endif
- /*Initially the entire set of mbufs is to be allocated.
- to_fill indicates this amount. */
- int to_fill = MAXLEN_MBUF_CHAIN;
- /* iovlen is the size of each mbuf in the chain */
- int i, n;
- unsigned int iovlen = MCLBYTES;
- int want_ext = (iovlen > MLEN)? 1 : 0;
- int want_header = 0;
- sctp_userspace_set_threadname("SCTP/IP4 rcv");
- memset(&src, 0, sizeof(struct sockaddr_in));
- memset(&dst, 0, sizeof(struct sockaddr_in));
- recvmbuf = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN);
- while (1) {
- for (i = 0; i < to_fill; i++) {
- /* Not getting the packet header. Tests with chain of one run
- as usual without having the packet header.
- Have tried both sending and receiving
- */
- recvmbuf[i] = sctp_get_mbuf_for_msg(iovlen, want_header, M_NOWAIT, want_ext, MT_DATA);
- #if !defined(_WIN32)
- recv_iovec[i].iov_base = (caddr_t)recvmbuf[i]->m_data;
- recv_iovec[i].iov_len = iovlen;
- #else
- recv_iovec[i].buf = (caddr_t)recvmbuf[i]->m_data;
- recv_iovec[i].len = iovlen;
- #endif
- }
- to_fill = 0;
- #if defined(_WIN32)
- flags = 0;
- ncounter = 0;
- fromlen = sizeof(struct sockaddr_in);
- memset(&from, 0, sizeof(struct sockaddr_in));
- nResult = WSARecvFrom(SCTP_BASE_VAR(userspace_rawsctp), recv_iovec, MAXLEN_MBUF_CHAIN, &ncounter, &flags, (struct sockaddr *)&from, &fromlen, NULL, NULL);
- if (nResult != 0) {
- m_ErrorCode = WSAGetLastError();
- if ((m_ErrorCode == WSAENOTSOCK) || (m_ErrorCode == WSAEINTR)) {
- break;
- }
- continue;
- }
- n = ncounter;
- #else
- memset(&msg, 0, sizeof(struct msghdr));
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = recv_iovec;
- msg.msg_iovlen = MAXLEN_MBUF_CHAIN;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- res = recvmsg(SCTP_BASE_VAR(userspace_rawsctp), &msg, 0);
- if (res < 0) {
- if (errno == EAGAIN || errno == EINTR) {
- continue;
- } else {
- break;
- }
- }
- ncounter = (unsigned int)res;
- n = (int)res;
- #endif
- SCTP_HEADER_LEN(recvmbuf[0]) = n; /* length of total packet */
- SCTP_STAT_INCR(sctps_recvpackets);
- SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
- if ((unsigned int)n <= iovlen) {
- SCTP_BUF_LEN(recvmbuf[0]) = n;
- (to_fill)++;
- } else {
- i = 0;
- SCTP_BUF_LEN(recvmbuf[0]) = iovlen;
- ncounter -= min(ncounter, iovlen);
- (to_fill)++;
- do {
- recvmbuf[i]->m_next = recvmbuf[i+1];
- SCTP_BUF_LEN(recvmbuf[i]->m_next) = min(ncounter, iovlen);
- i++;
- ncounter -= min(ncounter, iovlen);
- (to_fill)++;
- } while (ncounter > 0);
- }
- offset = sizeof(struct ip) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
- if (SCTP_BUF_LEN(recvmbuf[0]) < offset) {
- if ((recvmbuf[0] = m_pullup(recvmbuf[0], offset)) == NULL) {
- SCTP_STAT_INCR(sctps_hdrops);
- continue;
- }
- }
- iphdr = mtod(recvmbuf[0], struct ip *);
- sh = (struct sctphdr *)((caddr_t)iphdr + sizeof(struct ip));
- ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
- offset -= sizeof(struct sctp_chunkhdr);
- if (iphdr->ip_tos != 0) {
- ecn = iphdr->ip_tos & 0x03;
- }
- dst.sin_family = AF_INET;
- #ifdef HAVE_SIN_LEN
- dst.sin_len = sizeof(struct sockaddr_in);
- #endif
- dst.sin_addr = iphdr->ip_dst;
- dst.sin_port = sh->dest_port;
- src.sin_family = AF_INET;
- #ifdef HAVE_SIN_LEN
- src.sin_len = sizeof(struct sockaddr_in);
- #endif
- src.sin_addr = iphdr->ip_src;
- src.sin_port = sh->src_port;
- /* SCTP does not allow broadcasts or multicasts */
- if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
- m_freem(recvmbuf[0]);
- continue;
- }
- if (SCTP_IS_IT_BROADCAST(dst.sin_addr, recvmbuf[0])) {
- m_freem(recvmbuf[0]);
- continue;
- }
- port = 0;
- if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
- ((IN4_ISLOOPBACK_ADDRESS(&src.sin_addr) &&
- IN4_ISLOOPBACK_ADDRESS(&dst.sin_addr)) ||
- (src.sin_addr.s_addr == dst.sin_addr.s_addr))) {
- compute_crc = 0;
- SCTP_STAT_INCR(sctps_recvhwcrc);
- } else {
- SCTP_STAT_INCR(sctps_recvswcrc);
- }
- SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
- SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", offset);
- sctp_common_input_processing(&recvmbuf[0], sizeof(struct ip), offset, n,
- (struct sockaddr *)&src,
- (struct sockaddr *)&dst,
- sh, ch,
- compute_crc,
- ecn,
- SCTP_DEFAULT_VRFID, port);
- if (recvmbuf[0]) {
- m_freem(recvmbuf[0]);
- }
- }
- for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
- m_free(recvmbuf[i]);
- }
- /* free the array itself */
- free(recvmbuf);
- SCTPDBG(SCTP_DEBUG_USR, "%s: Exiting SCTP/IP4 rcv\n", __func__);
- return (NULL);
- }
- #endif
- #if defined(INET6)
- static void *
- recv_function_raw6(void *arg)
- {
- struct mbuf **recvmbuf6;
- #if !defined(_WIN32)
- ssize_t res;
- unsigned int ncounter;
- struct iovec recv_iovec[MAXLEN_MBUF_CHAIN];
- struct msghdr msg;
- struct cmsghdr *cmsgptr;
- char cmsgbuf[CMSG_SPACE(sizeof (struct in6_pktinfo))];
- #else
- WSABUF recv_iovec[MAXLEN_MBUF_CHAIN];
- int nResult, m_ErrorCode;
- DWORD ncounter = 0;
- struct sockaddr_in6 from;
- GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
- LPFN_WSARECVMSG WSARecvMsg;
- WSACMSGHDR *cmsgptr;
- WSAMSG msg;
- char ControlBuffer[1024];
- #endif
- struct sockaddr_in6 src, dst;
- struct sctphdr *sh;
- int offset;
- struct sctp_chunkhdr *ch;
- /*Initially the entire set of mbufs is to be allocated.
- to_fill indicates this amount. */
- int to_fill = MAXLEN_MBUF_CHAIN;
- /* iovlen is the size of each mbuf in the chain */
- int i, n;
- int compute_crc = 1;
- unsigned int iovlen = MCLBYTES;
- int want_ext = (iovlen > MLEN)? 1 : 0;
- int want_header = 0;
- sctp_userspace_set_threadname("SCTP/IP6 rcv");
- recvmbuf6 = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN);
- for (;;) {
- for (i = 0; i < to_fill; i++) {
- /* Not getting the packet header. Tests with chain of one run
- as usual without having the packet header.
- Have tried both sending and receiving
- */
- recvmbuf6[i] = sctp_get_mbuf_for_msg(iovlen, want_header, M_NOWAIT, want_ext, MT_DATA);
- #if !defined(_WIN32)
- recv_iovec[i].iov_base = (caddr_t)recvmbuf6[i]->m_data;
- recv_iovec[i].iov_len = iovlen;
- #else
- recv_iovec[i].buf = (caddr_t)recvmbuf6[i]->m_data;
- recv_iovec[i].len = iovlen;
- #endif
- }
- to_fill = 0;
- #if defined(_WIN32)
- ncounter = 0;
- memset(&from, 0, sizeof(struct sockaddr_in6));
- nResult = WSAIoctl(SCTP_BASE_VAR(userspace_rawsctp6), SIO_GET_EXTENSION_FUNCTION_POINTER,
- &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID,
- &WSARecvMsg, sizeof WSARecvMsg,
- &ncounter, NULL, NULL);
- if (nResult == 0) {
- msg.name = (void *)&src;
- msg.namelen = sizeof(struct sockaddr_in6);
- msg.lpBuffers = recv_iovec;
- msg.dwBufferCount = MAXLEN_MBUF_CHAIN;
- msg.Control.len = sizeof ControlBuffer;
- msg.Control.buf = ControlBuffer;
- msg.dwFlags = 0;
- nResult = WSARecvMsg(SCTP_BASE_VAR(userspace_rawsctp6), &msg, &ncounter, NULL, NULL);
- }
- if (nResult != 0) {
- m_ErrorCode = WSAGetLastError();
- if ((m_ErrorCode == WSAENOTSOCK) || (m_ErrorCode == WSAEINTR)) {
- break;
- }
- continue;
- }
- n = ncounter;
- #else
- memset(&msg, 0, sizeof(struct msghdr));
- memset(&src, 0, sizeof(struct sockaddr_in6));
- memset(&dst, 0, sizeof(struct sockaddr_in6));
- memset(cmsgbuf, 0, CMSG_SPACE(sizeof (struct in6_pktinfo)));
- msg.msg_name = (void *)&src;
- msg.msg_namelen = sizeof(struct sockaddr_in6);
- msg.msg_iov = recv_iovec;
- msg.msg_iovlen = MAXLEN_MBUF_CHAIN;
- msg.msg_control = (void *)cmsgbuf;
- msg.msg_controllen = (socklen_t)CMSG_SPACE(sizeof (struct in6_pktinfo));
- msg.msg_flags = 0;
- res = recvmsg(SCTP_BASE_VAR(userspace_rawsctp6), &msg, 0);
- if (res < 0) {
- if (errno == EAGAIN || errno == EINTR) {
- continue;
- } else {
- break;
- }
- }
- ncounter = (unsigned int)res;
- n = (int)res;
- #endif
- SCTP_HEADER_LEN(recvmbuf6[0]) = n; /* length of total packet */
- SCTP_STAT_INCR(sctps_recvpackets);
- SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
- if ((unsigned int)n <= iovlen) {
- SCTP_BUF_LEN(recvmbuf6[0]) = n;
- (to_fill)++;
- } else {
- i = 0;
- SCTP_BUF_LEN(recvmbuf6[0]) = iovlen;
- ncounter -= min(ncounter, iovlen);
- (to_fill)++;
- do {
- recvmbuf6[i]->m_next = recvmbuf6[i+1];
- SCTP_BUF_LEN(recvmbuf6[i]->m_next) = min(ncounter, iovlen);
- i++;
- ncounter -= min(ncounter, iovlen);
- (to_fill)++;
- } while (ncounter > 0);
- }
- for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
- if ((cmsgptr->cmsg_level == IPPROTO_IPV6) && (cmsgptr->cmsg_type == IPV6_PKTINFO)) {
- struct in6_pktinfo * info;
- info = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
- memcpy((void *)&dst.sin6_addr, (const void *) &(info->ipi6_addr), sizeof(struct in6_addr));
- break;
- }
- }
- /* SCTP does not allow broadcasts or multicasts */
- if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) {
- m_freem(recvmbuf6[0]);
- continue;
- }
- offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
- if (SCTP_BUF_LEN(recvmbuf6[0]) < offset) {
- if ((recvmbuf6[0] = m_pullup(recvmbuf6[0], offset)) == NULL) {
- SCTP_STAT_INCR(sctps_hdrops);
- continue;
- }
- }
- sh = mtod(recvmbuf6[0], struct sctphdr *);
- ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
- offset -= sizeof(struct sctp_chunkhdr);
- dst.sin6_family = AF_INET6;
- #ifdef HAVE_SIN6_LEN
- dst.sin6_len = sizeof(struct sockaddr_in6);
- #endif
- dst.sin6_port = sh->dest_port;
- src.sin6_family = AF_INET6;
- #ifdef HAVE_SIN6_LEN
- src.sin6_len = sizeof(struct sockaddr_in6);
- #endif
- src.sin6_port = sh->src_port;
- if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
- (memcmp(&src.sin6_addr, &dst.sin6_addr, sizeof(struct in6_addr)) == 0)) {
- compute_crc = 0;
- SCTP_STAT_INCR(sctps_recvhwcrc);
- } else {
- SCTP_STAT_INCR(sctps_recvswcrc);
- }
- SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
- SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", offset);
- sctp_common_input_processing(&recvmbuf6[0], 0, offset, n,
- (struct sockaddr *)&src,
- (struct sockaddr *)&dst,
- sh, ch,
- compute_crc,
- 0,
- SCTP_DEFAULT_VRFID, 0);
- if (recvmbuf6[0]) {
- m_freem(recvmbuf6[0]);
- }
- }
- for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
- m_free(recvmbuf6[i]);
- }
- /* free the array itself */
- free(recvmbuf6);
- SCTPDBG(SCTP_DEBUG_USR, "%s: Exiting SCTP/IP6 rcv\n", __func__);
- return (NULL);
- }
- #endif
- #ifdef INET
- 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;
- /* iovlen is the size of each mbuf in the chain */
- int i, n, offset;
- unsigned int iovlen = MCLBYTES;
- int want_ext = (iovlen > MLEN)? 1 : 0;
- int want_header = 0;
- struct sctphdr *sh;
- uint16_t port;
- struct sctp_chunkhdr *ch;
- struct sockaddr_in src, dst;
- #if defined(IP_PKTINFO)
- char cmsgbuf[CMSG_SPACE(sizeof(struct in_pktinfo))];
- #else
- char cmsgbuf[CMSG_SPACE(sizeof(struct in_addr))];
- #endif
- int compute_crc = 1;
- #if !defined(_WIN32)
- ssize_t res;
- unsigned int ncounter;
- struct iovec iov[MAXLEN_MBUF_CHAIN];
- struct msghdr msg;
- struct cmsghdr *cmsgptr;
- #else
- GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
- LPFN_WSARECVMSG WSARecvMsg;
- char ControlBuffer[1024];
- WSABUF iov[MAXLEN_MBUF_CHAIN];
- WSAMSG msg;
- int nResult, m_ErrorCode;
- WSACMSGHDR *cmsgptr;
- DWORD ncounter;
- #endif
- sctp_userspace_set_threadname("SCTP/UDP/IP4 rcv");
- udprecvmbuf = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN);
- while (1) {
- for (i = 0; i < to_fill; i++) {
- /* Not getting the packet header. Tests with chain of one run
- as usual without having the packet header.
- Have tried both sending and receiving
- */
- udprecvmbuf[i] = sctp_get_mbuf_for_msg(iovlen, want_header, M_NOWAIT, want_ext, MT_DATA);
- #if !defined(_WIN32)
- iov[i].iov_base = (caddr_t)udprecvmbuf[i]->m_data;
- iov[i].iov_len = iovlen;
- #else
- iov[i].buf = (caddr_t)udprecvmbuf[i]->m_data;
- iov[i].len = iovlen;
- #endif
- }
- to_fill = 0;
- #if !defined(_WIN32)
- memset(&msg, 0, sizeof(struct msghdr));
- #else
- memset(&msg, 0, sizeof(WSAMSG));
- #endif
- memset(&src, 0, sizeof(struct sockaddr_in));
- memset(&dst, 0, sizeof(struct sockaddr_in));
- memset(cmsgbuf, 0, sizeof(cmsgbuf));
- #if !defined(_WIN32)
- msg.msg_name = (void *)&src;
- msg.msg_namelen = sizeof(struct sockaddr_in);
- msg.msg_iov = iov;
- msg.msg_iovlen = MAXLEN_MBUF_CHAIN;
- msg.msg_control = (void *)cmsgbuf;
- msg.msg_controllen = sizeof(cmsgbuf);
- msg.msg_flags = 0;
- res = recvmsg(SCTP_BASE_VAR(userspace_udpsctp), &msg, 0);
- if (res < 0) {
- if (errno == EAGAIN || errno == EINTR) {
- continue;
- } else {
- break;
- }
- }
- ncounter = (unsigned int)res;
- n = (int)res;
- #else
- nResult = WSAIoctl(SCTP_BASE_VAR(userspace_udpsctp), SIO_GET_EXTENSION_FUNCTION_POINTER,
- &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID,
- &WSARecvMsg, sizeof WSARecvMsg,
- &ncounter, NULL, NULL);
- if (nResult == 0) {
- msg.name = (void *)&src;
- msg.namelen = sizeof(struct sockaddr_in);
- msg.lpBuffers = iov;
- msg.dwBufferCount = MAXLEN_MBUF_CHAIN;
- msg.Control.len = sizeof ControlBuffer;
- msg.Control.buf = ControlBuffer;
- msg.dwFlags = 0;
- nResult = WSARecvMsg(SCTP_BASE_VAR(userspace_udpsctp), &msg, &ncounter, NULL, NULL);
- }
- if (nResult != 0) {
- m_ErrorCode = WSAGetLastError();
- if ((m_ErrorCode == WSAENOTSOCK) || (m_ErrorCode == WSAEINTR)) {
- break;
- }
- continue;
- }
- n = ncounter;
- #endif
- SCTP_HEADER_LEN(udprecvmbuf[0]) = n; /* length of total packet */
- SCTP_STAT_INCR(sctps_recvpackets);
- SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
- if ((unsigned int)n <= iovlen) {
- SCTP_BUF_LEN(udprecvmbuf[0]) = n;
- (to_fill)++;
- } else {
- i = 0;
- SCTP_BUF_LEN(udprecvmbuf[0]) = iovlen;
- ncounter -= min(ncounter, iovlen);
- (to_fill)++;
- do {
- udprecvmbuf[i]->m_next = udprecvmbuf[i+1];
- SCTP_BUF_LEN(udprecvmbuf[i]->m_next) = min(ncounter, iovlen);
- i++;
- ncounter -= min(ncounter, iovlen);
- (to_fill)++;
- } while (ncounter > 0);
- }
- for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
- #if defined(IP_PKTINFO)
- if ((cmsgptr->cmsg_level == IPPROTO_IP) && (cmsgptr->cmsg_type == IP_PKTINFO)) {
- struct in_pktinfo *info;
- dst.sin_family = AF_INET;
- #ifdef HAVE_SIN_LEN
- dst.sin_len = sizeof(struct sockaddr_in);
- #endif
- info = (struct in_pktinfo *)CMSG_DATA(cmsgptr);
- memcpy((void *)&dst.sin_addr, (const void *)&(info->ipi_addr), sizeof(struct in_addr));
- break;
- }
- #else
- if ((cmsgptr->cmsg_level == IPPROTO_IP) && (cmsgptr->cmsg_type == IP_RECVDSTADDR)) {
- struct in_addr *addr;
- dst.sin_family = AF_INET;
- #ifdef HAVE_SIN_LEN
- dst.sin_len = sizeof(struct sockaddr_in);
- #endif
- addr = (struct in_addr *)CMSG_DATA(cmsgptr);
- memcpy((void *)&dst.sin_addr, (const void *)addr, sizeof(struct in_addr));
- break;
- }
- #endif
- }
- /* SCTP does not allow broadcasts or multicasts */
- if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
- m_freem(udprecvmbuf[0]);
- continue;
- }
- if (SCTP_IS_IT_BROADCAST(dst.sin_addr, udprecvmbuf[0])) {
- m_freem(udprecvmbuf[0]);
- continue;
- }
- offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
- if (SCTP_BUF_LEN(udprecvmbuf[0]) < offset) {
- if ((udprecvmbuf[0] = m_pullup(udprecvmbuf[0], offset)) == NULL) {
- SCTP_STAT_INCR(sctps_hdrops);
- continue;
- }
- }
- sh = mtod(udprecvmbuf[0], struct sctphdr *);
- ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
- offset -= sizeof(struct sctp_chunkhdr);
- port = src.sin_port;
- src.sin_port = sh->src_port;
- dst.sin_port = sh->dest_port;
- if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
- (src.sin_addr.s_addr == dst.sin_addr.s_addr)) {
- compute_crc = 0;
- SCTP_STAT_INCR(sctps_recvhwcrc);
- } else {
- SCTP_STAT_INCR(sctps_recvswcrc);
- }
- SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
- SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", offset);
- sctp_common_input_processing(&udprecvmbuf[0], 0, offset, n,
- (struct sockaddr *)&src,
- (struct sockaddr *)&dst,
- sh, ch,
- compute_crc,
- 0,
- SCTP_DEFAULT_VRFID, port);
- if (udprecvmbuf[0]) {
- m_freem(udprecvmbuf[0]);
- }
- }
- for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
- m_free(udprecvmbuf[i]);
- }
- /* free the array itself */
- free(udprecvmbuf);
- SCTPDBG(SCTP_DEBUG_USR, "%s: Exiting SCTP/UDP/IP4 rcv\n", __func__);
- return (NULL);
- }
- #endif
- #if defined(INET6)
- 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;
- /* iovlen is the size of each mbuf in the chain */
- int i, n, offset;
- unsigned int iovlen = MCLBYTES;
- int want_ext = (iovlen > MLEN)? 1 : 0;
- int want_header = 0;
- struct sockaddr_in6 src, dst;
- struct sctphdr *sh;
- uint16_t port;
- struct sctp_chunkhdr *ch;
- char cmsgbuf[CMSG_SPACE(sizeof (struct in6_pktinfo))];
- int compute_crc = 1;
- #if !defined(_WIN32)
- struct iovec iov[MAXLEN_MBUF_CHAIN];
- struct msghdr msg;
- struct cmsghdr *cmsgptr;
- ssize_t res;
- unsigned int ncounter;
- #else
- GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
- LPFN_WSARECVMSG WSARecvMsg;
- char ControlBuffer[1024];
- WSABUF iov[MAXLEN_MBUF_CHAIN];
- WSAMSG msg;
- int nResult, m_ErrorCode;
- WSACMSGHDR *cmsgptr;
- DWORD ncounter;
- #endif
- sctp_userspace_set_threadname("SCTP/UDP/IP6 rcv");
- udprecvmbuf6 = malloc(sizeof(struct mbuf *) * MAXLEN_MBUF_CHAIN);
- while (1) {
- for (i = 0; i < to_fill; i++) {
- /* Not getting the packet header. Tests with chain of one run
- as usual without having the packet header.
- Have tried both sending and receiving
- */
- udprecvmbuf6[i] = sctp_get_mbuf_for_msg(iovlen, want_header, M_NOWAIT, want_ext, MT_DATA);
- #if !defined(_WIN32)
- iov[i].iov_base = (caddr_t)udprecvmbuf6[i]->m_data;
- iov[i].iov_len = iovlen;
- #else
- iov[i].buf = (caddr_t)udprecvmbuf6[i]->m_data;
- iov[i].len = iovlen;
- #endif
- }
- to_fill = 0;
- #if !defined(_WIN32)
- memset(&msg, 0, sizeof(struct msghdr));
- #else
- memset(&msg, 0, sizeof(WSAMSG));
- #endif
- memset(&src, 0, sizeof(struct sockaddr_in6));
- memset(&dst, 0, sizeof(struct sockaddr_in6));
- memset(cmsgbuf, 0, CMSG_SPACE(sizeof (struct in6_pktinfo)));
- #if !defined(_WIN32)
- msg.msg_name = (void *)&src;
- msg.msg_namelen = sizeof(struct sockaddr_in6);
- msg.msg_iov = iov;
- msg.msg_iovlen = MAXLEN_MBUF_CHAIN;
- msg.msg_control = (void *)cmsgbuf;
- msg.msg_controllen = (socklen_t)CMSG_SPACE(sizeof (struct in6_pktinfo));
- msg.msg_flags = 0;
- res = recvmsg(SCTP_BASE_VAR(userspace_udpsctp6), &msg, 0);
- if (res < 0) {
- if (errno == EAGAIN || errno == EINTR) {
- continue;
- } else {
- break;
- }
- }
- ncounter = (unsigned int)res;
- n = (int)res;
- #else
- nResult = WSAIoctl(SCTP_BASE_VAR(userspace_udpsctp6), SIO_GET_EXTENSION_FUNCTION_POINTER,
- &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID,
- &WSARecvMsg, sizeof WSARecvMsg,
- &ncounter, NULL, NULL);
- if (nResult == SOCKET_ERROR) {
- m_ErrorCode = WSAGetLastError();
- WSARecvMsg = NULL;
- }
- if (nResult == 0) {
- msg.name = (void *)&src;
- msg.namelen = sizeof(struct sockaddr_in6);
- msg.lpBuffers = iov;
- msg.dwBufferCount = MAXLEN_MBUF_CHAIN;
- msg.Control.len = sizeof ControlBuffer;
- msg.Control.buf = ControlBuffer;
- msg.dwFlags = 0;
- nResult = WSARecvMsg(SCTP_BASE_VAR(userspace_udpsctp6), &msg, &ncounter, NULL, NULL);
- }
- if (nResult != 0) {
- m_ErrorCode = WSAGetLastError();
- if ((m_ErrorCode == WSAENOTSOCK) || (m_ErrorCode == WSAEINTR)) {
- break;
- }
- continue;
- }
- n = ncounter;
- #endif
- SCTP_HEADER_LEN(udprecvmbuf6[0]) = n; /* length of total packet */
- SCTP_STAT_INCR(sctps_recvpackets);
- SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
- if ((unsigned int)n <= iovlen) {
- SCTP_BUF_LEN(udprecvmbuf6[0]) = n;
- (to_fill)++;
- } else {
- i = 0;
- SCTP_BUF_LEN(udprecvmbuf6[0]) = iovlen;
- ncounter -= min(ncounter, iovlen);
- (to_fill)++;
- do {
- udprecvmbuf6[i]->m_next = udprecvmbuf6[i+1];
- SCTP_BUF_LEN(udprecvmbuf6[i]->m_next) = min(ncounter, iovlen);
- i++;
- ncounter -= min(ncounter, iovlen);
- (to_fill)++;
- } while (ncounter > 0);
- }
- for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
- if ((cmsgptr->cmsg_level == IPPROTO_IPV6) && (cmsgptr->cmsg_type == IPV6_PKTINFO)) {
- struct in6_pktinfo *info;
- dst.sin6_family = AF_INET6;
- #ifdef HAVE_SIN6_LEN
- dst.sin6_len = sizeof(struct sockaddr_in6);
- #endif
- info = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
- /*dst.sin6_port = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));*/
- memcpy((void *)&dst.sin6_addr, (const void *)&(info->ipi6_addr), sizeof(struct in6_addr));
- }
- }
- /* SCTP does not allow broadcasts or multicasts */
- if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) {
- m_freem(udprecvmbuf6[0]);
- continue;
- }
- offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
- if (SCTP_BUF_LEN(udprecvmbuf6[0]) < offset) {
- if ((udprecvmbuf6[0] = m_pullup(udprecvmbuf6[0], offset)) == NULL) {
- SCTP_STAT_INCR(sctps_hdrops);
- continue;
- }
- }
- sh = mtod(udprecvmbuf6[0], struct sctphdr *);
- ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
- offset -= sizeof(struct sctp_chunkhdr);
- port = src.sin6_port;
- src.sin6_port = sh->src_port;
- dst.sin6_port = sh->dest_port;
- if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
- (memcmp(&src.sin6_addr, &dst.sin6_addr, sizeof(struct in6_addr)) == 0)) {
- compute_crc = 0;
- SCTP_STAT_INCR(sctps_recvhwcrc);
- } else {
- SCTP_STAT_INCR(sctps_recvswcrc);
- }
- SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
- SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", (int)sizeof(struct sctphdr));
- sctp_common_input_processing(&udprecvmbuf6[0], 0, offset, n,
- (struct sockaddr *)&src,
- (struct sockaddr *)&dst,
- sh, ch,
- compute_crc,
- 0,
- SCTP_DEFAULT_VRFID, port);
- if (udprecvmbuf6[0]) {
- m_freem(udprecvmbuf6[0]);
- }
- }
- for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
- m_free(udprecvmbuf6[i]);
- }
- /* free the array itself */
- free(udprecvmbuf6);
- SCTPDBG(SCTP_DEBUG_USR, "%s: Exiting SCTP/UDP/IP6 rcv\n", __func__);
- return (NULL);
- }
- #endif
- #if defined(_WIN32)
- static void
- setReceiveBufferSize(SOCKET sfd, int new_size)
- #else
- static void
- setReceiveBufferSize(int sfd, int new_size)
- #endif
- {
- int ch = new_size;
- if (setsockopt (sfd, SOL_SOCKET, SO_RCVBUF, (void*)&ch, sizeof(ch)) < 0) {
- #if defined(_WIN32)
- 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;
- }
- #if defined(_WIN32)
- static void
- setSendBufferSize(SOCKET sfd, int new_size)
- #else
- static void
- setSendBufferSize(int sfd, int new_size)
- #endif
- {
- int ch = new_size;
- if (setsockopt (sfd, SOL_SOCKET, SO_SNDBUF, (void*)&ch, sizeof(ch)) < 0) {
- #if defined(_WIN32)
- 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(_WIN32)
- struct timeval timeout;
- memset(&timeout, 0, sizeof(struct timeval));
- 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(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__)
- if (SCTP_BASE_VAR(userspace_route) == -1) {
- if ((SCTP_BASE_VAR(userspace_route) = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) {
- 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(_WIN32)
- 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)) == -1) {
- #if defined(_WIN32)
- 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(_WIN32)
- 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(_WIN32)
- 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(_WIN32)
- 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) && (SCTP_BASE_SYSCTL(sctp_udp_tunneling_port) != 0)) {
- if ((SCTP_BASE_VAR(userspace_udpsctp) = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
- #if defined(_WIN32)
- 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(_WIN32)
- #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(_WIN32)
- 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(_WIN32)
- 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)) == -1) {
- #if defined(_WIN32)
- 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(_WIN32)
- 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(_WIN32)
- 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(_WIN32)
- 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(_WIN32)
- 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(_WIN32)
- 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) && (SCTP_BASE_SYSCTL(sctp_udp_tunneling_port) != 0)) {
- if ((SCTP_BASE_VAR(userspace_udpsctp6) = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
- #if defined(_WIN32)
- 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(_WIN32)
- 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(_WIN32)
- 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(_WIN32)
- 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(_WIN32)
- 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(_WIN32)
- 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(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__)
- #if defined(INET) || defined(INET6)
- if (SCTP_BASE_VAR(userspace_route) != -1) {
- int rc;
- if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadroute), &recv_function_route))) {
- 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 = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadraw), &recv_function_raw))) {
- SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv4 recv thread (%d).\n", rc);
- #if defined(_WIN32)
- closesocket(SCTP_BASE_VAR(userspace_rawsctp));
- #else
- close(SCTP_BASE_VAR(userspace_rawsctp));
- #endif
- SCTP_BASE_VAR(userspace_rawsctp) = -1;
- }
- }
- if (SCTP_BASE_VAR(userspace_udpsctp) != -1) {
- int rc;
- if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadudp), &recv_function_udp))) {
- SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv4 recv thread (%d).\n", rc);
- #if defined(_WIN32)
- closesocket(SCTP_BASE_VAR(userspace_udpsctp));
- #else
- close(SCTP_BASE_VAR(userspace_udpsctp));
- #endif
- SCTP_BASE_VAR(userspace_udpsctp) = -1;
- }
- }
- #endif
- #if defined(INET6)
- if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
- int rc;
- if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadraw6), &recv_function_raw6))) {
- SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/IPv6 recv thread (%d).\n", rc);
- #if defined(_WIN32)
- closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
- #else
- close(SCTP_BASE_VAR(userspace_rawsctp6));
- #endif
- SCTP_BASE_VAR(userspace_rawsctp6) = -1;
- }
- }
- if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) {
- int rc;
- if ((rc = sctp_userspace_thread_create(&SCTP_BASE_VAR(recvthreadudp6), &recv_function_udp6))) {
- SCTPDBG(SCTP_DEBUG_USR, "Can't start SCTP/UDP/IPv6 recv thread (%d).\n", rc);
- #if defined(_WIN32)
- closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
- #else
- close(SCTP_BASE_VAR(userspace_udpsctp6));
- #endif
- SCTP_BASE_VAR(userspace_udpsctp6) = -1;
- }
- }
- #endif
- }
- void
- recv_thread_destroy(void)
- {
- #if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__)
- #if defined(INET) || defined(INET6)
- if (SCTP_BASE_VAR(userspace_route) != -1) {
- close(SCTP_BASE_VAR(userspace_route));
- pthread_join(SCTP_BASE_VAR(recvthreadroute), NULL);
- }
- #endif
- #endif
- #if defined(INET)
- if (SCTP_BASE_VAR(userspace_rawsctp) != -1) {
- #if defined(_WIN32)
- closesocket(SCTP_BASE_VAR(userspace_rawsctp));
- SCTP_BASE_VAR(userspace_rawsctp) = -1;
- WaitForSingleObject(SCTP_BASE_VAR(recvthreadraw), INFINITE);
- CloseHandle(SCTP_BASE_VAR(recvthreadraw));
- #else
- close(SCTP_BASE_VAR(userspace_rawsctp));
- SCTP_BASE_VAR(userspace_rawsctp) = -1;
- pthread_join(SCTP_BASE_VAR(recvthreadraw), NULL);
- #endif
- }
- if (SCTP_BASE_VAR(userspace_udpsctp) != -1) {
- #if defined(_WIN32)
- closesocket(SCTP_BASE_VAR(userspace_udpsctp));
- SCTP_BASE_VAR(userspace_udpsctp) = -1;
- WaitForSingleObject(SCTP_BASE_VAR(recvthreadudp), INFINITE);
- CloseHandle(SCTP_BASE_VAR(recvthreadudp));
- #else
- close(SCTP_BASE_VAR(userspace_udpsctp));
- SCTP_BASE_VAR(userspace_udpsctp) = -1;
- pthread_join(SCTP_BASE_VAR(recvthreadudp), NULL);
- #endif
- }
- #endif
- #if defined(INET6)
- if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
- #if defined(_WIN32)
- closesocket(SCTP_BASE_VAR(userspace_rawsctp6));
- SCTP_BASE_VAR(userspace_rawsctp6) = -1;
- WaitForSingleObject(SCTP_BASE_VAR(recvthreadraw6), INFINITE);
- CloseHandle(SCTP_BASE_VAR(recvthreadraw6));
- #else
- close(SCTP_BASE_VAR(userspace_rawsctp6));
- SCTP_BASE_VAR(userspace_rawsctp6) = -1;
- pthread_join(SCTP_BASE_VAR(recvthreadraw6), NULL);
- #endif
- }
- if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) {
- #if defined(_WIN32)
- SCTP_BASE_VAR(userspace_udpsctp6) = -1;
- closesocket(SCTP_BASE_VAR(userspace_udpsctp6));
- WaitForSingleObject(SCTP_BASE_VAR(recvthreadudp6), INFINITE);
- CloseHandle(SCTP_BASE_VAR(recvthreadudp6));
- #else
- close(SCTP_BASE_VAR(userspace_udpsctp6));
- SCTP_BASE_VAR(userspace_udpsctp6) = -1;
- pthread_join(SCTP_BASE_VAR(recvthreadudp6), NULL);
- #endif
- }
- #endif
- }
- #else
- int foo;
- #endif
|