user_recv_thread.c 49 KB

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