tor  master
compat.h
1 /* Copyright (c) 2003-2004, Roger Dingledine
2  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3  * Copyright (c) 2007-2017, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
6 #ifndef TOR_COMPAT_H
7 #define TOR_COMPAT_H
8 
9 #include "orconfig.h"
10 #ifdef _WIN32
11 #include <winsock2.h>
12 #include <ws2tcpip.h>
13 #ifndef SIO_IDEAL_SEND_BACKLOG_QUERY
14 #define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747b
15 #endif
16 #endif
17 #include "torint.h"
18 #include "testsupport.h"
19 #ifdef HAVE_SYS_PARAM_H
20 #include <sys/param.h>
21 #endif
22 #ifdef HAVE_SYS_TYPES_H
23 #include <sys/types.h>
24 #endif
25 #ifdef HAVE_SYS_TIME_H
26 #include <sys/time.h>
27 #endif
28 #ifdef HAVE_TIME_H
29 #include <time.h>
30 #endif
31 #ifdef HAVE_STRING_H
32 #include <string.h>
33 #endif
34 #include <stdarg.h>
35 #ifdef HAVE_SYS_RESOURCE_H
36 #include <sys/resource.h>
37 #endif
38 #ifdef HAVE_SYS_SOCKET_H
39 #include <sys/socket.h>
40 #endif
41 #ifdef HAVE_NETINET_IN_H
42 #include <netinet/in.h>
43 #endif
44 #ifdef HAVE_NETINET6_IN6_H
45 #include <netinet6/in6.h>
46 #endif
47 
48 #include "compat_time.h"
49 
50 #if defined(__has_feature)
51 # if __has_feature(address_sanitizer)
52 /* Some of the fancy glibc strcmp() macros include references to memory that
53  * clang rejects because it is off the end of a less-than-3. Clang hates this,
54  * even though those references never actually happen. */
55 # undef strcmp
56 #endif /* __has_feature(address_sanitizer) */
57 #endif /* defined(__has_feature) */
58 
59 #include <stdio.h>
60 #include <errno.h>
61 
62 #ifndef NULL_REP_IS_ZERO_BYTES
63 #error "It seems your platform does not represent NULL as zero. We can't cope."
64 #endif
65 
66 #ifndef DOUBLE_0_REP_IS_ZERO_BYTES
67 #error "It seems your platform does not represent 0.0 as zeros. We can't cope."
68 #endif
69 
70 #if 'a'!=97 || 'z'!=122 || 'A'!=65 || ' '!=32
71 #error "It seems that you encode characters in something other than ASCII."
72 #endif
73 
74 /* ===== Compiler compatibility */
75 
76 /* GCC can check printf and scanf types on arbitrary functions. */
77 #ifdef __GNUC__
78 #define CHECK_PRINTF(formatIdx, firstArg) \
79  __attribute__ ((format(printf, formatIdx, firstArg)))
80 #else
81 #define CHECK_PRINTF(formatIdx, firstArg)
82 #endif /* defined(__GNUC__) */
83 #ifdef __GNUC__
84 #define CHECK_SCANF(formatIdx, firstArg) \
85  __attribute__ ((format(scanf, formatIdx, firstArg)))
86 #else
87 #define CHECK_SCANF(formatIdx, firstArg)
88 #endif /* defined(__GNUC__) */
89 
90 /* What GCC do we have? */
91 #ifdef __GNUC__
92 #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
93 #else
94 #define GCC_VERSION 0
95 #endif
96 
97 /* Temporarily enable and disable warnings. */
98 #ifdef __GNUC__
99 # define PRAGMA_STRINGIFY_(s) #s
100 # define PRAGMA_JOIN_STRINGIFY_(a,b) PRAGMA_STRINGIFY_(a ## b)
101 /* Support for macro-generated pragmas (c99) */
102 # define PRAGMA_(x) _Pragma (#x)
103 # ifdef __clang__
104 # define PRAGMA_DIAGNOSTIC_(x) PRAGMA_(clang diagnostic x)
105 # else
106 # define PRAGMA_DIAGNOSTIC_(x) PRAGMA_(GCC diagnostic x)
107 # endif
108 # if defined(__clang__) || GCC_VERSION >= 406
109 /* we have push/pop support */
110 # define DISABLE_GCC_WARNING(warningopt) \
111  PRAGMA_DIAGNOSTIC_(push) \
112  PRAGMA_DIAGNOSTIC_(ignored PRAGMA_JOIN_STRINGIFY_(-W,warningopt))
113 # define ENABLE_GCC_WARNING(warningopt) \
114  PRAGMA_DIAGNOSTIC_(pop)
115 #else /* !(defined(__clang__) || GCC_VERSION >= 406) */
116 /* older version of gcc: no push/pop support. */
117 # define DISABLE_GCC_WARNING(warningopt) \
118  PRAGMA_DIAGNOSTIC_(ignored PRAGMA_JOIN_STRINGIFY_(-W,warningopt))
119 # define ENABLE_GCC_WARNING(warningopt) \
120  PRAGMA_DIAGNOSTIC_(warning PRAGMA_JOIN_STRINGIFY_(-W,warningopt))
121 #endif /* defined(__clang__) || GCC_VERSION >= 406 */
122 #else /* !(defined(__GNUC__)) */
123 /* not gcc at all */
124 # define DISABLE_GCC_WARNING(warning)
125 # define ENABLE_GCC_WARNING(warning)
126 #endif /* defined(__GNUC__) */
127 
128 /* inline is __inline on windows. */
129 #ifdef _WIN32
130 #define inline __inline
131 #endif
132 
133 /* Try to get a reasonable __func__ substitute in place. */
134 #if defined(_MSC_VER)
135 
136 #define __func__ __FUNCTION__
137 
138 #else
139 /* For platforms where autoconf works, make sure __func__ is defined
140  * sanely. */
141 #ifndef HAVE_MACRO__func__
142 #ifdef HAVE_MACRO__FUNCTION__
143 #define __func__ __FUNCTION__
144 #elif HAVE_MACRO__FUNC__
145 #define __func__ __FUNC__
146 #else
147 #define __func__ "???"
148 #endif /* defined(HAVE_MACRO__FUNCTION__) || ... */
149 #endif /* !defined(HAVE_MACRO__func__) */
150 #endif /* defined(_MSC_VER) */
151 
152 #define U64_TO_DBL(x) ((double) (x))
153 #define DBL_TO_U64(x) ((uint64_t) (x))
154 
155 #ifdef ENUM_VALS_ARE_SIGNED
156 #define ENUM_BF(t) unsigned
157 #else
158 
162 #define ENUM_BF(t) t
163 #endif /* defined(ENUM_VALS_ARE_SIGNED) */
164 
165 /* GCC has several useful attributes. */
166 #if defined(__GNUC__) && __GNUC__ >= 3
167 #define ATTR_NORETURN __attribute__((noreturn))
168 #define ATTR_CONST __attribute__((const))
169 #define ATTR_MALLOC __attribute__((malloc))
170 #define ATTR_NORETURN __attribute__((noreturn))
171 #define ATTR_WUR __attribute__((warn_unused_result))
172 /* Alas, nonnull is not at present a good idea for us. We'd like to get
173  * warnings when we pass NULL where we shouldn't (which nonnull does, albeit
174  * spottily), but we don't want to tell the compiler to make optimizations
175  * with the assumption that the argument can't be NULL (since this would make
176  * many of our checks go away, and make our code less robust against
177  * programming errors). Unfortunately, nonnull currently does both of these
178  * things, and there's no good way to split them up.
179  *
180  * #define ATTR_NONNULL(x) __attribute__((nonnull x)) */
181 #define ATTR_NONNULL(x)
182 #define ATTR_UNUSED __attribute__ ((unused))
183 
191 #define PREDICT_LIKELY(exp) __builtin_expect(!!(exp), 1)
192 
199 #define PREDICT_UNLIKELY(exp) __builtin_expect(!!(exp), 0)
200 #else /* !(defined(__GNUC__) && __GNUC__ >= 3) */
201 #define ATTR_NORETURN
202 #define ATTR_CONST
203 #define ATTR_MALLOC
204 #define ATTR_NORETURN
205 #define ATTR_NONNULL(x)
206 #define ATTR_UNUSED
207 #define ATTR_WUR
208 #define PREDICT_LIKELY(exp) (exp)
209 #define PREDICT_UNLIKELY(exp) (exp)
210 #endif /* defined(__GNUC__) && __GNUC__ >= 3 */
211 
213 #define STMT_NIL (void)0
214 
217 #define STMT_VOID(a) while (0) { (void)(a); }
218 
219 #ifdef __GNUC__
220 
222 #define STMT_BEGIN (void) ({
223 #define STMT_END })
224 #elif defined(sun) || defined(__sun__)
225 #define STMT_BEGIN if (1) {
226 #define STMT_END } else STMT_NIL
227 #else
228 #define STMT_BEGIN do {
229 #define STMT_END } while (0)
230 #endif /* defined(__GNUC__) || ... */
231 
232 /* Some tools (like coccinelle) don't like to see operators as macro
233  * arguments. */
234 #define OP_LT <
235 #define OP_GT >
236 #define OP_GE >=
237 #define OP_LE <=
238 #define OP_EQ ==
239 #define OP_NE !=
240 
241 /* ===== String compatibility */
242 #ifdef _WIN32
243 /* Windows names string functions differently from most other platforms. */
244 #define strncasecmp _strnicmp
245 #define strcasecmp _stricmp
246 #endif
247 
248 #if defined __APPLE__
249 /* On OSX 10.9 and later, the overlap-checking code for strlcat would
250  * appear to have a severe bug that can sometimes cause aborts in Tor.
251  * Instead, use the non-checking variants. This is sad.
252  *
253  * See https://trac.torproject.org/projects/tor/ticket/15205
254  */
255 #undef strlcat
256 #undef strlcpy
257 #endif /* defined __APPLE__ */
258 
259 #ifndef HAVE_STRLCAT
260 size_t strlcat(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2));
261 #endif
262 #ifndef HAVE_STRLCPY
263 size_t strlcpy(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2));
264 #endif
265 
266 #ifdef _MSC_VER
267 
269 #define U64_PRINTF_ARG(a) (a)
270 
272 #define U64_SCANF_ARG(a) (a)
273 
274 #define U64_LITERAL(n) (n ## ui64)
275 #define I64_PRINTF_ARG(a) (a)
276 #define I64_SCANF_ARG(a) (a)
277 #define I64_LITERAL(n) (n ## i64)
278 #else /* !(defined(_MSC_VER)) */
279 #define U64_PRINTF_ARG(a) ((long long unsigned int)(a))
280 #define U64_SCANF_ARG(a) ((long long unsigned int*)(a))
281 #define U64_LITERAL(n) (n ## llu)
282 #define I64_PRINTF_ARG(a) ((long long signed int)(a))
283 #define I64_SCANF_ARG(a) ((long long signed int*)(a))
284 #define I64_LITERAL(n) (n ## ll)
285 #endif /* defined(_MSC_VER) */
286 
287 #if defined(__MINGW32__) || defined(__MINGW64__)
288 #define MINGW_ANY
289 #endif
290 
291 #if defined(_MSC_VER) || defined(MINGW_ANY)
292 
294 #define U64_FORMAT "%I64u"
295 #define I64_FORMAT "%I64d"
296 #else /* !(defined(_MSC_VER) || defined(MINGW_ANY)) */
297 #define U64_FORMAT "%llu"
298 #define I64_FORMAT "%lld"
299 #endif /* defined(_MSC_VER) || defined(MINGW_ANY) */
300 
301 #if (SIZEOF_INTPTR_T == SIZEOF_INT)
302 #define INTPTR_T_FORMAT "%d"
303 #define INTPTR_PRINTF_ARG(x) ((int)(x))
304 #elif (SIZEOF_INTPTR_T == SIZEOF_LONG)
305 #define INTPTR_T_FORMAT "%ld"
306 #define INTPTR_PRINTF_ARG(x) ((long)(x))
307 #elif (SIZEOF_INTPTR_T == 8)
308 #define INTPTR_T_FORMAT I64_FORMAT
309 #define INTPTR_PRINTF_ARG(x) I64_PRINTF_ARG(x)
310 #else
311 #error Unknown: SIZEOF_INTPTR_T
312 #endif /* (SIZEOF_INTPTR_T == SIZEOF_INT) || ... */
313 
316 typedef struct tor_mmap_t {
317  const char *data;
318  size_t size;
320  /* None of the fields below should be accessed from outside compat.c */
321 #ifdef HAVE_MMAP
322  size_t mapping_size;
324 #elif defined _WIN32
325  HANDLE mmap_handle;
326 #endif /* defined(HAVE_MMAP) || ... */
327 
328 } tor_mmap_t;
329 
330 tor_mmap_t *tor_mmap_file(const char *filename) ATTR_NONNULL((1));
331 int tor_munmap_file(tor_mmap_t *handle) ATTR_NONNULL((1));
332 
333 int tor_snprintf(char *str, size_t size, const char *format, ...)
334  CHECK_PRINTF(3,4) ATTR_NONNULL((1,3));
335 int tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
336  CHECK_PRINTF(3,0) ATTR_NONNULL((1,3));
337 
338 int tor_asprintf(char **strp, const char *fmt, ...)
339  CHECK_PRINTF(2,3);
340 int tor_vasprintf(char **strp, const char *fmt, va_list args)
341  CHECK_PRINTF(2,0);
342 
343 const void *tor_memmem(const void *haystack, size_t hlen, const void *needle,
344  size_t nlen) ATTR_NONNULL((1,3));
345 static const void *tor_memstr(const void *haystack, size_t hlen,
346  const char *needle) ATTR_NONNULL((1,3));
347 static inline const void *
348 tor_memstr(const void *haystack, size_t hlen, const char *needle)
349 {
350  return tor_memmem(haystack, hlen, needle, strlen(needle));
351 }
352 
353 /* Much of the time when we're checking ctypes, we're doing spec compliance,
354  * which all assumes we're doing ASCII. */
355 #define DECLARE_CTYPE_FN(name) \
356  static int TOR_##name(char c); \
357  extern const uint32_t TOR_##name##_TABLE[]; \
358  static inline int TOR_##name(char c) { \
359  uint8_t u = c; \
360  return !!(TOR_##name##_TABLE[(u >> 5) & 7] & (1u << (u & 31))); \
361  }
362 DECLARE_CTYPE_FN(ISALPHA)
363 DECLARE_CTYPE_FN(ISALNUM)
364 DECLARE_CTYPE_FN(ISSPACE)
365 DECLARE_CTYPE_FN(ISDIGIT)
366 DECLARE_CTYPE_FN(ISXDIGIT)
367 DECLARE_CTYPE_FN(ISPRINT)
368 DECLARE_CTYPE_FN(ISLOWER)
369 DECLARE_CTYPE_FN(ISUPPER)
370 extern const uint8_t TOR_TOUPPER_TABLE[];
371 extern const uint8_t TOR_TOLOWER_TABLE[];
372 #define TOR_TOLOWER(c) (TOR_TOLOWER_TABLE[(uint8_t)c])
373 #define TOR_TOUPPER(c) (TOR_TOUPPER_TABLE[(uint8_t)c])
374 
375 char *tor_strtok_r_impl(char *str, const char *sep, char **lasts);
376 #ifdef HAVE_STRTOK_R
377 #define tor_strtok_r(str, sep, lasts) strtok_r(str, sep, lasts)
378 #else
379 #define tor_strtok_r(str, sep, lasts) tor_strtok_r_impl(str, sep, lasts)
380 #endif
381 
382 #ifdef _WIN32
383 #define SHORT_FILE__ (tor_fix_source_file(__FILE__))
384 const char *tor_fix_source_file(const char *fname);
385 #else
386 #define SHORT_FILE__ (__FILE__)
387 #define tor_fix_source_file(s) (s)
388 #endif /* defined(_WIN32) */
389 
390 /* ===== Time compatibility */
391 
392 struct tm *tor_localtime_r(const time_t *timep, struct tm *result);
393 struct tm *tor_gmtime_r(const time_t *timep, struct tm *result);
394 
395 #ifndef timeradd
396 
398 #define timeradd(tv1,tv2,tvout) \
399  do { \
400  (tvout)->tv_sec = (tv1)->tv_sec + (tv2)->tv_sec; \
401  (tvout)->tv_usec = (tv1)->tv_usec + (tv2)->tv_usec; \
402  if ((tvout)->tv_usec >= 1000000) { \
403  (tvout)->tv_usec -= 1000000; \
404  (tvout)->tv_sec++; \
405  } \
406  } while (0)
407 #endif /* !defined(timeradd) */
408 
409 #ifndef timersub
410 
412 #define timersub(tv1,tv2,tvout) \
413  do { \
414  (tvout)->tv_sec = (tv1)->tv_sec - (tv2)->tv_sec; \
415  (tvout)->tv_usec = (tv1)->tv_usec - (tv2)->tv_usec; \
416  if ((tvout)->tv_usec < 0) { \
417  (tvout)->tv_usec += 1000000; \
418  (tvout)->tv_sec--; \
419  } \
420  } while (0)
421 #endif /* !defined(timersub) */
422 
423 #ifndef timercmp
424 
431 #define timercmp(tv1,tv2,op) \
432  (((tv1)->tv_sec == (tv2)->tv_sec) ? \
433  ((tv1)->tv_usec op (tv2)->tv_usec) : \
434  ((tv1)->tv_sec op (tv2)->tv_sec))
435 #endif /* !defined(timercmp) */
436 
437 /* ===== File compatibility */
438 int tor_open_cloexec(const char *path, int flags, unsigned mode);
439 FILE *tor_fopen_cloexec(const char *path, const char *mode);
440 int tor_rename(const char *path_old, const char *path_new);
441 
442 int replace_file(const char *from, const char *to);
443 int touch_file(const char *fname);
444 
445 typedef struct tor_lockfile_t tor_lockfile_t;
446 tor_lockfile_t *tor_lockfile_lock(const char *filename, int blocking,
447  int *locked_out);
448 void tor_lockfile_unlock(tor_lockfile_t *lockfile);
449 
450 off_t tor_fd_getpos(int fd);
451 int tor_fd_setpos(int fd, off_t pos);
452 int tor_fd_seekend(int fd);
453 int tor_ftruncate(int fd);
454 
455 int64_t tor_get_avail_disk_space(const char *path);
456 
457 #ifdef _WIN32
458 #define PATH_SEPARATOR "\\"
459 #else
460 #define PATH_SEPARATOR "/"
461 #endif
462 
463 /* ===== Net compatibility */
464 
465 #if (SIZEOF_SOCKLEN_T == 0)
466 typedef int socklen_t;
467 #endif
468 
469 #ifdef _WIN32
470 /* XXX Actually, this should arguably be SOCKET; we use intptr_t here so that
471  * any inadvertent checks for the socket being <= 0 or > 0 will probably
472  * still work. */
473 #define tor_socket_t intptr_t
474 #define TOR_SOCKET_T_FORMAT INTPTR_T_FORMAT
475 #define SOCKET_OK(s) ((SOCKET)(s) != INVALID_SOCKET)
476 #define TOR_INVALID_SOCKET INVALID_SOCKET
477 #else /* !(defined(_WIN32)) */
478 
479 #define tor_socket_t int
480 #define TOR_SOCKET_T_FORMAT "%d"
481 
482 #define SOCKET_OK(s) ((s) >= 0)
483 
484 #define TOR_INVALID_SOCKET (-1)
485 #endif /* defined(_WIN32) */
486 
487 int tor_close_socket_simple(tor_socket_t s);
488 MOCK_DECL(int, tor_close_socket, (tor_socket_t s));
489 void tor_take_socket_ownership(tor_socket_t s);
491  int domain, int type, int protocol,
492  int cloexec, int nonblock);
493 MOCK_DECL(tor_socket_t,
494 tor_open_socket,(int domain, int type, int protocol));
495 tor_socket_t tor_open_socket_nonblocking(int domain, int type, int protocol);
496 tor_socket_t tor_accept_socket(tor_socket_t sockfd, struct sockaddr *addr,
497  socklen_t *len);
498 tor_socket_t tor_accept_socket_nonblocking(tor_socket_t sockfd,
499  struct sockaddr *addr,
500  socklen_t *len);
501 tor_socket_t tor_accept_socket_with_extensions(tor_socket_t sockfd,
502  struct sockaddr *addr,
503  socklen_t *len,
504  int cloexec, int nonblock);
505 MOCK_DECL(tor_socket_t,
506 tor_connect_socket,(tor_socket_t socket,const struct sockaddr *address,
507  socklen_t address_len));
508 int get_n_open_sockets(void);
509 
510 MOCK_DECL(int,
511 tor_getsockname,(tor_socket_t socket, struct sockaddr *address,
512  socklen_t *address_len));
513 struct tor_addr_t;
514 int tor_addr_from_getsockname(struct tor_addr_t *addr_out, tor_socket_t sock);
515 
516 #define tor_socket_send(s, buf, len, flags) send(s, buf, len, flags)
517 #define tor_socket_recv(s, buf, len, flags) recv(s, buf, len, flags)
518 
523 #if !defined(HAVE_STRUCT_IN6_ADDR)
524 struct in6_addr
525 {
526  union {
527  uint8_t u6_addr8[16];
528  uint16_t u6_addr16[8];
529  uint32_t u6_addr32[4];
530  } in6_u;
531 #define s6_addr in6_u.u6_addr8
532 #define s6_addr16 in6_u.u6_addr16
533 #define s6_addr32 in6_u.u6_addr32
534 };
535 #endif /* !defined(HAVE_STRUCT_IN6_ADDR) */
536 
539 #if defined(__APPLE__) || defined(__darwin__) || \
540  defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
541 #ifndef s6_addr16
542 #define s6_addr16 __u6_addr.__u6_addr16
543 #endif
544 #ifndef s6_addr32
545 #define s6_addr32 __u6_addr.__u6_addr32
546 #endif
547 #endif /* defined(__APPLE__) || defined(__darwin__) || ... */
548 
550 #ifndef HAVE_SA_FAMILY_T
551 typedef uint16_t sa_family_t;
552 #endif
553 
557 #ifdef HAVE_STRUCT_IN6_ADDR_S6_ADDR32
558 #define S6_ADDR32(x) ((uint32_t*)(x).s6_addr32)
559 #else
560 #define S6_ADDR32(x) ((uint32_t*)((char*)&(x).s6_addr))
561 #endif
562 #ifdef HAVE_STRUCT_IN6_ADDR_S6_ADDR16
563 #define S6_ADDR16(x) ((uint16_t*)(x).s6_addr16)
564 #else
565 #define S6_ADDR16(x) ((uint16_t*)((char*)&(x).s6_addr))
566 #endif
567 
571 #if !defined(HAVE_STRUCT_SOCKADDR_IN6)
572 struct sockaddr_in6 {
573  sa_family_t sin6_family;
574  uint16_t sin6_port;
575  // uint32_t sin6_flowinfo;
576  struct in6_addr sin6_addr;
577  // uint32_t sin6_scope_id;
578 };
579 #endif /* !defined(HAVE_STRUCT_SOCKADDR_IN6) */
580 
581 MOCK_DECL(int,tor_gethostname,(char *name, size_t namelen));
582 int tor_inet_aton(const char *cp, struct in_addr *addr) ATTR_NONNULL((1,2));
583 const char *tor_inet_ntop(int af, const void *src, char *dst, size_t len);
584 int tor_inet_pton(int af, const char *src, void *dst);
585 MOCK_DECL(int,tor_lookup_hostname,(const char *name, uint32_t *addr));
586 int set_socket_nonblocking(tor_socket_t socket);
587 int tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2]);
588 int network_init(void);
589 
590 /* For stupid historical reasons, windows sockets have an independent
591  * set of errnos, and an independent way to get them. Also, you can't
592  * always believe WSAEWOULDBLOCK. Use the macros below to compare
593  * errnos against expected values, and use tor_socket_errno to find
594  * the actual errno after a socket operation fails.
595  */
596 #if defined(_WIN32)
597 
598 #define SOCK_ERRNO(e) WSA##e
599 
600 #define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || (e) == WSAEWOULDBLOCK)
601 
602 #define ERRNO_IS_EINPROGRESS(e) ((e) == WSAEINPROGRESS)
603 
605 #define ERRNO_IS_CONN_EINPROGRESS(e) \
606  ((e) == WSAEINPROGRESS || (e)== WSAEINVAL || (e) == WSAEWOULDBLOCK)
607 
609 #define ERRNO_IS_ACCEPT_EAGAIN(e) ERRNO_IS_EAGAIN(e)
610 
612 #define ERRNO_IS_RESOURCE_LIMIT(e) \
613  ((e) == WSAEMFILE || (e) == WSAENOBUFS)
614 
615 #define ERRNO_IS_EADDRINUSE(e) ((e) == WSAEADDRINUSE)
616 
617 #define ERRNO_IS_EINTR(e) ((e) == WSAEINTR || 0)
618 int tor_socket_errno(tor_socket_t sock);
619 const char *tor_socket_strerror(int e);
620 #else /* !(defined(_WIN32)) */
621 #define SOCK_ERRNO(e) e
622 #if EAGAIN == EWOULDBLOCK
623 /* || 0 is for -Wparentheses-equality (-Wall?) appeasement under clang */
624 #define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || 0)
625 #else
626 #define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || (e) == EWOULDBLOCK)
627 #endif /* EAGAIN == EWOULDBLOCK */
628 #define ERRNO_IS_EINTR(e) ((e) == EINTR || 0)
629 #define ERRNO_IS_EINPROGRESS(e) ((e) == EINPROGRESS || 0)
630 #define ERRNO_IS_CONN_EINPROGRESS(e) ((e) == EINPROGRESS || 0)
631 #define ERRNO_IS_ACCEPT_EAGAIN(e) \
632  (ERRNO_IS_EAGAIN(e) || (e) == ECONNABORTED)
633 #define ERRNO_IS_RESOURCE_LIMIT(e) \
634  ((e) == EMFILE || (e) == ENFILE || (e) == ENOBUFS || (e) == ENOMEM)
635 #define ERRNO_IS_EADDRINUSE(e) (((e) == EADDRINUSE) || 0)
636 #define tor_socket_errno(sock) (errno)
637 #define tor_socket_strerror(e) strerror(e)
638 #endif /* defined(_WIN32) */
639 
641 typedef enum {
642  SOCKS5_SUCCEEDED = 0x00,
643  SOCKS5_GENERAL_ERROR = 0x01,
644  SOCKS5_NOT_ALLOWED = 0x02,
645  SOCKS5_NET_UNREACHABLE = 0x03,
646  SOCKS5_HOST_UNREACHABLE = 0x04,
647  SOCKS5_CONNECTION_REFUSED = 0x05,
648  SOCKS5_TTL_EXPIRED = 0x06,
649  SOCKS5_COMMAND_NOT_SUPPORTED = 0x07,
650  SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED = 0x08,
651 } socks5_reply_status_t;
652 
653 /* ===== OS compatibility */
654 MOCK_DECL(const char *, get_uname, (void));
655 
656 uint16_t get_uint16(const void *cp) ATTR_NONNULL((1));
657 uint32_t get_uint32(const void *cp) ATTR_NONNULL((1));
658 uint64_t get_uint64(const void *cp) ATTR_NONNULL((1));
659 void set_uint16(void *cp, uint16_t v) ATTR_NONNULL((1));
660 void set_uint32(void *cp, uint32_t v) ATTR_NONNULL((1));
661 void set_uint64(void *cp, uint64_t v) ATTR_NONNULL((1));
662 
663 /* These uint8 variants are defined to make the code more uniform. */
664 #define get_uint8(cp) (*(const uint8_t*)(cp))
665 static void set_uint8(void *cp, uint8_t v);
666 static inline void
667 set_uint8(void *cp, uint8_t v)
668 {
669  *(uint8_t*)cp = v;
670 }
671 
672 #if !defined(HAVE_RLIM_T)
673 typedef unsigned long rlim_t;
674 #endif
675 int get_max_sockets(void);
676 int set_max_file_descriptors(rlim_t limit, int *max);
678 
679 #if defined(HAVE_SYS_CAPABILITY_H) && defined(HAVE_CAP_SET_PROC)
680 #define HAVE_LINUX_CAPABILITIES
681 #endif
682 
683 int have_capability_support(void);
684 
686 #define SWITCH_ID_KEEP_BINDLOW (1<<0)
687 
688 #define SWITCH_ID_WARN_IF_NO_CAPS (1<<1)
689 int switch_id(const char *user, unsigned flags);
690 #ifdef HAVE_PWD_H
691 char *get_user_homedir(const char *username);
692 #endif
693 
694 #ifndef _WIN32
695 const struct passwd *tor_getpwnam(const char *username);
696 const struct passwd *tor_getpwuid(uid_t uid);
697 #endif
698 
699 int get_parent_directory(char *fname);
700 char *make_path_absolute(char *fname);
701 
702 char **get_environment(void);
703 
704 MOCK_DECL(int, get_total_system_memory, (size_t *mem_out));
705 
706 int compute_num_cpus(void);
707 
708 int tor_mlockall(void);
709 
716 #ifndef MAX
717 #define MAX(a,b) ( ((a)<(b)) ? (b) : (a) )
718 #endif
719 #ifndef MIN
720 #define MIN(a,b) ( ((a)>(b)) ? (b) : (a) )
721 #endif
722 
723 /* Platform-specific helpers. */
724 #ifdef _WIN32
725 char *format_win32_error(DWORD err);
726 #endif
727 
728 /*for some reason my compiler doesn't have these version flags defined
729  a nice homework assignment for someone one day is to define the rest*/
730 //these are the values as given on MSDN
731 #ifdef _WIN32
732 
733 #ifndef VER_SUITE_EMBEDDEDNT
734 #define VER_SUITE_EMBEDDEDNT 0x00000040
735 #endif
736 
737 #ifndef VER_SUITE_SINGLEUSERTS
738 #define VER_SUITE_SINGLEUSERTS 0x00000100
739 #endif
740 
741 #endif /* defined(_WIN32) */
742 
743 #ifdef COMPAT_PRIVATE
744 #if !defined(HAVE_SOCKETPAIR) || defined(_WIN32) || defined(TOR_UNIT_TESTS)
745 #define NEED_ERSATZ_SOCKETPAIR
746 STATIC int tor_ersatz_socketpair(int family, int type, int protocol,
747  tor_socket_t fd[2]);
748 #endif
749 #endif /* defined(COMPAT_PRIVATE) */
750 
751 ssize_t tor_getpass(const char *prompt, char *output, size_t buflen);
752 
753 /* This needs some of the declarations above so we include it here. */
754 #include "compat_threads.h"
755 
756 #endif /* !defined(TOR_COMPAT_H) */
757 
int tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
Definition: compat.c:1410
int set_socket_nonblocking(tor_socket_t sock)
Definition: compat.c:1369
uint64_t get_uint64(const void *cp)
Definition: compat.c:762
tor_socket_t tor_accept_socket(tor_socket_t sockfd, struct sockaddr *addr, socklen_t *len)
Definition: compat.c:1248
int fd
Definition: compat.c:841
void set_uint16(void *cp, uint16_t v)
Definition: compat.c:774
int tor_addr_from_getsockname(tor_addr_t *addr_out, tor_socket_t sock)
Definition: compat.c:1353
const uint8_t TOR_TOUPPER_TABLE[256]
Definition: compat.c:618
Definition: address.h:56
Functions and types for monotonic times.
const void * tor_memmem(const void *_haystack, size_t hlen, const void *_needle, size_t nlen)
Definition: compat.c:558
int set_max_file_descriptors(rlim_t limit, int *max_out)
Definition: compat.c:1654
int tor_rename(const char *path_old, const char *path_new)
Definition: compat.c:199
struct tm * tor_gmtime_r(const time_t *timep, struct tm *result)
Definition: compat.c:3006
int tor_fd_seekend(int fd)
Definition: compat.c:975
int compute_num_cpus(void)
Definition: compat.c:2835
MOCK_DECL(int, router_have_minimum_dir_info,(void))
int64_t tor_get_avail_disk_space(const char *path)
Definition: compat.c:3495
ssize_t tor_getpass(const char *prompt, char *output, size_t buflen)
Definition: compat.c:3420
void set_uint32(void *cp, uint32_t v)
Definition: compat.c:783
Header file to define uint32_t and friends.
int replace_file(const char *from, const char *to)
Definition: compat.c:804
uint16_t get_uint16(const void *cp)
Definition: compat.c:738
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition: compat.c:416
char * tor_strtok_r_impl(char *str, const char *sep, char **lasts)
Definition: compat.c:675
void set_uint64(void *cp, uint64_t v)
Definition: compat.c:792
char ** get_environment(void)
Definition: compat.c:2414
int tor_open_cloexec(const char *path, int flags, unsigned mode)
Definition: compat.c:150
tor_socket_t tor_open_socket_with_extensions(int domain, int type, int protocol, int cloexec, int nonblock)
Definition: compat.c:1173
struct tm * tor_localtime_r(const time_t *timep, struct tm *result)
Definition: compat.c:2963
Definition: compat.h:524
const char * tor_inet_ntop(int af, const void *src, char *dst, size_t len)
Definition: compat.c:2465
int network_init(void)
Definition: compat.c:3226
int tor_vasprintf(char **strp, const char *fmt, va_list args)
Definition: compat.c:486
int tor_asprintf(char **strp, const char *fmt,...)
Definition: compat.c:464
void tor_lockfile_unlock(tor_lockfile_t *lockfile)
Definition: compat.c:920
int touch_file(const char *fname)
Definition: compat.c:829
char * filename
Definition: compat.c:839
const char * data
Definition: compat.h:317
Definition: compat.h:316
int tor_disable_debugger_attach(void)
Definition: compat.c:2218
const struct passwd * tor_getpwnam(const char *username)
Definition: compat.c:1903
FILE * tor_fopen_cloexec(const char *path, const char *mode)
Definition: compat.c:182
int tor_close_socket_simple(tor_socket_t s)
Definition: compat.c:1056
off_t tor_fd_getpos(int fd)
Definition: compat.c:962
int tor_inet_pton(int af, const char *src, void *dst)
Definition: compat.c:2554
int get_n_open_sockets(void)
Definition: compat.c:1330
int tor_ftruncate(int fd)
Definition: compat.c:1006
int tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
Definition: compat.c:430
tor_socket_t tor_open_socket_nonblocking(int domain, int type, int protocol)
Definition: compat.c:1163
const struct passwd * tor_getpwuid(uid_t uid)
Definition: compat.c:1939
int switch_id(const char *user, const unsigned flags)
Definition: compat.c:2042
Definition: compat.h:572
tor_socket_t tor_accept_socket_nonblocking(tor_socket_t sockfd, struct sockaddr *addr, socklen_t *len)
Definition: compat.c:1256
int tor_fd_setpos(int fd, off_t pos)
Definition: compat.c:994
Definition: compat.c:837
size_t size
Definition: compat.h:318
void tor_take_socket_ownership(tor_socket_t s)
Definition: compat.c:1238
char * make_path_absolute(char *fname)
Definition: compat.c:2365
uint32_t get_uint32(const void *cp)
Definition: compat.c:750
tor_socket_t tor_accept_socket_with_extensions(tor_socket_t sockfd, struct sockaddr *addr, socklen_t *len, int cloexec, int nonblock)
Definition: compat.c:1267
int tor_mlockall(void)
Definition: compat.c:3075
int have_capability_support(void)
Definition: compat.c:1961
tor_lockfile_t * tor_lockfile_lock(const char *filename, int blocking, int *locked_out)
Definition: compat.c:862
int get_parent_directory(char *fname)
Definition: compat.c:2281
int tor_inet_aton(const char *str, struct in_addr *addr)
Definition: compat.c:2442