Coverage Report

Created: 2025-07-12 06:07

/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