sctp_userspace.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. /*-
  2. * Copyright (c) 2011-2012 Irene Ruengeler
  3. * Copyright (c) 2011-2012 Michael Tuexen
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  16. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25. * SUCH DAMAGE.
  26. *
  27. */
  28. #ifdef _WIN32
  29. #include <netinet/sctp_pcb.h>
  30. #include <sys/timeb.h>
  31. #include <iphlpapi.h>
  32. #if !defined(__MINGW32__)
  33. #pragma comment(lib, "iphlpapi.lib")
  34. #endif
  35. #endif
  36. #include <netinet/sctp_os_userspace.h>
  37. #if defined(__FreeBSD__)
  38. #include <pthread_np.h>
  39. #endif
  40. #if defined(__linux__)
  41. #include <sys/prctl.h>
  42. #endif
  43. #if defined(_WIN32)
  44. /* Adapter to translate Unix thread start routines to Windows thread start
  45. * routines.
  46. */
  47. #if defined(__MINGW32__)
  48. #pragma GCC diagnostic push
  49. #pragma GCC diagnostic ignored "-Wpedantic"
  50. #endif
  51. static DWORD WINAPI
  52. sctp_create_thread_adapter(void *arg) {
  53. start_routine_t start_routine = (start_routine_t)arg;
  54. return start_routine(NULL) == NULL;
  55. }
  56. int
  57. sctp_userspace_thread_create(userland_thread_t *thread, start_routine_t start_routine)
  58. {
  59. *thread = CreateThread(NULL, 0, sctp_create_thread_adapter,
  60. (void *)start_routine, 0, NULL);
  61. if (*thread == NULL)
  62. return GetLastError();
  63. return 0;
  64. }
  65. #if defined(__MINGW32__)
  66. #pragma GCC diagnostic pop
  67. #endif
  68. #else
  69. int
  70. sctp_userspace_thread_create(userland_thread_t *thread, start_routine_t start_routine)
  71. {
  72. return pthread_create(thread, NULL, start_routine, NULL);
  73. }
  74. #endif
  75. void
  76. sctp_userspace_set_threadname(const char *name)
  77. {
  78. #if defined(__APPLE__)
  79. pthread_setname_np(name);
  80. #endif
  81. #if defined(__linux__)
  82. prctl(PR_SET_NAME, name);
  83. #endif
  84. #if defined(__FreeBSD__)
  85. pthread_set_name_np(pthread_self(), name);
  86. #endif
  87. }
  88. #if !defined(_WIN32) && !defined(__native_client__)
  89. int
  90. sctp_userspace_get_mtu_from_ifn(uint32_t if_index)
  91. {
  92. #if defined(INET) || defined(INET6)
  93. struct ifreq ifr;
  94. int fd;
  95. #endif
  96. int mtu;
  97. if (if_index == 0xffffffff) {
  98. mtu = 1280;
  99. } else {
  100. mtu = 0;
  101. #if defined(INET) || defined(INET6)
  102. memset(&ifr, 0, sizeof(struct ifreq));
  103. if (if_indextoname(if_index, ifr.ifr_name) != NULL) {
  104. /* TODO can I use the raw socket here and not have to open a new one with each query? */
  105. #if defined(INET)
  106. if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
  107. #else
  108. if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) >= 0) {
  109. #endif
  110. if (ioctl(fd, SIOCGIFMTU, &ifr) >= 0) {
  111. mtu = ifr.ifr_mtu;
  112. }
  113. close(fd);
  114. }
  115. }
  116. #endif
  117. }
  118. return (mtu);
  119. }
  120. #endif
  121. #if defined(__native_client__)
  122. int
  123. sctp_userspace_get_mtu_from_ifn(uint32_t if_index)
  124. {
  125. return 1280;
  126. }
  127. #endif
  128. #if defined(__APPLE__) || defined(__DragonFly__) || defined(__linux__) || defined(__native_client__) || defined(__NetBSD__) || defined(__QNX__) || defined(_WIN32) || defined(__Fuchsia__) || defined(__EMSCRIPTEN__)
  129. int
  130. timingsafe_bcmp(const void *b1, const void *b2, size_t n)
  131. {
  132. const unsigned char *p1 = b1, *p2 = b2;
  133. int ret = 0;
  134. for (; n > 0; n--)
  135. ret |= *p1++ ^ *p2++;
  136. return (ret != 0);
  137. }
  138. #endif
  139. #ifdef _WIN32
  140. int
  141. sctp_userspace_get_mtu_from_ifn(uint32_t if_index)
  142. {
  143. #if defined(INET) || defined(INET6)
  144. PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
  145. DWORD AdapterAddrsSize, Err;
  146. #endif
  147. int mtu;
  148. if (if_index == 0xffffffff) {
  149. mtu = 1280;
  150. } else {
  151. mtu = 0;
  152. #if defined(INET) || defined(INET6)
  153. AdapterAddrsSize = 0;
  154. pAdapterAddrs = NULL;
  155. if ((Err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &AdapterAddrsSize)) != 0) {
  156. if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) {
  157. SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersAddresses() sizing failed with error code %d, AdapterAddrsSize = %d\n", Err, AdapterAddrsSize);
  158. mtu = -1;
  159. goto cleanup;
  160. }
  161. }
  162. if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
  163. SCTPDBG(SCTP_DEBUG_USR, "Memory allocation error!\n");
  164. mtu = -1;
  165. goto cleanup;
  166. }
  167. if ((Err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) {
  168. SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersAddresses() failed with error code %d\n", Err);
  169. mtu = -1;
  170. goto cleanup;
  171. }
  172. for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) {
  173. if (pAdapt->IfIndex == if_index) {
  174. mtu = pAdapt->Mtu;
  175. break;
  176. }
  177. }
  178. cleanup:
  179. if (pAdapterAddrs != NULL) {
  180. GlobalFree(pAdapterAddrs);
  181. }
  182. #endif
  183. }
  184. return (mtu);
  185. }
  186. void
  187. getwintimeofday(struct timeval *tv)
  188. {
  189. FILETIME filetime;
  190. ULARGE_INTEGER ularge;
  191. GetSystemTimeAsFileTime(&filetime);
  192. ularge.LowPart = filetime.dwLowDateTime;
  193. ularge.HighPart = filetime.dwHighDateTime;
  194. /* Change base from Jan 1 1601 00:00:00 to Jan 1 1970 00:00:00 */
  195. #if defined(__MINGW32__)
  196. ularge.QuadPart -= 116444736000000000ULL;
  197. #else
  198. ularge.QuadPart -= 116444736000000000UI64;
  199. #endif
  200. /*
  201. * ularge.QuadPart is now the number of 100-nanosecond intervals
  202. * since Jan 1 1970 00:00:00.
  203. */
  204. #if defined(__MINGW32__)
  205. tv->tv_sec = (long)(ularge.QuadPart / 10000000ULL);
  206. tv->tv_usec = (long)((ularge.QuadPart % 10000000ULL) / 10ULL);
  207. #else
  208. tv->tv_sec = (long)(ularge.QuadPart / 10000000UI64);
  209. tv->tv_usec = (long)((ularge.QuadPart % 10000000UI64) / 10UI64);
  210. #endif
  211. }
  212. int
  213. win_if_nametoindex(const char *ifname)
  214. {
  215. IP_ADAPTER_ADDRESSES *addresses, *addr;
  216. ULONG status, size;
  217. int index = 0;
  218. if (!ifname) {
  219. return 0;
  220. }
  221. size = 0;
  222. status = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size);
  223. if (status != ERROR_BUFFER_OVERFLOW) {
  224. return 0;
  225. }
  226. addresses = malloc(size);
  227. status = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, addresses, &size);
  228. if (status == ERROR_SUCCESS) {
  229. for (addr = addresses; addr; addr = addr->Next) {
  230. if (addr->AdapterName && !strcmp(ifname, addr->AdapterName)) {
  231. index = addr->IfIndex;
  232. break;
  233. }
  234. }
  235. }
  236. free(addresses);
  237. return index;
  238. }
  239. #if WINVER < 0x0600
  240. /* These functions are written based on the code at
  241. * http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
  242. * Therefore, for the rest of the file the following applies:
  243. *
  244. *
  245. * Copyright and Licensing Information for ACE(TM), TAO(TM), CIAO(TM),
  246. * DAnCE(TM), and CoSMIC(TM)
  247. *
  248. * [1]ACE(TM), [2]TAO(TM), [3]CIAO(TM), DAnCE(TM), and [4]CoSMIC(TM)
  249. * (henceforth referred to as "DOC software") are copyrighted by
  250. * [5]Douglas C. Schmidt and his [6]research group at [7]Washington
  251. * University, [8]University of California, Irvine, and [9]Vanderbilt
  252. * University, Copyright (c) 1993-2012, all rights reserved. Since DOC
  253. * software is open-source, freely available software, you are free to
  254. * use, modify, copy, and distribute--perpetually and irrevocably--the
  255. * DOC software source code and object code produced from the source, as
  256. * well as copy and distribute modified versions of this software. You
  257. * must, however, include this copyright statement along with any code
  258. * built using DOC software that you release. No copyright statement
  259. * needs to be provided if you just ship binary executables of your
  260. * software products.
  261. *
  262. * You can use DOC software in commercial and/or binary software releases
  263. * and are under no obligation to redistribute any of your source code
  264. * that is built using DOC software. Note, however, that you may not
  265. * misappropriate the DOC software code, such as copyrighting it yourself
  266. * or claiming authorship of the DOC software code, in a way that will
  267. * prevent DOC software from being distributed freely using an
  268. * open-source development model. You needn't inform anyone that you're
  269. * using DOC software in your software, though we encourage you to let
  270. * [10]us know so we can promote your project in the [11]DOC software
  271. * success stories.
  272. *
  273. * The [12]ACE, [13]TAO, [14]CIAO, [15]DAnCE, and [16]CoSMIC web sites
  274. * are maintained by the [17]DOC Group at the [18]Institute for Software
  275. * Integrated Systems (ISIS) and the [19]Center for Distributed Object
  276. * Computing of Washington University, St. Louis for the development of
  277. * open-source software as part of the open-source software community.
  278. * Submissions are provided by the submitter ``as is'' with no warranties
  279. * whatsoever, including any warranty of merchantability, noninfringement
  280. * of third party intellectual property, or fitness for any particular
  281. * purpose. In no event shall the submitter be liable for any direct,
  282. * indirect, special, exemplary, punitive, or consequential damages,
  283. * including without limitation, lost profits, even if advised of the
  284. * possibility of such damages. Likewise, DOC software is provided as is
  285. * with no warranties of any kind, including the warranties of design,
  286. * merchantability, and fitness for a particular purpose,
  287. * noninfringement, or arising from a course of dealing, usage or trade
  288. * practice. Washington University, UC Irvine, Vanderbilt University,
  289. * their employees, and students shall have no liability with respect to
  290. * the infringement of copyrights, trade secrets or any patents by DOC
  291. * software or any part thereof. Moreover, in no event will Washington
  292. * University, UC Irvine, or Vanderbilt University, their employees, or
  293. * students be liable for any lost revenue or profits or other special,
  294. * indirect and consequential damages.
  295. *
  296. * DOC software is provided with no support and without any obligation on
  297. * the part of Washington University, UC Irvine, Vanderbilt University,
  298. * their employees, or students to assist in its use, correction,
  299. * modification, or enhancement. A [20]number of companies around the
  300. * world provide commercial support for DOC software, however. DOC
  301. * software is Y2K-compliant, as long as the underlying OS platform is
  302. * Y2K-compliant. Likewise, DOC software is compliant with the new US
  303. * daylight savings rule passed by Congress as "The Energy Policy Act of
  304. * 2005," which established new daylight savings times (DST) rules for
  305. * the United States that expand DST as of March 2007. Since DOC software
  306. * obtains time/date and calendaring information from operating systems
  307. * users will not be affected by the new DST rules as long as they
  308. * upgrade their operating systems accordingly.
  309. *
  310. * The names ACE(TM), TAO(TM), CIAO(TM), DAnCE(TM), CoSMIC(TM),
  311. * Washington University, UC Irvine, and Vanderbilt University, may not
  312. * be used to endorse or promote products or services derived from this
  313. * source without express written permission from Washington University,
  314. * UC Irvine, or Vanderbilt University. This license grants no permission
  315. * to call products or services derived from this source ACE(TM),
  316. * TAO(TM), CIAO(TM), DAnCE(TM), or CoSMIC(TM), nor does it grant
  317. * permission for the name Washington University, UC Irvine, or
  318. * Vanderbilt University to appear in their names.
  319. *
  320. * If you have any suggestions, additions, comments, or questions, please
  321. * let [21]me know.
  322. *
  323. * [22]Douglas C. Schmidt
  324. *
  325. * References
  326. *
  327. * 1. http://www.cs.wustl.edu/~schmidt/ACE.html
  328. * 2. http://www.cs.wustl.edu/~schmidt/TAO.html
  329. * 3. http://www.dre.vanderbilt.edu/CIAO/
  330. * 4. http://www.dre.vanderbilt.edu/cosmic/
  331. * 5. http://www.dre.vanderbilt.edu/~schmidt/
  332. * 6. http://www.cs.wustl.edu/~schmidt/ACE-members.html
  333. * 7. http://www.wustl.edu/
  334. * 8. http://www.uci.edu/
  335. * 9. http://www.vanderbilt.edu/
  336. * 10. mailto:doc_group@cs.wustl.edu
  337. * 11. http://www.cs.wustl.edu/~schmidt/ACE-users.html
  338. * 12. http://www.cs.wustl.edu/~schmidt/ACE.html
  339. * 13. http://www.cs.wustl.edu/~schmidt/TAO.html
  340. * 14. http://www.dre.vanderbilt.edu/CIAO/
  341. * 15. http://www.dre.vanderbilt.edu/~schmidt/DOC_ROOT/DAnCE/
  342. * 16. http://www.dre.vanderbilt.edu/cosmic/
  343. * 17. http://www.dre.vanderbilt.edu/
  344. * 18. http://www.isis.vanderbilt.edu/
  345. * 19. http://www.cs.wustl.edu/~schmidt/doc-center.html
  346. * 20. http://www.cs.wustl.edu/~schmidt/commercial-support.html
  347. * 21. mailto:d.schmidt@vanderbilt.edu
  348. * 22. http://www.dre.vanderbilt.edu/~schmidt/
  349. * 23. http://www.cs.wustl.edu/ACE.html
  350. */
  351. void
  352. InitializeXPConditionVariable(userland_cond_t *cv)
  353. {
  354. cv->waiters_count = 0;
  355. InitializeCriticalSection(&(cv->waiters_count_lock));
  356. cv->events_[C_SIGNAL] = CreateEvent (NULL, FALSE, FALSE, NULL);
  357. cv->events_[C_BROADCAST] = CreateEvent (NULL, TRUE, FALSE, NULL);
  358. }
  359. void
  360. DeleteXPConditionVariable(userland_cond_t *cv)
  361. {
  362. CloseHandle(cv->events_[C_BROADCAST]);
  363. CloseHandle(cv->events_[C_SIGNAL]);
  364. DeleteCriticalSection(&(cv->waiters_count_lock));
  365. }
  366. int
  367. SleepXPConditionVariable(userland_cond_t *cv, userland_mutex_t *mtx)
  368. {
  369. int result, last_waiter;
  370. EnterCriticalSection(&cv->waiters_count_lock);
  371. cv->waiters_count++;
  372. LeaveCriticalSection(&cv->waiters_count_lock);
  373. LeaveCriticalSection (mtx);
  374. result = WaitForMultipleObjects(2, cv->events_, FALSE, INFINITE);
  375. if (result==-1) {
  376. result = GetLastError();
  377. }
  378. EnterCriticalSection(&cv->waiters_count_lock);
  379. cv->waiters_count--;
  380. last_waiter = result == (C_SIGNAL + C_BROADCAST && (cv->waiters_count == 0));
  381. LeaveCriticalSection(&cv->waiters_count_lock);
  382. if (last_waiter)
  383. ResetEvent(cv->events_[C_BROADCAST]);
  384. EnterCriticalSection (mtx);
  385. return result;
  386. }
  387. void
  388. WakeAllXPConditionVariable(userland_cond_t *cv)
  389. {
  390. int have_waiters;
  391. EnterCriticalSection(&cv->waiters_count_lock);
  392. have_waiters = cv->waiters_count > 0;
  393. LeaveCriticalSection(&cv->waiters_count_lock);
  394. if (have_waiters)
  395. SetEvent (cv->events_[C_BROADCAST]);
  396. }
  397. #endif
  398. #endif