diff options
Diffstat (limited to 'src')
248 files changed, 4075 insertions, 2204 deletions
diff --git a/src/common/address.c b/src/common/address.c index 894e15114c..aa61b5423b 100644 --- a/src/common/address.c +++ b/src/common/address.c @@ -33,7 +33,7 @@ #include <process.h> #include <windows.h> #include <iphlpapi.h> -#endif +#endif /* defined(_WIN32) */ #include "compat.h" #include "util.h" @@ -198,7 +198,7 @@ tor_sockaddr_to_str(const struct sockaddr *sa) tor_asprintf(&result, "unix:%s", s_un->sun_path); return result; } -#endif +#endif /* defined(HAVE_SYS_UN_H) */ if (sa->sa_family == AF_UNSPEC) return tor_strdup("unspec"); @@ -305,7 +305,7 @@ tor_addr_lookup,(const char *name, uint16_t family, tor_addr_t *addr)) return result; } return (err == EAI_AGAIN) ? 1 : -1; -#else +#else /* !(defined(HAVE_GETADDRINFO)) */ struct hostent *ent; int err; #ifdef HAVE_GETHOSTBYNAME_R_6_ARG @@ -330,7 +330,7 @@ tor_addr_lookup,(const char *name, uint16_t family, tor_addr_t *addr)) #else err = h_errno; #endif -#endif /* endif HAVE_GETHOSTBYNAME_R_6_ARG. */ +#endif /* defined(HAVE_GETHOSTBYNAME_R_6_ARG) || ... */ if (ent) { if (ent->h_addrtype == AF_INET) { tor_addr_from_in(addr, (struct in_addr*) ent->h_addr); @@ -346,7 +346,7 @@ tor_addr_lookup,(const char *name, uint16_t family, tor_addr_t *addr)) #else return (err == TRY_AGAIN) ? 1 : -1; #endif -#endif +#endif /* defined(HAVE_GETADDRINFO) */ } } @@ -1409,7 +1409,7 @@ get_interface_addresses_ifaddrs(int severity, sa_family_t family) return result; } -#endif +#endif /* defined(HAVE_IFADDRS_TO_SMARTLIST) */ #ifdef HAVE_IP_ADAPTER_TO_SMARTLIST @@ -1500,7 +1500,7 @@ get_interface_addresses_win32(int severity, sa_family_t family) return result; } -#endif +#endif /* defined(HAVE_IP_ADAPTER_TO_SMARTLIST) */ #ifdef HAVE_IFCONF_TO_SMARTLIST @@ -1602,7 +1602,7 @@ get_interface_addresses_ioctl(int severity, sa_family_t family) tor_free(ifc.ifc_buf); return result; } -#endif +#endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */ /** Try to ask our network interfaces what addresses they are bound to. * Return a new smartlist of tor_addr_t on success, and NULL on failure. diff --git a/src/common/address.h b/src/common/address.h index ce85b3d81d..c7f6935754 100644 --- a/src/common/address.h +++ b/src/common/address.h @@ -44,7 +44,7 @@ #endif // TODO win32 specific includes -#endif // ADDRESS_PRIVATE +#endif /* defined(ADDRESS_PRIVATE) */ /** The number of bits from an address to consider while doing a masked * comparison. */ @@ -358,23 +358,23 @@ STATIC smartlist_t *ifaddrs_to_smartlist(const struct ifaddrs *ifa, sa_family_t family); STATIC smartlist_t *get_interface_addresses_ifaddrs(int severity, sa_family_t family); -#endif +#endif /* defined(HAVE_IFADDRS_TO_SMARTLIST) */ #ifdef HAVE_IP_ADAPTER_TO_SMARTLIST STATIC smartlist_t *ip_adapter_addresses_to_smartlist( const IP_ADAPTER_ADDRESSES *addresses); STATIC smartlist_t *get_interface_addresses_win32(int severity, sa_family_t family); -#endif +#endif /* defined(HAVE_IP_ADAPTER_TO_SMARTLIST) */ #ifdef HAVE_IFCONF_TO_SMARTLIST STATIC smartlist_t *ifreq_to_smartlist(char *ifr, size_t buflen); STATIC smartlist_t *get_interface_addresses_ioctl(int severity, sa_family_t family); -#endif +#endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */ -#endif // ADDRESS_PRIVATE +#endif /* defined(ADDRESS_PRIVATE) */ -#endif +#endif /* !defined(TOR_ADDRESS_H) */ diff --git a/src/common/aes.c b/src/common/aes.c index 94d33d4392..20b51a6758 100644 --- a/src/common/aes.c +++ b/src/common/aes.c @@ -70,7 +70,7 @@ ENABLE_GCC_WARNING(redundant-decls) #define USE_EVP_AES_CTR -#endif +#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_V_NOPATCH(1,1,0) || ... */ /* We have 2 strategies for getting the AES block cipher: Via OpenSSL's * AES_encrypt function, or via OpenSSL's EVP_EncryptUpdate function. @@ -142,7 +142,7 @@ evaluate_ctr_for_aes(void) { return 0; } -#else +#else /* !(defined(USE_EVP_AES_CTR)) */ /*======================================================================*/ /* Interface to AES code, and counter implementation */ @@ -163,7 +163,7 @@ struct aes_cnt_cipher { uint32_t counter2; uint32_t counter1; uint32_t counter0; -#endif +#endif /* !defined(WORDS_BIGENDIAN) */ union { /** The counter, in big-endian order, as bytes. */ @@ -212,7 +212,7 @@ evaluate_evp_for_aes(int force_val) log_info(LD_CRYPTO, "No AES engine found; using AES_* functions."); should_use_EVP = 0; } -#endif +#endif /* defined(DISABLE_ENGINES) */ return 0; } @@ -312,7 +312,7 @@ aes_set_key(aes_cnt_cipher_t *cipher, const uint8_t *key, int key_bits) cipher->counter1 = 0; cipher->counter2 = 0; cipher->counter3 = 0; -#endif +#endif /* defined(USING_COUNTER_VARS) */ memset(cipher->ctr_buf.buf, 0, sizeof(cipher->ctr_buf.buf)); @@ -341,7 +341,7 @@ aes_cipher_free(aes_cnt_cipher_t *cipher) STMT_END #else #define UPDATE_CTR_BUF(c, n) -#endif +#endif /* defined(USING_COUNTER_VARS) */ /* Helper function to use EVP with openssl's counter-mode wrapper. */ static void @@ -396,10 +396,10 @@ aes_set_iv(aes_cnt_cipher_t *cipher, const uint8_t *iv) cipher->counter2 = ntohl(get_uint32(iv+4)); cipher->counter1 = ntohl(get_uint32(iv+8)); cipher->counter0 = ntohl(get_uint32(iv+12)); -#endif +#endif /* defined(USING_COUNTER_VARS) */ cipher->pos = 0; memcpy(cipher->ctr_buf.buf, iv, 16); } -#endif +#endif /* defined(USE_EVP_AES_CTR) */ diff --git a/src/common/aes.h b/src/common/aes.h index 6fd9c3ea16..1e400a56e0 100644 --- a/src/common/aes.h +++ b/src/common/aes.h @@ -23,5 +23,5 @@ void aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len); int evaluate_evp_for_aes(int force_value); int evaluate_ctr_for_aes(void); -#endif +#endif /* !defined(TOR_AES_H) */ diff --git a/src/common/backtrace.c b/src/common/backtrace.c index 0f0fa857bf..f2498b2aa6 100644 --- a/src/common/backtrace.c +++ b/src/common/backtrace.c @@ -37,7 +37,7 @@ #include <sys/ucontext.h> #elif defined(HAVE_UCONTEXT_H) #include <ucontext.h> -#endif +#endif /* defined(HAVE_CYGWIN_SIGNAL_H) || ... */ #define EXPOSE_CLEAN_BACKTRACE #include "backtrace.h" @@ -81,16 +81,16 @@ clean_backtrace(void **stack, size_t depth, const ucontext_t *ctx) const size_t n = 2; #else const size_t n = 1; -#endif +#endif /* defined(__linux__) || ... */ if (depth <= n) return; stack[n] = (void*) ctx->PC_FROM_UCONTEXT; -#else +#else /* !(defined(PC_FROM_UCONTEXT)) */ (void) depth; (void) ctx; (void) stack; -#endif +#endif /* defined(PC_FROM_UCONTEXT) */ } /** Log a message <b>msg</b> at <b>severity</b> in <b>domain</b>, and follow @@ -202,7 +202,7 @@ remove_bt_handler(void) { tor_mutex_uninit(&cb_buf_mutex); } -#endif +#endif /* defined(USE_BACKTRACE) */ #ifdef NO_BACKTRACE_IMPL void @@ -221,7 +221,7 @@ static void remove_bt_handler(void) { } -#endif +#endif /* defined(NO_BACKTRACE_IMPL) */ /** Set up code to handle generating error messages on crashes. */ int diff --git a/src/common/backtrace.h b/src/common/backtrace.h index 8cd1dcf06c..3d0ab8a90a 100644 --- a/src/common/backtrace.h +++ b/src/common/backtrace.h @@ -15,7 +15,7 @@ void clean_up_backtrace_handler(void); defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) void clean_backtrace(void **stack, size_t depth, const ucontext_t *ctx); #endif -#endif +#endif /* defined(EXPOSE_CLEAN_BACKTRACE) */ -#endif +#endif /* !defined(TOR_BACKTRACE_H) */ diff --git a/src/common/buffers.c b/src/common/buffers.c index 9583c70361..55a30092ee 100644 --- a/src/common/buffers.c +++ b/src/common/buffers.c @@ -39,7 +39,7 @@ #define check() STMT_BEGIN buf_assert_ok(buf); STMT_END #else #define check() STMT_NIL -#endif +#endif /* defined(PARANOIA) */ /* Implementation notes: * @@ -98,7 +98,7 @@ DBG_S(tor_assert(a == b)); \ memset(a,0,SENTINEL_LEN); \ } while (0) -#endif +#endif /* defined(DISABLE_MEMORY_SENTINELS) */ /** Move all bytes stored in <b>chunk</b> to the front of <b>chunk</b>->mem, * to free up space at the end. */ @@ -311,7 +311,7 @@ buf_new_with_data(const char *cp, size_t sz) return buf; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /** Remove the first <b>n</b> bytes from buf. */ void diff --git a/src/common/buffers.h b/src/common/buffers.h index 5a52b2a81c..1eaa5f2d04 100644 --- a/src/common/buffers.h +++ b/src/common/buffers.h @@ -119,7 +119,7 @@ CHUNK_WRITE_PTR(chunk_t *chunk) return chunk->data + chunk->datalen; } -#endif +#endif /* defined(BUFFERS_PRIVATE) */ -#endif +#endif /* !defined(TOR_BUFFERS_H) */ diff --git a/src/common/buffers_tls.h b/src/common/buffers_tls.h index e91dfeba0b..2f9fda45a0 100644 --- a/src/common/buffers_tls.h +++ b/src/common/buffers_tls.h @@ -15,5 +15,5 @@ int buf_read_from_tls(struct buf_t *buf, int buf_flush_to_tls(struct buf_t *buf, struct tor_tls_t *tls, size_t sz, size_t *buf_flushlen); -#endif +#endif /* !defined(TOR_BUFFERS_TLS_H) */ diff --git a/src/common/compat.c b/src/common/compat.c index ab117f7c72..ab1fbc64fe 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -88,12 +88,12 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt) while (cnt--) *vcptr++ = 0; } -#endif +#endif /* defined(HAVE_DECL_SECUREZEROMEMORY) && !HAVE_DECL_SECUREZEROMEMORY */ #elif defined(HAVE_READPASSPHRASE_H) #include <readpassphrase.h> #else #include "tor_readpassphrase.h" -#endif +#endif /* defined(_WIN32) || ... */ /* Includes for the process attaching prevention */ #if defined(HAVE_SYS_PRCTL_H) && defined(__linux__) @@ -102,7 +102,7 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt) #elif defined(__APPLE__) #include <sys/types.h> #include <sys/ptrace.h> -#endif +#endif /* defined(HAVE_SYS_PRCTL_H) && defined(__linux__) || ... */ #ifdef HAVE_NETDB_H #include <netdb.h> @@ -161,7 +161,7 @@ tor_open_cloexec(const char *path, int flags, unsigned mode) * are running on one without. */ if (errno != EINVAL) return -1; -#endif +#endif /* defined(O_CLOEXEC) */ log_debug(LD_FS, "Opening %s with flags %x", p, flags); fd = open(p, flags, mode); @@ -173,7 +173,7 @@ tor_open_cloexec(const char *path, int flags, unsigned mode) return -1; } } -#endif +#endif /* defined(FD_CLOEXEC) */ return fd; } @@ -191,7 +191,7 @@ tor_fopen_cloexec(const char *path, const char *mode) return NULL; } } -#endif +#endif /* defined(FD_CLOEXEC) */ return result; } @@ -212,7 +212,8 @@ tor_rename(const char *path_old, const char *path_new) #define COMPAT_HAS_MMAN_AND_PAGESIZE #endif -#if defined(COMPAT_HAS_MMAN_AND_PAGESIZE) || defined(RUNNING_DOXYGEN) +#if defined(COMPAT_HAS_MMAN_AND_PAGESIZE) || \ + defined(RUNNING_DOXYGEN) /** Try to create a memory mapping for <b>filename</b> and return it. On * failure, return NULL. Sets errno properly, using ERANGE to mean * "empty file". */ @@ -450,7 +451,7 @@ tor_munmap_file(tor_mmap_t *handle) /* Can't fail in this mmap()/munmap()-free case */ return 0; } -#endif +#endif /* defined(COMPAT_HAS_MMAN_AND_PAGESIZE) || ... || ... */ /** Replacement for snprintf. Differs from platform snprintf in two * ways: First, always NUL-terminates its output. Second, always @@ -590,7 +591,7 @@ tor_vasprintf(char **strp, const char *fmt, va_list args) } *strp = strp_tmp; return len; -#endif +#endif /* defined(HAVE_VASPRINTF) || ... */ } /** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at @@ -636,7 +637,7 @@ tor_memmem(const void *_haystack, size_t hlen, } } return NULL; -#endif +#endif /* defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2) */ } /** @@ -774,7 +775,7 @@ tor_fix_source_file(const char *fname) } return r; } -#endif +#endif /* defined(_WIN32) */ /** * Read a 16-bit value beginning at <b>cp</b>. Equivalent to @@ -868,7 +869,7 @@ replace_file(const char *from, const char *to) return -1; } return tor_rename(from,to); -#endif +#endif /* !defined(_WIN32) */ } /** Change <b>fname</b>'s modification time to now. */ @@ -954,7 +955,7 @@ tor_lockfile_lock(const char *filename, int blocking, int *locked_out) return NULL; } } -#endif +#endif /* defined(_WIN32) || ... */ result = tor_malloc(sizeof(tor_lockfile_t)); result->filename = tor_strdup(filename); @@ -982,7 +983,7 @@ tor_lockfile_unlock(tor_lockfile_t *lockfile) } #else /* Closing the lockfile is sufficient. */ -#endif +#endif /* defined(_WIN32) || ... */ close(lockfile->fd); lockfile->fd = -1; @@ -1030,9 +1031,9 @@ tor_fd_seekend(int fd) * no need to worry. */ if (rc < 0 && errno == ESPIPE) rc = 0; -#endif +#endif /* defined(ESPIPE) */ return (rc < 0) ? -1 : 0; -#endif +#endif /* defined(_WIN32) */ } /** Move <b>fd</b> to position <b>pos</b> in the file. Return -1 on error, 0 @@ -1071,7 +1072,7 @@ tor_ftruncate(int fd) static bitarray_t *open_sockets = NULL; /** The size of <b>open_sockets</b>, in bits. */ static int max_socket = -1; -#endif +#endif /* defined(DEBUG_SOCKET_COUNTING) */ /** Count of number of sockets currently open. (Undercounts sockets opened by * eventdns and libevent.) */ @@ -1141,7 +1142,7 @@ tor_close_socket,(tor_socket_t s)) tor_assert(open_sockets && s <= max_socket); bitarray_clear(open_sockets, s); } -#endif +#endif /* defined(DEBUG_SOCKET_COUNTING) */ if (r == 0) { --n_sockets_open; } else { @@ -1151,7 +1152,7 @@ tor_close_socket,(tor_socket_t s)) #else if (r != EBADF) --n_sockets_open; // LCOV_EXCL_LINE -- EIO and EINTR too hard to force. -#endif +#endif /* defined(_WIN32) */ r = -1; } @@ -1184,9 +1185,9 @@ mark_socket_open(tor_socket_t s) } bitarray_set(open_sockets, s); } -#else +#else /* !(defined(DEBUG_SOCKET_COUNTING)) */ #define mark_socket_open(s) STMT_NIL -#endif +#endif /* defined(DEBUG_SOCKET_COUNTING) */ /** @} */ /** As socket(), but counts the number of open sockets. */ @@ -1244,7 +1245,7 @@ tor_open_socket_with_extensions(int domain, int type, int protocol, * support, we are running on one without. */ if (errno != EINVAL) return s; -#endif /* SOCK_CLOEXEC && SOCK_NONBLOCK */ +#endif /* defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) */ s = socket(domain, type, protocol); if (! SOCKET_OK(s)) @@ -1258,9 +1259,9 @@ tor_open_socket_with_extensions(int domain, int type, int protocol, return TOR_INVALID_SOCKET; } } -#else +#else /* !(defined(FD_CLOEXEC)) */ (void)cloexec; -#endif +#endif /* defined(FD_CLOEXEC) */ if (nonblock) { if (set_socket_nonblocking(s) == -1) { @@ -1316,7 +1317,8 @@ tor_accept_socket_with_extensions(tor_socket_t sockfd, struct sockaddr *addr, return TOR_INVALID_SOCKET; } -#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) +#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) \ + && defined(SOCK_NONBLOCK) int ext_flags = (cloexec ? SOCK_CLOEXEC : 0) | (nonblock ? SOCK_NONBLOCK : 0); s = accept4(sockfd, addr, len, ext_flags); @@ -1328,7 +1330,7 @@ tor_accept_socket_with_extensions(tor_socket_t sockfd, struct sockaddr *addr, * we are missing SOCK_CLOEXEC/SOCK_NONBLOCK support. */ if (errno != EINVAL && errno != ENOSYS) return s; -#endif +#endif /* defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) ... */ s = accept(sockfd, addr, len); if (!SOCKET_OK(s)) @@ -1342,9 +1344,9 @@ tor_accept_socket_with_extensions(tor_socket_t sockfd, struct sockaddr *addr, return TOR_INVALID_SOCKET; } } -#else +#else /* !(defined(FD_CLOEXEC)) */ (void)cloexec; -#endif +#endif /* defined(FD_CLOEXEC) */ if (nonblock) { if (set_socket_nonblocking(s) == -1) { @@ -1404,7 +1406,7 @@ set_socket_nonblocking(tor_socket_t sock) log_warn(LD_NET, "Couldn't set file status flags: %s", strerror(errno)); return -1; } -#endif +#endif /* defined(_WIN32) */ return 0; } @@ -1442,7 +1444,7 @@ tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2]) * are running on one without. */ if (errno != EINVAL) return -errno; -#endif +#endif /* defined(SOCK_CLOEXEC) */ r = socketpair(family, type, protocol, fd); if (r < 0) @@ -1465,7 +1467,7 @@ tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2]) return -errno; } } -#endif +#endif /* defined(FD_CLOEXEC) */ goto sockets_ok; /* So that sockets_ok will not be unused. */ sockets_ok: @@ -1481,9 +1483,9 @@ tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2]) socket_accounting_unlock(); return 0; -#else +#else /* !(defined(HAVE_SOCKETPAIR) && !defined(_WIN32)) */ return tor_ersatz_socketpair(family, type, protocol, fd); -#endif +#endif /* defined(HAVE_SOCKETPAIR) && !defined(_WIN32) */ } #ifdef NEED_ERSATZ_SOCKETPAIR @@ -1640,7 +1642,7 @@ tor_ersatz_socketpair(int family, int type, int protocol, tor_socket_t fd[2]) #undef SIZEOF_SOCKADDR -#endif +#endif /* defined(NEED_ERSATZ_SOCKETPAIR) */ /* Return the maximum number of allowed sockets. */ int @@ -1694,7 +1696,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out) #else const char *platform = "unknown platforms with no getrlimit()"; const unsigned long MAX_CONNECTIONS = 15000; -#endif +#endif /* defined(CYGWIN) || defined(__CYGWIN__) || ... */ log_fn(LOG_INFO, LD_NET, "This platform is missing getrlimit(). Proceeding."); if (limit > MAX_CONNECTIONS) { @@ -1705,7 +1707,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out) return -1; } limit = MAX_CONNECTIONS; -#else /* HAVE_GETRLIMIT */ +#else /* !(!defined(HAVE_GETRLIMIT)) */ struct rlimit rlim; if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) { @@ -1754,7 +1756,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out) bad = 0; } } -#endif /* OPEN_MAX */ +#endif /* defined(OPEN_MAX) */ if (bad) { log_warn(LD_CONFIG,"Couldn't set maximum number of file descriptors: %s", strerror(errno)); @@ -1763,7 +1765,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out) } /* leave some overhead for logs, etc, */ limit = rlim.rlim_cur; -#endif /* HAVE_GETRLIMIT */ +#endif /* !defined(HAVE_GETRLIMIT) */ if (limit > INT_MAX) limit = INT_MAX; @@ -1801,7 +1803,7 @@ log_credential_status(void) "UID is %u (real), %u (effective), %u (saved)", (unsigned)ruid, (unsigned)euid, (unsigned)suid); } -#else +#else /* !(defined(HAVE_GETRESUID)) */ /* getresuid is not present on MacOS X, so we can't get the saved (E)UID */ ruid = getuid(); euid = geteuid(); @@ -1810,7 +1812,7 @@ log_credential_status(void) log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "UID is %u (real), %u (effective), unknown (saved)", (unsigned)ruid, (unsigned)euid); -#endif +#endif /* defined(HAVE_GETRESUID) */ /* log GIDs */ #ifdef HAVE_GETRESGID @@ -1822,7 +1824,7 @@ log_credential_status(void) "GID is %u (real), %u (effective), %u (saved)", (unsigned)rgid, (unsigned)egid, (unsigned)sgid); } -#else +#else /* !(defined(HAVE_GETRESGID)) */ /* getresgid is not present on MacOS X, so we can't get the saved (E)GID */ rgid = getgid(); egid = getegid(); @@ -1830,7 +1832,7 @@ log_credential_status(void) log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "GID is %u (real), %u (effective), unknown (saved)", (unsigned)rgid, (unsigned)egid); -#endif +#endif /* defined(HAVE_GETRESGID) */ /* log supplementary groups */ sup_gids_size = 64; @@ -1870,7 +1872,7 @@ log_credential_status(void) return 0; } -#endif +#endif /* !defined(_WIN32) */ #ifndef _WIN32 /** Cached struct from the last getpwname() call we did successfully. */ @@ -1970,7 +1972,7 @@ tor_getpwuid(uid_t uid) return NULL; } -#endif +#endif /* !defined(_WIN32) */ /** Return true iff we were compiled with capability support, and capabilities * seem to work. **/ @@ -1983,9 +1985,9 @@ have_capability_support(void) return 0; cap_free(caps); return 1; -#else +#else /* !(defined(HAVE_LINUX_CAPABILITIES)) */ return 0; -#endif +#endif /* defined(HAVE_LINUX_CAPABILITIES) */ } #ifdef HAVE_LINUX_CAPABILITIES @@ -2044,7 +2046,7 @@ drop_capabilities(int pre_setuid) return 0; } -#endif +#endif /* defined(HAVE_LINUX_CAPABILITIES) */ /** Call setuid and setgid to run as <b>user</b> and switch to their * primary group. Return 0 on success. On failure, log and return -1. @@ -2094,13 +2096,13 @@ switch_id(const char *user, const unsigned flags) if (drop_capabilities(1)) return -1; } -#else +#else /* !(defined(HAVE_LINUX_CAPABILITIES)) */ (void) keep_bindlow; if (warn_if_no_caps) { log_warn(LD_CONFIG, "KeepBindCapabilities set, but no capability support " "on this system."); } -#endif +#endif /* defined(HAVE_LINUX_CAPABILITIES) */ /* Properly switch egid,gid,euid,uid here or bail out */ if (setgroups(1, &pw->pw_gid)) { @@ -2160,7 +2162,7 @@ switch_id(const char *user, const unsigned flags) if (drop_capabilities(0)) return -1; } -#endif +#endif /* defined(HAVE_LINUX_CAPABILITIES) */ #if !defined(CYGWIN) && !defined(__CYGWIN__) /* If we tried to drop privilege to a group/user other than root, attempt to @@ -2184,7 +2186,7 @@ switch_id(const char *user, const unsigned flags) return -1; } } -#endif +#endif /* !defined(CYGWIN) && !defined(__CYGWIN__) */ /* Check what really happened */ if (log_credential_status()) { @@ -2193,8 +2195,8 @@ switch_id(const char *user, const unsigned flags) have_already_switched_id = 1; /* mark success so we never try again */ -#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && defined(HAVE_PRCTL) -#ifdef PR_SET_DUMPABLE +#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && \ + defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) if (pw->pw_uid) { /* Re-enable core dumps if we're not running as root. */ log_info(LD_CONFIG, "Re-enabling coredumps"); @@ -2202,17 +2204,16 @@ switch_id(const char *user, const unsigned flags) log_warn(LD_CONFIG, "Unable to re-enable coredumps: %s",strerror(errno)); } } -#endif -#endif +#endif /* defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && ... */ return 0; -#else +#else /* !(!defined(_WIN32)) */ (void)user; (void)flags; log_warn(LD_CONFIG, "Switching users is unsupported on your OS."); return -1; -#endif +#endif /* !defined(_WIN32) */ } /* We only use the linux prctl for now. There is no Win32 support; this may @@ -2239,15 +2240,14 @@ tor_disable_debugger_attach(void) log_debug(LD_CONFIG, "Attemping to disable debugger attachment to Tor for " "unprivileged users."); -#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && defined(HAVE_PRCTL) -#ifdef PR_SET_DUMPABLE +#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) \ + && defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) #define TRIED_TO_DISABLE r = prctl(PR_SET_DUMPABLE, 0); -#endif #elif defined(__APPLE__) && defined(PT_DENY_ATTACH) -#define TRIED_TO_DISABLE +#define TRIED_TO_ATTACH r = ptrace(PT_DENY_ATTACH, 0, 0, 0); -#endif +#endif /* defined(__linux__) && defined(HAVE_SYS_PRCTL_H) ... || ... */ // XXX: TODO - Mac OS X has dtrace and this may be disabled. // XXX: TODO - Windows probably has something similar @@ -2260,7 +2260,7 @@ tor_disable_debugger_attach(void) log_warn(LD_CONFIG, "Unable to disable debugger attaching: %s", strerror(errno)); } -#endif +#endif /* defined(TRIED_TO_DISABLE) */ #undef TRIED_TO_DISABLE return r; } @@ -2280,7 +2280,7 @@ get_user_homedir(const char *username) } return tor_strdup(pw->pw_dir); } -#endif +#endif /* defined(HAVE_PWD_H) */ /** Modify <b>fname</b> to contain the name of its parent directory. Doesn't * actually examine the filesystem; does a purely syntactic modification. @@ -2308,7 +2308,7 @@ get_parent_directory(char *fname) if (fname[0] && fname[1] == ':') { fname += 2; } -#endif +#endif /* defined(_WIN32) */ /* Now we want to remove all path-separators at the end of the string, * and to remove the end of the string starting with the path separator * before the last non-path-separator. In perl, this would be @@ -2357,7 +2357,7 @@ alloc_getcwd(void) raw_free(cwd); // alias for free to avoid tripping check-spaces. } return result; -#else +#else /* !(defined(HAVE_GET_CURRENT_DIR_NAME)) */ size_t size = 1024; char *buf = NULL; char *ptr = NULL; @@ -2374,9 +2374,9 @@ alloc_getcwd(void) size *= 2; } return buf; -#endif +#endif /* defined(HAVE_GET_CURRENT_DIR_NAME) */ } -#endif +#endif /* !defined(_WIN32) */ /** Expand possibly relative path <b>fname</b> to an absolute path. * Return a newly allocated string, possibly equal to <b>fname</b>. */ @@ -2392,7 +2392,7 @@ make_path_absolute(char *fname) if (absfname_malloced) raw_free(absfname_malloced); return absfname; -#else +#else /* !(defined(_WIN32)) */ char *absfname = NULL, *path = NULL; tor_assert(fname); @@ -2415,7 +2415,7 @@ make_path_absolute(char *fname) } } return absfname; -#endif +#endif /* defined(_WIN32) */ } #ifndef HAVE__NSGETENVIRON @@ -2424,8 +2424,8 @@ make_path_absolute(char *fname) #ifndef RUNNING_DOXYGEN extern char **environ; #endif -#endif -#endif +#endif /* !defined(HAVE_EXTERN_ENVIRON_DECLARED) */ +#endif /* !defined(HAVE__NSGETENVIRON) */ /** Return the current environment. This is a portable replacement for * 'environ'. */ @@ -2437,9 +2437,9 @@ get_environment(void) * when we do a mostly-static build on OSX 10.7, the resulting binary won't * work on OSX 10.6. */ return *_NSGetEnviron(); -#else +#else /* !(defined(HAVE__NSGETENVIRON)) */ return environ; -#endif +#endif /* defined(HAVE__NSGETENVIRON) */ } /** Get name of current host and write it to <b>name</b> array, whose @@ -2717,7 +2717,7 @@ get_uname,(void)) /* (Linux says 0 is success, Solaris says 1 is success) */ strlcpy(uname_result, u.sysname, sizeof(uname_result)); } else -#endif +#endif /* defined(HAVE_UNAME) */ { #ifdef _WIN32 OSVERSIONINFOEX info; @@ -2779,12 +2779,12 @@ get_uname,(void)) info.wProductType == VER_NT_DOMAIN_CONTROLLER) { strlcat(uname_result, " [server]", sizeof(uname_result)); } -#endif -#else +#endif /* defined(VER_NT_SERVER) */ +#else /* !(defined(_WIN32)) */ /* LCOV_EXCL_START -- can't provoke uname failure */ strlcpy(uname_result, "Unknown platform", sizeof(uname_result)); /* LCOV_EXCL_STOP */ -#endif +#endif /* defined(_WIN32) */ } uname_result_is_set = 1; } @@ -2840,7 +2840,7 @@ compute_num_cpus_impl(void) return -1; #else return -1; -#endif +#endif /* defined(_WIN32) || ... */ } #define MAX_DETECTABLE_CPUS 16 @@ -3003,7 +3003,7 @@ tor_localtime_r(const time_t *timep, struct tm *result) memcpy(result, r, sizeof(struct tm)); return correct_tm(1, timep, result, r); } -#endif +#endif /* defined(HAVE_LOCALTIME_R) || ... */ /** @} */ /** @{ */ @@ -3046,9 +3046,13 @@ tor_gmtime_r(const time_t *timep, struct tm *result) memcpy(result, r, sizeof(struct tm)); return correct_tm(0, timep, result, r); } -#endif +#endif /* defined(HAVE_GMTIME_R) || ... */ #if defined(HAVE_MLOCKALL) && HAVE_DECL_MLOCKALL && defined(RLIMIT_MEMLOCK) +#define HAVE_UNIX_MLOCKALL +#endif + +#ifdef HAVE_UNIX_MLOCKALL /** Attempt to raise the current and max rlimit to infinity for our process. * This only needs to be done once and can probably only be done when we have * not already dropped privileges. @@ -3079,7 +3083,7 @@ tor_set_max_memlock(void) return 0; } -#endif +#endif /* defined(HAVE_UNIX_MLOCKALL) */ /** Attempt to lock all current and all future memory pages. * This should only be called once and while we're privileged. @@ -3104,7 +3108,7 @@ tor_mlockall(void) * http://msdn.microsoft.com/en-us/library/aa366895(VS.85).aspx */ -#if defined(HAVE_MLOCKALL) && HAVE_DECL_MLOCKALL && defined(RLIMIT_MEMLOCK) +#ifdef HAVE_UNIX_MLOCKALL if (tor_set_max_memlock() == 0) { log_debug(LD_GENERAL, "RLIMIT_MEMLOCK is now set to RLIM_INFINITY."); } @@ -3125,10 +3129,10 @@ tor_mlockall(void) "pages: %s", strerror(errno)); return -1; } -#else +#else /* !(defined(HAVE_UNIX_MLOCKALL)) */ log_warn(LD_GENERAL, "Unable to lock memory pages. mlockall() unsupported?"); return -1; -#endif +#endif /* defined(HAVE_UNIX_MLOCKALL) */ } /** @@ -3156,7 +3160,7 @@ tor_socket_errno(tor_socket_t sock) } return err; } -#endif +#endif /* defined(_WIN32) */ #if defined(_WIN32) #define E(code, s) { code, (s " [" #code " ]") } @@ -3232,7 +3236,7 @@ tor_socket_strerror(int e) } return strerror(e); } -#endif +#endif /* defined(_WIN32) */ /** Called before we make any calls to network-related functions. * (Some operating systems require their network libraries to be @@ -3258,7 +3262,7 @@ network_init(void) /* WSAData.iMaxSockets might show the max sockets we're allowed to use. * We might use it to complain if we're trying to be a server but have * too few sockets available. */ -#endif +#endif /* defined(_WIN32) */ return 0; } @@ -3294,9 +3298,9 @@ format_win32_error(DWORD err) result = tor_malloc(len); wcstombs(result,str,len); result[len-1] = '\0'; -#else +#else /* !(defined(UNICODE)) */ result = tor_strdup(str); -#endif +#endif /* defined(UNICODE) */ } else { result = tor_strdup("<unformattable error>"); } @@ -3305,7 +3309,7 @@ format_win32_error(DWORD err) } return result; } -#endif +#endif /* defined(_WIN32) */ #if defined(HW_PHYSMEM64) /* This appears to be an OpenBSD thing */ @@ -3313,7 +3317,7 @@ format_win32_error(DWORD err) #elif defined(HW_MEMSIZE) /* OSX defines this one */ #define INT64_HW_MEM HW_MEMSIZE -#endif +#endif /* defined(HW_PHYSMEM64) || ... */ /** * Helper: try to detect the total system memory, and return it. On failure, @@ -3387,7 +3391,7 @@ get_total_system_memory_impl(void) #else /* I have no clue. */ return 0; -#endif +#endif /* defined(__linux__) || ... */ } /** @@ -3420,7 +3424,7 @@ get_total_system_memory(size_t *mem_out) * size_t. */ m = SIZE_MAX; } -#endif +#endif /* SIZE_MAX != UINT64_MAX */ *mem_out = mem_cached = (size_t) m; @@ -3501,7 +3505,7 @@ tor_getpass(const char *prompt, char *output, size_t buflen) return r; #else #error "No implementation for tor_getpass found!" -#endif +#endif /* defined(HAVE_READPASSPHRASE) || ... */ } /** Return the amount of free disk space we have permission to use, in @@ -3541,6 +3545,6 @@ tor_get_avail_disk_space(const char *path) (void)path; errno = ENOSYS; return -1; -#endif +#endif /* defined(HAVE_STATVFS) || ... */ } diff --git a/src/common/compat.h b/src/common/compat.h index 473ad2b957..fee9e6587d 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -50,8 +50,8 @@ * clang rejects because it is off the end of a less-than-3. Clang hates this, * even though those references never actually happen. */ # undef strcmp -# endif -#endif +#endif /* __has_feature(address_sanitizer) */ +#endif /* defined(__has_feature) */ #include <stdio.h> #include <errno.h> @@ -76,13 +76,13 @@ __attribute__ ((format(printf, formatIdx, firstArg))) #else #define CHECK_PRINTF(formatIdx, firstArg) -#endif +#endif /* defined(__GNUC__) */ #ifdef __GNUC__ #define CHECK_SCANF(formatIdx, firstArg) \ __attribute__ ((format(scanf, formatIdx, firstArg))) #else #define CHECK_SCANF(formatIdx, firstArg) -#endif +#endif /* defined(__GNUC__) */ /* What GCC do we have? */ #ifdef __GNUC__ @@ -109,18 +109,18 @@ PRAGMA_DIAGNOSTIC_(ignored PRAGMA_JOIN_STRINGIFY_(-W,warningopt)) # define ENABLE_GCC_WARNING(warningopt) \ PRAGMA_DIAGNOSTIC_(pop) -# else +#else /* !(defined(__clang__) || GCC_VERSION >= 406) */ /* older version of gcc: no push/pop support. */ # define DISABLE_GCC_WARNING(warningopt) \ PRAGMA_DIAGNOSTIC_(ignored PRAGMA_JOIN_STRINGIFY_(-W,warningopt)) # define ENABLE_GCC_WARNING(warningopt) \ PRAGMA_DIAGNOSTIC_(warning PRAGMA_JOIN_STRINGIFY_(-W,warningopt)) -# endif -#else /* ifdef __GNUC__ */ +#endif /* defined(__clang__) || GCC_VERSION >= 406 */ +#else /* !(defined(__GNUC__)) */ /* not gcc at all */ # define DISABLE_GCC_WARNING(warning) # define ENABLE_GCC_WARNING(warning) -#endif +#endif /* defined(__GNUC__) */ /* inline is __inline on windows. */ #ifdef _WIN32 @@ -142,9 +142,9 @@ #define __func__ __FUNC__ #else #define __func__ "???" -#endif -#endif /* ifndef MAVE_MACRO__func__ */ -#endif /* if not windows */ +#endif /* defined(HAVE_MACRO__FUNCTION__) || ... */ +#endif /* !defined(HAVE_MACRO__func__) */ +#endif /* defined(_MSC_VER) */ #define U64_TO_DBL(x) ((double) (x)) #define DBL_TO_U64(x) ((uint64_t) (x)) @@ -157,7 +157,7 @@ * problems), but if enumerated types are unsigned, we must use unsigned, * so that the loss of precision doesn't make large values negative. */ #define ENUM_BF(t) t -#endif +#endif /* defined(ENUM_VALS_ARE_SIGNED) */ /* GCC has several useful attributes. */ #if defined(__GNUC__) && __GNUC__ >= 3 @@ -194,7 +194,7 @@ * taken. This can generate slightly better code with some CPUs. */ #define PREDICT_UNLIKELY(exp) __builtin_expect(!!(exp), 0) -#else +#else /* !(defined(__GNUC__) && __GNUC__ >= 3) */ #define ATTR_NORETURN #define ATTR_CONST #define ATTR_MALLOC @@ -204,7 +204,7 @@ #define ATTR_WUR #define PREDICT_LIKELY(exp) (exp) #define PREDICT_UNLIKELY(exp) (exp) -#endif +#endif /* defined(__GNUC__) && __GNUC__ >= 3 */ /** Expands to a syntactically valid empty statement. */ #define STMT_NIL (void)0 @@ -224,7 +224,7 @@ #else #define STMT_BEGIN do { #define STMT_END } while (0) -#endif +#endif /* defined(__GNUC__) || ... */ /* Some tools (like coccinelle) don't like to see operators as macro * arguments. */ @@ -251,7 +251,7 @@ */ #undef strlcat #undef strlcpy -#endif +#endif /* defined __APPLE__ */ #ifndef HAVE_STRLCAT size_t strlcat(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2)); @@ -272,24 +272,28 @@ size_t strlcpy(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2)); #define I64_PRINTF_ARG(a) (a) #define I64_SCANF_ARG(a) (a) #define I64_LITERAL(n) (n ## i64) -#else +#else /* !(defined(_MSC_VER)) */ #define U64_PRINTF_ARG(a) ((long long unsigned int)(a)) #define U64_SCANF_ARG(a) ((long long unsigned int*)(a)) #define U64_LITERAL(n) (n ## llu) #define I64_PRINTF_ARG(a) ((long long signed int)(a)) #define I64_SCANF_ARG(a) ((long long signed int*)(a)) #define I64_LITERAL(n) (n ## ll) +#endif /* defined(_MSC_VER) */ + +#if defined(__MINGW32__) || defined(__MINGW64__) +#define MINGW_ANY #endif -#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) +#if defined(_MSC_VER) || defined(MINGW_ANY) /** The formatting string used to put a uint64_t value in a printf() or * scanf() function. See also U64_PRINTF_ARG and U64_SCANF_ARG. */ #define U64_FORMAT "%I64u" #define I64_FORMAT "%I64d" -#else +#else /* !(defined(_MSC_VER) || defined(MINGW_ANY)) */ #define U64_FORMAT "%llu" #define I64_FORMAT "%lld" -#endif +#endif /* defined(_MSC_VER) || defined(MINGW_ANY) */ #if (SIZEOF_INTPTR_T == SIZEOF_INT) #define INTPTR_T_FORMAT "%d" @@ -302,7 +306,7 @@ size_t strlcpy(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2)); #define INTPTR_PRINTF_ARG(x) I64_PRINTF_ARG(x) #else #error Unknown: SIZEOF_INTPTR_T -#endif +#endif /* (SIZEOF_INTPTR_T == SIZEOF_INT) || ... */ /** Represents an mmaped file. Allocated via tor_mmap_file; freed with * tor_munmap_file. */ @@ -316,7 +320,7 @@ typedef struct tor_mmap_t { * size, rounded up to the nearest page.) */ #elif defined _WIN32 HANDLE mmap_handle; -#endif +#endif /* defined(HAVE_SYS_MMAN_H) || ... */ } tor_mmap_t; @@ -378,7 +382,7 @@ const char *tor_fix_source_file(const char *fname); #else #define SHORT_FILE__ (__FILE__) #define tor_fix_source_file(s) (s) -#endif +#endif /* defined(_WIN32) */ /* ===== Time compatibility */ @@ -397,7 +401,7 @@ struct tm *tor_gmtime_r(const time_t *timep, struct tm *result); (tvout)->tv_sec++; \ } \ } while (0) -#endif +#endif /* !defined(timeradd) */ #ifndef timersub /** Replacement for timersub on platforms that do not have it: sets tvout to @@ -411,7 +415,7 @@ struct tm *tor_gmtime_r(const time_t *timep, struct tm *result); (tvout)->tv_sec--; \ } \ } while (0) -#endif +#endif /* !defined(timersub) */ #ifndef timercmp /** Replacement for timercmp on platforms that do not have it: returns true @@ -425,7 +429,7 @@ struct tm *tor_gmtime_r(const time_t *timep, struct tm *result); (((tv1)->tv_sec == (tv2)->tv_sec) ? \ ((tv1)->tv_usec op (tv2)->tv_usec) : \ ((tv1)->tv_sec op (tv2)->tv_sec)) -#endif +#endif /* !defined(timercmp) */ /* ===== File compatibility */ int tor_open_cloexec(const char *path, int flags, unsigned mode); @@ -467,7 +471,7 @@ typedef int socklen_t; #define TOR_SOCKET_T_FORMAT INTPTR_T_FORMAT #define SOCKET_OK(s) ((SOCKET)(s) != INVALID_SOCKET) #define TOR_INVALID_SOCKET INVALID_SOCKET -#else +#else /* !(defined(_WIN32)) */ /** Type used for a network socket. */ #define tor_socket_t int #define TOR_SOCKET_T_FORMAT "%d" @@ -475,7 +479,7 @@ typedef int socklen_t; #define SOCKET_OK(s) ((s) >= 0) /** Error/uninitialized value for a tor_socket_t. */ #define TOR_INVALID_SOCKET (-1) -#endif +#endif /* defined(_WIN32) */ int tor_close_socket_simple(tor_socket_t s); MOCK_DECL(int, tor_close_socket, (tor_socket_t s)); @@ -522,19 +526,19 @@ struct in6_addr #define s6_addr16 in6_u.u6_addr16 #define s6_addr32 in6_u.u6_addr32 }; -#endif +#endif /* !defined(HAVE_STRUCT_IN6_ADDR) */ /** @{ */ /** Many BSD variants seem not to define these. */ -#if defined(__APPLE__) || defined(__darwin__) || defined(__FreeBSD__) \ - || defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__APPLE__) || defined(__darwin__) || \ + defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #ifndef s6_addr16 #define s6_addr16 __u6_addr.__u6_addr16 #endif #ifndef s6_addr32 #define s6_addr32 __u6_addr.__u6_addr32 #endif -#endif +#endif /* defined(__APPLE__) || defined(__darwin__) || ... */ /** @} */ #ifndef HAVE_SA_FAMILY_T @@ -566,7 +570,7 @@ struct sockaddr_in6 { struct in6_addr sin6_addr; // uint32_t sin6_scope_id; }; -#endif +#endif /* !defined(HAVE_STRUCT_SOCKADDR_IN6) */ MOCK_DECL(int,tor_gethostname,(char *name, size_t namelen)); int tor_inet_aton(const char *cp, struct in_addr *addr) ATTR_NONNULL((1,2)); @@ -607,14 +611,14 @@ int network_init(void); #define ERRNO_IS_EINTR(e) ((e) == WSAEINTR || 0) int tor_socket_errno(tor_socket_t sock); const char *tor_socket_strerror(int e); -#else +#else /* !(defined(_WIN32)) */ #define SOCK_ERRNO(e) e #if EAGAIN == EWOULDBLOCK /* || 0 is for -Wparentheses-equality (-Wall?) appeasement under clang */ #define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || 0) #else #define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || (e) == EWOULDBLOCK) -#endif +#endif /* EAGAIN == EWOULDBLOCK */ #define ERRNO_IS_EINTR(e) ((e) == EINTR || 0) #define ERRNO_IS_EINPROGRESS(e) ((e) == EINPROGRESS || 0) #define ERRNO_IS_CONN_EINPROGRESS(e) ((e) == EINPROGRESS || 0) @@ -625,7 +629,7 @@ const char *tor_socket_strerror(int e); #define ERRNO_IS_EADDRINUSE(e) (((e) == EADDRINUSE) || 0) #define tor_socket_errno(sock) (errno) #define tor_socket_strerror(e) strerror(e) -#endif +#endif /* defined(_WIN32) */ /** Specified SOCKS5 status codes. */ typedef enum { @@ -728,7 +732,7 @@ char *format_win32_error(DWORD err); #define VER_SUITE_SINGLEUSERTS 0x00000100 #endif -#endif +#endif /* defined(_WIN32) */ #ifdef COMPAT_PRIVATE #if !defined(HAVE_SOCKETPAIR) || defined(_WIN32) || defined(TOR_UNIT_TESTS) @@ -736,12 +740,12 @@ char *format_win32_error(DWORD err); STATIC int tor_ersatz_socketpair(int family, int type, int protocol, tor_socket_t fd[2]); #endif -#endif +#endif /* defined(COMPAT_PRIVATE) */ ssize_t tor_getpass(const char *prompt, char *output, size_t buflen); /* This needs some of the declarations above so we include it here. */ #include "compat_threads.h" -#endif +#endif /* !defined(TOR_COMPAT_H) */ diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c index 31eb4ac496..740cc2a11d 100644 --- a/src/common/compat_libevent.c +++ b/src/common/compat_libevent.c @@ -88,8 +88,8 @@ static struct event_base *the_event_base = NULL; (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1040) #else #define MACOSX_KQUEUE_IS_BROKEN 0 -#endif -#endif +#endif /* defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) */ +#endif /* defined(__APPLE__) */ /** Initialize the Libevent library and set up the event base. */ void @@ -237,8 +237,9 @@ tor_init_libevent_rng(void) return rv; } -#if defined(LIBEVENT_VERSION_NUMBER) && LIBEVENT_VERSION_NUMBER >= V(2,1,1) \ - && !defined(TOR_UNIT_TESTS) +#if defined(LIBEVENT_VERSION_NUMBER) && \ + LIBEVENT_VERSION_NUMBER >= V(2,1,1) && \ + !defined(TOR_UNIT_TESTS) void tor_gettimeofday_cached(struct timeval *tv) { @@ -249,7 +250,7 @@ tor_gettimeofday_cache_clear(void) { event_base_update_cache_time(the_event_base); } -#else +#else /* !(defined(LIBEVENT_VERSION_NUMBER) && ...) */ /** Cache the current hi-res time; the cache gets reset when libevent * calls us. */ static struct timeval cached_time_hires = {0, 0}; @@ -289,6 +290,6 @@ tor_libevent_postfork(void) int r = event_reinit(tor_libevent_get_base()); tor_assert(r == 0); } -#endif -#endif +#endif /* defined(TOR_UNIT_TESTS) */ +#endif /* defined(LIBEVENT_VERSION_NUMBER) && ... */ diff --git a/src/common/compat_libevent.h b/src/common/compat_libevent.h index 904938415c..834354c405 100644 --- a/src/common/compat_libevent.h +++ b/src/common/compat_libevent.h @@ -70,7 +70,7 @@ void tor_libevent_postfork(void); STATIC void libevent_logging_callback(int severity, const char *msg); -#endif +#endif /* defined(COMPAT_LIBEVENT_PRIVATE) */ -#endif +#endif /* !defined(TOR_COMPAT_LIBEVENT_H) */ diff --git a/src/common/compat_openssl.h b/src/common/compat_openssl.h index 2b94fe5b4e..c695f1e9df 100644 --- a/src/common/compat_openssl.h +++ b/src/common/compat_openssl.h @@ -25,7 +25,7 @@ /* We define this macro if we're trying to build with the majorly refactored * API in OpenSSL 1.1 */ #define OPENSSL_1_1_API -#endif +#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0) && ... */ #ifndef OPENSSL_1_1_API #define OPENSSL_VERSION SSLEAY_VERSION @@ -37,11 +37,11 @@ ((st) == SSL3_ST_SW_SRVR_HELLO_B)) #define OSSL_HANDSHAKE_STATE int #define CONST_IF_OPENSSL_1_1_API -#else +#else /* !(!defined(OPENSSL_1_1_API)) */ #define STATE_IS_SW_SERVER_HELLO(st) \ ((st) == TLS_ST_SW_SRVR_HELLO) #define CONST_IF_OPENSSL_1_1_API const -#endif +#endif /* !defined(OPENSSL_1_1_API) */ -#endif +#endif /* !defined(TOR_COMPAT_OPENSSL_H) */ diff --git a/src/common/compat_pthreads.c b/src/common/compat_pthreads.c index 8e4b833573..002274c469 100644 --- a/src/common/compat_pthreads.c +++ b/src/common/compat_pthreads.c @@ -201,20 +201,21 @@ tor_cond_init(tor_cond_t *cond) } #if defined(HAVE_CLOCK_GETTIME) -#if defined(CLOCK_MONOTONIC) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) +#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && \ + defined(CLOCK_MONOTONIC) /* Use monotonic time so when we timedwait() on it, any clock adjustment * won't affect the timeout value. */ if (pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC)) { return -1; } #define USE_COND_CLOCK CLOCK_MONOTONIC -#else /* !defined HAVE_PTHREAD_CONDATTR_SETCLOCK */ +#else /* !(defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && ...) */ /* On OSX Sierra, there is no pthread_condattr_setclock, so we are stuck * with the realtime clock. */ #define USE_COND_CLOCK CLOCK_REALTIME -#endif /* which clock to use */ -#endif /* HAVE_CLOCK_GETTIME */ +#endif /* defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && ... */ +#endif /* defined(HAVE_CLOCK_GETTIME) */ if (pthread_cond_init(&cond->cond, &condattr)) { return -1; } @@ -266,11 +267,11 @@ tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex, const struct timeval *tv) tvnow.tv_sec = ts.tv_sec; tvnow.tv_usec = (int)(ts.tv_nsec / 1000); timeradd(tv, &tvnow, &tvsum); -#else +#else /* !(defined(HAVE_CLOCK_GETTIME) && defined(USE_COND_CLOCK)) */ if (gettimeofday(&tvnow, NULL) < 0) return -1; timeradd(tv, &tvnow, &tvsum); -#endif /* HAVE_CLOCK_GETTIME, CLOCK_MONOTONIC */ +#endif /* defined(HAVE_CLOCK_GETTIME) && defined(USE_COND_CLOCK) */ ts.tv_sec = tvsum.tv_sec; ts.tv_nsec = tvsum.tv_usec * 1000; diff --git a/src/common/compat_rust.h b/src/common/compat_rust.h index 752a29b56c..72fde39296 100644 --- a/src/common/compat_rust.h +++ b/src/common/compat_rust.h @@ -24,5 +24,5 @@ const char *rust_str_get(const rust_str_t); rust_str_t rust_welcome_string(void); -#endif +#endif /* !defined(TOR_RUST_COMPAT_H) */ diff --git a/src/common/compat_threads.c b/src/common/compat_threads.c index c593e9af8d..208d3138d9 100644 --- a/src/common/compat_threads.c +++ b/src/common/compat_threads.c @@ -126,7 +126,7 @@ read_ni(int fd, void *buf, size_t n) } return r; } -#endif +#endif /* defined(HAVE_EVENTFD) || defined(HAVE_PIPE) */ /** As send(), but retry on EINTR, and return the negative error code on * error. */ @@ -186,7 +186,7 @@ eventfd_drain(int fd) return r; return 0; } -#endif +#endif /* defined(HAVE_EVENTFD) */ #ifdef HAVE_PIPE /** Send a byte over a pipe. Return 0 on success or EAGAIN; -1 on error */ @@ -214,7 +214,7 @@ pipe_drain(int fd) /* A value of r = 0 means EOF on the fd so successfully drained. */ return 0; } -#endif +#endif /* defined(HAVE_PIPE) */ /** Send a byte on socket <b>fd</b>t. Return 0 on success or EAGAIN, * -1 on error. */ @@ -276,7 +276,7 @@ alert_sockets_create(alert_sockets_t *socks_out, uint32_t flags) socks_out->drain_fn = eventfd_drain; return 0; } -#endif +#endif /* defined(HAVE_EVENTFD) */ #ifdef HAVE_PIPE2 /* Now we're going to try pipes. First type the pipe2() syscall, if we @@ -289,7 +289,7 @@ alert_sockets_create(alert_sockets_t *socks_out, uint32_t flags) socks_out->drain_fn = pipe_drain; return 0; } -#endif +#endif /* defined(HAVE_PIPE2) */ #ifdef HAVE_PIPE /* Now try the regular pipe() syscall. Pipes have a bit lower overhead than @@ -313,7 +313,7 @@ alert_sockets_create(alert_sockets_t *socks_out, uint32_t flags) socks_out->drain_fn = pipe_drain; return 0; } -#endif +#endif /* defined(HAVE_PIPE) */ /* If nothing else worked, fall back on socketpair(). */ if (!(flags & ASOCKS_NOSOCKETPAIR) && diff --git a/src/common/compat_threads.h b/src/common/compat_threads.h index 9fa3d0d0b7..42f14eab2a 100644 --- a/src/common/compat_threads.h +++ b/src/common/compat_threads.h @@ -20,7 +20,7 @@ #define USE_PTHREADS #else #error "No threading system was found" -#endif +#endif /* defined(_WIN32) || ... */ int spawn_func(void (*func)(void *), void *data); void spawn_exit(void) ATTR_NORETURN; @@ -41,7 +41,7 @@ typedef struct tor_mutex_t { #else /** No-threads only: Dummy variable so that tor_mutex_t takes up space. */ int _unused; -#endif +#endif /* defined(USE_WIN32_THREADS) || ... */ } tor_mutex_t; tor_mutex_t *tor_mutex_new(void); @@ -73,7 +73,7 @@ typedef struct tor_cond_t { int generation; #else #error no known condition implementation. -#endif +#endif /* defined(USE_PTHREADS) || ... */ } tor_cond_t; tor_cond_t *tor_cond_new(void); @@ -161,5 +161,5 @@ void atomic_counter_add(atomic_counter_t *counter, size_t add); void atomic_counter_sub(atomic_counter_t *counter, size_t sub); size_t atomic_counter_get(atomic_counter_t *counter); -#endif +#endif /* !defined(TOR_COMPAT_THREADS_H) */ diff --git a/src/common/compat_time.c b/src/common/compat_time.c index 3c00c96f94..1ce6f5ce4e 100644 --- a/src/common/compat_time.c +++ b/src/common/compat_time.c @@ -28,7 +28,7 @@ /* as fallback implementation for tor_sleep_msec */ #include <sys/select.h> #endif -#endif +#endif /* defined(TOR_UNIT_TESTS) */ #ifdef __APPLE__ #include <mach/mach_time.h> @@ -64,9 +64,9 @@ tor_sleep_msec(int msec) select(0, NULL, NULL, NULL, &tv); #else sleep(CEIL_DIV(msec, 1000)); -#endif +#endif /* defined(_WIN32) || ... */ } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /** Set *timeval to the current time of day. On error, log and terminate. * (Same as gettimeofday(timeval,NULL), but never returns -1.) @@ -112,7 +112,7 @@ tor_gettimeofday(struct timeval *timeval) timeval->tv_usec = tb.millitm * 1000; #else #error "No way to get time." -#endif +#endif /* defined(_WIN32) || ... */ return; } @@ -187,8 +187,8 @@ monotime_coarse_set_mock_time_nsec(int64_t nsec) tor_assert_nonfatal(monotime_mocking_enabled == 1); mock_time_nsec_coarse = nsec; } -#endif -#endif +#endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */ +#endif /* defined(TOR_UNIT_TESTS) */ /* "ratchet" functions for monotonic time. */ @@ -235,7 +235,7 @@ ratchet_coarse_performance_counter(const int64_t count_raw) last_tick_count = count; return count; } -#endif +#endif /* defined(_WIN32) || defined(TOR_UNIT_TESTS) */ #if defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS) static struct timeval last_timeofday = { 0, 0 }; @@ -259,7 +259,7 @@ ratchet_timeval(const struct timeval *timeval_raw, struct timeval *out) memcpy(&last_timeofday, out, sizeof(struct timeval)); } } -#endif +#endif /* defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS) */ #ifdef TOR_UNIT_TESTS /** For testing: reset all the ratchets */ @@ -271,7 +271,7 @@ monotime_reset_ratchets_for_testing(void) memset(&last_timeofday, 0, sizeof(struct timeval)); memset(&timeofday_offset, 0, sizeof(struct timeval)); } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ #ifdef __APPLE__ @@ -301,7 +301,7 @@ monotime_get(monotime_t *out) / mach_time_info.numer; return; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ out->abstime_ = mach_absolute_time(); } @@ -332,7 +332,7 @@ monotime_diff_nsec(const monotime_t *start, * an old Linux kernel. In that case, we will fall back to CLOCK_MONOTONIC. */ static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE; -#endif +#endif /* defined(CLOCK_MONOTONIC_COARSE) */ static void monotime_init_internal(void) @@ -344,7 +344,7 @@ monotime_init_internal(void) "falling back to CLOCK_MONOTONIC.", strerror(errno)); clock_monotonic_coarse = CLOCK_MONOTONIC; } -#endif +#endif /* defined(CLOCK_MONOTONIC_COARSE) */ } void @@ -356,7 +356,7 @@ monotime_get(monotime_t *out) out->ts_.tv_nsec = (int) (mock_time_nsec % ONE_BILLION); return; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_); tor_assert(r == 0); } @@ -371,7 +371,7 @@ monotime_coarse_get(monotime_coarse_t *out) out->ts_.tv_nsec = (int) (mock_time_nsec_coarse % ONE_BILLION); return; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ int r = clock_gettime(clock_monotonic_coarse, &out->ts_); if (PREDICT_UNLIKELY(r < 0) && errno == EINVAL && @@ -386,7 +386,7 @@ monotime_coarse_get(monotime_coarse_t *out) tor_assert(r == 0); } -#endif +#endif /* defined(CLOCK_MONOTONIC_COARSE) */ int64_t monotime_diff_nsec(const monotime_t *start, @@ -462,7 +462,7 @@ monotime_get(monotime_t *out) / nsec_per_tick_numer; return; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /* Alas, QueryPerformanceCounter is not always monotonic: see bug list at @@ -486,7 +486,7 @@ monotime_coarse_get(monotime_coarse_t *out) out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION; return; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ if (GetTickCount64_fn) { out->tick_count_ = (int64_t)GetTickCount64_fn(); @@ -570,7 +570,7 @@ monotime_diff_nsec(const monotime_t *start, /* end of "MONOTIME_USING_GETTIMEOFDAY" */ #else #error "No way to implement monotonic timers." -#endif +#endif /* defined(__APPLE__) || ... */ /** * Initialize the monotonic timer subsystem. Must be called before any @@ -653,5 +653,5 @@ monotime_coarse_absolute_msec(void) { return monotime_coarse_absolute_nsec() / ONE_MILLION; } -#endif +#endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */ diff --git a/src/common/compat_time.h b/src/common/compat_time.h index 90194c5ebc..5ea4aae42b 100644 --- a/src/common/compat_time.h +++ b/src/common/compat_time.h @@ -28,13 +28,13 @@ #include <time.h> #endif -#if !defined(HAVE_GETTIMEOFDAY) && !defined(HAVE_STRUCT_TIMEVAL_TV_SEC) +#if !defined(HAVE_STRUCT_TIMEVAL_TV_SEC) /** Implementation of timeval for platforms that don't have it. */ struct timeval { time_t tv_sec; unsigned int tv_usec; }; -#endif +#endif /* !defined(HAVE_STRUCT_TIMEVAL_TV_SEC) */ /** Represents a monotonic timer in a platform-dependent way. */ typedef struct monotime_t { @@ -51,10 +51,11 @@ typedef struct monotime_t { #define MONOTIME_USING_GETTIMEOFDAY /* Otherwise, we will be stuck using gettimeofday. */ struct timeval tv_; -#endif +#endif /* defined(__APPLE__) || ... */ } monotime_t; -#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC_COARSE) +#if defined(CLOCK_MONOTONIC_COARSE) && \ + defined(HAVE_CLOCK_GETTIME) #define MONOTIME_COARSE_FN_IS_DIFFERENT #define monotime_coarse_t monotime_t #elif defined(_WIN32) @@ -66,7 +67,7 @@ typedef struct monotime_coarse_t { } monotime_coarse_t; #else #define monotime_coarse_t monotime_t -#endif +#endif /* defined(CLOCK_MONOTONIC_COARSE) && ... || ... */ /** * Initialize the timing subsystem. This function is idempotent. @@ -109,12 +110,12 @@ void monotime_coarse_get(monotime_coarse_t *out); uint64_t monotime_coarse_absolute_nsec(void); uint64_t monotime_coarse_absolute_usec(void); uint64_t monotime_coarse_absolute_msec(void); -#else +#else /* !(defined(MONOTIME_COARSE_FN_IS_DIFFERENT)) */ #define monotime_coarse_get monotime_get #define monotime_coarse_absolute_nsec monotime_absolute_nsec #define monotime_coarse_absolute_usec monotime_absolute_usec #define monotime_coarse_absolute_msec monotime_absolute_msec -#endif +#endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */ #if defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT) int64_t monotime_coarse_diff_nsec(const monotime_coarse_t *start, @@ -123,11 +124,11 @@ int64_t monotime_coarse_diff_usec(const monotime_coarse_t *start, const monotime_coarse_t *end); int64_t monotime_coarse_diff_msec(const monotime_coarse_t *start, const monotime_coarse_t *end); -#else +#else /* !(defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT)) */ #define monotime_coarse_diff_nsec monotime_diff_nsec #define monotime_coarse_diff_usec monotime_diff_usec #define monotime_coarse_diff_msec monotime_diff_msec -#endif +#endif /* defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT) */ void tor_gettimeofday(struct timeval *timeval); @@ -142,7 +143,7 @@ void monotime_coarse_set_mock_time_nsec(int64_t); #else #define monotime_coarse_set_mock_time_nsec monotime_set_mock_time_nsec #endif -#endif +#endif /* defined(TOR_UNIT_TESTS) */ #ifdef COMPAT_TIME_PRIVATE #if defined(_WIN32) || defined(TOR_UNIT_TESTS) @@ -156,7 +157,7 @@ STATIC void ratchet_timeval(const struct timeval *timeval_raw, #ifdef TOR_UNIT_TESTS void monotime_reset_ratchets_for_testing(void); #endif -#endif +#endif /* defined(COMPAT_TIME_PRIVATE) */ -#endif +#endif /* !defined(TOR_COMPAT_TIME_H) */ diff --git a/src/common/compat_winthreads.c b/src/common/compat_winthreads.c index 915368b94f..50a3c498ca 100644 --- a/src/common/compat_winthreads.c +++ b/src/common/compat_winthreads.c @@ -246,5 +246,5 @@ tor_threads_init(void) set_main_thread(); } -#endif +#endif /* defined(_WIN32) */ diff --git a/src/common/compress.h b/src/common/compress.h index 59c8b7b9b5..ecb20668e4 100644 --- a/src/common/compress.h +++ b/src/common/compress.h @@ -85,5 +85,5 @@ size_t tor_compress_state_size(const tor_compress_state_t *state); void tor_compress_init(void); -#endif // TOR_COMPRESS_H. +#endif /* !defined(TOR_COMPRESS_H) */ diff --git a/src/common/compress_lzma.c b/src/common/compress_lzma.c index d453d9f718..2bdbbe1d45 100644 --- a/src/common/compress_lzma.c +++ b/src/common/compress_lzma.c @@ -75,7 +75,7 @@ lzma_error_str(lzma_ret error) return "Unknown LZMA error"; } } -#endif // HAVE_LZMA. +#endif /* defined(HAVE_LZMA) */ /** Return 1 if LZMA compression is supported; otherwise 0. */ int @@ -161,7 +161,7 @@ tor_lzma_state_size_precalc(int compress, compression_level_t level) err: return 0; // LCOV_EXCL_LINE } -#endif // HAVE_LZMA. +#endif /* defined(HAVE_LZMA) */ /** Construct and return a tor_lzma_compress_state_t object using * <b>method</b>. If <b>compress</b>, it's for compression; otherwise it's for @@ -215,13 +215,13 @@ tor_lzma_compress_new(int compress, err: tor_free(result); // LCOV_EXCL_LINE return NULL; -#else // HAVE_LZMA. +#else /* !(defined(HAVE_LZMA)) */ (void)compress; (void)method; (void)level; return NULL; -#endif // HAVE_LZMA. +#endif /* defined(HAVE_LZMA) */ } /** Compress/decompress some bytes using <b>state</b>. Read up to @@ -306,7 +306,7 @@ tor_lzma_compress_process(tor_lzma_compress_state_t *state, lzma_error_str(retval)); return TOR_COMPRESS_ERROR; } -#else // HAVE_LZMA. +#else /* !(defined(HAVE_LZMA)) */ (void)state; (void)out; (void)out_len; @@ -314,7 +314,7 @@ tor_lzma_compress_process(tor_lzma_compress_state_t *state, (void)in_len; (void)finish; return TOR_COMPRESS_ERROR; -#endif // HAVE_LZMA. +#endif /* defined(HAVE_LZMA) */ } /** Deallocate <b>state</b>. */ diff --git a/src/common/compress_lzma.h b/src/common/compress_lzma.h index 1433c89f88..7639d98a70 100644 --- a/src/common/compress_lzma.h +++ b/src/common/compress_lzma.h @@ -39,5 +39,5 @@ size_t tor_lzma_get_total_allocation(void); void tor_lzma_init(void); -#endif // TOR_COMPRESS_LZMA_H. +#endif /* !defined(TOR_COMPRESS_LZMA_H) */ diff --git a/src/common/compress_none.h b/src/common/compress_none.h index d1ebb4b625..77c3cef47b 100644 --- a/src/common/compress_none.h +++ b/src/common/compress_none.h @@ -16,5 +16,5 @@ tor_cnone_compress_process(char **out, size_t *out_len, const char **in, size_t *in_len, int finish); -#endif // TOR_COMPRESS_NONE_H. +#endif /* !defined(TOR_COMPRESS_NONE_H) */ diff --git a/src/common/compress_zlib.h b/src/common/compress_zlib.h index df5c196ac7..8ace467bf0 100644 --- a/src/common/compress_zlib.h +++ b/src/common/compress_zlib.h @@ -39,5 +39,5 @@ size_t tor_zlib_get_total_allocation(void); void tor_zlib_init(void); -#endif // TOR_COMPRESS_ZLIB_H. +#endif /* !defined(TOR_COMPRESS_ZLIB_H) */ diff --git a/src/common/compress_zstd.c b/src/common/compress_zstd.c index 0808bcd9ab..58ec28d001 100644 --- a/src/common/compress_zstd.c +++ b/src/common/compress_zstd.c @@ -38,7 +38,7 @@ memory_level(compression_level_t level) case LOW_COMPRESSION: return 7; } } -#endif // HAVE_ZSTD. +#endif /* defined(HAVE_ZSTD) */ /** Return 1 if Zstandard compression is supported; otherwise 0. */ int @@ -68,9 +68,9 @@ tor_zstd_get_version_str(void) version_number % 100); return version_str; -#else +#else /* !(defined(HAVE_ZSTD)) */ return NULL; -#endif +#endif /* defined(HAVE_ZSTD) */ } /** Return a string representation of the version of the version of libzstd @@ -95,7 +95,7 @@ struct tor_zstd_compress_state_t { /** Decompression stream. Used when <b>compress</b> is false. */ ZSTD_DStream *decompress_stream; } u; /**< Zstandard stream objects. */ -#endif // HAVE_ZSTD. +#endif /* defined(HAVE_ZSTD) */ int compress; /**< True if we are compressing; false if we are inflating */ int have_called_end; /**< True if we are compressing and we've called @@ -171,7 +171,7 @@ tor_zstd_state_size_precalc(int compress, int preset) return memory_usage; } -#endif // HAVE_ZSTD. +#endif /* defined(HAVE_ZSTD) */ /** Construct and return a tor_zstd_compress_state_t object using * <b>method</b>. If <b>compress</b>, it's for compression; otherwise it's for @@ -248,13 +248,13 @@ tor_zstd_compress_new(int compress, tor_free(result); return NULL; // LCOV_EXCL_STOP -#else // HAVE_ZSTD. +#else /* !(defined(HAVE_ZSTD)) */ (void)compress; (void)method; (void)level; return NULL; -#endif // HAVE_ZSTD. +#endif /* defined(HAVE_ZSTD) */ } /** Compress/decompress some bytes using <b>state</b>. Read up to @@ -385,7 +385,7 @@ tor_zstd_compress_process(tor_zstd_compress_state_t *state, return TOR_COMPRESS_OK; } -#else // HAVE_ZSTD. +#else /* !(defined(HAVE_ZSTD)) */ (void)state; (void)out; (void)out_len; @@ -394,7 +394,7 @@ tor_zstd_compress_process(tor_zstd_compress_state_t *state, (void)finish; return TOR_COMPRESS_ERROR; -#endif // HAVE_ZSTD. +#endif /* defined(HAVE_ZSTD) */ } /** Deallocate <b>state</b>. */ @@ -412,7 +412,7 @@ tor_zstd_compress_free(tor_zstd_compress_state_t *state) } else { ZSTD_freeDStream(state->u.decompress_stream); } -#endif // HAVE_ZSTD. +#endif /* defined(HAVE_ZSTD) */ tor_free(state); } diff --git a/src/common/compress_zstd.h b/src/common/compress_zstd.h index d3e65c2f16..02466010ff 100644 --- a/src/common/compress_zstd.h +++ b/src/common/compress_zstd.h @@ -39,5 +39,5 @@ size_t tor_zstd_get_total_allocation(void); void tor_zstd_init(void); -#endif // TOR_COMPRESS_ZSTD_H. +#endif /* !defined(TOR_COMPRESS_ZSTD_H) */ diff --git a/src/common/confline.c b/src/common/confline.c index 15fd96bf38..f2fbe9c8e9 100644 --- a/src/common/confline.c +++ b/src/common/confline.c @@ -288,7 +288,7 @@ config_process_include(const char *path, int recursion_level, int extended, return -1; } tor_free(unquoted_path); -#endif +#endif /* 0 */ smartlist_t *config_files = config_get_file_list(path); if (!config_files) { return -1; diff --git a/src/common/confline.h b/src/common/confline.h index eb863e8fd8..8256326f2d 100644 --- a/src/common/confline.h +++ b/src/common/confline.h @@ -49,5 +49,5 @@ void config_free_lines(config_line_t *front); const char *parse_config_line_from_str_verbose(const char *line, char **key_out, char **value_out, const char **err_out); -#endif +#endif /* !defined(TOR_CONFLINE_H) */ diff --git a/src/common/container.h b/src/common/container.h index db68d892f5..f6affd3bc6 100644 --- a/src/common/container.h +++ b/src/common/container.h @@ -74,11 +74,11 @@ static inline void smartlist_set(smartlist_t *sl, int idx, void *val) { tor_assert(sl->num_used > idx); sl->list[idx] = val; } -#else +#else /* !(defined(DEBUG_SMARTLIST)) */ #define smartlist_len(sl) ((sl)->num_used) #define smartlist_get(sl, idx) ((sl)->list[idx]) #define smartlist_set(sl, idx, val) ((sl)->list[idx] = (val)) -#endif +#endif /* defined(DEBUG_SMARTLIST) */ /** Exchange the elements at indices <b>idx1</b> and <b>idx2</b> of the * smartlist <b>sl</b>. */ @@ -580,7 +580,7 @@ void* strmap_remove_lc(strmap_t *map, const char *key); #define BITARRAY_SHIFT 6 #else #error "int is neither 4 nor 8 bytes. I can't deal with that." -#endif +#endif /* SIZEOF_INT == 4 || ... */ #define BITARRAY_MASK ((1u<<BITARRAY_SHIFT)-1) /** A random-access array of one-bit-wide elements. */ @@ -723,5 +723,5 @@ third_quartile_uint32(uint32_t *array, int n_elements) return find_nth_uint32(array, n_elements, (n_elements*3)/4); } -#endif +#endif /* !defined(TOR_CONTAINER_H) */ diff --git a/src/common/crypto.c b/src/common/crypto.c index 4d6a70bc49..1730619f83 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -20,7 +20,7 @@ /* Windows defines this; so does OpenSSL 0.9.8h and later. We don't actually * use either definition. */ #undef OCSP_RESPONSE -#endif +#endif /* defined(_WIN32) */ #define CRYPTO_PRIVATE #include "crypto.h" @@ -50,7 +50,7 @@ ENABLE_GCC_WARNING(redundant-decls) #else #pragma GCC diagnostic warning "-Wredundant-decls" #endif -#endif +#endif /* __GNUC__ && GCC_VERSION >= 402 */ #ifdef HAVE_CTYPE_H #include <ctype.h> @@ -101,7 +101,7 @@ ENABLE_GCC_WARNING(redundant-decls) * pointless, so let's not. */ #define NEW_THREAD_API -#endif +#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_VER(1,1,0,0,5) && ... */ /** Longest recognized */ #define MAX_DNS_LABEL_SIZE 63 @@ -114,7 +114,7 @@ ENABLE_GCC_WARNING(redundant-decls) static tor_mutex_t **openssl_mutexes_ = NULL; /** How many mutexes have we allocated for use by OpenSSL? */ static int n_openssl_mutexes_ = 0; -#endif +#endif /* !defined(NEW_THREAD_API) */ /** A public key, or a public/private key-pair. */ struct crypto_pk_t @@ -198,7 +198,7 @@ log_engine(const char *fn, ENGINE *e) log_info(LD_CRYPTO, "Using default implementation for %s", fn); } } -#endif +#endif /* !defined(DISABLE_ENGINES) */ #ifndef DISABLE_ENGINES /** Try to load an engine in a shared library via fully qualified path. @@ -218,7 +218,7 @@ try_load_engine(const char *path, const char *engine) } return e; } -#endif +#endif /* !defined(DISABLE_ENGINES) */ /* Returns a trimmed and human-readable version of an openssl version string * <b>raw_version</b>. They are usually in the form of 'OpenSSL 1.0.0b 10 @@ -394,7 +394,7 @@ crypto_global_init(int useAccel, const char *accelName, const char *accelDir) #else log_engine("ECDH", ENGINE_get_default_ECDH()); log_engine("ECDSA", ENGINE_get_default_ECDSA()); -#endif +#endif /* defined(OPENSSL_1_1_API) */ log_engine("RAND", ENGINE_get_default_RAND()); log_engine("RAND (which we will not use)", ENGINE_get_default_RAND()); log_engine("SHA1", ENGINE_get_digest_engine(NID_sha1)); @@ -412,7 +412,7 @@ crypto_global_init(int useAccel, const char *accelName, const char *accelDir) log_engine("AES-256-GCM", ENGINE_get_cipher_engine(NID_aes_256_gcm)); #endif -#endif +#endif /* defined(DISABLE_ENGINES) */ } else { log_info(LD_CRYPTO, "NOT using OpenSSL engine support."); } @@ -450,9 +450,9 @@ crypto_pk_private_ok(const crypto_pk_t *k) const BIGNUM *p, *q; RSA_get0_factors(k->key, &p, &q); return p != NULL; /* XXX/yawning: Should we check q? */ -#else +#else /* !(defined(OPENSSL_1_1_API)) */ return k && k->key && k->key->p; -#endif +#endif /* defined(OPENSSL_1_1_API) */ } /** used by tortls.c: wrap an RSA* in a crypto_pk_t. */ @@ -884,7 +884,7 @@ crypto_pk_public_exponent_ok(crypto_pk_t *env) RSA_get0_key(env->key, &n, &e, &d); #else e = env->key->e; -#endif +#endif /* defined(OPENSSL_1_1_API) */ return BN_is_word(e, 65537); } @@ -918,7 +918,7 @@ crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b) a_e = a->key->e; b_n = b->key->n; b_e = b->key->e; -#endif +#endif /* defined(OPENSSL_1_1_API) */ tor_assert(a_n != NULL && a_e != NULL); tor_assert(b_n != NULL && b_e != NULL); @@ -967,10 +967,10 @@ crypto_pk_num_bits(crypto_pk_t *env) tor_assert(n != NULL); return RSA_bits(env->key); -#else +#else /* !(defined(OPENSSL_1_1_API)) */ tor_assert(env->key->n); return BN_num_bits(env->key->n); -#endif +#endif /* defined(OPENSSL_1_1_API) */ } /** Increase the reference count of <b>env</b>, and return it. @@ -997,7 +997,7 @@ crypto_pk_assign_(crypto_pk_t *dest, const crypto_pk_t *src) RSA_free(dest->key); dest->key = RSAPrivateKey_dup(src->key); } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /** Make a real honest-to-goodness copy of <b>env</b>, and return it. * Returns NULL on failure. */ @@ -1871,7 +1871,7 @@ crypto_digest_get_algorithm(crypto_digest_t *digest) return digest->algorithm; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /** * Return the number of bytes we need to malloc in order to get a @@ -2255,12 +2255,12 @@ crypto_validate_dh_params(const BIGNUM *p, const BIGNUM *g) goto out; if (!DH_set0_pqg(dh, dh_p, NULL, dh_g)) goto out; -#else +#else /* !(defined(OPENSSL_1_1_API)) */ if (!(dh->p = BN_dup(p))) goto out; if (!(dh->g = BN_dup(g))) goto out; -#endif +#endif /* defined(OPENSSL_1_1_API) */ /* Perform the validation. */ int codes = 0; @@ -2431,7 +2431,7 @@ crypto_dh_new(int dh_type) if (!DH_set_length(res->dh, DH_PRIVATE_KEY_BITS)) goto err; -#else +#else /* !(defined(OPENSSL_1_1_API)) */ if (dh_type == DH_TYPE_TLS) { if (!(res->dh->p = BN_dup(dh_param_p_tls))) goto err; @@ -2444,7 +2444,7 @@ crypto_dh_new(int dh_type) goto err; res->dh->length = DH_PRIVATE_KEY_BITS; -#endif +#endif /* defined(OPENSSL_1_1_API) */ return res; err: @@ -2506,7 +2506,7 @@ crypto_dh_generate_public(crypto_dh_t *dh) "the-universe chances really do happen. Treating as a failure."); return -1; } -#else +#else /* !(defined(OPENSSL_1_1_API)) */ if (tor_check_dh_key(LOG_WARN, dh->dh->pub_key)<0) { /* LCOV_EXCL_START * If this happens, then openssl's DH implementation is busted. */ @@ -2519,7 +2519,7 @@ crypto_dh_generate_public(crypto_dh_t *dh) goto again; /* LCOV_EXCL_STOP */ } -#endif +#endif /* defined(OPENSSL_1_1_API) */ return 0; } @@ -2540,7 +2540,7 @@ crypto_dh_get_public(crypto_dh_t *dh, char *pubkey, size_t pubkey_len) DH_get0_key(dh->dh, &dh_pub, &dh_priv); #else dh_pub = dh->dh->pub_key; -#endif +#endif /* defined(OPENSSL_1_1_API) */ if (!dh_pub) { if (crypto_dh_generate_public(dh)<0) @@ -2883,7 +2883,7 @@ crypto_strongest_rand_syscall(uint8_t *out, size_t out_len) return getentropy(out, out_len); #else (void) out; -#endif +#endif /* defined(_WIN32) || ... */ /* This platform doesn't have a supported syscall based random. */ return -1; @@ -2907,7 +2907,7 @@ crypto_strongest_rand_fallback(uint8_t *out, size_t out_len) (void)out; (void)out_len; return -1; -#else +#else /* !(defined(_WIN32)) */ static const char *filenames[] = { "/dev/srandom", "/dev/urandom", "/dev/random", NULL }; @@ -2935,7 +2935,7 @@ crypto_strongest_rand_fallback(uint8_t *out, size_t out_len) } return -1; -#endif +#endif /* defined(_WIN32) */ } /** Try to get <b>out_len</b> bytes of the strongest entropy we can generate, @@ -3184,7 +3184,7 @@ crypto_rand_double(void) #define UINT_MAX_AS_DOUBLE 1.8446744073709552e+19 #else #error SIZEOF_INT is neither 4 nor 8 -#endif +#endif /* SIZEOF_INT == 4 || ... */ return ((double)u) / UINT_MAX_AS_DOUBLE; } @@ -3313,7 +3313,7 @@ memwipe(void *mem, uint8_t byte, size_t sz) **/ OPENSSL_cleanse(mem, sz); -#endif +#endif /* defined(SecureZeroMemory) || defined(HAVE_SECUREZEROMEMORY) || ... */ /* Just in case some caller of memwipe() is relying on getting a buffer * filled with a particular value, fill the buffer. @@ -3355,7 +3355,7 @@ tor_set_openssl_thread_id(CRYPTO_THREADID *threadid) { CRYPTO_THREADID_set_numeric(threadid, tor_get_thread_id()); } -#endif +#endif /* !defined(NEW_THREAD_API) */ #if 0 /* This code is disabled, because OpenSSL never actually uses these callbacks. @@ -3405,7 +3405,7 @@ openssl_dynlock_destroy_cb_(struct CRYPTO_dynlock_value *v, tor_mutex_free(v->lock); tor_free(v); } -#endif +#endif /* 0 */ /** @{ */ /** Helper: Construct mutexes, and set callbacks to help OpenSSL handle being @@ -3422,7 +3422,7 @@ setup_openssl_threading(void) openssl_mutexes_[i] = tor_mutex_new(); CRYPTO_set_locking_callback(openssl_locking_cb_); CRYPTO_THREADID_set_callback(tor_set_openssl_thread_id); -#endif +#endif /* !defined(NEW_THREAD_API) */ #if 0 CRYPTO_set_dynlock_create_callback(openssl_dynlock_create_cb_); CRYPTO_set_dynlock_lock_callback(openssl_dynlock_lock_cb_); @@ -3469,7 +3469,7 @@ crypto_global_cleanup(void) } tor_free(ms); } -#endif +#endif /* !defined(NEW_THREAD_API) */ tor_free(crypto_openssl_version_str); tor_free(crypto_openssl_header_version_str); @@ -3488,5 +3488,5 @@ crypto_use_tor_alloc_functions(void) int r = CRYPTO_set_mem_ex_functions(tor_malloc_, tor_realloc_, tor_free_); return r ? 0 : -1; } -#endif +#endif /* defined(USE_DMALLOC) */ diff --git a/src/common/crypto.h b/src/common/crypto.h index cde241dd37..6f5e13a8de 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -346,12 +346,12 @@ STATIC int crypto_strongest_rand_raw(uint8_t *out, size_t out_len); extern int break_strongest_rng_syscall; extern int break_strongest_rng_fallback; #endif -#endif +#endif /* defined(CRYPTO_PRIVATE) */ #ifdef TOR_UNIT_TESTS void crypto_pk_assign_(crypto_pk_t *dest, const crypto_pk_t *src); digest_algorithm_t crypto_digest_get_algorithm(crypto_digest_t *digest); #endif -#endif +#endif /* !defined(TOR_CRYPTO_H) */ diff --git a/src/common/crypto_curve25519.c b/src/common/crypto_curve25519.c index b99f13a93b..f5c2acb877 100644 --- a/src/common/crypto_curve25519.c +++ b/src/common/crypto_curve25519.c @@ -43,7 +43,7 @@ int curve25519_donna(uint8_t *mypublic, #elif defined(HAVE_NACL_CRYPTO_SCALARMULT_CURVE25519_H) #include <nacl/crypto_scalarmult_curve25519.h> #endif -#endif +#endif /* defined(USE_CURVE25519_NACL) */ static void pick_curve25519_basepoint_impl(void); @@ -72,7 +72,7 @@ curve25519_impl(uint8_t *output, const uint8_t *secret, r = crypto_scalarmult_curve25519(output, secret, bp); #else #error "No implementation of curve25519 is available." -#endif +#endif /* defined(USE_CURVE25519_DONNA) || ... */ memwipe(bp, 0, sizeof(bp)); return r; } diff --git a/src/common/crypto_curve25519.h b/src/common/crypto_curve25519.h index e7790edac0..d024ab79f5 100644 --- a/src/common/crypto_curve25519.h +++ b/src/common/crypto_curve25519.h @@ -71,7 +71,7 @@ STATIC int curve25519_impl(uint8_t *output, const uint8_t *secret, const uint8_t *basepoint); STATIC int curve25519_basepoint_impl(uint8_t *output, const uint8_t *secret); -#endif +#endif /* defined(CRYPTO_CURVE25519_PRIVATE) */ #define CURVE25519_BASE64_PADDED_LEN 44 @@ -83,5 +83,5 @@ int curve25519_public_to_base64(char *output, void curve25519_set_impl_params(int use_ed); void curve25519_init(void); -#endif +#endif /* !defined(TOR_CRYPTO_CURVE25519_H) */ diff --git a/src/common/crypto_ed25519.c b/src/common/crypto_ed25519.c index abf23c4b38..969cc1047b 100644 --- a/src/common/crypto_ed25519.c +++ b/src/common/crypto_ed25519.c @@ -151,7 +151,7 @@ crypto_ed25519_testing_restore_impl(void) ed25519_impl = saved_ed25519_impl; saved_ed25519_impl = NULL; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /** * Initialize a new ed25519 secret key in <b>seckey_out</b>. If diff --git a/src/common/crypto_ed25519.h b/src/common/crypto_ed25519.h index 3a439207b3..8d13a487d6 100644 --- a/src/common/crypto_ed25519.h +++ b/src/common/crypto_ed25519.h @@ -138,5 +138,5 @@ void crypto_ed25519_testing_restore_impl(void); MOCK_DECL(STATIC int, ed25519_impl_spot_check, (void)); #endif -#endif +#endif /* !defined(TOR_CRYPTO_ED25519_H) */ diff --git a/src/common/crypto_format.h b/src/common/crypto_format.h index 390916cf04..bbd85dc720 100644 --- a/src/common/crypto_format.h +++ b/src/common/crypto_format.h @@ -43,5 +43,5 @@ int digest_from_base64(char *digest, const char *d64); int digest256_to_base64(char *d64, const char *digest); int digest256_from_base64(char *digest, const char *d64); -#endif +#endif /* !defined(TOR_CRYPTO_FORMAT_H) */ diff --git a/src/common/crypto_pwbox.h b/src/common/crypto_pwbox.h index aadd477078..cee8653587 100644 --- a/src/common/crypto_pwbox.h +++ b/src/common/crypto_pwbox.h @@ -16,5 +16,5 @@ int crypto_unpwbox(uint8_t **out, size_t *outlen_out, const uint8_t *inp, size_t input_len, const char *secret, size_t secret_len); -#endif +#endif /* !defined(CRYPTO_PWBOX_H_INCLUDED_) */ diff --git a/src/common/crypto_s2k.c b/src/common/crypto_s2k.c index 076df815a9..4db6762ef7 100644 --- a/src/common/crypto_s2k.c +++ b/src/common/crypto_s2k.c @@ -290,9 +290,9 @@ secret_to_key_compute_key(uint8_t *key_out, size_t key_out_len, if (rv != 0) return S2K_FAILED; return (int)key_out_len; -#else +#else /* !(defined(HAVE_SCRYPT)) */ return S2K_NO_SCRYPT_SUPPORT; -#endif +#endif /* defined(HAVE_SCRYPT) */ } default: return S2K_BAD_ALGORITHM; diff --git a/src/common/crypto_s2k.h b/src/common/crypto_s2k.h index 04212b868a..849ff59ce8 100644 --- a/src/common/crypto_s2k.h +++ b/src/common/crypto_s2k.h @@ -67,7 +67,7 @@ STATIC int secret_to_key_compute_key(uint8_t *key_out, size_t key_out_len, const uint8_t *spec, size_t spec_len, const char *secret, size_t secret_len, int type); -#endif +#endif /* defined(CRYPTO_S2K_PRIVATE) */ -#endif +#endif /* !defined(TOR_CRYPTO_S2K_H_INCLUDED) */ diff --git a/src/common/di_ops.c b/src/common/di_ops.c index e47998107d..7c0b4e7630 100644 --- a/src/common/di_ops.c +++ b/src/common/di_ops.c @@ -86,7 +86,7 @@ tor_memcmp(const void *a, const void *b, size_t len) } return retval; -#endif /* timingsafe_memcmp */ +#endif /* defined(HAVE_TIMINGSAFE_MEMCMP) */ } /** @@ -238,7 +238,7 @@ gt_i64_timei(uint64_t a, uint64_t b) int res = diff >> 63; return res & 1; } -#endif +#endif /* SIZEOF_VOID_P == 8 */ /** * Given an array of list of <b>n_entries</b> uint64_t values, whose sum is diff --git a/src/common/di_ops.h b/src/common/di_ops.h index e174fcc4e4..e79973ba52 100644 --- a/src/common/di_ops.h +++ b/src/common/di_ops.h @@ -46,5 +46,5 @@ int select_array_member_cumulative_timei(const uint64_t *entries, int n_entries, uint64_t total, uint64_t rand_val); -#endif +#endif /* !defined(TOR_DI_OPS_H) */ diff --git a/src/common/handles.h b/src/common/handles.h index 6d7262ab80..a610753a1c 100644 --- a/src/common/handles.h +++ b/src/common/handles.h @@ -149,5 +149,5 @@ } \ } -#endif /* TOR_HANDLE_H */ +#endif /* !defined(TOR_HANDLE_H) */ diff --git a/src/common/log.c b/src/common/log.c index 6a5819064a..0becb5ce03 100644 --- a/src/common/log.c +++ b/src/common/log.c @@ -444,11 +444,11 @@ logfile_deliver(logfile_t *lf, const char *buf, size_t msg_len, if (m != msg_after_prefix) { tor_free(m); } -#else +#else /* !(defined(MAXLINE)) */ /* We have syslog but not MAXLINE. That's promising! */ syslog(severity, "%s", msg_after_prefix); -#endif -#endif +#endif /* defined(MAXLINE) */ +#endif /* defined(HAVE_SYSLOG_H) */ } else if (lf->callback) { if (domain & LD_NOCB) { if (!*callbacks_deferred && pending_cb_messages) { @@ -807,7 +807,7 @@ close_log(logfile_t *victim) /* There are no other syslogs; close the logging facility. */ closelog(); } -#endif +#endif /* defined(HAVE_SYSLOG_H) */ } } @@ -1144,7 +1144,7 @@ add_syslog_log(const log_severity_list_t *severity, UNLOCK_LOGS(); return 0; } -#endif +#endif /* defined(HAVE_SYSLOG_H) */ /** If <b>level</b> is a valid log severity, return the corresponding * numeric value. Otherwise, return -1. */ diff --git a/src/common/memarea.c b/src/common/memarea.c index 4e2a5e5fc5..b059987e0e 100644 --- a/src/common/memarea.c +++ b/src/common/memarea.c @@ -33,7 +33,7 @@ #define MEMAREA_ALIGN_MASK ((uintptr_t)7) #else #error "void* is neither 4 nor 8 bytes long. I don't know how to align stuff." -#endif +#endif /* MEMAREA_ALIGN == 4 || ... */ #if defined(__GNUC__) && defined(FLEXIBLE_ARRAY_MEMBER) #define USE_ALIGNED_ATTRIBUTE @@ -41,7 +41,7 @@ #define U_MEM mem #else #define U_MEM u.mem -#endif +#endif /* defined(__GNUC__) && defined(FLEXIBLE_ARRAY_MEMBER) */ #ifdef USE_SENTINELS /** Magic value that we stick at the end of a memarea so we can make sure @@ -61,11 +61,11 @@ uint32_t sent_val = get_uint32(&(chunk)->U_MEM[chunk->mem_size]); \ tor_assert(sent_val == SENTINEL_VAL); \ STMT_END -#else +#else /* !(defined(USE_SENTINELS)) */ #define SENTINEL_LEN 0 #define SET_SENTINEL(chunk) STMT_NIL #define CHECK_SENTINEL(chunk) STMT_NIL -#endif +#endif /* defined(USE_SENTINELS) */ /** Increment <b>ptr</b> until it is aligned to MEMAREA_ALIGN. */ static inline void * @@ -97,7 +97,7 @@ typedef struct memarea_chunk_t { void *void_for_alignment_; /**< Dummy; used to make sure mem is aligned. */ } u; /**< Union used to enforce alignment when we don't have support for * doing it right. */ -#endif +#endif /* defined(USE_ALIGNED_ATTRIBUTE) */ } memarea_chunk_t; /** How many bytes are needed for overhead before we get to the memory part @@ -308,7 +308,7 @@ memarea_assert_ok(memarea_t *area) } } -#else +#else /* !(!defined(DISABLE_MEMORY_SENTINELS)) */ struct memarea_t { smartlist_t *pieces; @@ -394,5 +394,5 @@ memarea_assert_ok(memarea_t *area) (void)area; } -#endif +#endif /* !defined(DISABLE_MEMORY_SENTINELS) */ diff --git a/src/common/memarea.h b/src/common/memarea.h index 85012c1c34..c3d954e1ce 100644 --- a/src/common/memarea.h +++ b/src/common/memarea.h @@ -20,5 +20,5 @@ void memarea_get_stats(memarea_t *area, size_t *allocated_out, size_t *used_out); void memarea_assert_ok(memarea_t *area); -#endif +#endif /* !defined(TOR_MEMAREA_H) */ diff --git a/src/common/procmon.c b/src/common/procmon.c index 5ef16c7268..26c11823e8 100644 --- a/src/common/procmon.c +++ b/src/common/procmon.c @@ -36,7 +36,7 @@ typedef int pid_t; #define PID_T_FORMAT I64_FORMAT #else #error Unknown: SIZEOF_PID_T -#endif +#endif /* (0 == SIZEOF_PID_T) && defined(_WIN32) || ... */ /* Define to 1 if process-termination monitors on this OS and Libevent version must poll for process termination themselves. */ @@ -114,7 +114,7 @@ struct tor_process_monitor_t { HANDLE hproc; /* XXXX We should have Libevent watch hproc for us, * if/when some version of Libevent can be told to do so. */ -#endif +#endif /* defined(_WIN32) */ /* XXXX On Linux, we can and should receive the 22nd * (space-delimited) field (‘starttime’) of /proc/$PID/stat from the @@ -219,7 +219,7 @@ tor_process_monitor_new(struct event_base *base, "try again later.", procmon->pid); } -#endif +#endif /* defined(_WIN32) */ procmon->cb = cb; procmon->cb_arg = cb_arg; @@ -232,9 +232,9 @@ tor_process_monitor_new(struct event_base *base, * tor_evtimer_new never returns NULL. */ evtimer_add(procmon->e, &poll_interval_tv); -#else +#else /* !(defined(PROCMON_POLLS)) */ #error OOPS? -#endif +#endif /* defined(PROCMON_POLLS) */ return procmon; err: @@ -306,11 +306,11 @@ tor_process_monitor_poll_cb(evutil_socket_t unused1, short unused2, tor_free(errmsg); } } -#else +#else /* !(defined(_WIN32)) */ /* Unix makes this part easy, if a bit racy. */ its_dead_jim = kill(procmon->pid, 0); its_dead_jim = its_dead_jim && (errno == ESRCH); -#endif +#endif /* defined(_WIN32) */ tor_log(its_dead_jim ? LOG_NOTICE : LOG_INFO, procmon->log_domain, "Monitored process "PID_T_FORMAT" is %s.", @@ -321,7 +321,7 @@ tor_process_monitor_poll_cb(evutil_socket_t unused1, short unused2, procmon->cb(procmon->cb_arg); } } -#endif +#endif /* defined(PROCMON_POLLS) */ /** Free the process-termination monitor <b>procmon</b>. */ void diff --git a/src/common/procmon.h b/src/common/procmon.h index b07cff2c4a..10ead11ba8 100644 --- a/src/common/procmon.h +++ b/src/common/procmon.h @@ -29,5 +29,5 @@ tor_process_monitor_t *tor_process_monitor_new(struct event_base *base, const char **msg); void tor_process_monitor_free(tor_process_monitor_t *procmon); -#endif +#endif /* !defined(TOR_PROCMON_H) */ diff --git a/src/common/pubsub.h b/src/common/pubsub.h index 6f4ce08754..2bee3af085 100644 --- a/src/common/pubsub.h +++ b/src/common/pubsub.h @@ -175,5 +175,5 @@ int pubsub_notify_(pubsub_topic_t *topic, pubsub_notify_fn_t notify_fn, pubsub_clear_(&name##_topic_); \ } -#endif /* TOR_PUBSUB_H */ +#endif /* !defined(TOR_PUBSUB_H) */ diff --git a/src/common/sandbox.c b/src/common/sandbox.c index a85b1406fa..7a4e3ece38 100644 --- a/src/common/sandbox.c +++ b/src/common/sandbox.c @@ -17,7 +17,7 @@ * with the libevent fix. */ #define _LARGEFILE64_SOURCE -#endif +#endif /* !defined(_LARGEFILE64_SOURCE) */ /** Malloc mprotect limit in bytes. * @@ -77,7 +77,7 @@ #define USE_BACKTRACE #define EXPOSE_CLEAN_BACKTRACE #include "backtrace.h" -#endif +#endif /* defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && ... */ #ifdef USE_BACKTRACE #include <execinfo.h> @@ -103,7 +103,7 @@ #define M_SYSCALL arm_r7 -#endif +#endif /* defined(__i386__) || ... */ /**Determines if at least one sandbox is active.*/ static int sandbox_active = 0; @@ -302,7 +302,7 @@ sb_time(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(0, SCMP_CMP_EQ, 0)); #else return 0; -#endif +#endif /* defined(__NR_time) */ } /** @@ -321,7 +321,7 @@ sb_accept4(scmp_filter_ctx ctx, sandbox_cfg_t *filter) if (rc) { return rc; } -#endif +#endif /* defined(__i386__) */ rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4), SCMP_CMP_MASKED(3, SOCK_CLOEXEC|SOCK_NONBLOCK, 0)); @@ -394,7 +394,7 @@ sb_mmap2(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return 0; } -#endif +#endif /* defined(__NR_mmap2) */ /** * Function responsible for setting up the open syscall for @@ -653,6 +653,25 @@ sb_socketpair(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return 0; } +#ifdef HAVE_KIST_SUPPORT + +#include <linux/sockios.h> + +static int +sb_ioctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter) +{ + int rc; + (void) filter; + + rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), + SCMP_CMP(1, SCMP_CMP_EQ, SIOCOUTQNSD)); + if (rc) + return rc; + return 0; +} + +#endif /* defined(HAVE_KIST_SUPPORT) */ + /** * Function responsible for setting up the setsockopt syscall for * the seccomp filter sandbox. @@ -693,7 +712,7 @@ sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUFFORCE)); if (rc) return rc; -#endif +#endif /* defined(HAVE_SYSTEMD) */ #ifdef IP_TRANSPARENT rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), @@ -701,7 +720,7 @@ sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(2, SCMP_CMP_EQ, IP_TRANSPARENT)); if (rc) return rc; -#endif +#endif /* defined(IP_TRANSPARENT) */ #ifdef IPV6_V6ONLY rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), @@ -709,7 +728,7 @@ sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(2, SCMP_CMP_EQ, IPV6_V6ONLY)); if (rc) return rc; -#endif +#endif /* defined(IPV6_V6ONLY) */ return 0; } @@ -742,7 +761,7 @@ sb_getsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(2, SCMP_CMP_EQ, SO_SNDBUF)); if (rc) return rc; -#endif +#endif /* defined(HAVE_SYSTEMD) */ #ifdef HAVE_LINUX_NETFILTER_IPV4_H rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), @@ -750,7 +769,7 @@ sb_getsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(2, SCMP_CMP_EQ, SO_ORIGINAL_DST)); if (rc) return rc; -#endif +#endif /* defined(HAVE_LINUX_NETFILTER_IPV4_H) */ #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), @@ -758,7 +777,16 @@ sb_getsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) SCMP_CMP(2, SCMP_CMP_EQ, IP6T_SO_ORIGINAL_DST)); if (rc) return rc; -#endif +#endif /* defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H) */ + +#ifdef HAVE_KIST_SUPPORT +#include <netinet/tcp.h> + rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), + SCMP_CMP(1, SCMP_CMP_EQ, SOL_TCP), + SCMP_CMP(2, SCMP_CMP_EQ, TCP_INFO)); + if (rc) + return rc; +#endif /* defined(HAVE_KIST_SUPPORT) */ return 0; } @@ -798,7 +826,7 @@ sb_fcntl64(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return 0; } -#endif +#endif /* defined(__NR_fcntl64) */ /** * Function responsible for setting up the epoll_ctl syscall for @@ -1023,7 +1051,7 @@ sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return 0; } -#endif +#endif /* defined(__NR_stat64) */ /** * Array of function pointers responsible for filtering different syscalls at @@ -1060,7 +1088,11 @@ static sandbox_filter_func_t filter_func[] = { sb_socket, sb_setsockopt, sb_getsockopt, - sb_socketpair + sb_socketpair, + +#ifdef HAVE_KIST_SUPPORT + sb_ioctl, +#endif }; const char * @@ -1708,7 +1740,7 @@ sigsys_debugging(int nr, siginfo_t *info, void *void_context) /* Clean up the top stack frame so we get the real function * name for the most recently failing function. */ clean_backtrace(syscall_cb_buf, depth, ctx); -#endif +#endif /* defined(USE_BACKTRACE) */ syscall_name = get_syscall_name(syscall); @@ -1782,7 +1814,7 @@ register_cfg(sandbox_cfg_t* cfg) return 0; } -#endif // USE_LIBSECCOMP +#endif /* defined(USE_LIBSECCOMP) */ #ifdef USE_LIBSECCOMP /** @@ -1812,7 +1844,7 @@ sandbox_is_active(void) { return sandbox_active != 0; } -#endif // USE_LIBSECCOMP +#endif /* defined(USE_LIBSECCOMP) */ sandbox_cfg_t* sandbox_cfg_new(void) @@ -1840,7 +1872,7 @@ sandbox_init(sandbox_cfg_t *cfg) "Currently, sandboxing is only implemented on Linux. The feature " "is disabled on your platform."); return 0; -#endif +#endif /* defined(USE_LIBSECCOMP) || ... */ } #ifndef USE_LIBSECCOMP @@ -1896,5 +1928,5 @@ void sandbox_disable_getaddrinfo_cache(void) { } -#endif +#endif /* !defined(USE_LIBSECCOMP) */ diff --git a/src/common/sandbox.h b/src/common/sandbox.h index 55454eaa2b..d0f85570f4 100644 --- a/src/common/sandbox.h +++ b/src/common/sandbox.h @@ -23,7 +23,7 @@ */ #define SYS_SECCOMP 1 -#endif +#endif /* !defined(SYS_SECCOMP) */ #if defined(HAVE_SECCOMP_H) && defined(__linux__) #define USE_LIBSECCOMP @@ -101,7 +101,7 @@ typedef struct { sandbox_cfg_t *filter_dynamic; } sandbox_t; -#endif // USE_LIBSECCOMP +#endif /* defined(USE_LIBSECCOMP) */ #ifdef USE_LIBSECCOMP /** Pre-calls getaddrinfo in order to pre-record result. */ @@ -114,7 +114,7 @@ int sandbox_getaddrinfo(const char *name, const char *servname, struct addrinfo **res); void sandbox_freeaddrinfo(struct addrinfo *addrinfo); void sandbox_free_getaddrinfo_cache(void); -#else +#else /* !(defined(USE_LIBSECCOMP)) */ #define sandbox_getaddrinfo(name, servname, hints, res) \ getaddrinfo((name),(servname), (hints),(res)) #define sandbox_add_addrinfo(name) \ @@ -122,16 +122,16 @@ void sandbox_free_getaddrinfo_cache(void); #define sandbox_freeaddrinfo(addrinfo) \ freeaddrinfo((addrinfo)) #define sandbox_free_getaddrinfo_cache() -#endif +#endif /* defined(USE_LIBSECCOMP) */ #ifdef USE_LIBSECCOMP /** Returns a registered protected string used with the sandbox, given that * it matches the parameter. */ const char* sandbox_intern_string(const char *param); -#else +#else /* !(defined(USE_LIBSECCOMP)) */ #define sandbox_intern_string(s) (s) -#endif +#endif /* defined(USE_LIBSECCOMP) */ /** Creates an empty sandbox configuration file.*/ sandbox_cfg_t * sandbox_cfg_new(void); @@ -170,5 +170,5 @@ int sandbox_is_active(void); void sandbox_disable_getaddrinfo_cache(void); -#endif /* SANDBOX_H_ */ +#endif /* !defined(SANDBOX_H_) */ diff --git a/src/common/storagedir.h b/src/common/storagedir.h index db25057e65..3de0afc361 100644 --- a/src/common/storagedir.h +++ b/src/common/storagedir.h @@ -47,5 +47,5 @@ int storage_dir_shrink(storage_dir_t *d, int storage_dir_remove_all(storage_dir_t *d); int storage_dir_get_max_files(storage_dir_t *d); -#endif +#endif /* !defined(TOR_STORAGEDIR_H) */ diff --git a/src/common/testsupport.h b/src/common/testsupport.h index 9fc96199b4..a3f2ff91ed 100644 --- a/src/common/testsupport.h +++ b/src/common/testsupport.h @@ -10,7 +10,7 @@ #else #define STATIC static #define EXTERN(type, name) -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /** Quick and dirty macros to implement test mocking. * @@ -76,15 +76,15 @@ do { \ func = func ##__real; \ } while (0) -#else +#else /* !(defined(TOR_UNIT_TESTS)) */ #define MOCK_DECL(rv, funcname, arglist) \ rv funcname arglist #define MOCK_DECL_ATTR(rv, funcname, arglist, attr) \ rv funcname arglist attr #define MOCK_IMPL(rv, funcname, arglist) \ rv funcname arglist -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /** @} */ -#endif +#endif /* !defined(TOR_TESTSUPPORT_H) */ diff --git a/src/common/timers.c b/src/common/timers.c index 42d368baab..c8e09414f4 100644 --- a/src/common/timers.c +++ b/src/common/timers.c @@ -53,7 +53,7 @@ struct timeout_cb { #else /* We're not exposing any of the functions outside this file. */ #define TIMEOUT_PUBLIC static -#endif +#endif /* defined(__GNUC__) */ /* We're not using periodic events. */ #define TIMEOUT_DISABLE_INTERVALS /* We always know the global_timeouts object, so we don't need each timeout diff --git a/src/common/timers.h b/src/common/timers.h index d9602cd2ae..d4d4fb00a9 100644 --- a/src/common/timers.h +++ b/src/common/timers.h @@ -26,5 +26,5 @@ void timers_shutdown(void); STATIC void timers_run_pending(void); #endif -#endif +#endif /* !defined(TOR_TIMERS_H) */ diff --git a/src/common/torint.h b/src/common/torint.h index ee31459e94..bc81c114f8 100644 --- a/src/common/torint.h +++ b/src/common/torint.h @@ -34,8 +34,8 @@ does the same thing (but doesn't defined __FreeBSD__). */ #include <machine/limits.h> -#endif -#endif +#endif /* !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) */ +#endif /* defined(HAVE_MACHINE_LIMITS_H) */ #ifdef HAVE_INTTYPES_H #include <inttypes.h> #endif @@ -80,7 +80,7 @@ typedef signed char int8_t; typedef unsigned char uint8_t; #define HAVE_UINT8_T #endif -#endif +#endif /* (SIZEOF_CHAR == 1) */ #if (SIZEOF_SHORT == 2) #ifndef HAVE_INT16_T @@ -91,7 +91,7 @@ typedef signed short int16_t; typedef unsigned short uint16_t; #define HAVE_UINT16_T #endif -#endif +#endif /* (SIZEOF_SHORT == 2) */ #if (SIZEOF_INT == 2) #ifndef HAVE_INT16_T @@ -129,7 +129,7 @@ typedef unsigned int uint32_t; #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif -#endif +#endif /* (SIZEOF_INT == 2) || ... */ #if (SIZEOF_LONG == 4) #ifndef HAVE_INT32_T @@ -142,7 +142,7 @@ typedef unsigned long uint32_t; #ifndef UINT32_MAX #define UINT32_MAX 0xfffffffful #endif -#endif +#endif /* !defined(HAVE_UINT32_T) */ #elif (SIZEOF_LONG == 8) #ifndef HAVE_INT64_T typedef signed long int64_t; @@ -155,7 +155,7 @@ typedef unsigned long uint64_t; #ifndef UINT64_MAX #define UINT64_MAX 0xfffffffffffffffful #endif -#endif +#endif /* (SIZEOF_LONG == 4) || ... */ #if (SIZEOF_LONG_LONG == 8) #ifndef HAVE_INT64_T @@ -172,7 +172,7 @@ typedef unsigned long long uint64_t; #ifndef INT64_MAX #define INT64_MAX 0x7fffffffffffffffll #endif -#endif +#endif /* (SIZEOF_LONG_LONG == 8) */ #if (SIZEOF___INT64 == 8) #ifndef HAVE_INT64_T @@ -189,7 +189,7 @@ typedef unsigned __int64 uint64_t; #ifndef INT64_MAX #define INT64_MAX 0x7fffffffffffffffi64 #endif -#endif +#endif /* (SIZEOF___INT64 == 8) */ #ifndef INT64_MIN #define INT64_MIN ((- INT64_MAX) - 1) @@ -202,8 +202,8 @@ typedef unsigned __int64 uint64_t; #define SIZE_MAX UINT32_MAX #else #error "Can't define SIZE_MAX" -#endif -#endif +#endif /* SIZEOF_SIZE_T == 8 || ... */ +#endif /* !defined(SIZE_MAX) */ #ifndef HAVE_SSIZE_T #if SIZEOF_SIZE_T == 8 @@ -212,8 +212,8 @@ typedef int64_t ssize_t; typedef int32_t ssize_t; #else #error "Can't define ssize_t." -#endif -#endif +#endif /* SIZEOF_SIZE_T == 8 || ... */ +#endif /* !defined(HAVE_SSIZE_T) */ #if (SIZEOF_VOID_P > 4 && SIZEOF_VOID_P <= 8) #ifndef HAVE_INTPTR_T @@ -235,7 +235,7 @@ typedef uint32_t uintptr_t; #endif #else #error "void * is either >8 bytes or <= 2. In either case, I am confused." -#endif +#endif /* (SIZEOF_VOID_P > 4 && SIZEOF_VOID_P <= 8) || ... */ #ifndef HAVE_INT8_T #error "Missing type int8_t" @@ -275,8 +275,8 @@ typedef uint32_t uintptr_t; #define LONG_MAX 0x7fffffffffffffffL #else #error "Can't define LONG_MAX" -#endif -#endif +#endif /* (SIZEOF_LONG == 4) || ... */ +#endif /* !defined(LONG_MAX) */ #ifndef INT_MAX #if (SIZEOF_INT == 4) @@ -285,8 +285,8 @@ typedef uint32_t uintptr_t; #define INT_MAX 0x7fffffffffffffffL #else #error "Can't define INT_MAX" -#endif -#endif +#endif /* (SIZEOF_INT == 4) || ... */ +#endif /* !defined(INT_MAX) */ #ifndef UINT_MAX #if (SIZEOF_INT == 2) @@ -297,8 +297,8 @@ typedef uint32_t uintptr_t; #define UINT_MAX 0xffffffffffffffffu #else #error "Can't define UINT_MAX" -#endif -#endif +#endif /* (SIZEOF_INT == 2) || ... */ +#endif /* !defined(UINT_MAX) */ #ifndef SHORT_MAX #if (SIZEOF_SHORT == 2) @@ -307,8 +307,8 @@ typedef uint32_t uintptr_t; #define SHORT_MAX 0x7fffffff #else #error "Can't define SHORT_MAX" -#endif -#endif +#endif /* (SIZEOF_SHORT == 2) || ... */ +#endif /* !defined(SHORT_MAX) */ #ifndef TIME_MAX @@ -320,9 +320,9 @@ typedef uint32_t uintptr_t; #define TIME_MAX ((time_t)INT64_MAX) #else #error "Can't define TIME_MAX" -#endif +#endif /* (SIZEOF_TIME_T == SIZEOF_INT) || ... */ -#endif /* ifndef(TIME_MAX) */ +#endif /* !defined(TIME_MAX) */ #ifndef TIME_MIN @@ -334,9 +334,9 @@ typedef uint32_t uintptr_t; #define TIME_MIN ((time_t)INT64_MIN) #else #error "Can't define TIME_MIN" -#endif +#endif /* (SIZEOF_TIME_T == SIZEOF_INT) || ... */ -#endif /* ifndef(TIME_MIN) */ +#endif /* !defined(TIME_MIN) */ #ifndef SIZE_MAX #if (SIZEOF_SIZE_T == 4) @@ -345,8 +345,8 @@ typedef uint32_t uintptr_t; #define SIZE_MAX UINT64_MAX #else #error "Can't define SIZE_MAX" -#endif -#endif +#endif /* (SIZEOF_SIZE_T == 4) || ... */ +#endif /* !defined(SIZE_MAX) */ #ifndef SSIZE_MAX #if (SIZEOF_SIZE_T == 4) @@ -355,13 +355,13 @@ typedef uint32_t uintptr_t; #define SSIZE_MAX INT64_MAX #else #error "Can't define SSIZE_MAX" -#endif -#endif +#endif /* (SIZEOF_SIZE_T == 4) || ... */ +#endif /* !defined(SSIZE_MAX) */ /** Any ssize_t larger than this amount is likely to be an underflow. */ #define SSIZE_T_CEILING ((ssize_t)(SSIZE_MAX-16)) /** Any size_t larger than this amount is likely to be an underflow. */ #define SIZE_T_CEILING ((size_t)(SSIZE_MAX-16)) -#endif /* __TORINT_H */ +#endif /* !defined(TOR_TORINT_H) */ diff --git a/src/common/torlog.h b/src/common/torlog.h index 6e374b1c11..65bf41702a 100644 --- a/src/common/torlog.h +++ b/src/common/torlog.h @@ -22,7 +22,7 @@ #error "Your syslog.h thinks high numbers are more important. " \ "We aren't prepared to deal with that." #endif -#else +#else /* !(defined(HAVE_SYSLOG_H)) */ /* Note: Syslog's logging code refers to priorities, with 0 being the most * important. Thus, all our comparisons needed to be reversed when we added * syslog support. @@ -48,7 +48,7 @@ /** Error-level severity: for messages that only appear when something has gone * very wrong, and the Tor process can no longer proceed. */ #define LOG_ERR 3 -#endif +#endif /* defined(HAVE_SYSLOG_H) */ /* Logging domains */ @@ -213,7 +213,7 @@ void log_fn_ratelim_(struct ratelim_t *ratelim, int severity, #define log_err(domain, args...) \ log_fn_(LOG_ERR, domain, __FUNCTION__, args) -#else /* ! defined(__GNUC__) */ +#else /* !(defined(__GNUC__) && __GNUC__ <= 3) */ /* Here are the c99 variadic macros, to work with non-GCC compilers */ @@ -240,7 +240,7 @@ void log_fn_ratelim_(struct ratelim_t *ratelim, int severity, #define log_fn_ratelim(ratelim, severity, domain, args,...) \ log_fn_ratelim_(ratelim, severity, domain, __FUNCTION__, \ args, ##__VA_ARGS__) -#endif +#endif /* defined(__GNUC__) && __GNUC__ <= 3 */ #ifdef LOG_PRIVATE MOCK_DECL(STATIC void, logv, (int severity, log_domain_mask_t domain, @@ -249,5 +249,5 @@ MOCK_DECL(STATIC void, logv, (int severity, log_domain_mask_t domain, #endif # define TOR_TORLOG_H -#endif +#endif /* !defined(TOR_TORLOG_H) */ diff --git a/src/common/tortls.c b/src/common/tortls.c index 5f3cd92a63..8727b605b3 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -76,7 +76,7 @@ ENABLE_GCC_WARNING(redundant-decls) * SSL3 safely at the same time. */ #define DISABLE_SSL3_HANDSHAKE -#endif +#endif /* OPENSSL_VERSION_NUMBER < OPENSSL_V(1,0,0,'f') */ /* We redefine these so that we can run correctly even if the vendor gives us * a version of OpenSSL that does not match its header files. (Apple: I am @@ -390,7 +390,7 @@ tor_tls_init(void) "when configuring it) would make ECDH much faster."); } /* LCOV_EXCL_STOP */ -#endif +#endif /* (SIZEOF_VOID_P >= 8 && ... */ tor_tls_allocate_tor_tls_object_ex_data_index(); @@ -1134,7 +1134,7 @@ tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime, * with existing Tors. */ if (!(result->ctx = SSL_CTX_new(TLSv1_method()))) goto error; -#endif +#endif /* 0 */ /* Tell OpenSSL to use TLS 1.0 or later but not SSL2 or SSL3. */ #ifdef HAVE_TLS_METHOD @@ -1143,7 +1143,7 @@ tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime, #else if (!(result->ctx = SSL_CTX_new(SSLv23_method()))) goto error; -#endif +#endif /* defined(HAVE_TLS_METHOD) */ SSL_CTX_set_options(result->ctx, SSL_OP_NO_SSLv2); SSL_CTX_set_options(result->ctx, SSL_OP_NO_SSLv3); @@ -1193,7 +1193,7 @@ tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime, if (result->ctx->comp_methods) result->ctx->comp_methods = NULL; #endif -#endif +#endif /* OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,1,0) */ #ifdef SSL_MODE_RELEASE_BUFFERS SSL_CTX_set_mode(result->ctx, SSL_MODE_RELEASE_BUFFERS); @@ -1354,7 +1354,7 @@ find_cipher_by_id(const SSL *ssl, const SSL_METHOD *m, uint16_t cipher) tor_assert((SSL_CIPHER_get_id(c) & 0xffff) == cipher); return c != NULL; } -#else +#else /* !(defined(HAVE_SSL_CIPHER_FIND)) */ # if defined(HAVE_STRUCT_SSL_METHOD_ST_GET_CIPHER_BY_CHAR) if (m && m->get_cipher_by_char) { @@ -1368,7 +1368,7 @@ find_cipher_by_id(const SSL *ssl, const SSL_METHOD *m, uint16_t cipher) tor_assert((c->id & 0xffff) == cipher); return c != NULL; } -# endif +#endif /* defined(HAVE_STRUCT_SSL_METHOD_ST_GET_CIPHER_BY_CHAR) */ # ifndef OPENSSL_1_1_API if (m && m->get_cipher && m->num_ciphers) { /* It would seem that some of the "let's-clean-up-openssl" forks have @@ -1384,12 +1384,12 @@ find_cipher_by_id(const SSL *ssl, const SSL_METHOD *m, uint16_t cipher) } return 0; } -# endif +#endif /* !defined(OPENSSL_1_1_API) */ (void) ssl; (void) m; (void) cipher; return 1; /* No way to search */ -#endif +#endif /* defined(HAVE_SSL_CIPHER_FIND) */ } /** Remove from v2_cipher_list every cipher that we don't support, so that @@ -1517,7 +1517,7 @@ tor_tls_client_is_using_v2_ciphers(const SSL *ssl) return CIPHERS_ERR; } ciphers = session->ciphers; -#endif +#endif /* defined(HAVE_SSL_GET_CLIENT_CIPHERS) */ return tor_tls_classify_client_ciphers(ssl, ciphers) >= CIPHERS_V2; } @@ -1648,7 +1648,7 @@ tor_tls_new(int sock, int isServer) SSL_set_tlsext_host_name(result->ssl, fake_hostname); tor_free(fake_hostname); } -#endif +#endif /* defined(SSL_set_tlsext_host_name) */ if (!SSL_set_cipher_list(result->ssl, isServer ? SERVER_CIPHER_LIST : CLIENT_CIPHER_LIST)) { @@ -1775,7 +1775,7 @@ tor_tls_assert_renegotiation_unblocked(tor_tls_t *tls) tor_assert(0 != (options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)); #else (void) tls; -#endif +#endif /* defined(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) && ... */ } /** Return whether this tls initiated the connect (client) or @@ -2311,7 +2311,7 @@ tor_x509_cert_replace_expiration(const tor_x509_cert_t *inp, EVP_PKEY_free(pk); return tor_x509_cert_new(newc); } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /** Return the number of bytes available for reading from <b>tls</b>. */ @@ -2355,10 +2355,10 @@ tor_tls_get_n_raw_bytes(tor_tls_t *tls, size_t *n_read, size_t *n_written) if (BIO_method_type(wbio) == BIO_TYPE_BUFFER && (tmpbio = BIO_next(wbio)) != NULL) wbio = tmpbio; -#else +#else /* !(OPENSSL_VERSION_NUMBER >= OPENSSL_VER(1,1,0,0,5)) */ if (wbio->method == BIO_f_buffer() && (tmpbio = BIO_next(wbio)) != NULL) wbio = tmpbio; -#endif +#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_VER(1,1,0,0,5) */ w = (unsigned long) BIO_number_written(wbio); /* We are ok with letting these unsigned ints go "negative" here: @@ -2437,7 +2437,7 @@ SSL_get_client_random(SSL *s, uint8_t *out, size_t len) memcpy(out, s->s3->client_random, len); return len; } -#endif +#endif /* !defined(HAVE_SSL_GET_CLIENT_RANDOM) */ #ifndef HAVE_SSL_GET_SERVER_RANDOM static size_t @@ -2450,7 +2450,7 @@ SSL_get_server_random(SSL *s, uint8_t *out, size_t len) memcpy(out, s->s3->server_random, len); return len; } -#endif +#endif /* !defined(HAVE_SSL_GET_SERVER_RANDOM) */ #ifndef HAVE_SSL_SESSION_GET_MASTER_KEY STATIC size_t @@ -2464,7 +2464,7 @@ SSL_SESSION_get_master_key(SSL_SESSION *s, uint8_t *out, size_t len) memcpy(out, s->master_key, len); return len; } -#endif +#endif /* !defined(HAVE_SSL_SESSION_GET_MASTER_KEY) */ /** Set the DIGEST256_LEN buffer at <b>secrets_out</b> to the value used in * the v3 handshake to prove that the client knows the TLS secrets for the @@ -2573,7 +2573,7 @@ tor_tls_get_buffer_sizes(tor_tls_t *tls, (void)wbuf_bytes; return -1; -#else +#else /* !(OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)) */ if (tls->ssl->s3->rbuf.buf) *rbuf_capacity = tls->ssl->s3->rbuf.len; else @@ -2585,7 +2585,7 @@ tor_tls_get_buffer_sizes(tor_tls_t *tls, *rbuf_bytes = tls->ssl->s3->rbuf.left; *wbuf_bytes = tls->ssl->s3->wbuf.left; return 0; -#endif +#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0) */ } /** Check whether the ECC group requested is supported by the current OpenSSL diff --git a/src/common/tortls.h b/src/common/tortls.h index f430aff70b..6145f7dbc9 100644 --- a/src/common/tortls.h +++ b/src/common/tortls.h @@ -161,7 +161,7 @@ STATIC int tor_tls_session_secret_cb(struct ssl_st *ssl, void *secret, void *arg); STATIC int find_cipher_by_id(const SSL *ssl, const SSL_METHOD *m, uint16_t cipher); -#endif +#endif /* defined(TORTLS_OPENSSL_PRIVATE) */ MOCK_DECL(STATIC struct x509_st *, tor_tls_create_certificate, (crypto_pk_t *rsa, crypto_pk_t *rsa_sign, @@ -192,9 +192,9 @@ STATIC tor_x509_cert_t *tor_x509_cert_replace_expiration( const tor_x509_cert_t *inp, time_t new_expiration_time, crypto_pk_t *signing_key); -#endif +#endif /* defined(TOR_UNIT_TESTS) */ -#endif /* endif TORTLS_PRIVATE */ +#endif /* defined(TORTLS_PRIVATE) */ tor_x509_cert_t *tor_x509_cert_dup(const tor_x509_cert_t *cert); const char *tor_tls_err_to_string(int err); @@ -288,5 +288,5 @@ const char *tor_tls_get_ciphersuite_name(tor_tls_t *tls); int evaluate_ecgroup_for_tls(const char *ecgroup); -#endif +#endif /* !defined(TOR_TORTLS_H) */ diff --git a/src/common/util.c b/src/common/util.c index c8358ea705..bcb1449a18 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -31,11 +31,11 @@ #include <process.h> #include <tchar.h> #include <winbase.h> -#else +#else /* !(defined(_WIN32)) */ #include <dirent.h> #include <pwd.h> #include <grp.h> -#endif +#endif /* defined(_WIN32) */ /* math.h needs this on Linux */ #ifndef _USE_ISOC99_ @@ -84,8 +84,8 @@ * scold us for being so stupid as to autodetect its presence. To be fair, * they've done this since 1996, when autoconf was only 5 years old. */ #include <malloc.h> -#endif -#endif +#endif /* !defined(OpenBSD) && !defined(__FreeBSD__) */ +#endif /* defined(HAVE_MALLOC_H) */ #ifdef HAVE_MALLOC_NP_H #include <malloc_np.h> #endif @@ -116,12 +116,12 @@ dmalloc_strndup(file, line, (string), -1, xalloc_b) #else #error "No dmalloc_strdup or equivalent" - #endif +#endif /* defined(HAVE_DMALLOC_STRDUP) || ... */ -#else /* not using dmalloc */ +#else /* !(defined(USE_DMALLOC)) */ #define DMALLOC_FN_ARGS -#endif +#endif /* defined(USE_DMALLOC) */ /** Allocate a chunk of <b>size</b> bytes of memory, and return a pointer to * result. On error, log and terminate the process. (Same as malloc(size), @@ -142,7 +142,7 @@ tor_malloc_(size_t size DMALLOC_PARAMS) if (size==0) { size=1; } -#endif +#endif /* !defined(MALLOC_ZERO_WORKS) */ #ifdef USE_DMALLOC result = dmalloc_malloc(file, line, size, DMALLOC_FUNC_MALLOC, 0, 0); @@ -233,7 +233,7 @@ tor_realloc_(void *ptr, size_t size DMALLOC_PARAMS) if (size==0) { size=1; } -#endif +#endif /* !defined(MALLOC_ZERO_WORKS) */ #ifdef USE_DMALLOC result = dmalloc_realloc(file, line, ptr, size, DMALLOC_FUNC_REALLOC, 0); @@ -362,16 +362,16 @@ tor_log_mallinfo(int severity) mi.arena, mi.ordblks, mi.smblks, mi.hblks, mi.hblkhd, mi.usmblks, mi.fsmblks, mi.uordblks, mi.fordblks, mi.keepcost); -#else +#else /* !(defined(HAVE_MALLINFO)) */ (void)severity; -#endif +#endif /* defined(HAVE_MALLINFO) */ #ifdef USE_DMALLOC dmalloc_log_changed(0, /* Since the program started. */ 1, /* Log info about non-freed pointers. */ 0, /* Do not log info about freed pointers. */ 0 /* Do not log individual pointers. */ ); -#endif +#endif /* defined(USE_DMALLOC) */ } ENABLE_GCC_WARNING(aggregate-return) @@ -401,7 +401,7 @@ tor_lround(double d) return (long)rint(d); #else return (long)(d > 0 ? d + 0.5 : ceil(d - 0.5)); -#endif +#endif /* defined(HAVE_LROUND) || ... */ } /** Return the 64-bit integer closest to d. We define this wrapper here so @@ -416,7 +416,7 @@ tor_llround(double d) return (int64_t)rint(d); #else return (int64_t)(d > 0 ? d + 0.5 : ceil(d - 0.5)); -#endif +#endif /* defined(HAVE_LLROUND) || ... */ } /** Returns floor(log2(u64)). If u64 is 0, (incorrectly) returns 0. */ @@ -477,7 +477,7 @@ round_to_power_of_2(uint64_t u64) /** Return the lowest x such that x is at least <b>number</b>, and x modulo * <b>divisor</b> == 0. If no such x can be expressed as an unsigned, return - * UINT_MAX */ + * UINT_MAX. Asserts if divisor is zero. */ unsigned round_to_next_multiple_of(unsigned number, unsigned divisor) { @@ -491,7 +491,7 @@ round_to_next_multiple_of(unsigned number, unsigned divisor) /** Return the lowest x such that x is at least <b>number</b>, and x modulo * <b>divisor</b> == 0. If no such x can be expressed as a uint32_t, return - * UINT32_MAX */ + * UINT32_MAX. Asserts if divisor is zero. */ uint32_t round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor) { @@ -506,7 +506,7 @@ round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor) /** Return the lowest x such that x is at least <b>number</b>, and x modulo * <b>divisor</b> == 0. If no such x can be expressed as a uint64_t, return - * UINT64_MAX */ + * UINT64_MAX. Asserts if divisor is zero. */ uint64_t round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor) { @@ -1238,7 +1238,7 @@ tor_parse_uint64(const char *s, int base, uint64_t min, r = (uint64_t)strtoul(s, &endptr, base); #else #error "I don't know how to parse 64-bit numbers." -#endif +#endif /* defined(HAVE_STRTOULL) || ... */ CHECK_STRTOX_RESULT(); } @@ -1636,7 +1636,7 @@ tor_timegm(const struct tm *tm, time_t *time_out) log_warn(LD_BUG, "Result does not fit in tor_timegm"); return -1; } -#endif +#endif /* SIZEOF_TIME_T < 8 */ *time_out = (time_t)seconds; return 0; } @@ -2014,7 +2014,7 @@ update_approx_time(time_t now) { cached_approx_time = now; } -#endif +#endif /* !defined(TIME_IS_FAST) */ /* ===== * Rate limiting @@ -2143,9 +2143,9 @@ clean_name_for_stat(char *name) return; name[len-1]='\0'; } -#else +#else /* !(defined(_WIN32)) */ (void)name; -#endif +#endif /* defined(_WIN32) */ } /** Wrapper for unlink() to make it mockable for the test suite; returns 0 @@ -2342,21 +2342,27 @@ check_private_dir,(const char *dirname, cpd_check_t check, running_gid = getgid(); } if (st.st_uid != running_uid) { - const struct passwd *pw_uid = NULL; - char *process_ownername = NULL; + char *process_ownername = NULL, *file_ownername = NULL; - pw_uid = tor_getpwuid(running_uid); - process_ownername = pw_uid ? tor_strdup(pw_uid->pw_name) : - tor_strdup("<unknown>"); + { + const struct passwd *pw_running = tor_getpwuid(running_uid); + process_ownername = pw_running ? tor_strdup(pw_running->pw_name) : + tor_strdup("<unknown>"); + } - pw_uid = tor_getpwuid(st.st_uid); + { + const struct passwd *pw_stat = tor_getpwuid(st.st_uid); + file_ownername = pw_stat ? tor_strdup(pw_stat->pw_name) : + tor_strdup("<unknown>"); + } log_warn(LD_FS, "%s is not owned by this user (%s, %d) but by " "%s (%d). Perhaps you are running Tor as the wrong user?", - dirname, process_ownername, (int)running_uid, - pw ? pw->pw_name : "<unknown>", (int)st.st_uid); + dirname, process_ownername, (int)running_uid, + file_ownername, (int)st.st_uid); tor_free(process_ownername); + tor_free(file_ownername); close(fd); return -1; } @@ -2413,7 +2419,7 @@ check_private_dir,(const char *dirname, cpd_check_t check, } } close(fd); -#else +#else /* !(!defined(_WIN32)) */ /* Win32 case: we can't open() a directory. */ (void)effective_user; @@ -2447,7 +2453,7 @@ check_private_dir,(const char *dirname, cpd_check_t check, return -1; } -#endif +#endif /* !defined(_WIN32) */ return 0; } @@ -2467,7 +2473,7 @@ write_str_to_file,(const char *fname, const char *str, int bin)) "We're writing a text string that already contains a CR to %s", escaped(fname)); } -#endif +#endif /* defined(_WIN32) */ return write_bytes_to_file(fname, str, strlen(str), bin); } @@ -2867,7 +2873,7 @@ read_file_to_str, (const char *filename, int flags, struct stat *stat_out)) errno = save_errno; return string; } -#endif +#endif /* !defined(_WIN32) */ if ((uint64_t)(statbuf.st_size)+1 >= SIZE_T_CEILING) { close(fd); @@ -2900,7 +2906,7 @@ read_file_to_str, (const char *filename, int flags, struct stat *stat_out)) if (!bin) { statbuf.st_size = (size_t) r; } else -#endif +#endif /* defined(_WIN32) || defined(__CYGWIN__) */ if (r != statbuf.st_size) { /* Unless we're using text mode on win32, we'd better have an exact * match for size. */ @@ -3084,7 +3090,7 @@ expand_filename(const char *filename) * Chapter+3.+Input+Validation/3.7+Validating+Filenames+and+Paths/ */ return tor_strdup(filename); -#else +#else /* !(defined(_WIN32)) */ if (*filename == '~') { char *home, *result=NULL; const char *rest; @@ -3114,10 +3120,10 @@ expand_filename(const char *filename) } tor_free(username); rest = slash ? (slash+1) : ""; -#else +#else /* !(defined(HAVE_PWD_H)) */ log_warn(LD_CONFIG, "Couldn't expand homedir on system without pwd.h"); return tor_strdup(filename); -#endif +#endif /* defined(HAVE_PWD_H) */ } tor_assert(home); /* Remove trailing slash. */ @@ -3130,7 +3136,7 @@ expand_filename(const char *filename) } else { return tor_strdup(filename); } -#endif +#endif /* defined(_WIN32) */ } #define MAX_SCANF_WIDTH 9999 @@ -3499,7 +3505,7 @@ tor_listdir, (const char *dirname)) name[sizeof(name)-1] = '\0'; #else strlcpy(name,findData.cFileName,sizeof(name)); -#endif +#endif /* defined(UNICODE) */ if (strcmp(name, ".") && strcmp(name, "..")) { smartlist_add_strdup(result, name); @@ -3516,7 +3522,7 @@ tor_listdir, (const char *dirname)) } FindClose(handle); tor_free(pattern); -#else +#else /* !(defined(_WIN32)) */ const char *prot_dname = sandbox_intern_string(dirname); DIR *d; struct dirent *de; @@ -3531,7 +3537,7 @@ tor_listdir, (const char *dirname)) smartlist_add_strdup(result, de->d_name); } closedir(d); -#endif +#endif /* defined(_WIN32) */ return result; } @@ -3547,7 +3553,7 @@ path_is_relative(const char *filename) else if (filename && strlen(filename)>3 && TOR_ISALPHA(filename[0]) && filename[1] == ':' && filename[2] == '\\') return 0; -#endif +#endif /* defined(_WIN32) */ else return 1; } @@ -3677,7 +3683,7 @@ finish_daemon(const char *desired_cwd) } close(daemon_filedes[1]); } -#else +#else /* !(!defined(_WIN32)) */ /* defined(_WIN32) */ void start_daemon(void) @@ -3688,7 +3694,7 @@ finish_daemon(const char *cp) { (void)cp; } -#endif +#endif /* !defined(_WIN32) */ /** Write the current process ID, followed by NL, into <b>filename</b>. * Return 0 on success, -1 on failure. @@ -3730,7 +3736,7 @@ load_windows_system_library(const TCHAR *library_name) _tcscat(path, library_name); return LoadLibrary(path); } -#endif +#endif /* defined(_WIN32) */ /** Format a single argument for being put on a Windows command line. * Returns a newly allocated string */ @@ -4025,7 +4031,7 @@ format_helper_exit_status(unsigned char child_state, int saved_errno, done: return res; } -#endif +#endif /* !defined(_WIN32) */ /* Maximum number of file descriptors, if we cannot get it via sysconf() */ #define DEFAULT_MAX_FD 256 @@ -4049,12 +4055,12 @@ tor_terminate_process(process_handle_t *process_handle) else return 0; } -#else /* Unix */ +#else /* !(defined(_WIN32)) */ if (process_handle->waitpid_cb) { /* We haven't got a waitpid yet, so we can just kill off the process. */ return kill(process_handle->pid, SIGTERM); } -#endif +#endif /* defined(_WIN32) */ return 0; /* We didn't need to kill the process, so report success */ } @@ -4076,14 +4082,14 @@ tor_process_get_stdout_pipe(process_handle_t *process_handle) { return process_handle->stdout_pipe; } -#else +#else /* !(defined(_WIN32)) */ /* DOCDOC tor_process_get_stdout_pipe */ int tor_process_get_stdout_pipe(process_handle_t *process_handle) { return process_handle->stdout_pipe; } -#endif +#endif /* defined(_WIN32) */ /* DOCDOC process_handle_new */ static process_handle_t * @@ -4099,7 +4105,7 @@ process_handle_new(void) out->stdin_pipe = -1; out->stdout_pipe = -1; out->stderr_pipe = -1; -#endif +#endif /* defined(_WIN32) */ return out; } @@ -4119,7 +4125,7 @@ process_handle_waitpid_cb(int status, void *arg) process_handle->status = PROCESS_STATUS_NOTRUNNING; process_handle->waitpid_cb = 0; } -#endif +#endif /* !defined(_WIN32) */ /** * @name child-process states @@ -4302,7 +4308,7 @@ tor_spawn_background(const char *const filename, const char **argv, /* TODO: Close pipes on exit */ *process_handle_out = process_handle; return status; -#else // _WIN32 +#else /* !(defined(_WIN32)) */ pid_t pid; int stdout_pipe[2]; int stderr_pipe[2]; @@ -4376,9 +4382,9 @@ tor_spawn_background(const char *const filename, const char **argv, "Cannot find maximum file descriptor, assuming %d", max_fd); } } -#else +#else /* !(defined(_SC_OPEN_MAX)) */ max_fd = DEFAULT_MAX_FD; -#endif +#endif /* defined(_SC_OPEN_MAX) */ // child_state = CHILD_STATE_FORK; @@ -4393,7 +4399,7 @@ tor_spawn_background(const char *const filename, const char **argv, * than nothing. */ prctl(PR_SET_PDEATHSIG, SIGTERM); -#endif +#endif /* defined(HAVE_SYS_PRCTL_H) && defined(__linux__) */ child_state = CHILD_STATE_DUPOUT; @@ -4536,7 +4542,7 @@ tor_spawn_background(const char *const filename, const char **argv, *process_handle_out = process_handle; return status; -#endif // _WIN32 +#endif /* defined(_WIN32) */ } /** Destroy all resources allocated by the process handle in @@ -4578,13 +4584,13 @@ tor_process_handle_destroy,(process_handle_t *process_handle, if (process_handle->stdin_pipe) CloseHandle(process_handle->stdin_pipe); -#else +#else /* !(defined(_WIN32)) */ close(process_handle->stdout_pipe); close(process_handle->stderr_pipe); close(process_handle->stdin_pipe); clear_waitpid_callback(process_handle->waitpid_cb); -#endif +#endif /* defined(_WIN32) */ memset(process_handle, 0x0f, sizeof(process_handle_t)); tor_free(process_handle); @@ -4637,7 +4643,7 @@ tor_get_exit_code(process_handle_t *process_handle, return PROCESS_EXIT_ERROR; } } -#else +#else /* !(defined(_WIN32)) */ int stat_loc; int retval; @@ -4672,7 +4678,7 @@ tor_get_exit_code(process_handle_t *process_handle, if (exit_code != NULL) *exit_code = WEXITSTATUS(stat_loc); -#endif // _WIN32 +#endif /* defined(_WIN32) */ return PROCESS_EXIT_EXITED; } @@ -4912,7 +4918,7 @@ tor_read_all_handle(HANDLE h, char *buf, size_t count, } return (ssize_t)numread; } -#else +#else /* !(defined(_WIN32)) */ /** Read from a handle <b>fd</b> into <b>buf</b>, up to <b>count</b> bytes. If * <b>process</b> is NULL, the function will return immediately if there is * nothing more to read. Otherwise data will be read until end of file, or @@ -4957,7 +4963,7 @@ tor_read_all_handle(int fd, char *buf, size_t count, log_debug(LD_GENERAL, "read() read %d bytes from handle", (int)numread); return (ssize_t)numread; } -#endif +#endif /* defined(_WIN32) */ /** Read from stdout of a process until the process exits. */ ssize_t @@ -4970,7 +4976,7 @@ tor_read_all_from_process_stdout(const process_handle_t *process_handle, #else return tor_read_all_handle(process_handle->stdout_pipe, buf, count, process_handle, NULL); -#endif +#endif /* defined(_WIN32) */ } /** Read from stdout of a process until the process exits. */ @@ -4984,7 +4990,7 @@ tor_read_all_from_process_stderr(const process_handle_t *process_handle, #else return tor_read_all_handle(process_handle->stderr_pipe, buf, count, process_handle, NULL); -#endif +#endif /* defined(_WIN32) */ } /** Split buf into lines, and add to smartlist. The buffer <b>buf</b> will be @@ -5173,7 +5179,7 @@ log_from_handle(HANDLE *pipe, int severity) return 0; } -#else +#else /* !(defined(_WIN32)) */ /** Return a smartlist containing lines outputted from * <b>fd</b>. Return NULL on error, and set @@ -5238,7 +5244,7 @@ log_from_pipe(int fd, int severity, const char *executable, /* We should never get here */ return -1; } -#endif +#endif /* defined(_WIN32) */ /** Reads from <b>fd</b> and stores input in <b>buf_out</b> making * sure it's below <b>count</b> bytes. @@ -5490,7 +5496,7 @@ tor_check_port_forwarding(const char *filename, status = tor_spawn_background(NULL, argv, NULL, &child_handle); #else status = tor_spawn_background(filename, argv, NULL, &child_handle); -#endif +#endif /* defined(_WIN32) */ tor_free_((void*)argv); argv=NULL; @@ -5516,7 +5522,7 @@ tor_check_port_forwarding(const char *filename, #else stderr_status = log_from_pipe(child_handle->stderr_pipe, LOG_INFO, filename, &retval); -#endif +#endif /* defined(_WIN32) */ if (handle_fw_helper_output(filename, child_handle) < 0) { log_warn(LD_GENERAL, "Failed to handle fw helper output."); stdout_status = -1; @@ -5541,13 +5547,13 @@ tor_check_port_forwarding(const char *filename, * between log_from_handle and tor_get_exit_code? */ retval = 1; } -#else +#else /* !(defined(_WIN32)) */ else if (1 == stdout_status || 1 == stderr_status) /* stdout or stderr was closed, the process probably * exited. It will be reaped by waitpid() in main.c */ /* TODO: Do something with the process return value */ retval = 1; -#endif +#endif /* defined(_WIN32) */ else /* Both are fine */ retval = 0; @@ -5618,7 +5624,7 @@ clamp_double_to_int64(double number) { int exponent; -#if (defined(__MINGW32__) || defined(__MINGW64__)) && GCC_VERSION >= 409 +#if defined(MINGW_ANY) && GCC_VERSION >= 409 /* Mingw's math.h uses gcc's __builtin_choose_expr() facility to declare isnan, isfinite, and signbit. But as implemented in at least some @@ -5627,7 +5633,7 @@ clamp_double_to_int64(double number) */ #define PROBLEMATIC_FLOAT_CONVERSION_WARNING DISABLE_GCC_WARNING(float-conversion) -#endif +#endif /* defined(MINGW_ANY) && GCC_VERSION >= 409 */ /* With clang 4.0 we apparently run into "double promotion" warnings here, @@ -5638,7 +5644,7 @@ DISABLE_GCC_WARNING(float-conversion) #define PROBLEMATIC_DOUBLE_PROMOTION_WARNING DISABLE_GCC_WARNING(double-promotion) #endif -#endif +#endif /* defined(__clang__) */ /* NaN is a special case that can't be used with the logic below. */ if (isnan(number)) { @@ -5685,7 +5691,7 @@ tor_htonll(uint64_t a) /* Little endian. The worst... */ return htonl((uint32_t)(a>>32)) | (((uint64_t)htonl((uint32_t)a))<<32); -#endif /* WORDS_BIGENDIAN */ +#endif /* defined(WORDS_BIGENDIAN) */ } /** Return a uint64_t value from <b>a</b> in host byte order. */ diff --git a/src/common/util.h b/src/common/util.h index 073fb82aed..6bc853da26 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -45,7 +45,7 @@ #else #define DMALLOC_PARAMS #define DMALLOC_ARGS -#endif +#endif /* defined(USE_DMALLOC) */ /* Memory management */ void *tor_malloc_(size_t size DMALLOC_PARAMS) ATTR_MALLOC; @@ -72,7 +72,7 @@ extern int dmalloc_free(const char *file, const int line, void *pnt, (p)=NULL; \ } \ STMT_END -#else +#else /* !(defined(USE_DMALLOC)) */ /** Release memory allocated by tor_malloc, tor_realloc, tor_strdup, etc. * Unlike the free() function, tor_free() will still work on NULL pointers, * and it sets the pointer value to NULL after freeing it. @@ -86,7 +86,7 @@ extern int dmalloc_free(const char *file, const int line, void *pnt, (p)=NULL; \ } \ STMT_END -#endif +#endif /* defined(USE_DMALLOC) */ #define tor_malloc(size) tor_malloc_(size DMALLOC_ARGS) #define tor_malloc_zero(size) tor_malloc_zero_(size DMALLOC_ARGS) @@ -261,7 +261,7 @@ int format_time_interval(char *out, size_t out_len, long interval); #else time_t approx_time(void); void update_approx_time(time_t now); -#endif +#endif /* defined(TIME_IS_FAST) */ /* Rate-limiter */ @@ -451,7 +451,7 @@ struct process_handle_t { HANDLE stdout_pipe; HANDLE stderr_pipe; PROCESS_INFORMATION pid; -#else +#else /* !(defined(_WIN32)) */ int stdin_pipe; int stdout_pipe; int stderr_pipe; @@ -462,9 +462,9 @@ struct process_handle_t { struct waitpid_callback_t *waitpid_cb; /** The exit status reported by waitpid. */ int waitpid_exit_status; -#endif // _WIN32 +#endif /* defined(_WIN32) */ }; -#endif +#endif /* defined(UTIL_PRIVATE) */ /* Return values of tor_get_exit_code() */ #define PROCESS_EXIT_RUNNING 1 @@ -480,7 +480,7 @@ ssize_t tor_read_all_handle(HANDLE h, char *buf, size_t count, ssize_t tor_read_all_handle(int fd, char *buf, size_t count, const process_handle_t *process, int *eof); -#endif +#endif /* defined(_WIN32) */ ssize_t tor_read_all_from_process_stdout( const process_handle_t *process_handle, char *buf, size_t count); ssize_t tor_read_all_from_process_stderr( @@ -502,7 +502,7 @@ tor_get_lines_from_handle,(HANDLE *handle, MOCK_DECL(struct smartlist_t *, tor_get_lines_from_handle,(int fd, enum stream_status *stream_status)); -#endif +#endif /* defined(_WIN32) */ int tor_terminate_process(process_handle_t *process_handle); @@ -539,13 +539,13 @@ STATIC int format_helper_exit_status(unsigned char child_state, leading minus) and newline (no null) */ #define HEX_ERRNO_SIZE (sizeof(char) * 2 + 1 + \ 1 + sizeof(int) * 2 + 1) -#endif +#endif /* !defined(_WIN32) */ -#endif +#endif /* defined(UTIL_PRIVATE) */ int size_mul_check(const size_t x, const size_t y); #define ARRAY_LENGTH(x) ((sizeof(x)) / sizeof(x[0])) -#endif +#endif /* !defined(TOR_UTIL_H) */ diff --git a/src/common/util_bug.c b/src/common/util_bug.c index cc1ac2ff84..126e843866 100644 --- a/src/common/util_bug.c +++ b/src/common/util_bug.c @@ -59,10 +59,10 @@ tor_set_failed_assertion_callback(void (*fn)(void)) { failed_assertion_cb = fn; } -#else +#else /* !(defined(TOR_UNIT_TESTS)) */ #define capturing_bugs() (0) #define add_captured_bug(s) do { } while (0) -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /** Helper for tor_assert: report the assertion failure. */ void diff --git a/src/common/util_bug.h b/src/common/util_bug.h index ce6565d92d..be549fde07 100644 --- a/src/common/util_bug.h +++ b/src/common/util_bug.h @@ -53,7 +53,7 @@ * security-critical properties. */ #error "Sorry; we don't support building with NDEBUG." -#endif +#endif /* defined(NDEBUG) */ /* Sometimes we don't want to use assertions during branch coverage tests; it * leads to tons of unreached branches which in reality are only assertions we @@ -70,7 +70,7 @@ tor_assertion_failed_(SHORT_FILE__, __LINE__, __func__, #expr); \ abort(); \ } STMT_END -#endif +#endif /* defined(TOR_UNIT_TESTS) && defined(DISABLE_ASSERTS_IN_UNIT_TESTS) */ #define tor_assert_unreached() tor_assert(0) @@ -92,7 +92,7 @@ extern int bug_macro_deadcode_dummy__; // We use this "deadcode_dummy__" trick to prevent coverity from // complaining about unreachable bug cases. #nodef BUG(x) ((x)?(__coverity_panic__(),1):(0+bug_macro_deadcode_dummy__)) -#endif +#endif /* defined(__COVERITY__) */ #if defined(__COVERITY__) || defined(__clang_analyzer__) // We're running with a static analysis tool: let's treat even nonfatal @@ -143,7 +143,7 @@ extern int bug_macro_deadcode_dummy__; (PREDICT_UNLIKELY(cond) ? \ (tor_bug_occurred_(SHORT_FILE__,__LINE__,__func__,"!("#cond")",0), 1) \ : 0) -#endif +#endif /* defined(ALL_BUGS_ARE_FATAL) || ... */ #ifdef __GNUC__ #define IF_BUG_ONCE__(cond,var) \ @@ -156,7 +156,7 @@ extern int bug_macro_deadcode_dummy__; "!("#cond")", 1); \ } \ PREDICT_UNLIKELY(bool_result); } )) -#else +#else /* !(defined(__GNUC__)) */ #define IF_BUG_ONCE__(cond,var) \ static int var = 0; \ if (PREDICT_UNLIKELY(cond) ? \ @@ -166,7 +166,7 @@ extern int bug_macro_deadcode_dummy__; "!("#cond")", 1), \ 1)) \ : 0) -#endif +#endif /* defined(__GNUC__) */ #define IF_BUG_ONCE_VARNAME_(a) \ warning_logged_on_ ## a ## __ #define IF_BUG_ONCE_VARNAME__(a) \ @@ -196,7 +196,7 @@ void tor_capture_bugs_(int n); void tor_end_capture_bugs_(void); const struct smartlist_t *tor_get_captured_bug_log_(void); void tor_set_failed_assertion_callback(void (*fn)(void)); -#endif +#endif /* defined(TOR_UNIT_TESTS) */ -#endif +#endif /* !defined(TOR_UTIL_BUG_H) */ diff --git a/src/common/util_format.h b/src/common/util_format.h index 4af8832bbe..0aefe3a44e 100644 --- a/src/common/util_format.h +++ b/src/common/util_format.h @@ -48,5 +48,5 @@ int hex_decode_digit(char c); void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen); int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen); -#endif +#endif /* !defined(TOR_UTIL_FORMAT_H) */ diff --git a/src/common/util_process.c b/src/common/util_process.c index 9e9679b099..c2826152e9 100644 --- a/src/common/util_process.c +++ b/src/common/util_process.c @@ -154,5 +154,5 @@ notify_pending_waitpid_callbacks(void) } } -#endif +#endif /* !defined(_WIN32) */ diff --git a/src/common/util_process.h b/src/common/util_process.h index c3a63498b5..c9aa771b77 100644 --- a/src/common/util_process.h +++ b/src/common/util_process.h @@ -20,7 +20,7 @@ waitpid_callback_t *set_waitpid_callback(pid_t pid, void (*fn)(int, void *), void *arg); void clear_waitpid_callback(waitpid_callback_t *ent); void notify_pending_waitpid_callbacks(void); -#endif +#endif /* !defined(_WIN32) */ -#endif +#endif /* !defined(TOR_UTIL_PROCESS_H) */ diff --git a/src/common/workqueue.h b/src/common/workqueue.h index d2508f5329..eb885e680d 100644 --- a/src/common/workqueue.h +++ b/src/common/workqueue.h @@ -59,5 +59,5 @@ replyqueue_t *replyqueue_new(uint32_t alertsocks_flags); tor_socket_t replyqueue_get_socket(replyqueue_t *rq); void replyqueue_process(replyqueue_t *queue); -#endif +#endif /* !defined(TOR_WORKQUEUE_H) */ diff --git a/src/ext/ht.h b/src/ext/ht.h index caa420e9b5..99da773faf 100644 --- a/src/ext/ht.h +++ b/src/ext/ht.h @@ -150,6 +150,8 @@ #define HT_CLEAR(name, head) name##_HT_CLEAR(head) #define HT_INIT(name, head) name##_HT_INIT(head) #define HT_REP_IS_BAD_(name, head) name##_HT_REP_IS_BAD_(head) +#define HT_FOREACH_FN(name, head, fn, data) \ + name##_HT_FOREACH_FN((head), (fn), (data)) /* Helper: */ static inline unsigned ht_improve_hash(unsigned h) diff --git a/src/or/addressmap.c b/src/or/addressmap.c index f278564e80..ebafc1cc00 100644 --- a/src/or/addressmap.c +++ b/src/or/addressmap.c @@ -814,7 +814,7 @@ parse_virtual_addr_network(const char *val, sa_family_t family, ipv6?"IPv6":""); return -1; } -#endif +#endif /* 0 */ if (bits > max_prefix_bits) { if (msg) @@ -1044,7 +1044,7 @@ addressmap_register_virtual_address(int type, char *new_address) safe_str_client(*addrp), safe_str_client(new_address)); } -#endif +#endif /* 0 */ return *addrp; } diff --git a/src/or/addressmap.h b/src/or/addressmap.h index 80f453b4c1..1544b76e10 100644 --- a/src/or/addressmap.h +++ b/src/or/addressmap.h @@ -59,7 +59,7 @@ typedef struct virtual_addr_conf_t { STATIC void get_random_virtual_addr(const virtual_addr_conf_t *conf, tor_addr_t *addr_out); -#endif +#endif /* defined(ADDRESSMAP_PRIVATE) */ -#endif +#endif /* !defined(TOR_ADDRESSMAP_H) */ diff --git a/src/or/bridges.c b/src/or/bridges.c index 461f86260f..1c748b4156 100644 --- a/src/or/bridges.c +++ b/src/or/bridges.c @@ -310,7 +310,7 @@ learned_router_identity(const tor_addr_t *addr, uint16_t port, memcpy(&bridge->ed25519_identity, ed_id, sizeof(*ed_id)); learned = 1; } -#endif +#endif /* 0 */ if (learned) { char *transport_info = NULL; const char *transport_name = @@ -455,8 +455,8 @@ bridge_add_from_config(bridge_line_t *bridge_line) b->fetch_status.schedule = DL_SCHED_BRIDGE; b->fetch_status.backoff = DL_SCHED_RANDOM_EXPONENTIAL; b->fetch_status.increment_on = DL_SCHED_INCREMENT_ATTEMPT; - /* This will fail if UseBridges is not set */ - download_status_reset(&b->fetch_status); + /* We can't reset the bridge's download status here, because UseBridges + * might be 0 now, and it might be changed to 1 much later. */ b->socks_args = bridge_line->socks_args; if (!bridge_list) bridge_list = smartlist_new(); @@ -625,6 +625,7 @@ fetch_bridge_descriptors(const or_options_t *options, time_t now) SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge) { + /* This resets the download status on first use */ if (!download_status_is_ready(&bridge->fetch_status, now, IMPOSSIBLE_TO_DOWNLOAD)) continue; /* don't bother, no need to retry yet */ @@ -835,7 +836,9 @@ learned_bridge_descriptor(routerinfo_t *ri, int from_cache) MOCK_IMPL(int, any_bridge_descriptors_known, (void)) { - tor_assert(get_options()->UseBridges); + if (BUG(!get_options()->UseBridges)) { + return 0; + } if (!bridge_list) return 0; diff --git a/src/or/bridges.h b/src/or/bridges.h index 19341818f4..263c7d51b2 100644 --- a/src/or/bridges.h +++ b/src/or/bridges.h @@ -66,5 +66,5 @@ MOCK_DECL(download_status_t *, get_bridge_dl_status_by_id, void bridges_free_all(void); -#endif +#endif /* !defined(TOR_BRIDGES_H) */ diff --git a/src/or/channel.c b/src/or/channel.c index 56eeccc2a7..faece55981 100644 --- a/src/or/channel.c +++ b/src/or/channel.c @@ -701,7 +701,7 @@ channel_remove_from_digest_map(channel_t *chan) return; } -#endif +#endif /* 0 */ /* Pull it out of its list, wherever that list is */ TOR_LIST_REMOVE(chan, next_with_same_id); @@ -1832,7 +1832,7 @@ cell_queue_entry_is_padding(cell_queue_entry_t *q) return 0; } -#endif +#endif /* 0 */ /** * Allocate a new cell queue entry for a fixed-size cell @@ -2603,8 +2603,8 @@ channel_flush_cells(channel_t *chan) * available. */ -int -channel_more_to_flush(channel_t *chan) +MOCK_IMPL(int, +channel_more_to_flush, (channel_t *chan)) { tor_assert(chan); @@ -2715,7 +2715,7 @@ channel_do_open_actions(channel_t *chan) router_set_status(chan->identity_digest, 1); } else { /* only report it to the geoip module if it's not a known router */ - if (!router_get_by_id_digest(chan->identity_digest)) { + if (!connection_or_digest_is_known_relay(chan->identity_digest)) { if (channel_get_addr_if_possible(chan, &remote_addr)) { char *transport_name = NULL; if (chan->get_transport_name(chan, &transport_name) < 0) @@ -4841,8 +4841,6 @@ channel_update_xmit_queue_size(channel_t *chan) U64_FORMAT ", new size is " U64_FORMAT, U64_PRINTF_ARG(adj), U64_PRINTF_ARG(chan->global_identifier), U64_PRINTF_ARG(estimated_total_queue_size)); - /* Tell the scheduler we're increasing the queue size */ - scheduler_adjust_queue_size(chan, 1, adj); } } else if (queued < chan->bytes_queued_for_xmit) { adj = chan->bytes_queued_for_xmit - queued; @@ -4865,8 +4863,6 @@ channel_update_xmit_queue_size(channel_t *chan) U64_FORMAT ", new size is " U64_FORMAT, U64_PRINTF_ARG(adj), U64_PRINTF_ARG(chan->global_identifier), U64_PRINTF_ARG(estimated_total_queue_size)); - /* Tell the scheduler we're decreasing the queue size */ - scheduler_adjust_queue_size(chan, -1, adj); } } } diff --git a/src/or/channel.h b/src/or/channel.h index 2d0ec39924..204b244293 100644 --- a/src/or/channel.h +++ b/src/or/channel.h @@ -487,7 +487,7 @@ STATIC void cell_queue_entry_free(cell_queue_entry_t *q, int handed_off); void channel_write_cell_generic_(channel_t *chan, const char *cell_type, void *cell, cell_queue_entry_t *q); -#endif +#endif /* defined(CHANNEL_PRIVATE_) */ /* Channel operations for subclasses and internal use only */ @@ -568,7 +568,7 @@ MOCK_DECL(ssize_t, channel_flush_some_cells, (channel_t *chan, ssize_t num_cells)); /* Query if data available on this channel */ -int channel_more_to_flush(channel_t *chan); +MOCK_DECL(int, channel_more_to_flush, (channel_t *chan)); /* Notify flushed outgoing for dirreq handling */ void channel_notify_flushed(channel_t *chan); @@ -580,7 +580,7 @@ void channel_do_open_actions(channel_t *chan); extern uint64_t estimated_total_queue_size; #endif -#endif +#endif /* defined(TOR_CHANNEL_INTERNAL_) */ /* Helper functions to perform operations on channels */ @@ -719,5 +719,5 @@ int packed_cell_is_destroy(channel_t *chan, /* Declare the handle helpers */ HANDLE_DECL(channel, channel_s,) -#endif +#endif /* !defined(TOR_CHANNEL_H) */ diff --git a/src/or/channelpadding.h b/src/or/channelpadding.h index a227e27d5b..58bf741d5c 100644 --- a/src/or/channelpadding.h +++ b/src/or/channelpadding.h @@ -41,5 +41,5 @@ int channelpadding_get_circuits_available_timeout(void); unsigned int channelpadding_get_channel_idle_timeout(const channel_t *, int); void channelpadding_new_consensus_params(networkstatus_t *ns); -#endif +#endif /* !defined(TOR_CHANNELPADDING_H) */ diff --git a/src/or/channeltls.c b/src/or/channeltls.c index 4ccd3b5fbf..7f68824482 100644 --- a/src/or/channeltls.c +++ b/src/or/channeltls.c @@ -1044,7 +1044,7 @@ channel_tls_time_process_cell(cell_t *cell, channel_tls_t *chan, int *time, *time += time_passed; } -#endif +#endif /* defined(KEEP_TIMING_STATS) */ /** * Handle an incoming cell on a channel_tls_t @@ -1072,9 +1072,9 @@ channel_tls_handle_cell(cell_t *cell, or_connection_t *conn) channel_tls_time_process_cell(cl, cn, & tp ## time , \ channel_tls_process_ ## tp ## _cell); \ } STMT_END -#else +#else /* !(defined(KEEP_TIMING_STATS)) */ #define PROCESS_CELL(tp, cl, cn) channel_tls_process_ ## tp ## _cell(cl, cn) -#endif +#endif /* defined(KEEP_TIMING_STATS) */ tor_assert(cell); tor_assert(conn); @@ -1204,7 +1204,7 @@ channel_tls_handle_var_cell(var_cell_t *var_cell, or_connection_t *conn) /* remember which second it is, for next time */ current_second = now; } -#endif +#endif /* defined(KEEP_TIMING_STATS) */ tor_assert(var_cell); tor_assert(conn); @@ -1579,7 +1579,7 @@ channel_tls_process_versions_cell(var_cell_t *cell, channel_tls_t *chan) connection_or_close_normally(chan->conn, 1); return; } -#endif +#endif /* defined(DISABLE_V3_LINKPROTO_SERVERSIDE) */ if (send_versions) { if (connection_or_send_versions(chan->conn, 1) < 0) { @@ -1680,6 +1680,8 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan) long apparent_skew = 0; tor_addr_t my_apparent_addr = TOR_ADDR_NULL; + int started_here = 0; + const char *identity_digest = NULL; tor_assert(cell); tor_assert(chan); @@ -1699,10 +1701,12 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan) } tor_assert(chan->conn->handshake_state && chan->conn->handshake_state->received_versions); + started_here = connection_or_nonopen_was_started_here(chan->conn); + identity_digest = chan->conn->identity_digest; if (chan->conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3) { tor_assert(chan->conn->link_proto >= 3); - if (chan->conn->handshake_state->started_here) { + if (started_here) { if (!(chan->conn->handshake_state->authenticated)) { log_fn(LOG_PROTOCOL_WARN, LD_OR, "Got a NETINFO cell from server, " @@ -1813,7 +1817,7 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan) "they will not consider this connection canonical. They " "think we are at %s, but we think its %s.", safe_str(descr), - safe_str(hex_str(chan->conn->identity_digest, DIGEST_LEN)), + safe_str(hex_str(identity_digest, DIGEST_LEN)), safe_str(tor_addr_is_null(&my_apparent_addr) ? "<none>" : fmt_and_decorate_addr(&my_apparent_addr)), safe_str(fmt_addr32(me->addr))); @@ -1823,7 +1827,8 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan) /** Warn when we get a netinfo skew with at least this value. */ #define NETINFO_NOTICE_SKEW 3600 if (labs(apparent_skew) > NETINFO_NOTICE_SKEW && - router_get_by_id_digest(chan->conn->identity_digest)) { + (started_here || + connection_or_digest_is_known_relay(chan->conn->identity_digest))) { int trusted = router_digest_is_trusted_dir(chan->conn->identity_digest); clock_skew_warning(TO_CONN(chan->conn), apparent_skew, trusted, LD_GENERAL, "NETINFO cell", "OR"); @@ -1857,8 +1862,7 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan) safe_str_client(chan->conn->base_.address), chan->conn->base_.port, (int)(chan->conn->link_proto), - hex_str(TLS_CHAN_TO_BASE(chan)->identity_digest, - DIGEST_LEN), + hex_str(identity_digest, DIGEST_LEN), tor_addr_is_null(&my_apparent_addr) ? "<none>" : fmt_and_decorate_addr(&my_apparent_addr)); } @@ -1929,7 +1933,7 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan) int n_certs, i; certs_cell_t *cc = NULL; - int send_netinfo = 0; + int send_netinfo = 0, started_here = 0; memset(x509_certs, 0, sizeof(x509_certs)); memset(ed_certs, 0, sizeof(ed_certs)); @@ -1947,6 +1951,11 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan) goto err; \ } while (0) + /* Can't use connection_or_nonopen_was_started_here(); its conn->tls + * check looks like it breaks + * test_link_handshake_recv_certs_ok_server(). */ + started_here = chan->conn->handshake_state->started_here; + if (chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V3) ERR("We're not doing a v3 handshake!"); if (chan->conn->link_proto < 3) @@ -2060,7 +2069,7 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan) /* Note that this warns more loudly about time and validity if we were * _trying_ to connect to an authority, not necessarily if we _did_ connect * to one. */ - if (chan->conn->handshake_state->started_here && + if (started_here && router_digest_is_trusted_dir(TLS_CHAN_TO_BASE(chan)->identity_digest)) severity = LOG_WARN; else @@ -2078,7 +2087,7 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan) if (!checked_rsa_id) ERR("Invalid certificate chain!"); - if (chan->conn->handshake_state->started_here) { + if (started_here) { /* No more information is needed. */ chan->conn->handshake_state->authenticated = 1; diff --git a/src/or/channeltls.h b/src/or/channeltls.h index 1f9a39d8a4..d9c4239c3a 100644 --- a/src/or/channeltls.h +++ b/src/or/channeltls.h @@ -26,7 +26,7 @@ struct channel_tls_s { or_connection_t *conn; }; -#endif /* TOR_CHANNEL_INTERNAL_ */ +#endif /* defined(TOR_CHANNEL_INTERNAL_) */ channel_t * channel_tls_connect(const tor_addr_t *addr, uint16_t port, const char *id_digest, @@ -69,7 +69,7 @@ STATIC void channel_tls_process_auth_challenge_cell(var_cell_t *cell, STATIC void channel_tls_common_init(channel_tls_t *tlschan); STATIC void channel_tls_process_authenticate_cell(var_cell_t *cell, channel_tls_t *tlschan); -#endif +#endif /* defined(CHANNELTLS_PRIVATE) */ -#endif +#endif /* !defined(TOR_CHANNELTLS_H) */ diff --git a/src/or/circpathbias.c b/src/or/circpathbias.c index 4c0bd9e455..f4bd5ea2fa 100644 --- a/src/or/circpathbias.c +++ b/src/or/circpathbias.c @@ -292,7 +292,7 @@ pathbias_is_new_circ_attempt(origin_circuit_t *circ) return circ->cpath && circ->cpath->next != circ->cpath && circ->cpath->next->state == CPATH_STATE_AWAITING_KEYS; -#else +#else /* !(defined(N2N_TAGGING_IS_POSSIBLE)) */ /* If tagging attacks are no longer possible, we probably want to * count bias from the first hop. However, one could argue that * timing-based tagging is still more useful than per-hop failure. @@ -300,7 +300,7 @@ pathbias_is_new_circ_attempt(origin_circuit_t *circ) */ return circ->cpath && circ->cpath->state == CPATH_STATE_AWAITING_KEYS; -#endif +#endif /* defined(N2N_TAGGING_IS_POSSIBLE) */ } /** diff --git a/src/or/circpathbias.h b/src/or/circpathbias.h index 2a4c316807..c9e572d2ae 100644 --- a/src/or/circpathbias.h +++ b/src/or/circpathbias.h @@ -25,5 +25,5 @@ void pathbias_mark_use_success(origin_circuit_t *circ); void pathbias_mark_use_rollback(origin_circuit_t *circ); const char *pathbias_state_to_string(path_state_t state); -#endif +#endif /* !defined(TOR_CIRCPATHBIAS_H) */ diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index e796ea2ed3..aa048f8c31 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -1566,7 +1566,7 @@ circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer, int reason) log_info(LD_CIRC, "finished"); return 0; -#endif +#endif /* 0 */ } /** Given a response payload and keys, initialize, then send a created @@ -2104,7 +2104,7 @@ pick_tor2web_rendezvous_node(router_crn_flags_t flags, return rp_node; } -#endif +#endif /* defined(ENABLE_TOR2WEB_MODE) || defined(TOR_UNIT_TESTS) */ /* Pick a Rendezvous Point for our HS circuits according to <b>flags</b>. */ static const node_t * @@ -2140,7 +2140,7 @@ pick_rendezvous_node(router_crn_flags_t flags) "Unable to find a random rendezvous point that is reachable via " "a direct connection, falling back to a 3-hop path."); } -#endif +#endif /* defined(ENABLE_TOR2WEB_MODE) */ return router_choose_random_node(NULL, options->ExcludeNodes, flags); } @@ -2430,7 +2430,7 @@ cpath_get_n_hops(crypt_path_t **head_ptr) return n_hops; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /** A helper function used by onion_extend_cpath(). Use <b>purpose</b> * and <b>state</b> and the cpath <b>head</b> (currently populated only diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index 62a6367ed2..b8a651e055 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -86,9 +86,9 @@ STATIC const node_t *pick_tor2web_rendezvous_node(router_crn_flags_t flags, const or_options_t *options); unsigned int cpath_get_n_hops(crypt_path_t **head_ptr); -#endif +#endif /* defined(ENABLE_TOR2WEB_MODE) || defined(TOR_UNIT_TESTS) */ -#endif +#endif /* defined(CIRCUITBUILD_PRIVATE) */ -#endif +#endif /* !defined(TOR_CIRCUITBUILD_H) */ diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index 5cc6252325..a0ff74190e 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -1434,7 +1434,7 @@ circuit_unlink_all_from_channel(channel_t *chan, int reason) smartlist_free(detached_2); } } -#endif +#endif /* defined(DEBUG_CIRCUIT_UNLINK_ALL) */ SMARTLIST_FOREACH_BEGIN(detached, circuit_t *, circ) { int mark = 0; diff --git a/src/or/circuitlist.h b/src/or/circuitlist.h index b882b2c6a8..5d0da15ca8 100644 --- a/src/or/circuitlist.h +++ b/src/or/circuitlist.h @@ -86,7 +86,7 @@ STATIC size_t n_cells_in_circ_queues(const circuit_t *c); STATIC uint32_t circuit_max_queued_data_age(const circuit_t *c, uint32_t now); STATIC uint32_t circuit_max_queued_cell_age(const circuit_t *c, uint32_t now); STATIC uint32_t circuit_max_queued_item_age(const circuit_t *c, uint32_t now); -#endif +#endif /* defined(CIRCUITLIST_PRIVATE) */ -#endif +#endif /* !defined(TOR_CIRCUITLIST_H) */ diff --git a/src/or/circuitmux.c b/src/or/circuitmux.c index b52606d12f..f3b8aecb1b 100644 --- a/src/or/circuitmux.c +++ b/src/or/circuitmux.c @@ -185,7 +185,7 @@ struct chanid_circid_muxinfo_t { circuitmux_assert_okay(cmux) #else #define circuitmux_assert_okay_paranoid(cmux) -#endif +#endif /* defined(CMUX_PARANOIA) */ /* * Static function declarations diff --git a/src/or/circuitmux.h b/src/or/circuitmux.h index 42a46aaa47..3e7496ea1c 100644 --- a/src/or/circuitmux.h +++ b/src/or/circuitmux.h @@ -156,5 +156,5 @@ void circuitmux_mark_destroyed_circids_usable(circuitmux_t *cmux, MOCK_DECL(int, circuitmux_compare_muxes, (circuitmux_t *cmux_1, circuitmux_t *cmux_2)); -#endif /* TOR_CIRCUITMUX_H */ +#endif /* !defined(TOR_CIRCUITMUX_H) */ diff --git a/src/or/circuitmux_ewma.h b/src/or/circuitmux_ewma.h index 1f04408789..8f4e57865e 100644 --- a/src/or/circuitmux_ewma.h +++ b/src/or/circuitmux_ewma.h @@ -20,5 +20,5 @@ unsigned int cell_ewma_get_tick(void); void cell_ewma_set_scale_factor(const or_options_t *options, const networkstatus_t *consensus); -#endif /* TOR_CIRCUITMUX_EWMA_H */ +#endif /* !defined(TOR_CIRCUITMUX_EWMA_H) */ diff --git a/src/or/circuitstats.c b/src/or/circuitstats.c index 963892c9d1..ad0630e27e 100644 --- a/src/or/circuitstats.c +++ b/src/or/circuitstats.c @@ -60,7 +60,7 @@ static circuit_build_times_t circ_times; static int unit_tests = 0; #else #define unit_tests 0 -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /** Return a pointer to the data structure describing our current circuit * build time history and computations. */ @@ -148,7 +148,7 @@ circuit_build_times_disabled_(const or_options_t *options, "Consensus=%d, Config=%d, AuthDir=%d, StateFile=%d", consensus_disabled, config_disabled, dirauth_disabled, state_disabled); -#endif +#endif /* 0 */ return 1; } else { #if 0 @@ -157,7 +157,7 @@ circuit_build_times_disabled_(const or_options_t *options, "Consensus=%d, Config=%d, AuthDir=%d, StateFile=%d", consensus_disabled, config_disabled, dirauth_disabled, state_disabled); -#endif +#endif /* 0 */ return 0; } } @@ -608,7 +608,7 @@ circuit_build_times_rewind_history(circuit_build_times_t *cbt, int n) "Rewound history by %d places. Current index: %d. " "Total: %d", n, cbt->build_times_idx, cbt->total_build_times); } -#endif +#endif /* 0 */ /** * Add a new build time value <b>time</b> to the set of build times. Time @@ -676,7 +676,7 @@ circuit_build_times_min(circuit_build_times_t *cbt) } return min_build_time; } -#endif +#endif /* 0 */ /** * Calculate and return a histogram for the set of build times. @@ -1165,7 +1165,7 @@ circuit_build_times_cdf(circuit_build_times_t *cbt, double x) tor_assert(0 <= ret && ret <= 1.0); return ret; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ #ifdef TOR_UNIT_TESTS /** @@ -1200,7 +1200,7 @@ circuit_build_times_generate_sample(circuit_build_times_t *cbt, tor_assert(ret > 0); return ret; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ #ifdef TOR_UNIT_TESTS /** @@ -1223,7 +1223,7 @@ circuit_build_times_initial_alpha(circuit_build_times_t *cbt, (tor_mathlog(cbt->Xm)-tor_mathlog(timeout_ms)); tor_assert(cbt->alpha > 0); } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /** * Returns true if we need circuits to be built @@ -1682,7 +1682,7 @@ circuitbuild_running_unit_tests(void) { unit_tests = 1; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ void circuit_build_times_update_last_circ(circuit_build_times_t *cbt) diff --git a/src/or/circuitstats.h b/src/or/circuitstats.h index 8a1dec4bfd..92dc6405ba 100644 --- a/src/or/circuitstats.h +++ b/src/or/circuitstats.h @@ -54,7 +54,7 @@ STATIC void circuit_build_times_reset(circuit_build_times_t *cbt); /* Network liveness functions */ STATIC int circuit_build_times_network_check_changed( circuit_build_times_t *cbt); -#endif +#endif /* defined(CIRCUITSTATS_PRIVATE) */ #ifdef TOR_UNIT_TESTS build_time_t circuit_build_times_generate_sample(circuit_build_times_t *cbt, @@ -63,7 +63,7 @@ double circuit_build_times_cdf(circuit_build_times_t *cbt, double x); void circuit_build_times_initial_alpha(circuit_build_times_t *cbt, double quantile, double time_ms); void circuitbuild_running_unit_tests(void); -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /* Network liveness functions */ void circuit_build_times_network_is_live(circuit_build_times_t *cbt); @@ -95,7 +95,7 @@ struct circuit_build_times_s { /** How long we wait before actually closing the circuit. */ double close_ms; }; -#endif +#endif /* defined(CIRCUITSTATS_PRIVATE) */ -#endif +#endif /* !defined(TOR_CIRCUITSTATS_H) */ diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 7545dea290..8ffb506043 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -410,7 +410,7 @@ circuit_conforms_to_options(const origin_circuit_t *circ, return 1; } -#endif +#endif /* 0 */ /** Close all circuits that start at us, aren't open, and were born * at least CircuitBuildTimeout seconds ago. @@ -634,7 +634,7 @@ circuit_expire_building(void) victim->n_circ_id, (int)(now - victim->timestamp_dirty)); } -#endif +#endif /* 0 */ /* if circ is !open, or if it's open but purpose is a non-finished * intro or rend, then mark it for close */ @@ -1339,7 +1339,7 @@ circuit_expire_old_circs_as_needed(time_t now) log_fn(LOG_INFO,"Creating a new testing circuit."); circuit_launch(CIRCUIT_PURPOSE_C_GENERAL, 0); } -#endif +#endif /* 0 */ } } @@ -2282,7 +2282,7 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn, new_circ_purpose == CIRCUIT_PURPOSE_C_INTRODUCING)) { want_onehop = 1; } -#endif +#endif /* defined(ENABLE_TOR2WEB_MODE) */ /* Determine what kind of a circuit to launch, and actually launch it. */ { diff --git a/src/or/circuituse.h b/src/or/circuituse.h index 6c0bcbb357..2b0f983f1a 100644 --- a/src/or/circuituse.h +++ b/src/or/circuituse.h @@ -82,7 +82,7 @@ STATIC int needs_hs_client_circuits(time_t now, STATIC int needs_circuits_for_build(int num); -#endif +#endif /* defined(TOR_UNIT_TESTS) */ -#endif +#endif /* !defined(TOR_CIRCUITUSE_H) */ diff --git a/src/or/command.c b/src/or/command.c index 2c82984901..56134659c5 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -128,7 +128,7 @@ command_time_process_cell(cell_t *cell, channel_t *chan, int *time, } *time += time_passed; } -#endif +#endif /* defined(KEEP_TIMING_STATS) */ /** Process a <b>cell</b> that was just received on <b>chan</b>. Keep internal * statistics about how many of each cell we've processed so far @@ -165,7 +165,7 @@ command_process_cell(channel_t *chan, cell_t *cell) /* remember which second it is, for next time */ current_second = now; } -#endif +#endif /* defined(KEEP_TIMING_STATS) */ #ifdef KEEP_TIMING_STATS #define PROCESS_CELL(tp, cl, cn) STMT_BEGIN { \ @@ -173,9 +173,9 @@ command_process_cell(channel_t *chan, cell_t *cell) command_time_process_cell(cl, cn, & tp ## time , \ command_process_ ## tp ## _cell); \ } STMT_END -#else +#else /* !(defined(KEEP_TIMING_STATS)) */ #define PROCESS_CELL(tp, cl, cn) command_process_ ## tp ## _cell(cl, cn) -#endif +#endif /* defined(KEEP_TIMING_STATS) */ switch (cell->command) { case CELL_CREATE: diff --git a/src/or/command.h b/src/or/command.h index 5079d42e75..c0d1996cbb 100644 --- a/src/or/command.h +++ b/src/or/command.h @@ -27,5 +27,5 @@ extern uint64_t stats_n_created_cells_processed; extern uint64_t stats_n_relay_cells_processed; extern uint64_t stats_n_destroy_cells_processed; -#endif +#endif /* !defined(TOR_COMMAND_H) */ diff --git a/src/or/config.c b/src/or/config.c index 76461d75bf..6badb4e68a 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -114,9 +114,9 @@ * Coverity. Here's a kludge to unconfuse it. */ # define __INCLUDE_LEVEL__ 2 -# endif +#endif /* defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) */ #include <systemd/sd-daemon.h> -#endif +#endif /* defined(HAVE_SYSTEMD) */ /* Prefix used to indicate a Unix socket in a FooPort configuration. */ static const char unix_socket_prefix[] = "unix:"; @@ -208,7 +208,7 @@ static config_var_t option_vars_[] = { VAR("AccountingRule", STRING, AccountingRule_option, "max"), V(AccountingStart, STRING, NULL), V(Address, STRING, NULL), - V(AllowDotExit, BOOL, "0"), + OBSOLETE("AllowDotExit"), OBSOLETE("AllowInvalidNodes"), V(AllowNonRFC953Hostnames, BOOL, "0"), OBSOLETE("AllowSingleHopCircuits"), @@ -345,7 +345,7 @@ static config_var_t option_vars_[] = { SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "geoip"), V(GeoIPv6File, FILENAME, SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "geoip6"), -#endif +#endif /* defined(_WIN32) */ OBSOLETE("Group"), V(GuardLifetime, INTERVAL, "0 minutes"), V(HardwareAccel, BOOL, "0"), @@ -488,9 +488,12 @@ static config_var_t option_vars_[] = { V(ServerDNSSearchDomains, BOOL, "0"), V(ServerDNSTestAddresses, CSV, "www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"), - V(SchedulerLowWaterMark__, MEMUNIT, "100 MB"), - V(SchedulerHighWaterMark__, MEMUNIT, "101 MB"), - V(SchedulerMaxFlushCells__, UINT, "1000"), + OBSOLETE("SchedulerLowWaterMark__"), + OBSOLETE("SchedulerHighWaterMark__"), + OBSOLETE("SchedulerMaxFlushCells__"), + V(KISTSchedRunInterval, MSEC_INTERVAL, "0 msec"), + V(KISTSockBufSizeFactor, DOUBLE, "1.0"), + V(Schedulers, CSV, "KIST,KISTLite,Vanilla"), V(ShutdownWaitLength, INTERVAL, "30 seconds"), OBSOLETE("SocksListenAddress"), V(SocksPolicy, LINELIST, NULL), @@ -681,11 +684,6 @@ static const config_var_t testing_tor_network_defaults[] = { #undef OBSOLETE static const config_deprecation_t option_deprecation_notes_[] = { - /* Deprecated since 0.2.9.2-alpha... */ - { "AllowDotExit", "Unrestricted use of the .exit notation can be used for " - "a wide variety of application-level attacks." }, - /* End of options deprecated since 0.2.9.2-alpha. */ - /* Deprecated since 0.3.2.0-alpha. */ { "HTTPProxy", "It only applies to direct unencrypted HTTP connections " "to your directory server, which your Tor probably wasn't using." }, @@ -918,6 +916,10 @@ or_options_free(or_options_t *options) rs, routerset_free(rs)); smartlist_free(options->NodeFamilySets); } + if (options->SchedulerTypes_) { + SMARTLIST_FOREACH(options->SchedulerTypes_, int *, i, tor_free(i)); + smartlist_free(options->SchedulerTypes_); + } tor_free(options->BridgePassword_AuthDigest_); tor_free(options->command_arg); tor_free(options->master_key_fname); @@ -1248,13 +1250,13 @@ options_act_reversible(const or_options_t *old_options, char **msg) "on this OS/with this build."); goto rollback; } -#else +#else /* !(!defined(HAVE_SYS_UN_H)) */ if (options->ControlSocketsGroupWritable && !options->ControlSocket) { *msg = tor_strdup("Setting ControlSocketGroupWritable without setting" "a ControlSocket makes no sense."); goto rollback; } -#endif +#endif /* !defined(HAVE_SYS_UN_H) */ if (running_tor) { int n_ports=0; @@ -1331,7 +1333,7 @@ options_act_reversible(const or_options_t *old_options, char **msg) goto rollback; } } -#endif +#endif /* defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H) */ /* Attempt to lock all current and future memory with mlockall() only once */ if (options->DisableAllSwap) { @@ -1383,7 +1385,7 @@ options_act_reversible(const or_options_t *old_options, char **msg) options->DataDirectory, strerror(errno)); } } -#endif +#endif /* !defined(_WIN32) */ /* Bail out at this point if we're not going to be a client or server: * we don't run Tor itself. */ @@ -1665,7 +1667,7 @@ options_act(const or_options_t *old_options) return -1; } /* LCOV_EXCL_STOP */ -#else +#else /* !(defined(ENABLE_TOR2WEB_MODE)) */ if (options->Tor2webMode) { log_err(LD_CONFIG, "This copy of Tor was not compiled to run in " "'tor2web mode'. It cannot be run with the Tor2webMode torrc " @@ -1673,7 +1675,7 @@ options_act(const or_options_t *old_options) "--enable-tor2web-mode option."); return -1; } -#endif +#endif /* defined(ENABLE_TOR2WEB_MODE) */ /* If we are a bridge with a pluggable transport proxy but no Extended ORPort, inform the user that they are missing out. */ @@ -1828,11 +1830,9 @@ options_act(const or_options_t *old_options) return -1; } - /* Set up scheduler thresholds */ - scheduler_set_watermarks((uint32_t)options->SchedulerLowWaterMark__, - (uint32_t)options->SchedulerHighWaterMark__, - (options->SchedulerMaxFlushCells__ > 0) ? - options->SchedulerMaxFlushCells__ : 1000); + /* Inform the scheduler subsystem that a configuration changed happened. It + * might be a change of scheduler or parameter. */ + scheduler_conf_changed(); /* Set up accounting */ if (accounting_parse_options(options, 0)<0) { @@ -2868,7 +2868,7 @@ options_validate_cb(void *old_options, void *options, void *default_options, #else #define COMPLAIN(args, ...) \ STMT_BEGIN log_warn(LD_CONFIG, args, ##__VA_ARGS__); STMT_END -#endif +#endif /* defined(__GNUC__) && __GNUC__ <= 3 */ /** Log a warning message iff <b>filepath</b> is not absolute. * Warning message must contain option name <b>option</b> and @@ -2928,6 +2928,61 @@ warn_about_relative_paths(or_options_t *options) return n != 0; } +/* Validate options related to the scheduler. From the Schedulers list, the + * SchedulerTypes_ list is created with int values so once we select the + * scheduler, which can happen anytime at runtime, we don't have to parse + * strings and thus be quick. + * + * Return 0 on success else -1 and msg is set with an error message. */ +static int +options_validate_scheduler(or_options_t *options, char **msg) +{ + tor_assert(options); + tor_assert(msg); + + if (!options->Schedulers || smartlist_len(options->Schedulers) == 0) { + REJECT("Empty Schedulers list. Either remove the option so the defaults " + "can be used or set at least one value."); + } + /* Ok, we do have scheduler types, validate them. */ + options->SchedulerTypes_ = smartlist_new(); + SMARTLIST_FOREACH_BEGIN(options->Schedulers, const char *, type) { + int *sched_type; + if (!strcasecmp("KISTLite", type)) { + sched_type = tor_malloc_zero(sizeof(int)); + *sched_type = SCHEDULER_KIST_LITE; + smartlist_add(options->SchedulerTypes_, sched_type); + } else if (!strcasecmp("KIST", type)) { + sched_type = tor_malloc_zero(sizeof(int)); + *sched_type = SCHEDULER_KIST; + smartlist_add(options->SchedulerTypes_, sched_type); + } else if (!strcasecmp("Vanilla", type)) { + sched_type = tor_malloc_zero(sizeof(int)); + *sched_type = SCHEDULER_VANILLA; + smartlist_add(options->SchedulerTypes_, sched_type); + } else { + tor_asprintf(msg, "Unknown type %s in option Schedulers. " + "Possible values are KIST, KISTLite and Vanilla.", + escaped(type)); + return -1; + } + } SMARTLIST_FOREACH_END(type); + + if (options->KISTSockBufSizeFactor < 0) { + REJECT("KISTSockBufSizeFactor must be at least 0"); + } + + /* Don't need to validate that the Interval is less than anything because + * zero is valid and all negative values are valid. */ + if (options->KISTSchedRunInterval > KIST_SCHED_RUN_INTERVAL_MAX) { + tor_asprintf(msg, "KISTSchedRunInterval must not be more than %d (ms)", + KIST_SCHED_RUN_INTERVAL_MAX); + return -1; + } + + return 0; +} + /* Validate options related to single onion services. * Modifies some options that are incompatible with single onion services. * On failure returns -1, and sets *msg to an error string. @@ -3116,7 +3171,7 @@ options_validate(or_options_t *old_options, or_options_t *options, "and OS X/Darwin-specific feature."); #else options->TransProxyType_parsed = TPT_PF_DIVERT; -#endif +#endif /* !defined(OpenBSD) && !defined( DARWIN ) */ } else if (!strcasecmp(options->TransProxyType, "tproxy")) { #if !defined(__linux__) REJECT("TPROXY is a Linux-specific feature."); @@ -3130,7 +3185,7 @@ options_validate(or_options_t *old_options, or_options_t *options, "and OS X/Darwin-specific feature."); #else options->TransProxyType_parsed = TPT_IPFW; -#endif +#endif /* !defined(KERNEL_MAY_SUPPORT_IPFW) */ } else { REJECT("Unrecognized value for TransProxyType"); } @@ -3140,10 +3195,10 @@ options_validate(or_options_t *old_options, or_options_t *options, REJECT("Cannot use TransProxyType without any valid TransPort."); } } -#else +#else /* !(defined(USE_TRANSPARENT)) */ if (options->TransPort_set) REJECT("TransPort is disabled in this build."); -#endif +#endif /* defined(USE_TRANSPARENT) */ if (options->TokenBucketRefillInterval <= 0 || options->TokenBucketRefillInterval > 1000) { @@ -3156,17 +3211,6 @@ options_validate(or_options_t *old_options, or_options_t *options, routerset_union(options->ExcludeExitNodesUnion_,options->ExcludeNodes); } - if (options->SchedulerLowWaterMark__ == 0 || - options->SchedulerLowWaterMark__ > UINT32_MAX) { - log_warn(LD_GENERAL, "Bad SchedulerLowWaterMark__ option"); - return -1; - } else if (options->SchedulerHighWaterMark__ <= - options->SchedulerLowWaterMark__ || - options->SchedulerHighWaterMark__ > UINT32_MAX) { - log_warn(LD_GENERAL, "Bad SchedulerHighWaterMark option"); - return -1; - } - if (options->NodeFamilies) { options->NodeFamilySets = smartlist_new(); for (cl = options->NodeFamilies; cl; cl = cl->next) { @@ -3475,7 +3519,7 @@ options_validate(or_options_t *old_options, or_options_t *options, "Tor2WebMode is enabled; disabling UseEntryGuards."); options->UseEntryGuards = 0; } -#endif +#endif /* defined(ENABLE_TOR2WEB_MODE) */ if (options->Tor2webRendezvousPoints && !options->Tor2webMode) { REJECT("Tor2webRendezvousPoints cannot be set without Tor2webMode."); @@ -4285,6 +4329,10 @@ options_validate(or_options_t *old_options, or_options_t *options, REJECT("BridgeRelay is 1, ORPort is not set. This is an invalid " "combination."); + if (options_validate_scheduler(options, msg) < 0) { + return -1; + } + return 0; } @@ -4319,7 +4367,7 @@ compute_real_max_mem_in_queues(const uint64_t val, int log_guess) #else /* (presumably) 32-bit system. Let's hope for 1 GB. */ result = ONE_GIGABYTE; -#endif +#endif /* SIZEOF_VOID_P >= 8 */ } else { /* We detected it, so let's pick 3/4 of the total RAM as our limit. */ const uint64_t avail = (ram / 4) * 3; @@ -4652,7 +4700,7 @@ get_windows_conf_root(void) path[sizeof(path)-1] = '\0'; #else strlcpy(path,tpath,sizeof(path)); -#endif +#endif /* defined(UNICODE) */ /* Now we need to free the memory that the path-idl was stored in. In * typical Windows fashion, we can't just call 'free()' on it. */ @@ -4668,7 +4716,7 @@ get_windows_conf_root(void) is_set = 1; return path; } -#endif +#endif /* defined(_WIN32) */ /** Return the default location for our torrc file (if <b>defaults_file</b> is * false), or for the torrc-defaults file (if <b>defaults_file</b> is true). */ @@ -4692,7 +4740,7 @@ get_default_conf_file(int defaults_file) } #else return defaults_file ? CONFDIR "/torrc-defaults" : CONFDIR "/torrc"; -#endif +#endif /* defined(DISABLE_SYSTEM_TORRC) || ... */ } /** Verify whether lst is a list of strings containing valid-looking @@ -4843,9 +4891,9 @@ find_torrc_filename(config_line_t *cmd_arg, } else { fname = dflt ? tor_strdup(dflt) : NULL; } -#else +#else /* !(!defined(_WIN32)) */ fname = dflt ? tor_strdup(dflt) : NULL; -#endif +#endif /* !defined(_WIN32) */ } } return fname; @@ -5476,7 +5524,7 @@ options_init_logs(const or_options_t *old_options, or_options_t *options, } #else log_warn(LD_CONFIG, "Syslog is not supported on this system. Sorry."); -#endif +#endif /* defined(HAVE_SYSLOG_H) */ goto cleanup; } @@ -6689,7 +6737,7 @@ parse_port_config(smartlist_t *out, } else if (!strcasecmp(elt, "AllAddrs")) { all_addrs = 1; -#endif +#endif /* 0 */ } else if (!strcasecmp(elt, "IPv4Only")) { bind_ipv4_only = 1; } else if (!strcasecmp(elt, "IPv6Only")) { @@ -7472,7 +7520,7 @@ normalize_data_directory(or_options_t *options) strlcpy(p,get_windows_conf_root(),MAX_PATH); options->DataDirectory = p; return 0; -#else +#else /* !(defined(_WIN32)) */ const char *d = options->DataDirectory; if (!d) d = "~/.tor"; @@ -7498,7 +7546,7 @@ normalize_data_directory(or_options_t *options) options->DataDirectory = fn; } return 0; -#endif +#endif /* defined(_WIN32) */ } /** Check and normalize the value of options->DataDirectory; return 0 if it @@ -8029,10 +8077,10 @@ config_load_geoip_file_(sa_family_t family, } geoip_load_file(family, fname); tor_free(free_fname); -#else +#else /* !(defined(_WIN32)) */ (void)default_fname; geoip_load_file(family, fname); -#endif +#endif /* defined(_WIN32) */ } /** Load geoip files for IPv4 and IPv6 if <a>options</a> and @@ -8107,9 +8155,9 @@ init_cookie_authentication(const char *fname, const char *header, log_warn(LD_FS,"Unable to make %s group-readable.", escaped(fname)); } } -#else +#else /* !(!defined(_WIN32)) */ (void) group_readable; -#endif +#endif /* !defined(_WIN32) */ /* Success! */ log_info(LD_GENERAL, "Generated auth cookie file in '%s'.", escaped(fname)); diff --git a/src/or/config.h b/src/or/config.h index 3cfa7c4e5b..f69a3c483f 100644 --- a/src/or/config.h +++ b/src/or/config.h @@ -202,7 +202,7 @@ STATIC int parse_port_config(smartlist_t *out, const char *defaultaddr, int defaultport, const unsigned flags); -#endif +#endif /* defined(CONFIG_PRIVATE) */ -#endif +#endif /* !defined(TOR_CONFIG_H) */ diff --git a/src/or/confparse.h b/src/or/confparse.h index 9c4205d07c..9eb46fab03 100644 --- a/src/or/confparse.h +++ b/src/or/confparse.h @@ -129,5 +129,5 @@ const char *config_expand_abbrev(const config_format_t *fmt, int command_line, int warn_obsolete); void warn_deprecated_option(const char *what, const char *why); -#endif +#endif /* !defined(TOR_CONFPARSE_H) */ diff --git a/src/or/connection.c b/src/or/connection.c index ac26d43fff..dd5cb3480d 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -704,7 +704,7 @@ connection_free,(connection_t *conn)) connection_ap_warn_and_unmark_if_pending_circ(TO_ENTRY_CONN(conn), "connection_free"); } -#endif +#endif /* 1 */ connection_unregister_events(conn); connection_free_(conn); } @@ -928,7 +928,7 @@ create_unix_sockaddr(const char *listenaddress, char **readable_address, *len_out = sizeof(struct sockaddr_un); return sockaddr; } -#else +#else /* !(defined(HAVE_SYS_UN_H) || defined(RUNNING_DOXYGEN)) */ static struct sockaddr * create_unix_sockaddr(const char *listenaddress, char **readable_address, socklen_t *len_out) @@ -941,7 +941,7 @@ create_unix_sockaddr(const char *listenaddress, char **readable_address, tor_fragile_assert(); return NULL; } -#endif /* HAVE_SYS_UN_H */ +#endif /* defined(HAVE_SYS_UN_H) || defined(RUNNING_DOXYGEN) */ /** Warn that an accept or a connect has failed because we're running out of * TCP sockets we can use on current system. Rate-limit these warnings so @@ -1056,7 +1056,7 @@ check_location_for_unix_socket(const or_options_t *options, const char *path, tor_free(p); return r; } -#endif +#endif /* defined(HAVE_SYS_UN_H) */ /** Tell the TCP stack that it shouldn't wait for a long time after * <b>sock</b> has closed before reusing its port. Return 0 on success, @@ -1079,7 +1079,7 @@ make_socket_reuseable(tor_socket_t sock) return -1; } return 0; -#endif +#endif /* defined(_WIN32) */ } #ifdef _WIN32 @@ -1100,12 +1100,12 @@ make_win32_socket_exclusive(tor_socket_t sock) return -1; } return 0; -#else +#else /* !(defined(SO_EXCLUSIVEADDRUSE)) */ (void) sock; return 0; -#endif +#endif /* defined(SO_EXCLUSIVEADDRUSE) */ } -#endif +#endif /* defined(_WIN32) */ /** Max backlog to pass to listen. We start at */ static int listen_limit = INT_MAX; @@ -1195,7 +1195,7 @@ connection_listener_new(const struct sockaddr *listensockaddr, conn_type_to_string(type), tor_socket_strerror(errno)); } -#endif +#endif /* defined(_WIN32) */ #if defined(USE_TRANSPARENT) && defined(IP_TRANSPARENT) if (options->TransProxyType_parsed == TPT_TPROXY && @@ -1212,7 +1212,7 @@ connection_listener_new(const struct sockaddr *listensockaddr, tor_socket_strerror(e), extra); } } -#endif +#endif /* defined(USE_TRANSPARENT) && defined(IP_TRANSPARENT) */ #ifdef IPV6_V6ONLY if (listensockaddr->sa_family == AF_INET6) { @@ -1227,7 +1227,7 @@ connection_listener_new(const struct sockaddr *listensockaddr, /* Keep going; probably not harmful. */ } } -#endif +#endif /* defined(IPV6_V6ONLY) */ if (bind(s,listensockaddr,socklen) < 0) { const char *helpfulhint = ""; @@ -1330,7 +1330,7 @@ connection_listener_new(const struct sockaddr *listensockaddr, goto err; } } -#endif +#endif /* defined(HAVE_PWD_H) */ { unsigned mode; @@ -1361,7 +1361,7 @@ connection_listener_new(const struct sockaddr *listensockaddr, tor_socket_strerror(tor_socket_errno(s))); goto err; } -#endif /* HAVE_SYS_UN_H */ +#endif /* defined(HAVE_SYS_UN_H) */ } else { log_err(LD_BUG, "Got unexpected address family %d.", listensockaddr->sa_family); @@ -2626,7 +2626,7 @@ retry_listener_ports(smartlist_t *old_conns, if (port->is_unix_addr && !geteuid() && (options->User) && strcmp(options->User, "root")) continue; -#endif +#endif /* !defined(_WIN32) */ if (port->is_unix_addr) { listensockaddr = (struct sockaddr *) @@ -5221,7 +5221,7 @@ clock_skew_warning(const connection_t *conn, long apparent_skew, int trusted, const char *source) { char dbuf[64]; - char *ext_source = NULL; + char *ext_source = NULL, *warn = NULL; format_time_interval(dbuf, sizeof(dbuf), apparent_skew); if (conn) tor_asprintf(&ext_source, "%s:%s:%d", source, conn->address, conn->port); @@ -5235,9 +5235,14 @@ clock_skew_warning(const connection_t *conn, long apparent_skew, int trusted, apparent_skew > 0 ? "ahead" : "behind", dbuf, apparent_skew > 0 ? "behind" : "ahead", (!conn || trusted) ? "" : ", or they are sending us the wrong time"); - if (trusted) + if (trusted) { control_event_general_status(LOG_WARN, "CLOCK_SKEW SKEW=%ld SOURCE=%s", apparent_skew, ext_source); + tor_asprintf(&warn, "Clock skew %ld in %s from %s", apparent_skew, + received, source); + control_event_bootstrap_problem(warn, "CLOCK_SKEW", conn, 1); + } + tor_free(warn); tor_free(ext_source); } diff --git a/src/or/connection.h b/src/or/connection.h index 5b51bb9fae..4a5bd6971b 100644 --- a/src/or/connection.h +++ b/src/or/connection.h @@ -286,7 +286,7 @@ MOCK_DECL(STATIC int,connection_connect_sockaddr, MOCK_DECL(STATIC void, kill_conn_list_for_oos, (smartlist_t *conns)); MOCK_DECL(STATIC smartlist_t *, pick_oos_victims, (int n)); -#endif +#endif /* defined(CONNECTION_PRIVATE) */ -#endif +#endif /* !defined(TOR_CONNECTION_H) */ diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index d1b8abda82..e413e5bc36 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -115,7 +115,7 @@ #define TRANS_NETFILTER #define TRANS_NETFILTER_IPV6 #endif -#endif +#endif /* defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H) */ #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H) #include <net/if.h> @@ -661,7 +661,7 @@ connection_ap_about_to_close(entry_connection_t *entry_conn) connection_ap_warn_and_unmark_if_pending_circ(entry_conn, "about_to_close"); } -#endif +#endif /* 1 */ control_event_stream_bandwidth(edge_conn); control_event_stream_status(entry_conn, STREAM_EVENT_CLOSED, @@ -871,9 +871,9 @@ connection_ap_rescan_and_attach_pending(void) entry_conn->marked_pending_circ_line = 0; \ entry_conn->marked_pending_circ_file = 0; \ } while (0) -#else +#else /* !(defined(DEBUGGING_17659)) */ #define UNMARK() do { } while (0) -#endif +#endif /* defined(DEBUGGING_17659) */ /** Tell any AP streams that are listed as waiting for a new circuit to try * again. If there is an available circuit for a stream, attach it. Otherwise, @@ -979,7 +979,7 @@ connection_ap_mark_as_pending_circuit_(entry_connection_t *entry_conn, log_warn(LD_BUG, "(Previously called from %s:%d.)\n", f2 ? f2 : "<NULL>", entry_conn->marked_pending_circ_line); -#endif +#endif /* defined(DEBUGGING_17659) */ log_backtrace(LOG_WARN, LD_BUG, "To debug, this may help"); return; } @@ -1237,10 +1237,9 @@ connection_ap_handshake_rewrite(entry_connection_t *conn, /* Check for whether this is a .exit address. By default, those are * disallowed when they're coming straight from the client, but you're * allowed to have them in MapAddress commands and so forth. */ - if (!strcmpend(socks->address, ".exit") && !options->AllowDotExit) { + if (!strcmpend(socks->address, ".exit")) { log_warn(LD_APP, "The \".exit\" notation is disabled in Tor due to " - "security risks. Set AllowDotExit in your torrc to enable " - "it (at your own risk)."); + "security risks."); control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s", escaped(socks->address)); out->end_reason = END_STREAM_REASON_TORPROTOCOL; @@ -1674,23 +1673,23 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn, const node_t *node = NULL; /* If this .exit was added by an AUTOMAP, then it came straight from - * a user. Make sure that options->AllowDotExit permits that! */ - if (exit_source == ADDRMAPSRC_AUTOMAP && !options->AllowDotExit) { - /* Whoops; this one is stale. It must have gotten added earlier, - * when AllowDotExit was on. */ - log_warn(LD_APP,"Stale automapped address for '%s.exit', with " - "AllowDotExit disabled. Refusing.", + * a user. That's not safe. */ + if (exit_source == ADDRMAPSRC_AUTOMAP) { + /* Whoops; this one is stale. It must have gotten added earlier? + * (Probably this is not possible, since AllowDotExit no longer + * exists.) */ + log_warn(LD_APP,"Stale automapped address for '%s.exit'. Refusing.", safe_str_client(socks->address)); control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s", escaped(socks->address)); connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL); + tor_assert_nonfatal_unreached(); return -1; } /* Double-check to make sure there are no .exits coming from * impossible/weird sources. */ - if (exit_source == ADDRMAPSRC_DNS || - (exit_source == ADDRMAPSRC_NONE && !options->AllowDotExit)) { + if (exit_source == ADDRMAPSRC_DNS || exit_source == ADDRMAPSRC_NONE) { /* It shouldn't be possible to get a .exit address from any of these * sources. */ log_warn(LD_BUG,"Address '%s.exit', with impossible source for the " @@ -1792,7 +1791,7 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn, connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY); return -1; } -#endif +#endif /* defined(ENABLE_TOR2WEB_MODE) */ /* socks->address is a non-onion hostname or IP address. * If we can't do any non-onion requests, refuse the connection. @@ -2068,7 +2067,7 @@ get_pf_socket(void) #else /* works on NetBSD and FreeBSD */ pf = tor_open_cloexec("/dev/pf", O_RDWR, 0); -#endif +#endif /* defined(OpenBSD) */ if (pf < 0) { log_warn(LD_NET, "open(\"/dev/pf\") failed: %s", strerror(errno)); @@ -2078,9 +2077,10 @@ get_pf_socket(void) pf_socket = pf; return pf_socket; } -#endif +#endif /* defined(TRANS_PF) */ -#if defined(TRANS_NETFILTER) || defined(TRANS_PF) || defined(TRANS_TPROXY) +#if defined(TRANS_NETFILTER) || defined(TRANS_PF) || \ + defined(TRANS_TPROXY) /** Try fill in the address of <b>req</b> from the socket configured * with <b>conn</b>. */ static int @@ -2100,7 +2100,7 @@ destination_from_socket(entry_connection_t *conn, socks_request_t *req) } goto done; } -#endif +#endif /* defined(TRANS_TPROXY) */ #ifdef TRANS_NETFILTER int rv = -1; @@ -2110,13 +2110,13 @@ destination_from_socket(entry_connection_t *conn, socks_request_t *req) rv = getsockopt(ENTRY_TO_CONN(conn)->s, SOL_IP, SO_ORIGINAL_DST, (struct sockaddr*)&orig_dst, &orig_dst_len); break; -#endif +#endif /* defined(TRANS_NETFILTER_IPV4) */ #ifdef TRANS_NETFILTER_IPV6 case AF_INET6: rv = getsockopt(ENTRY_TO_CONN(conn)->s, SOL_IPV6, IP6T_SO_ORIGINAL_DST, (struct sockaddr*)&orig_dst, &orig_dst_len); break; -#endif +#endif /* defined(TRANS_NETFILTER_IPV6) */ default: log_warn(LD_BUG, "Received transparent data from an unsuported socket family %d", @@ -2142,7 +2142,7 @@ destination_from_socket(entry_connection_t *conn, socks_request_t *req) (void)req; log_warn(LD_BUG, "Unable to determine destination from socket."); return -1; -#endif +#endif /* defined(TRANS_NETFILTER) || ... */ done: tor_addr_from_sockaddr(&addr, (struct sockaddr*)&orig_dst, &req->port); @@ -2150,7 +2150,7 @@ destination_from_socket(entry_connection_t *conn, socks_request_t *req) return 0; } -#endif +#endif /* defined(TRANS_NETFILTER) || defined(TRANS_PF) || ... */ #ifdef TRANS_PF static int @@ -2184,7 +2184,7 @@ destination_from_pf(entry_connection_t *conn, socks_request_t *req) return 0; } -#endif +#endif /* defined(__FreeBSD__) */ memset(&pnl, 0, sizeof(pnl)); pnl.proto = IPPROTO_TCP; @@ -2233,7 +2233,7 @@ destination_from_pf(entry_connection_t *conn, socks_request_t *req) return 0; } -#endif +#endif /* defined(TRANS_PF) */ /** Fetch the original destination address and port from a * system-specific interface and put them into a @@ -2269,7 +2269,7 @@ connection_ap_get_original_destination(entry_connection_t *conn, log_warn(LD_BUG, "Called connection_ap_get_original_destination, but no " "transparent proxy method was configured."); return -1; -#endif +#endif /* defined(TRANS_NETFILTER) || ... */ } /** connection_edge_process_inbuf() found a conn in state diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h index e47043f7fe..c6583d3845 100644 --- a/src/or/connection_edge.h +++ b/src/or/connection_edge.h @@ -191,7 +191,7 @@ STATIC void connection_ap_handshake_rewrite(entry_connection_t *conn, rewrite_result_t *out); STATIC int connection_ap_process_http_connect(entry_connection_t *conn); -#endif +#endif /* defined(CONNECTION_EDGE_PRIVATE) */ -#endif +#endif /* !defined(TOR_CONNECTION_EDGE_H) */ diff --git a/src/or/connection_or.c b/src/or/connection_or.c index d890b58da6..e4fda7ce78 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -727,7 +727,7 @@ connection_or_about_to_close(or_connection_t *or_conn) control_event_or_conn_status(or_conn, OR_CONN_EVENT_FAILED, reason); if (!authdir_mode_tests_reachability(options)) - control_event_bootstrap_problem( + control_event_bootstrap_prob_or( orconn_end_reason_to_control_string(reason), reason, or_conn); } @@ -1113,7 +1113,7 @@ connection_or_connect_failed(or_connection_t *conn, { control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED, reason); if (!authdir_mode_tests_reachability(get_options())) - control_event_bootstrap_problem(msg, reason, conn); + control_event_bootstrap_prob_or(msg, reason, conn); } /** <b>conn</b> got an error in connection_handle_read_impl() or @@ -1236,7 +1236,7 @@ connection_or_connect, (const tor_addr_t *_addr, uint16_t port, fmt_addrport(&TO_CONN(conn)->addr, TO_CONN(conn)->port), transport_name, transport_name); - control_event_bootstrap_problem( + control_event_bootstrap_prob_or( "Can't connect to bridge", END_OR_CONN_REASON_PT_MISSING, conn); @@ -1714,7 +1714,7 @@ connection_or_client_learned_peer_id(or_connection_t *conn, control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED, END_OR_CONN_REASON_OR_IDENTITY); if (!authdir_mode_tests_reachability(options)) - control_event_bootstrap_problem( + control_event_bootstrap_prob_or( "Unexpected identity in router certificate", END_OR_CONN_REASON_OR_IDENTITY, conn); diff --git a/src/or/connection_or.h b/src/or/connection_or.h index fe85a3f5fd..ee66b7c528 100644 --- a/src/or/connection_or.h +++ b/src/or/connection_or.h @@ -118,5 +118,5 @@ void connection_or_group_set_badness_(smartlist_t *group, int force); extern int certs_cell_ed25519_disabled_for_testing; #endif -#endif +#endif /* !defined(TOR_CONNECTION_OR_H) */ diff --git a/src/or/conscache.c b/src/or/conscache.c index 9e13ce8e43..0f3e453eaf 100644 --- a/src/or/conscache.c +++ b/src/or/conscache.c @@ -15,7 +15,7 @@ * changes throughout our logic. */ #define MUST_UNMAP_TO_UNLINK -#endif +#endif /* defined(_WIN32) */ /** * A consensus_cache_entry_t is a reference-counted handle to an @@ -90,11 +90,11 @@ consensus_cache_open(const char *subdir, int max_entries) */ #define VERY_LARGE_STORAGEDIR_LIMIT (1000*1000) storagedir_max_entries = VERY_LARGE_STORAGEDIR_LIMIT; -#else +#else /* !(defined(MUST_UNMAP_TO_UNLINK)) */ /* Otherwise, we can just tell the storagedir to use the same limits * as this cache. */ storagedir_max_entries = max_entries; -#endif +#endif /* defined(MUST_UNMAP_TO_UNLINK) */ cache->dir = storage_dir_new(directory, storagedir_max_entries); tor_free(directory); @@ -145,7 +145,7 @@ consensus_cache_register_with_sandbox(consensus_cache_t *cache, * conditional. */ tor_assert_nonfatal_unreached(); -#endif +#endif /* defined(MUST_UNMAP_TO_UNLINK) */ return storage_dir_register_with_sandbox(cache->dir, cfg); } @@ -474,7 +474,7 @@ consensus_cache_get_n_filenames_available(consensus_cache_t *cache) return 0; #else tor_assert_nonfatal(max >= used); -#endif +#endif /* defined(MUST_UNMAP_TO_UNLINK) */ return max - used; } @@ -495,7 +495,7 @@ consensus_cache_delete_pending(consensus_cache_t *cache, int force) if (ent->map) { force_ent = 0; } -#endif +#endif /* defined(MUST_UNMAP_TO_UNLINK) */ if (! force_ent) { if (ent->refcnt > 1 || BUG(ent->in_cache == NULL)) { /* Somebody is using this entry right now */ @@ -611,5 +611,5 @@ consensus_cache_entry_is_mapped(consensus_cache_entry_t *ent) return 0; } } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ diff --git a/src/or/conscache.h b/src/or/conscache.h index a0d74c4e08..3c89dedf43 100644 --- a/src/or/conscache.h +++ b/src/or/conscache.h @@ -58,5 +58,5 @@ int consensus_cache_entry_get_body(const consensus_cache_entry_t *ent, int consensus_cache_entry_is_mapped(consensus_cache_entry_t *ent); #endif -#endif +#endif /* !defined(TOR_CONSCACHE_H) */ diff --git a/src/or/consdiff.h b/src/or/consdiff.h index d05df74b75..eb772c0b2b 100644 --- a/src/or/consdiff.h +++ b/src/or/consdiff.h @@ -92,7 +92,7 @@ MOCK_DECL(STATIC int, MOCK_DECL(STATIC int, consensus_digest_eq,(const uint8_t *d1, const uint8_t *d2)); -#endif +#endif /* defined(CONSDIFF_PRIVATE) */ -#endif +#endif /* !defined(TOR_CONSDIFF_H) */ diff --git a/src/or/consdiffmgr.c b/src/or/consdiffmgr.c index 831d5d45c3..1d63d59577 100644 --- a/src/or/consdiffmgr.c +++ b/src/or/consdiffmgr.c @@ -659,7 +659,7 @@ consdiffmgr_find_diff_from(consensus_cache_entry_t **entry_out, smartlist_free(matches); return result; -#endif +#endif /* 0 */ } /** diff --git a/src/or/consdiffmgr.h b/src/or/consdiffmgr.h index 079f9fe2d2..df569c8e23 100644 --- a/src/or/consdiffmgr.h +++ b/src/or/consdiffmgr.h @@ -68,7 +68,7 @@ STATIC int cdm_entry_get_sha3_value(uint8_t *digest_out, const char *label); STATIC int uncompress_or_copy(char **out, size_t *outlen, consensus_cache_entry_t *ent); -#endif +#endif /* defined(CONSDIFFMGR_PRIVATE) */ -#endif +#endif /* !defined(TOR_CONSDIFFMGR_H) */ diff --git a/src/or/control.c b/src/or/control.c index c11193f397..bd5f01a046 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -593,7 +593,7 @@ control_ports_write_to_file(void) smartlist_add_asprintf(lines, "UNIX_PORT=%s\n", conn->address); continue; } -#endif +#endif /* defined(AF_UNIX) */ smartlist_add_asprintf(lines, "PORT=%s:%d\n", conn->address, conn->port); } SMARTLIST_FOREACH_END(conn); @@ -610,7 +610,7 @@ control_ports_write_to_file(void) options->ControlPortWriteToFile); } } -#endif +#endif /* !defined(_WIN32) */ tor_free(joined); SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp)); smartlist_free(lines); @@ -1749,7 +1749,7 @@ getinfo_helper_misc(control_connection_t *conn, const char *question, #else int myUid = geteuid(); tor_asprintf(answer, "%d", myUid); - #endif +#endif /* defined(_WIN32) */ } else if (!strcmp(question, "process/user")) { #ifdef _WIN32 *answer = tor_strdup(""); @@ -1762,7 +1762,7 @@ getinfo_helper_misc(control_connection_t *conn, const char *question, } else { *answer = tor_strdup(""); } - #endif +#endif /* defined(_WIN32) */ } else if (!strcmp(question, "process/descriptor-limit")) { int max_fds = get_max_sockets(); tor_asprintf(answer, "%d", max_fds); @@ -2158,7 +2158,7 @@ download_status_to_string(const download_status_t *dl) if (dl) { /* Get some substrings of the eventual output ready */ - format_iso_time(tbuf, dl->next_attempt_at); + format_iso_time(tbuf, download_status_get_next_attempt_at(dl)); switch (dl->schedule) { case DL_SCHED_GENERIC: @@ -5587,15 +5587,20 @@ control_event_stream_bandwidth(edge_connection_t *edge_conn) { circuit_t *circ; origin_circuit_t *ocirc; + struct timeval now; + char tbuf[ISO_TIME_USEC_LEN+1]; if (EVENT_IS_INTERESTING(EVENT_STREAM_BANDWIDTH_USED)) { if (!edge_conn->n_read && !edge_conn->n_written) return 0; + tor_gettimeofday(&now); + format_iso_time_nospace_usec(tbuf, &now); send_control_event(EVENT_STREAM_BANDWIDTH_USED, - "650 STREAM_BW "U64_FORMAT" %lu %lu\r\n", + "650 STREAM_BW "U64_FORMAT" %lu %lu %s\r\n", U64_PRINTF_ARG(edge_conn->base_.global_identifier), (unsigned long)edge_conn->n_read, - (unsigned long)edge_conn->n_written); + (unsigned long)edge_conn->n_written, + tbuf); circ = circuit_get_by_edge_conn(edge_conn); if (circ && CIRCUIT_IS_ORIGIN(circ)) { @@ -5617,6 +5622,8 @@ control_event_stream_bandwidth_used(void) if (EVENT_IS_INTERESTING(EVENT_STREAM_BANDWIDTH_USED)) { smartlist_t *conns = get_connection_array(); edge_connection_t *edge_conn; + struct timeval now; + char tbuf[ISO_TIME_USEC_LEN+1]; SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) { @@ -5626,11 +5633,14 @@ control_event_stream_bandwidth_used(void) if (!edge_conn->n_read && !edge_conn->n_written) continue; + tor_gettimeofday(&now); + format_iso_time_nospace_usec(tbuf, &now); send_control_event(EVENT_STREAM_BANDWIDTH_USED, - "650 STREAM_BW "U64_FORMAT" %lu %lu\r\n", + "650 STREAM_BW "U64_FORMAT" %lu %lu %s\r\n", U64_PRINTF_ARG(edge_conn->base_.global_identifier), (unsigned long)edge_conn->n_read, - (unsigned long)edge_conn->n_written); + (unsigned long)edge_conn->n_written, + tbuf); edge_conn->n_written = edge_conn->n_read = 0; } @@ -5646,6 +5656,8 @@ int control_event_circ_bandwidth_used(void) { origin_circuit_t *ocirc; + struct timeval now; + char tbuf[ISO_TIME_USEC_LEN+1]; if (!EVENT_IS_INTERESTING(EVENT_CIRC_BANDWIDTH_USED)) return 0; @@ -5655,11 +5667,15 @@ control_event_circ_bandwidth_used(void) ocirc = TO_ORIGIN_CIRCUIT(circ); if (!ocirc->n_read_circ_bw && !ocirc->n_written_circ_bw) continue; + tor_gettimeofday(&now); + format_iso_time_nospace_usec(tbuf, &now); send_control_event(EVENT_CIRC_BANDWIDTH_USED, - "650 CIRC_BW ID=%d READ=%lu WRITTEN=%lu\r\n", + "650 CIRC_BW ID=%d READ=%lu WRITTEN=%lu " + "TIME=%s\r\n", ocirc->global_identifier, (unsigned long)ocirc->n_read_circ_bw, - (unsigned long)ocirc->n_written_circ_bw); + (unsigned long)ocirc->n_written_circ_bw, + tbuf); ocirc->n_written_circ_bw = ocirc->n_read_circ_bw = 0; } SMARTLIST_FOREACH_END(circ); @@ -6754,80 +6770,112 @@ control_event_bootstrap(bootstrap_status_t status, int progress) } /** Called when Tor has failed to make bootstrapping progress in a way - * that indicates a problem. <b>warn</b> gives a hint as to why, and - * <b>reason</b> provides an "or_conn_end_reason" tag. <b>or_conn</b> - * is the connection that caused this problem. + * that indicates a problem. <b>warn</b> gives a human-readable hint + * as to why, and <b>reason</b> provides a controller-facing short + * tag. <b>conn</b> is the connection that caused this problem and + * can be NULL if a connection cannot be easily identified. */ -MOCK_IMPL(void, -control_event_bootstrap_problem, (const char *warn, int reason, - or_connection_t *or_conn)) +void +control_event_bootstrap_problem(const char *warn, const char *reason, + const connection_t *conn, int dowarn) { int status = bootstrap_percent; const char *tag = "", *summary = ""; char buf[BOOTSTRAP_MSG_LEN]; const char *recommendation = "ignore"; int severity; + char *or_id = NULL, *hostaddr = NULL; + or_connection_t *or_conn = NULL; /* bootstrap_percent must not be in "undefined" state here. */ tor_assert(status >= 0); - if (or_conn->have_noted_bootstrap_problem) - return; - - or_conn->have_noted_bootstrap_problem = 1; - if (bootstrap_percent == 100) return; /* already bootstrapped; nothing to be done here. */ bootstrap_problems++; if (bootstrap_problems >= BOOTSTRAP_PROBLEM_THRESHOLD) - recommendation = "warn"; - - if (reason == END_OR_CONN_REASON_NO_ROUTE) - recommendation = "warn"; - - /* If we are using bridges and all our OR connections are now - closed, it means that we totally failed to connect to our - bridges. Throw a warning. */ - if (get_options()->UseBridges && !any_other_active_or_conns(or_conn)) - recommendation = "warn"; + dowarn = 1; if (we_are_hibernating()) - recommendation = "ignore"; + dowarn = 0; while (status>=0 && bootstrap_status_to_string(status, &tag, &summary) < 0) status--; /* find a recognized status string based on current progress */ status = bootstrap_percent; /* set status back to the actual number */ - severity = !strcmp(recommendation, "warn") ? LOG_WARN : LOG_INFO; + severity = dowarn ? LOG_WARN : LOG_INFO; + + if (dowarn) + recommendation = "warn"; + + if (conn && conn->type == CONN_TYPE_OR) { + /* XXX TO_OR_CONN can't deal with const */ + or_conn = TO_OR_CONN((connection_t *)conn); + or_id = tor_strdup(hex_str(or_conn->identity_digest, DIGEST_LEN)); + } else { + or_id = tor_strdup("?"); + } + + if (conn) + tor_asprintf(&hostaddr, "%s:%d", conn->address, (int)conn->port); + else + hostaddr = tor_strdup("?"); log_fn(severity, LD_CONTROL, "Problem bootstrapping. Stuck at %d%%: %s. (%s; %s; " - "count %d; recommendation %s; host %s at %s:%d)", - status, summary, warn, - orconn_end_reason_to_control_string(reason), + "count %d; recommendation %s; host %s at %s)", + status, summary, warn, reason, bootstrap_problems, recommendation, - hex_str(or_conn->identity_digest, DIGEST_LEN), - or_conn->base_.address, - or_conn->base_.port); + or_id, hostaddr); connection_or_report_broken_states(severity, LD_HANDSHAKE); tor_snprintf(buf, sizeof(buf), "BOOTSTRAP PROGRESS=%d TAG=%s SUMMARY=\"%s\" WARNING=\"%s\" REASON=%s " - "COUNT=%d RECOMMENDATION=%s HOSTID=\"%s\" HOSTADDR=\"%s:%d\"", - bootstrap_percent, tag, summary, warn, - orconn_end_reason_to_control_string(reason), bootstrap_problems, + "COUNT=%d RECOMMENDATION=%s HOSTID=\"%s\" HOSTADDR=\"%s\"", + bootstrap_percent, tag, summary, warn, reason, bootstrap_problems, recommendation, - hex_str(or_conn->identity_digest, DIGEST_LEN), - or_conn->base_.address, - (int)or_conn->base_.port); + or_id, hostaddr); tor_snprintf(last_sent_bootstrap_message, sizeof(last_sent_bootstrap_message), "WARN %s", buf); control_event_client_status(LOG_WARN, "%s", buf); + + tor_free(hostaddr); + tor_free(or_id); +} + +/** Called when Tor has failed to make bootstrapping progress in a way + * that indicates a problem. <b>warn</b> gives a hint as to why, and + * <b>reason</b> provides an "or_conn_end_reason" tag. <b>or_conn</b> + * is the connection that caused this problem. + */ +MOCK_IMPL(void, +control_event_bootstrap_prob_or, (const char *warn, int reason, + or_connection_t *or_conn)) +{ + int dowarn = 0; + + if (or_conn->have_noted_bootstrap_problem) + return; + + or_conn->have_noted_bootstrap_problem = 1; + + if (reason == END_OR_CONN_REASON_NO_ROUTE) + dowarn = 1; + + /* If we are using bridges and all our OR connections are now + closed, it means that we totally failed to connect to our + bridges. Throw a warning. */ + if (get_options()->UseBridges && !any_other_active_or_conns(or_conn)) + dowarn = 1; + + control_event_bootstrap_problem(warn, + orconn_end_reason_to_control_string(reason), + TO_CONN(or_conn), dowarn); } /** We just generated a new summary of which countries we've seen clients @@ -7269,5 +7317,5 @@ control_testing_set_global_event_mask(uint64_t mask) { global_event_mask = mask; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ diff --git a/src/or/control.h b/src/or/control.h index 5f6dcc352b..e957b593a6 100644 --- a/src/or/control.h +++ b/src/or/control.h @@ -99,9 +99,11 @@ void enable_control_logging(void); void monitor_owning_controller_process(const char *process_spec); int control_event_bootstrap(bootstrap_status_t status, int progress); -MOCK_DECL(void, control_event_bootstrap_problem,(const char *warn, +MOCK_DECL(void, control_event_bootstrap_prob_or,(const char *warn, int reason, or_connection_t *or_conn)); +void control_event_bootstrap_problem(const char *warn, const char *reason, + const connection_t *conn, int dowarn); void control_event_clients_seen(const char *controller_str); void control_event_transport_launched(const char *mode, @@ -223,7 +225,7 @@ MOCK_DECL(STATIC void, queue_control_event_string,(uint16_t event, char *msg)); void control_testing_set_global_event_mask(uint64_t mask); -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /** Helper structure: temporarily stores cell statistics for a circuit. */ typedef struct cell_stats_t { @@ -290,7 +292,7 @@ STATIC int getinfo_helper_dir( const char *question, char **answer, const char **errmsg); -#endif +#endif /* defined(CONTROL_PRIVATE) */ -#endif +#endif /* !defined(TOR_CONTROL_H) */ diff --git a/src/or/cpuworker.h b/src/or/cpuworker.h index 320de9532f..d39851325f 100644 --- a/src/or/cpuworker.h +++ b/src/or/cpuworker.h @@ -33,5 +33,5 @@ void cpuworker_log_onionskin_overhead(int severity, int onionskin_type, const char *onionskin_type_name); void cpuworker_cancel_circ_handshake(or_circuit_t *circ); -#endif +#endif /* !defined(TOR_CPUWORKER_H) */ diff --git a/src/or/dircollate.h b/src/or/dircollate.h index 52214282b9..7932e18998 100644 --- a/src/or/dircollate.h +++ b/src/or/dircollate.h @@ -62,7 +62,7 @@ struct dircollator_s { * identity digests .*/ smartlist_t *all_rsa_sha1_lst; }; -#endif +#endif /* defined(DIRCOLLATE_PRIVATE) */ -#endif +#endif /* !defined(TOR_DIRCOLLATE_H) */ diff --git a/src/or/directory.c b/src/or/directory.c index 00f6b6a5d2..6470723cd8 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -3476,17 +3476,31 @@ connection_dir_about_to_close(dir_connection_t *dir_conn) * <b>status</b> and <b>reason_phrase</b>. Write it to <b>conn</b>. */ static void -write_http_status_line(dir_connection_t *conn, int status, +write_short_http_response(dir_connection_t *conn, int status, const char *reason_phrase) { - char buf[256]; - if (tor_snprintf(buf, sizeof(buf), "HTTP/1.0 %d %s\r\n\r\n", - status, reason_phrase ? reason_phrase : "OK") < 0) { - log_warn(LD_BUG,"status line too long."); - return; + char *buf = NULL; + char *datestring = NULL; + + IF_BUG_ONCE(!reason_phrase) { /* bullet-proofing */ + reason_phrase = "unspecified"; + } + + if (server_mode(get_options())) { + /* include the Date: header, but only if we're a relay or bridge */ + char datebuf[RFC1123_TIME_LEN+1]; + format_rfc1123_time(datebuf, time(NULL)); + tor_asprintf(&datestring, "Date: %s\r\n", datebuf); } + + tor_asprintf(&buf, "HTTP/1.0 %d %s\r\n%s\r\n", + status, reason_phrase, datestring?datestring:""); + log_debug(LD_DIRSERV,"Wrote status 'HTTP/1.0 %d %s'", status, reason_phrase); connection_buf_add(buf, strlen(buf), TO_CONN(conn)); + + tor_free(datestring); + tor_free(buf); } /** Write the header for an HTTP/1.0 response onto <b>conn</b>-\>outbuf, @@ -3834,7 +3848,7 @@ directory_handle_command_get,(dir_connection_t *conn, const char *headers, conn->base_.state = DIR_CONN_STATE_SERVER_WRITING; if (parse_http_url(headers, &url) < 0) { - write_http_status_line(conn, 400, "Bad request"); + write_short_http_response(conn, 400, "Bad request"); return 0; } if ((header = http_get_header(headers, "If-Modified-Since: "))) { @@ -3896,7 +3910,7 @@ directory_handle_command_get,(dir_connection_t *conn, const char *headers, } /* we didn't recognize the url */ - write_http_status_line(conn, 404, "Not found"); + write_short_http_response(conn, 404, "Not found"); result = 0; done: @@ -3924,7 +3938,7 @@ handle_get_frontpage(dir_connection_t *conn, const get_handler_args_t *args) NULL, DIRPORTFRONTPAGE_CACHE_LIFETIME); connection_buf_add(frontpage, dlen, TO_CONN(conn)); } else { - write_http_status_line(conn, 404, "Not found"); + write_short_http_response(conn, 404, "Not found"); } return 0; } @@ -4306,13 +4320,13 @@ handle_get_current_consensus(dir_connection_t *conn, parsed_consensus_request_t req; if (parse_consensus_request(&req, args) < 0) { - write_http_status_line(conn, 404, "Couldn't parse request"); + write_short_http_response(conn, 404, "Couldn't parse request"); goto done; } if (digest_list_contains_best_consensus(req.flav, req.diff_from_digests)) { - write_http_status_line(conn, 304, "Not modified"); + write_short_http_response(conn, 304, "Not modified"); geoip_note_ns_response(GEOIP_REJECT_NOT_MODIFIED); goto done; } @@ -4327,7 +4341,7 @@ handle_get_current_consensus(dir_connection_t *conn, } if (req.diff_only && !cached_consensus) { - write_http_status_line(conn, 404, "No such diff available"); + write_short_http_response(conn, 404, "No such diff available"); // XXXX warn_consensus_is_too_old(v, req.flavor, now); geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND); goto done; @@ -4350,7 +4364,7 @@ handle_get_current_consensus(dir_connection_t *conn, if (cached_consensus && have_valid_until && !networkstatus_valid_until_is_reasonably_live(valid_until, now)) { - write_http_status_line(conn, 404, "Consensus is too old"); + write_short_http_response(conn, 404, "Consensus is too old"); warn_consensus_is_too_old(cached_consensus, req.flavor, now); geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND); goto done; @@ -4358,7 +4372,7 @@ handle_get_current_consensus(dir_connection_t *conn, if (cached_consensus && req.want_fps && !client_likes_consensus(cached_consensus, req.want_fps)) { - write_http_status_line(conn, 404, "Consensus not signed by sufficient " + write_short_http_response(conn, 404, "Consensus not signed by sufficient " "number of requested authorities"); geoip_note_ns_response(GEOIP_REJECT_NOT_ENOUGH_SIGS); goto done; @@ -4384,11 +4398,11 @@ handle_get_current_consensus(dir_connection_t *conn, &n_expired); if (!smartlist_len(conn->spool) && !n_expired) { - write_http_status_line(conn, 404, "Not found"); + write_short_http_response(conn, 404, "Not found"); geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND); goto done; } else if (!smartlist_len(conn->spool)) { - write_http_status_line(conn, 304, "Not modified"); + write_short_http_response(conn, 304, "Not modified"); geoip_note_ns_response(GEOIP_REJECT_NOT_MODIFIED); goto done; } @@ -4397,7 +4411,7 @@ handle_get_current_consensus(dir_connection_t *conn, log_debug(LD_DIRSERV, "Client asked for network status lists, but we've been " "writing too many bytes lately. Sending 503 Dir busy."); - write_http_status_line(conn, 503, "Directory busy, try again later"); + write_short_http_response(conn, 503, "Directory busy, try again later"); geoip_note_ns_response(GEOIP_REJECT_BUSY); goto done; } @@ -4510,7 +4524,7 @@ handle_get_status_vote(dir_connection_t *conn, const get_handler_args_t *args) smartlist_free(fps); } if (!smartlist_len(dir_items) && !smartlist_len(items)) { - write_http_status_line(conn, 404, "Not found"); + write_short_http_response(conn, 404, "Not found"); goto vote_done; } @@ -4547,7 +4561,7 @@ handle_get_status_vote(dir_connection_t *conn, const get_handler_args_t *args) }); if (global_write_bucket_low(TO_CONN(conn), estimated_len, 2)) { - write_http_status_line(conn, 503, "Directory busy, try again later"); + write_short_http_response(conn, 503, "Directory busy, try again later"); goto vote_done; } write_http_response_header(conn, body_len ? body_len : -1, @@ -4604,14 +4618,14 @@ handle_get_microdesc(dir_connection_t *conn, const get_handler_args_t *args) compress_method != NO_METHOD, &size_guess, NULL); if (smartlist_len(conn->spool) == 0) { - write_http_status_line(conn, 404, "Not found"); + write_short_http_response(conn, 404, "Not found"); goto done; } if (global_write_bucket_low(TO_CONN(conn), size_guess, 2)) { log_info(LD_DIRSERV, "Client asked for server descriptors, but we've been " "writing too many bytes lately. Sending 503 Dir busy."); - write_http_status_line(conn, 503, "Directory busy, try again later"); + write_short_http_response(conn, 503, "Directory busy, try again later"); goto done; } @@ -4703,13 +4717,14 @@ handle_get_descriptor(dir_connection_t *conn, const get_handler_args_t *args) if (res < 0 || size_guess == 0 || smartlist_len(conn->spool) == 0) { if (msg == NULL) msg = "Not found"; - write_http_status_line(conn, 404, msg); + write_short_http_response(conn, 404, msg); } else { if (global_write_bucket_low(TO_CONN(conn), size_guess, 2)) { log_info(LD_DIRSERV, "Client asked for server descriptors, but we've been " "writing too many bytes lately. Sending 503 Dir busy."); - write_http_status_line(conn, 503, "Directory busy, try again later"); + write_short_http_response(conn, 503, + "Directory busy, try again later"); dir_conn_clear_spool(conn); goto done; } @@ -4782,18 +4797,18 @@ handle_get_keys(dir_connection_t *conn, const get_handler_args_t *args) }); smartlist_free(fp_sks); } else { - write_http_status_line(conn, 400, "Bad request"); + write_short_http_response(conn, 400, "Bad request"); goto keys_done; } if (!smartlist_len(certs)) { - write_http_status_line(conn, 404, "Not found"); + write_short_http_response(conn, 404, "Not found"); goto keys_done; } SMARTLIST_FOREACH(certs, authority_cert_t *, c, if (c->cache_info.published_on < if_modified_since) SMARTLIST_DEL_CURRENT(certs, c)); if (!smartlist_len(certs)) { - write_http_status_line(conn, 304, "Not modified"); + write_short_http_response(conn, 304, "Not modified"); goto keys_done; } len = 0; @@ -4803,7 +4818,7 @@ handle_get_keys(dir_connection_t *conn, const get_handler_args_t *args) if (global_write_bucket_low(TO_CONN(conn), compress_method != NO_METHOD ? len/2 : len, 2)) { - write_http_status_line(conn, 503, "Directory busy, try again later"); + write_short_http_response(conn, 503, "Directory busy, try again later"); goto keys_done; } @@ -4854,19 +4869,19 @@ handle_get_hs_descriptor_v2(dir_connection_t *conn, connection_buf_add(descp, strlen(descp), TO_CONN(conn)); break; case 0: /* well-formed but not present */ - write_http_status_line(conn, 404, "Not found"); + write_short_http_response(conn, 404, "Not found"); break; case -1: /* not well-formed */ - write_http_status_line(conn, 400, "Bad request"); + write_short_http_response(conn, 400, "Bad request"); break; } } else { /* not well-formed */ - write_http_status_line(conn, 400, "Bad request"); + write_short_http_response(conn, 400, "Bad request"); } goto done; } else { /* Not encrypted! */ - write_http_status_line(conn, 404, "Not found"); + write_short_http_response(conn, 404, "Not found"); } done: return 0; @@ -4885,7 +4900,7 @@ handle_get_hs_descriptor_v3(dir_connection_t *conn, /* Reject unencrypted dir connections */ if (!connection_dir_is_encrypted(conn)) { - write_http_status_line(conn, 404, "Not found"); + write_short_http_response(conn, 404, "Not found"); goto done; } @@ -4897,7 +4912,7 @@ handle_get_hs_descriptor_v3(dir_connection_t *conn, retval = hs_cache_lookup_as_dir(HS_VERSION_THREE, pubkey_str, &desc_str); if (retval <= 0 || desc_str == NULL) { - write_http_status_line(conn, 404, "Not found"); + write_short_http_response(conn, 404, "Not found"); goto done; } @@ -4932,7 +4947,7 @@ handle_get_networkstatus_bridges(dir_connection_t *conn, if (!header || tor_memneq(digest, options->BridgePassword_AuthDigest_, DIGEST256_LEN)) { - write_http_status_line(conn, 404, "Not found"); + write_short_http_response(conn, 404, "Not found"); tor_free(header); goto done; } @@ -5067,12 +5082,12 @@ directory_handle_command_post,(dir_connection_t *conn, const char *headers, if (!public_server_mode(options)) { log_info(LD_DIR, "Rejected dir post request from %s " "since we're not a public relay.", conn->base_.address); - write_http_status_line(conn, 503, "Not acting as a public relay"); + write_short_http_response(conn, 503, "Not acting as a public relay"); goto done; } if (parse_http_url(headers, &url) < 0) { - write_http_status_line(conn, 400, "Bad request"); + write_short_http_response(conn, 400, "Bad request"); return 0; } log_debug(LD_DIRSERV,"rewritten url as '%s'.", escaped(url)); @@ -5083,10 +5098,10 @@ directory_handle_command_post,(dir_connection_t *conn, const char *headers, if (rend_cache_store_v2_desc_as_dir(body) < 0) { log_warn(LD_REND, "Rejected v2 rend descriptor (body size %d) from %s.", (int)body_len, conn->base_.address); - write_http_status_line(conn, 400, + write_short_http_response(conn, 400, "Invalid v2 service descriptor rejected"); } else { - write_http_status_line(conn, 200, "Service descriptor (v2) stored"); + write_short_http_response(conn, 200, "Service descriptor (v2) stored"); log_info(LD_REND, "Handled v2 rendezvous descriptor post: accepted"); } goto done; @@ -5103,14 +5118,14 @@ directory_handle_command_post,(dir_connection_t *conn, const char *headers, if (code != 200) { msg = "Invalid HS descriptor. Rejected."; } - write_http_status_line(conn, code, msg); + write_short_http_response(conn, code, msg); goto done; } if (!authdir_mode(options)) { /* we just provide cached directories; we don't want to * receive anything. */ - write_http_status_line(conn, 400, "Nonauthoritative directory does not " + write_short_http_response(conn, 400, "Nonauthoritative directory does not " "accept posted server descriptors"); goto done; } @@ -5125,7 +5140,7 @@ directory_handle_command_post,(dir_connection_t *conn, const char *headers, tor_assert(msg); if (r == ROUTER_ADDED_SUCCESSFULLY) { - write_http_status_line(conn, 200, msg); + write_short_http_response(conn, 200, msg); } else if (WRA_WAS_OUTDATED(r)) { write_http_response_header_impl(conn, -1, NULL, NULL, "X-Descriptor-Not-New: Yes\r\n", -1); @@ -5134,7 +5149,7 @@ directory_handle_command_post,(dir_connection_t *conn, const char *headers, "Rejected router descriptor or extra-info from %s " "(\"%s\").", conn->base_.address, msg); - write_http_status_line(conn, 400, msg); + write_short_http_response(conn, 400, msg); } goto done; } @@ -5144,12 +5159,12 @@ directory_handle_command_post,(dir_connection_t *conn, const char *headers, const char *msg = "OK"; int status; if (dirvote_add_vote(body, &msg, &status)) { - write_http_status_line(conn, status, "Vote stored"); + write_short_http_response(conn, status, "Vote stored"); } else { tor_assert(msg); log_warn(LD_DIRSERV, "Rejected vote from %s (\"%s\").", conn->base_.address, msg); - write_http_status_line(conn, status, msg); + write_short_http_response(conn, status, msg); } goto done; } @@ -5158,17 +5173,18 @@ directory_handle_command_post,(dir_connection_t *conn, const char *headers, !strcmp(url,"/tor/post/consensus-signature")) { /* sigs on consensus. */ const char *msg = NULL; if (dirvote_add_signatures(body, conn->base_.address, &msg)>=0) { - write_http_status_line(conn, 200, msg?msg:"Signatures stored"); + write_short_http_response(conn, 200, msg?msg:"Signatures stored"); } else { log_warn(LD_DIR, "Unable to store signatures posted by %s: %s", conn->base_.address, msg?msg:"???"); - write_http_status_line(conn, 400, msg?msg:"Unable to store signatures"); + write_short_http_response(conn, 400, + msg?msg:"Unable to store signatures"); } goto done; } /* we didn't recognize the url */ - write_http_status_line(conn, 404, "Not found"); + write_short_http_response(conn, 404, "Not found"); done: tor_free(url); @@ -5323,26 +5339,24 @@ connection_dir_finished_connecting(dir_connection_t *conn) STATIC const smartlist_t * find_dl_schedule(const download_status_t *dls, const or_options_t *options) { - const int dir_server = dir_server_mode(options); - const int multi_d = networkstatus_consensus_can_use_multiple_directories( - options); - const int we_are_bootstrapping = networkstatus_consensus_is_bootstrapping( - time(NULL)); - const int use_fallbacks = networkstatus_consensus_can_use_extra_fallbacks( - options); switch (dls->schedule) { case DL_SCHED_GENERIC: - if (dir_server) { + /* Any other directory document */ + if (dir_server_mode(options)) { + /* A directory authority or directory mirror */ return options->TestingServerDownloadSchedule; } else { return options->TestingClientDownloadSchedule; } case DL_SCHED_CONSENSUS: - if (!multi_d) { + if (!networkstatus_consensus_can_use_multiple_directories(options)) { + /* A public relay */ return options->TestingServerConsensusDownloadSchedule; } else { - if (we_are_bootstrapping) { - if (!use_fallbacks) { + /* A client or bridge */ + if (networkstatus_consensus_is_bootstrapping(time(NULL))) { + /* During bootstrapping */ + if (!networkstatus_consensus_can_use_extra_fallbacks(options)) { /* A bootstrapping client without extra fallback directories */ return options->ClientBootstrapConsensusAuthorityOnlyDownloadSchedule; @@ -5358,12 +5372,14 @@ find_dl_schedule(const download_status_t *dls, const or_options_t *options) options->ClientBootstrapConsensusFallbackDownloadSchedule; } } else { + /* A client with a reasonably live consensus, with or without + * certificates */ return options->TestingClientConsensusDownloadSchedule; } } case DL_SCHED_BRIDGE: /* A bridge client downloading bridge descriptors */ - if (any_bridge_descriptors_known()) { + if (options->UseBridges && any_bridge_descriptors_known()) { /* A bridge client with one or more running bridges */ return options->TestingBridgeDownloadSchedule; } else { diff --git a/src/or/directory.h b/src/or/directory.h index 1200728411..79984be32d 100644 --- a/src/or/directory.h +++ b/src/or/directory.h @@ -194,7 +194,7 @@ STATIC void warn_disallowed_anonymous_compression_method(compress_method_t); STATIC int handle_response_fetch_hsdesc_v3(dir_connection_t *conn, const response_handler_args_t *args); -#endif +#endif /* defined(DIRECTORY_PRIVATE) */ #ifdef TOR_UNIT_TESTS /* Used only by test_dir.c and test_hs_cache.c */ @@ -232,7 +232,7 @@ STATIC int parse_hs_version_from_post(const char *url, const char *prefix, const char **end_pos); STATIC unsigned parse_accept_encoding_header(const char *h); -#endif +#endif /* defined(TOR_UNIT_TESTS) */ #if defined(TOR_UNIT_TESTS) || defined(DIRECTORY_PRIVATE) /* Used only by directory.c and test_dir.c */ @@ -242,7 +242,7 @@ STATIC unsigned parse_accept_encoding_header(const char *h); /* no more than triple the previous delay */ #define DIR_TEST_NET_RANDOM_MULTIPLIER (2) -#endif +#endif /* defined(TOR_UNIT_TESTS) || defined(DIRECTORY_PRIVATE) */ -#endif +#endif /* !defined(TOR_DIRECTORY_H) */ diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 06ac15d587..ddee92da55 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -338,7 +338,7 @@ dirserv_router_get_status(const routerinfo_t *router, const char **msg, } return FP_REJECT; } -#endif +#endif /* defined(DISABLE_DISABLING_ED25519) */ } } diff --git a/src/or/dirserv.h b/src/or/dirserv.h index 480174d5bb..46967a6cb2 100644 --- a/src/or/dirserv.h +++ b/src/or/dirserv.h @@ -182,7 +182,7 @@ STATIC int dirserv_has_measured_bw(const char *node_id); STATIC int dirserv_read_guardfraction_file_from_str(const char *guardfraction_file_str, smartlist_t *vote_routerstatuses); -#endif +#endif /* defined(DIRSERV_PRIVATE) */ int dirserv_read_measured_bandwidths(const char *from_file, smartlist_t *routerstatuses); @@ -204,5 +204,5 @@ void dirserv_spool_remove_missing_and_guess_size(dir_connection_t *conn, void dirserv_spool_sort(dir_connection_t *conn); void dir_conn_clear_spool(dir_connection_t *conn); -#endif +#endif /* !defined(TOR_DIRSERV_H) */ diff --git a/src/or/dirvote.h b/src/or/dirvote.h index e342dc78ea..fb3e60f000 100644 --- a/src/or/dirvote.h +++ b/src/or/dirvote.h @@ -242,7 +242,7 @@ STATIC int networkstatus_compute_bw_weights_v10(smartlist_t *chunks, int64_t G, int64_t M, int64_t E, int64_t D, int64_t T, int64_t weight_scale); -#endif +#endif /* defined(DIRVOTE_PRIVATE) */ -#endif +#endif /* !defined(TOR_DIRVOTE_H) */ diff --git a/src/or/dns.c b/src/or/dns.c index 2d642773f3..078bde3ef2 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -102,7 +102,7 @@ static void assert_cache_ok_(void); #define assert_cache_ok() assert_cache_ok_() #else #define assert_cache_ok() STMT_NIL -#endif +#endif /* defined(DEBUG_DNS_CACHE) */ static void assert_resolve_ok(cached_resolve_t *resolve); /** Hash table of cached_resolve objects. */ @@ -961,14 +961,14 @@ assert_connection_edge_not_dns_pending(edge_connection_t *conn) for (pend = resolve->pending_connections; pend; pend = pend->next) { tor_assert(pend->conn != conn); } -#else +#else /* !(1) */ cached_resolve_t **resolve; HT_FOREACH(resolve, cache_map, &cache_root) { for (pend = (*resolve)->pending_connections; pend; pend = pend->next) { tor_assert(pend->conn != conn); } } -#endif +#endif /* 1 */ } /** Log an error and abort if any connection waiting for a DNS resolve is @@ -1396,7 +1396,7 @@ configure_nameservers(int force) evdns_base_load_hosts(the_evdns_base, sandbox_intern_string("/etc/hosts")); } -#endif +#endif /* defined(DNS_OPTION_HOSTSFILE) && defined(USE_LIBSECCOMP) */ log_info(LD_EXIT, "Parsing resolver configuration in '%s'", conf_fname); if ((r = evdns_base_resolv_conf_parse(the_evdns_base, flags, sandbox_intern_string(conf_fname)))) { @@ -1434,7 +1434,7 @@ configure_nameservers(int force) tor_free(resolv_conf_fname); resolv_conf_mtime = 0; } -#endif +#endif /* defined(_WIN32) */ #define SET(k,v) evdns_base_set_option(the_evdns_base, (k), (v)) @@ -2033,7 +2033,7 @@ assert_resolve_ok(cached_resolve_t *resolve) tor_assert(!resolve->hostname); else tor_assert(!resolve->result_ipv4.addr_ipv4); -#endif +#endif /* 0 */ /*XXXXX ADD MORE */ } } @@ -2097,7 +2097,7 @@ assert_cache_ok_(void) }); } -#endif +#endif /* defined(DEBUG_DNS_CACHE) */ cached_resolve_t * dns_get_cache_entry(cached_resolve_t *query) diff --git a/src/or/dns.h b/src/or/dns.h index a81cbd20da..28d9f947b4 100644 --- a/src/or/dns.h +++ b/src/or/dns.h @@ -64,7 +64,7 @@ set_exitconn_info_from_resolve,(edge_connection_t *exitconn, MOCK_DECL(STATIC int, launch_resolve,(cached_resolve_t *resolve)); -#endif +#endif /* defined(DNS_PRIVATE) */ -#endif +#endif /* !defined(TOR_DNS_H) */ diff --git a/src/or/dns_structs.h b/src/or/dns_structs.h index dc00e9f7b9..e22f23ac15 100644 --- a/src/or/dns_structs.h +++ b/src/or/dns_structs.h @@ -98,5 +98,5 @@ typedef struct cached_resolve_t { int minheap_idx; } cached_resolve_t; -#endif +#endif /* !defined(TOR_DNS_STRUCTS_H) */ diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c index 54a22a5150..d254717a54 100644 --- a/src/or/dnsserv.c +++ b/src/or/dnsserv.c @@ -226,10 +226,10 @@ dnsserv_launch_request(const char *name, int reverse, TO_CONN(conn)->port = control_conn->base_.port; TO_CONN(conn)->address = tor_addr_to_str_dup(&control_conn->base_.addr); } -#else +#else /* !(defined(AF_UNIX)) */ TO_CONN(conn)->port = control_conn->base_.port; TO_CONN(conn)->address = tor_addr_to_str_dup(&control_conn->base_.addr); -#endif +#endif /* defined(AF_UNIX) */ if (reverse) entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR; diff --git a/src/or/dnsserv.h b/src/or/dnsserv.h index 6c0643b8dc..2af366eee5 100644 --- a/src/or/dnsserv.h +++ b/src/or/dnsserv.h @@ -23,5 +23,5 @@ void dnsserv_reject_request(entry_connection_t *conn); int dnsserv_launch_request(const char *name, int is_reverse, control_connection_t *control_conn); -#endif +#endif /* !defined(TOR_DNSSERV_H) */ diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c index 739ec82484..129b983334 100644 --- a/src/or/entrynodes.c +++ b/src/or/entrynodes.c @@ -1751,7 +1751,7 @@ entry_guards_update_primary(guard_selection_t *gs) bool_eq(guard->is_primary, smartlist_contains(new_primary_guards, guard))); }); -#endif +#endif /* 1 */ int any_change = 0; if (smartlist_len(gs->primary_entry_guards) != @@ -2385,7 +2385,7 @@ entry_guards_upgrade_waiting_circuits(guard_selection_t *gs, SMARTLIST_FOREACH_BEGIN(all_circuits, origin_circuit_t *, circ) { circuit_guard_state_t *state = origin_circuit_get_guard_state(circ); - if BUG((state == NULL)) + if (BUG(state == NULL)) continue; if (state->state == GUARD_CIRC_STATE_WAITING_FOR_BETTER_GUARD) { diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h index 735c7738ba..f74ccd97f4 100644 --- a/src/or/entrynodes.h +++ b/src/or/entrynodes.h @@ -310,7 +310,7 @@ struct circuit_guard_state_t { */ entry_guard_restriction_t *restrictions; }; -#endif +#endif /* defined(ENTRYNODES_PRIVATE) */ /* Common entry points for old and new guard code */ int guards_update_all(void); @@ -335,7 +335,7 @@ int num_live_entry_guards_for_guard_selection( guard_selection_t *gs, int for_directory); int num_live_entry_guards(int for_directory); -#endif +#endif /* 1 */ const node_t *entry_guard_find_node(const entry_guard_t *guard); const char *entry_guard_get_rsa_id_digest(const entry_guard_t *guard); @@ -550,7 +550,7 @@ STATIC unsigned entry_guards_note_guard_success(guard_selection_t *gs, unsigned old_state); STATIC int entry_guard_has_higher_priority(entry_guard_t *a, entry_guard_t *b); STATIC char *getinfo_helper_format_single_entry_guard(const entry_guard_t *e); -#endif +#endif /* defined(ENTRYNODES_PRIVATE) */ void remove_all_entry_guards_for_guard_selection(guard_selection_t *gs); void remove_all_entry_guards(void); @@ -597,5 +597,5 @@ guard_get_guardfraction_bandwidth(guardfraction_bandwidth_t *guardfraction_bw, int orig_bandwidth, uint32_t guardfraction_percentage); -#endif +#endif /* !defined(TOR_ENTRYNODES_H) */ diff --git a/src/or/ext_orport.h b/src/or/ext_orport.h index b2cd05db8f..af2b97e77c 100644 --- a/src/or/ext_orport.h +++ b/src/or/ext_orport.h @@ -36,7 +36,7 @@ STATIC int handle_client_auth_nonce(const char *client_nonce, extern uint8_t *ext_or_auth_cookie; extern int ext_or_auth_cookie_is_set; #endif -#endif +#endif /* defined(EXT_ORPORT_PRIVATE) */ -#endif +#endif /* !defined(EXT_ORPORT_H) */ diff --git a/src/or/fp_pair.h b/src/or/fp_pair.h index 4cea3eda6d..f7c060b459 100644 --- a/src/or/fp_pair.h +++ b/src/or/fp_pair.h @@ -41,5 +41,5 @@ void fp_pair_map_assert_ok(const fp_pair_map_t *map); #undef DECLARE_MAP_FNS -#endif +#endif /* !defined(_TOR_FP_PAIR_H) */ diff --git a/src/or/geoip.h b/src/or/geoip.h index 55ca8ca28c..acf61b97ae 100644 --- a/src/or/geoip.h +++ b/src/or/geoip.h @@ -19,7 +19,7 @@ STATIC int geoip_parse_entry(const char *line, sa_family_t family); STATIC int geoip_get_country_by_ipv4(uint32_t ipaddr); STATIC int geoip_get_country_by_ipv6(const struct in6_addr *addr); STATIC void clear_geoip_db(void); -#endif +#endif /* defined(GEOIP_PRIVATE) */ int should_record_bridge_info(const or_options_t *options); int geoip_load_file(sa_family_t family, const char *filename); MOCK_DECL(int, geoip_get_country_by_addr, (const tor_addr_t *addr)); @@ -67,5 +67,5 @@ const char *geoip_get_bridge_stats_extrainfo(time_t); char *geoip_get_bridge_stats_controller(time_t); char *format_client_stats_heartbeat(time_t now); -#endif +#endif /* !defined(TOR_GEOIP_H) */ diff --git a/src/or/hibernate.c b/src/or/hibernate.c index 8c48a6f47d..74ab766468 100644 --- a/src/or/hibernate.c +++ b/src/or/hibernate.c @@ -1124,5 +1124,5 @@ hibernate_set_state_for_testing_(hibernate_state_t newstate) { hibernate_state = newstate; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ diff --git a/src/or/hibernate.h b/src/or/hibernate.h index 8bdb65a927..85fb42864b 100644 --- a/src/or/hibernate.h +++ b/src/or/hibernate.h @@ -53,7 +53,7 @@ typedef enum { #ifdef TOR_UNIT_TESTS void hibernate_set_state_for_testing_(hibernate_state_t newstate); #endif -#endif +#endif /* defined(HIBERNATE_PRIVATE) */ -#endif +#endif /* !defined(TOR_HIBERNATE_H) */ diff --git a/src/or/hs_cache.c b/src/or/hs_cache.c index 7f2a9cbbb7..3ebe13fb4d 100644 --- a/src/or/hs_cache.c +++ b/src/or/hs_cache.c @@ -20,6 +20,9 @@ #include "hs_cache.h" +static int cached_client_descriptor_has_expired(time_t now, + const hs_cache_client_descriptor_t *cached_desc); + /********************** Directory HS cache ******************/ /* Directory descriptor cache. Map indexed by blinded key. */ @@ -356,12 +359,27 @@ store_v3_desc_as_client(hs_cache_client_descriptor_t *desc) rend_cache_increment_allocation(cache_get_client_entry_size(desc)); } -/* Query our cache and return the entry or NULL if not found. */ +/* Query our cache and return the entry or NULL if not found or if expired. */ STATIC hs_cache_client_descriptor_t * lookup_v3_desc_as_client(const uint8_t *key) { + time_t now = approx_time(); + hs_cache_client_descriptor_t *cached_desc; + tor_assert(key); - return digest256map_get(hs_cache_v3_client, key); + + /* Do the lookup */ + cached_desc = digest256map_get(hs_cache_v3_client, key); + if (!cached_desc) { + return NULL; + } + + /* Don't return expired entries */ + if (cached_client_descriptor_has_expired(now, cached_desc)) { + return NULL; + } + + return cached_desc; } /* Parse the encoded descriptor in <b>desc_str</b> using @@ -388,7 +406,10 @@ cache_client_desc_new(const char *desc_str, /* All is good: make a cache object for this descriptor */ client_desc = tor_malloc_zero(sizeof(hs_cache_client_descriptor_t)); ed25519_pubkey_copy(&client_desc->key, service_identity_pk); - client_desc->created_ts = approx_time(); + /* Set expiration time for this cached descriptor to be the start of the next + * time period since that's when clients need to start using the next blinded + * pk of the service (and hence will need its next descriptor). */ + client_desc->expiration_ts = hs_get_start_time_of_next_time_period(0); client_desc->desc = desc; client_desc->encoded_desc = tor_strdup(desc_str); @@ -603,9 +624,8 @@ cache_store_as_client(hs_cache_client_descriptor_t *client_desc) if (cache_entry != NULL) { /* If we have an entry in our cache that has a revision counter greater * than the one we just fetched, discard the one we fetched. */ - if (cache_entry->desc->plaintext_data.revision_counter > - client_desc->desc->plaintext_data.revision_counter) { - log_info(LD_REND, "We already have fresher descriptor. Ignoring."); + if (BUG(cache_entry->desc->plaintext_data.revision_counter > + client_desc->desc->plaintext_data.revision_counter)) { cache_client_desc_free(client_desc); goto done; } @@ -621,7 +641,30 @@ cache_store_as_client(hs_cache_client_descriptor_t *client_desc) return 0; } -/* Clean the client cache using now as the current time. Return the total size +/* Return true iff the cached client descriptor at <b>cached_desc</b has + * expired. */ +static int +cached_client_descriptor_has_expired(time_t now, + const hs_cache_client_descriptor_t *cached_desc) +{ + /* We use the current consensus time to see if we should expire this + * descriptor since we use consensus time for all other parts of the protocol + * as well (e.g. to build the blinded key and compute time periods). */ + const networkstatus_t *ns = networkstatus_get_live_consensus(now); + /* If we don't have a recent consensus, consider this entry expired since we + * will want to fetch a new HS desc when we get a live consensus. */ + if (!ns) { + return 1; + } + + if (cached_desc->expiration_ts <= ns->valid_after) { + return 1; + } + + return 0; +} + +/* clean the client cache using now as the current time. Return the total size * of removed bytes from the cache. */ static size_t cache_clean_v3_as_client(time_t now) @@ -635,11 +678,9 @@ cache_clean_v3_as_client(time_t now) DIGEST256MAP_FOREACH_MODIFY(hs_cache_v3_client, key, hs_cache_client_descriptor_t *, entry) { size_t entry_size; - time_t cutoff = now - rend_cache_max_entry_lifetime(); - /* If the entry has been created _after_ the cutoff, not expired so - * continue to the next entry in our v3 cache. */ - if (entry->created_ts > cutoff) { + /* If the entry has not expired, continue to the next cached entry */ + if (!cached_client_descriptor_has_expired(now, entry)) { continue; } /* Here, our entry has expired, remove and free. */ diff --git a/src/or/hs_cache.h b/src/or/hs_cache.h index 8dbc842b95..2dcc518a71 100644 --- a/src/or/hs_cache.h +++ b/src/or/hs_cache.h @@ -103,8 +103,10 @@ typedef struct hs_cache_client_descriptor_t { /* This object is indexed using the service identity public key */ ed25519_public_key_t key; - /* When was this entry created. Used to expire entries. */ - time_t created_ts; + /* When will this entry expire? We expire cached client descriptors in the + * start of the next time period, since that's when clients need to start + * using the next blinded key of the service. */ + time_t expiration_ts; /* The cached descriptor, this object is the owner. It can't be NULL. A * cache object without a valid descriptor is not possible. */ @@ -119,7 +121,7 @@ STATIC size_t cache_clean_v3_as_dir(time_t now, time_t global_cutoff); STATIC hs_cache_client_descriptor_t * lookup_v3_desc_as_client(const uint8_t *key); -#endif /* HS_CACHE_PRIVATE */ +#endif /* defined(HS_CACHE_PRIVATE) */ -#endif /* TOR_HS_CACHE_H */ +#endif /* !defined(TOR_HS_CACHE_H) */ diff --git a/src/or/hs_cell.h b/src/or/hs_cell.h index 5136fce933..958dde4ffc 100644 --- a/src/or/hs_cell.h +++ b/src/or/hs_cell.h @@ -118,5 +118,5 @@ int hs_cell_parse_rendezvous2(const uint8_t *payload, size_t payload_len, /* Util API. */ void hs_cell_introduce1_data_clear(hs_cell_introduce1_data_t *data); -#endif /* TOR_HS_CELL_H */ +#endif /* !defined(TOR_HS_CELL_H) */ diff --git a/src/or/hs_circuit.h b/src/or/hs_circuit.h index 3b0e3aca1c..9085e3fb0b 100644 --- a/src/or/hs_circuit.h +++ b/src/or/hs_circuit.h @@ -59,5 +59,5 @@ int hs_circuit_setup_e2e_rend_circ(origin_circuit_t *circ, int hs_circuit_setup_e2e_rend_circ_legacy_client(origin_circuit_t *circ, const uint8_t *rend_cell_body); -#endif /* TOR_HS_CIRCUIT_H */ +#endif /* !defined(TOR_HS_CIRCUIT_H) */ diff --git a/src/or/hs_circuitmap.c b/src/or/hs_circuitmap.c index 63d5c1ba2e..97d6053e9b 100644 --- a/src/or/hs_circuitmap.c +++ b/src/or/hs_circuitmap.c @@ -87,7 +87,7 @@ get_hs_circuitmap(void) return the_hs_circuitmap; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /****************** HS circuitmap utility functions **************************/ diff --git a/src/or/hs_circuitmap.h b/src/or/hs_circuitmap.h index 0903de2347..43b2947c17 100644 --- a/src/or/hs_circuitmap.h +++ b/src/or/hs_circuitmap.h @@ -99,7 +99,7 @@ struct hs_token_s { uint8_t *token; }; -#endif /* HS_CIRCUITMAP_PRIVATE */ +#endif /* defined(HS_CIRCUITMAP_PRIVATE) */ #ifdef TOR_UNIT_TESTS @@ -107,5 +107,5 @@ hs_circuitmap_ht *get_hs_circuitmap(void); #endif /* TOR_UNIT_TESTS */ -#endif /* TOR_HS_CIRCUITMAP_H */ +#endif /* !defined(TOR_HS_CIRCUITMAP_H) */ diff --git a/src/or/hs_client.c b/src/or/hs_client.c index be5ece068c..77fbf548ed 100644 --- a/src/or/hs_client.c +++ b/src/or/hs_client.c @@ -521,7 +521,7 @@ client_rendezvous_circ_has_opened(origin_circuit_t *circ) * to a newly allocated extend_info_t object fully initialized. Return NULL if * we can't convert it for which chances are that we are missing or malformed * link specifiers. */ -static extend_info_t * +STATIC extend_info_t * desc_intro_point_to_extend_info(const hs_desc_intro_point_t *ip) { extend_info_t *ei; @@ -594,7 +594,7 @@ intro_point_is_usable(const ed25519_public_key_t *service_pk, /* Using a descriptor desc, return a newly allocated extend_info_t object of a * randomly picked introduction point from its list. Return NULL if none are * usable. */ -static extend_info_t * +STATIC extend_info_t * client_get_random_intro(const ed25519_public_key_t *service_pk) { extend_info_t *ei = NULL, *ei_excluded = NULL; @@ -646,6 +646,12 @@ client_get_random_intro(const ed25519_public_key_t *service_pk) /* If this pick is in the ExcludeNodes list, we keep its reference so if * we ever end up not being able to pick anything else and StrictNodes is * unset, we'll use it. */ + if (ei_excluded) { + /* If something was already here free it. After the loop is gone we + * will examine the last excluded intro point, and that's fine since + * that's random anyway */ + extend_info_free(ei_excluded); + } ei_excluded = ei; continue; } @@ -662,6 +668,7 @@ client_get_random_intro(const ed25519_public_key_t *service_pk) if (options->StrictNodes) { log_warn(LD_REND, "Every introduction points are in the ExcludeNodes set " "and StrictNodes is set. We can't connect."); + extend_info_free(ei); ei = NULL; } diff --git a/src/or/hs_client.h b/src/or/hs_client.h index 3ea2b8cdf9..4eee1174bd 100644 --- a/src/or/hs_client.h +++ b/src/or/hs_client.h @@ -71,7 +71,13 @@ void hs_client_free_all(void); STATIC routerstatus_t * pick_hsdir_v3(const ed25519_public_key_t *onion_identity_pk); -#endif +STATIC extend_info_t * +client_get_random_intro(const ed25519_public_key_t *service_pk); -#endif /* TOR_HS_CLIENT_H */ +STATIC extend_info_t * +desc_intro_point_to_extend_info(const hs_desc_intro_point_t *ip); + +#endif /* defined(HS_CLIENT_PRIVATE) */ + +#endif /* !defined(TOR_HS_CLIENT_H) */ diff --git a/src/or/hs_common.c b/src/or/hs_common.c index 291d8ae8da..2cdfe57cd6 100644 --- a/src/or/hs_common.c +++ b/src/or/hs_common.c @@ -76,7 +76,7 @@ set_unix_port(edge_connection_t *conn, rend_service_port_config_t *p) return 0; } -#else /* defined(HAVE_SYS_UN_H) */ +#else /* !(defined(HAVE_SYS_UN_H)) */ static int set_unix_port(edge_connection_t *conn, rend_service_port_config_t *p) @@ -94,7 +94,7 @@ add_unix_port(smartlist_t *ports, rend_service_port_config_t *p) return -ENOSYS; } -#endif /* HAVE_SYS_UN_H */ +#endif /* defined(HAVE_SYS_UN_H) */ /* Helper function: The key is a digest that we compare to a node_t object * current hsdir_index. */ @@ -235,7 +235,7 @@ get_time_period_length(void) } /** Get the HS time period number at time <b>now</b>. If <b>now</b> is not set, - * we try to get the time ourselves. */ + * we try to get the time ourselves from a live consensus. */ uint64_t hs_get_time_period_num(time_t now) { @@ -269,22 +269,26 @@ hs_get_time_period_num(time_t now) } /** Get the number of the _upcoming_ HS time period, given that the current - * time is <b>now</b>. */ + * time is <b>now</b>. If <b>now</b> is not set, we try to get the time from a + * live consensus. */ uint64_t hs_get_next_time_period_num(time_t now) { return hs_get_time_period_num(now) + 1; } -/* Get the number of the _previous_ HS time period, given that the current - * time is <b>now</b>. */ +/* Get the number of the _previous_ HS time period, given that the current time + * is <b>now</b>. If <b>now</b> is not set, we try to get the time from a live + * consensus. */ uint64_t hs_get_previous_time_period_num(time_t now) { return hs_get_time_period_num(now) - 1; } -/* Return the start time of the upcoming time period based on <b>now</b>. */ +/* Return the start time of the upcoming time period based on <b>now</b>. If + <b>now</b> is not set, we try to get the time ourselves from a live + consensus. */ time_t hs_get_start_time_of_next_time_period(time_t now) { @@ -637,7 +641,7 @@ get_second_cached_disaster_srv(void) return cached_disaster_srv[1]; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /* When creating a blinded key, we need a parameter which construction is as * follow: H(pubkey | [secret] | ed25519-basepoint | nonce). @@ -914,22 +918,31 @@ hs_address_is_valid(const char *address) uint8_t version; uint8_t checksum[HS_SERVICE_ADDR_CHECKSUM_LEN_USED]; uint8_t target_checksum[DIGEST256_LEN]; - ed25519_public_key_t key; + ed25519_public_key_t service_pubkey; /* Parse the decoded address into the fields we need. */ - if (hs_parse_address(address, &key, checksum, &version) < 0) { + if (hs_parse_address(address, &service_pubkey, checksum, &version) < 0) { goto invalid; } /* Get the checksum it's suppose to be and compare it with what we have * encoded in the address. */ - build_hs_checksum(&key, version, target_checksum); + build_hs_checksum(&service_pubkey, version, target_checksum); if (tor_memcmp(checksum, target_checksum, sizeof(checksum))) { log_warn(LD_REND, "Service address %s invalid checksum.", escaped_safe_str(address)); goto invalid; } + /* Validate that this pubkey does not have a torsion component. We need to do + * this on the prop224 client-side so that attackers can't give equivalent + * forms of an onion address to users. */ + if (ed25519_validate_pubkey(&service_pubkey) < 0) { + log_warn(LD_REND, "Service address %s has bad pubkey .", + escaped_safe_str(address)); + goto invalid; + } + /* Valid address. */ return 1; invalid: diff --git a/src/or/hs_common.h b/src/or/hs_common.h index 5851578fd6..e28ffe1adb 100644 --- a/src/or/hs_common.h +++ b/src/or/hs_common.h @@ -266,9 +266,9 @@ STATIC uint64_t get_time_period_length(void); STATIC uint8_t *get_first_cached_disaster_srv(void); STATIC uint8_t *get_second_cached_disaster_srv(void); -#endif /* TOR_UNIT_TESTS */ +#endif /* defined(TOR_UNIT_TESTS) */ -#endif /* HS_COMMON_PRIVATE */ +#endif /* defined(HS_COMMON_PRIVATE) */ -#endif /* TOR_HS_COMMON_H */ +#endif /* !defined(TOR_HS_COMMON_H) */ diff --git a/src/or/hs_config.h b/src/or/hs_config.h index 2f8cbdc130..6cd7aed460 100644 --- a/src/or/hs_config.h +++ b/src/or/hs_config.h @@ -20,5 +20,5 @@ int hs_config_service_all(const or_options_t *options, int validate_only); -#endif /* TOR_HS_CONFIG_H */ +#endif /* !defined(TOR_HS_CONFIG_H) */ diff --git a/src/or/hs_descriptor.h b/src/or/hs_descriptor.h index 61e7a28c2e..971e856647 100644 --- a/src/or/hs_descriptor.h +++ b/src/or/hs_descriptor.h @@ -261,7 +261,7 @@ STATIC size_t decode_superencrypted(const char *message, size_t message_len, uint8_t **encrypted_out); STATIC void desc_plaintext_data_free_contents(hs_desc_plaintext_data_t *desc); -#endif /* HS_DESCRIPTOR_PRIVATE */ +#endif /* defined(HS_DESCRIPTOR_PRIVATE) */ -#endif /* TOR_HS_DESCRIPTOR_H */ +#endif /* !defined(TOR_HS_DESCRIPTOR_H) */ diff --git a/src/or/hs_ident.h b/src/or/hs_ident.h index 101c1cfffd..03150d25ea 100644 --- a/src/or/hs_ident.h +++ b/src/or/hs_ident.h @@ -137,5 +137,5 @@ void hs_ident_edge_conn_free(hs_ident_edge_conn_t *ident); /* Validators */ int hs_ident_intro_circ_is_valid(const hs_ident_circuit_t *ident); -#endif /* TOR_HS_IDENT_H */ +#endif /* !defined(TOR_HS_IDENT_H) */ diff --git a/src/or/hs_intropoint.h b/src/or/hs_intropoint.h index 5c77f07ec3..749d1530e1 100644 --- a/src/or/hs_intropoint.h +++ b/src/or/hs_intropoint.h @@ -73,7 +73,7 @@ STATIC int handle_introduce1(or_circuit_t *client_circ, STATIC int validate_introduce1_parsed_cell(const trn_cell_introduce1_t *cell); STATIC int circuit_is_suitable_for_introduce1(const or_circuit_t *circ); -#endif /* HS_INTROPOINT_PRIVATE */ +#endif /* defined(HS_INTROPOINT_PRIVATE) */ -#endif /* TOR_HS_INTRO_H */ +#endif /* !defined(TOR_HS_INTRO_H) */ diff --git a/src/or/hs_ntor.h b/src/or/hs_ntor.h index d07bff8cf0..77e544a130 100644 --- a/src/or/hs_ntor.h +++ b/src/or/hs_ntor.h @@ -63,5 +63,5 @@ int hs_ntor_client_rendezvous2_mac_is_good( const hs_ntor_rend_cell_keys_t *hs_ntor_rend_cell_keys, const uint8_t *rcvd_mac); -#endif +#endif /* !defined(TOR_HS_NTOR_H) */ diff --git a/src/or/hs_service.c b/src/or/hs_service.c index 05045035f3..d26f49516d 100644 --- a/src/or/hs_service.c +++ b/src/or/hs_service.c @@ -910,7 +910,7 @@ write_address_to_file(const hs_service_t *service, const char *fname_) "group-readable.", escaped(fname)); } } -#endif /* _WIN32 */ +#endif /* !defined(_WIN32) */ /* Success. */ ret = 0; @@ -3309,5 +3309,5 @@ get_first_service(void) return *obj; } -#endif /* TOR_UNIT_TESTS */ +#endif /* defined(TOR_UNIT_TESTS) */ diff --git a/src/or/hs_service.h b/src/or/hs_service.h index 248df27e10..ed1053d850 100644 --- a/src/or/hs_service.h +++ b/src/or/hs_service.h @@ -346,9 +346,9 @@ STATIC void service_desc_schedule_upload(hs_service_descriptor_t *desc, STATIC int service_desc_hsdirs_changed(const hs_service_t *service, const hs_service_descriptor_t *desc); -#endif /* TOR_UNIT_TESTS */ +#endif /* defined(TOR_UNIT_TESTS) */ -#endif /* HS_SERVICE_PRIVATE */ +#endif /* defined(HS_SERVICE_PRIVATE) */ -#endif /* TOR_HS_SERVICE_H */ +#endif /* !defined(TOR_HS_SERVICE_H) */ diff --git a/src/or/include.am b/src/or/include.am index 021f5f9d5d..7216aba9af 100644 --- a/src/or/include.am +++ b/src/or/include.am @@ -99,6 +99,8 @@ LIBTOR_A_SOURCES = \ src/or/routerparse.c \ src/or/routerset.c \ src/or/scheduler.c \ + src/or/scheduler_kist.c \ + src/or/scheduler_vanilla.c \ src/or/statefile.c \ src/or/status.c \ src/or/torcert.c \ diff --git a/src/or/keypin.h b/src/or/keypin.h index 2564f5befb..fbb77e5c35 100644 --- a/src/or/keypin.h +++ b/src/or/keypin.h @@ -41,7 +41,7 @@ STATIC keypin_ent_t * keypin_parse_journal_line(const char *cp); STATIC int keypin_load_journal_impl(const char *data, size_t size); MOCK_DECL(STATIC void, keypin_add_entry_to_map, (keypin_ent_t *ent)); -#endif +#endif /* defined(KEYPIN_PRIVATE) */ -#endif +#endif /* !defined(TOR_KEYPIN_H) */ diff --git a/src/or/main.c b/src/or/main.c index c987ddc61b..65b0b8f4df 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -122,9 +122,9 @@ * Coverity. Here's a kludge to unconfuse it. */ # define __INCLUDE_LEVEL__ 2 -# endif +#endif /* defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) */ #include <systemd/sd-daemon.h> -#endif +#endif /* defined(HAVE_SYSTEMD) */ void evdns_shutdown(int); @@ -742,7 +742,7 @@ conn_read_callback(evutil_socket_t fd, short event, void *_conn) "(fd %d); removing", conn_type_to_string(conn->type), (int)conn->s); tor_fragile_assert(); -#endif +#endif /* !defined(_WIN32) */ if (CONN_IS_EDGE(conn)) connection_edge_end_errno(TO_EDGE_CONN(conn)); connection_mark_for_close(conn); @@ -2227,7 +2227,7 @@ systemd_watchdog_callback(periodic_timer_t *timer, void *arg) (void)arg; sd_notify(0, "WATCHDOG=1"); } -#endif +#endif /* defined(HAVE_SYSTEMD_209) */ /** Timer: used to invoke refill_callback(). */ static periodic_timer_t *refill_timer = NULL; @@ -2291,7 +2291,7 @@ got_libevent_error(void) } return 0; } -#endif +#endif /* !defined(_WIN32) */ #define UPTIME_CUTOFF_FOR_NEW_BANDWIDTH_TEST (6*60*60) @@ -2565,7 +2565,7 @@ do_main_loop(void) tor_assert(systemd_watchdog_timer); } } -#endif +#endif /* defined(HAVE_SYSTEMD_209) */ if (!refill_timer) { struct timeval refill_interval; @@ -2593,7 +2593,7 @@ do_main_loop(void) log_info(LD_GENERAL, "Systemd NOTIFY_SOCKET not present."); } } -#endif +#endif /* defined(HAVE_SYSTEMD) */ return run_main_loop_until_done(); } @@ -2646,7 +2646,7 @@ run_main_loop_once(void) log_warn(LD_NET, "EINVAL from libevent: should you upgrade libevent?"); if (got_libevent_error()) return -1; -#endif +#endif /* !defined(_WIN32) */ } else { tor_assert_nonfatal_once(! ERRNO_IS_EINPROGRESS(e)); log_debug(LD_NET,"libevent call interrupted."); @@ -3002,7 +3002,7 @@ handle_signals(int is_parent) #ifdef SIGXFSZ sigaction(SIGXFSZ, &action, NULL); #endif -#endif +#endif /* !defined(_WIN32) */ } } @@ -3730,7 +3730,7 @@ tor_main(int argc, char *argv[]) setdeppolicy(3); } } -#endif +#endif /* defined(_WIN32) */ configure_backtrace_handler(get_version()); @@ -3746,14 +3746,14 @@ tor_main(int argc, char *argv[]) int r = crypto_use_tor_alloc_functions(); tor_assert(r == 0); } -#endif +#endif /* defined(USE_DMALLOC) */ #ifdef NT_SERVICE { int done = 0; result = nt_service_parse_options(argc, argv, &done); if (done) return result; } -#endif +#endif /* defined(NT_SERVICE) */ if (tor_init(argc, argv)<0) return -1; @@ -3785,7 +3785,6 @@ tor_main(int argc, char *argv[]) case CMD_KEY_EXPIRATION: init_keys(); result = log_cert_expiration(); - result = 0; break; case CMD_LIST_FINGERPRINT: result = do_list_fingerprint(); diff --git a/src/or/main.h b/src/or/main.h index 57aa372750..132ab12bbb 100644 --- a/src/or/main.h +++ b/src/or/main.h @@ -95,7 +95,7 @@ STATIC void teardown_periodic_events(void); #ifdef TOR_UNIT_TESTS extern smartlist_t *connection_array; #endif -#endif +#endif /* defined(MAIN_PRIVATE) */ -#endif +#endif /* !defined(TOR_MAIN_H) */ diff --git a/src/or/microdesc.h b/src/or/microdesc.h index 943873066e..b40d66b3e3 100644 --- a/src/or/microdesc.h +++ b/src/or/microdesc.h @@ -50,5 +50,5 @@ int we_fetch_microdescriptors(const or_options_t *options); int we_fetch_router_descriptors(const or_options_t *options); int we_use_microdescriptors_for_circuits(const or_options_t *options); -#endif +#endif /* !defined(TOR_MICRODESC_H) */ diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index 8b07a88853..93bb8643d8 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -61,6 +61,7 @@ #include "router.h" #include "routerlist.h" #include "routerparse.h" +#include "scheduler.h" #include "shared_random.h" #include "transports.h" #include "torcert.h" @@ -1561,6 +1562,15 @@ notify_control_networkstatus_changed(const networkstatus_t *old_c, smartlist_free(changed); } +/* Called when the consensus has changed from old_c to new_c. */ +static void +notify_networkstatus_changed(const networkstatus_t *old_c, + const networkstatus_t *new_c) +{ + notify_control_networkstatus_changed(old_c, new_c); + scheduler_notify_networkstatus_changed(old_c, new_c); +} + /** Copy all the ancillary information (like router download status and so on) * from <b>old_c</b> to <b>new_c</b>. */ static void @@ -1618,7 +1628,7 @@ networkstatus_set_current_consensus_from_ns(networkstatus_t *c, } return current_md_consensus ? 0 : -1; } -#endif //TOR_UNIT_TESTS +#endif /* defined(TOR_UNIT_TESTS) */ /** * Return true if any option is set in <b>options</b> to make us behave @@ -1886,8 +1896,7 @@ networkstatus_set_current_consensus(const char *consensus, const int is_usable_flavor = flav == usable_consensus_flavor(); if (is_usable_flavor) { - notify_control_networkstatus_changed( - networkstatus_get_latest_consensus(), c); + notify_networkstatus_changed(networkstatus_get_latest_consensus(), c); } if (flav == FLAV_NS) { if (current_ns_consensus) { @@ -1989,14 +1998,16 @@ networkstatus_set_current_consensus(const char *consensus, char tbuf[ISO_TIME_LEN+1]; char dbuf[64]; long delta = now - c->valid_after; + char *flavormsg = NULL; format_iso_time(tbuf, c->valid_after); format_time_interval(dbuf, sizeof(dbuf), delta); log_warn(LD_GENERAL, "Our clock is %s behind the time published in the " "consensus network status document (%s UTC). Tor needs an " "accurate clock to work correctly. Please check your time and " "date settings!", dbuf, tbuf); - control_event_general_status(LOG_WARN, - "CLOCK_SKEW MIN_SKEW=%ld SOURCE=CONSENSUS", delta); + tor_asprintf(&flavormsg, "%s flavor consensus", flavor); + clock_skew_warning(NULL, delta, 1, LD_GENERAL, flavormsg, "CONSENSUS"); + tor_free(flavormsg); } router_dir_info_changed(); @@ -2312,9 +2323,9 @@ get_net_param_from_list(smartlist_t *net_params, const char *param_name, * Make sure the value parsed from the consensus is at least * <b>min_val</b> and at most <b>max_val</b> and raise/cap the parsed value * if necessary. */ -int32_t -networkstatus_get_param(const networkstatus_t *ns, const char *param_name, - int32_t default_val, int32_t min_val, int32_t max_val) +MOCK_IMPL(int32_t, +networkstatus_get_param, (const networkstatus_t *ns, const char *param_name, + int32_t default_val, int32_t min_val, int32_t max_val)) { if (!ns) /* if they pass in null, go find it ourselves */ ns = networkstatus_get_latest_consensus(); diff --git a/src/or/networkstatus.h b/src/or/networkstatus.h index adaa108904..39a0f753d8 100644 --- a/src/or/networkstatus.h +++ b/src/or/networkstatus.h @@ -109,10 +109,9 @@ void signed_descs_update_status_from_consensus_networkstatus( char *networkstatus_getinfo_helper_single(const routerstatus_t *rs); char *networkstatus_getinfo_by_purpose(const char *purpose_string, time_t now); void networkstatus_dump_bridge_status_to_file(time_t now); -int32_t networkstatus_get_param(const networkstatus_t *ns, - const char *param_name, - int32_t default_val, int32_t min_val, - int32_t max_val); +MOCK_DECL(int32_t, networkstatus_get_param, + (const networkstatus_t *ns, const char *param_name, + int32_t default_val, int32_t min_val, int32_t max_val)); int32_t networkstatus_get_overridable_param(const networkstatus_t *ns, int32_t torrc_value, const char *param_name, @@ -138,8 +137,8 @@ STATIC int networkstatus_set_current_consensus_from_ns(networkstatus_t *c, const char *flavor); extern networkstatus_t *current_ns_consensus; extern networkstatus_t *current_md_consensus; -#endif -#endif +#endif /* defined(TOR_UNIT_TESTS) */ +#endif /* defined(NETWORKSTATUS_PRIVATE) */ -#endif +#endif /* !defined(TOR_NETWORKSTATUS_H) */ diff --git a/src/or/nodelist.h b/src/or/nodelist.h index 427e449ad9..754990ac8d 100644 --- a/src/or/nodelist.h +++ b/src/or/nodelist.h @@ -149,9 +149,9 @@ int count_loading_descriptors_progress(void); STATIC void node_set_hsdir_index(node_t *node, const networkstatus_t *ns); -#endif /* TOR_UNIT_TESTS */ +#endif /* defined(TOR_UNIT_TESTS) */ -#endif /* NODELIST_PRIVATE */ +#endif /* defined(NODELIST_PRIVATE) */ -#endif +#endif /* !defined(TOR_NODELIST_H) */ diff --git a/src/or/ntmain.c b/src/or/ntmain.c index 7a85ba9708..508e5844eb 100644 --- a/src/or/ntmain.c +++ b/src/or/ntmain.c @@ -502,7 +502,7 @@ nt_service_command_line(int *using_default_torrc) tor_exe_ascii[sizeof(tor_exe_ascii)-1] = '\0'; #else strlcpy(tor_exe_ascii, tor_exe, sizeof(tor_exe_ascii)); -#endif +#endif /* defined(UNICODE) */ /* Allocate a string for the NT service command line and */ /* Format the service command */ @@ -778,5 +778,5 @@ nt_service_parse_options(int argc, char **argv, int *should_exit) return 0; } -#endif +#endif /* defined(_WIN32) */ diff --git a/src/or/ntmain.h b/src/or/ntmain.h index 4b771b1828..81b7159855 100644 --- a/src/or/ntmain.h +++ b/src/or/ntmain.h @@ -22,7 +22,7 @@ int nt_service_is_stopping(void); void nt_service_set_state(DWORD state); #else #define nt_service_is_stopping() 0 -#endif +#endif /* defined(NT_SERVICE) */ -#endif +#endif /* !defined(TOR_NTMAIN_H) */ diff --git a/src/or/onion.h b/src/or/onion.h index 37a7b08cb6..95544dfac1 100644 --- a/src/or/onion.h +++ b/src/or/onion.h @@ -119,5 +119,5 @@ int extend_cell_format(uint8_t *command_out, uint16_t *len_out, int extended_cell_format(uint8_t *command_out, uint16_t *len_out, uint8_t *payload_out, const extended_cell_t *cell_in); -#endif +#endif /* !defined(TOR_ONION_H) */ diff --git a/src/or/onion_fast.h b/src/or/onion_fast.h index b31f8e9492..3a5aefea3f 100644 --- a/src/or/onion_fast.h +++ b/src/or/onion_fast.h @@ -35,5 +35,5 @@ int fast_client_handshake(const fast_handshake_state_t *handshake_state, size_t key_out_len, const char **msg_out); -#endif +#endif /* !defined(TOR_ONION_FAST_H) */ diff --git a/src/or/onion_ntor.h b/src/or/onion_ntor.h index 158c499de4..02dea2dfc1 100644 --- a/src/or/onion_ntor.h +++ b/src/or/onion_ntor.h @@ -55,7 +55,7 @@ struct ntor_handshake_state_t { curve25519_public_key_t pubkey_X; /** @} */ }; -#endif +#endif /* defined(ONION_NTOR_PRIVATE) */ -#endif +#endif /* !defined(TOR_ONION_NTOR_H) */ diff --git a/src/or/onion_tap.h b/src/or/onion_tap.h index bd625231f4..713c1d7391 100644 --- a/src/or/onion_tap.h +++ b/src/or/onion_tap.h @@ -34,5 +34,5 @@ int onion_skin_TAP_client_handshake(crypto_dh_t *handshake_state, size_t key_out_len, const char **msg_out); -#endif +#endif /* !defined(TOR_ONION_TAP_H) */ diff --git a/src/or/or.h b/src/or/or.h index b3c4ed8293..4fc0e788a0 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -64,7 +64,7 @@ #include <process.h> #include <direct.h> #include <windows.h> -#endif +#endif /* defined(_WIN32) */ #include "crypto.h" #include "crypto_format.h" @@ -1834,7 +1834,7 @@ typedef struct dir_connection_t { /** Number of RELAY_DATA cells sent. */ uint32_t data_cells_sent; -#endif +#endif /* defined(MEASUREMENTS_21206) */ } dir_connection_t; /** Subtype of connection_t for an connection to a controller. */ @@ -4169,13 +4169,6 @@ typedef struct { * if we are a cache). For authorities, this is always true. */ int DownloadExtraInfo; - /** If true, we convert "www.google.com.foo.exit" addresses on the - * socks/trans/natd ports into "www.google.com" addresses that - * exit from the node "foo". Disabled by default since attacking - * websites and exit relays can use it to manipulate your path - * selection. */ - int AllowDotExit; - /** If true, we're configured to collect statistics on clients * requesting network statuses from us as directory. */ int DirReqStatistics_option; @@ -4548,19 +4541,6 @@ typedef struct { /** How long (seconds) do we keep a guard before picking a new one? */ int GuardLifetime; - /** Low-water mark for global scheduler - start sending when estimated - * queued size falls below this threshold. - */ - uint64_t SchedulerLowWaterMark__; - /** High-water mark for global scheduler - stop sending when estimated - * queued size exceeds this threshold. - */ - uint64_t SchedulerHighWaterMark__; - /** Flush size for global scheduler - flush this many cells at a time - * when sending. - */ - int SchedulerMaxFlushCells__; - /** Is this an exit node? This is a tristate, where "1" means "yes, and use * the default exit policy if none is given" and "0" means "no; exit policy * is 'reject *'" and "auto" (-1) means "same as 1, but warn the user." @@ -4633,6 +4613,21 @@ typedef struct { /** Bool (default: 0). Tells Tor to never try to exec another program. */ int NoExec; + + /** Have the KIST scheduler run every X milliseconds. If less than zero, do + * not use the KIST scheduler but use the old vanilla scheduler instead. If + * zero, do what the consensus says and fall back to using KIST as if this is + * set to "10 msec" if the consensus doesn't say anything. */ + int64_t KISTSchedRunInterval; + + /** A multiplier for the KIST per-socket limit calculation. */ + double KISTSockBufSizeFactor; + + /** The list of scheduler type string ordered by priority that is first one + * has to be tried first. Default: KIST,KISTLite,Vanilla */ + smartlist_t *Schedulers; + /* An ordered list of scheduler_types mapped from Schedulers. */ + smartlist_t *SchedulerTypes_; } or_options_t; /** Persistent state for an onion router, as saved to disk. */ @@ -5056,7 +5051,7 @@ typedef struct measured_bw_line_t { long int bw_kb; } measured_bw_line_t; -#endif +#endif /* defined(DIRSERV_PRIVATE) */ /********************************* dirvote.c ************************/ @@ -5469,5 +5464,5 @@ typedef struct tor_version_t { char git_tag[DIGEST_LEN]; } tor_version_t; -#endif +#endif /* !defined(TOR_OR_H) */ diff --git a/src/or/parsecommon.h b/src/or/parsecommon.h index 5e5f9f4db6..903d94478b 100644 --- a/src/or/parsecommon.h +++ b/src/or/parsecommon.h @@ -318,5 +318,5 @@ directory_token_t *find_opt_by_keyword(smartlist_t *s, directory_keyword keyword); smartlist_t * find_all_by_keyword(const smartlist_t *s, directory_keyword k); -#endif /* TOR_PARSECOMMON_H */ +#endif /* !defined(TOR_PARSECOMMON_H) */ diff --git a/src/or/periodic.h b/src/or/periodic.h index 88d00cc7e9..8baf3994eb 100644 --- a/src/or/periodic.h +++ b/src/or/periodic.h @@ -33,5 +33,5 @@ void periodic_event_setup(periodic_event_item_t *event); void periodic_event_destroy(periodic_event_item_t *event); void periodic_event_reschedule(periodic_event_item_t *event); -#endif +#endif /* !defined(TOR_PERIODIC_H) */ diff --git a/src/or/policies.h b/src/or/policies.h index ce08d497e9..52ff4e2f99 100644 --- a/src/or/policies.h +++ b/src/or/policies.h @@ -141,7 +141,7 @@ STATIC const tor_addr_port_t * fascist_firewall_choose_address( firewall_connection_t fw_connection, int pref_only, int pref_ipv6); -#endif +#endif /* defined(POLICIES_PRIVATE) */ -#endif +#endif /* !defined(TOR_POLICIES_H) */ diff --git a/src/or/proto_cell.h b/src/or/proto_cell.h index 91729a391e..bbc14b9a02 100644 --- a/src/or/proto_cell.h +++ b/src/or/proto_cell.h @@ -13,5 +13,5 @@ struct var_cell_t; int fetch_var_cell_from_buf(struct buf_t *buf, struct var_cell_t **out, int linkproto); -#endif +#endif /* !defined(TOR_PROTO_CELL_H) */ diff --git a/src/or/proto_control0.h b/src/or/proto_control0.h index 6df6bebaa5..0cc8eacad0 100644 --- a/src/or/proto_control0.h +++ b/src/or/proto_control0.h @@ -10,5 +10,5 @@ struct buf_t; int peek_buf_has_control0_command(struct buf_t *buf); -#endif +#endif /* !defined(TOR_PROTO_CONTROL0_H) */ diff --git a/src/or/proto_ext_or.h b/src/or/proto_ext_or.h index 2ef185356c..cc504d18e3 100644 --- a/src/or/proto_ext_or.h +++ b/src/or/proto_ext_or.h @@ -13,5 +13,5 @@ struct ext_or_cmt_t; int fetch_ext_or_command_from_buf(struct buf_t *buf, struct ext_or_cmd_t **out); -#endif +#endif /* !defined(TOR_PROTO_EXT_OR_H) */ diff --git a/src/or/proto_http.h b/src/or/proto_http.h index dbff823cce..805686070f 100644 --- a/src/or/proto_http.h +++ b/src/or/proto_http.h @@ -20,5 +20,5 @@ STATIC int buf_http_find_content_length(const char *headers, size_t headerlen, size_t *result_out); #endif -#endif +#endif /* !defined(TOR_PROTO_HTTP_H) */ diff --git a/src/or/proto_socks.h b/src/or/proto_socks.h index 4a24773199..a714151414 100644 --- a/src/or/proto_socks.h +++ b/src/or/proto_socks.h @@ -16,5 +16,5 @@ int fetch_from_buf_socks(struct buf_t *buf, socks_request_t *req, int log_sockstype, int safe_socks); int fetch_from_buf_socks_client(buf_t *buf, int state, char **reason); -#endif +#endif /* !defined(TOR_PROTO_SOCKS_H) */ diff --git a/src/or/protover.h b/src/or/protover.h index ec8da1a0d0..657977279e 100644 --- a/src/or/protover.h +++ b/src/or/protover.h @@ -75,7 +75,7 @@ STATIC void proto_entry_free(proto_entry_t *entry); STATIC char *encode_protocol_list(const smartlist_t *sl); STATIC const char *protocol_type_to_str(protocol_type_t pr); STATIC int str_to_protocol_type(const char *s, protocol_type_t *pr_out); -#endif +#endif /* defined(PROTOVER_PRIVATE) */ -#endif +#endif /* !defined(TOR_PROTOVER_H) */ diff --git a/src/or/reasons.c b/src/or/reasons.c index 717cf57c24..03d49418da 100644 --- a/src/or/reasons.c +++ b/src/or/reasons.c @@ -167,7 +167,7 @@ stream_end_reason_to_socks5_response(int reason) #else #define E_CASE(s) case s #define S_CASE(s) case s -#endif +#endif /* defined(_WIN32) */ /** Given an errno from a failed exit connection, return a reason code * appropriate for use in a RELAY END cell. */ diff --git a/src/or/reasons.h b/src/or/reasons.h index f98db55bdd..3d6ba8fc83 100644 --- a/src/or/reasons.h +++ b/src/or/reasons.h @@ -28,5 +28,5 @@ const char *socks5_response_code_to_string(uint8_t code); const char *bandwidth_weight_rule_to_string(enum bandwidth_weight_rule_t rule); const char *end_reason_to_http_connect_response_line(int endreason); -#endif +#endif /* !defined(TOR_REASONS_H) */ diff --git a/src/or/relay.c b/src/or/relay.c index c00afc8e72..2bfec342d3 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -818,7 +818,7 @@ connection_edge_send_command(edge_connection_t *fromconn, if (linked_conn && linked_conn->type == CONN_TYPE_DIR) { ++(TO_DIR_CONN(linked_conn)->data_cells_sent); } -#endif +#endif /* defined(MEASUREMENTS_21206) */ return relay_send_command_from_edge(fromconn->stream_id, circ, relay_command, payload, @@ -1685,7 +1685,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, if (linked_conn && linked_conn->type == CONN_TYPE_DIR) { ++(TO_DIR_CONN(linked_conn)->data_cells_received); } -#endif +#endif /* defined(MEASUREMENTS_21206) */ if (!optimistic_data) { /* Only send a SENDME if we're not getting optimistic data; otherwise @@ -2383,7 +2383,7 @@ circuit_consider_sending_sendme(circuit_t *circ, crypt_path_t *layer_hint) assert_circuit_mux_okay(chan) #else #define assert_cmux_ok_paranoid(chan) -#endif +#endif /* defined(ACTIVE_CIRCUITS_PARANOIA) */ /** The total number of cells we have allocated. */ static size_t total_cells_allocated = 0; @@ -2851,7 +2851,7 @@ get_max_middle_cells(void) { return ORCIRC_MAX_MIDDLE_CELLS; } -#endif +#endif /* 0 */ /** Add <b>cell</b> to the queue of <b>circ</b> writing to <b>chan</b> * transmitting in <b>direction</b>. */ @@ -2961,7 +2961,7 @@ append_cell_to_circuit_queue(circuit_t *circ, channel_t *chan, } } } -#endif +#endif /* 0 */ cell_queue_append_packed_copy(circ, queue, exitward, cell, chan->wide_circ_ids, 1); diff --git a/src/or/relay.h b/src/or/relay.h index a160cd5551..2412dcb23c 100644 --- a/src/or/relay.h +++ b/src/or/relay.h @@ -104,7 +104,7 @@ STATIC packed_cell_t *packed_cell_new(void); STATIC packed_cell_t *cell_queue_pop(cell_queue_t *queue); STATIC size_t cell_queues_get_total_allocation(void); STATIC int cell_queues_check_size(void); -#endif +#endif /* defined(RELAY_PRIVATE) */ -#endif +#endif /* !defined(TOR_RELAY_H) */ diff --git a/src/or/rendcache.h b/src/or/rendcache.h index 1bd3be2243..5b13eadfa1 100644 --- a/src/or/rendcache.h +++ b/src/or/rendcache.h @@ -115,8 +115,8 @@ extern strmap_t *rend_cache; extern strmap_t *rend_cache_failure; extern digestmap_t *rend_cache_v2_dir; extern size_t rend_cache_total_allocation; -#endif -#endif +#endif /* defined(TOR_UNIT_TESTS) */ +#endif /* defined(RENDCACHE_PRIVATE) */ -#endif /* TOR_RENDCACHE_H */ +#endif /* !defined(TOR_RENDCACHE_H) */ diff --git a/src/or/rendclient.c b/src/or/rendclient.c index 55f79c50fb..3274819241 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -440,7 +440,7 @@ directory_get_from_hs_dir(const char *desc_id, const int how_to_fetch = tor2web_mode ? DIRIND_ONEHOP : DIRIND_ANONYMOUS; #else const int how_to_fetch = DIRIND_ANONYMOUS; -#endif +#endif /* defined(ENABLE_TOR2WEB_MODE) */ tor_assert(desc_id); tor_assert(rend_query); @@ -1218,7 +1218,7 @@ rend_client_allow_non_anonymous_connection(const or_options_t *options) #else (void)options; return 0; -#endif +#endif /* defined(NON_ANONYMOUS_MODE_ENABLED) */ } /* At compile-time, was non-anonymous mode enabled via @@ -1233,6 +1233,6 @@ rend_client_non_anonymous_mode_enabled(const or_options_t *options) return 1; #else return 0; -#endif +#endif /* defined(NON_ANONYMOUS_MODE_ENABLED) */ } diff --git a/src/or/rendclient.h b/src/or/rendclient.h index ac0503bade..e8495ce09c 100644 --- a/src/or/rendclient.h +++ b/src/or/rendclient.h @@ -50,5 +50,5 @@ void rend_service_authorization_free_all(void); int rend_client_allow_non_anonymous_connection(const or_options_t *options); int rend_client_non_anonymous_mode_enabled(const or_options_t *options); -#endif +#endif /* !defined(TOR_RENDCLIENT_H) */ diff --git a/src/or/rendcommon.h b/src/or/rendcommon.h index af8dd60099..c35d7272fd 100644 --- a/src/or/rendcommon.h +++ b/src/or/rendcommon.h @@ -68,7 +68,7 @@ void assert_circ_anonymity_ok(const origin_circuit_t *circ, STATIC int rend_desc_v2_is_parsable(rend_encoded_v2_service_descriptor_t *desc); -#endif +#endif /* defined(RENDCOMMON_PRIVATE) */ -#endif +#endif /* !defined(TOR_RENDCOMMON_H) */ diff --git a/src/or/rendmid.h b/src/or/rendmid.h index daf9e2885e..6cc1fc8d95 100644 --- a/src/or/rendmid.h +++ b/src/or/rendmid.h @@ -21,5 +21,5 @@ int rend_mid_establish_rendezvous(or_circuit_t *circ, const uint8_t *request, int rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request, size_t request_len); -#endif +#endif /* !defined(TOR_RENDMID_H) */ diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 02240a7e06..f67e332b7f 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -1459,7 +1459,7 @@ rend_service_load_keys(rend_service_t *s) log_warn(LD_FS,"Unable to make hidden hostname file %s group-readable.", fname); } -#endif +#endif /* !defined(_WIN32) */ /* If client authorization is configured, load or generate keys. */ if (s->auth_type != REND_NO_AUTH) { @@ -4370,5 +4370,5 @@ set_rend_rend_service_staging_list(smartlist_t *new_list) rend_service_staging_list = new_list; } -#endif /* TOR_UNIT_TESTS */ +#endif /* defined(TOR_UNIT_TESTS) */ diff --git a/src/or/rendservice.h b/src/or/rendservice.h index ed1044f04a..5946e31861 100644 --- a/src/or/rendservice.h +++ b/src/or/rendservice.h @@ -131,9 +131,9 @@ STATIC void set_rend_service_list(smartlist_t *new_list); STATIC void set_rend_rend_service_staging_list(smartlist_t *new_list); STATIC void rend_service_prune_list_impl_(void); -#endif /* TOR_UNIT_TESTS */ +#endif /* defined(TOR_UNIT_TESTS) */ -#endif /* RENDSERVICE_PRIVATE */ +#endif /* defined(RENDSERVICE_PRIVATE) */ int rend_num_services(void); int rend_config_service(const config_line_t *line_, @@ -214,5 +214,5 @@ int rend_service_allow_non_anonymous_connection(const or_options_t *options); int rend_service_reveal_startup_time(const or_options_t *options); int rend_service_non_anonymous_mode_enabled(const or_options_t *options); -#endif +#endif /* !defined(TOR_RENDSERVICE_H) */ diff --git a/src/or/rephist.c b/src/or/rephist.c index ae45c5023a..51e800bc31 100644 --- a/src/or/rephist.c +++ b/src/or/rephist.c @@ -947,9 +947,9 @@ rep_hist_record_mtbf_data(time_t now, int missing_means_down) base16_encode(dbuf, sizeof(dbuf), digest, DIGEST_LEN); if (missing_means_down && hist->start_of_run && - !router_get_by_id_digest(digest)) { + !connection_or_digest_is_known_relay(digest)) { /* We think this relay is running, but it's not listed in our - * routerlist. Somehow it fell out without telling us it went + * consensus. Somehow it fell out without telling us it went * down. Complain and also correct it. */ log_info(LD_HIST, "Relay '%s' is listed as up in rephist, but it's not in " diff --git a/src/or/rephist.h b/src/or/rephist.h index 8f6d46616d..496e366865 100644 --- a/src/or/rephist.h +++ b/src/or/rephist.h @@ -143,5 +143,5 @@ void rep_hist_reset_padding_counts(void); void rep_hist_prep_published_padding_counts(time_t now); void rep_hist_padding_count_timers(uint64_t num_timers); -#endif +#endif /* !defined(TOR_REPHIST_H) */ diff --git a/src/or/replaycache.h b/src/or/replaycache.h index 0d637939a4..1cae3497ae 100644 --- a/src/or/replaycache.h +++ b/src/or/replaycache.h @@ -29,7 +29,7 @@ struct replaycache_s { digest256map_t *digests_seen; }; -#endif /* REPLAYCACHE_PRIVATE */ +#endif /* defined(REPLAYCACHE_PRIVATE) */ /* replaycache_t free/new */ @@ -51,7 +51,7 @@ STATIC int replaycache_add_and_test_internal( STATIC void replaycache_scrub_if_needed_internal( time_t present, replaycache_t *r); -#endif /* REPLAYCACHE_PRIVATE */ +#endif /* defined(REPLAYCACHE_PRIVATE) */ /* * replaycache_t methods @@ -62,5 +62,5 @@ int replaycache_add_test_and_elapsed( replaycache_t *r, const void *data, size_t len, time_t *elapsed); void replaycache_scrub_if_needed(replaycache_t *r); -#endif +#endif /* !defined(TOR_REPLAYCACHE_H) */ diff --git a/src/or/router.c b/src/or/router.c index 2bc7a875f1..172531e70e 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1945,7 +1945,7 @@ router_compare_to_my_exit_policy(const tor_addr_t *addr, uint16_t port) desc_routerinfo->ipv6_exit_policy && compare_tor_addr_to_short_policy(addr, port, me->ipv6_exit_policy) != ADDR_POLICY_ACCEPTED; -#endif +#endif /* 0 */ } else { return -1; } @@ -3047,7 +3047,7 @@ router_dump_router_to_string(routerinfo_t *router, tor_free(s_dup); routerinfo_free(ri_tmp); } -#endif +#endif /* defined(DEBUG_ROUTER_DUMP_ROUTER_TO_STRING) */ goto done; @@ -3607,7 +3607,7 @@ routerstatus_describe(const routerstatus_t *rs) return routerstatus_get_description(buf, rs); } -/** Return a human-readable description of the extend_info_t <b>ri</b>. +/** Return a human-readable description of the extend_info_t <b>ei</b>. * * This function is not thread-safe. Each call to this function invalidates * previous values returned by this function. diff --git a/src/or/router.h b/src/or/router.h index 97f331713a..3351400911 100644 --- a/src/or/router.h +++ b/src/or/router.h @@ -160,5 +160,5 @@ STATIC void get_platform_str(char *platform, size_t len); STATIC int router_write_fingerprint(int hashed); #endif -#endif +#endif /* !defined(TOR_ROUTER_H) */ diff --git a/src/or/routerkeys.c b/src/or/routerkeys.c index 4822ff3be3..7295c19653 100644 --- a/src/or/routerkeys.c +++ b/src/or/routerkeys.c @@ -1134,7 +1134,7 @@ init_mock_ed_keys(const crypto_pk_t *rsa_identity_key) } #undef MAKEKEY #undef MAKECERT -#endif +#endif /* defined(TOR_UNIT_TESTS) */ /** * Print the ISO8601-formated <b>expiration</b> for a certificate with @@ -1262,7 +1262,7 @@ get_master_identity_keypair(void) { return master_identity_key; } -#endif +#endif /* defined(TOR_UNIT_TESTS) */ const ed25519_keypair_t * get_master_signing_keypair(void) diff --git a/src/or/routerkeys.h b/src/or/routerkeys.h index 0cf13e7600..3e67952ea0 100644 --- a/src/or/routerkeys.h +++ b/src/or/routerkeys.h @@ -81,5 +81,5 @@ const ed25519_keypair_t *get_master_identity_keypair(void); void init_mock_ed_keys(const crypto_pk_t *rsa_identity_key); #endif -#endif +#endif /* !defined(TOR_ROUTERKEYS_H) */ diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 9111d93c3c..9b056e80aa 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1872,7 +1872,7 @@ router_picked_poor_directory_log(const routerstatus_t *rs) || !router_have_minimum_dir_info()) { return; } -#endif +#endif /* !LOG_FALSE_POSITIVES_DURING_BOOTSTRAP */ /* We couldn't find a node, or the one we have doesn't fit our preferences. * Sometimes this is normal, sometimes it can be a reachability issue. */ @@ -4052,7 +4052,7 @@ routerlist_remove_old_cached_routers_with_id(time_t now, signed_descriptor_t *r = smartlist_get(lst, i); tor_assert(tor_memeq(ident, r->identity_digest, DIGEST_LEN)); } -#endif +#endif /* 1 */ /* Check whether we need to do anything at all. */ { int mdpr = directory_caches_dir_info(get_options()) ? 2 : 1; diff --git a/src/or/routerlist.h b/src/or/routerlist.h index 27c8d88f05..8384c7eb8c 100644 --- a/src/or/routerlist.h +++ b/src/or/routerlist.h @@ -251,7 +251,7 @@ MOCK_DECL(STATIC void, initiate_descriptor_downloads, STATIC int router_is_already_dir_fetching(const tor_addr_port_t *ap, int serverdesc, int microdesc); -#endif +#endif /* defined(ROUTERLIST_PRIVATE) */ -#endif +#endif /* !defined(TOR_ROUTERLIST_H) */ diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 7a58dd5056..15cdb0bbde 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -388,9 +388,9 @@ static int check_signature_token(const char *digest, log_debug(LD_MM, "Area for %s has %lu allocated; using %lu.", \ name, (unsigned long)alloc, (unsigned long)used); \ STMT_END -#else +#else /* !(defined(DEBUG_AREA_ALLOC)) */ #define DUMP_AREA(a,name) STMT_NIL -#endif +#endif /* defined(DEBUG_AREA_ALLOC) */ /* Dump mechanism for unparseable descriptors */ @@ -701,7 +701,7 @@ dump_desc_populate_one_file, (const char *dirname, const char *f)) goto done; /* LCOV_EXCL_STOP */ } -#endif +#endif /* SIZE_MAX > UINT64_MAX */ if (BUG(st.st_size < 0)) { /* LCOV_EXCL_START * Should be impossible, since the OS isn't supposed to be b0rken. */ @@ -1425,9 +1425,9 @@ dump_distinct_digest_count(int severity) verified_digests = digestmap_new(); tor_log(severity, LD_GENERAL, "%d *distinct* router digests verified", digestmap_size(verified_digests)); -#else +#else /* !(defined(COUNT_DISTINCT_DIGESTS)) */ (void)severity; /* suppress "unused parameter" warning */ -#endif +#endif /* defined(COUNT_DISTINCT_DIGESTS) */ } /** Try to find an IPv6 OR port in <b>list</b> of directory_token_t's diff --git a/src/or/routerparse.h b/src/or/routerparse.h index 088f773c5e..c4c8635f4b 100644 --- a/src/or/routerparse.h +++ b/src/or/routerparse.h @@ -133,9 +133,9 @@ MOCK_DECL(STATIC int, router_compute_hash_final,(char *digest, digest_algorithm_t alg)); MOCK_DECL(STATIC int, signed_digest_equals, (const uint8_t *d1, const uint8_t *d2, size_t len)); -#endif +#endif /* defined(ROUTERPARSE_PRIVATE) */ #define ED_DESC_SIGNATURE_PREFIX "Tor router descriptor signature v1" -#endif +#endif /* !defined(TOR_ROUTERPARSE_H) */ diff --git a/src/or/routerset.h b/src/or/routerset.h index a63677b471..d8819ef3fd 100644 --- a/src/or/routerset.h +++ b/src/or/routerset.h @@ -82,6 +82,6 @@ struct routerset_t { * reloaded. */ bitarray_t *countries; }; -#endif -#endif +#endif /* defined(ROUTERSET_PRIVATE) */ +#endif /* !defined(TOR_ROUTERSET_H) */ diff --git a/src/or/scheduler.c b/src/or/scheduler.c index 0d31c7d58c..2d6f7fc4bd 100644 --- a/src/or/scheduler.c +++ b/src/or/scheduler.c @@ -2,45 +2,50 @@ /* See LICENSE for licensing information */ #include "or.h" - -#define TOR_CHANNEL_INTERNAL_ /* For channel_flush_some_cells() */ -#include "channel.h" +#include "config.h" #include "compat_libevent.h" #define SCHEDULER_PRIVATE_ +#define SCHEDULER_KIST_PRIVATE #include "scheduler.h" #include <event2/event.h> -/* - * Scheduler high/low watermarks - */ - -static uint32_t sched_q_low_water = 16384; -static uint32_t sched_q_high_water = 32768; - -/* - * Maximum cells to flush in a single call to channel_flush_some_cells(); - * setting this low means more calls, but too high and we could overshoot - * sched_q_high_water. - */ - -static uint32_t sched_max_flush_cells = 16; - /** * \file scheduler.c * \brief Channel scheduling system: decides which channels should send and * receive when. * - * This module implements a scheduler algorithm, to decide - * which channels should send/receive when. + * This module is the global/common parts of the scheduling system. This system + * is what decides what channels get to send cells on their circuits and when. + * + * Terms: + * - "Scheduling system": the collection of scheduler*.{h,c} files and their + * aggregate behavior. + * - "Scheduler implementation": a scheduler_t. The scheduling system has one + * active scheduling implementation at a time. + * + * In this file you will find state that any scheduler implmentation can have + * access to as well as the functions the rest of Tor uses to interact with the + * scheduling system. * * The earliest versions of Tor approximated a kind of round-robin system - * among active connections, but only approximated it. + * among active connections, but only approximated it. It would only consider + * one connection (roughly equal to a channel in today's terms) at a time, and + * thus could only prioritize circuits against others on the same connection. + * + * Then in response to the KIST paper[0], Tor implemented a global + * circuit scheduler. It was supposed to prioritize circuits across man + * channels, but wasn't effective. It is preserved in scheduler_vanilla.c. * - * Now, write scheduling works by keeping track of which channels can - * accept cells, and have cells to write. From the scheduler's perspective, - * a channel can be in four possible states: + * [0]: http://www.robgjansen.com/publications/kist-sec2014.pdf + * + * Then we actually got around to implementing KIST for real. We decided to + * modularize the scheduler so new ones can be implemented. You can find KIST + * in scheduler_kist.c. + * + * Channels have one of four scheduling states based on whether or not they + * have cells to send and whether or not they are able to send. * * <ol> * <li> @@ -125,85 +130,96 @@ static uint32_t sched_max_flush_cells = 16; * </ol> * * Other event-driven parts of the code move channels between these scheduling - * states by calling scheduler functions; the scheduler only runs on open-for- - * writes/has-cells channels and is the only path for those to transition to - * other states. The scheduler_run() function gives us the opportunity to do - * scheduling work, and is called from other scheduler functions whenever a - * state transition occurs, and periodically from the main event loop. + * states by calling scheduler functions. The scheduling system builds up a + * list of channels in the SCHED_CHAN_PENDING state that the scheduler + * implementation should then use when it runs. Scheduling implementations need + * to properly update channel states during their scheduler_t->run() function + * as that is the only opportunity for channels to move from SCHED_CHAN_PENDING + * to any other state. + * + * The remainder of this file is a small amount of state that any scheduler + * implementation should have access to, and the functions the rest of Tor uses + * to interact with the scheduling system. */ -/* Scheduler global data structures */ +/***************************************************************************** + * Scheduling system state + * + * State that can be accessed from any scheduler implementation (but not + * outside the scheduling system) + *****************************************************************************/ + +STATIC const scheduler_t *the_scheduler; /* * We keep a list of channels that are pending - i.e, have cells to write - * and can accept them to send. The enum scheduler_state in channel_t + * and can accept them to send. The enum scheduler_state in channel_t * is reserved for our use. + * + * Priority queue of channels that can write and have cells (pending work) */ - -/* Pqueue of channels that can write and have cells (pending work) */ STATIC smartlist_t *channels_pending = NULL; /* * This event runs the scheduler from its callback, and is manually * activated whenever a channel enters open for writes/cells to send. */ - STATIC struct event *run_sched_ev = NULL; -/* - * Queue heuristic; this is not the queue size, but an 'effective queuesize' - * that ages out contributions from stalled channels. - */ - -STATIC uint64_t queue_heuristic = 0; +/***************************************************************************** + * Scheduling system static function definitions + * + * Functions that can only be accessed from this file. + *****************************************************************************/ /* - * Timestamp for last queue heuristic update + * Scheduler event callback; this should get triggered once per event loop + * if any scheduling work was created during the event loop. */ +static void +scheduler_evt_callback(evutil_socket_t fd, short events, void *arg) +{ + (void) fd; + (void) events; + (void) arg; -STATIC time_t queue_heuristic_timestamp = 0; - -/* Scheduler static function declarations */ + log_debug(LD_SCHED, "Scheduler event callback called"); -static void scheduler_evt_callback(evutil_socket_t fd, - short events, void *arg); -static int scheduler_more_work(void); -static void scheduler_retrigger(void); -#if 0 -static void scheduler_trigger(void); -#endif + /* Run the scheduler. This is a mandatory function. */ -/* Scheduler function implementations */ + /* We might as well assert on this. If this function doesn't exist, no cells + * are getting scheduled. Things are very broken. scheduler_t says the run() + * function is mandatory. */ + tor_assert(the_scheduler->run); + the_scheduler->run(); -/** Free everything and shut down the scheduling system */ + /* Schedule itself back in if it has more work. */ -void -scheduler_free_all(void) -{ - log_debug(LD_SCHED, "Shutting down scheduler"); + /* Again, might as well assert on this mandatory scheduler_t function. If it + * doesn't exist, there's no way to tell libevent to run the scheduler again + * in the future. */ + tor_assert(the_scheduler->schedule); + the_scheduler->schedule(); +} - if (run_sched_ev) { - if (event_del(run_sched_ev) < 0) { - log_warn(LD_BUG, "Problem deleting run_sched_ev"); - } - tor_event_free(run_sched_ev); - run_sched_ev = NULL; - } +/***************************************************************************** + * Scheduling system private function definitions + * + * Functions that can only be accessed from scheduler*.c + *****************************************************************************/ - if (channels_pending) { - smartlist_free(channels_pending); - channels_pending = NULL; - } +/* Return the pending channel list. */ +smartlist_t * +get_channels_pending(void) +{ + return channels_pending; } -/** - * Comparison function to use when sorting pending channels - */ - -MOCK_IMPL(STATIC int, +/* Comparison function to use when sorting pending channels */ +MOCK_IMPL(int, scheduler_compare_channels, (const void *c1_v, const void *c2_v)) { - channel_t *c1 = NULL, *c2 = NULL; + const channel_t *c1 = NULL, *c2 = NULL; /* These are a workaround for -Wbad-function-cast throwing a fit */ const circuitmux_policy_t *p1, *p2; uintptr_t p1_i, p2_i; @@ -211,11 +227,8 @@ scheduler_compare_channels, (const void *c1_v, const void *c2_v)) tor_assert(c1_v); tor_assert(c2_v); - c1 = (channel_t *)(c1_v); - c2 = (channel_t *)(c2_v); - - tor_assert(c1); - tor_assert(c2); + c1 = (const channel_t *)(c1_v); + c2 = (const channel_t *)(c2_v); if (c1 != c2) { if (circuitmux_get_policy(c1->cmux) == @@ -242,26 +255,158 @@ scheduler_compare_channels, (const void *c1_v, const void *c2_v)) } } +/***************************************************************************** + * Scheduling system global functions + * + * Functions that can be accessed from anywhere in Tor. + *****************************************************************************/ + +/* Using the global options, select the scheduler we should be using. */ +static void +select_scheduler(void) +{ + const char *chosen_sched_type = NULL; + +#ifdef TOR_UNIT_TESTS + /* This is hella annoying to set in the options for every test that passes + * through the scheduler and there are many so if we don't explicitely have + * a list of types set, just put the vanilla one. */ + if (get_options()->SchedulerTypes_ == NULL) { + the_scheduler = get_vanilla_scheduler(); + return; + } +#endif /* defined(TOR_UNIT_TESTS) */ + + /* This list is ordered that is first entry has the first priority. Thus, as + * soon as we find a scheduler type that we can use, we use it and stop. */ + SMARTLIST_FOREACH_BEGIN(get_options()->SchedulerTypes_, int *, type) { + switch (*type) { + case SCHEDULER_VANILLA: + the_scheduler = get_vanilla_scheduler(); + chosen_sched_type = "Vanilla"; + goto end; + case SCHEDULER_KIST: + if (!scheduler_can_use_kist()) { +#ifdef HAVE_KIST_SUPPORT + if (get_options()->KISTSchedRunInterval == -1) { + log_info(LD_SCHED, "Scheduler type KIST can not be used. It is " + "disabled because KISTSchedRunInterval=-1"); + } else { + log_notice(LD_SCHED, "Scheduler type KIST has been disabled by " + "the consensus."); + } +#else /* !(defined(HAVE_KIST_SUPPORT)) */ + log_info(LD_SCHED, "Scheduler type KIST not built in"); +#endif /* defined(HAVE_KIST_SUPPORT) */ + continue; + } + the_scheduler = get_kist_scheduler(); + chosen_sched_type = "KIST"; + scheduler_kist_set_full_mode(); + goto end; + case SCHEDULER_KIST_LITE: + chosen_sched_type = "KISTLite"; + the_scheduler = get_kist_scheduler(); + scheduler_kist_set_lite_mode(); + goto end; + default: + /* Our option validation should have caught this. */ + tor_assert_unreached(); + } + } SMARTLIST_FOREACH_END(type); + + end: + log_notice(LD_CONFIG, "Scheduler type %s has been enabled.", + chosen_sched_type); +} + /* - * Scheduler event callback; this should get triggered once per event loop - * if any scheduling work was created during the event loop. + * Little helper function called from a few different places. It changes the + * scheduler implementation, if necessary. And if it did, it then tells the + * old one to free its state and the new one to initialize. */ - static void -scheduler_evt_callback(evutil_socket_t fd, short events, void *arg) +set_scheduler(void) { - (void)fd; - (void)events; - (void)arg; - log_debug(LD_SCHED, "Scheduler event callback called"); + const scheduler_t *old_scheduler = the_scheduler; - tor_assert(run_sched_ev); + /* From the options, select the scheduler type to set. */ + select_scheduler(); - /* Run the scheduler */ - scheduler_run(); + if (old_scheduler != the_scheduler) { + /* Allow the old scheduler to clean up, if needed. */ + if (old_scheduler && old_scheduler->free_all) { + old_scheduler->free_all(); + } + /* We don't clean up the old scheduler_t. We keep any type of scheduler + * we've allocated so we can do an easy switch back. */ - /* Do we have more work to do? */ - if (scheduler_more_work()) scheduler_retrigger(); + /* Initialize the new scheduler. */ + if (the_scheduler->init) { + the_scheduler->init(); + } + } +} + +/* + * This is how the scheduling system is notified of Tor's configuration + * changing. For example: a SIGHUP was issued. + */ +void +scheduler_conf_changed(void) +{ + /* Let the scheduler decide what it should do. */ + set_scheduler(); + + /* Then tell the (possibly new) scheduler that we have new options. */ + if (the_scheduler->on_new_options) { + the_scheduler->on_new_options(); + } +} + +/* + * Whenever we get a new consensus, this function is called. + */ +void +scheduler_notify_networkstatus_changed(const networkstatus_t *old_c, + const networkstatus_t *new_c) +{ + /* Then tell the (possibly new) scheduler that we have a new consensus */ + if (the_scheduler->on_new_consensus) { + the_scheduler->on_new_consensus(old_c, new_c); + } + /* Maybe the consensus param made us change the scheduler. */ + set_scheduler(); +} + +/* + * Free everything scheduling-related from main.c. Note this is only called + * when Tor is shutting down, while scheduler_t->free_all() is called both when + * Tor is shutting down and when we are switching schedulers. + */ +void +scheduler_free_all(void) +{ + log_debug(LD_SCHED, "Shutting down scheduler"); + + if (run_sched_ev) { + if (event_del(run_sched_ev) < 0) { + log_warn(LD_BUG, "Problem deleting run_sched_ev"); + } + tor_event_free(run_sched_ev); + run_sched_ev = NULL; + } + + if (channels_pending) { + /* We don't have ownership of the object in this list. */ + smartlist_free(channels_pending); + channels_pending = NULL; + } + + if (the_scheduler && the_scheduler->free_all) { + the_scheduler->free_all(); + } + the_scheduler = NULL; } /** Mark a channel as no longer ready to accept writes */ @@ -269,9 +414,12 @@ scheduler_evt_callback(evutil_socket_t fd, short events, void *arg) MOCK_IMPL(void, scheduler_channel_doesnt_want_writes,(channel_t *chan)) { - tor_assert(chan); - - tor_assert(channels_pending); + IF_BUG_ONCE(!chan) { + return; + } + IF_BUG_ONCE(!channels_pending) { + return; + } /* If it's already in pending, we can put it in waiting_to_write */ if (chan->scheduler_state == SCHED_CHAN_PENDING) { @@ -309,10 +457,12 @@ scheduler_channel_doesnt_want_writes,(channel_t *chan)) MOCK_IMPL(void, scheduler_channel_has_waiting_cells,(channel_t *chan)) { - int became_pending = 0; - - tor_assert(chan); - tor_assert(channels_pending); + IF_BUG_ONCE(!chan) { + return; + } + IF_BUG_ONCE(!channels_pending) { + return; + } /* First, check if this one also writeable */ if (chan->scheduler_state == SCHED_CHAN_WAITING_FOR_CELLS) { @@ -330,7 +480,9 @@ scheduler_channel_has_waiting_cells,(channel_t *chan)) "Channel " U64_FORMAT " at %p went from waiting_for_cells " "to pending", U64_PRINTF_ARG(chan->global_identifier), chan); - became_pending = 1; + /* If we made a channel pending, we potentially have scheduling work to + * do. */ + the_scheduler->schedule(); } else { /* * It's not in waiting_for_cells, so it can't become pending; it's @@ -345,240 +497,104 @@ scheduler_channel_has_waiting_cells,(channel_t *chan)) U64_PRINTF_ARG(chan->global_identifier), chan); } } +} - /* - * If we made a channel pending, we potentially have scheduling work - * to do. - */ - if (became_pending) scheduler_retrigger(); +/* Add the scheduler event to the set of pending events with next_run being + * the time up to libevent should wait before triggering the event. */ +void +scheduler_ev_add(const struct timeval *next_run) +{ + tor_assert(run_sched_ev); + tor_assert(next_run); + event_add(run_sched_ev, next_run); } -/** Set up the scheduling system */ +/* Make the scheduler event active with the given flags. */ +void +scheduler_ev_active(int flags) +{ + tor_assert(run_sched_ev); + event_active(run_sched_ev, flags, 1); +} +/* + * Initialize everything scheduling-related from config.c. Note this is only + * called when Tor is starting up, while scheduler_t->init() is called both + * when Tor is starting up and when we are switching schedulers. + */ void scheduler_init(void) { log_debug(LD_SCHED, "Initting scheduler"); - tor_assert(!run_sched_ev); + // Two '!' because we really do want to check if the pointer is non-NULL + IF_BUG_ONCE(!!run_sched_ev) { + log_warn(LD_SCHED, "We should not already have a libevent scheduler event." + "I'll clean the old one up, but this is odd."); + tor_event_free(run_sched_ev); + run_sched_ev = NULL; + } run_sched_ev = tor_event_new(tor_libevent_get_base(), -1, 0, scheduler_evt_callback, NULL); - channels_pending = smartlist_new(); - queue_heuristic = 0; - queue_heuristic_timestamp = approx_time(); -} - -/** Check if there's more scheduling work */ - -static int -scheduler_more_work(void) -{ - tor_assert(channels_pending); - return ((scheduler_get_queue_heuristic() < sched_q_low_water) && - ((smartlist_len(channels_pending) > 0))) ? 1 : 0; + set_scheduler(); } -/** Retrigger the scheduler in a way safe to use from the callback */ - -static void -scheduler_retrigger(void) -{ - tor_assert(run_sched_ev); - event_active(run_sched_ev, EV_TIMEOUT, 1); -} - -/** Notify the scheduler of a channel being closed */ - +/* + * If a channel is going away, this is how the scheduling system is informed + * so it can do any freeing necessary. This ultimately calls + * scheduler_t->on_channel_free() so the current scheduler can release any + * state specific to this channel. + */ MOCK_IMPL(void, scheduler_release_channel,(channel_t *chan)) { - tor_assert(chan); - tor_assert(channels_pending); - - if (chan->scheduler_state == SCHED_CHAN_PENDING) { - smartlist_pqueue_remove(channels_pending, - scheduler_compare_channels, - offsetof(channel_t, sched_heap_idx), - chan); + IF_BUG_ONCE(!chan) { + return; + } + IF_BUG_ONCE(!channels_pending) { + return; } - chan->scheduler_state = SCHED_CHAN_IDLE; -} - -/** Run the scheduling algorithm if necessary */ - -MOCK_IMPL(void, -scheduler_run, (void)) -{ - int n_cells, n_chans_before, n_chans_after; - uint64_t q_len_before, q_heur_before, q_len_after, q_heur_after; - ssize_t flushed, flushed_this_time; - smartlist_t *to_readd = NULL; - channel_t *chan = NULL; - - log_debug(LD_SCHED, "We have a chance to run the scheduler"); - - if (scheduler_get_queue_heuristic() < sched_q_low_water) { - n_chans_before = smartlist_len(channels_pending); - q_len_before = channel_get_global_queue_estimate(); - q_heur_before = scheduler_get_queue_heuristic(); - - while (scheduler_get_queue_heuristic() <= sched_q_high_water && - smartlist_len(channels_pending) > 0) { - /* Pop off a channel */ - chan = smartlist_pqueue_pop(channels_pending, - scheduler_compare_channels, - offsetof(channel_t, sched_heap_idx)); - tor_assert(chan); - - /* Figure out how many cells we can write */ - n_cells = channel_num_cells_writeable(chan); - if (n_cells > 0) { - log_debug(LD_SCHED, - "Scheduler saw pending channel " U64_FORMAT " at %p with " - "%d cells writeable", - U64_PRINTF_ARG(chan->global_identifier), chan, n_cells); - - flushed = 0; - while (flushed < n_cells && - scheduler_get_queue_heuristic() <= sched_q_high_water) { - flushed_this_time = - channel_flush_some_cells(chan, - MIN(sched_max_flush_cells, - (size_t) n_cells - flushed)); - if (flushed_this_time <= 0) break; - flushed += flushed_this_time; - } - - if (flushed < n_cells) { - /* We ran out of cells to flush */ - chan->scheduler_state = SCHED_CHAN_WAITING_FOR_CELLS; - log_debug(LD_SCHED, - "Channel " U64_FORMAT " at %p " - "entered waiting_for_cells from pending", - U64_PRINTF_ARG(chan->global_identifier), - chan); - } else { - /* The channel may still have some cells */ - if (channel_more_to_flush(chan)) { - /* The channel goes to either pending or waiting_to_write */ - if (channel_num_cells_writeable(chan) > 0) { - /* Add it back to pending later */ - if (!to_readd) to_readd = smartlist_new(); - smartlist_add(to_readd, chan); - log_debug(LD_SCHED, - "Channel " U64_FORMAT " at %p " - "is still pending", - U64_PRINTF_ARG(chan->global_identifier), - chan); - } else { - /* It's waiting to be able to write more */ - chan->scheduler_state = SCHED_CHAN_WAITING_TO_WRITE; - log_debug(LD_SCHED, - "Channel " U64_FORMAT " at %p " - "entered waiting_to_write from pending", - U64_PRINTF_ARG(chan->global_identifier), - chan); - } - } else { - /* No cells left; it can go to idle or waiting_for_cells */ - if (channel_num_cells_writeable(chan) > 0) { - /* - * It can still accept writes, so it goes to - * waiting_for_cells - */ - chan->scheduler_state = SCHED_CHAN_WAITING_FOR_CELLS; - log_debug(LD_SCHED, - "Channel " U64_FORMAT " at %p " - "entered waiting_for_cells from pending", - U64_PRINTF_ARG(chan->global_identifier), - chan); - } else { - /* - * We exactly filled up the output queue with all available - * cells; go to idle. - */ - chan->scheduler_state = SCHED_CHAN_IDLE; - log_debug(LD_SCHED, - "Channel " U64_FORMAT " at %p " - "become idle from pending", - U64_PRINTF_ARG(chan->global_identifier), - chan); - } - } - } - - log_debug(LD_SCHED, - "Scheduler flushed %d cells onto pending channel " - U64_FORMAT " at %p", - (int)flushed, U64_PRINTF_ARG(chan->global_identifier), - chan); - } else { - log_info(LD_SCHED, - "Scheduler saw pending channel " U64_FORMAT " at %p with " - "no cells writeable", - U64_PRINTF_ARG(chan->global_identifier), chan); - /* Put it back to WAITING_TO_WRITE */ - chan->scheduler_state = SCHED_CHAN_WAITING_TO_WRITE; - } - } - - /* Readd any channels we need to */ - if (to_readd) { - SMARTLIST_FOREACH_BEGIN(to_readd, channel_t *, readd_chan) { - readd_chan->scheduler_state = SCHED_CHAN_PENDING; - smartlist_pqueue_add(channels_pending, - scheduler_compare_channels, - offsetof(channel_t, sched_heap_idx), - readd_chan); - } SMARTLIST_FOREACH_END(readd_chan); - smartlist_free(to_readd); + if (chan->scheduler_state == SCHED_CHAN_PENDING) { + if (smartlist_pos(channels_pending, chan) == -1) { + log_warn(LD_SCHED, "Scheduler asked to release channel %" PRIu64 " " + "but it wasn't in channels_pending", + chan->global_identifier); + } else { + smartlist_pqueue_remove(channels_pending, + scheduler_compare_channels, + offsetof(channel_t, sched_heap_idx), + chan); } - - n_chans_after = smartlist_len(channels_pending); - q_len_after = channel_get_global_queue_estimate(); - q_heur_after = scheduler_get_queue_heuristic(); - log_debug(LD_SCHED, - "Scheduler handled %d of %d pending channels, queue size from " - U64_FORMAT " to " U64_FORMAT ", queue heuristic from " - U64_FORMAT " to " U64_FORMAT, - n_chans_before - n_chans_after, n_chans_before, - U64_PRINTF_ARG(q_len_before), U64_PRINTF_ARG(q_len_after), - U64_PRINTF_ARG(q_heur_before), U64_PRINTF_ARG(q_heur_after)); } -} -/** Trigger the scheduling event so we run the scheduler later */ - -#if 0 -static void -scheduler_trigger(void) -{ - log_debug(LD_SCHED, "Triggering scheduler event"); - - tor_assert(run_sched_ev); - - event_add(run_sched_ev, EV_TIMEOUT, 1); + if (the_scheduler->on_channel_free) { + the_scheduler->on_channel_free(chan); + } + chan->scheduler_state = SCHED_CHAN_IDLE; } -#endif /** Mark a channel as ready to accept writes */ void scheduler_channel_wants_writes(channel_t *chan) { - int became_pending = 0; - - tor_assert(chan); - tor_assert(channels_pending); + IF_BUG_ONCE(!chan) { + return; + } + IF_BUG_ONCE(!channels_pending) { + return; + } /* If it's already in waiting_to_write, we can put it in pending */ if (chan->scheduler_state == SCHED_CHAN_WAITING_TO_WRITE) { /* * It can write now, so it goes to channels_pending. */ + log_debug(LD_SCHED, "chan=%" PRIu64 " became pending", + chan->global_identifier); smartlist_pqueue_add(channels_pending, scheduler_compare_channels, offsetof(channel_t, sched_heap_idx), @@ -588,7 +604,8 @@ scheduler_channel_wants_writes(channel_t *chan) "Channel " U64_FORMAT " at %p went from waiting_to_write " "to pending", U64_PRINTF_ARG(chan->global_identifier), chan); - became_pending = 1; + /* We just made a channel pending, we have scheduling work to do. */ + the_scheduler->schedule(); } else { /* * It's not in SCHED_CHAN_WAITING_TO_WRITE, so it can't become pending; @@ -602,23 +619,19 @@ scheduler_channel_wants_writes(channel_t *chan) U64_PRINTF_ARG(chan->global_identifier), chan); } } - - /* - * If we made a channel pending, we potentially have scheduling work - * to do. - */ - if (became_pending) scheduler_retrigger(); } -/** - * Notify the scheduler that a channel's position in the pqueue may have - * changed - */ +#ifdef TOR_UNIT_TESTS +/* + * Notify scheduler that a channel's queue position may have changed. + */ void scheduler_touch_channel(channel_t *chan) { - tor_assert(chan); + IF_BUG_ONCE(!chan) { + return; + } if (chan->scheduler_state == SCHED_CHAN_PENDING) { /* Remove and re-add it */ @@ -634,105 +647,5 @@ scheduler_touch_channel(channel_t *chan) /* else no-op, since it isn't in the queue */ } -/** - * Notify the scheduler of a queue size adjustment, to recalculate the - * queue heuristic. - */ - -void -scheduler_adjust_queue_size(channel_t *chan, int dir, uint64_t adj) -{ - time_t now = approx_time(); - - log_debug(LD_SCHED, - "Queue size adjustment by %s" U64_FORMAT " for channel " - U64_FORMAT, - (dir >= 0) ? "+" : "-", - U64_PRINTF_ARG(adj), - U64_PRINTF_ARG(chan->global_identifier)); - - /* Get the queue heuristic up to date */ - scheduler_update_queue_heuristic(now); - - /* Adjust as appropriate */ - if (dir >= 0) { - /* Increasing it */ - queue_heuristic += adj; - } else { - /* Decreasing it */ - if (queue_heuristic > adj) queue_heuristic -= adj; - else queue_heuristic = 0; - } - - log_debug(LD_SCHED, - "Queue heuristic is now " U64_FORMAT, - U64_PRINTF_ARG(queue_heuristic)); -} - -/** - * Query the current value of the queue heuristic - */ - -STATIC uint64_t -scheduler_get_queue_heuristic(void) -{ - time_t now = approx_time(); - - scheduler_update_queue_heuristic(now); - - return queue_heuristic; -} - -/** - * Adjust the queue heuristic value to the present time - */ - -STATIC void -scheduler_update_queue_heuristic(time_t now) -{ - time_t diff; - - if (queue_heuristic_timestamp == 0) { - /* - * Nothing we can sensibly do; must not have been initted properly. - * Oh well. - */ - queue_heuristic_timestamp = now; - } else if (queue_heuristic_timestamp < now) { - diff = now - queue_heuristic_timestamp; - /* - * This is a simple exponential age-out; the other proposed alternative - * was a linear age-out using the bandwidth history in rephist.c; I'm - * going with this out of concern that if an adversary can jam the - * scheduler long enough, it would cause the bandwidth to drop to - * zero and render the aging mechanism ineffective thereafter. - */ - if (0 <= diff && diff < 64) queue_heuristic >>= diff; - else queue_heuristic = 0; - - queue_heuristic_timestamp = now; - - log_debug(LD_SCHED, - "Queue heuristic is now " U64_FORMAT, - U64_PRINTF_ARG(queue_heuristic)); - } - /* else no update needed, or time went backward */ -} - -/** - * Set scheduler watermarks and flush size - */ - -void -scheduler_set_watermarks(uint32_t lo, uint32_t hi, uint32_t max_flush) -{ - /* Sanity assertions - caller should ensure these are true */ - tor_assert(lo > 0); - tor_assert(hi > lo); - tor_assert(max_flush > 0); - - sched_q_low_water = lo; - sched_q_high_water = hi; - sched_max_flush_cells = max_flush; -} +#endif /* defined(TOR_UNIT_TESTS) */ diff --git a/src/or/scheduler.h b/src/or/scheduler.h index e29c13de7e..3c0748fa68 100644 --- a/src/or/scheduler.h +++ b/src/or/scheduler.h @@ -1,9 +1,9 @@ -/* * Copyright (c) 2013-2017, The Tor Project, Inc. */ +/* * Copyright (c) 2017, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** * \file scheduler.h - * \brief Header file for scheduler.c + * \brief Header file for scheduler*.c **/ #ifndef TOR_SCHEDULER_H @@ -13,45 +13,192 @@ #include "channel.h" #include "testsupport.h" -/* Global-visibility scheduler functions */ +/* + * A scheduler implementation is a collection of function pointers. If you + * would like to add a new scheduler called foo, create scheduler_foo.c, + * implement at least the mandatory ones, and implement get_foo_scheduler() + * that returns a complete scheduler_t for your foo scheduler. See + * scheduler_kist.c for an example. + * + * These function pointers SHOULD NOT be used anywhere outside of the + * scheduling source files. The rest of Tor should communicate with the + * scheduling system through the functions near the bottom of this file, and + * those functions will call into the current scheduler implementation as + * necessary. + * + * If your scheduler doesn't need to implement something (for example: it + * doesn't create any state for itself, thus it has nothing to free when Tor + * is shutting down), then set that function pointer to NULL. + */ +typedef struct scheduler_s { + /* (Optional) To be called when we want to prepare a scheduler for use. + * Perhaps Tor just started and we are the lucky chosen scheduler, or + * perhaps Tor is switching to this scheduler. No matter the case, this is + * where we would prepare any state and initialize parameters. You might + * think of this as the opposite of free_all(). */ + void (*init)(void); -/* Set up and shut down the scheduler from main.c */ -void scheduler_free_all(void); -void scheduler_init(void); -MOCK_DECL(void, scheduler_run, (void)); + /* (Optional) To be called when we want to tell the scheduler to delete all + * of its state (if any). Perhaps Tor is shutting down or perhaps we are + * switching schedulers. */ + void (*free_all)(void); -/* Mark channels as having cells or wanting/not wanting writes */ -MOCK_DECL(void,scheduler_channel_doesnt_want_writes,(channel_t *chan)); -MOCK_DECL(void,scheduler_channel_has_waiting_cells,(channel_t *chan)); -void scheduler_channel_wants_writes(channel_t *chan); + /* (Mandatory) Libevent controls the main event loop in Tor, and this is + * where we register with libevent the next execution of run_sched_ev [which + * ultimately calls run()]. */ + void (*schedule)(void); -/* Notify the scheduler of a channel being closed */ -MOCK_DECL(void,scheduler_release_channel,(channel_t *chan)); + /* (Mandatory) This is the heart of a scheduler! This is where the + * excitement happens! Here libevent has given us the chance to execute, and + * we should do whatever we need to do in order to move some cells from + * their circuit queues to output buffers in an intelligent manner. We + * should do this quickly. When we are done, we'll try to schedule() ourself + * if more work needs to be done to setup the next scehduling run. */ + void (*run)(void); -/* Notify scheduler of queue size adjustments */ -void scheduler_adjust_queue_size(channel_t *chan, int dir, uint64_t adj); + /* + * External event not related to the scheduler but that can influence it. + */ -/* Notify scheduler that a channel's queue position may have changed */ -void scheduler_touch_channel(channel_t *chan); + /* (Optional) To be called whenever Tor finds out about a new consensus. + * First the scheduling system as a whole will react to the new consensus + * and change the scheduler if needed. After that, the current scheduler + * (which might be new) will call this so it has the chance to react to the + * new consensus too. If there's a consensus parameter that your scheduler + * wants to keep an eye on, this is where you should check for it. */ + void (*on_new_consensus)(const networkstatus_t *old_c, + const networkstatus_t *new_c); + + /* (Optional) To be called when a channel is being freed. Sometimes channels + * go away (for example: the relay on the other end is shutting down). If + * the scheduler keeps any channel-specific state and has memory to free + * when channels go away, implement this and free it here. */ + void (*on_channel_free)(const channel_t *); + + /* (Optional) To be called whenever Tor is reloading configuration options. + * For example: SIGHUP was issued and Tor is rereading its torrc. A + * scheduler should use this as an opportunity to parse and cache torrc + * options so that it doesn't have to call get_options() all the time. */ + void (*on_new_options)(void); +} scheduler_t; + +/** Scheduler type, we build an ordered list with those values from the + * parsed strings in Schedulers. The reason to do such a thing is so we can + * quickly and without parsing strings select the scheduler at anytime. */ +typedef enum { + SCHEDULER_VANILLA = 1, + SCHEDULER_KIST = 2, + SCHEDULER_KIST_LITE = 3, +} scheduler_types_t; -/* Adjust the watermarks from config file*/ -void scheduler_set_watermarks(uint32_t lo, uint32_t hi, uint32_t max_flush); +/***************************************************************************** + * Globally visible scheduler variables/values + * + * These are variables/constants that all of Tor should be able to see. + *****************************************************************************/ -/* Things only scheduler.c and its test suite should see */ +/* Default interval that KIST runs (in ms). */ +#define KIST_SCHED_RUN_INTERVAL_DEFAULT 10 +/* Minimum interval that KIST runs. This value disables KIST. */ +#define KIST_SCHED_RUN_INTERVAL_MIN 0 +/* Maximum interval that KIST runs (in ms). */ +#define KIST_SCHED_RUN_INTERVAL_MAX 100 +/***************************************************************************** + * Globally visible scheduler functions + * + * These functions are how the rest of Tor communicates with the scheduling + * system. + *****************************************************************************/ + +void scheduler_init(void); +void scheduler_free_all(void); +void scheduler_conf_changed(void); +void scheduler_notify_networkstatus_changed(const networkstatus_t *old_c, + const networkstatus_t *new_c); +MOCK_DECL(void, scheduler_release_channel, (channel_t *chan)); + +/* + * Ways for a channel to interact with the scheduling system. A channel only + * really knows (i) whether or not it has cells it wants to send, and + * (ii) whether or not it would like to write. + */ +void scheduler_channel_wants_writes(channel_t *chan); +MOCK_DECL(void, scheduler_channel_doesnt_want_writes, (channel_t *chan)); +MOCK_DECL(void, scheduler_channel_has_waiting_cells, (channel_t *chan)); + +/***************************************************************************** + * Private scheduler functions + * + * These functions are only visible to the scheduling system, the current + * scheduler implementation, and tests. + *****************************************************************************/ #ifdef SCHEDULER_PRIVATE_ -MOCK_DECL(STATIC int, scheduler_compare_channels, + +/********************************* + * Defined in scheduler.c + *********************************/ +smartlist_t *get_channels_pending(void); +MOCK_DECL(int, scheduler_compare_channels, (const void *c1_v, const void *c2_v)); -STATIC uint64_t scheduler_get_queue_heuristic(void); -STATIC void scheduler_update_queue_heuristic(time_t now); +void scheduler_ev_active(int flags); +void scheduler_ev_add(const struct timeval *next_run); #ifdef TOR_UNIT_TESTS extern smartlist_t *channels_pending; extern struct event *run_sched_ev; -extern uint64_t queue_heuristic; -extern time_t queue_heuristic_timestamp; -#endif -#endif +extern const scheduler_t *the_scheduler; +void scheduler_touch_channel(channel_t *chan); +#endif /* defined(TOR_UNIT_TESTS) */ + +/********************************* + * Defined in scheduler_kist.c + *********************************/ + +#ifdef SCHEDULER_KIST_PRIVATE + +/* Socke table entry which holds information of a channel's socket and kernel + * TCP information. Only used by KIST. */ +typedef struct socket_table_ent_s { + HT_ENTRY(socket_table_ent_s) node; + const channel_t *chan; + /* Amount written this scheduling run */ + uint64_t written; + /* Amount that can be written this scheduling run */ + uint64_t limit; + /* TCP info from the kernel */ + uint32_t cwnd; + uint32_t unacked; + uint32_t mss; + uint32_t notsent; +} socket_table_ent_t; + +typedef HT_HEAD(outbuf_table_s, outbuf_table_ent_s) outbuf_table_t; + +MOCK_DECL(int, channel_should_write_to_kernel, + (outbuf_table_t *table, channel_t *chan)); +MOCK_DECL(void, channel_write_to_kernel, (channel_t *chan)); +MOCK_DECL(void, update_socket_info_impl, (socket_table_ent_t *ent)); + +int scheduler_can_use_kist(void); +void scheduler_kist_set_full_mode(void); +void scheduler_kist_set_lite_mode(void); +scheduler_t *get_kist_scheduler(void); +int32_t kist_scheduler_run_interval(const networkstatus_t *ns); + +#ifdef TOR_UNIT_TESTS +extern int32_t sched_run_interval; +#endif /* TOR_UNIT_TESTS */ + +#endif /* defined(SCHEDULER_KIST_PRIVATE) */ + +/********************************* + * Defined in scheduler_vanilla.c + *********************************/ + +scheduler_t *get_vanilla_scheduler(void); + +#endif /* defined(SCHEDULER_PRIVATE_) */ #endif /* !defined(TOR_SCHEDULER_H) */ diff --git a/src/or/scheduler_kist.c b/src/or/scheduler_kist.c new file mode 100644 index 0000000000..2249d49f79 --- /dev/null +++ b/src/or/scheduler_kist.c @@ -0,0 +1,776 @@ +/* Copyright (c) 2017, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#define SCHEDULER_KIST_PRIVATE + +#include <event2/event.h> + +#include "or.h" +#include "buffers.h" +#include "config.h" +#include "connection.h" +#include "networkstatus.h" +#define TOR_CHANNEL_INTERNAL_ +#include "channel.h" +#include "channeltls.h" +#define SCHEDULER_PRIVATE_ +#include "scheduler.h" + +#define TLS_PER_CELL_OVERHEAD 29 + +#ifdef HAVE_KIST_SUPPORT +/* Kernel interface needed for KIST. */ +#include <netinet/tcp.h> +#include <linux/sockios.h> +#endif /* HAVE_KIST_SUPPORT */ + +/***************************************************************************** + * Data structures and supporting functions + *****************************************************************************/ + +#ifdef HAVE_KIST_SUPPORT +/* Indicate if KIST lite mode is on or off. We can disable it at runtime. + * Important to have because of the KISTLite -> KIST possible transition. */ +static unsigned int kist_lite_mode = 0; +/* Indicate if we don't have the kernel support. This can happen if the kernel + * changed and it doesn't recognized the values passed to the syscalls needed + * by KIST. In that case, fallback to the naive approach. */ +static unsigned int kist_no_kernel_support = 0; +#else /* !(defined(HAVE_KIST_SUPPORT)) */ +static unsigned int kist_no_kernel_support = 1; +static unsigned int kist_lite_mode = 1; +#endif /* defined(HAVE_KIST_SUPPORT) */ + +/* Socket_table hash table stuff. The socket_table keeps track of per-socket + * limit information imposed by kist and used by kist. */ + +static uint32_t +socket_table_ent_hash(const socket_table_ent_t *ent) +{ + return (uint32_t)ent->chan->global_identifier; +} + +static unsigned +socket_table_ent_eq(const socket_table_ent_t *a, const socket_table_ent_t *b) +{ + return a->chan == b->chan; +} + +typedef HT_HEAD(socket_table_s, socket_table_ent_s) socket_table_t; + +static socket_table_t socket_table = HT_INITIALIZER(); + +HT_PROTOTYPE(socket_table_s, socket_table_ent_s, node, socket_table_ent_hash, + socket_table_ent_eq) +HT_GENERATE2(socket_table_s, socket_table_ent_s, node, socket_table_ent_hash, + socket_table_ent_eq, 0.6, tor_reallocarray, tor_free_) + +/* outbuf_table hash table stuff. The outbuf_table keeps track of which + * channels have data sitting in their outbuf so the kist scheduler can force + * a write from outbuf to kernel periodically during a run and at the end of a + * run. */ + +typedef struct outbuf_table_ent_s { + HT_ENTRY(outbuf_table_ent_s) node; + channel_t *chan; +} outbuf_table_ent_t; + +static uint32_t +outbuf_table_ent_hash(const outbuf_table_ent_t *ent) +{ + return (uint32_t)ent->chan->global_identifier; +} + +static unsigned +outbuf_table_ent_eq(const outbuf_table_ent_t *a, const outbuf_table_ent_t *b) +{ + return a->chan->global_identifier == b->chan->global_identifier; +} + +HT_PROTOTYPE(outbuf_table_s, outbuf_table_ent_s, node, outbuf_table_ent_hash, + outbuf_table_ent_eq) +HT_GENERATE2(outbuf_table_s, outbuf_table_ent_s, node, outbuf_table_ent_hash, + outbuf_table_ent_eq, 0.6, tor_reallocarray, tor_free_) + +/***************************************************************************** + * Other internal data + *****************************************************************************/ + +/* Store the last time the scheduler was run so we can decide when to next run + * the scheduler based on it. */ +static monotime_t scheduler_last_run; +/* This is a factor for the extra_space calculation in kist per-socket limits. + * It is the number of extra congestion windows we want to write to the kernel. + */ +static double sock_buf_size_factor = 1.0; +/* How often the scheduler runs. */ +STATIC int32_t sched_run_interval = 10; + +/***************************************************************************** + * Internally called function implementations + *****************************************************************************/ + +/* Little helper function to get the length of a channel's output buffer */ +static inline size_t +channel_outbuf_length(channel_t *chan) +{ + /* In theory, this can not happen because we can not scheduler a channel + * without a connection that has its outbuf initialized. Just in case, bug + * on this so we can understand a bit more why it happened. */ + if (BUG(BASE_CHAN_TO_TLS(chan)->conn == NULL)) { + return 0; + } + return buf_datalen(TO_CONN(BASE_CHAN_TO_TLS(chan)->conn)->outbuf); +} + +/* Little helper function for HT_FOREACH_FN. */ +static int +each_channel_write_to_kernel(outbuf_table_ent_t *ent, void *data) +{ + (void) data; /* Make compiler happy. */ + channel_write_to_kernel(ent->chan); + return 0; /* Returning non-zero removes the element from the table. */ +} + +/* Free the given outbuf table entry ent. */ +static int +free_outbuf_info_by_ent(outbuf_table_ent_t *ent, void *data) +{ + (void) data; /* Make compiler happy. */ + log_debug(LD_SCHED, "Freeing outbuf table entry from chan=%" PRIu64, + ent->chan->global_identifier); + tor_free(ent); + return 1; /* So HT_FOREACH_FN will remove the element */ +} + +/* Free the given socket table entry ent. */ +static int +free_socket_info_by_ent(socket_table_ent_t *ent, void *data) +{ + (void) data; /* Make compiler happy. */ + log_debug(LD_SCHED, "Freeing socket table entry from chan=%" PRIu64, + ent->chan->global_identifier); + tor_free(ent); + return 1; /* So HT_FOREACH_FN will remove the element */ +} + +/* Clean up socket_table. Probably because the KIST sched impl is going away */ +static void +free_all_socket_info(void) +{ + HT_FOREACH_FN(socket_table_s, &socket_table, free_socket_info_by_ent, NULL); +} + +static socket_table_ent_t * +socket_table_search(socket_table_t *table, const channel_t *chan) +{ + socket_table_ent_t search, *ent = NULL; + search.chan = chan; + ent = HT_FIND(socket_table_s, table, &search); + return ent; +} + +/* Free a socket entry in table for the given chan. */ +static void +free_socket_info_by_chan(socket_table_t *table, const channel_t *chan) +{ + socket_table_ent_t *ent = NULL; + ent = socket_table_search(table, chan); + if (!ent) + return; + log_debug(LD_SCHED, "scheduler free socket info for chan=%" PRIu64, + chan->global_identifier); + HT_REMOVE(socket_table_s, table, ent); + free_socket_info_by_ent(ent, NULL); +} + +/* Perform system calls for the given socket in order to calculate kist's + * per-socket limit as documented in the function body. */ +MOCK_IMPL(void, +update_socket_info_impl, (socket_table_ent_t *ent)) +{ +#ifdef HAVE_KIST_SUPPORT + int64_t tcp_space, extra_space; + const tor_socket_t sock = + TO_CONN(BASE_CHAN_TO_TLS((channel_t *) ent->chan)->conn)->s; + struct tcp_info tcp; + socklen_t tcp_info_len = sizeof(tcp); + + if (kist_no_kernel_support || kist_lite_mode) { + goto fallback; + } + + /* Gather information */ + if (getsockopt(sock, SOL_TCP, TCP_INFO, (void *)&(tcp), &tcp_info_len) < 0) { + if (errno == EINVAL) { + /* Oops, this option is not provided by the kernel, we'll have to + * disable KIST entirely. This can happen if tor was built on a machine + * with the support previously or if the kernel was updated and lost the + * support. */ + log_notice(LD_SCHED, "Looks like our kernel doesn't have the support " + "for KIST anymore. We will fallback to the naive " + "approach. Set KISTSchedRunInterval=-1 to disable " + "KIST."); + kist_no_kernel_support = 1; + } + goto fallback; + } + if (ioctl(sock, SIOCOUTQNSD, &(ent->notsent)) < 0) { + if (errno == EINVAL) { + log_notice(LD_SCHED, "Looks like our kernel doesn't have the support " + "for KIST anymore. We will fallback to the naive " + "approach. Set KISTSchedRunInterval=-1 to disable " + "KIST."); + /* Same reason as the above. */ + kist_no_kernel_support = 1; + } + goto fallback; + } + ent->cwnd = tcp.tcpi_snd_cwnd; + ent->unacked = tcp.tcpi_unacked; + ent->mss = tcp.tcpi_snd_mss; + + /* In order to reduce outbound kernel queuing delays and thus improve Tor's + * ability to prioritize circuits, KIST wants to set a socket write limit + * that is near the amount that the socket would be able to immediately send + * into the Internet. + * + * We first calculate how much the socket could send immediately (assuming + * completely full packets) according to the congestion window and the number + * of unacked packets. + * + * Then we add a little extra space in a controlled way. We do this so any + * when the kernel gets ACKs back for data currently sitting in the "TCP + * space", it will already have some more data to send immediately. It will + * not have to wait for the scheduler to run again. The amount of extra space + * is a factor of the current congestion window. With the suggested + * sock_buf_size_factor value of 1.0, we allow at most 2*cwnd bytes to sit in + * the kernel: 1 cwnd on the wire waiting for ACKs and 1 cwnd ready and + * waiting to be sent when those ACKs finally come. + * + * In the below diagram, we see some bytes in the TCP-space (denoted by '*') + * that have be sent onto the wire and are waiting for ACKs. We have a little + * more room in "TCP space" that we can fill with data that will be + * immediately sent. We also see the "extra space" KIST calculates. The sum + * of the empty "TCP space" and the "extra space" is the kist-imposed write + * limit for this socket. + * + * <----------------kernel-outbound-socket-queue----------------| + * <*********---------------------------------------------------| + * <----TCP-space-----|----extra-space-----| + * <------------------| + * ^ ((cwnd - unacked) * mss) bytes + * |--------------------| + * ^ ((cwnd * mss) * factor) bytes + */ + + /* Assuming all these values from the kernel are uint32_t still, they will + * always fit into a int64_t tcp_space variable. */ + tcp_space = (ent->cwnd - ent->unacked) * (int64_t)ent->mss; + if (tcp_space < 0) { + tcp_space = 0; + } + + /* The clamp_double_to_int64 makes sure the first part fits into an int64_t. + * In fact, if sock_buf_size_factor is still forced to be >= 0 in config.c, + * then it will be positive for sure. Then we subtract a uint32_t. At worst + * we end up negative, but then we just set extra_space to 0 in the sanity + * check.*/ + extra_space = + clamp_double_to_int64( + (ent->cwnd * (int64_t)ent->mss) * sock_buf_size_factor) - + ent->notsent; + if (extra_space < 0) { + extra_space = 0; + } + + /* Finally we set the limit. Adding two positive int64_t together will always + * fit in an uint64_t. */ + ent->limit = (uint64_t)tcp_space + (uint64_t)extra_space; + return; + +#else /* !(defined(HAVE_KIST_SUPPORT)) */ + goto fallback; +#endif /* defined(HAVE_KIST_SUPPORT) */ + + fallback: + /* If all of a sudden we don't have kist support, we just zero out all the + * variables for this socket since we don't know what they should be. + * We also effectively allow the socket write as much as it wants to the + * kernel, effectively returning it to vanilla scheduler behavior. Writes + * are still limited by the lower layers of Tor: socket blocking, full + * outbuf, etc. */ + ent->cwnd = ent->unacked = ent->mss = ent->notsent = 0; + ent->limit = INT_MAX; +} + +/* Given a socket that isn't in the table, add it. + * Given a socket that is in the table, reinit values that need init-ing + * every scheduling run + */ +static void +init_socket_info(socket_table_t *table, const channel_t *chan) +{ + socket_table_ent_t *ent = NULL; + ent = socket_table_search(table, chan); + if (!ent) { + log_debug(LD_SCHED, "scheduler init socket info for chan=%" PRIu64, + chan->global_identifier); + ent = tor_malloc_zero(sizeof(*ent)); + ent->chan = chan; + HT_INSERT(socket_table_s, table, ent); + } + ent->written = 0; +} + +/* Add chan to the outbuf table if it isn't already in it. If it is, then don't + * do anything */ +static void +outbuf_table_add(outbuf_table_t *table, channel_t *chan) +{ + outbuf_table_ent_t search, *ent; + search.chan = chan; + ent = HT_FIND(outbuf_table_s, table, &search); + if (!ent) { + log_debug(LD_SCHED, "scheduler init outbuf info for chan=%" PRIu64, + chan->global_identifier); + ent = tor_malloc_zero(sizeof(*ent)); + ent->chan = chan; + HT_INSERT(outbuf_table_s, table, ent); + } +} + +static void +outbuf_table_remove(outbuf_table_t *table, channel_t *chan) +{ + outbuf_table_ent_t search, *ent; + search.chan = chan; + ent = HT_FIND(outbuf_table_s, table, &search); + if (ent) { + HT_REMOVE(outbuf_table_s, table, ent); + free_outbuf_info_by_ent(ent, NULL); + } +} + +/* Set the scheduler running interval. */ +static void +set_scheduler_run_interval(const networkstatus_t *ns) +{ + int32_t old_sched_run_interval = sched_run_interval; + sched_run_interval = kist_scheduler_run_interval(ns); + if (old_sched_run_interval != sched_run_interval) { + log_info(LD_SCHED, "Scheduler KIST changing its running interval " + "from %" PRId32 " to %" PRId32, + old_sched_run_interval, sched_run_interval); + } +} + +/* Return true iff the channel associated socket can write to the kernel that + * is hasn't reach the limit. */ +static int +socket_can_write(socket_table_t *table, const channel_t *chan) +{ + socket_table_ent_t *ent = NULL; + ent = socket_table_search(table, chan); + IF_BUG_ONCE(!ent) { + return 1; // Just return true, saying that kist wouldn't limit the socket + } + + /* We previously caclulated a write limit for this socket. In the below + * calculation, first determine how much room is left in bytes. Then divide + * that by the amount of space a cell takes. If there's room for at least 1 + * cell, then KIST will allow the socket to write. */ + int64_t kist_limit_space = + (int64_t) (ent->limit - ent->written) / + (CELL_MAX_NETWORK_SIZE + TLS_PER_CELL_OVERHEAD); + return kist_limit_space > 0; +} + +/* Update the channel's socket kernel information. */ +static void +update_socket_info(socket_table_t *table, const channel_t *chan) +{ + socket_table_ent_t *ent = NULL; + ent = socket_table_search(table, chan); + IF_BUG_ONCE(!ent) { + return; // Whelp. Entry didn't exist for some reason so nothing to do. + } + update_socket_info_impl(ent); +} + +/* Increament the channel's socket written value by the number of bytes. */ +static void +update_socket_written(socket_table_t *table, channel_t *chan, size_t bytes) +{ + socket_table_ent_t *ent = NULL; + ent = socket_table_search(table, chan); + IF_BUG_ONCE(!ent) { + return; // Whelp. Entry didn't exist so nothing to do. + } + + log_debug(LD_SCHED, "chan=%" PRIu64 " wrote %lu bytes, old was %" PRIi64, + chan->global_identifier, (unsigned long) bytes, ent->written); + + ent->written += bytes; +} + +/* + * A naive KIST impl would write every single cell all the way to the kernel. + * That would take a lot of system calls. A less bad KIST impl would write a + * channel's outbuf to the kernel only when we are switching to a different + * channel. But if we have two channels with equal priority, we end up writing + * one cell for each and bouncing back and forth. This KIST impl avoids that + * by only writing a channel's outbuf to the kernel if it has 8 cells or more + * in it. + */ +MOCK_IMPL(int, channel_should_write_to_kernel, + (outbuf_table_t *table, channel_t *chan)) +{ + outbuf_table_add(table, chan); + /* CELL_MAX_NETWORK_SIZE * 8 because we only want to write the outbuf to the + * kernel if there's 8 or more cells waiting */ + return channel_outbuf_length(chan) > (CELL_MAX_NETWORK_SIZE * 8); +} + +/* Little helper function to write a channel's outbuf all the way to the + * kernel */ +MOCK_IMPL(void, channel_write_to_kernel, (channel_t *chan)) +{ + log_debug(LD_SCHED, "Writing %lu bytes to kernel for chan %" PRIu64, + (unsigned long)channel_outbuf_length(chan), + chan->global_identifier); + connection_handle_write(TO_CONN(BASE_CHAN_TO_TLS(chan)->conn), 0); +} + +/* Return true iff the scheduler has work to perform. */ +static int +have_work(void) +{ + smartlist_t *cp = get_channels_pending(); + IF_BUG_ONCE(!cp) { + return 0; // channels_pending doesn't exist so... no work? + } + return smartlist_len(cp) > 0; +} + +/* Function of the scheduler interface: free_all() */ +static void +kist_free_all(void) +{ + free_all_socket_info(); +} + +/* Function of the scheduler interface: on_channel_free() */ +static void +kist_on_channel_free(const channel_t *chan) +{ + free_socket_info_by_chan(&socket_table, chan); +} + +/* Function of the scheduler interface: on_new_consensus() */ +static void +kist_scheduler_on_new_consensus(const networkstatus_t *old_c, + const networkstatus_t *new_c) +{ + (void) old_c; + (void) new_c; + + set_scheduler_run_interval(new_c); +} + +/* Function of the scheduler interface: on_new_options() */ +static void +kist_scheduler_on_new_options(void) +{ + sock_buf_size_factor = get_options()->KISTSockBufSizeFactor; + + /* Calls kist_scheduler_run_interval which calls get_options(). */ + set_scheduler_run_interval(NULL); +} + +/* Function of the scheduler interface: init() */ +static void +kist_scheduler_init(void) +{ + kist_scheduler_on_new_options(); + IF_BUG_ONCE(sched_run_interval <= 0) { + log_warn(LD_SCHED, "We are initing the KIST scheduler and noticed the " + "KISTSchedRunInterval is telling us to not use KIST. That's " + "weird! We'll continue using KIST, but at %dms.", + KIST_SCHED_RUN_INTERVAL_DEFAULT); + sched_run_interval = KIST_SCHED_RUN_INTERVAL_DEFAULT; + } +} + +/* Function of the scheduler interface: schedule() */ +static void +kist_scheduler_schedule(void) +{ + struct monotime_t now; + struct timeval next_run; + int32_t diff; + + if (!have_work()) { + return; + } + monotime_get(&now); + diff = (int32_t) monotime_diff_msec(&scheduler_last_run, &now); + if (diff < sched_run_interval) { + next_run.tv_sec = 0; + /* 1000 for ms -> us */ + next_run.tv_usec = (sched_run_interval - diff) * 1000; + /* Readding an event reschedules it. It does not duplicate it. */ + scheduler_ev_add(&next_run); + } else { + scheduler_ev_active(EV_TIMEOUT); + } +} + +/* Function of the scheduler interface: run() */ +static void +kist_scheduler_run(void) +{ + /* Define variables */ + channel_t *chan = NULL; // current working channel + /* The last distinct chan served in a sched loop. */ + channel_t *prev_chan = NULL; + int flush_result; // temporarily store results from flush calls + /* Channels to be readding to pending at the end */ + smartlist_t *to_readd = NULL; + smartlist_t *cp = get_channels_pending(); + + outbuf_table_t outbuf_table = HT_INITIALIZER(); + + /* For each pending channel, collect new kernel information */ + SMARTLIST_FOREACH_BEGIN(cp, const channel_t *, pchan) { + init_socket_info(&socket_table, pchan); + update_socket_info(&socket_table, pchan); + } SMARTLIST_FOREACH_END(pchan); + + log_debug(LD_SCHED, "Running the scheduler. %d channels pending", + smartlist_len(cp)); + + /* The main scheduling loop. Loop until there are no more pending channels */ + while (smartlist_len(cp) > 0) { + /* get best channel */ + chan = smartlist_pqueue_pop(cp, scheduler_compare_channels, + offsetof(channel_t, sched_heap_idx)); + IF_BUG_ONCE(!chan) { + /* Some-freaking-how a NULL got into the channels_pending. That should + * never happen, but it should be harmless to ignore it and keep looping. + */ + continue; + } + outbuf_table_add(&outbuf_table, chan); + + /* if we have switched to a new channel, consider writing the previous + * channel's outbuf to the kernel. */ + if (!prev_chan) { + prev_chan = chan; + } + if (prev_chan != chan) { + if (channel_should_write_to_kernel(&outbuf_table, prev_chan)) { + channel_write_to_kernel(prev_chan); + outbuf_table_remove(&outbuf_table, prev_chan); + } + prev_chan = chan; + } + + /* Only flush and write if the per-socket limit hasn't been hit */ + if (socket_can_write(&socket_table, chan)) { + /* flush to channel queue/outbuf */ + flush_result = (int)channel_flush_some_cells(chan, 1); // 1 for num cells + /* flush_result has the # cells flushed */ + if (flush_result > 0) { + update_socket_written(&socket_table, chan, flush_result * + (CELL_MAX_NETWORK_SIZE + TLS_PER_CELL_OVERHEAD)); + } + /* XXX What if we didn't flush? */ + } + + /* Decide what to do with the channel now */ + + if (!channel_more_to_flush(chan) && + !socket_can_write(&socket_table, chan)) { + + /* Case 1: no more cells to send, and cannot write */ + + /* + * You might think we should put the channel in SCHED_CHAN_IDLE. And + * you're probably correct. While implementing KIST, we found that the + * scheduling system would sometimes lose track of channels when we did + * that. We suspect it has to do with the difference between "can't + * write because socket/outbuf is full" and KIST's "can't write because + * we've arbitrarily decided that that's enough for now." Sometimes + * channels run out of cells at the same time they hit their + * kist-imposed write limit and maybe the rest of Tor doesn't put the + * channel back in pending when it is supposed to. + * + * This should be investigated again. It is as simple as changing + * SCHED_CHAN_WAITING_FOR_CELLS to SCHED_CHAN_IDLE and seeing if Tor + * starts having serious throughput issues. Best done in shadow/chutney. + */ + chan->scheduler_state = SCHED_CHAN_WAITING_FOR_CELLS; + log_debug(LD_SCHED, "chan=%" PRIu64 " now waiting_for_cells", + chan->global_identifier); + } else if (!channel_more_to_flush(chan)) { + + /* Case 2: no more cells to send, but still open for writes */ + + chan->scheduler_state = SCHED_CHAN_WAITING_FOR_CELLS; + log_debug(LD_SCHED, "chan=%" PRIu64 " now waiting_for_cells", + chan->global_identifier); + } else if (!socket_can_write(&socket_table, chan)) { + + /* Case 3: cells to send, but cannot write */ + + /* + * We want to write, but can't. If we left the channel in + * channels_pending, we would never exit the scheduling loop. We need to + * add it to a temporary list of channels to be added to channels_pending + * after the scheduling loop is over. They can hopefully be taken care of + * in the next scheduling round. + */ + chan->scheduler_state = SCHED_CHAN_WAITING_TO_WRITE; + if (!to_readd) { + to_readd = smartlist_new(); + } + smartlist_add(to_readd, chan); + log_debug(LD_SCHED, "chan=%" PRIu64 " now waiting_to_write", + chan->global_identifier); + } else { + + /* Case 4: cells to send, and still open for writes */ + + chan->scheduler_state = SCHED_CHAN_PENDING; + smartlist_pqueue_add(cp, scheduler_compare_channels, + offsetof(channel_t, sched_heap_idx), chan); + } + } /* End of main scheduling loop */ + + /* Write the outbuf of any channels that still have data */ + HT_FOREACH_FN(outbuf_table_s, &outbuf_table, each_channel_write_to_kernel, + NULL); + /* We are done with it. */ + HT_FOREACH_FN(outbuf_table_s, &outbuf_table, free_outbuf_info_by_ent, NULL); + HT_CLEAR(outbuf_table_s, &outbuf_table); + + log_debug(LD_SCHED, "len pending=%d, len to_readd=%d", + smartlist_len(cp), + (to_readd ? smartlist_len(to_readd) : -1)); + + /* Readd any channels we need to */ + if (to_readd) { + SMARTLIST_FOREACH_BEGIN(to_readd, channel_t *, readd_chan) { + readd_chan->scheduler_state = SCHED_CHAN_PENDING; + if (!smartlist_contains(cp, readd_chan)) { + smartlist_pqueue_add(cp, scheduler_compare_channels, + offsetof(channel_t, sched_heap_idx), readd_chan); + } + } SMARTLIST_FOREACH_END(readd_chan); + smartlist_free(to_readd); + } + + monotime_get(&scheduler_last_run); +} + +/***************************************************************************** + * Externally called function implementations not called through scheduler_t + *****************************************************************************/ + +/* Stores the kist scheduler function pointers. */ +static scheduler_t kist_scheduler = { + .free_all = kist_free_all, + .on_channel_free = kist_on_channel_free, + .init = kist_scheduler_init, + .on_new_consensus = kist_scheduler_on_new_consensus, + .schedule = kist_scheduler_schedule, + .run = kist_scheduler_run, + .on_new_options = kist_scheduler_on_new_options, +}; + +/* Return the KIST scheduler object. If it didn't exists, return a newly + * allocated one but init() is not called. */ +scheduler_t * +get_kist_scheduler(void) +{ + return &kist_scheduler; +} + +/* Check the torrc for the configured KIST scheduler run interval. + * - If torrc < 0, then return the negative torrc value (shouldn't even be + * using KIST) + * - If torrc > 0, then return the positive torrc value (should use KIST, and + * should use the set value) + * - If torrc == 0, then look in the consensus for what the value should be. + * - If == 0, then return -1 (don't use KIST) + * - If > 0, then return the positive consensus value + * - If consensus doesn't say anything, return 10 milliseconds + */ +int32_t +kist_scheduler_run_interval(const networkstatus_t *ns) +{ + int32_t run_interval = (int32_t)get_options()->KISTSchedRunInterval; + if (run_interval != 0) { + log_debug(LD_SCHED, "Found KISTSchedRunInterval in torrc. Using that."); + return run_interval; + } + + log_debug(LD_SCHED, "Turning to the consensus for KISTSchedRunInterval"); + run_interval = networkstatus_get_param(ns, "KISTSchedRunInterval", + KIST_SCHED_RUN_INTERVAL_DEFAULT, + KIST_SCHED_RUN_INTERVAL_MIN, + KIST_SCHED_RUN_INTERVAL_MAX); + if (run_interval <= 0) + return -1; + return run_interval; +} + +/* Set KISTLite mode that is KIST without kernel support. */ +void +scheduler_kist_set_lite_mode(void) +{ + kist_lite_mode = 1; + log_info(LD_SCHED, + "Setting KIST scheduler without kernel support (KISTLite mode)"); +} + +/* Set KIST mode that is KIST with kernel support. */ +void +scheduler_kist_set_full_mode(void) +{ + kist_lite_mode = 0; + log_info(LD_SCHED, + "Setting KIST scheduler with kernel support (KIST mode)"); +} + +#ifdef HAVE_KIST_SUPPORT + +/* Return true iff the scheduler subsystem should use KIST. */ +int +scheduler_can_use_kist(void) +{ + if (kist_no_kernel_support) { + /* We have no kernel support so we can't use KIST. */ + return 0; + } + + /* We do have the support, time to check if we can get the interval that the + * consensus can be disabling. */ + int64_t run_interval = kist_scheduler_run_interval(NULL); + log_debug(LD_SCHED, "Determined KIST sched_run_interval should be " + "%" PRId64 ". Can%s use KIST.", + run_interval, (run_interval > 0 ? "" : " not")); + return run_interval > 0; +} + +#else /* !(defined(HAVE_KIST_SUPPORT)) */ + +int +scheduler_can_use_kist(void) +{ + return 0; +} + +#endif /* defined(HAVE_KIST_SUPPORT) */ + diff --git a/src/or/scheduler_vanilla.c b/src/or/scheduler_vanilla.c new file mode 100644 index 0000000000..09653f445e --- /dev/null +++ b/src/or/scheduler_vanilla.c @@ -0,0 +1,196 @@ +/* Copyright (c) 2017, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include <event2/event.h> + +#include "or.h" +#include "config.h" +#define TOR_CHANNEL_INTERNAL_ +#include "channel.h" +#define SCHEDULER_PRIVATE_ +#include "scheduler.h" + +/***************************************************************************** + * Other internal data + *****************************************************************************/ + +/* Maximum cells to flush in a single call to channel_flush_some_cells(); */ +#define MAX_FLUSH_CELLS 1000 + +/***************************************************************************** + * Externally called function implementations + *****************************************************************************/ + +/* Return true iff the scheduler has work to perform. */ +static int +have_work(void) +{ + smartlist_t *cp = get_channels_pending(); + IF_BUG_ONCE(!cp) { + return 0; // channels_pending doesn't exist so... no work? + } + return smartlist_len(cp) > 0; +} + +/** Retrigger the scheduler in a way safe to use from the callback */ + +static void +vanilla_scheduler_schedule(void) +{ + if (!have_work()) { + return; + } + + /* Activate our event so it can process channels. */ + scheduler_ev_active(EV_TIMEOUT); +} + +static void +vanilla_scheduler_run(void) +{ + int n_cells, n_chans_before, n_chans_after; + ssize_t flushed, flushed_this_time; + smartlist_t *cp = get_channels_pending(); + smartlist_t *to_readd = NULL; + channel_t *chan = NULL; + + log_debug(LD_SCHED, "We have a chance to run the scheduler"); + + n_chans_before = smartlist_len(cp); + + while (smartlist_len(cp) > 0) { + /* Pop off a channel */ + chan = smartlist_pqueue_pop(cp, + scheduler_compare_channels, + offsetof(channel_t, sched_heap_idx)); + IF_BUG_ONCE(!chan) { + /* Some-freaking-how a NULL got into the channels_pending. That should + * never happen, but it should be harmless to ignore it and keep looping. + */ + continue; + } + + /* Figure out how many cells we can write */ + n_cells = channel_num_cells_writeable(chan); + if (n_cells > 0) { + log_debug(LD_SCHED, + "Scheduler saw pending channel " U64_FORMAT " at %p with " + "%d cells writeable", + U64_PRINTF_ARG(chan->global_identifier), chan, n_cells); + + flushed = 0; + while (flushed < n_cells) { + flushed_this_time = + channel_flush_some_cells(chan, + MIN(MAX_FLUSH_CELLS, (size_t) n_cells - flushed)); + if (flushed_this_time <= 0) break; + flushed += flushed_this_time; + } + + if (flushed < n_cells) { + /* We ran out of cells to flush */ + chan->scheduler_state = SCHED_CHAN_WAITING_FOR_CELLS; + log_debug(LD_SCHED, + "Channel " U64_FORMAT " at %p " + "entered waiting_for_cells from pending", + U64_PRINTF_ARG(chan->global_identifier), + chan); + } else { + /* The channel may still have some cells */ + if (channel_more_to_flush(chan)) { + /* The channel goes to either pending or waiting_to_write */ + if (channel_num_cells_writeable(chan) > 0) { + /* Add it back to pending later */ + if (!to_readd) to_readd = smartlist_new(); + smartlist_add(to_readd, chan); + log_debug(LD_SCHED, + "Channel " U64_FORMAT " at %p " + "is still pending", + U64_PRINTF_ARG(chan->global_identifier), + chan); + } else { + /* It's waiting to be able to write more */ + chan->scheduler_state = SCHED_CHAN_WAITING_TO_WRITE; + log_debug(LD_SCHED, + "Channel " U64_FORMAT " at %p " + "entered waiting_to_write from pending", + U64_PRINTF_ARG(chan->global_identifier), + chan); + } + } else { + /* No cells left; it can go to idle or waiting_for_cells */ + if (channel_num_cells_writeable(chan) > 0) { + /* + * It can still accept writes, so it goes to + * waiting_for_cells + */ + chan->scheduler_state = SCHED_CHAN_WAITING_FOR_CELLS; + log_debug(LD_SCHED, + "Channel " U64_FORMAT " at %p " + "entered waiting_for_cells from pending", + U64_PRINTF_ARG(chan->global_identifier), + chan); + } else { + /* + * We exactly filled up the output queue with all available + * cells; go to idle. + */ + chan->scheduler_state = SCHED_CHAN_IDLE; + log_debug(LD_SCHED, + "Channel " U64_FORMAT " at %p " + "become idle from pending", + U64_PRINTF_ARG(chan->global_identifier), + chan); + } + } + } + + log_debug(LD_SCHED, + "Scheduler flushed %d cells onto pending channel " + U64_FORMAT " at %p", + (int)flushed, U64_PRINTF_ARG(chan->global_identifier), + chan); + } else { + log_info(LD_SCHED, + "Scheduler saw pending channel " U64_FORMAT " at %p with " + "no cells writeable", + U64_PRINTF_ARG(chan->global_identifier), chan); + /* Put it back to WAITING_TO_WRITE */ + chan->scheduler_state = SCHED_CHAN_WAITING_TO_WRITE; + } + } + + /* Readd any channels we need to */ + if (to_readd) { + SMARTLIST_FOREACH_BEGIN(to_readd, channel_t *, readd_chan) { + readd_chan->scheduler_state = SCHED_CHAN_PENDING; + smartlist_pqueue_add(cp, + scheduler_compare_channels, + offsetof(channel_t, sched_heap_idx), + readd_chan); + } SMARTLIST_FOREACH_END(readd_chan); + smartlist_free(to_readd); + } + + n_chans_after = smartlist_len(cp); + log_debug(LD_SCHED, "Scheduler handled %d of %d pending channels", + n_chans_before - n_chans_after, n_chans_before); +} + +/* Stores the vanilla scheduler function pointers. */ +static scheduler_t vanilla_scheduler = { + .free_all = NULL, + .on_channel_free = NULL, + .init = NULL, + .on_new_consensus = NULL, + .schedule = vanilla_scheduler_schedule, + .run = vanilla_scheduler_run, + .on_new_options = NULL, +}; + +scheduler_t * +get_vanilla_scheduler(void) +{ + return &vanilla_scheduler; +} + diff --git a/src/or/shared_random.c b/src/or/shared_random.c index e4ee64139a..bbb7af0a33 100644 --- a/src/or/shared_random.c +++ b/src/or/shared_random.c @@ -1447,5 +1447,5 @@ set_num_srv_agreements(int32_t value) num_srv_agreements_from_vote = value; } -#endif /* TOR_UNIT_TESTS */ +#endif /* defined(TOR_UNIT_TESTS) */ diff --git a/src/or/shared_random.h b/src/or/shared_random.h index 76d5b95422..c0992489cb 100644 --- a/src/or/shared_random.h +++ b/src/or/shared_random.h @@ -160,7 +160,7 @@ STATIC int should_keep_commit(const sr_commit_t *commit, sr_phase_t phase); STATIC void save_commit_during_reveal_phase(const sr_commit_t *commit); -#endif /* SHARED_RANDOM_PRIVATE */ +#endif /* defined(SHARED_RANDOM_PRIVATE) */ #ifdef TOR_UNIT_TESTS @@ -168,5 +168,5 @@ void set_num_srv_agreements(int32_t value); #endif /* TOR_UNIT_TESTS */ -#endif /* TOR_SHARED_RANDOM_H */ +#endif /* !defined(TOR_SHARED_RANDOM_H) */ diff --git a/src/or/shared_random_state.c b/src/or/shared_random_state.c index 5fcf88cc4a..13ef95bb0c 100644 --- a/src/or/shared_random_state.c +++ b/src/or/shared_random_state.c @@ -1391,5 +1391,5 @@ get_sr_state(void) return sr_state; } -#endif /* TOR_UNIT_TESTS */ +#endif /* defined(TOR_UNIT_TESTS) */ diff --git a/src/or/shared_random_state.h b/src/or/shared_random_state.h index 837fa75392..a154eb5636 100644 --- a/src/or/shared_random_state.h +++ b/src/or/shared_random_state.h @@ -139,14 +139,14 @@ STATIC void new_protocol_run(time_t valid_after); STATIC void state_rotate_srv(void); STATIC int is_phase_transition(sr_phase_t next_phase); -#endif /* SHARED_RANDOM_STATE_PRIVATE */ +#endif /* defined(SHARED_RANDOM_STATE_PRIVATE) */ #ifdef TOR_UNIT_TESTS STATIC void set_sr_phase(sr_phase_t phase); STATIC sr_state_t *get_sr_state(void); -#endif /* TOR_UNIT_TESTS */ +#endif /* defined(TOR_UNIT_TESTS) */ -#endif /* TOR_SHARED_RANDOM_STATE_H */ +#endif /* !defined(TOR_SHARED_RANDOM_STATE_H) */ diff --git a/src/or/statefile.h b/src/or/statefile.h index 10c09324bc..574afb3622 100644 --- a/src/or/statefile.h +++ b/src/or/statefile.h @@ -24,5 +24,5 @@ STATIC void or_state_free(or_state_t *state); STATIC or_state_t *or_state_new(void); #endif -#endif +#endif /* !defined(TOR_STATEFILE_H) */ diff --git a/src/or/status.h b/src/or/status.h index c1a0033ce0..49da6abc0f 100644 --- a/src/or/status.h +++ b/src/or/status.h @@ -14,5 +14,5 @@ STATIC char *secs_to_uptime(long secs); STATIC char *bytes_to_usage(uint64_t bytes); #endif -#endif +#endif /* !defined(TOR_STATUS_H) */ diff --git a/src/or/torcert.h b/src/or/torcert.h index 416ff7aa23..c77ae2089d 100644 --- a/src/or/torcert.h +++ b/src/or/torcert.h @@ -101,5 +101,5 @@ void or_handshake_certs_check_both(int severity, int tor_cert_encode_ed22519(const tor_cert_t *cert, char **cert_str_out); -#endif +#endif /* !defined(TORCERT_H_INCLUDED) */ diff --git a/src/or/transports.c b/src/or/transports.c index 31849a8d15..68d1354844 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -527,12 +527,12 @@ launch_managed_proxy(managed_proxy_t *mp) (const char **)mp->argv, env, &mp->process_handle); -#else +#else /* !(defined(_WIN32)) */ retval = tor_spawn_background(mp->argv[0], (const char **)mp->argv, env, &mp->process_handle); -#endif +#endif /* defined(_WIN32) */ process_environment_free(env); diff --git a/src/or/transports.h b/src/or/transports.h index 44a9626e50..e368e447c3 100644 --- a/src/or/transports.h +++ b/src/or/transports.h @@ -133,7 +133,7 @@ STATIC char* get_pt_proxy_uri(void); STATIC void free_execve_args(char **arg); -#endif +#endif /* defined(PT_PRIVATE) */ -#endif +#endif /* !defined(TOR_TRANSPORTS_H) */ diff --git a/src/test/bench.c b/src/test/bench.c index 9d589332ae..b7b123eee2 100644 --- a/src/test/bench.c +++ b/src/test/bench.c @@ -58,7 +58,7 @@ perftime(void) return timespec_to_nsec(&ts) - nanostart; } -#else +#else /* !(defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID)) */ static struct timeval tv_start = { 0, 0 }; static void reset_perftime(void) @@ -73,7 +73,7 @@ perftime(void) timersub(&now, &tv_start, &out); return ((uint64_t)out.tv_sec)*1000000000 + out.tv_usec*1000; } -#endif +#endif /* defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID) */ #define NANOCOUNT(start,end,iters) \ ( ((double)((end)-(start))) / (iters) ) diff --git a/src/test/hs_build_address.py b/src/test/hs_build_address.py index 7be9c8b85a..7ff22c3a9a 100644 --- a/src/test/hs_build_address.py +++ b/src/test/hs_build_address.py @@ -21,8 +21,9 @@ if TEST_VALUE != sha3.sha3_256(b"Hello World").hexdigest(): # Checksum is built like so: # CHECKSUM = SHA3(".onion checksum" || PUBKEY || VERSION) PREFIX = ".onion checksum".encode() -# 32 bytes ed25519 pubkey. -PUBKEY = ("\x42" * 32).encode() +# 32 bytes ed25519 pubkey from first test vector of +# https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-02#section-6 +PUBKEY = "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".decode('hex') # Version 3 is proposal224 VERSION = 3 diff --git a/src/test/hs_indexes.py b/src/test/hs_indexes.py new file mode 100644 index 0000000000..af0b81f8de --- /dev/null +++ b/src/test/hs_indexes.py @@ -0,0 +1,70 @@ +# +# The hidden service subsystem has two type of index. The first type is a +# value that each node in the network gets assigned to using their identity +# key which is their position in the hashring. (hs_build_hsdir_index()). +# +# The second type is a value that both the client and service computes to +# store/fetch the descriptor on the hashring. (hs_build_hs_index()). +# + +import sys +import hashlib +import struct +import base64 + +# Python 3.6+, the SHA3 is available in hashlib natively. Else this requires +# the pysha3 package (pip install pysha3). +if sys.version_info < (3, 6): + import sha3 + # Test vector to make sure the right sha3 version will be used. pysha3 < 1.0 + # used the old Keccak implementation. During the finalization of SHA3, NIST + # changed the delimiter suffix from 0x01 to 0x06. The Keccak sponge function + # stayed the same. pysha3 1.0 provides the previous Keccak hash, too. + TEST_VALUE = "e167f68d6563d75bb25f3aa49c29ef612d41352dc00606de7cbd630bb2665f51" + if TEST_VALUE != sha3.sha3_256(b"Hello World").hexdigest(): + print("pysha3 version is < 1.0. Please install from:") + print("https://github.com/tiran/pysha3https://github.com/tiran/pysha3") + sys.exit(1) + +# The first index we'll build is the position index in the hashring that is +# constructed by the hs_build_hsdir_index() function. Construction is: +# SHA3-256("node-idx" | node_identity | +# shared_random_value | INT_8(period_length) | INT_8(period_num) ) + +PREFIX = "node-idx".encode() +# 32 bytes ed25519 pubkey. +IDENTITY = ("\x42" * 32).encode() +# SRV is 32 bytes. +SRV = ("\x43" * 32).encode() +# Time period length is a 8 bytes value. +PERIOD_LEN = 1440 +# Period number is a 8 bytes value. +PERIOD_NUM = 42 + +data = struct.pack('!8s32s32sQQ', PREFIX, IDENTITY, SRV, PERIOD_NUM, + PERIOD_LEN) +hsdir_index = hashlib.sha3_256(data).hexdigest() + +print("[hs_build_hsdir_index] %s" % (hsdir_index)) + +# The second index we'll build is where the HS stores and the client fetches +# the descriptor on the hashring. It is constructed by the hs_build_hs_index() +# function and the construction is: +# SHA3-256("store-at-idx" | blinded_public_key | +# INT_8(replicanum) | INT_8(period_num) | INT_8(period_length) ) + +PREFIX = "store-at-idx".encode() +# 32 bytes ed25519 pubkey. +PUBKEY = ("\x42" * 32).encode() +# Replica number is a 8 bytes value. +REPLICA_NUM = 1 +# Time period length is a 8 bytes value. +PERIOD_LEN = 1440 +# Period number is a 8 bytes value. +PERIOD_NUM = 42 + +data = struct.pack('!12s32sQQQ', PREFIX, PUBKEY, REPLICA_NUM, PERIOD_LEN, + PERIOD_NUM) +hs_index = hashlib.sha3_256(data).hexdigest() + +print("[hs_build_hs_index] %s" % (hs_index)) diff --git a/src/test/hs_test_helpers.c b/src/test/hs_test_helpers.c index 2753d29078..9355971267 100644 --- a/src/test/hs_test_helpers.c +++ b/src/test/hs_test_helpers.c @@ -18,28 +18,29 @@ hs_helper_build_intro_point(const ed25519_keypair_t *signing_kp, time_t now, hs_desc_intro_point_t *intro_point = NULL; hs_desc_intro_point_t *ip = hs_desc_intro_point_new(); + /* For a usable intro point we need at least two link specifiers: One legacy + * keyid and one ipv4 */ { - hs_desc_link_specifier_t *ls = tor_malloc_zero(sizeof(*ls)); - if (legacy) { - ls->type = LS_LEGACY_ID; - memcpy(ls->u.legacy_id, "0299F268FCA9D55CD157976D39AE92B4B455B3A8", - DIGEST_LEN); - } else { - ls->u.ap.port = 9001; - int family = tor_addr_parse(&ls->u.ap.addr, addr); - switch (family) { - case AF_INET: - ls->type = LS_IPV4; + hs_desc_link_specifier_t *ls_legacy = tor_malloc_zero(sizeof(*ls_legacy)); + hs_desc_link_specifier_t *ls_v4 = tor_malloc_zero(sizeof(*ls_v4)); + ls_legacy->type = LS_LEGACY_ID; + memcpy(ls_legacy->u.legacy_id, "0299F268FCA9D55CD157976D39AE92B4B455B3A8", + DIGEST_LEN); + ls_v4->u.ap.port = 9001; + int family = tor_addr_parse(&ls_v4->u.ap.addr, addr); + switch (family) { + case AF_INET: + ls_v4->type = LS_IPV4; break; case AF_INET6: - ls->type = LS_IPV6; + ls_v4->type = LS_IPV6; break; default: /* Stop the test, not suppose to have an error. */ tt_int_op(family, OP_EQ, AF_INET); - } } - smartlist_add(ip->link_specifiers, ls); + smartlist_add(ip->link_specifiers, ls_legacy); + smartlist_add(ip->link_specifiers, ls_v4); } ret = ed25519_keypair_generate(&auth_kp, 0); @@ -104,7 +105,7 @@ hs_helper_build_hs_desc_impl(unsigned int no_ip, memcpy(&desc->plaintext_data.signing_pubkey, &signing_kp->pubkey, sizeof(ed25519_public_key_t)); - uint64_t current_time_period = hs_get_time_period_num(approx_time()); + uint64_t current_time_period = hs_get_time_period_num(0); hs_build_blinded_keypair(signing_kp, NULL, 0, current_time_period, &blinded_kp); /* Copy only the public key into the descriptor. */ @@ -137,7 +138,7 @@ hs_helper_build_hs_desc_impl(unsigned int no_ip, smartlist_add(desc->encrypted_data.intro_points, hs_helper_build_intro_point(signing_kp, now, "3.2.1.4", 1)); smartlist_add(desc->encrypted_data.intro_points, - hs_helper_build_intro_point(signing_kp, now, "", 1)); + hs_helper_build_intro_point(signing_kp, now, "5.6.7.8", 1)); } descp = desc; diff --git a/src/test/hs_test_helpers.h b/src/test/hs_test_helpers.h index 05f5aa7b64..b1b0490f05 100644 --- a/src/test/hs_test_helpers.h +++ b/src/test/hs_test_helpers.h @@ -21,5 +21,5 @@ void hs_helper_get_subcred_from_identity_keypair(ed25519_keypair_t *signing_kp, uint8_t *subcred_out); -#endif /* TOR_HS_TEST_HELPERS_H */ +#endif /* !defined(TOR_HS_TEST_HELPERS_H) */ diff --git a/src/test/include.am b/src/test/include.am index ced16c0a8d..8e8c9ca0da 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -332,6 +332,8 @@ EXTRA_DIST += \ src/test/bt_test.py \ src/test/ntor_ref.py \ src/test/hs_ntor_ref.py \ + src/test/hs_build_address.py \ + src/test/hs_indexes.py \ src/test/fuzz_static_testcases.sh \ src/test/slownacl_curve25519.py \ src/test/zero_length_keys.sh \ diff --git a/src/test/log_test_helpers.h b/src/test/log_test_helpers.h index f7798c0249..70c584eb37 100644 --- a/src/test/log_test_helpers.h +++ b/src/test/log_test_helpers.h @@ -101,5 +101,5 @@ void mock_dump_saved_logs(void); assert_log_predicate(!mock_saved_log_has_entry(), \ "expected log to not contain entries"); -#endif +#endif /* !defined(TOR_LOG_TEST_HELPERS_H) */ diff --git a/src/test/rend_test_helpers.h b/src/test/rend_test_helpers.h index 6f0ef114de..abf4324988 100644 --- a/src/test/rend_test_helpers.h +++ b/src/test/rend_test_helpers.h @@ -12,5 +12,5 @@ void create_descriptor(rend_service_descriptor_t **generated, char **service_id, int intro_points); rend_data_t *mock_rend_data(const char *onion_address); -#endif +#endif /* !defined(TOR_REND_TEST_HELPERS_H) */ diff --git a/src/test/test-child.c b/src/test/test-child.c index f0bdb3ea26..f78a829107 100644 --- a/src/test/test-child.c +++ b/src/test/test-child.c @@ -8,7 +8,7 @@ #include <windows.h> #else #include <unistd.h> -#endif +#endif /* defined(_WIN32) */ #include <string.h> #ifdef _WIN32 diff --git a/src/test/test.c b/src/test/test.c index 702a13ab38..70436002ee 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -20,7 +20,7 @@ #include <direct.h> #else #include <dirent.h> -#endif +#endif /* defined(_WIN32) */ /* These macros pull in declarations for some functions and structures that * are typically file-private. */ diff --git a/src/test/test.h b/src/test/test.h index f3e826afe1..109607cb36 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -55,7 +55,7 @@ #else #define U64_PRINTF_TYPE unsigned long long #define I64_PRINTF_TYPE long long -#endif +#endif /* defined(_MSC_VER) */ #define tt_size_op(a,op,b) \ tt_assert_test_fmt_type(a,b,#a" "#op" "#b,size_t,(val1_ op val2_), \ @@ -269,5 +269,5 @@ extern const char AUTHORITY_SIGNKEY_3[]; extern const char AUTHORITY_SIGNKEY_C_DIGEST[]; extern const char AUTHORITY_SIGNKEY_C_DIGEST256[]; -#endif +#endif /* !defined(TOR_TEST_H) */ diff --git a/src/test/test_addr.c b/src/test/test_addr.c index 1a3754f086..e1a40b7e60 100644 --- a/src/test/test_addr.c +++ b/src/test/test_addr.c @@ -1012,7 +1012,7 @@ test_addr_sockaddr_to_str(void *arg) s_un.sun_family = AF_UNIX; strlcpy(s_un.sun_path, "/here/is/a/path", sizeof(s_un.sun_path)); CHECK(s_un, "unix:/here/is/a/path"); -#endif +#endif /* defined(HAVE_SYS_UN_H) */ memset(&sin6,0,sizeof(sin6)); sin6.sin6_family = AF_INET6; diff --git a/src/test/test_address.c b/src/test/test_address.c index 8e1fd73033..f36ff6998b 100644 --- a/src/test/test_address.c +++ b/src/test/test_address.c @@ -21,7 +21,7 @@ #include <sys/ioctl.h> #endif #include <net/if.h> -#endif +#endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */ #include "or.h" #include "address.h" @@ -305,7 +305,7 @@ test_address_get_if_addrs_ifaddrs(void *arg) return; } -#endif +#endif /* defined(HAVE_IFADDRS_TO_SMARTLIST) */ #ifdef HAVE_IP_ADAPTER_TO_SMARTLIST @@ -421,7 +421,7 @@ test_address_ip_adapter_addresses_to_smartlist(void *arg) tor_free(sockaddr_to_check); return; } -#endif +#endif /* defined(HAVE_IP_ADAPTER_TO_SMARTLIST) */ #ifdef HAVE_IFCONF_TO_SMARTLIST @@ -543,7 +543,7 @@ test_address_get_if_addrs_ioctl(void *arg) return; } -#endif +#endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */ #define FAKE_SOCKET_FD (42) @@ -706,7 +706,7 @@ test_address_udp_socket_trick_blackbox(void *arg) tt_assert( (retval == -1 && retval_reference == -1) || (tor_addr_compare(&addr6,&addr6_to_check,CMP_EXACT) == 0) ); -#else +#else /* !(0) */ /* Both of the blackbox test cases fail horribly if: * * The host has no external addreses. * * There are multiple interfaces with either AF_INET or AF_INET6. @@ -721,7 +721,7 @@ test_address_udp_socket_trick_blackbox(void *arg) (void)addr6_to_check; (void)addr6; (void) retval_reference; -#endif +#endif /* 0 */ /* When family is neither AF_INET nor AF_INET6, we want _hack to * fail and return -1. diff --git a/src/test/test_bt_cl.c b/src/test/test_bt_cl.c index ed588ecc5b..b5c8d7cf9e 100644 --- a/src/test/test_bt_cl.c +++ b/src/test/test_bt_cl.c @@ -38,7 +38,7 @@ crash(int x) * don't need to see us dereference NULL. */ #else *(volatile int *)0 = 0; -#endif +#endif /* defined(__clang_analyzer__) || defined(__COVERITY__) */ } else if (crashtype == 1) { tor_assert(1 == 0); } else if (crashtype == -1) { diff --git a/src/test/test_channelpadding.c b/src/test/test_channelpadding.c index 1c6107a872..1e9d599318 100644 --- a/src/test/test_channelpadding.c +++ b/src/test/test_channelpadding.c @@ -1,6 +1,7 @@ #define TOR_CHANNEL_INTERNAL_ #define MAIN_PRIVATE #define NETWORKSTATUS_PRIVATE +#define TOR_TIMERS_PRIVATE #include "or.h" #include "test.h" #include "testsupport.h" @@ -30,6 +31,8 @@ void test_channelpadding_killonehop(void *arg); void dummy_nop_timer(void); +#define NSEC_PER_MSEC (1000*1000) + /* Thing to cast to fake tor_tls_t * to appease assert_connection_ok() */ static int fake_tortls = 0; /* Bleh... */ @@ -514,6 +517,7 @@ test_channelpadding_consensus(void *arg) channelpadding_decision_t decision; or_options_t *options = get_options_mutable(); int64_t val; + int64_t new_time; (void)arg; tor_libevent_postfork(); @@ -536,7 +540,9 @@ test_channelpadding_consensus(void *arg) */ channel_t *chan; routerstatus_t *relay = tor_malloc_zero(sizeof(routerstatus_t)); - monotime_init(); + monotime_enable_test_mocking(); + monotime_set_mock_time_nsec(1); + monotime_coarse_set_mock_time_nsec(1); timers_initialize(); connection_array = smartlist_new(); @@ -559,7 +565,10 @@ test_channelpadding_consensus(void *arg) tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_ALREADY_SCHEDULED); // Wait for the timer - event_base_loop(tor_libevent_get_base(), 0); + new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC; + monotime_coarse_set_mock_time_nsec(new_time); + monotime_set_mock_time_nsec(new_time); + timers_run_pending(); tt_int_op(tried_to_write_cell, OP_EQ, 1); tt_assert(!chan->pending_padding_callback); @@ -613,7 +622,10 @@ test_channelpadding_consensus(void *arg) tt_i64_op(val, OP_LE, 200); // Wait for the timer - event_base_loop(tor_libevent_get_base(), 0); + new_time = (monotime_coarse_absolute_msec()+201)*NSEC_PER_MSEC; + monotime_set_mock_time_nsec(new_time); + monotime_coarse_set_mock_time_nsec(new_time); + timers_run_pending(); tt_int_op(tried_to_write_cell, OP_EQ, 1); tt_assert(!chan->pending_padding_callback); @@ -713,6 +725,7 @@ test_channelpadding_consensus(void *arg) smartlist_free(connection_array); timers_shutdown(); + monotime_disable_test_mocking(); channel_free_all(); return; @@ -885,12 +898,16 @@ test_channelpadding_decide_to_pad_channel(void *arg) * + We should not send padding */ channel_t *chan; + int64_t new_time; connection_array = smartlist_new(); (void)arg; tor_libevent_postfork(); monotime_init(); + monotime_enable_test_mocking(); + monotime_set_mock_time_nsec(1); + monotime_coarse_set_mock_time_nsec(1); timers_initialize(); setup_full_capture_of_logs(LOG_WARN); channelpadding_new_consensus_params(NULL); @@ -922,7 +939,10 @@ test_channelpadding_decide_to_pad_channel(void *arg) tt_int_op(tried_to_write_cell, OP_EQ, 0); // Wait for the timer from case #2b - event_base_loop(tor_libevent_get_base(), 0); + new_time = (monotime_coarse_absolute_msec() + 1000)*NSEC_PER_MSEC; + monotime_set_mock_time_nsec(new_time); + monotime_coarse_set_mock_time_nsec(new_time); + timers_run_pending(); tt_int_op(tried_to_write_cell, OP_EQ, 1); tt_assert(!chan->pending_padding_callback); @@ -939,7 +959,10 @@ test_channelpadding_decide_to_pad_channel(void *arg) tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_ALREADY_SCHEDULED); // Wait for the timer - event_base_loop(tor_libevent_get_base(), 0); + new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC; + monotime_coarse_set_mock_time_nsec(new_time); + monotime_set_mock_time_nsec(new_time); + timers_run_pending(); tt_int_op(tried_to_write_cell, OP_EQ, 1); tt_assert(!chan->pending_padding_callback); @@ -971,7 +994,11 @@ test_channelpadding_decide_to_pad_channel(void *arg) channel_timestamp_active(chan); // We don't expect any timer callbacks here. Make a dummy one to be sure. - dummy_nop_timer(); + // Wait for the timer + new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC; + monotime_coarse_set_mock_time_nsec(new_time); + monotime_set_mock_time_nsec(new_time); + timers_run_pending(); tt_int_op(tried_to_write_cell, OP_EQ, 0); tt_assert(!chan->pending_padding_callback); @@ -988,7 +1015,10 @@ test_channelpadding_decide_to_pad_channel(void *arg) chan->state = CHANNEL_STATE_MAINT; // We don't expect any timer callbacks here. Make a dummy one to be sure. - dummy_nop_timer(); + new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC; + monotime_coarse_set_mock_time_nsec(new_time); + monotime_set_mock_time_nsec(new_time); + timers_run_pending(); tt_int_op(tried_to_write_cell, OP_EQ, 0); tt_assert(!chan->pending_padding_callback); @@ -1003,7 +1033,11 @@ test_channelpadding_decide_to_pad_channel(void *arg) tt_int_op(tried_to_write_cell, OP_EQ, 0); // Wait for the timer - event_base_loop(tor_libevent_get_base(), 0); + new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC; + monotime_coarse_set_mock_time_nsec(new_time); + monotime_set_mock_time_nsec(new_time); + timers_run_pending(); + tt_int_op(tried_to_write_cell, OP_EQ, 1); tt_assert(!chan->pending_padding_callback); @@ -1030,7 +1064,10 @@ test_channelpadding_decide_to_pad_channel(void *arg) free_fake_channeltls((channel_tls_t*)chan); // We don't expect any timer callbacks here. Make a dummy one to be sure. - dummy_nop_timer(); + new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC; + monotime_coarse_set_mock_time_nsec(new_time); + monotime_set_mock_time_nsec(new_time); + timers_run_pending(); tt_int_op(tried_to_write_cell, OP_EQ, 0); @@ -1038,6 +1075,7 @@ test_channelpadding_decide_to_pad_channel(void *arg) smartlist_free(connection_array); teardown_capture_of_logs(); + monotime_disable_test_mocking(); timers_shutdown(); channel_free_all(); diff --git a/src/test/test_checkdir.c b/src/test/test_checkdir.c index 38f3360b61..bf6a8376b3 100644 --- a/src/test/test_checkdir.c +++ b/src/test/test_checkdir.c @@ -20,7 +20,7 @@ #define umask(mask) ((void)0) #else #define tt_int_op_nowin(a,op,b) tt_int_op((a),op,(b)) -#endif +#endif /* defined(_WIN32) */ /** Run unit tests for private dir permission enforcement logic. */ static void diff --git a/src/test/test_config.c b/src/test/test_config.c index 379e2a0f55..9351f41653 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -279,7 +279,7 @@ test_config_check_or_create_data_subdir(void *arg) tt_assert(!is_private_dir(subpath)); tt_assert(!check_or_create_data_subdir(subdir)); tt_assert(is_private_dir(subpath)); -#endif +#endif /* !defined (_WIN32) */ done: rmdir(subpath); @@ -4005,7 +4005,7 @@ test_config_parse_port_config__ports__ports_given(void *data) tt_int_op(port_cfg->entry_cfg.onion_traffic, OP_EQ, 1); tt_int_op(port_cfg->entry_cfg.cache_ipv4_answers, OP_EQ, 1); tt_int_op(port_cfg->entry_cfg.prefer_ipv6_virtaddr, OP_EQ, 1); -#endif +#endif /* defined(_WIN32) */ // Test failure if we have no ipv4 and no ipv6 and no onion (DNS only) config_free_lines(config_port_invalid); config_port_invalid = NULL; @@ -4077,7 +4077,7 @@ test_config_parse_port_config__ports__ports_given(void *data) tt_int_op(port_cfg->entry_cfg.ipv4_traffic, OP_EQ, 0); tt_int_op(port_cfg->entry_cfg.ipv6_traffic, OP_EQ, 0); tt_int_op(port_cfg->entry_cfg.onion_traffic, OP_EQ, 1); -#endif +#endif /* defined(_WIN32) */ // Test success with quoted unix: address. config_free_lines(config_port_valid); config_port_valid = NULL; @@ -4099,7 +4099,7 @@ test_config_parse_port_config__ports__ports_given(void *data) tt_int_op(port_cfg->entry_cfg.ipv4_traffic, OP_EQ, 0); tt_int_op(port_cfg->entry_cfg.ipv6_traffic, OP_EQ, 0); tt_int_op(port_cfg->entry_cfg.onion_traffic, OP_EQ, 1); -#endif +#endif /* defined(_WIN32) */ // Test failure with broken quoted unix: address. config_free_lines(config_port_valid); config_port_valid = NULL; @@ -4144,7 +4144,7 @@ test_config_parse_port_config__ports__ports_given(void *data) tt_int_op(port_cfg->entry_cfg.ipv4_traffic, OP_EQ, 0); tt_int_op(port_cfg->entry_cfg.ipv6_traffic, OP_EQ, 0); tt_int_op(port_cfg->entry_cfg.onion_traffic, OP_EQ, 1); -#endif +#endif /* defined(_WIN32) */ // Test success with no ipv4 but take ipv6 config_free_lines(config_port_valid); config_port_valid = NULL; @@ -4163,7 +4163,7 @@ test_config_parse_port_config__ports__ports_given(void *data) port_cfg = (port_cfg_t *)smartlist_get(slout, 0); tt_int_op(port_cfg->entry_cfg.ipv4_traffic, OP_EQ, 0); tt_int_op(port_cfg->entry_cfg.ipv6_traffic, OP_EQ, 1); -#endif +#endif /* defined(_WIN32) */ // Test success with both ipv4 and ipv6 config_free_lines(config_port_valid); config_port_valid = NULL; @@ -4182,7 +4182,7 @@ test_config_parse_port_config__ports__ports_given(void *data) port_cfg = (port_cfg_t *)smartlist_get(slout, 0); tt_int_op(port_cfg->entry_cfg.ipv4_traffic, OP_EQ, 1); tt_int_op(port_cfg->entry_cfg.ipv6_traffic, OP_EQ, 1); -#endif +#endif /* defined(_WIN32) */ // Test failure if we specify world writable for an IP Port config_free_lines(config_port_invalid); config_port_invalid = NULL; @@ -4646,7 +4646,7 @@ test_config_parse_port_config__ports__ports_given(void *data) tt_int_op(smartlist_len(slout), OP_EQ, 1); port_cfg = (port_cfg_t *)smartlist_get(slout, 0); tt_int_op(port_cfg->is_group_writable, OP_EQ, 1); -#endif +#endif /* defined(_WIN32) */ done: if (slout) diff --git a/src/test/test_consdiff.c b/src/test/test_consdiff.c index ad362796cb..fda3a7f186 100644 --- a/src/test/test_consdiff.c +++ b/src/test/test_consdiff.c @@ -1108,7 +1108,7 @@ test_consdiff_apply_diff(void *arg) tt_ptr_op(NULL, OP_EQ, cons2); expect_log_msg_containing("Could not compute digests of the consensus " "resulting from applying a consensus diff."); -#endif +#endif /* 0 */ /* Very simple test, only to see that nothing errors. */ smartlist_clear(diff); diff --git a/src/test/test_consdiffmgr.c b/src/test/test_consdiffmgr.c index cb8ed8b649..80d3f943ab 100644 --- a/src/test/test_consdiffmgr.c +++ b/src/test/test_consdiffmgr.c @@ -230,7 +230,7 @@ test_consdiffmgr_init_failure(void *arg) done: tor_end_capture_bugs_(); } -#endif +#endif /* 0 */ static void test_consdiffmgr_sha3_helper(void *arg) diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c index 5d079e9f30..c8443fd3bb 100644 --- a/src/test/test_crypto.c +++ b/src/test/test_crypto.c @@ -1383,7 +1383,7 @@ do_truncate(const char *fname, size_t len) tor_free(bytes); return r; } -#endif +#endif /* defined(HAVE_TRUNCATE) */ /** Sanity check for crypto pk digests */ static void @@ -1907,7 +1907,7 @@ test_crypto_curve25519_impl(void *arg) "e0544770bc7de853b38f9100489e3e79"; const char e1e2k_expected[] = "cd6e8269104eb5aaee886bd2071fba88" "bd13861475516bc2cd2b6e005e805064"; -#else +#else /* !(defined(SLOW_CURVE25519_TEST)) */ const int loop_max=200; const char e1_expected[] = "bc7112cde03f97ef7008cad1bdc56be3" "c6a1037d74cceb3712e9206871dcf654"; @@ -1915,7 +1915,7 @@ test_crypto_curve25519_impl(void *arg) "8e3ee1a63c7d14274ea5d4c67f065467"; const char e1e2k_expected[] = "7ddb98bd89025d2347776b33901b3e7e" "c0ee98cb2257a4545c0cfb2ca3e1812b"; -#endif +#endif /* defined(SLOW_CURVE25519_TEST) */ unsigned char e1k[32]; unsigned char e2k[32]; diff --git a/src/test/test_crypto_openssl.c b/src/test/test_crypto_openssl.c index f6817398da..090cb4242b 100644 --- a/src/test/test_crypto_openssl.c +++ b/src/test/test_crypto_openssl.c @@ -38,7 +38,7 @@ test_crypto_rng_engine(void *arg) #else tt_assert(RAND_get_rand_method() == &dummy_method); tt_int_op(1, OP_EQ, crypto_force_rand_ssleay()); -#endif +#endif /* defined(LIBRESSL_VERSION_NUMBER) */ tt_assert(RAND_get_rand_method() == RAND_OpenSSL()); /* Make sure we aren't calling dummy_method */ diff --git a/src/test/test_crypto_slow.c b/src/test/test_crypto_slow.c index b25d472a57..2afb71ff5a 100644 --- a/src/test/test_crypto_slow.c +++ b/src/test/test_crypto_slow.c @@ -242,7 +242,7 @@ test_libscrypt_eq_openssl(void *arg) done: return; } -#endif +#endif /* defined(HAVE_LIBSCRYPT) && defined(HAVE_EVP_PBE_SCRYPT) */ static void test_crypto_s2k_errors(void *arg) @@ -283,7 +283,7 @@ test_crypto_s2k_errors(void *arg) "ABC", 3, 0)); tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 50, &sz, "ABC", 3, S2K_FLAG_LOW_MEM)); -#endif +#endif /* defined(HAVE_LIBSCRYPT) */ tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 37, &sz, "ABC", 3, S2K_FLAG_USE_PBKDF2)); tt_int_op(S2K_TRUNCATED, OP_EQ, secret_to_key_new(buf, 29, &sz, @@ -318,7 +318,7 @@ test_crypto_s2k_errors(void *arg) tt_int_op(S2K_BAD_PARAMS, OP_EQ, secret_to_key_derivekey(buf2, sizeof(buf2), buf, 19, "ABC", 3)); -#endif +#endif /* defined(HAVE_LIBSCRYPT) */ done: ; @@ -600,7 +600,7 @@ struct testcase_t slow_crypto_tests[] = { #ifdef HAVE_EVP_PBE_SCRYPT { "libscrypt_eq_openssl", test_libscrypt_eq_openssl, 0, NULL, NULL }, #endif -#endif +#endif /* defined(HAVE_LIBSCRYPT) */ { "s2k_pbkdf2", test_crypto_s2k_general, 0, &passthrough_setup, (void*)"pbkdf2" }, { "s2k_rfc2440_general", test_crypto_s2k_general, 0, &passthrough_setup, diff --git a/src/test/test_dir.c b/src/test/test_dir.c index 3d1fb00dba..2d48cfc3c4 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -423,7 +423,7 @@ test_dir_formats(void *arg) add_fingerprint_to_dir(buf, fingerprint_list, 0); } -#endif +#endif /* 0 */ dirserv_free_fingerprint_list(); done: diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c index c4c74df662..e60884c867 100644 --- a/src/test/test_dir_handle_get.c +++ b/src/test/test_dir_handle_get.c @@ -39,7 +39,7 @@ #include <direct.h> #else #include <dirent.h> -#endif +#endif /* defined(_WIN32) */ #ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS DISABLE_GCC_WARNING(overlength-strings) @@ -1795,7 +1795,7 @@ status_vote_current_consensus_ns_test(char **header, char **body, dirserv_set_cached_consensus_networkstatus(NETWORK_STATUS, "ns", &digests, sha3, time(NULL)); -#endif +#endif /* 0 */ networkstatus_t *ns = tor_malloc_zero(sizeof(networkstatus_t)); ns->type = NS_TYPE_CONSENSUS; ns->flavor = FLAV_NS; diff --git a/src/test/test_entryconn.c b/src/test/test_entryconn.c index 2d28f1d428..86c0c3dca4 100644 --- a/src/test/test_entryconn.c +++ b/src/test/test_entryconn.c @@ -76,7 +76,6 @@ test_entryconn_rewrite_bad_dotexit(void *arg) entry_connection_t *ec = arg; rewrite_result_t rr; - get_options_mutable()->AllowDotExit = 0; tt_assert(ec->socks_request); strlcpy(ec->socks_request->address, "www.TORproject.org.foo.exit", sizeof(ec->socks_request->address)); @@ -286,7 +285,7 @@ test_entryconn_rewrite_automap_reverse(void *arg) done: connection_free_(ENTRY_TO_CONN(ec2)); } -#endif +#endif /* 0 */ /* Rewrite because of cached DNS entry. */ static void @@ -480,7 +479,7 @@ test_entryconn_rewrite_reject_internal_reverse(void *arg) ; } -/* Rewrite into .exit because of virtual address mapping */ +/* Rewrite into .exit because of virtual address mapping. */ static void test_entryconn_rewrite_automap_exit(void *arg) { @@ -491,43 +490,21 @@ test_entryconn_rewrite_automap_exit(void *arg) ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET); - get_options_mutable()->AutomapHostsOnResolve = 1; - get_options_mutable()->AllowDotExit = 1; smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes, ".EXIT"); parse_virtual_addr_network("127.1.0.0/16", AF_INET, 0, &msg); - /* Automap this on resolve. */ + /* Try to automap this on resolve. */ strlcpy(ec->socks_request->address, "website.example.exit", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_RESOLVE; connection_ap_handshake_rewrite(ec, &rr); - tt_int_op(rr.automap, OP_EQ, 1); - tt_int_op(rr.should_close, OP_EQ, 0); - tt_int_op(rr.end_reason, OP_EQ, 0); - tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); - tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); - tt_str_op(rr.orig_address, OP_EQ, "website.example.exit"); - tt_str_op(ec->original_dest_address, OP_EQ, "website.example.exit"); - - tt_assert(!strcmpstart(ec->socks_request->address,"127.1.")); - - /* Connect to it and make sure we get the original address back. */ - strlcpy(ec2->socks_request->address, ec->socks_request->address, - sizeof(ec2->socks_request->address)); - - ec2->socks_request->command = SOCKS_COMMAND_CONNECT; - connection_ap_handshake_rewrite(ec2, &rr); - + /* Make sure it isn't allowed -- there is no longer an AllowDotExit + * option. */ tt_int_op(rr.automap, OP_EQ, 0); - tt_int_op(rr.should_close, OP_EQ, 0); - tt_int_op(rr.end_reason, OP_EQ, 0); - tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); - tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_AUTOMAP); - tt_str_op(rr.orig_address, OP_EQ, ec->socks_request->address); - tt_str_op(ec2->original_dest_address, OP_EQ, ec->socks_request->address); - tt_str_op(ec2->socks_request->address, OP_EQ, "website.example.exit"); + tt_int_op(rr.should_close, OP_EQ, 1); + tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_TORPROTOCOL); done: connection_free_(ENTRY_TO_CONN(ec2)); @@ -577,7 +554,6 @@ test_entryconn_rewrite_mapaddress_automap_onion(void *arg) ec4 = entry_connection_new(CONN_TYPE_AP, AF_INET); get_options_mutable()->AutomapHostsOnResolve = 1; - get_options_mutable()->AllowDotExit = 1; smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes, ".onion"); parse_virtual_addr_network("192.168.0.0/16", AF_INET, 0, &msg); @@ -801,7 +777,7 @@ test_entryconn_rewrite_onion_v3(void *arg) /* Make a SOCKS request */ conn->socks_request->command = SOCKS_COMMAND_CONNECT; strlcpy(conn->socks_request->address, - "git.p3xnclpu4mu22dwaurjtsybyqk4xfjmcfz6z62yl24uwmhjatiwnlnad.onion", + "git.25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid.onion", sizeof(conn->socks_request->address)); /* Make an onion connection using the SOCKS request */ @@ -818,7 +794,7 @@ test_entryconn_rewrite_onion_v3(void *arg) tt_int_op(ENTRY_TO_CONN(conn)->state, OP_EQ, AP_CONN_STATE_CIRCUIT_WAIT); /* check that the address got rewritten */ tt_str_op(conn->socks_request->address, OP_EQ, - "p3xnclpu4mu22dwaurjtsybyqk4xfjmcfz6z62yl24uwmhjatiwnlnad"); + "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid"); /* check that HS information got attached to the connection */ tt_assert(ENTRY_TO_EDGE_CONN(conn)->hs_ident); tt_assert(!ENTRY_TO_EDGE_CONN(conn)->rend_data); diff --git a/src/test/test_extorport.c b/src/test/test_extorport.c index 9e8721ee36..e18deb2700 100644 --- a/src/test/test_extorport.c +++ b/src/test/test_extorport.c @@ -497,14 +497,14 @@ test_ext_or_handshake(void *arg) "te road There is always another ", 64); /* Send the wrong response. */ WRITE("not with a bang but a whimper...", 32); - MOCK(control_event_bootstrap_problem, ignore_bootstrap_problem); + MOCK(control_event_bootstrap_prob_or, ignore_bootstrap_problem); tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn)); CONTAINS("\x00", 1); tt_assert(TO_CONN(conn)->marked_for_close); /* XXXX Hold-open-until-flushed. */ close_closeable_connections(); conn = NULL; - UNMOCK(control_event_bootstrap_problem); + UNMOCK(control_event_bootstrap_prob_or); MOCK(connection_start_reading, note_read_started); MOCK(connection_stop_reading, note_read_stopped); @@ -552,26 +552,26 @@ test_ext_or_handshake(void *arg) do_ext_or_handshake(conn); /* USERADDR command with an extra NUL byte */ WRITE("\x00\x01\x00\x0d""1.2.3.4:5678\x00", 17); - MOCK(control_event_bootstrap_problem, ignore_bootstrap_problem); + MOCK(control_event_bootstrap_prob_or, ignore_bootstrap_problem); tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn)); CONTAINS("", 0); tt_assert(TO_CONN(conn)->marked_for_close); close_closeable_connections(); conn = NULL; - UNMOCK(control_event_bootstrap_problem); + UNMOCK(control_event_bootstrap_prob_or); /* Now fail the TRANSPORT command. */ conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET); do_ext_or_handshake(conn); /* TRANSPORT command with an extra NUL byte */ WRITE("\x00\x02\x00\x08""rfc1149\x00", 12); - MOCK(control_event_bootstrap_problem, ignore_bootstrap_problem); + MOCK(control_event_bootstrap_prob_or, ignore_bootstrap_problem); tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn)); CONTAINS("", 0); tt_assert(TO_CONN(conn)->marked_for_close); close_closeable_connections(); conn = NULL; - UNMOCK(control_event_bootstrap_problem); + UNMOCK(control_event_bootstrap_prob_or); /* Now fail the TRANSPORT command. */ conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET); @@ -579,13 +579,13 @@ test_ext_or_handshake(void *arg) /* TRANSPORT command with transport name with symbols (not a C-identifier) */ WRITE("\x00\x02\x00\x07""rf*1149", 11); - MOCK(control_event_bootstrap_problem, ignore_bootstrap_problem); + MOCK(control_event_bootstrap_prob_or, ignore_bootstrap_problem); tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn)); CONTAINS("", 0); tt_assert(TO_CONN(conn)->marked_for_close); close_closeable_connections(); conn = NULL; - UNMOCK(control_event_bootstrap_problem); + UNMOCK(control_event_bootstrap_prob_or); done: UNMOCK(connection_write_to_buf_impl_); diff --git a/src/test/test_helpers.h b/src/test/test_helpers.h index 847104a40a..9bc8553257 100644 --- a/src/test/test_helpers.h +++ b/src/test/test_helpers.h @@ -28,5 +28,5 @@ or_options_t *helper_parse_options(const char *conf); extern const char TEST_DESCRIPTORS[]; -#endif /* TOR_TEST_HELPERS_H */ +#endif /* !defined(TOR_TEST_HELPERS_H) */ diff --git a/src/test/test_hs_cache.c b/src/test/test_hs_cache.c index 950c0483d1..91b13be862 100644 --- a/src/test/test_hs_cache.c +++ b/src/test/test_hs_cache.c @@ -14,6 +14,7 @@ #include "hs_cache.h" #include "rendcache.h" #include "directory.h" +#include "networkstatus.h" #include "connection.h" #include "proto_http.h" @@ -433,6 +434,15 @@ test_hsdir_revision_counter_check(void *arg) tor_free(published_desc_str); } +static networkstatus_t mock_ns; + +static networkstatus_t * +mock_networkstatus_get_live_consensus(time_t now) +{ + (void) now; + return &mock_ns; +} + /** Test that we can store HS descriptors in the client HS cache. */ static void test_client_cache(void *arg) @@ -441,7 +451,7 @@ test_client_cache(void *arg) ed25519_keypair_t signing_kp; hs_descriptor_t *published_desc = NULL; char *published_desc_str = NULL; - + uint8_t wanted_subcredential[DIGEST256_LEN]; response_handler_args_t *args = NULL; dir_connection_t *conn = NULL; @@ -450,6 +460,17 @@ test_client_cache(void *arg) /* Initialize HSDir cache subsystem */ init_test(); + MOCK(networkstatus_get_live_consensus, + mock_networkstatus_get_live_consensus); + + /* Set consensus time */ + parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC", + &mock_ns.valid_after); + parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC", + &mock_ns.fresh_until); + parse_rfc1123_time("Sat, 26 Oct 1985 16:00:00 UTC", + &mock_ns.valid_until); + /* Generate a valid descriptor with normal values. */ { retval = ed25519_keypair_generate(&signing_kp, 0); @@ -459,6 +480,8 @@ test_client_cache(void *arg) retval = hs_desc_encode_descriptor(published_desc, &signing_kp, &published_desc_str); tt_int_op(retval, OP_EQ, 0); + memcpy(wanted_subcredential, published_desc->subcredential, DIGEST256_LEN); + tt_assert(!tor_mem_is_zero((char*)wanted_subcredential, DIGEST256_LEN)); } /* Test handle_response_fetch_hsdesc_v3() */ @@ -478,12 +501,36 @@ test_client_cache(void *arg) retval = handle_response_fetch_hsdesc_v3(conn, args); tt_int_op(retval, == , 0); - /* fetch the descriptor and make sure it's there */ + /* Progress time a bit and attempt to clean cache: our desc should not be + * cleaned since we still in the same TP. */ { - hs_cache_client_descriptor_t *cached_desc = NULL; - cached_desc = lookup_v3_desc_as_client(signing_kp.pubkey.pubkey); + parse_rfc1123_time("Sat, 27 Oct 1985 02:00:00 UTC", + &mock_ns.valid_after); + parse_rfc1123_time("Sat, 27 Oct 1985 03:00:00 UTC", + &mock_ns.fresh_until); + parse_rfc1123_time("Sat, 27 Oct 1985 05:00:00 UTC", + &mock_ns.valid_until); + + /* fetch the descriptor and make sure it's there */ + const hs_descriptor_t *cached_desc = NULL; + cached_desc = hs_cache_lookup_as_client(&signing_kp.pubkey); tt_assert(cached_desc); - tt_str_op(cached_desc->encoded_desc, OP_EQ, published_desc_str); + tt_mem_op(cached_desc->subcredential, OP_EQ, wanted_subcredential, + DIGEST256_LEN); + } + + /* Progress time to next TP and check that desc was cleaned */ + { + parse_rfc1123_time("Sat, 27 Oct 1985 12:00:00 UTC", + &mock_ns.valid_after); + parse_rfc1123_time("Sat, 27 Oct 1985 13:00:00 UTC", + &mock_ns.fresh_until); + parse_rfc1123_time("Sat, 27 Oct 1985 15:00:00 UTC", + &mock_ns.valid_until); + + const hs_descriptor_t *cached_desc = NULL; + cached_desc = hs_cache_lookup_as_client(&signing_kp.pubkey); + tt_assert(!cached_desc); } done: diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c index 6714daceae..38878d6ed5 100644 --- a/src/test/test_hs_client.c +++ b/src/test/test_hs_client.c @@ -8,6 +8,7 @@ #define CRYPTO_PRIVATE #define MAIN_PRIVATE +#define HS_CLIENT_PRIVATE #define TOR_CHANNEL_INTERNAL_ #define CIRCUITBUILD_PRIVATE #define CIRCUITLIST_PRIVATE @@ -17,17 +18,22 @@ #include "test_helpers.h" #include "log_test_helpers.h" #include "rend_test_helpers.h" +#include "hs_test_helpers.h" #include "config.h" #include "crypto.h" #include "channeltls.h" +#include "routerset.h" #include "hs_circuit.h" +#include "hs_client.h" #include "hs_ident.h" +#include "hs_cache.h" #include "circuitlist.h" #include "circuitbuild.h" #include "connection.h" #include "connection_edge.h" +#include "networkstatus.h" static int mock_connection_ap_handshake_send_begin(entry_connection_t *ap_conn) @@ -36,6 +42,15 @@ mock_connection_ap_handshake_send_begin(entry_connection_t *ap_conn) return 0; } +static networkstatus_t mock_ns; + +static networkstatus_t * +mock_networkstatus_get_live_consensus(time_t now) +{ + (void) now; + return &mock_ns; +} + /* Test helper function: Setup a circuit and a stream with the same hidden * service destination, and put them in <b>circ_out</b> and * <b>conn_out</b>. Make the stream wait for circuits to be established to the @@ -278,11 +293,176 @@ test_e2e_rend_circuit_setup(void *arg) circuit_free(TO_CIRCUIT(or_circ)); } +/** Test client logic for picking intro points from a descriptor. Also test how + * ExcludeNodes and intro point failures affect picking intro points. */ +static void +test_client_pick_intro(void *arg) +{ + int ret; + ed25519_keypair_t service_kp; + hs_descriptor_t *desc = NULL; + + MOCK(networkstatus_get_live_consensus, + mock_networkstatus_get_live_consensus); + + (void) arg; + + hs_init(); + + /* Generate service keypair */ + tt_int_op(0, OP_EQ, ed25519_keypair_generate(&service_kp, 0)); + + /* Set time */ + ret = parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC", + &mock_ns.valid_after); + tt_int_op(ret, OP_EQ, 0); + ret = parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC", + &mock_ns.fresh_until); + tt_int_op(ret, OP_EQ, 0); + + update_approx_time(mock_ns.fresh_until-10); + time_t now = approx_time(); + + /* Test logic: + * + * 1) Add our desc with intro points to the HS cache. + * + * 2) Mark all descriptor intro points except _the chosen one_ as + * failed. Then query the desc to get a random intro: check that we got + * _the chosen one_. Then fail the chosen one as well, and see that no + * intros are returned. + * + * 3) Then clean the intro state cache and get an intro point. + * + * 4) Try fetching an intro with the wrong service key: shouldn't work + * + * 5) Set StrictNodes and put all our intro points in ExcludeNodes: see that + * nothing is returned. + */ + + /* 1) Add desc to HS cache */ + { + char *encoded = NULL; + desc = hs_helper_build_hs_desc_with_ip(&service_kp); + ret = hs_desc_encode_descriptor(desc, &service_kp, &encoded); + tt_int_op(ret, OP_EQ, 0); + tt_assert(encoded); + + /* store it */ + hs_cache_store_as_client(encoded, &service_kp.pubkey); + + /* fetch it to make sure it works */ + const hs_descriptor_t *fetched_desc = + hs_cache_lookup_as_client(&service_kp.pubkey); + tt_assert(fetched_desc); + tt_mem_op(fetched_desc->subcredential, OP_EQ, desc->subcredential, + DIGEST256_LEN); + tt_assert(!tor_mem_is_zero((char*)fetched_desc->subcredential, + DIGEST256_LEN)); + tor_free(encoded); + } + + /* 2) Mark all intro points except _the chosen one_ as failed. Then query the + * desc and get a random intro: check that we got _the chosen one_. */ + { + /* Pick the chosen intro point and get its ei */ + hs_desc_intro_point_t *chosen_intro_point = + smartlist_get(desc->encrypted_data.intro_points, 0); + extend_info_t *chosen_intro_ei = + desc_intro_point_to_extend_info(chosen_intro_point); + tt_assert(chosen_intro_point); + tt_assert(chosen_intro_ei); + + /* Now mark all other intro points as failed */ + SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points, + hs_desc_intro_point_t *, ip) { + /* Skip the chosen intro point */ + if (ip == chosen_intro_point) { + continue; + } + ed25519_public_key_t *intro_auth_key = &ip->auth_key_cert->signed_key; + hs_cache_client_intro_state_note(&service_kp.pubkey, + intro_auth_key, + INTRO_POINT_FAILURE_GENERIC); + } SMARTLIST_FOREACH_END(ip); + + /* Try to get a random intro: Should return the chosen one! */ + extend_info_t *ip = client_get_random_intro(&service_kp.pubkey); + tor_assert(ip); + tt_assert(!tor_mem_is_zero((char*)ip->identity_digest, DIGEST_LEN)); + tt_mem_op(ip->identity_digest, OP_EQ, chosen_intro_ei->identity_digest, + DIGEST_LEN); + + extend_info_free(chosen_intro_ei); + extend_info_free(ip); + + /* Now also mark the chosen one as failed: See that we can't get any intro + points anymore. */ + hs_cache_client_intro_state_note(&service_kp.pubkey, + &chosen_intro_point->auth_key_cert->signed_key, + INTRO_POINT_FAILURE_TIMEOUT); + ip = client_get_random_intro(&service_kp.pubkey); + tor_assert(!ip); + } + + /* 3) Clean the intro state cache and get an intro point */ + { + /* Pretend we are 5 mins in the future and order a cleanup of the intro + * state. This should clean up the intro point failures and allow us to get + * an intro. */ + hs_cache_client_intro_state_clean(now + 5*60); + + /* Get an intro. It should work! */ + extend_info_t *ip = client_get_random_intro(&service_kp.pubkey); + tor_assert(ip); + extend_info_free(ip); + } + + /* 4) Try fetching an intro with the wrong service key: shouldn't work */ + { + ed25519_keypair_t dummy_kp; + tt_int_op(0, OP_EQ, ed25519_keypair_generate(&dummy_kp, 0)); + extend_info_t *ip = client_get_random_intro(&dummy_kp.pubkey); + tor_assert(!ip); + } + + /* 5) Set StrictNodes and put all our intro points in ExcludeNodes: see that + * nothing is returned. */ + { + get_options_mutable()->ExcludeNodes = routerset_new(); + get_options_mutable()->StrictNodes = 1; + SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points, + hs_desc_intro_point_t *, ip) { + extend_info_t *intro_ei = desc_intro_point_to_extend_info(ip); + if (intro_ei) { + const char *ptr; + char ip_addr[TOR_ADDR_BUF_LEN]; + /* We need to decorate in case it is an IPv6 else routerset_parse() + * doesn't like it. */ + ptr = tor_addr_to_str(ip_addr, &intro_ei->addr, sizeof(ip_addr), 1); + tt_assert(ptr == ip_addr); + ret = routerset_parse(get_options_mutable()->ExcludeNodes, + ip_addr, ""); + tt_int_op(ret, OP_EQ, 0); + extend_info_free(intro_ei); + } + } SMARTLIST_FOREACH_END(ip); + + extend_info_t *ip = client_get_random_intro(&service_kp.pubkey); + tt_assert(!ip); + } + + done: + hs_descriptor_free(desc); +} + struct testcase_t hs_client_tests[] = { { "e2e_rend_circuit_setup_legacy", test_e2e_rend_circuit_setup_legacy, TT_FORK, NULL, NULL }, { "e2e_rend_circuit_setup", test_e2e_rend_circuit_setup, TT_FORK, NULL, NULL }, + { "client_pick_intro", test_client_pick_intro, + TT_FORK, NULL, NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_hs_common.c b/src/test/test_hs_common.c index 3cacbab0f0..22fed12f1e 100644 --- a/src/test/test_hs_common.c +++ b/src/test/test_hs_common.c @@ -77,7 +77,7 @@ test_validate_address(void *arg) /* Valid address. */ ret = hs_address_is_valid( - "p3xnclpu4mu22dwaurjtsybyqk4xfjmcfz6z62yl24uwmhjatiwnlnad"); + "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid"); tt_int_op(ret, OP_EQ, 1); done: @@ -90,19 +90,23 @@ mock_write_str_to_file(const char *path, const char *str, int bin) (void)bin; tt_str_op(path, OP_EQ, "/double/five"PATH_SEPARATOR"squared"); tt_str_op(str, OP_EQ, - "ijbeeqscijbeeqscijbeeqscijbeeqscijbeeqscijbeeqscijbezhid.onion\n"); + "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid.onion\n"); done: return 0; } -/** Test building HS v3 onion addresses */ +/** Test building HS v3 onion addresses. Uses test vectors from the + * ./hs_build_address.py script. */ static void test_build_address(void *arg) { int ret; char onion_addr[HS_SERVICE_ADDR_LEN_BASE32 + 1]; ed25519_public_key_t pubkey; + /* hex-encoded ed25519 pubkey used in hs_build_address.py */ + char pubkey_hex[] = + "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"; hs_service_t *service = NULL; (void) arg; @@ -112,11 +116,11 @@ test_build_address(void *arg) /* The following has been created with hs_build_address.py script that * follows proposal 224 specification to build an onion address. */ static const char *test_addr = - "ijbeeqscijbeeqscijbeeqscijbeeqscijbeeqscijbeeqscijbezhid"; + "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid"; - /* Let's try to build the same onion address that the script can do. Key is - * a long set of very random \x42 :). */ - memset(&pubkey, '\x42', sizeof(pubkey)); + /* Let's try to build the same onion address as the script */ + base16_decode((char*)pubkey.pubkey, sizeof(pubkey.pubkey), + pubkey_hex, strlen(pubkey_hex)); hs_build_address(&pubkey, HS_VERSION_THREE, onion_addr); tt_str_op(test_addr, OP_EQ, onion_addr); /* Validate that address. */ @@ -474,9 +478,13 @@ test_desc_reupload_logic(void *arg) /* Let's start by building our descriptor and service */ hs_service_descriptor_t *desc = service_descriptor_new(); hs_service_t *service = NULL; + /* hex-encoded ed25519 pubkey used in hs_build_address.py */ + char pubkey_hex[] = + "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"; char onion_addr[HS_SERVICE_ADDR_LEN_BASE32 + 1]; ed25519_public_key_t pubkey; - memset(&pubkey, '\x42', sizeof(pubkey)); + base16_decode((char*)pubkey.pubkey, sizeof(pubkey.pubkey), + pubkey_hex, strlen(pubkey_hex)); hs_build_address(&pubkey, HS_VERSION_THREE, onion_addr); service = tor_malloc_zero(sizeof(hs_service_t)); memcpy(service->onion_address, onion_addr, sizeof(service->onion_address)); @@ -759,7 +767,7 @@ test_parse_extended_hostname(void *arg) char address6[] = "foo.bar.abcdefghijklmnop.onion"; char address7[] = ".abcdefghijklmnop.onion"; char address8[] = - "www.p3xnclpu4mu22dwaurjtsybyqk4xfjmcfz6z62yl24uwmhjatiwnlnad.onion"; + "www.25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid.onion"; tt_assert(BAD_HOSTNAME == parse_extended_hostname(address1)); tt_assert(ONION_V2_HOSTNAME == parse_extended_hostname(address2)); @@ -773,7 +781,7 @@ test_parse_extended_hostname(void *arg) tt_assert(BAD_HOSTNAME == parse_extended_hostname(address7)); tt_assert(ONION_V3_HOSTNAME == parse_extended_hostname(address8)); tt_str_op(address8, OP_EQ, - "p3xnclpu4mu22dwaurjtsybyqk4xfjmcfz6z62yl24uwmhjatiwnlnad"); + "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid"); done: ; } @@ -1446,31 +1454,102 @@ helper_client_pick_hsdir(const ed25519_public_key_t *onion_identity_pk, ; } -/** Set the consensus and system time based on <b>between_srv_and_tp</b>. If - * <b>between_srv_and_tp</b> is set, then set the time to be inside the time - * segment between SRV#N and TP#N. */ +static void +test_hs_indexes(void *arg) +{ + int ret; + uint64_t period_num = 42; + ed25519_public_key_t pubkey; + + (void) arg; + + /* Build the hs_index */ + { + uint8_t hs_index[DIGEST256_LEN]; + const char *b32_test_vector = + "37e5cbbd56a22823714f18f1623ece5983a0d64c78495a8cfab854245e5f9a8a"; + char test_vector[DIGEST256_LEN]; + ret = base16_decode(test_vector, sizeof(test_vector), b32_test_vector, + strlen(b32_test_vector)); + tt_int_op(ret, OP_EQ, sizeof(test_vector)); + /* Our test vector uses a public key set to 32 bytes of \x42. */ + memset(&pubkey, '\x42', sizeof(pubkey)); + hs_build_hs_index(1, &pubkey, period_num, hs_index); + tt_mem_op(hs_index, OP_EQ, test_vector, sizeof(hs_index)); + } + + /* Build the hsdir_index */ + { + uint8_t srv[DIGEST256_LEN]; + uint8_t hsdir_index[DIGEST256_LEN]; + const char *b32_test_vector = + "db475361014a09965e7e5e4d4a25b8f8d4b8f16cb1d8a7e95eed50249cc1a2d5"; + char test_vector[DIGEST256_LEN]; + ret = base16_decode(test_vector, sizeof(test_vector), b32_test_vector, + strlen(b32_test_vector)); + tt_int_op(ret, OP_EQ, sizeof(test_vector)); + /* Our test vector uses a public key set to 32 bytes of \x42. */ + memset(&pubkey, '\x42', sizeof(pubkey)); + memset(srv, '\x43', sizeof(srv)); + hs_build_hsdir_index(&pubkey, srv, period_num, hsdir_index); + tt_mem_op(hsdir_index, OP_EQ, test_vector, sizeof(hsdir_index)); + } + + done: + ; +} + +#define EARLY_IN_SRV_TO_TP 0 +#define LATE_IN_SRV_TO_TP 1 +#define EARLY_IN_TP_TO_SRV 2 +#define LATE_IN_TP_TO_SRV 3 + +/** Set the consensus and system time based on <b>position</b>. See the + * following diagram for details: + * + * +------------------------------------------------------------------+ + * | | + * | 00:00 12:00 00:00 12:00 00:00 12:00 | + * | SRV#1 TP#1 SRV#2 TP#2 SRV#3 TP#3 | + * | | + * | $==========|-----------$===========|----------$===========| | + * | | + * | | + * +------------------------------------------------------------------+ + */ static time_t -helper_set_consensus_and_system_time(networkstatus_t *ns, - int between_srv_and_tp) +helper_set_consensus_and_system_time(networkstatus_t *ns, int position) { - time_t real_time; + time_t real_time = 0; /* The period between SRV#N and TP#N is from 00:00 to 12:00 UTC. Consensus * valid_after is what matters here, the rest is just to specify the voting * period correctly. */ - if (between_srv_and_tp) { + if (position == LATE_IN_SRV_TO_TP) { parse_rfc1123_time("Wed, 13 Apr 2016 11:00:00 UTC", &ns->valid_after); parse_rfc1123_time("Wed, 13 Apr 2016 12:00:00 UTC", &ns->fresh_until); parse_rfc1123_time("Wed, 13 Apr 2016 14:00:00 UTC", &ns->valid_until); - } else { + } else if (position == EARLY_IN_TP_TO_SRV) { parse_rfc1123_time("Wed, 13 Apr 2016 13:00:00 UTC", &ns->valid_after); parse_rfc1123_time("Wed, 13 Apr 2016 14:00:00 UTC", &ns->fresh_until); parse_rfc1123_time("Wed, 13 Apr 2016 16:00:00 UTC", &ns->valid_until); + } else if (position == LATE_IN_TP_TO_SRV) { + parse_rfc1123_time("Wed, 13 Apr 2016 23:00:00 UTC", &ns->valid_after); + parse_rfc1123_time("Wed, 14 Apr 2016 00:00:00 UTC", &ns->fresh_until); + parse_rfc1123_time("Wed, 14 Apr 2016 02:00:00 UTC", &ns->valid_until); + } else if (position == EARLY_IN_SRV_TO_TP) { + parse_rfc1123_time("Wed, 14 Apr 2016 01:00:00 UTC", &ns->valid_after); + parse_rfc1123_time("Wed, 14 Apr 2016 02:00:00 UTC", &ns->fresh_until); + parse_rfc1123_time("Wed, 14 Apr 2016 04:00:00 UTC", &ns->valid_until); + } else { + tt_assert(0); } /* Set system time: pretend to be just 2 minutes before consensus expiry */ real_time = ns->valid_until - 120; update_approx_time(real_time); + + done: return real_time; } @@ -1478,8 +1557,7 @@ helper_set_consensus_and_system_time(networkstatus_t *ns, * test_client_service_sync() */ static void helper_test_hsdir_sync(networkstatus_t *ns, - int service_between_srv_and_tp, - int client_between_srv_and_tp, + int service_position, int client_position, int client_fetches_next_desc) { hs_service_descriptor_t *desc; @@ -1496,8 +1574,7 @@ helper_test_hsdir_sync(networkstatus_t *ns, */ /* 1) Initialize service time: consensus and real time */ - time_t now = helper_set_consensus_and_system_time(ns, - service_between_srv_and_tp); + time_t now = helper_set_consensus_and_system_time(ns, service_position); helper_initialize_big_hash_ring(ns); /* 2) Initialize service */ @@ -1512,7 +1589,7 @@ helper_test_hsdir_sync(networkstatus_t *ns, tt_int_op(smartlist_len(desc->previous_hsdirs), OP_EQ, 6); /* 3) Initialize client time */ - helper_set_consensus_and_system_time(ns, client_between_srv_and_tp); + helper_set_consensus_and_system_time(ns, client_position); cleanup_nodelist(); SMARTLIST_FOREACH(ns->routerstatus_list, @@ -1520,22 +1597,28 @@ helper_test_hsdir_sync(networkstatus_t *ns, smartlist_clear(ns->routerstatus_list); helper_initialize_big_hash_ring(ns); - /* 4) Fetch desc as client */ - char client_hsdir_b64_digest[BASE64_DIGEST_LEN+1] = {0}; - helper_client_pick_hsdir(&service->keys.identity_pk, - client_hsdir_b64_digest); - /* Cleanup right now so we don't memleak on error. */ - cleanup_nodelist(); + /* 4) Pick 6 HSDirs as a client and check that they were also chosen by the + service. */ + for (int y = 0 ; y < 6 ; y++) { + char client_hsdir_b64_digest[BASE64_DIGEST_LEN+1] = {0}; + helper_client_pick_hsdir(&service->keys.identity_pk, + client_hsdir_b64_digest); + + /* CHECK: Go through the hsdirs chosen by the service and make sure that it + * contains the one picked by the client! */ + retval = smartlist_contains_string(desc->previous_hsdirs, + client_hsdir_b64_digest); + tt_int_op(retval, OP_EQ, 1); + } - /* CHECK: Go through the hsdirs chosen by the service and make sure that it - * contains the one picked by the client! */ - retval = smartlist_contains_string(desc->previous_hsdirs, - client_hsdir_b64_digest); - tt_int_op(retval, OP_EQ, 1); + /* Finally, try to pick a 7th hsdir and see that NULL is returned since we + * exhausted all of them: */ + tt_assert(!pick_hsdir_v3(&service->keys.identity_pk)); done: /* At the end: free all services and initialize the subsystem again, we will * need it for next scenario. */ + cleanup_nodelist(); hs_service_free_all(); hs_service_init(); SMARTLIST_FOREACH(ns->routerstatus_list, @@ -1599,7 +1682,7 @@ test_client_service_hsdir_set_sync(void *arg) * | S C | * +------------------------------------------------------------------+ */ - helper_test_hsdir_sync(ns, 1, 1, 0); + helper_test_hsdir_sync(ns, LATE_IN_SRV_TO_TP, LATE_IN_SRV_TO_TP, 0); /* b) Scenario where both client and service are in the time segment between * TP#N and SRV#N+1. At this time the client fetches the second HS @@ -1615,7 +1698,7 @@ test_client_service_hsdir_set_sync(void *arg) * | S C | * +------------------------------------------------------------------+ */ - helper_test_hsdir_sync(ns, 0, 0, 1); + helper_test_hsdir_sync(ns, LATE_IN_TP_TO_SRV, LATE_IN_TP_TO_SRV, 1); /* c) Scenario where service is between SRV#N and TP#N, but client is * between TP#N and SRV#N+1. Client is forward in time so it fetches the @@ -1631,7 +1714,7 @@ test_client_service_hsdir_set_sync(void *arg) * | S C | * +------------------------------------------------------------------+ */ - helper_test_hsdir_sync(ns, 1, 0, 1); + helper_test_hsdir_sync(ns, LATE_IN_SRV_TO_TP, EARLY_IN_TP_TO_SRV, 1); /* d) Scenario where service is between TP#N and SRV#N+1, but client is * between SRV#N and TP#N. Client is backwards in time so it fetches the @@ -1647,7 +1730,39 @@ test_client_service_hsdir_set_sync(void *arg) * | C S | * +------------------------------------------------------------------+ */ - helper_test_hsdir_sync(ns, 0, 1, 0); + helper_test_hsdir_sync(ns, EARLY_IN_TP_TO_SRV, LATE_IN_SRV_TO_TP, 0); + + /* e) Scenario where service is between SRV#N and TP#N, but client is + * between TP#N-1 and SRV#3. Client is backwards in time so it fetches + * the first HS desc. + * + * +------------------------------------------------------------------+ + * | | + * | 00:00 12:00 00:00 12:00 00:00 12:00 | + * | SRV#1 TP#1 SRV#2 TP#2 SRV#3 TP#3 | + * | | + * | $==========|-----------$===========|-----------$===========| | + * | ^ ^ | + * | C S | + * +------------------------------------------------------------------+ + */ + helper_test_hsdir_sync(ns, EARLY_IN_SRV_TO_TP, LATE_IN_TP_TO_SRV, 0); + + /* f) Scenario where service is between TP#N and SRV#N+1, but client is + * between SRV#N+1 and TP#N+1. Client is forward in time so it fetches + * the second HS desc. + * + * +------------------------------------------------------------------+ + * | | + * | 00:00 12:00 00:00 12:00 00:00 12:00 | + * | SRV#1 TP#1 SRV#2 TP#2 SRV#3 TP#3 | + * | | + * | $==========|-----------$===========|-----------$===========| | + * | ^ ^ | + * | S C | + * +------------------------------------------------------------------+ + */ + helper_test_hsdir_sync(ns, LATE_IN_TP_TO_SRV, EARLY_IN_SRV_TO_TP, 1); done: networkstatus_vote_free(ns); @@ -1680,6 +1795,9 @@ struct testcase_t hs_common_tests[] = { NULL, NULL }, { "client_service_hsdir_set_sync", test_client_service_hsdir_set_sync, TT_FORK, NULL, NULL }, + { "hs_indexes", test_hs_indexes, TT_FORK, + NULL, NULL }, + END_OF_TESTCASES }; diff --git a/src/test/test_key_expiration.sh b/src/test/test_key_expiration.sh index 95d7911f04..5511dbf18c 100755 --- a/src/test/test_key_expiration.sh +++ b/src/test/test_key_expiration.sh @@ -90,7 +90,7 @@ if [ "$CASE1" = 1 ]; then echo "==== Case 1: Test --key-expiration without argument and ensure usage" echo " instructions are printed." - ${TOR} ${QUIETLY} --key-expiration 2>"$FN" + ${TOR} ${QUIETLY} --key-expiration 2>"$FN" || true grep "No valid argument to --key-expiration found!" "$FN" >/dev/null || \ die "Tor didn't mention supported --key-expiration argmuents" diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c index cb195d6e2a..4f0ecd778b 100644 --- a/src/test/test_microdesc.c +++ b/src/test/test_microdesc.c @@ -19,7 +19,7 @@ #include <direct.h> #else #include <dirent.h> -#endif +#endif /* defined(_WIN32) */ static const char test_md1[] = "onion-key\n" diff --git a/src/test/test_options.c b/src/test/test_options.c index 6e1e25249d..bb5cf685de 100644 --- a/src/test/test_options.c +++ b/src/test/test_options.c @@ -401,9 +401,8 @@ fixed_get_uname(void) "ClientUseIPv4 1\n" \ "VirtualAddrNetworkIPv4 127.192.0.0/10\n" \ "VirtualAddrNetworkIPv6 [FE80::]/10\n" \ - "SchedulerHighWaterMark__ 42\n" \ - "SchedulerLowWaterMark__ 10\n" \ - "UseEntryGuards 1\n" + "UseEntryGuards 1\n" \ + "Schedulers Vanilla\n" typedef struct { or_options_t *old_opt; @@ -507,7 +506,7 @@ test_options_validate__uname_for_server(void *ignored) fixed_get_uname_result = "Windows 2000"; mock_clean_saved_logs(); options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); - expect_log_entry(); + expect_no_log_entry(); tor_free(msg); done: @@ -593,13 +592,14 @@ test_options_validate__nickname(void *ignored) tdata = get_options_test_data("Nickname AMoreValidNick"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); - tt_assert(!msg); + tt_str_op(msg, OP_EQ, "ConnLimit must be greater than 0, but was set to 0"); + tor_free(msg); free_options_test_data(tdata); tdata = get_options_test_data("DataDirectory /tmp/somewhere"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); - tt_assert(!msg); + tt_str_op(msg, OP_EQ, "ConnLimit must be greater than 0, but was set to 0"); done: free_options_test_data(tdata); @@ -755,13 +755,13 @@ test_options_validate__authdir(void *ignored) mock_clean_saved_logs(); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); - tt_assert(!msg); + tt_str_op(msg, OP_EQ, "Authoritative directory servers must set " + "ContactInfo"); + tor_free(msg); free_options_test_data(tdata); tdata = get_options_test_data("AuthoritativeDirectory 1\n" - "Address 100.200.10.1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "Address 100.200.10.1\n"); mock_clean_saved_logs(); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -772,9 +772,7 @@ test_options_validate__authdir(void *ignored) free_options_test_data(tdata); tdata = get_options_test_data("AuthoritativeDirectory 1\n" "Address 100.200.10.1\n" - "TestingTorNetwork 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "TestingTorNetwork 1\n"); mock_clean_saved_logs(); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -785,9 +783,7 @@ test_options_validate__authdir(void *ignored) free_options_test_data(tdata); tdata = get_options_test_data("AuthoritativeDirectory 1\n" "Address 100.200.10.1\n" - "ContactInfo hello@hello.com\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ContactInfo hello@hello.com\n"); mock_clean_saved_logs(); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -799,9 +795,7 @@ test_options_validate__authdir(void *ignored) tdata = get_options_test_data("AuthoritativeDirectory 1\n" "Address 100.200.10.1\n" "RecommendedVersions 1.2, 3.14\n" - "ContactInfo hello@hello.com\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ContactInfo hello@hello.com\n"); mock_clean_saved_logs(); options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_str_op(tdata->opt->RecommendedClientVersions->value, OP_EQ, "1.2, 3.14"); @@ -814,9 +808,7 @@ test_options_validate__authdir(void *ignored) "RecommendedVersions 1.2, 3.14\n" "RecommendedClientVersions 25\n" "RecommendedServerVersions 4.18\n" - "ContactInfo hello@hello.com\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ContactInfo hello@hello.com\n"); mock_clean_saved_logs(); options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_str_op(tdata->opt->RecommendedClientVersions->value, OP_EQ, "25"); @@ -830,9 +822,7 @@ test_options_validate__authdir(void *ignored) "RecommendedVersions 1.2, 3.14\n" "RecommendedClientVersions 25\n" "RecommendedServerVersions 4.18\n" - "ContactInfo hello@hello.com\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ContactInfo hello@hello.com\n"); mock_clean_saved_logs(); options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_str_op(msg, OP_EQ, "AuthoritativeDir is set, but none of (Bridge/V3)" @@ -844,9 +834,7 @@ test_options_validate__authdir(void *ignored) "Address 100.200.10.1\n" "VersioningAuthoritativeDirectory 1\n" "RecommendedServerVersions 4.18\n" - "ContactInfo hello@hello.com\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ContactInfo hello@hello.com\n"); mock_clean_saved_logs(); options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_str_op(msg, OP_EQ, "Versioning authoritative dir servers must set " @@ -858,9 +846,7 @@ test_options_validate__authdir(void *ignored) "Address 100.200.10.1\n" "VersioningAuthoritativeDirectory 1\n" "RecommendedClientVersions 4.18\n" - "ContactInfo hello@hello.com\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ContactInfo hello@hello.com\n"); mock_clean_saved_logs(); options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_str_op(msg, OP_EQ, "Versioning authoritative dir servers must set " @@ -871,9 +857,7 @@ test_options_validate__authdir(void *ignored) tdata = get_options_test_data("AuthoritativeDirectory 1\n" "Address 100.200.10.1\n" "UseEntryGuards 1\n" - "ContactInfo hello@hello.com\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ContactInfo hello@hello.com\n"); mock_clean_saved_logs(); options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); expect_log_msg("Authoritative directory servers " @@ -885,9 +869,7 @@ test_options_validate__authdir(void *ignored) tdata = get_options_test_data("AuthoritativeDirectory 1\n" "Address 100.200.10.1\n" "V3AuthoritativeDir 1\n" - "ContactInfo hello@hello.com\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ContactInfo hello@hello.com\n"); mock_clean_saved_logs(); options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); expect_log_msg("Authoritative directories always try" @@ -900,9 +882,7 @@ test_options_validate__authdir(void *ignored) "Address 100.200.10.1\n" "DownloadExtraInfo 1\n" "V3AuthoritativeDir 1\n" - "ContactInfo hello@hello.com\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ContactInfo hello@hello.com\n"); mock_clean_saved_logs(); options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); expect_no_log_msg("Authoritative directories always try" @@ -913,9 +893,7 @@ test_options_validate__authdir(void *ignored) free_options_test_data(tdata); tdata = get_options_test_data("AuthoritativeDirectory 1\n" "Address 100.200.10.1\n" - "ContactInfo hello@hello.com\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ContactInfo hello@hello.com\n"); mock_clean_saved_logs(); options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_str_op(msg, OP_EQ, "AuthoritativeDir is set, but none of (Bridge/V3)" @@ -927,9 +905,7 @@ test_options_validate__authdir(void *ignored) "Address 100.200.10.1\n" "BridgeAuthoritativeDir 1\n" "ContactInfo hello@hello.com\n" - "V3BandwidthsFile non-existant-file\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "V3BandwidthsFile non-existant-file\n"); mock_clean_saved_logs(); options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_str_op(msg, OP_EQ, @@ -941,9 +917,7 @@ test_options_validate__authdir(void *ignored) "Address 100.200.10.1\n" "BridgeAuthoritativeDir 1\n" "ContactInfo hello@hello.com\n" - "V3BandwidthsFile non-existant-file\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "V3BandwidthsFile non-existant-file\n"); mock_clean_saved_logs(); options_validate(NULL, tdata->opt, tdata->def_opt, 0, &msg); tt_str_op(msg, OP_EQ, @@ -955,9 +929,7 @@ test_options_validate__authdir(void *ignored) "Address 100.200.10.1\n" "BridgeAuthoritativeDir 1\n" "ContactInfo hello@hello.com\n" - "GuardfractionFile non-existant-file\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "GuardfractionFile non-existant-file\n"); mock_clean_saved_logs(); options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_str_op(msg, OP_EQ, @@ -969,9 +941,7 @@ test_options_validate__authdir(void *ignored) "Address 100.200.10.1\n" "BridgeAuthoritativeDir 1\n" "ContactInfo hello@hello.com\n" - "GuardfractionFile non-existant-file\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "GuardfractionFile non-existant-file\n"); mock_clean_saved_logs(); options_validate(NULL, tdata->opt, tdata->def_opt, 0, &msg); tt_str_op(msg, OP_EQ, @@ -982,9 +952,7 @@ test_options_validate__authdir(void *ignored) tdata = get_options_test_data("AuthoritativeDirectory 1\n" "Address 100.200.10.1\n" "BridgeAuthoritativeDir 1\n" - "ContactInfo hello@hello.com\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ContactInfo hello@hello.com\n"); mock_clean_saved_logs(); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -997,9 +965,7 @@ test_options_validate__authdir(void *ignored) "Address 100.200.10.1\n" "DirPort 999\n" "BridgeAuthoritativeDir 1\n" - "ContactInfo hello@hello.com\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ContactInfo hello@hello.com\n"); mock_clean_saved_logs(); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1016,9 +982,7 @@ test_options_validate__authdir(void *ignored) /* "ORPort 888\n" */ /* "ClientOnly 1\n" */ /* "BridgeAuthoritativeDir 1\n" */ - /* "ContactInfo hello@hello.com\n" */ - /* "SchedulerHighWaterMark__ 42\n" */ - /* "SchedulerLowWaterMark__ 10\n"); */ + /* "ContactInfo hello@hello.com\n" ); */ /* mock_clean_saved_logs(); */ /* ret = options_validate(tdata->old_opt, tdata->opt, */ /* tdata->def_opt, 0, &msg); */ @@ -1111,7 +1075,7 @@ test_options_validate__transproxy(void *ignored) tt_int_op(tdata->opt->TransProxyType_parsed, OP_EQ, TPT_PF_DIVERT); tt_str_op(msg, OP_EQ, "Cannot use TransProxyType without " "any valid TransPort."); -#endif +#endif /* !defined(OpenBSD) && !defined( DARWIN ) */ tor_free(msg); // Test tproxy trans proxy @@ -1126,7 +1090,7 @@ test_options_validate__transproxy(void *ignored) tt_int_op(tdata->opt->TransProxyType_parsed, OP_EQ, TPT_TPROXY); tt_str_op(msg, OP_EQ, "Cannot use TransProxyType without any valid " "TransPort."); -#endif +#endif /* !defined(__linux__) */ tor_free(msg); // Test ipfw trans proxy @@ -1142,7 +1106,7 @@ test_options_validate__transproxy(void *ignored) tt_int_op(tdata->opt->TransProxyType_parsed, OP_EQ, TPT_IPFW); tt_str_op(msg, OP_EQ, "Cannot use TransProxyType without any valid " "TransPort."); -#endif +#endif /* !defined(KERNEL_MAY_SUPPORT_IPFW) */ tor_free(msg); // Test unknown trans proxy @@ -1162,9 +1126,7 @@ test_options_validate__transproxy(void *ignored) "TransPort 127.0.0.1:123\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); - if (msg) { - TT_DIE(("Expected NULL but got '%s'", msg)); - } + tt_str_op(msg, OP_EQ, "ConnLimit must be greater than 0, but was set to 0"); #elif defined(KERNEL_MAY_SUPPORT_IPFW) tdata = get_options_test_data("TransProxyType ipfw\n" "TransPort 127.0.0.1:123\n"); @@ -1189,19 +1151,19 @@ test_options_validate__transproxy(void *ignored) if (msg) { TT_DIE(("Expected NULL but got '%s'", msg)); } -#endif +#endif /* defined(__linux__) || ... */ // Assert that a test has run for some TransProxyType tt_assert(tdata); -#else +#else /* !(defined(USE_TRANSPARENT)) */ tdata = get_options_test_data("TransPort 127.0.0.1:555\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); tt_str_op(msg, OP_EQ, "TransPort is disabled in this build."); tor_free(msg); -#endif +#endif /* defined(USE_TRANSPARENT) */ done: free_options_test_data(tdata); @@ -1266,9 +1228,7 @@ test_options_validate__exclude_nodes(void *ignored) free_options_test_data(tdata); tdata = get_options_test_data("ExcludeNodes {cn}\n" - "StrictNodes 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "StrictNodes 1\n"); mock_clean_saved_logs(); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1279,9 +1239,7 @@ test_options_validate__exclude_nodes(void *ignored) tor_free(msg); free_options_test_data(tdata); - tdata = get_options_test_data("ExcludeNodes {cn}\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + tdata = get_options_test_data("ExcludeNodes {cn}\n"); mock_clean_saved_logs(); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1299,49 +1257,6 @@ test_options_validate__exclude_nodes(void *ignored) } static void -test_options_validate__scheduler(void *ignored) -{ - (void)ignored; - int ret; - char *msg; - setup_capture_of_logs(LOG_DEBUG); - options_test_data_t *tdata = get_options_test_data( - "SchedulerLowWaterMark__ 0\n"); - - ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); - tt_int_op(ret, OP_EQ, -1); - expect_log_msg("Bad SchedulerLowWaterMark__ option\n"); - tor_free(msg); - - // TODO: this test cannot run on platforms where UINT32_MAX == UINT64_MAX. - // I suspect it's unlikely this branch can actually happen - /* free_options_test_data(tdata); */ - /* tdata = get_options_test_data( */ - /* "SchedulerLowWaterMark 10000000000000000000\n"); */ - /* tdata->opt->SchedulerLowWaterMark__ = (uint64_t)UINT32_MAX; */ - /* tdata->opt->SchedulerLowWaterMark__++; */ - /* mock_clean_saved_logs(); */ - /* ret = options_validate(tdata->old_opt, tdata->opt, */ - /* tdata->def_opt, 0, &msg); */ - /* tt_int_op(ret, OP_EQ, -1); */ - /* expect_log_msg("Bad SchedulerLowWaterMark__ option\n"); */ - - free_options_test_data(tdata); - tdata = get_options_test_data("SchedulerLowWaterMark__ 42\n" - "SchedulerHighWaterMark__ 42\n"); - mock_clean_saved_logs(); - ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); - tt_int_op(ret, OP_EQ, -1); - expect_log_msg("Bad SchedulerHighWaterMark option\n"); - tor_free(msg); - - done: - teardown_capture_of_logs(); - free_options_test_data(tdata); - tor_free(msg); -} - -static void test_options_validate__node_families(void *ignored) { (void)ignored; @@ -1349,9 +1264,7 @@ test_options_validate__node_families(void *ignored) char *msg; options_test_data_t *tdata = get_options_test_data( "NodeFamily flux, flax\n" - "NodeFamily somewhere\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "NodeFamily somewhere\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1369,8 +1282,7 @@ test_options_validate__node_families(void *ignored) tor_free(msg); free_options_test_data(tdata); - tdata = get_options_test_data("SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + tdata = get_options_test_data(""); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1378,9 +1290,7 @@ test_options_validate__node_families(void *ignored) tor_free(msg); free_options_test_data(tdata); - tdata = get_options_test_data("NodeFamily !flux\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + tdata = get_options_test_data("NodeFamily !flux\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1429,9 +1339,7 @@ test_options_validate__recommended_packages(void *ignored) setup_capture_of_logs(LOG_WARN); options_test_data_t *tdata = get_options_test_data( "RecommendedPackages foo 1.2 http://foo.com sha1=123123123123\n" - "RecommendedPackages invalid-package-line\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "RecommendedPackages invalid-package-line\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1453,9 +1361,7 @@ test_options_validate__fetch_dir(void *ignored) char *msg; options_test_data_t *tdata = get_options_test_data( "FetchDirInfoExtraEarly 1\n" - "FetchDirInfoEarly 0\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "FetchDirInfoEarly 0\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1465,9 +1371,7 @@ test_options_validate__fetch_dir(void *ignored) free_options_test_data(tdata); tdata = get_options_test_data("FetchDirInfoExtraEarly 1\n" - "FetchDirInfoEarly 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "FetchDirInfoEarly 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1487,9 +1391,7 @@ test_options_validate__conn_limit(void *ignored) int ret; char *msg; options_test_data_t *tdata = get_options_test_data( - "ConnLimit 0\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 0\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1497,9 +1399,7 @@ test_options_validate__conn_limit(void *ignored) tor_free(msg); free_options_test_data(tdata); - tdata = get_options_test_data("ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + tdata = get_options_test_data("ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1521,9 +1421,7 @@ test_options_validate__paths_needed(void *ignored) setup_capture_of_logs(LOG_WARN); options_test_data_t *tdata = get_options_test_data( "PathsNeededToBuildCircuits 0.1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1536,9 +1434,7 @@ test_options_validate__paths_needed(void *ignored) free_options_test_data(tdata); mock_clean_saved_logs(); tdata = get_options_test_data("PathsNeededToBuildCircuits 0.99\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1551,9 +1447,7 @@ test_options_validate__paths_needed(void *ignored) free_options_test_data(tdata); mock_clean_saved_logs(); tdata = get_options_test_data("PathsNeededToBuildCircuits 0.91\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1576,9 +1470,7 @@ test_options_validate__max_client_circuits(void *ignored) char *msg; options_test_data_t *tdata = get_options_test_data( "MaxClientCircuitsPending 0\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1588,9 +1480,7 @@ test_options_validate__max_client_circuits(void *ignored) free_options_test_data(tdata); tdata = get_options_test_data("MaxClientCircuitsPending 1025\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1600,9 +1490,7 @@ test_options_validate__max_client_circuits(void *ignored) free_options_test_data(tdata); tdata = get_options_test_data("MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1623,9 +1511,7 @@ test_options_validate__ports(void *ignored) options_test_data_t *tdata = get_options_test_data( "FirewallPorts 65537\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1636,9 +1522,7 @@ test_options_validate__ports(void *ignored) tdata = get_options_test_data("FirewallPorts 1\n" "LongLivedPorts 124444\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1650,9 +1534,7 @@ test_options_validate__ports(void *ignored) "LongLivedPorts 2\n" "RejectPlaintextPorts 112233\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1665,9 +1547,7 @@ test_options_validate__ports(void *ignored) "RejectPlaintextPorts 3\n" "WarnPlaintextPorts 65536\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1680,9 +1560,7 @@ test_options_validate__ports(void *ignored) "RejectPlaintextPorts 3\n" "WarnPlaintextPorts 4\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1704,9 +1582,7 @@ test_options_validate__reachable_addresses(void *ignored) options_test_data_t *tdata = get_options_test_data( "FascistFirewall 1\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1724,9 +1600,7 @@ test_options_validate__reachable_addresses(void *ignored) "ReachableDirAddresses *:81\n" "ReachableORAddresses *:444\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); tdata->opt->FirewallPorts = smartlist_new(); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1740,9 +1614,7 @@ test_options_validate__reachable_addresses(void *ignored) tdata = get_options_test_data("FascistFirewall 1\n" "FirewallPort 123\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1759,9 +1631,7 @@ test_options_validate__reachable_addresses(void *ignored) "ReachableAddresses *:83\n" "ReachableAddresses reject *:*\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1777,9 +1647,7 @@ test_options_validate__reachable_addresses(void *ignored) tdata = get_options_test_data("ReachableAddresses *:82\n" "ORPort 127.0.0.1:5555\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1790,9 +1658,7 @@ test_options_validate__reachable_addresses(void *ignored) tdata = get_options_test_data("ReachableORAddresses *:82\n" "ORPort 127.0.0.1:5555\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1803,9 +1669,7 @@ test_options_validate__reachable_addresses(void *ignored) tdata = get_options_test_data("ReachableDirAddresses *:82\n" "ORPort 127.0.0.1:5555\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1816,9 +1680,7 @@ test_options_validate__reachable_addresses(void *ignored) tdata = get_options_test_data("ClientUseIPv4 0\n" "ORPort 127.0.0.1:5555\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1916,9 +1778,7 @@ test_options_validate__use_bridges(void *ignored) "ClientUseIPv4 1\n" "ORPort 127.0.0.1:5555\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1929,9 +1789,7 @@ test_options_validate__use_bridges(void *ignored) free_options_test_data(tdata); tdata = get_options_test_data("UseBridges 1\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -1944,9 +1802,7 @@ test_options_validate__use_bridges(void *ignored) tdata = get_options_test_data("UseBridges 1\n" "EntryNodes {cn}\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -2006,9 +1862,7 @@ test_options_validate__entry_nodes(void *ignored) "EntryNodes {cn}\n" "UseEntryGuards 0\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -2020,9 +1874,7 @@ test_options_validate__entry_nodes(void *ignored) tdata = get_options_test_data("EntryNodes {cn}\n" "UseEntryGuards 1\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -2043,9 +1895,7 @@ test_options_validate__safe_logging(void *ignored) char *msg; options_test_data_t *tdata = get_options_test_data( "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -2055,9 +1905,7 @@ test_options_validate__safe_logging(void *ignored) free_options_test_data(tdata); tdata = get_options_test_data("SafeLogging 0\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -2067,9 +1915,7 @@ test_options_validate__safe_logging(void *ignored) free_options_test_data(tdata); tdata = get_options_test_data("SafeLogging Relay\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -2079,9 +1925,7 @@ test_options_validate__safe_logging(void *ignored) free_options_test_data(tdata); tdata = get_options_test_data("SafeLogging 1\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -2091,9 +1935,7 @@ test_options_validate__safe_logging(void *ignored) free_options_test_data(tdata); tdata = get_options_test_data("SafeLogging stuffy\n" "MaxClientCircuitsPending 1\n" - "ConnLimit 1\n" - "SchedulerHighWaterMark__ 42\n" - "SchedulerLowWaterMark__ 10\n"); + "ConnLimit 1\n"); ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); @@ -3510,7 +3352,7 @@ test_options_validate__control(void *ignored) "can reconfigure your Tor. That's bad! You should upgrade your " "Tor controller as soon as possible.\n"); tor_free(msg); -#endif +#endif /* defined(HAVE_SYS_UN_H) */ free_options_test_data(tdata); tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES @@ -4422,7 +4264,6 @@ struct testcase_t options_tests[] = { LOCAL_VALIDATE_TEST(relay_with_hidden_services), LOCAL_VALIDATE_TEST(transproxy), LOCAL_VALIDATE_TEST(exclude_nodes), - LOCAL_VALIDATE_TEST(scheduler), LOCAL_VALIDATE_TEST(node_families), LOCAL_VALIDATE_TEST(token_bucket), LOCAL_VALIDATE_TEST(recommended_packages), diff --git a/src/test/test_routerkeys.c b/src/test/test_routerkeys.c index 821faa5052..d8b72651a0 100644 --- a/src/test/test_routerkeys.c +++ b/src/test/test_routerkeys.c @@ -449,7 +449,7 @@ test_routerkeys_ed_keys_init_all(void *arg) #else mkdir(dir, 0700); mkdir(get_fname("test_ed_keys_init_all/keys"), 0700); -#endif +#endif /* defined(_WIN32) */ options->DataDirectory = dir; diff --git a/src/test/test_scheduler.c b/src/test/test_scheduler.c index b0490ccfcf..51bedb3f9c 100644 --- a/src/test/test_scheduler.c +++ b/src/test/test_scheduler.c @@ -6,11 +6,16 @@ #include <math.h> #include <event2/event.h> +#define SCHEDULER_KIST_PRIVATE #define TOR_CHANNEL_INTERNAL_ #define CHANNEL_PRIVATE_ #include "or.h" +#include "config.h" #include "compat_libevent.h" #include "channel.h" +#include "channeltls.h" +#include "connection.h" +#include "networkstatus.h" #define SCHEDULER_PRIVATE_ #include "scheduler.h" @@ -18,53 +23,89 @@ #include "test.h" #include "fakechans.h" -/* Event base for scheduelr tests */ -static struct event_base *mock_event_base = NULL; - -/* Statics controlling mocks */ -static circuitmux_t *mock_ccm_tgt_1 = NULL; -static circuitmux_t *mock_ccm_tgt_2 = NULL; +/* Shamelessly stolen from compat_libevent.c */ +#define V(major, minor, patch) \ + (((major) << 24) | ((minor) << 16) | ((patch) << 8)) -static circuitmux_t *mock_cgp_tgt_1 = NULL; -static circuitmux_policy_t *mock_cgp_val_1 = NULL; -static circuitmux_t *mock_cgp_tgt_2 = NULL; -static circuitmux_policy_t *mock_cgp_val_2 = NULL; +/****************************************************************************** + * Statistical info + *****************************************************************************/ static int scheduler_compare_channels_mock_ctr = 0; static int scheduler_run_mock_ctr = 0; -static void channel_flush_some_cells_mock_free_all(void); -static void channel_flush_some_cells_mock_set(channel_t *chan, - ssize_t num_cells); +/****************************************************************************** + * Utility functions and things we need to mock + *****************************************************************************/ +static or_options_t mocked_options; +static const or_options_t * +mock_get_options(void) +{ + return &mocked_options; +} -/* Setup for mock event stuff */ -static void mock_event_free_all(void); -static void mock_event_init(void); +static void +cleanup_scheduler_options(void) +{ + if (mocked_options.SchedulerTypes_) { + SMARTLIST_FOREACH(mocked_options.SchedulerTypes_, int *, i, tor_free(i)); + smartlist_free(mocked_options.SchedulerTypes_); + mocked_options.SchedulerTypes_ = NULL; + } +} -/* Mocks used by scheduler tests */ -static ssize_t channel_flush_some_cells_mock(channel_t *chan, - ssize_t num_cells); -static int circuitmux_compare_muxes_mock(circuitmux_t *cmux_1, - circuitmux_t *cmux_2); -static const circuitmux_policy_t * circuitmux_get_policy_mock( - circuitmux_t *cmux); -static int scheduler_compare_channels_mock(const void *c1_v, - const void *c2_v); -static void scheduler_run_noop_mock(void); -static struct event_base * tor_libevent_get_base_mock(void); - -/* Scheduler test cases */ -static void test_scheduler_channel_states(void *arg); -static void test_scheduler_compare_channels(void *arg); -static void test_scheduler_initfree(void *arg); -static void test_scheduler_loop(void *arg); -static void test_scheduler_queue_heuristic(void *arg); - -/* Mock event init/free */ +static void +set_scheduler_options(int val) +{ + int *type; -/* Shamelessly stolen from compat_libevent.c */ -#define V(major, minor, patch) \ - (((major) << 24) | ((minor) << 16) | ((patch) << 8)) + if (mocked_options.SchedulerTypes_ == NULL) { + mocked_options.SchedulerTypes_ = smartlist_new(); + } + type = tor_malloc_zero(sizeof(int)); + *type = val; + smartlist_add(mocked_options.SchedulerTypes_, type); +} + +static void +clear_options(void) +{ + cleanup_scheduler_options(); + memset(&mocked_options, 0, sizeof(mocked_options)); +} +static int32_t +mock_vanilla_networkstatus_get_param( + const networkstatus_t *ns, const char *param_name, int32_t default_val, + int32_t min_val, int32_t max_val) +{ + (void)ns; + (void)default_val; + (void)min_val; + (void)max_val; + // only support KISTSchedRunInterval right now + tor_assert(strcmp(param_name, "KISTSchedRunInterval")==0); + return -1; +} + +static int32_t +mock_kist_networkstatus_get_param( + const networkstatus_t *ns, const char *param_name, int32_t default_val, + int32_t min_val, int32_t max_val) +{ + (void)ns; + (void)default_val; + (void)min_val; + (void)max_val; + // only support KISTSchedRunInterval right now + tor_assert(strcmp(param_name, "KISTSchedRunInterval")==0); + return 12; +} + +/* Event base for scheduelr tests */ +static struct event_base *mock_event_base = NULL; +/* Setup for mock event stuff */ +static void mock_event_free_all(void); +static void mock_event_init(void); static void mock_event_free_all(void) { @@ -110,7 +151,84 @@ mock_event_init(void) return; } -/* Mocks */ +static struct event_base * +tor_libevent_get_base_mock(void) +{ + return mock_event_base; +} + +static int +scheduler_compare_channels_mock(const void *c1_v, + const void *c2_v) +{ + uintptr_t p1, p2; + + p1 = (uintptr_t)(c1_v); + p2 = (uintptr_t)(c2_v); + + ++scheduler_compare_channels_mock_ctr; + + if (p1 == p2) return 0; + else if (p1 < p2) return 1; + else return -1; +} + +static void +scheduler_run_noop_mock(void) +{ + ++scheduler_run_mock_ctr; +} + +static circuitmux_t *mock_ccm_tgt_1 = NULL; +static circuitmux_t *mock_ccm_tgt_2 = NULL; +static circuitmux_t *mock_cgp_tgt_1 = NULL; +static circuitmux_policy_t *mock_cgp_val_1 = NULL; +static circuitmux_t *mock_cgp_tgt_2 = NULL; +static circuitmux_policy_t *mock_cgp_val_2 = NULL; + +static const circuitmux_policy_t * +circuitmux_get_policy_mock(circuitmux_t *cmux) +{ + const circuitmux_policy_t *result = NULL; + + tt_assert(cmux != NULL); + if (cmux) { + if (cmux == mock_cgp_tgt_1) result = mock_cgp_val_1; + else if (cmux == mock_cgp_tgt_2) result = mock_cgp_val_2; + else result = circuitmux_get_policy__real(cmux); + } + + done: + return result; +} + +static int +circuitmux_compare_muxes_mock(circuitmux_t *cmux_1, + circuitmux_t *cmux_2) +{ + int result = 0; + + tt_assert(cmux_1 != NULL); + tt_assert(cmux_2 != NULL); + + if (cmux_1 != cmux_2) { + if (cmux_1 == mock_ccm_tgt_1 && cmux_2 == mock_ccm_tgt_2) result = -1; + else if (cmux_1 == mock_ccm_tgt_2 && cmux_2 == mock_ccm_tgt_1) { + result = 1; + } else { + if (cmux_1 == mock_ccm_tgt_1 || cmux_1 == mock_ccm_tgt_2) result = -1; + else if (cmux_2 == mock_ccm_tgt_1 || cmux_2 == mock_ccm_tgt_2) { + result = 1; + } else { + result = circuitmux_compare_muxes__real(cmux_1, cmux_2); + } + } + } + /* else result = 0 always */ + + done: + return result; +} typedef struct { const channel_t *chan; @@ -174,6 +292,67 @@ channel_flush_some_cells_mock_set(channel_t *chan, ssize_t num_cells) } } +static int +channel_more_to_flush_mock(channel_t *chan) +{ + tor_assert(chan); + + flush_mock_channel_t *found_mock_ch = NULL; + + /* Check if we have any queued */ + if (! TOR_SIMPLEQ_EMPTY(&chan->incoming_queue)) + return 1; + + SMARTLIST_FOREACH_BEGIN(chans_for_flush_mock, + flush_mock_channel_t *, + flush_mock_ch) { + if (flush_mock_ch != NULL && flush_mock_ch->chan != NULL) { + if (flush_mock_ch->chan == chan) { + /* Found it */ + found_mock_ch = flush_mock_ch; + break; + } + } else { + /* That shouldn't be there... */ + SMARTLIST_DEL_CURRENT(chans_for_flush_mock, flush_mock_ch); + tor_free(flush_mock_ch); + } + } SMARTLIST_FOREACH_END(flush_mock_ch); + + tor_assert(found_mock_ch); + + /* Check if any circuits would like to queue some */ + /* special for the mock: return the number of cells (instead of 1), or zero + * if nothing to flush */ + return (found_mock_ch->cells > 0 ? (int)found_mock_ch->cells : 0 ); +} + +static void +channel_write_to_kernel_mock(channel_t *chan) +{ + (void)chan; + //log_debug(LD_SCHED, "chan=%d writing to kernel", + // (int)chan->global_identifier); +} + +static int +channel_should_write_to_kernel_mock(outbuf_table_t *ot, channel_t *chan) +{ + (void)ot; + (void)chan; + return 1; + /* We could make this more complicated if we wanted. But I don't think doing + * so tests much of anything */ + //static int called_counter = 0; + //if (++called_counter >= 3) { + // called_counter -= 3; + // log_debug(LD_SCHED, "chan=%d should write to kernel", + // (int)chan->global_identifier); + // return 1; + //} + //return 0; +} + static ssize_t channel_flush_some_cells_mock(channel_t *chan, ssize_t num_cells) { @@ -215,11 +394,6 @@ channel_flush_some_cells_mock(channel_t *chan, ssize_t num_cells) flushed += max; found->cells -= max; - - if (found->cells <= 0) { - smartlist_remove(chans_for_flush_mock, found); - tor_free(found); - } } } } @@ -228,90 +402,26 @@ channel_flush_some_cells_mock(channel_t *chan, ssize_t num_cells) return flushed; } -static int -circuitmux_compare_muxes_mock(circuitmux_t *cmux_1, - circuitmux_t *cmux_2) -{ - int result = 0; - - tt_ptr_op(cmux_1, OP_NE, NULL); - tt_ptr_op(cmux_2, OP_NE, NULL); - - if (cmux_1 != cmux_2) { - if (cmux_1 == mock_ccm_tgt_1 && cmux_2 == mock_ccm_tgt_2) result = -1; - else if (cmux_1 == mock_ccm_tgt_2 && cmux_2 == mock_ccm_tgt_1) { - result = 1; - } else { - if (cmux_1 == mock_ccm_tgt_1 || cmux_1 == mock_ccm_tgt_2) result = -1; - else if (cmux_2 == mock_ccm_tgt_1 || cmux_2 == mock_ccm_tgt_2) { - result = 1; - } else { - result = circuitmux_compare_muxes__real(cmux_1, cmux_2); - } - } - } - /* else result = 0 always */ - - done: - return result; -} - -static const circuitmux_policy_t * -circuitmux_get_policy_mock(circuitmux_t *cmux) -{ - const circuitmux_policy_t *result = NULL; - - tt_ptr_op(cmux, OP_NE, NULL); - if (cmux) { - if (cmux == mock_cgp_tgt_1) result = mock_cgp_val_1; - else if (cmux == mock_cgp_tgt_2) result = mock_cgp_val_2; - else result = circuitmux_get_policy__real(cmux); - } - - done: - return result; -} - -static int -scheduler_compare_channels_mock(const void *c1_v, - const void *c2_v) -{ - uintptr_t p1, p2; - - p1 = (uintptr_t)(c1_v); - p2 = (uintptr_t)(c2_v); - - ++scheduler_compare_channels_mock_ctr; - - if (p1 == p2) return 0; - else if (p1 < p2) return 1; - else return -1; -} - static void -scheduler_run_noop_mock(void) +update_socket_info_impl_mock(socket_table_ent_t *ent) { - ++scheduler_run_mock_ctr; + ent->cwnd = ent->unacked = ent->mss = ent->notsent = 0; + ent->limit = INT_MAX; } -static struct event_base * -tor_libevent_get_base_mock(void) -{ - return mock_event_base; -} - -/* Test cases */ - static void -test_scheduler_channel_states(void *arg) +perform_channel_state_tests(int KISTSchedRunInterval, int sched_type) { channel_t *ch1 = NULL, *ch2 = NULL; int old_count; - (void)arg; + /* setup options so we're sure about what sched we are running */ + MOCK(get_options, mock_get_options); + clear_options(); + mocked_options.KISTSchedRunInterval = KISTSchedRunInterval; + set_scheduler_options(sched_type); /* Set up libevent and scheduler */ - mock_event_init(); MOCK(tor_libevent_get_base, tor_libevent_get_base_mock); scheduler_init(); @@ -324,7 +434,7 @@ test_scheduler_channel_states(void *arg) * Disable scheduler_run so we can just check the state transitions * without having to make everything it might call work too. */ - MOCK(scheduler_run, scheduler_run_noop_mock); + ((scheduler_t *) the_scheduler)->run = scheduler_run_noop_mock; tt_int_op(smartlist_len(channels_pending), OP_EQ, 0); @@ -351,7 +461,7 @@ test_scheduler_channel_states(void *arg) channel_register(ch2); tt_assert(ch2->registered); - /* Send it to SCHED_CHAN_WAITING_TO_WRITE */ + /* Send ch1 to SCHED_CHAN_WAITING_TO_WRITE */ scheduler_channel_has_waiting_cells(ch1); tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_TO_WRITE); @@ -415,8 +525,9 @@ test_scheduler_channel_states(void *arg) tor_free(ch2); UNMOCK(scheduler_compare_channels); - UNMOCK(scheduler_run); UNMOCK(tor_libevent_get_base); + UNMOCK(get_options); + cleanup_scheduler_options(); return; } @@ -502,40 +613,22 @@ test_scheduler_compare_channels(void *arg) return; } -static void -test_scheduler_initfree(void *arg) -{ - (void)arg; - - tt_ptr_op(channels_pending, OP_EQ, NULL); - tt_ptr_op(run_sched_ev, OP_EQ, NULL); - - mock_event_init(); - MOCK(tor_libevent_get_base, tor_libevent_get_base_mock); - - scheduler_init(); - - tt_ptr_op(channels_pending, OP_NE, NULL); - tt_ptr_op(run_sched_ev, OP_NE, NULL); - - scheduler_free_all(); - - UNMOCK(tor_libevent_get_base); - mock_event_free_all(); - - tt_ptr_op(channels_pending, OP_EQ, NULL); - tt_ptr_op(run_sched_ev, OP_EQ, NULL); - - done: - return; -} +/****************************************************************************** + * The actual tests! + *****************************************************************************/ static void -test_scheduler_loop(void *arg) +test_scheduler_loop_vanilla(void *arg) { + (void)arg; channel_t *ch1 = NULL, *ch2 = NULL; + void (*run_func_ptr)(void); - (void)arg; + /* setup options so we're sure about what sched we are running */ + MOCK(get_options, mock_get_options); + clear_options(); + set_scheduler_options(SCHEDULER_VANILLA); + mocked_options.KISTSchedRunInterval = -1; /* Set up libevent and scheduler */ @@ -551,12 +644,14 @@ test_scheduler_loop(void *arg) * Disable scheduler_run so we can just check the state transitions * without having to make everything it might call work too. */ - MOCK(scheduler_run, scheduler_run_noop_mock); + run_func_ptr = the_scheduler->run; + ((scheduler_t *) the_scheduler)->run = scheduler_run_noop_mock; tt_int_op(smartlist_len(channels_pending), OP_EQ, 0); /* Set up a fake channel */ ch1 = new_fake_channel(); + ch1->magic = TLS_CHAN_MAGIC; tt_assert(ch1); /* Start it off in OPENING */ @@ -574,6 +669,7 @@ test_scheduler_loop(void *arg) /* Now get another one */ ch2 = new_fake_channel(); + ch2->magic = TLS_CHAN_MAGIC; tt_assert(ch2); ch2->state = CHANNEL_STATE_OPENING; ch2->cmux = circuitmux_alloc(); @@ -615,15 +711,9 @@ test_scheduler_loop(void *arg) /* * Now we've got two pending channels and need to fire off - * scheduler_run(); first, unmock it. + * the scheduler run() that we kept. */ - - UNMOCK(scheduler_run); - - scheduler_run(); - - /* Now re-mock it */ - MOCK(scheduler_run, scheduler_run_noop_mock); + run_func_ptr(); /* * Assert that they're still in the states we left and aren't still @@ -661,15 +751,10 @@ test_scheduler_loop(void *arg) channel_flush_some_cells_mock_set(ch2, 48); /* - * And re-run the scheduler_run() loop with non-zero returns from + * And re-run the scheduler run() loop with non-zero returns from * channel_flush_some_cells() this time. */ - UNMOCK(scheduler_run); - - scheduler_run(); - - /* Now re-mock it */ - MOCK(scheduler_run, scheduler_run_noop_mock); + run_func_ptr(); /* * ch1 should have gone to SCHED_CHAN_WAITING_FOR_CELLS, with 16 flushed @@ -704,55 +789,282 @@ test_scheduler_loop(void *arg) done: tor_free(ch1); tor_free(ch2); + cleanup_scheduler_options(); UNMOCK(channel_flush_some_cells); UNMOCK(scheduler_compare_channels); - UNMOCK(scheduler_run); UNMOCK(tor_libevent_get_base); + UNMOCK(get_options); } static void -test_scheduler_queue_heuristic(void *arg) +test_scheduler_loop_kist(void *arg) { - time_t now = approx_time(); - uint64_t qh; + (void) arg; +#ifndef HAVE_KIST_SUPPORT + return; +#endif + + channel_t *ch1 = new_fake_channel(), *ch2 = new_fake_channel(); + + /* setup options so we're sure about what sched we are running */ + MOCK(get_options, mock_get_options); + MOCK(channel_flush_some_cells, channel_flush_some_cells_mock); + MOCK(channel_more_to_flush, channel_more_to_flush_mock); + MOCK(channel_write_to_kernel, channel_write_to_kernel_mock); + MOCK(channel_should_write_to_kernel, channel_should_write_to_kernel_mock); + MOCK(update_socket_info_impl, update_socket_info_impl_mock); + clear_options(); + mocked_options.KISTSchedRunInterval = 11; + set_scheduler_options(SCHEDULER_KIST); + scheduler_init(); + + tt_assert(ch1); + ch1->magic = TLS_CHAN_MAGIC; + ch1->state = CHANNEL_STATE_OPENING; + ch1->cmux = circuitmux_alloc(); + channel_register(ch1); + tt_assert(ch1->registered); + channel_change_state_open(ch1); + scheduler_channel_has_waiting_cells(ch1); + scheduler_channel_wants_writes(ch1); + channel_flush_some_cells_mock_set(ch1, 5); + + tt_assert(ch2); + ch2->magic = TLS_CHAN_MAGIC; + ch2->state = CHANNEL_STATE_OPENING; + ch2->cmux = circuitmux_alloc(); + channel_register(ch2); + tt_assert(ch2->registered); + channel_change_state_open(ch2); + scheduler_channel_has_waiting_cells(ch2); + scheduler_channel_wants_writes(ch2); + channel_flush_some_cells_mock_set(ch2, 5); + + the_scheduler->run(); + + scheduler_channel_has_waiting_cells(ch1); + channel_flush_some_cells_mock_set(ch1, 5); + + the_scheduler->run(); + + scheduler_channel_has_waiting_cells(ch1); + channel_flush_some_cells_mock_set(ch1, 5); + scheduler_channel_has_waiting_cells(ch2); + channel_flush_some_cells_mock_set(ch2, 5); + + the_scheduler->run(); + + channel_flush_some_cells_mock_free_all(); + tt_int_op(1,==,1); + + done: + /* Prep the channel so the free() function doesn't explode. */ + ch1->state = ch2->state = CHANNEL_STATE_CLOSED; + ch1->registered = ch2->registered = 0; + channel_free(ch1); + channel_free(ch2); + UNMOCK(update_socket_info_impl); + UNMOCK(channel_should_write_to_kernel); + UNMOCK(channel_write_to_kernel); + UNMOCK(channel_more_to_flush); + UNMOCK(channel_flush_some_cells); + UNMOCK(get_options); + scheduler_free_all(); + return; +} + +static void +test_scheduler_channel_states(void *arg) +{ (void)arg; + perform_channel_state_tests(-1, SCHEDULER_VANILLA); + perform_channel_state_tests(11, SCHEDULER_KIST_LITE); +#ifdef HAVE_KIST_SUPPORT + perform_channel_state_tests(11, SCHEDULER_KIST); +#endif +} - queue_heuristic = 0; - queue_heuristic_timestamp = 0; +static void +test_scheduler_initfree(void *arg) +{ + (void)arg; - /* Not yet inited case */ - scheduler_update_queue_heuristic(now - 180); - tt_u64_op(queue_heuristic, OP_EQ, 0); - tt_int_op(queue_heuristic_timestamp, OP_EQ, now - 180); + tt_ptr_op(channels_pending, ==, NULL); + tt_ptr_op(run_sched_ev, ==, NULL); - queue_heuristic = 1000000000L; - queue_heuristic_timestamp = now - 120; + mock_event_init(); + MOCK(tor_libevent_get_base, tor_libevent_get_base_mock); + MOCK(get_options, mock_get_options); + set_scheduler_options(SCHEDULER_KIST); + set_scheduler_options(SCHEDULER_KIST_LITE); + set_scheduler_options(SCHEDULER_VANILLA); - scheduler_update_queue_heuristic(now - 119); - tt_u64_op(queue_heuristic, OP_EQ, 500000000L); - tt_int_op(queue_heuristic_timestamp, OP_EQ, now - 119); + scheduler_init(); - scheduler_update_queue_heuristic(now - 116); - tt_u64_op(queue_heuristic, OP_EQ, 62500000L); - tt_int_op(queue_heuristic_timestamp, OP_EQ, now - 116); + tt_ptr_op(channels_pending, !=, NULL); + tt_ptr_op(run_sched_ev, !=, NULL); + /* We have specified nothing in the torrc and there's no consensus so the + * KIST scheduler is what should be in use */ + tt_ptr_op(the_scheduler, ==, get_kist_scheduler()); + tt_int_op(sched_run_interval, ==, 10); - qh = scheduler_get_queue_heuristic(); - tt_u64_op(qh, OP_EQ, 0); + scheduler_free_all(); + + UNMOCK(tor_libevent_get_base); + mock_event_free_all(); + + tt_ptr_op(channels_pending, ==, NULL); + tt_ptr_op(run_sched_ev, ==, NULL); done: + UNMOCK(get_options); + cleanup_scheduler_options(); + return; +} + +static void +test_scheduler_can_use_kist(void *arg) +{ + (void)arg; + + int res_should, res_freq; + MOCK(get_options, mock_get_options); + + /* Test force disabling of KIST */ + clear_options(); + mocked_options.KISTSchedRunInterval = -1; + res_should = scheduler_can_use_kist(); + res_freq = kist_scheduler_run_interval(NULL); + tt_int_op(res_should, ==, 0); + tt_int_op(res_freq, ==, -1); + + /* Test force enabling of KIST */ + clear_options(); + mocked_options.KISTSchedRunInterval = 1234; + res_should = scheduler_can_use_kist(); + res_freq = kist_scheduler_run_interval(NULL); +#ifdef HAVE_KIST_SUPPORT + tt_int_op(res_should, ==, 1); +#else /* HAVE_KIST_SUPPORT */ + tt_int_op(res_should, ==, 0); +#endif /* HAVE_KIST_SUPPORT */ + tt_int_op(res_freq, ==, 1234); + + /* Test defer to consensus, but no consensus available */ + clear_options(); + mocked_options.KISTSchedRunInterval = 0; + res_should = scheduler_can_use_kist(); + res_freq = kist_scheduler_run_interval(NULL); +#ifdef HAVE_KIST_SUPPORT + tt_int_op(res_should, ==, 1); +#else /* HAVE_KIST_SUPPORT */ + tt_int_op(res_should, ==, 0); +#endif /* HAVE_KIST_SUPPORT */ + tt_int_op(res_freq, ==, 10); + + /* Test defer to consensus, and kist consensus available */ + MOCK(networkstatus_get_param, mock_kist_networkstatus_get_param); + clear_options(); + mocked_options.KISTSchedRunInterval = 0; + res_should = scheduler_can_use_kist(); + res_freq = kist_scheduler_run_interval(NULL); +#ifdef HAVE_KIST_SUPPORT + tt_int_op(res_should, ==, 1); +#else /* HAVE_KIST_SUPPORT */ + tt_int_op(res_should, ==, 0); +#endif /* HAVE_KIST_SUPPORT */ + tt_int_op(res_freq, ==, 12); + UNMOCK(networkstatus_get_param); + + /* Test defer to consensus, and vanilla consensus available */ + MOCK(networkstatus_get_param, mock_vanilla_networkstatus_get_param); + clear_options(); + mocked_options.KISTSchedRunInterval = 0; + res_should = scheduler_can_use_kist(); + res_freq = kist_scheduler_run_interval(NULL); + tt_int_op(res_should, ==, 0); + tt_int_op(res_freq, ==, -1); + UNMOCK(networkstatus_get_param); + + done: + UNMOCK(get_options); + return; +} + +static void +test_scheduler_ns_changed(void *arg) +{ + (void) arg; + + /* + * Currently no scheduler implementations use the old/new consensuses passed + * in scheduler_notify_networkstatus_changed, so it is okay to pass NULL. + * + * "But then what does test actually exercise???" It tests that + * scheduler_notify_networkstatus_changed fetches the correct value from the + * consensus, and then switches the scheduler if necessasry. + */ + + MOCK(get_options, mock_get_options); + clear_options(); + set_scheduler_options(SCHEDULER_KIST); + set_scheduler_options(SCHEDULER_VANILLA); + + tt_ptr_op(the_scheduler, ==, NULL); + + /* Change from vanilla to kist via consensus */ + the_scheduler = get_vanilla_scheduler(); + MOCK(networkstatus_get_param, mock_kist_networkstatus_get_param); + scheduler_notify_networkstatus_changed(NULL, NULL); + UNMOCK(networkstatus_get_param); +#ifdef HAVE_KIST_SUPPORT + tt_ptr_op(the_scheduler, ==, get_kist_scheduler()); +#else + tt_ptr_op(the_scheduler, ==, get_vanilla_scheduler()); +#endif + + /* Change from kist to vanilla via consensus */ + the_scheduler = get_kist_scheduler(); + MOCK(networkstatus_get_param, mock_vanilla_networkstatus_get_param); + scheduler_notify_networkstatus_changed(NULL, NULL); + UNMOCK(networkstatus_get_param); + tt_ptr_op(the_scheduler, ==, get_vanilla_scheduler()); + + /* Doesn't change when using KIST */ + the_scheduler = get_kist_scheduler(); + MOCK(networkstatus_get_param, mock_kist_networkstatus_get_param); + scheduler_notify_networkstatus_changed(NULL, NULL); + UNMOCK(networkstatus_get_param); +#ifdef HAVE_KIST_SUPPORT + tt_ptr_op(the_scheduler, ==, get_kist_scheduler()); +#else + tt_ptr_op(the_scheduler, ==, get_vanilla_scheduler()); +#endif + + /* Doesn't change when using vanilla */ + the_scheduler = get_vanilla_scheduler(); + MOCK(networkstatus_get_param, mock_vanilla_networkstatus_get_param); + scheduler_notify_networkstatus_changed(NULL, NULL); + UNMOCK(networkstatus_get_param); + tt_ptr_op(the_scheduler, ==, get_vanilla_scheduler()); + + done: + UNMOCK(get_options); + cleanup_scheduler_options(); return; } struct testcase_t scheduler_tests[] = { - { "channel_states", test_scheduler_channel_states, TT_FORK, NULL, NULL }, { "compare_channels", test_scheduler_compare_channels, TT_FORK, NULL, NULL }, + { "channel_states", test_scheduler_channel_states, TT_FORK, NULL, NULL }, { "initfree", test_scheduler_initfree, TT_FORK, NULL, NULL }, - { "loop", test_scheduler_loop, TT_FORK, NULL, NULL }, - { "queue_heuristic", test_scheduler_queue_heuristic, - TT_FORK, NULL, NULL }, + { "loop_vanilla", test_scheduler_loop_vanilla, TT_FORK, NULL, NULL }, + { "loop_kist", test_scheduler_loop_kist, TT_FORK, NULL, NULL }, + { "ns_changed", test_scheduler_ns_changed, TT_FORK, NULL, NULL}, + { "should_use_kist", test_scheduler_can_use_kist, TT_FORK, NULL, NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_switch_id.c b/src/test/test_switch_id.c index 53de793fe8..fe36d8c6e6 100644 --- a/src/test/test_switch_id.c +++ b/src/test/test_switch_id.c @@ -71,7 +71,7 @@ check_can_bind_low_ports(void) return -1; } -#endif +#endif /* !defined(_WIN32) */ int main(int argc, char **argv) @@ -83,7 +83,7 @@ main(int argc, char **argv) fprintf(stderr, "This test is not supported on your OS.\n"); return 77; -#else +#else /* !(defined(_WIN32)) */ const char *username; const char *testname; if (argc != 3) { @@ -174,7 +174,7 @@ main(int argc, char **argv) } cap_free(caps); } -#endif +#endif /* defined(HAVE_LINUX_CAPABILITIES) */ break; default: fprintf(stderr, "Unsupported test '%s'\n", testname); @@ -187,6 +187,6 @@ main(int argc, char **argv) } return (okay ? 0 : 1); -#endif +#endif /* defined(_WIN32) */ } diff --git a/src/test/test_tortls.c b/src/test/test_tortls.c index 0e89a66b53..d04a767170 100644 --- a/src/test/test_tortls.c +++ b/src/test/test_tortls.c @@ -63,7 +63,7 @@ fake_num_ciphers(void) { return 0; } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ static void test_tortls_errno_to_tls_error(void *data) @@ -145,7 +145,7 @@ test_tortls_tor_tls_new(void *data) client_tls_context->ctx = ctx; tls = tor_tls_new(-1, 0); tt_ptr_op(tls, OP_EQ, NULL); -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ done: UNMOCK(tor_tls_cert_matches_key); @@ -376,7 +376,7 @@ test_tortls_log_one_error(void *ignored) tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_RECORD_TOO_LARGE), LOG_WARN, 0, NULL); expect_log_severity(LOG_INFO); -#endif +#endif /* !defined(OPENSSL_1_1_API) */ mock_clean_saved_logs(); tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_UNKNOWN_PROTOCOL), @@ -490,7 +490,7 @@ test_tortls_get_error(void *ignored) tor_free(tls); SSL_CTX_free(ctx); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ static void test_tortls_always_accept_verify_cb(void *ignored) @@ -520,7 +520,7 @@ test_tortls_x509_cert_free(void *ignored) cert->encoded = tor_malloc_zero(1); tor_x509_cert_free(cert); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ static void test_tortls_x509_cert_get_id_digests(void *ignored) @@ -662,7 +662,7 @@ test_tortls_cert_get_key(void *ignored) tor_free(cert); crypto_pk_free(res); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ static void test_tortls_get_my_client_auth_key(void *ignored) @@ -744,7 +744,7 @@ get_cipher_by_name(const char *name) return NULL; } -#endif +#endif /* !defined(HAVE_SSL_GET_CLIENT_CIPHERS) */ #ifndef OPENSSL_OPAQUE static void @@ -879,7 +879,7 @@ test_tortls_classify_client_ciphers(void *ignored) tor_free(tls); SSL_CTX_free(ctx); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ static void test_tortls_client_is_using_v2_ciphers(void *ignored) @@ -921,7 +921,7 @@ test_tortls_client_is_using_v2_ciphers(void *ignored) done: SSL_free(ssl); SSL_CTX_free(ctx); -#endif +#endif /* defined(HAVE_SSL_GET_CLIENT_CIPHERS) */ } #ifndef OPENSSL_OPAQUE @@ -937,7 +937,7 @@ fixed_try_to_extract_certs_from_tls(int severity, tor_tls_t *tls, *cert_out = fixed_try_to_extract_certs_from_tls_cert_out_result; *id_cert_out = fixed_try_to_extract_certs_from_tls_id_cert_out_result; } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static const char* notCompletelyValidCertString = @@ -956,7 +956,7 @@ static const char* notCompletelyValidCertString = "jC9UeuErhaA/zzWi8ewMTFZW/WshOrm3fNvcMrMLKtH534JKvcdMg6qIdjTFINIr\n" "evnAhf0cwULaebn+lMs8Pdl7y37+sfluVok=\n" "-----END CERTIFICATE-----\n"; -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ static const char* validCertString = "-----BEGIN CERTIFICATE-----\n" "MIIDpTCCAY0CAg3+MA0GCSqGSIb3DQEBBQUAMF4xCzAJBgNVBAYTAlVTMREwDwYD\n" @@ -1079,7 +1079,7 @@ test_tortls_verify(void *ignored) tor_free(tls); tor_free(k); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static void @@ -1118,7 +1118,7 @@ test_tortls_check_lifetime(void *ignored) tor_free(tls); X509_free(validCert); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static int fixed_ssl_pending_result = 0; @@ -1153,7 +1153,7 @@ test_tortls_get_pending_bytes(void *ignored) tor_free(tls->ssl); tor_free(tls); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ static void test_tortls_get_forced_write_size(void *ignored) @@ -1276,13 +1276,13 @@ test_tortls_SSL_SESSION_get_master_key(void *ignored) tt_int_op(out[0], OP_EQ, 43); done: -#endif +#endif /* !defined(HAVE_SSL_SESSION_GET_MASTER_KEY) */ tor_free(tls->ssl->session); tor_free(tls->ssl); tor_free(tls); tor_free(out); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static void @@ -1308,7 +1308,7 @@ test_tortls_get_tlssecrets(void *ignored) tor_free(tls->ssl); tor_free(tls); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static void @@ -1350,7 +1350,7 @@ test_tortls_get_buffer_sizes(void *ignored) tt_int_op(rbuf_c, OP_EQ, 1); tt_int_op(wbuf_c, OP_EQ, 2); -#endif +#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0) */ done: tor_free(tls->ssl->s3->rbuf.buf); @@ -1359,7 +1359,7 @@ test_tortls_get_buffer_sizes(void *ignored) tor_free(tls->ssl); tor_free(tls); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ static void test_tortls_evaluate_ecgroup_for_tls(void *ignored) @@ -1451,7 +1451,7 @@ test_tortls_try_to_extract_certs_from_tls(void *ignored) X509_free(c1); X509_free(c2); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static void @@ -1483,7 +1483,7 @@ test_tortls_get_peer_cert(void *ignored) tor_free(tls); X509_free(cert); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static void @@ -1513,7 +1513,7 @@ test_tortls_peer_has_cert(void *ignored) tor_free(tls); X509_free(cert); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ static void test_tortls_is_server(void *ignored) @@ -1573,7 +1573,7 @@ test_tortls_session_secret_cb(void *ignored) SSL_CTX_free(ctx); tor_free(tls); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE /* TODO: It seems block_renegotiation and unblock_renegotiation and @@ -1624,7 +1624,7 @@ test_tortls_unblock_renegotiation(void *ignored) tor_free(tls->ssl); tor_free(tls); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static void @@ -1643,7 +1643,7 @@ test_tortls_assert_renegotiation_unblocked(void *ignored) tor_free(tls->ssl); tor_free(tls); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ static void test_tortls_set_logged_address(void *ignored) @@ -1698,7 +1698,7 @@ test_tortls_set_renegotiate_callback(void *ignored) tor_free(tls->ssl); tor_free(tls); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static SSL_CIPHER *fixed_cipher1 = NULL; @@ -1716,7 +1716,7 @@ fake_get_cipher(unsigned ncipher) return NULL; } } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static void @@ -1786,7 +1786,7 @@ test_tortls_find_cipher_by_id(void *ignored) SSL_CTX_free(ctx); tor_free(fixed_cipher1); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static void @@ -1814,7 +1814,7 @@ test_tortls_debug_state_callback(void *ignored) tor_free(buf); tor_free(ssl); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static void @@ -1878,7 +1878,7 @@ test_tortls_server_info_callback(void *ignored) SSL_CTX_free(ctx); tor_free(tls); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static int fixed_ssl_read_result_index; @@ -1919,7 +1919,7 @@ setting_version_and_state_ssl_shutdown(SSL *s) s->version = SSL2_VERSION; return fixed_ssl_shutdown_result; } -#endif +#endif /* !defined(LIBRESSL_VERSION_NUMBER) */ static int dummy_handshake_func(SSL *s) @@ -2015,7 +2015,7 @@ test_tortls_shutdown(void *ignored) method->ssl_shutdown = setting_version_and_state_ssl_shutdown; ret = tor_tls_shutdown(tls); tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC); -#endif +#endif /* !defined(LIBRESSL_VERSION_NUMBER) */ done: teardown_capture_of_logs(); @@ -2086,7 +2086,7 @@ test_tortls_read(void *ignored) ret = tor_tls_read(tls, buf, 10); tt_int_op(ret, OP_EQ, TOR_TLS_CLOSE); tt_int_op(tls->state, OP_EQ, TOR_TLS_ST_CLOSED); -#endif +#endif /* !defined(LIBRESSL_VERSION_NUMBER) */ // TODO: fill up done: @@ -2161,7 +2161,7 @@ test_tortls_write(void *ignored) tor_free(tls); tor_free(method); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static int fixed_ssl_accept_result; @@ -2241,7 +2241,7 @@ test_tortls_handshake(void *ignored) "(null):SSLv3 write client hello B)\n"); expect_log_msg("TLS error while handshaking: (null) (in system library:" "connect:SSLv3 write client hello B)\n"); -#endif +#endif /* 0 */ expect_log_severity(LOG_INFO); tls->isServer = 0; @@ -2259,7 +2259,7 @@ test_tortls_handshake(void *ignored) "(null) (in bignum routines:(null):SSLv3 write client hello B)\n"); expect_log_msg("TLS error while handshaking: " "(null) (in system library:connect:SSLv3 write client hello B)\n"); -#endif +#endif /* 0 */ expect_log_severity(LOG_WARN); done: @@ -2269,7 +2269,7 @@ test_tortls_handshake(void *ignored) tor_free(tls); tor_free(method); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #ifndef OPENSSL_OPAQUE static void @@ -2344,7 +2344,7 @@ test_tortls_finish_handshake(void *ignored) tor_free(method); teardown_capture_of_logs(); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ static int fixed_crypto_pk_new_result_index; static crypto_pk_t *fixed_crypto_pk_new_result[5]; @@ -2569,7 +2569,7 @@ test_tortls_context_new(void *ignored) UNMOCK(crypto_pk_generate_key_with_bits); UNMOCK(crypto_pk_new); } -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ static int fixed_crypto_pk_get_evp_pkey_result_index = 0; static EVP_PKEY *fixed_crypto_pk_get_evp_pkey_result[5]; @@ -2638,7 +2638,7 @@ test_tortls_cert_new(void *ignored) X509_get_pubkey(cert)->type = EVP_PKEY_DSA; ret = tor_x509_cert_new(cert); tt_assert(ret); -#endif +#endif /* 0 */ #ifndef OPENSSL_OPAQUE cert = read_cert_from(validCertString); @@ -2646,7 +2646,7 @@ test_tortls_cert_new(void *ignored) cert->cert_info = NULL; ret = tor_x509_cert_new(cert); tt_assert(ret); -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ done: tor_x509_cert_free(ret); @@ -2693,7 +2693,7 @@ test_tortls_cert_is_valid(void *ignored) cert->cert->cert_info->key = NULL; ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1); tt_int_op(ret, OP_EQ, 0); -#endif +#endif /* !defined(OPENSSL_OPAQUE) */ #if 0 tor_x509_cert_free(cert); @@ -2732,7 +2732,7 @@ test_tortls_cert_is_valid(void *ignored) X509_get_pubkey(cert->cert)->ameth = NULL; ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0); tt_int_op(ret, OP_EQ, 0); -#endif +#endif /* 0 */ done: tor_x509_cert_free(cert); @@ -2765,7 +2765,7 @@ test_tortls_context_init_one(void *ignored) { #name, NULL, TT_SKIP, NULL, NULL } #else #define INTRUSIVE_TEST_CASE(name, flags) LOCAL_TEST_CASE(name, flags) -#endif +#endif /* defined(OPENSSL_OPAQUE) */ struct testcase_t tortls_tests[] = { LOCAL_TEST_CASE(errno_to_tls_error, 0), diff --git a/src/test/test_util.c b/src/test/test_util.c index 6bed23fc7b..db629bcb6b 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -367,7 +367,7 @@ test_util_time(void *arg) * calculations internally, then catches the overflow. */ #define TV_SEC_MAX TIME_MAX #define TV_SEC_MIN TIME_MIN -#endif +#endif /* defined(_WIN32) */ /* Assume tv_usec is an unsigned integer until proven otherwise */ #define TV_USEC_MAX UINT_MAX @@ -641,7 +641,7 @@ test_util_time(void *arg) tt_int_op(t_res, OP_EQ, tor_timegm(&a_time)); tor_gmtime_r(&t_res, &b_time); TM_EQUAL(a_time, b_time); -#endif +#endif /* SIZEOF_TIME_T == 4 || ... */ /* Test tor_timegm out of range */ @@ -689,7 +689,7 @@ test_util_time(void *arg) CAPTURE(); tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time)); CHECK_TIMEGM_ARG_OUT_OF_RANGE(); -#endif +#endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */ #if SIZEOF_INT == 8 a_time.tm_year = -1*(1 << 48); @@ -711,7 +711,7 @@ test_util_time(void *arg) CAPTURE(); tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time)); CHECK_TIMEGM_ARG_OUT_OF_RANGE(); -#endif +#endif /* SIZEOF_INT == 8 */ /* Wrong year >= INT32_MAX - 1900 */ #if SIZEOF_INT == 4 || SIZEOF_INT == 8 @@ -724,7 +724,7 @@ test_util_time(void *arg) CAPTURE(); tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time)); CHECK_TIMEGM_ARG_OUT_OF_RANGE(); -#endif +#endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */ #if SIZEOF_INT == 8 /* one of the largest tm_year values my 64 bit system supports */ @@ -752,7 +752,7 @@ test_util_time(void *arg) CAPTURE(); tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time)); CHECK_TIMEGM_ARG_OUT_OF_RANGE(); -#endif +#endif /* SIZEOF_INT == 8 */ /* month */ a_time.tm_year = 2007-1900; /* restore valid year */ @@ -888,7 +888,7 @@ test_util_time(void *arg) teardown_capture_of_logs(); } } -#endif +#endif /* SIZEOF_TIME_T == 8 */ /* time_t >= INT_MAX yields a year clamped to 2037 or 9999, * depending on whether the implementation of the system gmtime(_r) @@ -904,7 +904,7 @@ test_util_time(void *arg) tt_assert(b_time.tm_year == (2037-1900) || b_time.tm_year == (2038-1900)); } -#endif +#endif /* SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8 */ #if SIZEOF_TIME_T == 8 { @@ -929,7 +929,7 @@ test_util_time(void *arg) tt_assert(b_time.tm_year == (2037-1900) || b_time.tm_year == (9999-1900)); } -#endif +#endif /* SIZEOF_TIME_T == 8 */ /* Test {format,parse}_rfc1123_time */ @@ -974,7 +974,7 @@ test_util_time(void *arg) i = parse_rfc1123_time(timestr, &t_res); tt_int_op(0,OP_EQ, i); tt_int_op(t_res,OP_EQ, (time_t)2150000000UL); -#endif +#endif /* SIZEOF_TIME_T == 4 || ... */ /* The timezone doesn't matter */ t_res = 0; @@ -1046,7 +1046,7 @@ test_util_time(void *arg) #elif SIZEOF_TIME_T == 8 tt_int_op(0,OP_EQ, i); tt_int_op(t_res,OP_EQ, (time_t)2150000000UL); -#endif +#endif /* SIZEOF_TIME_T == 4 || ... */ tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-zz 99-99x99", &t_res)); tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-32 00:00:00", &t_res)); @@ -1129,7 +1129,7 @@ test_util_time(void *arg) /* This SHOULD work on windows too; see bug #18665 */ tt_str_op("2038-02-17 06:13:20",OP_EQ, timestr); #endif -#endif +#endif /* SIZEOF_TIME_T == 4 || ... */ #undef CAPTURE #undef CHECK_TIMEGM_ARG_OUT_OF_RANGE @@ -1224,7 +1224,7 @@ test_util_parse_http_time(void *arg) tt_int_op(0,OP_EQ,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time)); tt_int_op((time_t)2150000000UL,OP_EQ, tor_timegm(&a_time)); T("2038-02-17 06:13:20"); -#endif +#endif /* SIZEOF_TIME_T == 4 || ... */ tt_int_op(-1,OP_EQ, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time)); tt_int_op(-1,OP_EQ, parse_http_time("2011-03-32 00:00:00 GMT", &a_time)); @@ -1471,7 +1471,7 @@ test_util_config_line_comment_character(void *arg) tor_free(k); tor_free(v); test_streq(str, ""); -#endif +#endif /* 0 */ done: tor_free(k); @@ -1602,7 +1602,7 @@ test_util_config_line_escaped_content(void *arg) str = parse_config_line_from_str_verbose(str, &k, &v, NULL); tt_ptr_op(str, OP_EQ, NULL); tor_free(k); tor_free(v); -#endif +#endif /* 0 */ str = buf6; @@ -1786,7 +1786,7 @@ test_util_expand_filename(void *arg) done: tor_free(str); } -#endif +#endif /* !defined(_WIN32) */ /** Test tor_escape_str_for_pt_args(). */ static void @@ -2555,7 +2555,7 @@ test_util_mmap(void *arg) tt_str_op(mapping->data,OP_EQ, "Short file."); tt_int_op(0, OP_EQ, tor_munmap_file(mapping)); mapping = NULL; -#endif +#endif /* defined(_WIN32) */ /* Now a zero-length file. */ write_str_to_file(fname1, "", 1); @@ -2884,7 +2884,7 @@ test_util_sscanf(void *arg) r = tor_sscanf("9223372036854775808. -9223372036854775809.", "%d. %d.", &int1, &int2); tt_int_op(r,OP_EQ, 0); -#endif +#endif /* SIZEOF_INT == 4 || ... */ #if SIZEOF_LONG == 4 /* %lu */ @@ -2979,7 +2979,7 @@ test_util_sscanf(void *arg) r = tor_sscanf("9223372036854775808. -9223372036854775809.", "%ld. %ld.", &lng1, &lng2); tt_int_op(r,OP_EQ, 0); -#endif +#endif /* SIZEOF_LONG == 4 || ... */ r = tor_sscanf("123.456 .000007 -900123123.2000787 00003.2", "%lf %lf %lf %lf", &d1,&d2,&d3,&d4); @@ -3006,7 +3006,7 @@ strnlen(const char *s, size_t len) return len; return p - s; } -#endif +#endif /* !defined(HAVE_STRNLEN) */ static void test_util_format_time_interval(void *arg) @@ -3373,7 +3373,7 @@ test_util_format_time_interval(void *arg) tt_ci_char_op(label_m[0],OP_EQ, 'm'); /* and 7 or 8 seconds - ignored */ -#endif +#endif /* SIZEOF_LONG == 4 || SIZEOF_LONG == 8 */ #if SIZEOF_LONG == 8 @@ -3411,7 +3411,7 @@ test_util_format_time_interval(void *arg) tt_ci_char_op(label_m[0],OP_EQ, 'm'); /* and 7 or 8 seconds - ignored */ -#endif +#endif /* SIZEOF_LONG == 8 */ done: ; @@ -3454,7 +3454,7 @@ test_util_path_is_relative(void *arg) tt_int_op(0,OP_EQ, path_is_relative("\\dir")); tt_int_op(0,OP_EQ, path_is_relative("a:\\dir")); tt_int_op(0,OP_EQ, path_is_relative("z:\\dir")); -#endif +#endif /* defined(_WIN32) */ done: ; @@ -3474,7 +3474,7 @@ test_util_memarea(void *arg) malloc(), which is free to lay out memory most any way it wants. */ if (1) tt_skip(); -#endif +#endif /* defined(DISABLE_MEMORY_SENTINELS) */ (void)arg; tt_assert(area); @@ -3996,7 +3996,7 @@ test_util_load_win_lib(void *ptr) if (h) FreeLibrary(h); } -#endif +#endif /* defined(_WIN32) */ #ifndef _WIN32 static void @@ -4048,7 +4048,7 @@ test_util_exit_status(void *ptr) tt_int_op(n,OP_EQ, strlen(hex_errno)); tt_int_op(n,OP_EQ, HEX_ERRNO_SIZE); -#endif +#endif /* SIZEOF_INT == 4 || ... */ clear_hex_errno(hex_errno); n = format_helper_exit_status(0x7F, 0, hex_errno); @@ -4066,7 +4066,7 @@ test_util_exit_status(void *ptr) done: ; } -#endif +#endif /* !defined(_WIN32) */ #ifndef _WIN32 static void @@ -4194,7 +4194,7 @@ test_util_string_from_pipe(void *ptr) close(test_pipe[1]); } -#endif // _WIN32 +#endif /* !defined(_WIN32) */ /** * Test for format_hex_number_sigsafe() @@ -5216,7 +5216,7 @@ fd_is_cloexec(tor_socket_t fd) int flags = fcntl(fd, F_GETFD, 0); return (flags & FD_CLOEXEC) == FD_CLOEXEC; } -#endif +#endif /* defined(FD_CLOEXEC) */ #ifndef _WIN32 #define CAN_CHECK_NONBLOCK @@ -5226,7 +5226,7 @@ fd_is_nonblocking(tor_socket_t fd) int flags = fcntl(fd, F_GETFL, 0); return (flags & O_NONBLOCK) == O_NONBLOCK; } -#endif +#endif /* !defined(_WIN32) */ #define ERRNO_IS_EPROTO(e) (e == SOCK_ERRNO(EPROTONOSUPPORT)) #define SOCK_ERR_IS_EPROTO(s) ERRNO_IS_EPROTO(tor_socket_errno(s)) @@ -5270,13 +5270,13 @@ test_util_socket(void *arg) tt_int_op(fd_is_cloexec(fd2), OP_EQ, 0); tt_int_op(fd_is_cloexec(fd3), OP_EQ, 1); tt_int_op(fd_is_cloexec(fd4), OP_EQ, 1); -#endif +#endif /* defined(CAN_CHECK_CLOEXEC) */ #ifdef CAN_CHECK_NONBLOCK tt_int_op(fd_is_nonblocking(fd1), OP_EQ, 0); tt_int_op(fd_is_nonblocking(fd2), OP_EQ, 1); tt_int_op(fd_is_nonblocking(fd3), OP_EQ, 0); tt_int_op(fd_is_nonblocking(fd4), OP_EQ, 1); -#endif +#endif /* defined(CAN_CHECK_NONBLOCK) */ tor_assert(tor_close_socket == tor_close_socket__real); @@ -5332,7 +5332,7 @@ is_there_a_localhost(int family) return result; } -#endif +#endif /* 0 */ /* Test for socketpair and ersatz_socketpair(). We test them both, since * the latter is a tolerably good way to exersize tor_accept_socket(). */ @@ -5359,7 +5359,7 @@ test_util_socketpair(void *arg) * Assume we're on a machine without 127.0.0.1 or ::1 and give up now. */ tt_skip(); } -#endif +#endif /* defined(__FreeBSD__) */ tt_int_op(0, OP_EQ, socketpair_result); tt_assert(SOCKET_OK(fds[0])); @@ -5520,7 +5520,7 @@ test_util_get_avail_disk_space(void *arg) #else tt_i64_op(val, OP_GT, 0); /* You have some space. */ tt_i64_op(val, OP_LT, ((int64_t)1)<<56); /* You don't have a zebibyte */ -#endif +#endif /* !defined(HAVE_STATVFS) && !defined(_WIN32) */ done: ; @@ -5630,7 +5630,7 @@ test_util_pwdb(void *arg) tor_free(dir); teardown_capture_of_logs(); } -#endif +#endif /* !defined(_WIN32) */ static void test_util_calloc_check(void *arg) @@ -5808,7 +5808,7 @@ test_util_htonll(void *arg) #else tt_u64_op(res_le, OP_EQ, tor_htonll(0x8877665544332211)); tt_u64_op(res_le, OP_EQ, tor_ntohll(0x8877665544332211)); -#endif +#endif /* defined(WORDS_BIGENDIAN) */ done: ; @@ -5915,7 +5915,7 @@ test_util_get_unquoted_path(void *arg) #define UTIL_TEST_NO_WIN(n, f) UTIL_TEST(n, (f)) #define UTIL_TEST_WIN_ONLY(n, f) { #n, NULL, TT_SKIP, NULL, NULL } #define UTIL_LEGACY_NO_WIN(n) UTIL_LEGACY(n) -#endif +#endif /* defined(_WIN32) */ struct testcase_t util_tests[] = { UTIL_LEGACY(time), diff --git a/src/test/test_util_process.c b/src/test/test_util_process.c index 70292f2287..68ce6cfd40 100644 --- a/src/test/test_util_process.c +++ b/src/test/test_util_process.c @@ -67,7 +67,7 @@ test_util_process_clear_waitpid_callback(void *ignored) done: teardown_capture_of_logs(); } -#endif /* _WIN32 */ +#endif /* !defined(_WIN32) */ #ifndef _WIN32 #define TEST(name) { #name, test_util_process_##name, 0, NULL, NULL } diff --git a/src/test/test_util_slow.c b/src/test/test_util_slow.c index b120c91083..2cd68cf118 100644 --- a/src/test/test_util_slow.c +++ b/src/test/test_util_slow.c @@ -22,14 +22,14 @@ #else #define TEST_CHILD (BUILDDIR "/src/test/test-child") #define EOL "\n" -#endif +#endif /* defined(_WIN32) */ #ifdef _WIN32 /* I've assumed Windows doesn't have the gap between fork and exec * that causes the race condition on unix-like platforms */ #define MATCH_PROCESS_STATUS(s1,s2) ((s1) == (s2)) -#else +#else /* !(defined(_WIN32)) */ /* work around a race condition of the timing of SIGCHLD handler updates * to the process_handle's fields, and checks of those fields * @@ -46,7 +46,7 @@ ||((s2) == PROCESS_STATUS_RUNNING_OR_NOTRUNNING \ && IS_RUNNING_OR_NOTRUNNING(s1))) -#endif // _WIN32 +#endif /* defined(_WIN32) */ /** Helper function for testing tor_spawn_background */ static void @@ -102,7 +102,7 @@ run_util_spawn_background(const char *argv[], const char *expected_out, * that is, PROCESS_STATUS_RUNNING_OR_NOTRUNNING */ tt_assert(process_handle->waitpid_cb != NULL || expected_status == PROCESS_STATUS_RUNNING_OR_NOTRUNNING); -#endif +#endif /* !defined(_WIN32) */ #ifdef _WIN32 tt_assert(process_handle->stdout_pipe != INVALID_HANDLE_VALUE); @@ -112,7 +112,7 @@ run_util_spawn_background(const char *argv[], const char *expected_out, tt_assert(process_handle->stdout_pipe >= 0); tt_assert(process_handle->stderr_pipe >= 0); tt_assert(process_handle->stdin_pipe >= 0); -#endif +#endif /* defined(_WIN32) */ /* Check stdout */ pos = tor_read_all_from_process_stdout(process_handle, stdout_buf, @@ -178,7 +178,7 @@ test_util_spawn_background_fail(void *ptr) /* TODO: Once we can signal failure to exec, set this to be * PROCESS_STATUS_RUNNING_OR_ERROR */ const int expected_status = PROCESS_STATUS_RUNNING_OR_NOTRUNNING; -#endif +#endif /* defined(_WIN32) */ memset(expected_out, 0xf0, sizeof(expected_out)); memset(code, 0xf0, sizeof(code)); @@ -244,7 +244,7 @@ test_util_spawn_background_partial_read_impl(int exit_early) tt_assert(!eof); pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf, sizeof(stdout_buf) - 1, NULL, &eof); -#endif +#endif /* defined(_WIN32) */ log_info(LD_GENERAL, "tor_read_all_handle() returned %d", (int)pos); /* We would have blocked, keep on trying */ @@ -270,7 +270,7 @@ test_util_spawn_background_partial_read_impl(int exit_early) sizeof(stdout_buf) - 1, process_handle); tt_int_op(0,OP_EQ, pos); -#else +#else /* !(defined(_WIN32)) */ if (!eof) { /* We should have got all the data, but maybe not the EOF flag */ pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf, @@ -280,7 +280,7 @@ test_util_spawn_background_partial_read_impl(int exit_early) tt_assert(eof); } /* Otherwise, we got the EOF on the last read */ -#endif +#endif /* defined(_WIN32) */ /* Check it terminated correctly */ retval = tor_get_exit_code(process_handle, 1, &exit_code); @@ -351,7 +351,7 @@ test_util_spawn_background_waitpid_notify(void *arg) } tt_int_op(ms_timer, OP_GT, 0); tt_ptr_op(process_handle->waitpid_cb, OP_EQ, NULL); -#endif +#endif /* !defined(_WIN32) */ ms_timer = 30*1000; while (((retval = tor_get_exit_code(process_handle, 0, &exit_code)) diff --git a/src/test/test_workqueue.c b/src/test/test_workqueue.c index 6fa46f90d4..2b03173717 100644 --- a/src/test/test_workqueue.c +++ b/src/test/test_workqueue.c @@ -61,9 +61,9 @@ mark_handled(int serial) tor_assert(! bitarray_is_set(handled, serial)); bitarray_set(handled, serial); tor_mutex_release(&bitmap_mutex); -#else +#else /* !(defined(TRACK_RESPONSES)) */ (void)serial; -#endif +#endif /* defined(TRACK_RESPONSES) */ } static workqueue_reply_t @@ -288,7 +288,7 @@ replysock_readable_cb(tor_socket_t sock, short what, void *arg) } puts(""); tor_mutex_release(&bitmap_mutex); -#endif +#endif /* defined(TRACK_RESPONSES) */ if (n_sent - (n_received+n_successful_cancel) < opt_n_lowwater) { int n_to_send = n_received + opt_n_inflight - n_sent; @@ -422,7 +422,7 @@ main(int argc, char **argv) received = bitarray_init_zero(opt_n_items); tor_mutex_init(&bitmap_mutex); handled_len = opt_n_items; -#endif +#endif /* defined(TRACK_RESPONSES) */ for (i = 0; i < opt_n_inflight; ++i) { if (! add_work(tp)) { diff --git a/src/test/testing_common.c b/src/test/testing_common.c index d7e36edbc0..7e9c47b48d 100644 --- a/src/test/testing_common.c +++ b/src/test/testing_common.c @@ -33,7 +33,7 @@ const char tor_git_revision[] = ""; #include <direct.h> #else #include <dirent.h> -#endif +#endif /* defined(_WIN32) */ #include "or.h" @@ -84,7 +84,7 @@ setup_directory(void) (int)getpid(), rnd32); r = mkdir(temp_dir); } -#else +#else /* !(defined(_WIN32)) */ tor_snprintf(temp_dir, sizeof(temp_dir), "/tmp/tor_test_%d_%s", (int) getpid(), rnd32); r = mkdir(temp_dir, 0700); @@ -92,7 +92,7 @@ setup_directory(void) /* undo sticky bit so tests don't get confused. */ r = chown(temp_dir, getuid(), getgid()); } -#endif +#endif /* defined(_WIN32) */ if (r) { fprintf(stderr, "Can't create directory %s:", temp_dir); perror(""); @@ -241,7 +241,7 @@ main(int c, const char **v) int r = crypto_use_tor_alloc_functions(); tor_assert(r == 0); } -#endif +#endif /* defined(USE_DMALLOC) */ update_approx_time(time(NULL)); options = options_new(); diff --git a/src/test/testing_rsakeys.c b/src/test/testing_rsakeys.c index 5dff233a69..7a24c0ed14 100644 --- a/src/test/testing_rsakeys.c +++ b/src/test/testing_rsakeys.c @@ -436,7 +436,7 @@ static int next_key_idx_1024; #define N_PREGEN_KEYS_2048 ARRAY_LENGTH(PREGEN_KEYS_2048) static crypto_pk_t *pregen_keys_2048[N_PREGEN_KEYS_2048]; static int next_key_idx_2048; -#endif +#endif /* defined(USE_PREGENERATED_RSA_KEYS) */ /** Generate and return a new keypair for use in unit tests. If we're using * the key cache optimization, we might reuse keys. "idx" is ignored. @@ -466,14 +466,14 @@ pk_generate_internal(int bits) *idxp += crypto_rand_int_range(1,3); *idxp %= n_pregen; return crypto_pk_dup_key(pregen_array[*idxp]); -#else +#else /* !(defined(USE_PREGENERATED_RSA_KEYS)) */ crypto_pk_t *result; int res; result = crypto_pk_new(); res = crypto_pk_generate_key_with_bits__real(result, bits); tor_assert(!res); return result; -#endif +#endif /* defined(USE_PREGENERATED_RSA_KEYS) */ } crypto_pk_t * @@ -496,7 +496,7 @@ crypto_pk_generate_key_with_bits__get_cached(crypto_pk_t *env, int bits) } return 0; } -#endif +#endif /* defined(USE_PREGENERATED_RSA_KEYS) */ /** Free all storage used for the cached key optimization. */ void @@ -516,7 +516,7 @@ free_pregenerated_keys(void) pregen_keys_2048[idx] = NULL; } } -#endif +#endif /* defined(USE_PREGENERATED_RSA_KEYS) */ } void @@ -541,6 +541,6 @@ init_pregenerated_keys(void) MOCK(crypto_pk_generate_key_with_bits, crypto_pk_generate_key_with_bits__get_cached); -#endif +#endif /* defined(USE_PREGENERATED_RSA_KEYS) */ } |