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