1b85b710cSNick Mathewson /* 2e49e2891SNick Mathewson * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 3b85b710cSNick Mathewson * 4b85b710cSNick Mathewson * Redistribution and use in source and binary forms, with or without 5b85b710cSNick Mathewson * modification, are permitted provided that the following conditions 6b85b710cSNick Mathewson * are met: 7b85b710cSNick Mathewson * 1. Redistributions of source code must retain the above copyright 8b85b710cSNick Mathewson * notice, this list of conditions and the following disclaimer. 9b85b710cSNick Mathewson * 2. Redistributions in binary form must reproduce the above copyright 10b85b710cSNick Mathewson * notice, this list of conditions and the following disclaimer in the 11b85b710cSNick Mathewson * documentation and/or other materials provided with the distribution. 12b85b710cSNick Mathewson * 3. The name of the author may not be used to endorse or promote products 13b85b710cSNick Mathewson * derived from this software without specific prior written permission. 14b85b710cSNick Mathewson * 15b85b710cSNick Mathewson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16b85b710cSNick Mathewson * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17b85b710cSNick Mathewson * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18b85b710cSNick Mathewson * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19b85b710cSNick Mathewson * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20b85b710cSNick Mathewson * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21b85b710cSNick Mathewson * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22b85b710cSNick Mathewson * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23b85b710cSNick Mathewson * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24b85b710cSNick Mathewson * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25b85b710cSNick Mathewson */ 263f8c7cd0SNick Mathewson #ifndef UTIL_INTERNAL_H_INCLUDED_ 273f8c7cd0SNick Mathewson #define UTIL_INTERNAL_H_INCLUDED_ 285ebd23adSNick Mathewson 29ec347b92SNick Mathewson #include "event2/event-config.h" 300915ca0aSKevin Bowling #include "evconfig-private.h" 310915ca0aSKevin Bowling 325ebd23adSNick Mathewson #include <errno.h> 335ebd23adSNick Mathewson 3437c3456dSNick Mathewson /* For EVUTIL_ASSERT */ 3537c3456dSNick Mathewson #include "log-internal.h" 3637c3456dSNick Mathewson #include <stdio.h> 3737c3456dSNick Mathewson #include <stdlib.h> 3868120d9bSNick Mathewson #ifdef EVENT__HAVE_SYS_SOCKET_H 390b9eb1bfSNick Mathewson #include <sys/socket.h> 400b9eb1bfSNick Mathewson #endif 4168120d9bSNick Mathewson #ifdef EVENT__HAVE_SYS_EVENTFD_H 42a1c042bfSNick Mathewson #include <sys/eventfd.h> 43a1c042bfSNick Mathewson #endif 4447bad8abSNick Mathewson #include "event2/util.h" 4537c3456dSNick Mathewson 4671bca50fSNick Mathewson #include "time-internal.h" 47713c254dSNick Mathewson #include "ipv6-internal.h" 48713c254dSNick Mathewson 495ebd23adSNick Mathewson #ifdef __cplusplus 505ebd23adSNick Mathewson extern "C" { 515ebd23adSNick Mathewson #endif 525ebd23adSNick Mathewson 53df01f798SAzat Khuzhin /* __has_attribute() wrapper */ 54df01f798SAzat Khuzhin #ifdef __has_attribute 55df01f798SAzat Khuzhin # define EVUTIL_HAS_ATTRIBUTE __has_attribute 56df01f798SAzat Khuzhin #endif 57df01f798SAzat Khuzhin /** clang 3 __has_attribute misbehaves in some versions */ 58*7fd7c5efSAzat Khuzhin #if defined(__clang__) && __clang__ == 1 59*7fd7c5efSAzat Khuzhin # if defined(__apple_build_version__) 60*7fd7c5efSAzat Khuzhin # if __clang_major__ <= 6 61df01f798SAzat Khuzhin # undef EVUTIL_HAS_ATTRIBUTE 62df01f798SAzat Khuzhin # endif 63*7fd7c5efSAzat Khuzhin # else /* !__apple_build_version__ */ 64*7fd7c5efSAzat Khuzhin # if __clang_major__ == 3 && __clang_minor__ >= 2 && __clang_minor__ <= 5 65*7fd7c5efSAzat Khuzhin # undef EVUTIL_HAS_ATTRIBUTE 66*7fd7c5efSAzat Khuzhin # endif 67*7fd7c5efSAzat Khuzhin # endif /* __apple_build_version__ */ 68*7fd7c5efSAzat Khuzhin #endif /*\ defined(__clang__) && __clang__ == 1 */ 69df01f798SAzat Khuzhin #ifndef EVUTIL_HAS_ATTRIBUTE 70df01f798SAzat Khuzhin # define EVUTIL_HAS_ATTRIBUTE(x) 0 7140da44bdSAzat Khuzhin #endif 7240da44bdSAzat Khuzhin 73ebf29455SNick Mathewson /* If we need magic to say "inline", get it for free internally. */ 7468120d9bSNick Mathewson #ifdef EVENT__inline 7568120d9bSNick Mathewson #define inline EVENT__inline 76ebf29455SNick Mathewson #endif 77b3af7bddSAzat Khuzhin 78b3af7bddSAzat Khuzhin /* Define to appropriate substitute if compiler doesnt have __func__ */ 79b3af7bddSAzat Khuzhin #if defined(EVENT__HAVE___func__) 80b3af7bddSAzat Khuzhin # ifndef __func__ 81b3af7bddSAzat Khuzhin # define __func__ __func__ 82b3af7bddSAzat Khuzhin # endif 83b3af7bddSAzat Khuzhin #elif defined(EVENT__HAVE___FUNCTION__) 84b3af7bddSAzat Khuzhin # define __func__ __FUNCTION__ 85b3af7bddSAzat Khuzhin #else 86b3af7bddSAzat Khuzhin # define __func__ __FILE__ 87ebf29455SNick Mathewson #endif 88ebf29455SNick Mathewson 89661b5eeaSNick Mathewson /* A good no-op to use in macro definitions. */ 90cb9da0bfSNick Mathewson #define EVUTIL_NIL_STMT_ ((void)0) 91cb8059d2SNick Mathewson /* A no-op that tricks the compiler into thinking a condition is used while 92cb8059d2SNick Mathewson * definitely not making any code for it. Used to compile out asserts while 93cb8059d2SNick Mathewson * avoiding "unused variable" warnings. The "!" forces the compiler to 94cb8059d2SNick Mathewson * do the sizeof() on an int, in case "condition" is a bitfield value. 95cb8059d2SNick Mathewson */ 96cb9da0bfSNick Mathewson #define EVUTIL_NIL_CONDITION_(condition) do { \ 97cb8059d2SNick Mathewson (void)sizeof(!(condition)); \ 98b63ab177SEvan Jones } while(0) 99661b5eeaSNick Mathewson 1005ebd23adSNick Mathewson /* Internal use only: macros to match patterns of error codes in a 1015ebd23adSNick Mathewson cross-platform way. We need these macros because of two historical 1025ebd23adSNick Mathewson reasons: first, nonblocking IO functions are generally written to give an 1035ebd23adSNick Mathewson error on the "blocked now, try later" case, so sometimes an error from a 1045ebd23adSNick Mathewson read, write, connect, or accept means "no error; just wait for more 1055ebd23adSNick Mathewson data," and we need to look at the error code. Second, Windows defines 1065ebd23adSNick Mathewson a different set of error codes for sockets. */ 1075ebd23adSNick Mathewson 1089f560bfaSNick Mathewson #ifndef _WIN32 1095ebd23adSNick Mathewson 110bf7a0ff2SNick Mathewson #if EAGAIN == EWOULDBLOCK 111bf7a0ff2SNick Mathewson #define EVUTIL_ERR_IS_EAGAIN(e) \ 112bf7a0ff2SNick Mathewson ((e) == EAGAIN) 113bf7a0ff2SNick Mathewson #else 114bf7a0ff2SNick Mathewson #define EVUTIL_ERR_IS_EAGAIN(e) \ 115bf7a0ff2SNick Mathewson ((e) == EAGAIN || (e) == EWOULDBLOCK) 116bf7a0ff2SNick Mathewson #endif 117bf7a0ff2SNick Mathewson 1185ebd23adSNick Mathewson /* True iff e is an error that means a read/write operation can be retried. */ 1195ebd23adSNick Mathewson #define EVUTIL_ERR_RW_RETRIABLE(e) \ 120bf7a0ff2SNick Mathewson ((e) == EINTR || EVUTIL_ERR_IS_EAGAIN(e)) 1217bc48bfdSNiels Provos /* True iff e is an error that means an connect can be retried. */ 1225ebd23adSNick Mathewson #define EVUTIL_ERR_CONNECT_RETRIABLE(e) \ 1235ebd23adSNick Mathewson ((e) == EINTR || (e) == EINPROGRESS) 1247bc48bfdSNiels Provos /* True iff e is an error that means a accept can be retried. */ 1255ebd23adSNick Mathewson #define EVUTIL_ERR_ACCEPT_RETRIABLE(e) \ 126bf7a0ff2SNick Mathewson ((e) == EINTR || EVUTIL_ERR_IS_EAGAIN(e) || (e) == ECONNABORTED) 1275ebd23adSNick Mathewson 1287bc48bfdSNiels Provos /* True iff e is an error that means the connection was refused */ 1297bc48bfdSNiels Provos #define EVUTIL_ERR_CONNECT_REFUSED(e) \ 1307bc48bfdSNiels Provos ((e) == ECONNREFUSED) 1317bc48bfdSNiels Provos 1325ebd23adSNick Mathewson #else 13342aaf4dcSNick Mathewson /* Win32 */ 13442aaf4dcSNick Mathewson 13542aaf4dcSNick Mathewson #define EVUTIL_ERR_IS_EAGAIN(e) \ 13642aaf4dcSNick Mathewson ((e) == WSAEWOULDBLOCK || (e) == EAGAIN) 1375ebd23adSNick Mathewson 1385ebd23adSNick Mathewson #define EVUTIL_ERR_RW_RETRIABLE(e) \ 139574d3202SNick Mathewson ((e) == WSAEWOULDBLOCK || \ 1405ebd23adSNick Mathewson (e) == WSAEINTR) 1415ebd23adSNick Mathewson 1425ebd23adSNick Mathewson #define EVUTIL_ERR_CONNECT_RETRIABLE(e) \ 1435ebd23adSNick Mathewson ((e) == WSAEWOULDBLOCK || \ 1445ebd23adSNick Mathewson (e) == WSAEINTR || \ 1455ebd23adSNick Mathewson (e) == WSAEINPROGRESS || \ 1469935d5b0SNick Mathewson (e) == WSAEINVAL) 1475ebd23adSNick Mathewson 1485ebd23adSNick Mathewson #define EVUTIL_ERR_ACCEPT_RETRIABLE(e) \ 1495ebd23adSNick Mathewson EVUTIL_ERR_RW_RETRIABLE(e) 1505ebd23adSNick Mathewson 1517bc48bfdSNiels Provos #define EVUTIL_ERR_CONNECT_REFUSED(e) \ 1527bc48bfdSNiels Provos ((e) == WSAECONNREFUSED) 1537bc48bfdSNiels Provos 1545ebd23adSNick Mathewson #endif 1555ebd23adSNick Mathewson 156145f221eSNick Mathewson /* Arguments for shutdown() */ 157145f221eSNick Mathewson #ifdef SHUT_RD 158145f221eSNick Mathewson #define EVUTIL_SHUT_RD SHUT_RD 159145f221eSNick Mathewson #else 160145f221eSNick Mathewson #define EVUTIL_SHUT_RD 0 161145f221eSNick Mathewson #endif 162145f221eSNick Mathewson #ifdef SHUT_WR 163145f221eSNick Mathewson #define EVUTIL_SHUT_WR SHUT_WR 164145f221eSNick Mathewson #else 16504fc82f7SAzat Khuzhin #define EVUTIL_SHUT_WR 1 /* SD_SEND */ 166145f221eSNick Mathewson #endif 167145f221eSNick Mathewson #ifdef SHUT_BOTH 168145f221eSNick Mathewson #define EVUTIL_SHUT_BOTH SHUT_BOTH 169145f221eSNick Mathewson #else 170145f221eSNick Mathewson #define EVUTIL_SHUT_BOTH 2 171145f221eSNick Mathewson #endif 172145f221eSNick Mathewson 173c89b4e63SNick Mathewson /* Helper: Verify that all the elements in 'dlist' are internally consistent. 174c89b4e63SNick Mathewson * Checks for circular lists and bad prev/next pointers. 175c89b4e63SNick Mathewson * 176c89b4e63SNick Mathewson * Example usage: 177c89b4e63SNick Mathewson * EVUTIL_ASSERT_LIST_OK(eventlist, event, ev_next); 178c89b4e63SNick Mathewson */ 179c89b4e63SNick Mathewson #define EVUTIL_ASSERT_LIST_OK(dlist, type, field) do { \ 180c89b4e63SNick Mathewson struct type *elm1, *elm2, **nextp; \ 181c89b4e63SNick Mathewson if (LIST_EMPTY((dlist))) \ 182c89b4e63SNick Mathewson break; \ 183c89b4e63SNick Mathewson \ 184c89b4e63SNick Mathewson /* Check list for circularity using Floyd's */ \ 185c89b4e63SNick Mathewson /* 'Tortoise and Hare' algorithm */ \ 186c89b4e63SNick Mathewson elm1 = LIST_FIRST((dlist)); \ 187c89b4e63SNick Mathewson elm2 = LIST_NEXT(elm1, field); \ 188c89b4e63SNick Mathewson while (elm1 && elm2) { \ 189c89b4e63SNick Mathewson EVUTIL_ASSERT(elm1 != elm2); \ 190c89b4e63SNick Mathewson elm1 = LIST_NEXT(elm1, field); \ 191c89b4e63SNick Mathewson elm2 = LIST_NEXT(elm2, field); \ 192c89b4e63SNick Mathewson if (!elm2) \ 193c89b4e63SNick Mathewson break; \ 194c89b4e63SNick Mathewson EVUTIL_ASSERT(elm1 != elm2); \ 195c89b4e63SNick Mathewson elm2 = LIST_NEXT(elm2, field); \ 196c89b4e63SNick Mathewson } \ 197c89b4e63SNick Mathewson \ 198c89b4e63SNick Mathewson /* Now check next and prev pointers for consistency. */ \ 199c89b4e63SNick Mathewson nextp = &LIST_FIRST((dlist)); \ 200c89b4e63SNick Mathewson elm1 = LIST_FIRST((dlist)); \ 201c89b4e63SNick Mathewson while (elm1) { \ 202c89b4e63SNick Mathewson EVUTIL_ASSERT(*nextp == elm1); \ 203c89b4e63SNick Mathewson EVUTIL_ASSERT(nextp == elm1->field.le_prev); \ 204c89b4e63SNick Mathewson nextp = &LIST_NEXT(elm1, field); \ 205c89b4e63SNick Mathewson elm1 = *nextp; \ 206c89b4e63SNick Mathewson } \ 207c89b4e63SNick Mathewson } while (0) 208c89b4e63SNick Mathewson 209c89b4e63SNick Mathewson /* Helper: Verify that all the elements in a TAILQ are internally consistent. 210c89b4e63SNick Mathewson * Checks for circular lists and bad prev/next pointers. 211c89b4e63SNick Mathewson * 212c89b4e63SNick Mathewson * Example usage: 213c89b4e63SNick Mathewson * EVUTIL_ASSERT_TAILQ_OK(activelist, event, ev_active_next); 214c89b4e63SNick Mathewson */ 215c89b4e63SNick Mathewson #define EVUTIL_ASSERT_TAILQ_OK(tailq, type, field) do { \ 216c89b4e63SNick Mathewson struct type *elm1, *elm2, **nextp; \ 217c89b4e63SNick Mathewson if (TAILQ_EMPTY((tailq))) \ 218c89b4e63SNick Mathewson break; \ 219c89b4e63SNick Mathewson \ 220c89b4e63SNick Mathewson /* Check list for circularity using Floyd's */ \ 221c89b4e63SNick Mathewson /* 'Tortoise and Hare' algorithm */ \ 222c89b4e63SNick Mathewson elm1 = TAILQ_FIRST((tailq)); \ 223c89b4e63SNick Mathewson elm2 = TAILQ_NEXT(elm1, field); \ 224c89b4e63SNick Mathewson while (elm1 && elm2) { \ 225c89b4e63SNick Mathewson EVUTIL_ASSERT(elm1 != elm2); \ 226c89b4e63SNick Mathewson elm1 = TAILQ_NEXT(elm1, field); \ 227c89b4e63SNick Mathewson elm2 = TAILQ_NEXT(elm2, field); \ 228c89b4e63SNick Mathewson if (!elm2) \ 229c89b4e63SNick Mathewson break; \ 230c89b4e63SNick Mathewson EVUTIL_ASSERT(elm1 != elm2); \ 231c89b4e63SNick Mathewson elm2 = TAILQ_NEXT(elm2, field); \ 232c89b4e63SNick Mathewson } \ 233c89b4e63SNick Mathewson \ 234c89b4e63SNick Mathewson /* Now check next and prev pointers for consistency. */ \ 235c89b4e63SNick Mathewson nextp = &TAILQ_FIRST((tailq)); \ 236c89b4e63SNick Mathewson elm1 = TAILQ_FIRST((tailq)); \ 237c89b4e63SNick Mathewson while (elm1) { \ 238c89b4e63SNick Mathewson EVUTIL_ASSERT(*nextp == elm1); \ 239c89b4e63SNick Mathewson EVUTIL_ASSERT(nextp == elm1->field.tqe_prev); \ 240c89b4e63SNick Mathewson nextp = &TAILQ_NEXT(elm1, field); \ 241c89b4e63SNick Mathewson elm1 = *nextp; \ 242c89b4e63SNick Mathewson } \ 243c89b4e63SNick Mathewson EVUTIL_ASSERT(nextp == (tailq)->tqh_last); \ 244c89b4e63SNick Mathewson } while (0) 245c89b4e63SNick Mathewson 246cd731b77SNick Mathewson /* Locale-independent replacements for some ctypes functions. Use these 247cd731b77SNick Mathewson * when you care about ASCII's notion of character types, because you are about 248cd731b77SNick Mathewson * to send those types onto the wire. 249cd731b77SNick Mathewson */ 2509806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 2518ac3c4c2SNick Mathewson int EVUTIL_ISALPHA_(char c); 2529806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 2538ac3c4c2SNick Mathewson int EVUTIL_ISALNUM_(char c); 2548ac3c4c2SNick Mathewson int EVUTIL_ISSPACE_(char c); 2559806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 2568ac3c4c2SNick Mathewson int EVUTIL_ISDIGIT_(char c); 2579806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 2588ac3c4c2SNick Mathewson int EVUTIL_ISXDIGIT_(char c); 2598ac3c4c2SNick Mathewson int EVUTIL_ISPRINT_(char c); 2608ac3c4c2SNick Mathewson int EVUTIL_ISLOWER_(char c); 2618ac3c4c2SNick Mathewson int EVUTIL_ISUPPER_(char c); 2629806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 2638ac3c4c2SNick Mathewson char EVUTIL_TOUPPER_(char c); 2649806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 2658ac3c4c2SNick Mathewson char EVUTIL_TOLOWER_(char c); 266cd731b77SNick Mathewson 267ac425197SNick Mathewson /** Remove all trailing horizontal whitespace (space or tab) from the end of a 268ac425197SNick Mathewson * string */ 2699806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 270ac425197SNick Mathewson void evutil_rtrim_lws_(char *); 271aa59d805SNick Mathewson 272aa59d805SNick Mathewson 273838d0a81SNick Mathewson /** Helper macro. If we know that a given pointer points to a field in a 274838d0a81SNick Mathewson structure, return a pointer to the structure itself. Used to implement 275838d0a81SNick Mathewson our half-baked C OO. Example: 276838d0a81SNick Mathewson 277838d0a81SNick Mathewson struct subtype { 278838d0a81SNick Mathewson int x; 279838d0a81SNick Mathewson struct supertype common; 280838d0a81SNick Mathewson int y; 281838d0a81SNick Mathewson }; 282838d0a81SNick Mathewson ... 283838d0a81SNick Mathewson void fn(struct supertype *super) { 284838d0a81SNick Mathewson struct subtype *sub = EVUTIL_UPCAST(super, struct subtype, common); 285838d0a81SNick Mathewson ... 286838d0a81SNick Mathewson } 287838d0a81SNick Mathewson */ 2880b47b125SNick Mathewson #define EVUTIL_UPCAST(ptr, type, field) \ 2898283b2f0SNick Mathewson ((type *)(((char*)(ptr)) - evutil_offsetof(type, field))) 2900b47b125SNick Mathewson 29103dce42dSNick Mathewson /* As open(pathname, flags, mode), except that the file is always opened with 29203dce42dSNick Mathewson * the close-on-exec flag set. (And the mode argument is mandatory.) 29303dce42dSNick Mathewson */ 2948ac3c4c2SNick Mathewson int evutil_open_closeonexec_(const char *pathname, int flags, unsigned mode); 295d2b5f722SRoss Lagerwall 2969806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 2978ac3c4c2SNick Mathewson int evutil_read_file_(const char *filename, char **content_out, size_t *len_out, 2980f7144fdSNick Mathewson int is_binary); 299709c21c4SNick Mathewson 3009806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 301a8d32c23SAzat Khuzhin int evutil_socket_connect_(evutil_socket_t *fd_ptr, const struct sockaddr *sa, int socklen); 302709c21c4SNick Mathewson 3038ac3c4c2SNick Mathewson int evutil_socket_finished_connecting_(evutil_socket_t fd); 30425af6954SNick Mathewson 3059806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 3068ac3c4c2SNick Mathewson int evutil_ersatz_socketpair_(int, int , int, evutil_socket_t[]); 30757b30cd7SNick Mathewson 3088ac3c4c2SNick Mathewson int evutil_resolve_(int family, const char *hostname, struct sockaddr *sa, 3090b9eb1bfSNick Mathewson ev_socklen_t *socklen, int port); 3100b9eb1bfSNick Mathewson 3118ac3c4c2SNick Mathewson const char *evutil_getenv_(const char *name); 312629a6133SNick Mathewson 3133aa44159SNick Mathewson /* Structure to hold the state of our weak random number generator. 3143aa44159SNick Mathewson */ 3153aa44159SNick Mathewson struct evutil_weakrand_state { 3163aa44159SNick Mathewson ev_uint32_t seed; 3173aa44159SNick Mathewson }; 3183aa44159SNick Mathewson 3193aa44159SNick Mathewson #define EVUTIL_WEAKRAND_MAX EV_INT32_MAX 3203aa44159SNick Mathewson 3213aa44159SNick Mathewson /* Initialize the state of a week random number generator based on 'seed'. If 3223aa44159SNick Mathewson * the seed is 0, construct a new seed based on not-very-strong platform 3233aa44159SNick Mathewson * entropy, like the PID and the time of day. 3243aa44159SNick Mathewson * 3253aa44159SNick Mathewson * This function, and the other evutil_weakrand* functions, are meant for 3263aa44159SNick Mathewson * speed, not security or statistical strength. If you need a RNG which an 3273aa44159SNick Mathewson * attacker can't predict, or which passes strong statistical tests, use the 3283aa44159SNick Mathewson * evutil_secure_rng* functions instead. 3293aa44159SNick Mathewson */ 3309806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 3313aa44159SNick Mathewson ev_uint32_t evutil_weakrand_seed_(struct evutil_weakrand_state *state, ev_uint32_t seed); 3323aa44159SNick Mathewson /* Return a pseudorandom value between 0 and EVUTIL_WEAKRAND_MAX inclusive. 3333aa44159SNick Mathewson * Updates the state in 'seed' as needed -- this value must be protected by a 3343aa44159SNick Mathewson * lock. 3353aa44159SNick Mathewson */ 3369806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 3373aa44159SNick Mathewson ev_int32_t evutil_weakrand_(struct evutil_weakrand_state *seed); 3383aa44159SNick Mathewson /* Return a pseudorandom value x such that 0 <= x < top. top must be no more 3393aa44159SNick Mathewson * than EVUTIL_WEAKRAND_MAX. Updates the state in 'seed' as needed -- this 3403aa44159SNick Mathewson * value must be proteced by a lock */ 3419806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 3423aa44159SNick Mathewson ev_int32_t evutil_weakrand_range_(struct evutil_weakrand_state *seed, ev_int32_t top); 343165d30e3SNick Mathewson 34437c3456dSNick Mathewson /* Evaluates to the same boolean value as 'p', and hints to the compiler that 34537c3456dSNick Mathewson * we expect this value to be false. */ 34609d39a12SDave Hart #if defined(__GNUC__) && __GNUC__ >= 3 /* gcc 3.0 or later */ 34737c3456dSNick Mathewson #define EVUTIL_UNLIKELY(p) __builtin_expect(!!(p),0) 34837c3456dSNick Mathewson #else 34937c3456dSNick Mathewson #define EVUTIL_UNLIKELY(p) (p) 35037c3456dSNick Mathewson #endif 35137c3456dSNick Mathewson 352df01f798SAzat Khuzhin #if EVUTIL_HAS_ATTRIBUTE(fallthrough) 35340da44bdSAzat Khuzhin #define EVUTIL_FALLTHROUGH __attribute__((fallthrough)) 35440da44bdSAzat Khuzhin #else 35540da44bdSAzat Khuzhin #define EVUTIL_FALLTHROUGH /* fallthrough */ 35640da44bdSAzat Khuzhin #endif 35740da44bdSAzat Khuzhin 35837c3456dSNick Mathewson /* Replacement for assert() that calls event_errx on failure. */ 359743f8665SNick Mathewson #ifdef NDEBUG 360cb9da0bfSNick Mathewson #define EVUTIL_ASSERT(cond) EVUTIL_NIL_CONDITION_(cond) 361743f8665SNick Mathewson #define EVUTIL_FAILURE_CHECK(cond) 0 362743f8665SNick Mathewson #else 36337c3456dSNick Mathewson #define EVUTIL_ASSERT(cond) \ 36437c3456dSNick Mathewson do { \ 36537c3456dSNick Mathewson if (EVUTIL_UNLIKELY(!(cond))) { \ 366cb9da0bfSNick Mathewson event_errx(EVENT_ERR_ABORT_, \ 36737c3456dSNick Mathewson "%s:%d: Assertion %s failed in %s", \ 36837c3456dSNick Mathewson __FILE__,__LINE__,#cond,__func__); \ 36937c3456dSNick Mathewson /* In case a user-supplied handler tries to */ \ 37037c3456dSNick Mathewson /* return control to us, log and abort here. */ \ 37137c3456dSNick Mathewson (void)fprintf(stderr, \ 37237c3456dSNick Mathewson "%s:%d: Assertion %s failed in %s", \ 37337c3456dSNick Mathewson __FILE__,__LINE__,#cond,__func__); \ 37437c3456dSNick Mathewson abort(); \ 37537c3456dSNick Mathewson } \ 37637c3456dSNick Mathewson } while (0) 377743f8665SNick Mathewson #define EVUTIL_FAILURE_CHECK(cond) EVUTIL_UNLIKELY(cond) 378743f8665SNick Mathewson #endif 37937c3456dSNick Mathewson 38068120d9bSNick Mathewson #ifndef EVENT__HAVE_STRUCT_SOCKADDR_STORAGE 3819184563eSNick Mathewson /* Replacement for sockaddr storage that we can use internally on platforms 3829184563eSNick Mathewson * that lack it. It is not space-efficient, but neither is sockaddr_storage. 3839184563eSNick Mathewson */ 3849184563eSNick Mathewson struct sockaddr_storage { 3859184563eSNick Mathewson union { 3869184563eSNick Mathewson struct sockaddr ss_sa; 3879184563eSNick Mathewson struct sockaddr_in ss_sin; 3889184563eSNick Mathewson struct sockaddr_in6 ss_sin6; 3899184563eSNick Mathewson char ss_padding[128]; 3909184563eSNick Mathewson } ss_union; 3919184563eSNick Mathewson }; 3929184563eSNick Mathewson #define ss_family ss_union.ss_sa.sa_family 3939184563eSNick Mathewson #endif 3949184563eSNick Mathewson 39586f57420SNick Mathewson /* Internal addrinfo error code. This one is returned from only from 3968ac3c4c2SNick Mathewson * evutil_getaddrinfo_common_, when we are sure that we'll have to hit a DNS 39786f57420SNick Mathewson * server. */ 39886f57420SNick Mathewson #define EVUTIL_EAI_NEED_RESOLVE -90002 39986f57420SNick Mathewson 40086f57420SNick Mathewson struct evdns_base; 40186f57420SNick Mathewson struct evdns_getaddrinfo_request; 40286f57420SNick Mathewson typedef struct evdns_getaddrinfo_request* (*evdns_getaddrinfo_fn)( 40386f57420SNick Mathewson struct evdns_base *base, 40486f57420SNick Mathewson const char *nodename, const char *servname, 40586f57420SNick Mathewson const struct evutil_addrinfo *hints_in, 40686f57420SNick Mathewson void (*cb)(int, struct evutil_addrinfo *, void *), void *arg); 4079806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 4088ac3c4c2SNick Mathewson void evutil_set_evdns_getaddrinfo_fn_(evdns_getaddrinfo_fn fn); 4098cbe65d5SAzat Khuzhin typedef void (*evdns_getaddrinfo_cancel_fn)( 4108cbe65d5SAzat Khuzhin struct evdns_getaddrinfo_request *req); 4119806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 4128cbe65d5SAzat Khuzhin void evutil_set_evdns_getaddrinfo_cancel_fn_(evdns_getaddrinfo_cancel_fn fn); 41386f57420SNick Mathewson 4149806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 4158ac3c4c2SNick Mathewson struct evutil_addrinfo *evutil_new_addrinfo_(struct sockaddr *sa, 41686f57420SNick Mathewson ev_socklen_t socklen, const struct evutil_addrinfo *hints); 4179806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 4188ac3c4c2SNick Mathewson struct evutil_addrinfo *evutil_addrinfo_append_(struct evutil_addrinfo *first, 41986f57420SNick Mathewson struct evutil_addrinfo *append); 4209806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 4218ac3c4c2SNick Mathewson void evutil_adjust_hints_for_addrconfig_(struct evutil_addrinfo *hints); 4229806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 4238ac3c4c2SNick Mathewson int evutil_getaddrinfo_common_(const char *nodename, const char *servname, 42486f57420SNick Mathewson struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum); 42586f57420SNick Mathewson 4268cbe65d5SAzat Khuzhin struct evdns_getaddrinfo_request *evutil_getaddrinfo_async_( 4278cbe65d5SAzat Khuzhin struct evdns_base *dns_base, 42886f57420SNick Mathewson const char *nodename, const char *servname, 42986f57420SNick Mathewson const struct evutil_addrinfo *hints_in, 43086f57420SNick Mathewson void (*cb)(int, struct evutil_addrinfo *, void *), void *arg); 4318cbe65d5SAzat Khuzhin void evutil_getaddrinfo_cancel_async_(struct evdns_getaddrinfo_request *data); 43286f57420SNick Mathewson 4338d4aaf90SNick Mathewson /** Return true iff sa is a looback address. (That is, it is 127.0.0.1/8, or 4348d4aaf90SNick Mathewson * ::1). */ 4359806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 4368ac3c4c2SNick Mathewson int evutil_sockaddr_is_loopback_(const struct sockaddr *sa); 4378d4aaf90SNick Mathewson 438b1c79500SNick Mathewson 439b1c79500SNick Mathewson /** 440b1c79500SNick Mathewson Formats a sockaddr sa into a string buffer of size outlen stored in out. 441b1c79500SNick Mathewson Returns a pointer to out. Always writes something into out, so it's safe 442b1c79500SNick Mathewson to use the output of this function without checking it for NULL. 443b1c79500SNick Mathewson */ 4449806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 4458ac3c4c2SNick Mathewson const char *evutil_format_sockaddr_port_(const struct sockaddr *sa, char *out, size_t outlen); 446b1c79500SNick Mathewson 4478ac3c4c2SNick Mathewson int evutil_hex_char_to_int_(char c); 44820fda296SNick Mathewson 449f25d9d32SNick Mathewson 450041ca00cSMark Ellzey void evutil_free_secure_rng_globals_(void); 451041ca00cSMark Ellzey void evutil_free_globals_(void); 452041ca00cSMark Ellzey 4539f560bfaSNick Mathewson #ifdef _WIN32 454ebd12e6dSAzat Khuzhin EVENT2_EXPORT_SYMBOL 455f691389eSNick Mathewson HMODULE evutil_load_windows_system_library_(const TCHAR *library_name); 456d49b5e33SNick Mathewson #endif 457d49b5e33SNick Mathewson 4583203f88cSNick Mathewson #ifndef EV_SIZE_FMT 4593203f88cSNick Mathewson #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) 4603203f88cSNick Mathewson #define EV_U64_FMT "%I64u" 4613203f88cSNick Mathewson #define EV_I64_FMT "%I64d" 4623203f88cSNick Mathewson #define EV_I64_ARG(x) ((__int64)(x)) 4633203f88cSNick Mathewson #define EV_U64_ARG(x) ((unsigned __int64)(x)) 4643203f88cSNick Mathewson #else 4653203f88cSNick Mathewson #define EV_U64_FMT "%llu" 4663203f88cSNick Mathewson #define EV_I64_FMT "%lld" 4673203f88cSNick Mathewson #define EV_I64_ARG(x) ((long long)(x)) 4683203f88cSNick Mathewson #define EV_U64_ARG(x) ((unsigned long long)(x)) 4693203f88cSNick Mathewson #endif 4703203f88cSNick Mathewson #endif 4713203f88cSNick Mathewson 47294866c27SNick Mathewson #ifdef _WIN32 47394866c27SNick Mathewson #define EV_SOCK_FMT EV_I64_FMT 47494866c27SNick Mathewson #define EV_SOCK_ARG(x) EV_I64_ARG((x)) 47594866c27SNick Mathewson #else 47694866c27SNick Mathewson #define EV_SOCK_FMT "%d" 47794866c27SNick Mathewson #define EV_SOCK_ARG(x) (x) 47894866c27SNick Mathewson #endif 47994866c27SNick Mathewson 48079b69d8bSAzat Khuzhin #if defined(__STDC__) && defined(__STDC_VERSION__) && !defined(__MINGW64_VERSION_MAJOR) 4813203f88cSNick Mathewson #if (__STDC_VERSION__ >= 199901L) 4823203f88cSNick Mathewson #define EV_SIZE_FMT "%zu" 4833203f88cSNick Mathewson #define EV_SSIZE_FMT "%zd" 4843203f88cSNick Mathewson #define EV_SIZE_ARG(x) (x) 4853203f88cSNick Mathewson #define EV_SSIZE_ARG(x) (x) 4863203f88cSNick Mathewson #endif 4873203f88cSNick Mathewson #endif 4883203f88cSNick Mathewson 4893203f88cSNick Mathewson #ifndef EV_SIZE_FMT 49068120d9bSNick Mathewson #if (EVENT__SIZEOF_SIZE_T <= EVENT__SIZEOF_LONG) 4913203f88cSNick Mathewson #define EV_SIZE_FMT "%lu" 4923203f88cSNick Mathewson #define EV_SSIZE_FMT "%ld" 4933203f88cSNick Mathewson #define EV_SIZE_ARG(x) ((unsigned long)(x)) 4943203f88cSNick Mathewson #define EV_SSIZE_ARG(x) ((long)(x)) 4953203f88cSNick Mathewson #else 4963203f88cSNick Mathewson #define EV_SIZE_FMT EV_U64_FMT 4973203f88cSNick Mathewson #define EV_SSIZE_FMT EV_I64_FMT 4983203f88cSNick Mathewson #define EV_SIZE_ARG(x) EV_U64_ARG(x) 4993203f88cSNick Mathewson #define EV_SSIZE_ARG(x) EV_I64_ARG(x) 5003203f88cSNick Mathewson #endif 5013203f88cSNick Mathewson #endif 5023203f88cSNick Mathewson 5039806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 5048ac3c4c2SNick Mathewson evutil_socket_t evutil_socket_(int domain, int type, int protocol); 5058ac3c4c2SNick Mathewson evutil_socket_t evutil_accept4_(evutil_socket_t sockfd, struct sockaddr *addr, 506ca47fa0bSNick Mathewson ev_socklen_t *addrlen, int flags); 5074545fa9bSTrond Norbye 5084545fa9bSTrond Norbye /* used by one of the test programs.. */ 5094545fa9bSTrond Norbye EVENT2_EXPORT_SYMBOL 5108ac3c4c2SNick Mathewson int evutil_make_internal_pipe_(evutil_socket_t fd[2]); 5118ac3c4c2SNick Mathewson evutil_socket_t evutil_eventfd_(unsigned initval, int flags); 512a1c042bfSNick Mathewson 513a1c042bfSNick Mathewson #ifdef SOCK_NONBLOCK 514a1c042bfSNick Mathewson #define EVUTIL_SOCK_NONBLOCK SOCK_NONBLOCK 515a1c042bfSNick Mathewson #else 516a1c042bfSNick Mathewson #define EVUTIL_SOCK_NONBLOCK 0x4000000 517a1c042bfSNick Mathewson #endif 518a1c042bfSNick Mathewson #ifdef SOCK_CLOEXEC 519a1c042bfSNick Mathewson #define EVUTIL_SOCK_CLOEXEC SOCK_CLOEXEC 520a1c042bfSNick Mathewson #else 521a1c042bfSNick Mathewson #define EVUTIL_SOCK_CLOEXEC 0x80000000 522a1c042bfSNick Mathewson #endif 523a1c042bfSNick Mathewson #ifdef EFD_NONBLOCK 524a1c042bfSNick Mathewson #define EVUTIL_EFD_NONBLOCK EFD_NONBLOCK 525a1c042bfSNick Mathewson #else 526a1c042bfSNick Mathewson #define EVUTIL_EFD_NONBLOCK 0x4000 527a1c042bfSNick Mathewson #endif 528a1c042bfSNick Mathewson #ifdef EFD_CLOEXEC 529a1c042bfSNick Mathewson #define EVUTIL_EFD_CLOEXEC EFD_CLOEXEC 530a1c042bfSNick Mathewson #else 531a1c042bfSNick Mathewson #define EVUTIL_EFD_CLOEXEC 0x8000 532a1c042bfSNick Mathewson #endif 533a1c042bfSNick Mathewson 534f5ced88cSNick Mathewson void evutil_memclear_(void *mem, size_t len); 535a1c042bfSNick Mathewson 536b07e43e6SAzat Khuzhin struct in_addr; 537b07e43e6SAzat Khuzhin struct in6_addr; 538b07e43e6SAzat Khuzhin 539b07e43e6SAzat Khuzhin /* This is a any, loopback, link-local, multicast */ 540b07e43e6SAzat Khuzhin EVENT2_EXPORT_SYMBOL 541b07e43e6SAzat Khuzhin int evutil_v4addr_is_local_(const struct in_addr *in); 542b07e43e6SAzat Khuzhin /* This is a reserved, ipv4compat, ipv4map, loopback, 543b07e43e6SAzat Khuzhin * link-local, multicast, or unspecified address. */ 544b07e43e6SAzat Khuzhin EVENT2_EXPORT_SYMBOL 545b07e43e6SAzat Khuzhin int evutil_v6addr_is_local_(const struct in6_addr *in); 546b07e43e6SAzat Khuzhin 5475ebd23adSNick Mathewson #ifdef __cplusplus 5485ebd23adSNick Mathewson } 5495ebd23adSNick Mathewson #endif 5505ebd23adSNick Mathewson 5515ebd23adSNick Mathewson #endif 552