sctp_os_userspace.h (33397B)
1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2006-2007, by Cisco Systems, Inc. All rights reserved. 5 * Copyright (c) 2008-2011, by Randall Stewart. All rights reserved. 6 * Copyright (c) 2008-2011, by Michael Tuexen. All rights reserved. 7 * Copyright (c) 2008-2011, by Brad Penoff. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions are met: 11 * 12 * a) Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * b) Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the distribution. 18 * 19 * c) Neither the name of Cisco Systems, Inc. nor the names of its 20 * contributors may be used to endorse or promote products derived 21 * from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 33 * THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #ifndef __sctp_os_userspace_h__ 37 #define __sctp_os_userspace_h__ 38 /* 39 * Userspace includes 40 * All the opt_xxx.h files are placed in the kernel build directory. 41 * We will place them in userspace stack build directory. 42 */ 43 44 #include <errno.h> 45 46 #if defined(_WIN32) 47 #include <winsock2.h> 48 #include <ws2tcpip.h> 49 #include <iphlpapi.h> 50 #include <mswsock.h> 51 #include <windows.h> 52 #include "user_environment.h" 53 typedef CRITICAL_SECTION userland_mutex_t; 54 #if WINVER < 0x0600 55 typedef CRITICAL_SECTION userland_rwlock_t; 56 enum { 57 C_SIGNAL = 0, 58 C_BROADCAST = 1, 59 C_MAX_EVENTS = 2 60 }; 61 typedef struct 62 { 63 u_int waiters_count; 64 CRITICAL_SECTION waiters_count_lock; 65 HANDLE events_[C_MAX_EVENTS]; 66 } userland_cond_t; 67 void InitializeXPConditionVariable(userland_cond_t *); 68 void DeleteXPConditionVariable(userland_cond_t *); 69 int SleepXPConditionVariable(userland_cond_t *, userland_mutex_t *); 70 void WakeAllXPConditionVariable(userland_cond_t *); 71 #define InitializeConditionVariable(cond) InitializeXPConditionVariable(cond) 72 #define DeleteConditionVariable(cond) DeleteXPConditionVariable(cond) 73 #define SleepConditionVariableCS(cond, mtx, time) SleepXPConditionVariable(cond, mtx) 74 #define WakeAllConditionVariable(cond) WakeAllXPConditionVariable(cond) 75 #else 76 typedef SRWLOCK userland_rwlock_t; 77 #define DeleteConditionVariable(cond) 78 typedef CONDITION_VARIABLE userland_cond_t; 79 #endif 80 typedef HANDLE userland_thread_t; 81 #define ADDRESS_FAMILY unsigned __int8 82 #define IPVERSION 4 83 #define MAXTTL 255 84 /* VS2010 comes with stdint.h */ 85 #if !defined(_MSC_VER) || (_MSC_VER >= 1600) 86 #include <stdint.h> 87 #else 88 typedef unsigned __int64 uint64_t; 89 typedef unsigned __int32 uint32_t; 90 typedef __int32 int32_t; 91 typedef unsigned __int16 uint16_t; 92 typedef __int16 int16_t; 93 typedef unsigned __int8 uint8_t; 94 typedef __int8 int8_t; 95 #endif 96 #ifndef _SIZE_T_DEFINED 97 #typedef __int32 size_t; 98 #endif 99 typedef unsigned __int32 u_int; 100 typedef unsigned char u_char; 101 typedef unsigned __int16 u_short; 102 typedef unsigned __int8 sa_family_t; 103 #ifndef _SSIZE_T_DEFINED 104 typedef __int64 ssize_t; 105 #endif 106 #if !defined(__MINGW32__) 107 #define __func__ __FUNCTION__ 108 #endif 109 #ifndef EWOULDBLOCK 110 #define EWOULDBLOCK WSAEWOULDBLOCK 111 #endif 112 #ifndef EINPROGRESS 113 #define EINPROGRESS WSAEINPROGRESS 114 #endif 115 #ifndef EALREADY 116 #define EALREADY WSAEALREADY 117 #endif 118 #ifndef ENOTSOCK 119 #define ENOTSOCK WSAENOTSOCK 120 #endif 121 #ifndef EDESTADDRREQ 122 #define EDESTADDRREQ WSAEDESTADDRREQ 123 #endif 124 #ifndef EMSGSIZE 125 #define EMSGSIZE WSAEMSGSIZE 126 #endif 127 #ifndef EPROTOTYPE 128 #define EPROTOTYPE WSAEPROTOTYPE 129 #endif 130 #ifndef ENOPROTOOPT 131 #define ENOPROTOOPT WSAENOPROTOOPT 132 #endif 133 #ifndef EPROTONOSUPPORT 134 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT 135 #endif 136 #ifndef ESOCKTNOSUPPORT 137 #define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT 138 #endif 139 #ifndef EOPNOTSUPP 140 #define EOPNOTSUPP WSAEOPNOTSUPP 141 #endif 142 #ifndef ENOTSUP 143 #define ENOTSUP WSAEOPNOTSUPP 144 #endif 145 #ifndef EPFNOSUPPORT 146 #define EPFNOSUPPORT WSAEPFNOSUPPORT 147 #endif 148 #ifndef EAFNOSUPPORT 149 #define EAFNOSUPPORT WSAEAFNOSUPPORT 150 #endif 151 #ifndef EADDRINUSE 152 #define EADDRINUSE WSAEADDRINUSE 153 #endif 154 #ifndef EADDRNOTAVAIL 155 #define EADDRNOTAVAIL WSAEADDRNOTAVAIL 156 #endif 157 #ifndef ENETDOWN 158 #define ENETDOWN WSAENETDOWN 159 #endif 160 #ifndef ENETUNREACH 161 #define ENETUNREACH WSAENETUNREACH 162 #endif 163 #ifndef ENETRESET 164 #define ENETRESET WSAENETRESET 165 #endif 166 #ifndef ECONNABORTED 167 #define ECONNABORTED WSAECONNABORTED 168 #endif 169 #ifndef ECONNRESET 170 #define ECONNRESET WSAECONNRESET 171 #endif 172 #ifndef ENOBUFS 173 #define ENOBUFS WSAENOBUFS 174 #endif 175 #ifndef EISCONN 176 #define EISCONN WSAEISCONN 177 #endif 178 #ifndef ENOTCONN 179 #define ENOTCONN WSAENOTCONN 180 #endif 181 #ifndef ESHUTDOWN 182 #define ESHUTDOWN WSAESHUTDOWN 183 #endif 184 #ifndef ETOOMANYREFS 185 #define ETOOMANYREFS WSAETOOMANYREFS 186 #endif 187 #ifndef ETIMEDOUT 188 #define ETIMEDOUT WSAETIMEDOUT 189 #endif 190 #ifndef ECONNREFUSED 191 #define ECONNREFUSED WSAECONNREFUSED 192 #endif 193 #ifndef ELOOP 194 #define ELOOP WSAELOOP 195 #endif 196 #ifndef EHOSTDOWN 197 #define EHOSTDOWN WSAEHOSTDOWN 198 #endif 199 #ifndef EHOSTUNREACH 200 #define EHOSTUNREACH WSAEHOSTUNREACH 201 #endif 202 #ifndef EPROCLIM 203 #define EPROCLIM WSAEPROCLIM 204 #endif 205 #ifndef EUSERS 206 #define EUSERS WSAEUSERS 207 #endif 208 #ifndef EDQUOT 209 #define EDQUOT WSAEDQUOT 210 #endif 211 #ifndef ESTALE 212 #define ESTALE WSAESTALE 213 #endif 214 #ifndef EREMOTE 215 #define EREMOTE WSAEREMOTE 216 #endif 217 218 typedef char* caddr_t; 219 220 #define bzero(buf, len) memset(buf, 0, len) 221 #define bcopy(srcKey, dstKey, len) memcpy(dstKey, srcKey, len) 222 223 #if defined(_MSC_VER) && (_MSC_VER < 1900) && !defined(__MINGW32__) 224 #define SCTP_SNPRINTF(data, size, format, ...) \ 225 if (_snprintf_s(data, size, _TRUNCATE, format, __VA_ARGS__) < 0) { \ 226 data[0] = '\0'; \ 227 } 228 #else 229 #define SCTP_SNPRINTF(data, ...) \ 230 if (snprintf(data, __VA_ARGS__) < 0 ) { \ 231 data[0] = '\0'; \ 232 } 233 #endif 234 235 #define inline __inline 236 #define __inline__ __inline 237 #define MSG_EOR 0x8 /* data completes record */ 238 #define MSG_DONTWAIT 0x80 /* this message should be nonblocking */ 239 240 #ifdef CMSG_DATA 241 #undef CMSG_DATA 242 #endif 243 /* 244 * The following definitions should apply iff WINVER < 0x0600 245 * but that check doesn't work in all cases. So be more pedantic... 246 */ 247 #define CMSG_DATA(x) WSA_CMSG_DATA(x) 248 #define CMSG_ALIGN(x) WSA_CMSGDATA_ALIGN(x) 249 #ifndef CMSG_FIRSTHDR 250 #define CMSG_FIRSTHDR(x) WSA_CMSG_FIRSTHDR(x) 251 #endif 252 #ifndef CMSG_NXTHDR 253 #define CMSG_NXTHDR(x, y) WSA_CMSG_NXTHDR(x, y) 254 #endif 255 #ifndef CMSG_SPACE 256 #define CMSG_SPACE(x) WSA_CMSG_SPACE(x) 257 #endif 258 #ifndef CMSG_LEN 259 #define CMSG_LEN(x) WSA_CMSG_LEN(x) 260 #endif 261 262 /**** from sctp_os_windows.h ***************/ 263 #define SCTP_IFN_IS_IFT_LOOP(ifn) ((ifn)->ifn_type == IFT_LOOP) 264 #define SCTP_ROUTE_IS_REAL_LOOP(ro) ((ro)->ro_rt && (ro)->ro_rt->rt_ifa && (ro)->ro_rt->rt_ifa->ifa_ifp && (ro)->ro_rt->rt_ifa->ifa_ifp->if_type == IFT_LOOP) 265 266 /* 267 * Access to IFN's to help with src-addr-selection 268 */ 269 /* This could return VOID if the index works but for BSD we provide both. */ 270 #define SCTP_GET_IFN_VOID_FROM_ROUTE(ro) \ 271 ((ro)->ro_rt != NULL ? (ro)->ro_rt->rt_ifp : NULL) 272 #define SCTP_ROUTE_HAS_VALID_IFN(ro) \ 273 ((ro)->ro_rt && (ro)->ro_rt->rt_ifp) 274 /******************************************/ 275 276 #define SCTP_GET_IF_INDEX_FROM_ROUTE(ro) 1 /* compiles... TODO use routing socket to determine */ 277 278 #define BIG_ENDIAN 1 279 #define LITTLE_ENDIAN 0 280 #ifdef WORDS_BIGENDIAN 281 #define BYTE_ORDER BIG_ENDIAN 282 #else 283 #define BYTE_ORDER LITTLE_ENDIAN 284 #endif 285 286 #else /* !defined(Userspace_os_Windows) */ 287 #include <sys/socket.h> 288 289 #if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__) 290 #error "Unsupported build configuration." 291 #endif 292 293 #include <pthread.h> 294 295 typedef pthread_mutex_t userland_mutex_t; 296 typedef pthread_rwlock_t userland_rwlock_t; 297 typedef pthread_cond_t userland_cond_t; 298 typedef pthread_t userland_thread_t; 299 #endif 300 301 #if defined(_WIN32) || defined(__native_client__) 302 303 #define IFNAMSIZ 64 304 305 #define random() rand() 306 #define srandom(s) srand(s) 307 308 #define timeradd(tvp, uvp, vvp) \ 309 do { \ 310 (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ 311 (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ 312 if ((vvp)->tv_usec >= 1000000) { \ 313 (vvp)->tv_sec++; \ 314 (vvp)->tv_usec -= 1000000; \ 315 } \ 316 } while (0) 317 318 #define timersub(tvp, uvp, vvp) \ 319 do { \ 320 (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ 321 (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ 322 if ((vvp)->tv_usec < 0) { \ 323 (vvp)->tv_sec--; \ 324 (vvp)->tv_usec += 1000000; \ 325 } \ 326 } while (0) 327 328 /*#include <packon.h> 329 #pragma pack(push, 1)*/ 330 struct ip { 331 u_char ip_hl:4, ip_v:4; 332 u_char ip_tos; 333 u_short ip_len; 334 u_short ip_id; 335 u_short ip_off; 336 #define IP_RP 0x8000 337 #define IP_DF 0x4000 338 #define IP_MF 0x2000 339 #define IP_OFFMASK 0x1fff 340 u_char ip_ttl; 341 u_char ip_p; 342 u_short ip_sum; 343 struct in_addr ip_src, ip_dst; 344 }; 345 346 struct ifaddrs { 347 struct ifaddrs *ifa_next; 348 char *ifa_name; 349 unsigned int ifa_flags; 350 struct sockaddr *ifa_addr; 351 struct sockaddr *ifa_netmask; 352 struct sockaddr *ifa_dstaddr; 353 void *ifa_data; 354 }; 355 356 struct udphdr { 357 uint16_t uh_sport; 358 uint16_t uh_dport; 359 uint16_t uh_ulen; 360 uint16_t uh_sum; 361 }; 362 363 struct iovec { 364 size_t len; 365 char *buf; 366 }; 367 368 #define iov_base buf 369 #define iov_len len 370 371 struct ifa_msghdr { 372 uint16_t ifam_msglen; 373 unsigned char ifam_version; 374 unsigned char ifam_type; 375 uint32_t ifam_addrs; 376 uint32_t ifam_flags; 377 uint16_t ifam_index; 378 uint32_t ifam_metric; 379 }; 380 381 struct ifdevmtu { 382 int ifdm_current; 383 int ifdm_min; 384 int ifdm_max; 385 }; 386 387 struct ifkpi { 388 unsigned int ifk_module_id; 389 unsigned int ifk_type; 390 union { 391 void *ifk_ptr; 392 int ifk_value; 393 } ifk_data; 394 }; 395 #endif 396 397 #if defined(_WIN32) 398 int Win_getifaddrs(struct ifaddrs**); 399 #define getifaddrs(interfaces) (int)Win_getifaddrs(interfaces) 400 int win_if_nametoindex(const char *); 401 #define if_nametoindex(x) win_if_nametoindex(x) 402 #endif 403 404 #define mtx_lock(arg1) 405 #define mtx_unlock(arg1) 406 #define mtx_assert(arg1,arg2) 407 #define MA_OWNED 7 /* sys/mutex.h typically on FreeBSD */ 408 #if !defined(__FreeBSD__) 409 struct mtx {int dummy;}; 410 #if !defined(__NetBSD__) 411 struct selinfo {int dummy;}; 412 #endif 413 struct sx {int dummy;}; 414 #endif 415 416 #include <stdio.h> 417 #include <string.h> 418 #include <stdbool.h> 419 /* #include <sys/param.h> in FreeBSD defines MSIZE */ 420 /* #include <sys/ktr.h> */ 421 /* #include <sys/systm.h> */ 422 #if defined(HAVE_SYS_QUEUE_H) 423 #include <sys/queue.h> 424 #else 425 #include <user_queue.h> 426 #endif 427 #include <user_malloc.h> 428 /* #include <sys/kernel.h> */ 429 /* #include <sys/sysctl.h> */ 430 /* #include <sys/protosw.h> */ 431 /* on FreeBSD, this results in a redefintion of SOCK(BUF)_(UN)LOCK and 432 * uknown type of struct mtx for sb_mtx in struct sockbuf */ 433 #include "user_socketvar.h" /* MALLOC_DECLARE's M_PCB. Replacement for sys/socketvar.h */ 434 /* #include <sys/jail.h> */ 435 /* #include <sys/sysctl.h> */ 436 #include <user_environment.h> 437 #include <user_atomic.h> 438 #include <user_mbuf.h> 439 /* #include <sys/uio.h> */ 440 /* #include <sys/lock.h> */ 441 #if defined(__FreeBSD__) && !defined(__Userspace__) 442 #include <sys/rwlock.h> 443 #endif 444 /* #include <sys/kthread.h> */ 445 #if defined(__FreeBSD__) && !defined(__Userspace__) 446 #include <sys/priv.h> 447 #endif 448 /* #include <sys/random.h> */ 449 #include <limits.h> 450 /* #include <machine/cpu.h> */ 451 452 #if defined(__APPLE__) 453 /* was a 0 byte file. needed for structs if_data(64) and net_event_data */ 454 #include <net/if_var.h> 455 #endif 456 #if defined(__FreeBSD__) 457 #include <net/if_types.h> 458 /* #include <net/if_var.h> was a 0 byte file. causes struct mtx redefinition */ 459 #endif 460 /* OOTB only - dummy route used at the moment. should we port route to 461 * userspace as well? */ 462 /* on FreeBSD, this results in a redefintion of struct route */ 463 /* #include <net/route.h> */ 464 #if !defined(_WIN32) && !defined(__native_client__) 465 #include <net/if.h> 466 #include <netinet/in.h> 467 #include <netinet/in_systm.h> 468 #include <netinet/ip.h> 469 #endif 470 #if defined(HAVE_NETINET_IP_ICMP_H) 471 #include <netinet/ip_icmp.h> 472 #else 473 #include <user_ip_icmp.h> 474 #endif 475 /* #include <netinet/in_pcb.h> ported to userspace */ 476 #include <user_inpcb.h> 477 478 /* for getifaddrs */ 479 #include <sys/types.h> 480 #if !defined(_WIN32) 481 #if defined(INET) || defined(INET6) 482 #include <ifaddrs.h> 483 #endif 484 485 /* for ioctl */ 486 #include <sys/ioctl.h> 487 488 /* for close, etc. */ 489 #include <unistd.h> 490 /* for gettimeofday */ 491 #include <sys/time.h> 492 #endif 493 494 /* lots of errno's used and needed in userspace */ 495 496 /* for offsetof */ 497 #include <stddef.h> 498 499 #if defined(SCTP_PROCESS_LEVEL_LOCKS) && !defined(_WIN32) 500 /* for pthread_mutex_lock, pthread_mutex_unlock, etc. */ 501 #include <pthread.h> 502 #endif 503 504 #ifdef IPSEC 505 #include <netipsec/ipsec.h> 506 #include <netipsec/key.h> 507 #endif /* IPSEC */ 508 509 #ifdef INET6 510 #if defined(__FreeBSD__) 511 #include <sys/domain.h> 512 #endif 513 #ifdef IPSEC 514 #include <netipsec/ipsec6.h> 515 #endif 516 #if !defined(_WIN32) 517 #include <netinet/ip6.h> 518 #endif 519 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(_WIN32) || defined(__EMSCRIPTEN__) 520 #include "user_ip6_var.h" 521 #else 522 #include <netinet6/ip6_var.h> 523 #endif 524 #if defined(__FreeBSD__) 525 #include <netinet6/in6_pcb.h> 526 #include <netinet6/scope6_var.h> 527 #endif 528 #endif /* INET6 */ 529 530 #if defined(HAVE_SCTP_PEELOFF_SOCKOPT) 531 #include <sys/file.h> 532 #include <sys/filedesc.h> 533 #endif 534 535 #include "netinet/sctp_sha1.h" 536 537 #if defined(__FreeBSD__) && !defined(__Userspace__) 538 #include <netinet/ip_options.h> 539 #endif 540 541 #define SCTP_PRINTF(...) \ 542 if (SCTP_BASE_VAR(debug_printf)) { \ 543 SCTP_BASE_VAR(debug_printf)(__VA_ARGS__); \ 544 } 545 546 /* Declare all the malloc names for all the various mallocs */ 547 MALLOC_DECLARE(SCTP_M_MAP); 548 MALLOC_DECLARE(SCTP_M_STRMI); 549 MALLOC_DECLARE(SCTP_M_STRMO); 550 MALLOC_DECLARE(SCTP_M_ASC_ADDR); 551 MALLOC_DECLARE(SCTP_M_ASC_IT); 552 MALLOC_DECLARE(SCTP_M_AUTH_CL); 553 MALLOC_DECLARE(SCTP_M_AUTH_KY); 554 MALLOC_DECLARE(SCTP_M_AUTH_HL); 555 MALLOC_DECLARE(SCTP_M_AUTH_IF); 556 MALLOC_DECLARE(SCTP_M_STRESET); 557 MALLOC_DECLARE(SCTP_M_CMSG); 558 MALLOC_DECLARE(SCTP_M_COPYAL); 559 MALLOC_DECLARE(SCTP_M_VRF); 560 MALLOC_DECLARE(SCTP_M_IFA); 561 MALLOC_DECLARE(SCTP_M_IFN); 562 MALLOC_DECLARE(SCTP_M_TIMW); 563 MALLOC_DECLARE(SCTP_M_MVRF); 564 MALLOC_DECLARE(SCTP_M_ITER); 565 MALLOC_DECLARE(SCTP_M_SOCKOPT); 566 567 #if defined(SCTP_LOCAL_TRACE_BUF) 568 569 #define SCTP_GET_CYCLECOUNT get_cyclecount() 570 #define SCTP_CTR6 sctp_log_trace 571 572 #else 573 #define SCTP_CTR6 CTR6 574 #endif 575 576 /* Empty ktr statement for _Userspace__ (similar to what is done for mac) */ 577 #define CTR6(m, d, p1, p2, p3, p4, p5, p6) 578 579 580 581 #define SCTP_BASE_INFO(__m) system_base_info.sctppcbinfo.__m 582 #define SCTP_BASE_STATS system_base_info.sctpstat 583 #define SCTP_BASE_STAT(__m) system_base_info.sctpstat.__m 584 #define SCTP_BASE_SYSCTL(__m) system_base_info.sctpsysctl.__m 585 #define SCTP_BASE_VAR(__m) system_base_info.__m 586 587 /* 588 * 589 */ 590 #if !defined(__APPLE__) 591 #define USER_ADDR_NULL (NULL) /* FIX ME: temp */ 592 #endif 593 594 #include <netinet/sctp_constants.h> 595 #if defined(SCTP_DEBUG) 596 #define SCTPDBG(level, ...) \ 597 { \ 598 do { \ 599 if (SCTP_BASE_SYSCTL(sctp_debug_on) & level) { \ 600 SCTP_PRINTF(__VA_ARGS__); \ 601 } \ 602 } while (0); \ 603 } 604 #define SCTPDBG_ADDR(level, addr) \ 605 { \ 606 do { \ 607 if (SCTP_BASE_SYSCTL(sctp_debug_on) & level ) { \ 608 sctp_print_address(addr); \ 609 } \ 610 } while (0); \ 611 } 612 #else 613 #define SCTPDBG(level, ...) 614 #define SCTPDBG_ADDR(level, addr) 615 #endif 616 617 #ifdef SCTP_LTRACE_CHUNKS 618 #define SCTP_LTRACE_CHK(a, b, c, d) if(sctp_logging_level & SCTP_LTRACE_CHUNK_ENABLE) CTR6(KTR_SUBSYS, "SCTP:%d[%d]:%x-%x-%x-%x", SCTP_LOG_CHUNK_PROC, 0, a, b, c, d) 619 #else 620 #define SCTP_LTRACE_CHK(a, b, c, d) 621 #endif 622 623 #ifdef SCTP_LTRACE_ERRORS 624 #define SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, file, err) \ 625 if (sctp_logging_level & SCTP_LTRACE_ERROR_ENABLE) \ 626 SCTP_PRINTF("mbuf:%p inp:%p stcb:%p net:%p file:%x line:%d error:%d\n", \ 627 (void *)m, (void *)inp, (void *)stcb, (void *)net, file, __LINE__, err); 628 #define SCTP_LTRACE_ERR_RET(inp, stcb, net, file, err) \ 629 if (sctp_logging_level & SCTP_LTRACE_ERROR_ENABLE) \ 630 SCTP_PRINTF("inp:%p stcb:%p net:%p file:%x line:%d error:%d\n", \ 631 (void *)inp, (void *)stcb, (void *)net, file, __LINE__, err); 632 #else 633 #define SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, file, err) 634 #define SCTP_LTRACE_ERR_RET(inp, stcb, net, file, err) 635 #endif 636 637 638 /* 639 * Local address and interface list handling 640 */ 641 #define SCTP_MAX_VRF_ID 0 642 #define SCTP_SIZE_OF_VRF_HASH 3 643 #define SCTP_IFNAMSIZ IFNAMSIZ 644 #define SCTP_DEFAULT_VRFID 0 645 #define SCTP_VRF_ADDR_HASH_SIZE 16 646 #define SCTP_VRF_IFN_HASH_SIZE 3 647 #define SCTP_INIT_VRF_TABLEID(vrf) 648 649 #if !defined(_WIN32) 650 #define SCTP_IFN_IS_IFT_LOOP(ifn) (strncmp((ifn)->ifn_name, "lo", 2) == 0) 651 /* BSD definition */ 652 /* #define SCTP_ROUTE_IS_REAL_LOOP(ro) ((ro)->ro_rt && (ro)->ro_rt->rt_ifa && (ro)->ro_rt->rt_ifa->ifa_ifp && (ro)->ro_rt->rt_ifa->ifa_ifp->if_type == IFT_LOOP) */ 653 /* only used in IPv6 scenario, which isn't supported yet */ 654 #define SCTP_ROUTE_IS_REAL_LOOP(ro) 0 655 656 /* 657 * Access to IFN's to help with src-addr-selection 658 */ 659 /* This could return VOID if the index works but for BSD we provide both. */ 660 #define SCTP_GET_IFN_VOID_FROM_ROUTE(ro) (void *)ro->ro_rt->rt_ifp 661 #define SCTP_GET_IF_INDEX_FROM_ROUTE(ro) 1 /* compiles... TODO use routing socket to determine */ 662 #define SCTP_ROUTE_HAS_VALID_IFN(ro) ((ro)->ro_rt && (ro)->ro_rt->rt_ifp) 663 #endif 664 665 /* 666 * general memory allocation 667 */ 668 #define SCTP_MALLOC(var, type, size, name) \ 669 do { \ 670 MALLOC(var, type, size, name, M_NOWAIT); \ 671 } while (0) 672 673 #define SCTP_FREE(var, type) FREE(var, type) 674 675 #define SCTP_MALLOC_SONAME(var, type, size) \ 676 do { \ 677 MALLOC(var, type, size, M_SONAME, (M_WAITOK | M_ZERO)); \ 678 } while (0) 679 680 #define SCTP_FREE_SONAME(var) FREE(var, M_SONAME) 681 682 #define SCTP_PROCESS_STRUCT struct proc * 683 684 /* 685 * zone allocation functions 686 */ 687 688 689 #if defined(SCTP_SIMPLE_ALLOCATOR) 690 /*typedef size_t sctp_zone_t;*/ 691 #define SCTP_ZONE_INIT(zone, name, size, number) { \ 692 zone = size; \ 693 } 694 695 /* __Userspace__ SCTP_ZONE_GET: allocate element from the zone */ 696 #define SCTP_ZONE_GET(zone, type) \ 697 (type *)malloc(zone); 698 699 700 /* __Userspace__ SCTP_ZONE_FREE: free element from the zone */ 701 #define SCTP_ZONE_FREE(zone, element) { \ 702 free(element); \ 703 } 704 705 #define SCTP_ZONE_DESTROY(zone) 706 #else 707 /*__Userspace__ 708 Compiling & linking notes: Needs libumem, which has been placed in ./user_lib 709 All userspace header files are in ./user_include. Makefile will need the 710 following. 711 CFLAGS = -I./ -Wall 712 LDFLAGS = -L./user_lib -R./user_lib -lumem 713 */ 714 #include "user_include/umem.h" 715 716 /* __Userspace__ SCTP_ZONE_INIT: initialize the zone */ 717 /* 718 __Userspace__ 719 No equivalent function to uma_zone_set_max added yet. (See SCTP_ZONE_INIT in sctp_os_bsd.h 720 for reference). It may not be required as mentioned in 721 http://nixdoc.net/man-pages/FreeBSD/uma_zalloc.9.html that 722 max limits may not enforced on systems with more than one CPU. 723 */ 724 #define SCTP_ZONE_INIT(zone, name, size, number) { \ 725 zone = umem_cache_create(name, size, 0, NULL, NULL, NULL, NULL, NULL, 0); \ 726 } 727 728 /* __Userspace__ SCTP_ZONE_GET: allocate element from the zone */ 729 #define SCTP_ZONE_GET(zone, type) \ 730 (type *)umem_cache_alloc(zone, UMEM_DEFAULT); 731 732 733 /* __Userspace__ SCTP_ZONE_FREE: free element from the zone */ 734 #define SCTP_ZONE_FREE(zone, element) \ 735 umem_cache_free(zone, element); 736 737 738 /* __Userspace__ SCTP_ZONE_DESTROY: destroy the zone */ 739 #define SCTP_ZONE_DESTROY(zone) \ 740 umem_cache_destroy(zone); 741 #endif 742 743 /* 744 * __Userspace__ Defining sctp_hashinit_flags() and sctp_hashdestroy() for userland. 745 */ 746 void *sctp_hashinit_flags(int elements, struct malloc_type *type, 747 u_long *hashmask, int flags); 748 void 749 sctp_hashdestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask); 750 751 void 752 sctp_hashfreedestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask); 753 754 755 #define HASH_NOWAIT 0x00000001 756 #define HASH_WAITOK 0x00000002 757 758 /* M_PCB is MALLOC_DECLARE'd in sys/socketvar.h */ 759 #define SCTP_HASH_INIT(size, hashmark) sctp_hashinit_flags(size, M_PCB, hashmark, HASH_NOWAIT) 760 761 #define SCTP_HASH_FREE(table, hashmark) sctp_hashdestroy(table, M_PCB, hashmark) 762 763 #define SCTP_HASH_FREE_DESTROY(table, hashmark) sctp_hashfreedestroy(table, M_PCB, hashmark) 764 #define SCTP_M_COPYM m_copym 765 766 /* 767 * timers 768 */ 769 /* __Userspace__ 770 * user_sctp_callout.h has typedef struct sctp_callout sctp_os_timer_t; 771 * which is used in the timer related functions such as 772 * SCTP_OS_TIMER_INIT etc. 773 */ 774 #include <netinet/sctp_callout.h> 775 776 /* __Userspace__ Creating a receive thread */ 777 #include <user_recv_thread.h> 778 779 /*__Userspace__ defining KTR_SUBSYS 1 as done in sctp_os_macosx.h */ 780 #define KTR_SUBSYS 1 781 782 /* The packed define for 64 bit platforms */ 783 #if !defined(_WIN32) 784 #define SCTP_PACKED __attribute__((packed)) 785 #define SCTP_UNUSED __attribute__((unused)) 786 #else 787 #define SCTP_PACKED 788 #define SCTP_UNUSED 789 #endif 790 791 /* 792 * Functions 793 */ 794 /* Mbuf manipulation and access macros */ 795 #define SCTP_BUF_LEN(m) (m->m_len) 796 #define SCTP_BUF_NEXT(m) (m->m_next) 797 #define SCTP_BUF_NEXT_PKT(m) (m->m_nextpkt) 798 #define SCTP_BUF_RESV_UF(m, size) m->m_data += size 799 #define SCTP_BUF_AT(m, size) m->m_data + size 800 #define SCTP_BUF_IS_EXTENDED(m) (m->m_flags & M_EXT) 801 #define SCTP_BUF_EXTEND_SIZE(m) (m->m_ext.ext_size) 802 #define SCTP_BUF_TYPE(m) (m->m_type) 803 #define SCTP_BUF_RECVIF(m) (m->m_pkthdr.rcvif) 804 #define SCTP_BUF_PREPEND M_PREPEND 805 806 #define SCTP_ALIGN_TO_END(m, len) if(m->m_flags & M_PKTHDR) { \ 807 MH_ALIGN(m, len); \ 808 } else if ((m->m_flags & M_EXT) == 0) { \ 809 M_ALIGN(m, len); \ 810 } 811 812 #if !defined(_WIN32) 813 #define SCTP_SNPRINTF(data, ...) \ 814 if (snprintf(data, __VA_ARGS__) < 0) { \ 815 data[0] = '\0'; \ 816 } 817 #endif 818 819 /* We make it so if you have up to 4 threads 820 * writting based on the default size of 821 * the packet log 65 k, that would be 822 * 4 16k packets before we would hit 823 * a problem. 824 */ 825 #define SCTP_PKTLOG_WRITERS_NEED_LOCK 3 826 827 828 /* 829 * routes, output, etc. 830 */ 831 832 typedef struct sctp_route sctp_route_t; 833 typedef struct sctp_rtentry sctp_rtentry_t; 834 835 static inline void sctp_userspace_rtalloc(sctp_route_t *ro) 836 { 837 if (ro->ro_rt != NULL) { 838 ro->ro_rt->rt_refcnt++; 839 return; 840 } 841 842 ro->ro_rt = (sctp_rtentry_t *) malloc(sizeof(sctp_rtentry_t)); 843 if (ro->ro_rt == NULL) 844 return; 845 846 /* initialize */ 847 memset(ro->ro_rt, 0, sizeof(sctp_rtentry_t)); 848 ro->ro_rt->rt_refcnt = 1; 849 850 /* set MTU */ 851 /* TODO set this based on the ro->ro_dst, looking up MTU with routing socket */ 852 #if 0 853 if (userspace_rawroute == -1) { 854 userspace_rawroute = socket(AF_ROUTE, SOCK_RAW, 0); 855 if (userspace_rawroute == -1) 856 return; 857 } 858 #endif 859 ro->ro_rt->rt_rmx.rmx_mtu = 1500; /* FIXME temporary solution */ 860 861 /* TODO enable the ability to obtain interface index of route for 862 * SCTP_GET_IF_INDEX_FROM_ROUTE macro. 863 */ 864 } 865 #define SCTP_RTALLOC(ro, vrf_id, fibnum) sctp_userspace_rtalloc((sctp_route_t *)ro) 866 867 /* dummy rtfree needed once user_route.h is included */ 868 static inline void sctp_userspace_rtfree(sctp_rtentry_t *rt) 869 { 870 if(rt == NULL) { 871 return; 872 } 873 if(--rt->rt_refcnt > 0) { 874 return; 875 } 876 free(rt); 877 } 878 #define rtfree(arg1) sctp_userspace_rtfree(arg1) 879 880 881 /*************************/ 882 /* MTU */ 883 /*************************/ 884 int sctp_userspace_get_mtu_from_ifn(uint32_t if_index); 885 886 #define SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index) sctp_userspace_get_mtu_from_ifn(ifn_index) 887 888 #define SCTP_GATHER_MTU_FROM_ROUTE(sctp_ifa, sa, rt) ((rt != NULL) ? rt->rt_rmx.rmx_mtu : 0) 889 890 #define SCTP_SET_MTU_OF_ROUTE(sa, rt, mtu) do { \ 891 if (rt != NULL) \ 892 rt->rt_rmx.rmx_mtu = mtu; \ 893 } while(0) 894 895 896 /*************************/ 897 /* These are for logging */ 898 /*************************/ 899 /* return the base ext data pointer */ 900 #define SCTP_BUF_EXTEND_BASE(m) (m->m_ext.ext_buf) 901 /* return the refcnt of the data pointer */ 902 #define SCTP_BUF_EXTEND_REFCNT(m) (*m->m_ext.ref_cnt) 903 /* return any buffer related flags, this is 904 * used beyond logging for apple only. 905 */ 906 #define SCTP_BUF_GET_FLAGS(m) (m->m_flags) 907 908 /* For BSD this just accesses the M_PKTHDR length 909 * so it operates on an mbuf with hdr flag. Other 910 * O/S's may have seperate packet header and mbuf 911 * chain pointers.. thus the macro. 912 */ 913 #define SCTP_HEADER_TO_CHAIN(m) (m) 914 #define SCTP_DETACH_HEADER_FROM_CHAIN(m) 915 #define SCTP_HEADER_LEN(m) ((m)->m_pkthdr.len) 916 #define SCTP_GET_HEADER_FOR_OUTPUT(o_pak) 0 917 #define SCTP_RELEASE_HEADER(m) 918 #define SCTP_RELEASE_PKT(m) sctp_m_freem(m) 919 920 #define SCTP_GET_PKT_VRFID(m, vrf_id) ((vrf_id = SCTP_DEFAULT_VRFID) != SCTP_DEFAULT_VRFID) 921 922 923 924 /* Attach the chain of data into the sendable packet. */ 925 #define SCTP_ATTACH_CHAIN(pak, m, packet_length) do { \ 926 pak = m; \ 927 pak->m_pkthdr.len = packet_length; \ 928 } while(0) 929 930 /* Other m_pkthdr type things */ 931 /* FIXME need real definitions */ 932 #define SCTP_IS_IT_BROADCAST(dst, m) 0 933 /* OOTB only #define SCTP_IS_IT_BROADCAST(dst, m) ((m->m_flags & M_PKTHDR) ? in_broadcast(dst, m->m_pkthdr.rcvif) : 0) BSD def */ 934 #define SCTP_IS_IT_LOOPBACK(m) 0 935 /* OOTB ONLY #define SCTP_IS_IT_LOOPBACK(m) ((m->m_flags & M_PKTHDR) && ((m->m_pkthdr.rcvif == NULL) || (m->m_pkthdr.rcvif->if_type == IFT_LOOP))) BSD def */ 936 937 938 /* This converts any input packet header 939 * into the chain of data holders, for BSD 940 * its a NOP. 941 */ 942 943 /* get the v6 hop limit */ 944 #define SCTP_GET_HLIM(inp, ro) 128 945 #define IPv6_HOP_LIMIT 128 946 947 /* is the endpoint v6only? */ 948 #define SCTP_IPV6_V6ONLY(sctp_inpcb) ((sctp_inpcb)->ip_inp.inp.inp_flags & IN6P_IPV6_V6ONLY) 949 /* is the socket non-blocking? */ 950 #define SCTP_SO_IS_NBIO(so) ((so)->so_state & SS_NBIO) 951 #define SCTP_SET_SO_NBIO(so) ((so)->so_state |= SS_NBIO) 952 #define SCTP_CLEAR_SO_NBIO(so) ((so)->so_state &= ~SS_NBIO) 953 /* get the socket type */ 954 #define SCTP_SO_TYPE(so) ((so)->so_type) 955 956 /* reserve sb space for a socket */ 957 #define SCTP_SORESERVE(so, send, recv) soreserve(so, send, recv) 958 959 /* wakeup a socket */ 960 #define SCTP_SOWAKEUP(so) wakeup(&(so)->so_timeo, so) 961 /* number of bytes ready to read */ 962 #define SCTP_SBAVAIL(sb) (sb)->sb_cc 963 #define SCTP_SB_INCR(sb, incr) \ 964 { \ 965 atomic_add_int(&(sb)->sb_cc, incr); \ 966 } 967 #define SCTP_SB_DECR(sb, decr) \ 968 { \ 969 SCTP_SAVE_ATOMIC_DECREMENT(&(sb)->sb_cc, (int)(decr)); \ 970 } 971 /* clear the socket buffer state */ 972 #define SCTP_SB_CLEAR(sb) \ 973 (sb).sb_cc = 0; \ 974 (sb).sb_mb = NULL; \ 975 (sb).sb_mbcnt = 0; 976 977 #define SCTP_SB_LIMIT_RCV(so) so->so_rcv.sb_hiwat 978 #define SCTP_SB_LIMIT_SND(so) so->so_snd.sb_hiwat 979 980 #define SCTP_READ_RANDOM(buf, len) read_random(buf, len) 981 982 #define SCTP_SHA1_CTX struct sctp_sha1_context 983 #define SCTP_SHA1_INIT sctp_sha1_init 984 #define SCTP_SHA1_UPDATE sctp_sha1_update 985 #define SCTP_SHA1_FINAL(x,y) sctp_sha1_final((unsigned char *)x, y) 986 987 /* start OOTB only stuff */ 988 /* TODO IFT_LOOP is in net/if_types.h on Linux */ 989 #define IFT_LOOP 0x18 990 991 /* sctp_pcb.h */ 992 993 #if defined(_WIN32) 994 #define SHUT_RD 1 995 #define SHUT_WR 2 996 #define SHUT_RDWR 3 997 #endif 998 #define PRU_FLUSH_RD SHUT_RD 999 #define PRU_FLUSH_WR SHUT_WR 1000 #define PRU_FLUSH_RDWR SHUT_RDWR 1001 1002 /* netinet/ip_var.h defintions are behind an if defined for _KERNEL on FreeBSD */ 1003 #define IP_RAWOUTPUT 0x2 1004 1005 1006 /* end OOTB only stuff */ 1007 1008 #define AF_CONN 123 1009 struct sockaddr_conn { 1010 #ifdef HAVE_SCONN_LEN 1011 uint8_t sconn_len; 1012 uint8_t sconn_family; 1013 #else 1014 uint16_t sconn_family; 1015 #endif 1016 uint16_t sconn_port; 1017 void *sconn_addr; 1018 }; 1019 1020 typedef void *(*start_routine_t)(void *); 1021 1022 extern int 1023 sctp_userspace_thread_create(userland_thread_t *thread, start_routine_t start_routine); 1024 1025 void 1026 sctp_userspace_set_threadname(const char *name); 1027 1028 /* 1029 * SCTP protocol specific mbuf flags. 1030 */ 1031 #define M_NOTIFICATION M_PROTO5 /* SCTP notification */ 1032 1033 /* 1034 * IP output routines 1035 */ 1036 1037 /* Defining SCTP_IP_ID macro. 1038 In netinet/ip_output.c, we have u_short ip_id; 1039 In netinet/ip_var.h, we have extern u_short ip_id; (enclosed within _KERNEL_) 1040 See static __inline uint16_t ip_newid(void) in netinet/ip_var.h 1041 */ 1042 #define SCTP_IP_ID(inp) (ip_id) 1043 1044 /* need sctphdr to get port in SCTP_IP_OUTPUT. sctphdr defined in sctp.h */ 1045 #include <netinet/sctp.h> 1046 extern void sctp_userspace_ip_output(int *result, struct mbuf *o_pak, 1047 sctp_route_t *ro, void *stcb, 1048 uint32_t vrf_id); 1049 1050 #define SCTP_IP_OUTPUT(result, o_pak, ro, inp, vrf_id) sctp_userspace_ip_output(&result, o_pak, ro, inp, vrf_id); 1051 1052 #if defined(INET6) 1053 extern void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak, 1054 struct route_in6 *ro, void *stcb, 1055 uint32_t vrf_id); 1056 #define SCTP_IP6_OUTPUT(result, o_pak, ro, ifp, inp, vrf_id) sctp_userspace_ip6_output(&result, o_pak, ro, inp, vrf_id); 1057 #endif 1058 1059 1060 1061 #if 0 1062 #define SCTP_IP6_OUTPUT(result, o_pak, ro, ifp, stcb, vrf_id) \ 1063 { \ 1064 if (stcb && stcb->sctp_ep) \ 1065 result = ip6_output(o_pak, \ 1066 ((struct inpcb *)(stcb->sctp_ep))->in6p_outputopts, \ 1067 (ro), 0, 0, ifp, NULL); \ 1068 else \ 1069 result = ip6_output(o_pak, NULL, (ro), 0, 0, ifp, NULL); \ 1070 } 1071 #endif 1072 1073 struct mbuf * 1074 sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int allonebuf, int type); 1075 1076 1077 /* with the current included files, this is defined in Linux but 1078 * in FreeBSD, it is behind a _KERNEL in sys/socket.h ... 1079 */ 1080 #if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__native_client__) 1081 /* stolen from /usr/include/sys/socket.h */ 1082 #define CMSG_ALIGN(n) _ALIGN(n) 1083 #elif defined(__NetBSD__) 1084 #define CMSG_ALIGN(n) (((n) + __ALIGNBYTES) & ~__ALIGNBYTES) 1085 #elif defined(__APPLE__) 1086 #if !defined(__DARWIN_ALIGNBYTES) 1087 #define __DARWIN_ALIGNBYTES (sizeof(__darwin_size_t) - 1) 1088 #endif 1089 1090 #if !defined(__DARWIN_ALIGN) 1091 #define __DARWIN_ALIGN(p) ((__darwin_size_t)((char *)(uintptr_t)(p) + __DARWIN_ALIGNBYTES) &~ __DARWIN_ALIGNBYTES) 1092 #endif 1093 1094 #if !defined(__DARWIN_ALIGNBYTES32) 1095 #define __DARWIN_ALIGNBYTES32 (sizeof(__uint32_t) - 1) 1096 #endif 1097 1098 #if !defined(__DARWIN_ALIGN32) 1099 #define __DARWIN_ALIGN32(p) ((__darwin_size_t)((char *)(uintptr_t)(p) + __DARWIN_ALIGNBYTES32) &~ __DARWIN_ALIGNBYTES32) 1100 #endif 1101 #define CMSG_ALIGN(n) __DARWIN_ALIGN32(n) 1102 #endif 1103 #define I_AM_HERE \ 1104 do { \ 1105 SCTP_PRINTF("%s:%d at %s\n", __FILE__, __LINE__ , __func__); \ 1106 } while (0) 1107 1108 #ifndef timevalsub 1109 #define timevalsub(tp1, tp2) \ 1110 do { \ 1111 (tp1)->tv_sec -= (tp2)->tv_sec; \ 1112 (tp1)->tv_usec -= (tp2)->tv_usec; \ 1113 if ((tp1)->tv_usec < 0) { \ 1114 (tp1)->tv_sec--; \ 1115 (tp1)->tv_usec += 1000000; \ 1116 } \ 1117 } while (0) 1118 #endif 1119 1120 #if defined(__linux__) 1121 #if !defined(TAILQ_FOREACH_SAFE) 1122 #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ 1123 for ((var) = ((head)->tqh_first); \ 1124 (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ 1125 (var) = (tvar)) 1126 #endif 1127 #if !defined(LIST_FOREACH_SAFE) 1128 #define LIST_FOREACH_SAFE(var, head, field, tvar) \ 1129 for ((var) = ((head)->lh_first); \ 1130 (var) && ((tvar) = LIST_NEXT((var), field), 1); \ 1131 (var) = (tvar)) 1132 #endif 1133 #endif 1134 #if defined(__DragonFly__) 1135 #define TAILQ_FOREACH_SAFE TAILQ_FOREACH_MUTABLE 1136 #define LIST_FOREACH_SAFE LIST_FOREACH_MUTABLE 1137 #endif 1138 1139 #if defined(__native_client__) 1140 #define timercmp(tvp, uvp, cmp) \ 1141 (((tvp)->tv_sec == (uvp)->tv_sec) ? \ 1142 ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ 1143 ((tvp)->tv_sec cmp (uvp)->tv_sec)) 1144 #endif 1145 1146 #define SCTP_IS_LISTENING(inp) ((inp->sctp_flags & SCTP_PCB_FLAGS_ACCEPTING) != 0) 1147 1148 #if defined(__APPLE__) || defined(__DragonFly__) || defined(__linux__) || defined(__native_client__) || defined(__NetBSD__) || defined(_WIN32) || defined(__Fuchsia__) || defined(__EMSCRIPTEN__) 1149 int 1150 timingsafe_bcmp(const void *, const void *, size_t); 1151 #endif 1152 1153 #endif