diff options
Diffstat (limited to 'src/lib')
388 files changed, 3706 insertions, 1065 deletions
diff --git a/src/lib/arch/bytes.h b/src/lib/arch/bytes.h index 4756ca2beb..c72ac3eb8e 100644 --- a/src/lib/arch/bytes.h +++ b/src/lib/arch/bytes.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_BYTES_H @@ -16,12 +16,17 @@ #include <string.h> #include "lib/cc/torint.h" -/* The uint8 variants are defined to make the code more uniform. */ +/** + * Read an 8-bit from <b>cp</b>. + */ static inline uint8_t get_uint8(const void *cp) { return *(const uint8_t*)(cp); } +/** + * Store an 8-bit value from <b>v</b> to <b>cp</b>. + */ static inline void set_uint8(void *cp, uint8_t v) { @@ -93,7 +98,7 @@ set_uint64(void *cp, uint64_t v) memcpy(cp,&v,8); } -#ifdef WORDS_BIGENDIAN +#if defined(WORDS_BIGENDIAN) static inline uint16_t tor_htons(uint32_t a) { @@ -130,6 +135,9 @@ tor_ntohll(uint64_t a) return a; } #else /* !defined(WORDS_BIGENDIAN) */ +/** + * Convert a 16-bit value from host order to network order (big-endian). + **/ static inline uint16_t tor_htons(uint16_t a) { @@ -139,12 +147,18 @@ tor_htons(uint16_t a) ((a & 0xff00) >> 8); } +/** + * Convert a 16-bit value from network order (big-endian) to host order. + **/ static inline uint16_t tor_ntohs(uint16_t a) { return tor_htons(a); } +/** + * Convert a 32-bit value from host order to network order (big-endian). + **/ static inline uint32_t tor_htonl(uint32_t a) { @@ -156,6 +170,9 @@ tor_htonl(uint32_t a) ((a & 0xff000000) >>24); } +/** + * Convert a 32-bit value from network order (big-endian) to host order. + **/ static inline uint32_t tor_ntohl(uint32_t a) { diff --git a/src/lib/arch/lib_arch.md b/src/lib/arch/lib_arch.md new file mode 100644 index 0000000000..9b8bccdf16 --- /dev/null +++ b/src/lib/arch/lib_arch.md @@ -0,0 +1,2 @@ +@dir /lib/arch +@brief lib/arch: Compatibility code for handling different CPU architectures. diff --git a/src/lib/buf/buffers.c b/src/lib/buf/buffers.c index ace5bdc4a4..d7b73e3807 100644 --- a/src/lib/buf/buffers.c +++ b/src/lib/buf/buffers.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -99,6 +99,7 @@ #define DBG_S(s) (void)0 #endif +#ifndef COCCI #ifdef DISABLE_MEMORY_SENTINELS #define CHUNK_SET_SENTINEL(chunk, alloclen) STMT_NIL #else @@ -109,6 +110,7 @@ memset(a,0,SENTINEL_LEN); \ } while (0) #endif /* defined(DISABLE_MEMORY_SENTINELS) */ +#endif /* !defined(COCCI) */ /** Move all bytes stored in <b>chunk</b> to the front of <b>chunk</b>->mem, * to free up space at the end. */ @@ -578,6 +580,7 @@ buf_add_vprintf(buf_t *buf, const char *format, va_list args) /* XXXX Faster implementations are easy enough, but let's optimize later */ char *tmp; tor_vasprintf(&tmp, format, args); + tor_assert(tmp != NULL); buf_add(buf, tmp, strlen(tmp)); tor_free(tmp); } diff --git a/src/lib/buf/buffers.h b/src/lib/buf/buffers.h index c103b93a82..fadd4174c0 100644 --- a/src/lib/buf/buffers.h +++ b/src/lib/buf/buffers.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/buf/lib_buf.md b/src/lib/buf/lib_buf.md new file mode 100644 index 0000000000..519ab50a2d --- /dev/null +++ b/src/lib/buf/lib_buf.md @@ -0,0 +1,13 @@ +@dir /lib/buf +@brief lib/buf: An efficient byte queue. + +This module defines the buf_t type, which is used throughout our networking +code. The implementation is a singly-linked queue of buffer chunks, similar +to the BSD kernel's +["mbuf"](https://www.freebsd.org/cgi/man.cgi?query=mbuf&sektion=9) structure. + +The buf_t type is also reasonable for use in constructing long strings. + +See \refdir{lib/net} for networking code that uses buf_t, and +\refdir{lib/tls} for cryptographic code that uses buf_t. + diff --git a/src/lib/cc/compat_compiler.h b/src/lib/cc/compat_compiler.h index d9ccabb2b3..015b5af320 100644 --- a/src/lib/cc/compat_compiler.h +++ b/src/lib/cc/compat_compiler.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -65,8 +65,6 @@ /* Temporarily enable and disable warnings. */ #ifdef __GNUC__ -# define PRAGMA_STRINGIFY_(s) #s -# define PRAGMA_JOIN_STRINGIFY_(a,b) PRAGMA_STRINGIFY_(a ## b) /* Support for macro-generated pragmas (c99) */ # define PRAGMA_(x) _Pragma (#x) # ifdef __clang__ @@ -78,15 +76,15 @@ /* we have push/pop support */ # define DISABLE_GCC_WARNING(warningopt) \ PRAGMA_DIAGNOSTIC_(push) \ - PRAGMA_DIAGNOSTIC_(ignored PRAGMA_JOIN_STRINGIFY_(-W,warningopt)) + PRAGMA_DIAGNOSTIC_(ignored warningopt) # define ENABLE_GCC_WARNING(warningopt) \ PRAGMA_DIAGNOSTIC_(pop) #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)) + PRAGMA_DIAGNOSTIC_(ignored warningopt) # define ENABLE_GCC_WARNING(warningopt) \ - PRAGMA_DIAGNOSTIC_(warning PRAGMA_JOIN_STRINGIFY_(-W,warningopt)) + PRAGMA_DIAGNOSTIC_(warning warningopt) #endif /* defined(__clang__) || GCC_VERSION >= 406 */ #else /* !defined(__GNUC__) */ /* not gcc at all */ @@ -200,8 +198,8 @@ /** Macro: yield a pointer to the field at position <b>off</b> within the * structure <b>st</b>. Example: * <pre> - * struct a { int foo; int bar; } x; - * ptrdiff_t bar_offset = offsetof(struct a, bar); + * struct a_t { int foo; int bar; } x; + * ptrdiff_t bar_offset = offsetof(struct a_t, bar); * int *bar_p = STRUCT_VAR_P(&x, bar_offset); * *bar_p = 3; * </pre> @@ -211,10 +209,10 @@ /** Macro: yield a pointer to an enclosing structure given a pointer to * a substructure at offset <b>off</b>. Example: * <pre> - * struct base { ... }; - * struct subtype { int x; struct base b; } x; - * struct base *bp = &x.base; - * struct *sp = SUBTYPE_P(bp, struct subtype, b); + * struct base_t { ... }; + * struct subtype_t { int x; struct base_t b; } x; + * struct base_t *bp = &x.base; + * struct *sp = SUBTYPE_P(bp, struct subtype_t, b); * </pre> */ #define SUBTYPE_P(p, subtype, basemember) \ @@ -235,4 +233,17 @@ #define EAT_SEMICOLON \ struct dummy_semicolon_eater__ +/** + * Tell our static analysis tool to believe that (clang's scan-build or + * coverity scan) that an expression might be true. We use this to suppress + * dead-code warnings. + **/ +#if defined(__COVERITY__) || defined(__clang_analyzer__) +/* By calling getenv, we force the analyzer not to conclude that 'expr' is + * false. */ +#define POSSIBLE(expr) ((expr) || getenv("STATIC_ANALYZER_DEADCODE_DUMMY_")) +#else +#define POSSIBLE(expr) (expr) +#endif /* defined(__COVERITY__) || defined(__clang_analyzer__) */ + #endif /* !defined(TOR_COMPAT_COMPILER_H) */ diff --git a/src/lib/cc/ctassert.h b/src/lib/cc/ctassert.h index bedf0b83a6..d9d3aa40b0 100644 --- a/src/lib/cc/ctassert.h +++ b/src/lib/cc/ctassert.h @@ -46,7 +46,7 @@ #define CTASSERT_EXPN(x, a, b) CTASSERT_DECL(x, a, b) #define CTASSERT_DECL(x, a, b) \ - typedef char tor_ctassert_##a##_##b[(x) ? 1 : -1] ATTR_UNUSED + typedef char tor_ctassert_##a##_##b[(x) ? 1 : -1] ATTR_UNUSED; EAT_SEMICOLON #endif /* __STDC_VERSION__ >= 201112L */ diff --git a/src/lib/cc/include.am b/src/lib/cc/include.am index 1aa722dd82..d2a415e956 100644 --- a/src/lib/cc/include.am +++ b/src/lib/cc/include.am @@ -3,4 +3,5 @@ noinst_HEADERS += \ src/lib/cc/compat_compiler.h \ src/lib/cc/ctassert.h \ + src/lib/cc/tokpaste.h \ src/lib/cc/torint.h diff --git a/src/lib/cc/lib_cc.md b/src/lib/cc/lib_cc.md new file mode 100644 index 0000000000..bd49005ba2 --- /dev/null +++ b/src/lib/cc/lib_cc.md @@ -0,0 +1,2 @@ +@dir /lib/cc +@brief lib/cc: Macros for managing the C compiler and language. diff --git a/src/lib/cc/tokpaste.h b/src/lib/cc/tokpaste.h new file mode 100644 index 0000000000..068621b5bd --- /dev/null +++ b/src/lib/cc/tokpaste.h @@ -0,0 +1,30 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2020, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file tokpaste.h + * @brief Token-pasting macros. + **/ + +#ifndef TOR_LIB_CC_TOKPASTE_H +#define TOR_LIB_CC_TOKPASTE_H + +/** + * Concatenate `a` and `b` in a way that allows their result itself to be + * expanded by the preprocessor. + * + * Ordinarily you could just say `a ## b` in a macro definition. But doing so + * results in a symbol which the preprocessor will not then expand. If you + * wanted to use `a ## b` to create the name of a macro and have the + * preprocessor expand _that_ macro, you need to have another level of + * indirection, as this macro provides. + **/ +#define PASTE(a,b) PASTE__(a,b) + +/** Helper for PASTE(). */ +#define PASTE__(a,b) a ## b + +#endif /* !defined(TOR_LIB_CC_TOKPASTE_H) */ diff --git a/src/lib/cc/torint.h b/src/lib/cc/torint.h index 94b79d30a1..cef1482bdc 100644 --- a/src/lib/cc/torint.h +++ b/src/lib/cc/torint.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/compress/compress.c b/src/lib/compress/compress.c index 51591410a2..c62d7d5d2a 100644 --- a/src/lib/compress/compress.c +++ b/src/lib/compress/compress.c @@ -1,6 +1,6 @@ /* Copyright (c) 2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/compress/compress.h b/src/lib/compress/compress.h index 8cea4ead60..f36cdb82aa 100644 --- a/src/lib/compress/compress.h +++ b/src/lib/compress/compress.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/compress/compress_buf.c b/src/lib/compress/compress_buf.c index 2e704466f2..d1941c9da6 100644 --- a/src/lib/compress/compress_buf.c +++ b/src/lib/compress/compress_buf.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/compress/compress_lzma.c b/src/lib/compress/compress_lzma.c index 915f4949ae..8884b020e8 100644 --- a/src/lib/compress/compress_lzma.c +++ b/src/lib/compress/compress_lzma.c @@ -1,6 +1,6 @@ /* Copyright (c) 2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/compress/compress_lzma.h b/src/lib/compress/compress_lzma.h index 556ab437dc..de03cda91c 100644 --- a/src/lib/compress/compress_lzma.h +++ b/src/lib/compress/compress_lzma.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/compress/compress_none.c b/src/lib/compress/compress_none.c index 0b5760773a..43c021c788 100644 --- a/src/lib/compress/compress_none.c +++ b/src/lib/compress/compress_none.c @@ -1,6 +1,6 @@ /* Copyright (c) 2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/compress/compress_none.h b/src/lib/compress/compress_none.h index 2bb9c3d66c..df696a11aa 100644 --- a/src/lib/compress/compress_none.h +++ b/src/lib/compress/compress_none.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/compress/compress_sys.h b/src/lib/compress/compress_sys.h index 6181072315..dce0549924 100644 --- a/src/lib/compress/compress_sys.h +++ b/src/lib/compress/compress_sys.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/compress/compress_zlib.c b/src/lib/compress/compress_zlib.c index df0d1bff5f..3711e46222 100644 --- a/src/lib/compress/compress_zlib.c +++ b/src/lib/compress/compress_zlib.c @@ -1,6 +1,6 @@ /* Copyright (c) 2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/compress/compress_zlib.h b/src/lib/compress/compress_zlib.h index e4f248cd9b..7328ce899b 100644 --- a/src/lib/compress/compress_zlib.h +++ b/src/lib/compress/compress_zlib.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/compress/compress_zstd.c b/src/lib/compress/compress_zstd.c index 9076665295..5913d823e1 100644 --- a/src/lib/compress/compress_zstd.c +++ b/src/lib/compress/compress_zstd.c @@ -1,6 +1,6 @@ /* Copyright (c) 2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -29,11 +29,11 @@ #ifdef HAVE_ZSTD #ifdef HAVE_CFLAG_WUNUSED_CONST_VARIABLE -DISABLE_GCC_WARNING(unused-const-variable) +DISABLE_GCC_WARNING("-Wunused-const-variable") #endif #include <zstd.h> #ifdef HAVE_CFLAG_WUNUSED_CONST_VARIABLE -ENABLE_GCC_WARNING(unused-const-variable) +ENABLE_GCC_WARNING("-Wunused-const-variable") #endif #endif /* defined(HAVE_ZSTD) */ diff --git a/src/lib/compress/compress_zstd.h b/src/lib/compress/compress_zstd.h index 47f950b9e0..0fc71db749 100644 --- a/src/lib/compress/compress_zstd.h +++ b/src/lib/compress/compress_zstd.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/compress/lib_compress.md b/src/lib/compress/lib_compress.md new file mode 100644 index 0000000000..c43f223fe7 --- /dev/null +++ b/src/lib/compress/lib_compress.md @@ -0,0 +1,6 @@ +@dir /lib/compress +@brief lib/compress: Wraps several compression libraries + +Currently supported are zlib (mandatory), zstd (optional), and lzma +(optional). + diff --git a/src/lib/conf/confdecl.h b/src/lib/conf/confdecl.h new file mode 100644 index 0000000000..c2d3fb335d --- /dev/null +++ b/src/lib/conf/confdecl.h @@ -0,0 +1,221 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2020, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file confdecl.h + * @brief Macros for generating a configuration struct from a list + * of its individual fields. + * + * This header defines three important macros: BEGIN_CONF_STRUCT(), + * END_CONF_STRUCT(), and CONF_VAR(). They're meant to be used together to + * define a configuration structure and the means for encoding and decoding + * it. + * + * To use them, make a new header with a name like `MOD_options.inc`. Start + * it with a BEGIN_CONF_STRUCT(), then define your variables with CONF_VAR(), + * then end the header with END_CONF_STRUCT(), as in: + * + * BEGIN_CONF_STRUCT(module_options_t) + * CONF_VAR(ModuleIsActive, BOOLEAN, 0, "1") + * END_CONF_STRUCT(module_options_t) + * + * Once you've done that, you can use that header to define a configuration + * structure by saying: + * + * typedef struct module_options_t module_options_t; + * #define CONF_CONTEXT STRUCT + * #include "MOD_options.inc" + * #undef CONF_CONTEXT + * + * And you can define your field definition table by saying: + * + * #define CONF_CONTEXT TABLE + * #include "MOD_options.inc" + * #undef CONF_CONTEXT + * + * The two above snippets will define a structure called `module_options_t` + * with appropriate members, and a table of config_var_t objects called + * `module_options_t_vars[]`. + * + * For lower-level modules, you can say <tt>\#define CONF_TABLE LL_TABLE</tt>, + * and get a table definition suitable for use in modules that are at a lower + * level than lib/confmgt. Note that the types for these tables cannot + * include any extended types. + **/ + +#ifndef TOR_LIB_CONF_CONFDECL_H +#define TOR_LIB_CONF_CONFDECL_H + +#undef CONF_CONTEXT +#include "lib/cc/tokpaste.h" +#include "lib/cc/torint.h" + +/** + * Begin the definition of a configuration object called `name`. + **/ +#define BEGIN_CONF_STRUCT(name) \ + PASTE(BEGIN_CONF_STRUCT__, CONF_CONTEXT)(name) +/** + * End the definition of a configuration object called `name`. + **/ +#define END_CONF_STRUCT(name) \ + PASTE(END_CONF_STRUCT__, CONF_CONTEXT)(name) +/** + * Declare a single configuration field with name `varname`, type `vartype`, + * flags `varflags`, and initial value `initval`. + **/ +#define CONF_VAR(varname, vartype, varflags, initval) \ + PASTE(CONF_VAR__, CONF_CONTEXT)(varname, vartype, varflags, initval) + +#ifndef COCCI +/** + * @defgroup STRUCT_MACROS Internal macros: struct definitions. + * Implementation helpers: the regular confdecl macros expand to these + * when CONF_CONTEXT is defined to STRUCT. Don't use them directly. + * @{*/ +#define BEGIN_CONF_STRUCT__STRUCT(name) \ + struct name { \ + uint32_t magic; +#define END_CONF_STRUCT__STRUCT(name) \ + }; +#define CONF_VAR__STRUCT(varname, vartype, varflags, initval) \ + config_decl_ ## vartype varname; +/** @} */ + +/** + * @defgroup TABLE_MACROS Internal macros: table definitions. + * Implementation helpers: the regular confdecl macros expand to these + * when CONF_CONTEXT is defined to TABLE. Don't use them directly. + * @{*/ +#define BEGIN_CONF_STRUCT__TABLE(structname) \ + /* We use this typedef so we can refer to the config type */ \ + /* without having its name as a macro argument to CONF_VAR. */ \ + typedef struct structname config_var_reference__obj; \ + static const config_var_t structname##_vars[] = { +#define END_CONF_STRUCT__TABLE(structname) \ + { .member = { .name = NULL } } \ + }; +#define CONF_VAR__TABLE(varname, vartype, varflags, initval) \ + { \ + .member = \ + { .name = #varname, \ + .type = CONFIG_TYPE_EXTENDED, \ + .type_def = &vartype ## _type_defn, \ + .offset=offsetof(config_var_reference__obj, varname), \ + }, \ + .flags = varflags, \ + .initvalue = initval \ + }, +/**@}*/ + +/** + * @defgroup LL_TABLE_MACROS Internal macros: low-level table definitions. + * Implementation helpers: the regular confdecl macros expand to these + * when CONF_CONTEXT is defined to LL_TABLE. Don't use them directly. + * @{*/ +#define BEGIN_CONF_STRUCT__LL_TABLE(structname) \ + /* We use this typedef so we can refer to the config type */ \ + /* without having its name as a macro argument to CONF_VAR. */ \ + typedef struct structname config_var_reference__obj; \ + static const config_var_t structname##_vars[] = { +#define END_CONF_STRUCT__LL_TABLE(structname) \ + { .member = { .name = NULL } } \ + }; +#define CONF_VAR__LL_TABLE(varname, vartype, varflags, initval) \ + { \ + .member = \ + { .name = #varname, \ + .type = CONFIG_TYPE_ ## vartype, \ + .offset=offsetof(config_var_reference__obj, varname), \ + }, \ + .flags = varflags, \ + .initvalue = initval \ + }, +/**@}*/ + +/** @defgroup STUB_TABLE_MACROS Internal macros: stub table declarations, + * for use when a module is disabled. + * Implementation helpers: the regular confdecl macros expand to these + * when CONF_CONTEXT is defined to LL_TABLE. Don't use them directly. + * @{ */ +#define BEGIN_CONF_STRUCT__STUB_TABLE(structname) \ + static const config_var_t structname##_vars[] = { +#define END_CONF_STRUCT__STUB_TABLE(structname) \ + { .member = { .name = NULL } } \ + }; +#define CONF_VAR__STUB_TABLE(varname, vartype, varflags, initval) \ + { \ + .member = \ + { .name = #varname, \ + .type = CONFIG_TYPE_IGNORE, \ + .offset = -1, \ + }, \ + .flags = CFLG_GROUP_DISABLED, \ + }, +/**@}*/ + +#endif /* !defined(COCCI) */ + +/** Type aliases for the "commonly used" configuration types. + * + * Defining them in this way allows our CONF_VAR__STRUCT() macro to declare + * structure members corresponding to the configuration types. For example, + * when the macro sees us declare a configuration option "foo" of type STRING, + * it can emit `config_decl_STRING foo;`, which is an alias for `char *foo`. + */ +/**@{*/ +typedef char *config_decl_STRING; +typedef char *config_decl_FILENAME; +/* Yes, "POSINT" is really an int, and not an unsigned int. For + * historical reasons, many configuration values are restricted + * to the range [0,INT_MAX], and stored in signed ints. + */ +typedef int config_decl_POSINT; +typedef uint64_t config_decl_UINT64; +typedef int config_decl_INT; +typedef int config_decl_INTERVAL; +typedef int config_decl_MSEC_INTERVAL; +typedef uint64_t config_decl_MEMUNIT; +typedef double config_decl_DOUBLE; +typedef int config_decl_BOOL; +typedef int config_decl_AUTOBOOL; +typedef time_t config_decl_ISOTIME; +typedef struct smartlist_t config_decl_CSV; +typedef int config_decl_CSV_INTERVAL; +typedef struct config_line_t *config_decl_LINELIST; +typedef struct config_line_t *config_decl_LINELIST_V; +typedef struct nonexistent_struct *config_decl_LINELIST_S; +/**@}*/ + +struct var_type_def_t; + +/* Forward declarations for configuration type definitions. These are used by + * the CONF_VAR__TABLE macro to set the definition of each variable type + * correctly. + */ +/**@{*/ +extern const struct var_type_def_t STRING_type_defn; +extern const struct var_type_def_t FILENAME_type_defn; +extern const struct var_type_def_t POSINT_type_defn; +extern const struct var_type_def_t UINT64_type_defn; +extern const struct var_type_def_t INT_type_defn; +extern const struct var_type_def_t INTERVAL_type_defn; +extern const struct var_type_def_t MSEC_INTERVAL_type_defn; +extern const struct var_type_def_t MEMUNIT_type_defn; +extern const struct var_type_def_t DOUBLE_type_defn; +extern const struct var_type_def_t BOOL_type_defn; +extern const struct var_type_def_t AUTOBOOL_type_defn; +extern const struct var_type_def_t ISOTIME_type_defn; +extern const struct var_type_def_t CSV_type_defn; +extern const struct var_type_def_t CSV_INTERVAL_type_defn; +extern const struct var_type_def_t LINELIST_type_defn; +extern const struct var_type_def_t LINELIST_V_type_defn; +extern const struct var_type_def_t LINELIST_S_type_defn; +extern const struct var_type_def_t IGNORE_type_defn; +extern const struct var_type_def_t OBSOLETE_type_defn; +/**@}*/ + +#endif /* !defined(TOR_LIB_CONF_CONFDECL_H) */ diff --git a/src/lib/conf/config.md b/src/lib/conf/config.md new file mode 100644 index 0000000000..7741e21f42 --- /dev/null +++ b/src/lib/conf/config.md @@ -0,0 +1,126 @@ + +@page configuration Configuration options and persistent state + +@tableofcontents + +## Introduction + +Tor uses a shared, table-driven mechanism to handle its +configuration (torrc) files and its state files. Each module can +declare a set of named fields for these files, and get notified +whenever the configuration changes, or when the state is about to be +flushed to disk. + +## Declaring options + +Most modules will only need to use the macros in confdecl.h to +declare a configuration or state structure. + +You'll write something like this: + + // my_module_config.inc + BEGIN_CONF_STRUCT(module_options_t) + CONF_VAR(FieldOne, INT, 0, "7") + CONF_VAR(FieldTwo, STRING, 0, NULL) + END_CONF_STRUCT(module_options_t) + +The above example will result in a structure called module_config_t +with two fields: one an integer called FieldOne and one a string +called FieldTwo. The integer gets a default value of 7; the +string's default value is NULL. + +After making a definition file like that, you include it twice: once +in a header, after saying \#define CONF_CONTEXT STRUCT, and once in +a C file, after saying \#define CONF_CONTEXT TABLE. The first time +defines a module_options_t structure, and the second time defines a +table that tells the configuration manager how to use it. + +Using the table, you declare a `const` config_format_t, which +associates the fields with a set of functions for validating and +normalizing them, a list of abbreviations and deprecations, and +other features. + +See confdecl.h and conftypes.h for more information. For example +usage, see crypto_options.inc or mainloop_state.inc. + +## Getting notifications + +After using those macros, you must tell the subsystem management +code about your module's configuration/state. + +If you're writing configuration code, you'll need a function that receives +the configuration object, and acts upon it. This function needs to be safe +to call multiple times, since Tor will reconfigure its subsystems whenever it +re-reads the torrc, gets a configuration change from a controller, or +restarts in process. This function goes in your subsystem's +subsys_fns_t.set_options field. + +If you're writing state code, you'll need a function that receives +state (subsys_fns_t.set_state), and a function that flushes the +application state into a state object (subsys_fns_t.flush_state). +The `set_state` function will be called once (@ref config_once_per +"1") when Tor is starting, whereas the `flush_state` function will +be called whenever Tor is about to save the state to disk. + +See subsys_fns_t for more information here, and \ref initialization +for more information about initialization and subsystems in general. + +> @anchor config_once_per 1. Technically, state is set once _per startup_. +> Remember that Tor can be stopped and started multiple times in +> the same process. If this happens, then your set_state() function +> is called once every time Tor starts. + +## How it works + +The common logic used to handle configuration and state files lives +in @refdir{lib/confmgt}. At the highest level, a configuration +manager object (config_mgr_t) maintains a list of each module's +configuration objects, and a list of all their fields. When the +user specifies a configuration value, the manager finds out how to +parse it, where to store it, and which configuration object is +affected. + +The top-level configuration module (config.c) and state module +(statefile.c) use config_mgr_t to create, initialize, set, compare, +and free a "top level configuration object". This object contains a +list of sub-objects: one for each module that participates in the +configuration/state system. This top-level code then invokes the +subsystem manager code (subsysmgr.c) to pass the corresponding +configuration or state objects to each module that has one. + +Note that the top level code does not have easy access to the +configuration objects used by the sub-modules. This is by design. A +module _may_ expose some or all of its configuration or state object via +accessor functions, if it likes, but if it does not, that object should +be considered module-local. + +## Adding new types + +Configuration and state fields each have a "type". These types +specify how the fields' values are represented in C; how they are +stored in files; and how they are encoded back and forth. + +There is a set of built-in types listed in conftypes.h, but +higher-level code can define its own types. To do so, you make an +instance of var_type_fns_t that describes how to manage your type, +and an instance of var_type_def_t that wraps your var_type_fns_t +with a name and optional parameters and flags. + +For an example of how a higher-level type is defined, see +ROUTERSET_type_defn in routerset.c. Also see the typedef +`config_decl_ROUTERSET`. Together, these let the routerset type be +used with the macros in confdecl.h. + +## Legacy configuration and state + +As of this writing (November 2019), most of the configuration and state is +still handled directly in config.c and statefile.c, and stored in the +monolithic structures or_options_t and or_state_t respectively. + +These top-level structures are accessed with get_options() and +get_state(), and used throughout much of the code, at the level of +@refdir{core} and higher. + +With time we hope to refactor this configuration into more +reasonable pieces, so that they are no longer (effectively) global +variables used throughout the code. diff --git a/src/lib/conf/confmacros.h b/src/lib/conf/confmacros.h index 68121891f1..9f85d21740 100644 --- a/src/lib/conf/confmacros.h +++ b/src/lib/conf/confmacros.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -15,11 +15,13 @@ #include "orconfig.h" #include "lib/conf/conftesting.h" +#ifndef COCCI /** * Used to indicate the end of an array of configuration variables. **/ #define END_OF_CONFIG_VARS \ { .member = { .name = NULL } DUMMY_CONF_TEST_MEMBERS } +#endif /* !defined(COCCI) */ /** * Declare a config_var_t as a member named <b>membername</b> of the structure @@ -43,7 +45,7 @@ } /** - * As CONFIG_VAR_XTYPE, but declares a value using an extension type whose + * As CONFIG_VAR_ETYPE, but declares a value using an extension type whose * type definition is <b>vartype</b>_type_defn. **/ #define CONFIG_VAR_DEFN(structtype, varname, vartype, membername, \ @@ -59,6 +61,9 @@ CONF_TEST_MEMBERS(structtype, vartype, membername) \ } +/** + * Declare an obsolete configuration variable with a given name. + **/ #define CONFIG_VAR_OBSOLETE(varname) \ { .member = { .name = varname, .type = CONFIG_TYPE_OBSOLETE }, \ .flags = CFLG_GROUP_OBSOLETE \ diff --git a/src/lib/conf/conftesting.h b/src/lib/conf/conftesting.h index f01f52d59e..4707c919d3 100644 --- a/src/lib/conf/conftesting.h +++ b/src/lib/conf/conftesting.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,10 +12,14 @@ #ifndef TOR_LIB_CONF_CONFTESTING_H #define TOR_LIB_CONF_CONFTESTING_H +#include "lib/cc/torint.h" + +#ifndef COCCI #ifdef TOR_UNIT_TESTS +#define USE_CONF_TESTING /** * Union used when building in test mode typechecking the members of a type - * used with confparse.c. See CONF_CHECK_VAR_TYPE for a description of how + * used with confmgt.c. See CONF_CHECK_VAR_TYPE for a description of how * it is used. */ typedef union { char **STRING; @@ -41,13 +45,11 @@ typedef union { // XXXX this doesn't belong at this level of abstraction. struct routerset_t **ROUTERSET; } confparse_dummy_values_t; -#endif /* defined(TOR_UNIT_TESTS) */ /* Macros to define extra members inside config_var_t fields, and at the * end of a list of them. */ -#ifdef TOR_UNIT_TESTS -/* This is a somewhat magic type-checking macro for users of confparse.c. +/* This is a somewhat magic type-checking macro for users of confmgt.c. * It initializes a union member "confparse_dummy_values_t.conftype" with * the address of a static member "tp_dummy.member". This * will give a compiler warning unless the member field is of the correct @@ -72,15 +74,16 @@ typedef union { #define DUMMY_CONF_TEST_MEMBERS , .var_ptr_dummy={ .INT=NULL } #define DUMMY_TYPECHECK_INSTANCE(tp) \ static tp tp ## _dummy +#endif /* defined(TOR_UNIT_TESTS) */ +#endif /* !defined(COCCI) */ -#else /* !defined(TOR_UNIT_TESTS) */ - +#ifndef USE_CONF_TESTING #define CONF_TEST_MEMBERS(tp, conftype, member) /* Repeatedly declarable incomplete struct to absorb redundant semicolons */ #define DUMMY_TYPECHECK_INSTANCE(tp) \ struct tor_semicolon_eater #define DUMMY_CONF_TEST_MEMBERS -#endif /* defined(TOR_UNIT_TESTS) */ +#endif /* !defined(USE_CONF_TESTING) */ #endif /* !defined(TOR_LIB_CONF_CONFTESTING_H) */ diff --git a/src/lib/conf/conftypes.h b/src/lib/conf/conftypes.h index 274065cff2..ebc2736aaa 100644 --- a/src/lib/conf/conftypes.h +++ b/src/lib/conf/conftypes.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -64,7 +64,18 @@ typedef enum config_type_t { CONFIG_TYPE_LINELIST_V, /**< Catch-all "virtual" option to summarize * context-sensitive config lines when fetching. */ - CONFIG_TYPE_OBSOLETE, /**< Obsolete (ignored) option. */ + /** Ignored (obsolete) option. Uses no storage. + * + * Reported as "obsolete" when its type is queried. + */ + CONFIG_TYPE_OBSOLETE, + /** Ignored option. Uses no storage. + * + * Reported as "ignored" when its type is queried. For use with options used + * by disabled modules. + **/ + CONFIG_TYPE_IGNORE, + /** * Extended type: definition appears in the <b>type_def</b> pointer * of the corresponding struct_member_t. @@ -120,6 +131,9 @@ typedef struct struct_member_t { * * These 'magic numbers' are 32-bit values used to tag objects to make sure * that they have the correct type. + * + * If all fields in this structure are zero or 0, the magic-number check is + * not performed. */ typedef struct struct_magic_decl_t { /** The name of the structure */ @@ -178,12 +192,35 @@ typedef struct struct_magic_decl_t { * however, setting them appends to their old value. */ #define CFLG_NOREPLACE (1u<<5) +/** + * Flag to indicate that an option or type cannot be changed while Tor is + * running. + **/ +#define CFLG_IMMUTABLE (1u<<6) +/** + * Flag to indicate that we should warn that an option or type is obsolete + * whenever the user tries to use it. + **/ +#define CFLG_WARN_OBSOLETE (1u<<7) +/** + * Flag to indicate that we should warn that an option applies only to + * a disabled module, whenever the user tries to use it. + **/ +#define CFLG_WARN_DISABLED (1u<<8) /** * A group of flags that should be set on all obsolete options and types. **/ #define CFLG_GROUP_OBSOLETE \ - (CFLG_NOCOPY|CFLG_NOCMP|CFLG_NODUMP|CFLG_NOSET|CFLG_NOLIST) + (CFLG_NOCOPY|CFLG_NOCMP|CFLG_NODUMP|CFLG_NOSET|CFLG_NOLIST|\ + CFLG_WARN_OBSOLETE) + +/** + * A group of fflags that should be set on all disabled options. + **/ +#define CFLG_GROUP_DISABLED \ + (CFLG_NOCOPY|CFLG_NOCMP|CFLG_NODUMP|CFLG_NOSET|CFLG_NOLIST|\ + CFLG_WARN_DISABLED) /** A variable allowed in the configuration file or on the command line. */ typedef struct config_var_t { @@ -199,4 +236,146 @@ typedef struct config_var_t { #endif } config_var_t; +/** + * An abbreviation or alias for a configuration option. + **/ +typedef struct config_abbrev_t { + /** The option name as abbreviated. Not case-sensitive. */ + const char *abbreviated; + /** The full name of the option. Not case-sensitive. */ + const char *full; + /** True if this abbreviation should only be allowed on the command line. */ + int commandline_only; + /** True if we should warn whenever this abbreviation is used. */ + int warn; +} config_abbrev_t; + +/** + * A note that a configuration option is deprecated, with an explanation why. + */ +typedef struct config_deprecation_t { + /** The option that is deprecated. */ + const char *name; + /** A user-facing string explaining why the option is deprecated. */ + const char *why_deprecated; +} config_deprecation_t; + +/** + * Handy macro for declaring "In the config file or on the command line, you + * can abbreviate <b>tok</b>s as <b>tok</b>". Used inside an array of + * config_abbrev_t. + * + * For example, to declare "NumCpu" as an abbreviation for "NumCPUs", + * you can say PLURAL(NumCpu). + **/ +#define PLURAL(tok) { #tok, #tok "s", 0, 0 } + +/** + * Validation function: verify whether a configuation object is well-formed + * and consistent. + * + * On success, return 0. On failure, set <b>msg_out</b> to a newly allocated + * string containing an error message, and return -1. */ +typedef int (*validate_fn_t)(const void *value, char **msg_out); +/** + * Validation function: verify whether a configuration object (`value`) is an + * allowable value given the previous configuration value (`old_value`). + * + * On success, return 0. On failure, set <b>msg_out</b> to a newly allocated + * string containing an error message, and return -1. */ +typedef int (*check_transition_fn_t)(const void *old_value, const void *value, + char **msg_out); +/** + * Validation function: normalize members of `value`, and compute derived + * members. + * + * This function is called before any other validation of `value`, and must + * not assume that validate_fn or check_transition_fn has passed. + * + * On success, return 0. On failure, set <b>msg_out</b> to a newly allocated + * string containing an error message, and return -1. */ +typedef int (*pre_normalize_fn_t)(void *value, char **msg_out); +/** + * Validation function: normalize members of `value`, and compute derived + * members. + * + * This function is called after validation of `value`, and may + * assume that validate_fn or check_transition_fn has passed. + * + * On success, return 0. On failure, set <b>msg_out</b> to a newly allocated + * string containing an error message, and return -1. */ +typedef int (*post_normalize_fn_t)(void *value, char **msg_out); + +/** + * Legacy function to validate whether a given configuration is + * well-formed and consistent. + * + * The configuration to validate is passed as <b>newval</b>. The previous + * configuration, if any, is provided in <b>oldval</b>. + * + * This API is deprecated, since it mixes the responsibilities of + * pre_normalize_fn_t, post_normalize_fn_t, validate_fn_t, and + * check_transition_fn_t. No new instances of this function type should + * be written. + * + * On success, return 0. On failure, set *<b>msg_out</b> to a newly allocated + * error message, and return -1. + */ +typedef int (*legacy_validate_fn_t)(const void *oldval, + void *newval, + char **msg_out); + +struct config_mgr_t; + +/** + * Callback to clear all non-managed fields of a configuration object. + * + * <b>obj</b> is the configuration object whose non-managed fields should be + * cleared. + * + * (Regular fields get cleared by config_reset(), but you might have fields + * in the object that do not correspond to configuration variables. If those + * fields need to be cleared or freed, this is where to do it.) + */ +typedef void (*clear_cfg_fn_t)(const struct config_mgr_t *mgr, void *obj); + +/** Information on the keys, value types, key-to-struct-member mappings, + * variable descriptions, validation functions, and abbreviations for a + * configuration or storage format. */ +typedef struct config_format_t { + size_t size; /**< Size of the struct that everything gets parsed into. */ + struct_magic_decl_t magic; /**< Magic number info for this struct. */ + const config_abbrev_t *abbrevs; /**< List of abbreviations that we expand + * when parsing this format. */ + const config_deprecation_t *deprecations; /** List of deprecated options */ + const config_var_t *vars; /**< List of variables we recognize, their default + * values, and where we stick them in the + * structure. */ + + /** Early-stage normalization callback. Invoked by config_validate(). */ + pre_normalize_fn_t pre_normalize_fn; + /** Configuration validation function. Invoked by config_validate(). */ + validate_fn_t validate_fn; + /** Legacy validation function. Invoked by config_validate(). */ + legacy_validate_fn_t legacy_validate_fn; + /** Transition checking function. Invoked by config_validate(). */ + check_transition_fn_t check_transition_fn; + /** Late-stage normalization callback. Invoked by config_validate(). */ + post_normalize_fn_t post_normalize_fn; + + clear_cfg_fn_t clear_fn; /**< Function to clear the configuration. */ + /** If present, extra denotes a LINELIST variable for unrecognized + * lines. Otherwise, unrecognized lines are an error. */ + const struct_member_t *extra; + /** + * If true, this format describes a top-level configuration, with + * a suite containing multiple sub-configuration objects. + */ + bool has_config_suite; + /** The position of a config_suite_t pointer within the toplevel object. + * Ignored unless have_config_suite is true. + */ + ptrdiff_t config_suite_offset; +} config_format_t; + #endif /* !defined(TOR_SRC_LIB_CONF_CONFTYPES_H) */ diff --git a/src/lib/conf/include.am b/src/lib/conf/include.am index cb7126184d..cb0b83fa64 100644 --- a/src/lib/conf/include.am +++ b/src/lib/conf/include.am @@ -1,6 +1,7 @@ # ADD_C_FILE: INSERT HEADERS HERE. noinst_HEADERS += \ + src/lib/conf/confdecl.h \ src/lib/conf/conftesting.h \ src/lib/conf/conftypes.h \ src/lib/conf/confmacros.h diff --git a/src/lib/conf/lib_conf.md b/src/lib/conf/lib_conf.md new file mode 100644 index 0000000000..60dd04e99e --- /dev/null +++ b/src/lib/conf/lib_conf.md @@ -0,0 +1,3 @@ +@dir /lib/conf +@brief lib/conf: Types and macros for declaring configuration options. + diff --git a/src/lib/confmgt/.may_include b/src/lib/confmgt/.may_include index 2564133917..5ff949f103 100644 --- a/src/lib/confmgt/.may_include +++ b/src/lib/confmgt/.may_include @@ -4,6 +4,7 @@ lib/conf/*.h lib/confmgt/*.h lib/container/*.h lib/encoding/*.h +lib/intmath/*.h lib/log/*.h lib/malloc/*.h lib/string/*.h diff --git a/src/lib/confmgt/confparse.c b/src/lib/confmgt/confmgt.c index 08e562f654..bf2764160e 100644 --- a/src/lib/confmgt/confparse.c +++ b/src/lib/confmgt/confmgt.c @@ -1,11 +1,11 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** - * \file confparse.c + * \file confmgt.c * * \brief Back-end for parsing and generating key-value files, used to * implement the torrc file format and the state file. @@ -21,9 +21,9 @@ * specified, and a linked list of key-value pairs. */ -#define CONFPARSE_PRIVATE +#define CONFMGT_PRIVATE #include "orconfig.h" -#include "lib/confmgt/confparse.h" +#include "lib/confmgt/confmgt.h" #include "lib/confmgt/structvar.h" #include "lib/confmgt/unitparse.h" @@ -169,9 +169,14 @@ config_mgr_register_fmt(config_mgr_t *mgr, "it had been frozen."); if (object_idx != IDX_TOPLEVEL) { - tor_assertf(fmt->config_suite_offset < 0, + tor_assertf(! fmt->has_config_suite, "Tried to register a toplevel format in a non-toplevel position"); } + if (fmt->config_suite_offset) { + tor_assertf(fmt->has_config_suite, + "config_suite_offset was set, but has_config_suite was not."); + } + tor_assertf(fmt != mgr->toplevel && ! smartlist_contains(mgr->subconfigs, fmt), "Tried to register an already-registered format."); @@ -223,7 +228,7 @@ config_mgr_add_format(config_mgr_t *mgr, static inline config_suite_t ** config_mgr_get_suite_ptr(const config_mgr_t *mgr, void *toplevel) { - if (mgr->toplevel->config_suite_offset < 0) + if (! mgr->toplevel->has_config_suite) return NULL; return STRUCT_VAR_P(toplevel, mgr->toplevel->config_suite_offset); } @@ -237,7 +242,7 @@ config_mgr_get_suite_ptr(const config_mgr_t *mgr, void *toplevel) * to configuration objects for other modules. This function gets * the sub-object for a particular module. */ -STATIC void * +void * config_mgr_get_obj_mutable(const config_mgr_t *mgr, void *toplevel, int idx) { tor_assert(mgr); @@ -256,7 +261,7 @@ config_mgr_get_obj_mutable(const config_mgr_t *mgr, void *toplevel, int idx) } /** As config_mgr_get_obj_mutable(), but return a const pointer. */ -STATIC const void * +const void * config_mgr_get_obj(const config_mgr_t *mgr, const void *toplevel, int idx) { return config_mgr_get_obj_mutable(mgr, (void*)toplevel, idx); @@ -334,6 +339,17 @@ config_mgr_list_deprecated_vars(const config_mgr_t *mgr) return result; } +/** + * Check the magic number on <b>object</b> to make sure it's a valid toplevel + * object, created with <b>mgr</b>. Exit with an assertion if it isn't. + **/ +void +config_check_toplevel_magic(const config_mgr_t *mgr, + const void *object) +{ + struct_check_magic(object, &mgr->toplevel_magic); +} + /** Assert that the magic fields in <b>options</b> and its subsidiary * objects are all okay. */ static void @@ -641,6 +657,14 @@ config_assign_value(const config_mgr_t *mgr, void *options, tor_assert(!strcmp(c->key, var->cvar->member.name)); void *object = config_mgr_get_obj_mutable(mgr, options, var->object_idx); + if (config_var_has_flag(var->cvar, CFLG_WARN_OBSOLETE)) { + log_warn(LD_GENERAL, "Skipping obsolete configuration option \"%s\".", + var->cvar->member.name); + } else if (config_var_has_flag(var->cvar, CFLG_WARN_DISABLED)) { + log_warn(LD_GENERAL, "This copy of Tor was built without support for " + "the option \"%s\". Skipping.", var->cvar->member.name); + } + return struct_var_kvassign(object, c, msg, &var->cvar->member); } @@ -1142,6 +1166,146 @@ config_init(const config_mgr_t *mgr, void *options) } SMARTLIST_FOREACH_END(mv); } +/** + * Helper for config_validate_single: see whether any immutable option + * has changed between old_options and new_options. + * + * On success return 0; on failure set *msg_out to a newly allocated + * string explaining what is wrong, and return -1. + */ +static int +config_check_immutable_flags(const config_format_t *fmt, + const void *old_options, + const void *new_options, + char **msg_out) +{ + tor_assert(fmt); + tor_assert(new_options); + if (BUG(! old_options)) + return 0; + + unsigned i; + for (i = 0; fmt->vars[i].member.name; ++i) { + const config_var_t *v = &fmt->vars[i]; + if (! config_var_has_flag(v, CFLG_IMMUTABLE)) + continue; + + if (! struct_var_eq(old_options, new_options, &v->member)) { + tor_asprintf(msg_out, + "While Tor is running, changing %s is not allowed", + v->member.name); + return -1; + } + } + + return 0; +} + +/** + * Normalize and validate a single object `options` within a configuration + * suite, according to its format. `options` may be modified as appropriate + * in order to set ancillary data. If `old_options` is provided, make sure + * that the transition from `old_options` to `options` is permitted. + * + * On success return VSTAT_OK; on failure set *msg_out to a newly allocated + * string explaining what is wrong, and return a different validation_status_t + * to describe which step failed. + **/ +static validation_status_t +config_validate_single(const config_format_t *fmt, + const void *old_options, void *options, + char **msg_out) +{ + tor_assert(fmt); + tor_assert(options); + + if (fmt->pre_normalize_fn) { + if (fmt->pre_normalize_fn(options, msg_out) < 0) { + return VSTAT_PRE_NORMALIZE_ERR; + } + } + + if (fmt->legacy_validate_fn) { + if (fmt->legacy_validate_fn(old_options, options, msg_out) < 0) { + return VSTAT_LEGACY_ERR; + } + } + + if (fmt->validate_fn) { + if (fmt->validate_fn(options, msg_out) < 0) { + return VSTAT_VALIDATE_ERR; + } + } + + if (old_options) { + if (config_check_immutable_flags(fmt, old_options, options, msg_out) < 0) { + return VSTAT_TRANSITION_ERR; + } + + if (fmt->check_transition_fn) { + if (fmt->check_transition_fn(old_options, options, msg_out) < 0) { + return VSTAT_TRANSITION_ERR; + } + } + } + + if (fmt->post_normalize_fn) { + if (fmt->post_normalize_fn(options, msg_out) < 0) { + return VSTAT_POST_NORMALIZE_ERR; + } + } + + return VSTAT_OK; +} + +/** + * Normalize and validate all the options in configuration object `options` + * and its sub-objects. `options` may be modified as appropriate in order to + * set ancillary data. If `old_options` is provided, make sure that the + * transition from `old_options` to `options` is permitted. + * + * On success return VSTAT_OK; on failure set *msg_out to a newly allocated + * string explaining what is wrong, and return a different validation_status_t + * to describe which step failed. + **/ +validation_status_t +config_validate(const config_mgr_t *mgr, + const void *old_options, void *options, + char **msg_out) +{ + validation_status_t rv; + CONFIG_CHECK(mgr, options); + if (old_options) { + CONFIG_CHECK(mgr, old_options); + } + + config_suite_t **suitep_new = config_mgr_get_suite_ptr(mgr, options); + config_suite_t **suitep_old = NULL; + if (old_options) + suitep_old = config_mgr_get_suite_ptr(mgr, (void*) old_options); + + /* Validate the sub-objects */ + if (suitep_new) { + SMARTLIST_FOREACH_BEGIN(mgr->subconfigs, const config_format_t *, fmt) { + void *obj = smartlist_get((*suitep_new)->configs, fmt_sl_idx); + const void *obj_old=NULL; + if (suitep_old) + obj_old = smartlist_get((*suitep_old)->configs, fmt_sl_idx); + + rv = config_validate_single(fmt, obj_old, obj, msg_out); + if (rv < 0) + return rv; + } SMARTLIST_FOREACH_END(fmt); + } + + /* Validate the top-level object. */ + rv = config_validate_single(mgr->toplevel, old_options, options, msg_out); + if (rv < 0) + return rv; + + return VSTAT_OK; +} + /** Allocate and return a new string holding the written-out values of the vars * in 'options'. If 'minimal', do not write out any default-valued vars. * Else, if comment_defaults, write default values as comments. @@ -1166,7 +1330,7 @@ config_dump(const config_mgr_t *mgr, const void *default_options, /* XXX use a 1 here so we don't add a new log line while dumping */ if (default_options == NULL) { - if (fmt->validate_fn(NULL, defaults_tmp, defaults_tmp, 1, &msg) < 0) { + if (config_validate(mgr, NULL, defaults_tmp, &msg) < 0) { // LCOV_EXCL_START log_err(LD_BUG, "Failed to validate default config: %s", msg); tor_free(msg); @@ -1197,9 +1361,10 @@ config_dump(const config_mgr_t *mgr, const void *default_options, */ continue; } - smartlist_add_asprintf(elements, "%s%s %s\n", + int value_exists = line->value && *(line->value); + smartlist_add_asprintf(elements, "%s%s%s%s\n", comment_option ? "# " : "", - line->key, line->value); + line->key, value_exists ? " " : "", line->value); } config_free_lines(assigned); } SMARTLIST_FOREACH_END(mv); @@ -1207,7 +1372,9 @@ config_dump(const config_mgr_t *mgr, const void *default_options, if (fmt->extra) { line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->offset); for (; line; line = line->next) { - smartlist_add_asprintf(elements, "%s %s\n", line->key, line->value); + int value_exists = line->value && *(line->value); + smartlist_add_asprintf(elements, "%s%s%s\n", + line->key, value_exists ? " " : "", line->value); } } diff --git a/src/lib/confmgt/confparse.h b/src/lib/confmgt/confmgt.h index 2332f69790..5065c13b60 100644 --- a/src/lib/confmgt/confparse.h +++ b/src/lib/confmgt/confmgt.h @@ -1,116 +1,23 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** - * \file confparse.h + * \file confmgt.h * - * \brief Header for confparse.c. + * \brief Header for confmgt.c. */ -#ifndef TOR_CONFPARSE_H -#define TOR_CONFPARSE_H +#ifndef TOR_CONFMGT_H +#define TOR_CONFMGT_H #include "lib/conf/conftypes.h" #include "lib/conf/confmacros.h" #include "lib/testsupport/testsupport.h" /** - * An abbreviation or alias for a configuration option. - **/ -typedef struct config_abbrev_t { - /** The option name as abbreviated. Not case-sensitive. */ - const char *abbreviated; - /** The full name of the option. Not case-sensitive. */ - const char *full; - /** True if this abbreviation should only be allowed on the command line. */ - int commandline_only; - /** True if we should warn whenever this abbreviation is used. */ - int warn; -} config_abbrev_t; - -/** - * A note that a configuration option is deprecated, with an explanation why. - */ -typedef struct config_deprecation_t { - /** The option that is deprecated. */ - const char *name; - /** A user-facing string explaining why the option is deprecated. */ - const char *why_deprecated; -} config_deprecation_t; - -/** - * Handy macro for declaring "In the config file or on the command line, you - * can abbreviate <b>tok</b>s as <b>tok</b>". Used inside an array of - * config_abbrev_t. - * - * For example, to declare "NumCpu" as an abbreviation for "NumCPUs", - * you can say PLURAL(NumCpu). - **/ -#define PLURAL(tok) { #tok, #tok "s", 0, 0 } - -/** - * Type of a callback to validate whether a given configuration is - * well-formed and consistent. - * - * The configuration to validate is passed as <b>newval</b>. The previous - * configuration, if any, is provided in <b>oldval</b>. The - * <b>default_val</b> argument receives a configuration object initialized - * with default values for all its fields. The <b>from_setconf</b> argument - * is true iff the input comes from a SETCONF controller command. - * - * On success, return 0. On failure, set *<b>msg_out</b> to a newly allocated - * error message, and return -1. - * - * REFACTORING NOTE: Currently, this callback type is only used from inside - * config_dump(); later in our refactoring, it will be cleaned up and used - * more generally. - */ -typedef int (*validate_fn_t)(void *oldval, - void *newval, - void *default_val, - int from_setconf, - char **msg_out); - -struct config_mgr_t; - -/** - * Callback to clear all non-managed fields of a configuration object. - * - * <b>obj</b> is the configuration object whose non-managed fields should be - * cleared. - * - * (Regular fields get cleared by config_reset(), but you might have fields - * in the object that do not correspond to configuration variables. If those - * fields need to be cleared or freed, this is where to do it.) - */ -typedef void (*clear_cfg_fn_t)(const struct config_mgr_t *mgr, void *obj); - -/** Information on the keys, value types, key-to-struct-member mappings, - * variable descriptions, validation functions, and abbreviations for a - * configuration or storage format. */ -typedef struct config_format_t { - size_t size; /**< Size of the struct that everything gets parsed into. */ - struct_magic_decl_t magic; /**< Magic number info for this struct. */ - const config_abbrev_t *abbrevs; /**< List of abbreviations that we expand - * when parsing this format. */ - const config_deprecation_t *deprecations; /** List of deprecated options */ - const config_var_t *vars; /**< List of variables we recognize, their default - * values, and where we stick them in the - * structure. */ - validate_fn_t validate_fn; /**< Function to validate config. */ - clear_cfg_fn_t clear_fn; /**< Function to clear the configuration. */ - /** If present, extra denotes a LINELIST variable for unrecognized - * lines. Otherwise, unrecognized lines are an error. */ - const struct_member_t *extra; - /** The position of a config_suite_t pointer within the toplevel object, - * or -1 if there is no such pointer. */ - ptrdiff_t config_suite_offset; -} config_format_t; - -/** * A collection of config_format_t objects to describe several objects * that are all configured with the same configuration file. * @@ -171,10 +78,26 @@ int config_is_same(const config_mgr_t *fmt, struct config_line_t *config_get_changes(const config_mgr_t *mgr, const void *options1, const void *options2); void config_init(const config_mgr_t *mgr, void *options); + +/** An enumeration to report which validation step failed. */ +typedef enum { + VSTAT_PRE_NORMALIZE_ERR = -5, + VSTAT_VALIDATE_ERR = -4, + VSTAT_LEGACY_ERR = -3, + VSTAT_TRANSITION_ERR = -2, + VSTAT_POST_NORMALIZE_ERR = -1, + VSTAT_OK = 0, +} validation_status_t; + +validation_status_t config_validate(const config_mgr_t *mgr, + const void *old_options, void *options, + char **msg_out); void *config_dup(const config_mgr_t *mgr, const void *old); char *config_dump(const config_mgr_t *mgr, const void *default_options, const void *options, int minimal, int comment_defaults); +void config_check_toplevel_magic(const config_mgr_t *mgr, + const void *object); bool config_check_ok(const config_mgr_t *mgr, const void *options, int severity); int config_assign(const config_mgr_t *mgr, void *options, @@ -200,13 +123,14 @@ bool config_var_is_listable(const config_var_t *var); #define CFG_EQ_LINELIST(a,b,opt) config_lines_eq((a)->opt, (b)->opt) #define CFG_EQ_ROUTERSET(a,b,opt) routerset_equal((a)->opt, (b)->opt) -#ifdef CONFPARSE_PRIVATE +void *config_mgr_get_obj_mutable(const config_mgr_t *mgr, + void *toplevel, int idx); +const void *config_mgr_get_obj(const config_mgr_t *mgr, + const void *toplevel, int idx); + +#ifdef CONFMGT_PRIVATE STATIC void config_reset_line(const config_mgr_t *mgr, void *options, const char *key, int use_defaults); -STATIC void *config_mgr_get_obj_mutable(const config_mgr_t *mgr, - void *toplevel, int idx); -STATIC const void *config_mgr_get_obj(const config_mgr_t *mgr, - const void *toplevel, int idx); -#endif /* defined(CONFPARSE_PRIVATE) */ +#endif /* defined(CONFMGT_PRIVATE) */ -#endif /* !defined(TOR_CONFPARSE_H) */ +#endif /* !defined(TOR_CONFMGT_H) */ diff --git a/src/lib/confmgt/include.am b/src/lib/confmgt/include.am index 81cd868e5e..d3a7a7cd69 100644 --- a/src/lib/confmgt/include.am +++ b/src/lib/confmgt/include.am @@ -6,7 +6,7 @@ endif # ADD_C_FILE: INSERT SOURCES HERE. src_lib_libtor_confmgt_a_SOURCES = \ - src/lib/confmgt/confparse.c \ + src/lib/confmgt/confmgt.c \ src/lib/confmgt/structvar.c \ src/lib/confmgt/type_defs.c \ src/lib/confmgt/typedvar.c \ @@ -19,7 +19,7 @@ src_lib_libtor_confmgt_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) # ADD_C_FILE: INSERT HEADERS HERE. noinst_HEADERS += \ - src/lib/confmgt/confparse.h \ + src/lib/confmgt/confmgt.h \ src/lib/confmgt/structvar.h \ src/lib/confmgt/type_defs.h \ src/lib/confmgt/typedvar.h \ diff --git a/src/lib/confmgt/lib_confmgt.md b/src/lib/confmgt/lib_confmgt.md new file mode 100644 index 0000000000..861e720f64 --- /dev/null +++ b/src/lib/confmgt/lib_confmgt.md @@ -0,0 +1,7 @@ +@dir /lib/confmgt +@brief lib/confmgt: Parse, encode, manipulate configuration files. + +This logic is used in common by our state files (statefile.c) and +configuration files (config.c) to manage a set of named, typed fields, +reading and writing them to disk and to the controller. + diff --git a/src/lib/confmgt/structvar.c b/src/lib/confmgt/structvar.c index 7a3b8c7df2..55deb4759c 100644 --- a/src/lib/confmgt/structvar.c +++ b/src/lib/confmgt/structvar.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -30,13 +30,28 @@ #include <stddef.h> /** + * Return true iff all fields on <b>decl</b> are NULL or 0, indicating that + * there is no object or no magic number to check. + **/ +static inline bool +magic_is_null(const struct_magic_decl_t *decl) +{ + return decl->typename == NULL && + decl->magic_offset == 0 && + decl->magic_val == 0; +} + +/** * Set the 'magic number' on <b>object</b> to correspond to decl. **/ void struct_set_magic(void *object, const struct_magic_decl_t *decl) { - tor_assert(object); tor_assert(decl); + if (magic_is_null(decl)) + return; + + tor_assert(object); uint32_t *ptr = STRUCT_VAR_P(object, decl->magic_offset); *ptr = decl->magic_val; } @@ -47,8 +62,11 @@ struct_set_magic(void *object, const struct_magic_decl_t *decl) void struct_check_magic(const void *object, const struct_magic_decl_t *decl) { - tor_assert(object); tor_assert(decl); + if (magic_is_null(decl)) + return; + + tor_assert(object); const uint32_t *ptr = STRUCT_VAR_P(object, decl->magic_offset); tor_assertf(*ptr == decl->magic_val, diff --git a/src/lib/confmgt/structvar.h b/src/lib/confmgt/structvar.h index bcb4b58c3f..91334fa8c5 100644 --- a/src/lib/confmgt/structvar.h +++ b/src/lib/confmgt/structvar.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/confmgt/type_defs.c b/src/lib/confmgt/type_defs.c index 5066e12265..d9e5e1e4c2 100644 --- a/src/lib/confmgt/type_defs.c +++ b/src/lib/confmgt/type_defs.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -17,12 +17,12 @@ #include "orconfig.h" #include "lib/conf/conftypes.h" +#include "lib/conf/confdecl.h" #include "lib/confmgt/typedvar.h" #include "lib/confmgt/type_defs.h" #include "lib/confmgt/unitparse.h" #include "lib/cc/compat_compiler.h" -#include "lib/conf/conftypes.h" #include "lib/container/smartlist.h" #include "lib/encoding/confline.h" #include "lib/encoding/time_fmt.h" @@ -52,11 +52,10 @@ static int string_parse(void *target, const char *value, char **errmsg, - const void *params, const char *key) + const void *params) { (void)params; (void)errmsg; - (void)key; char **p = (char**)target; *p = tor_strdup(value); return 0; @@ -91,9 +90,12 @@ static const var_type_fns_t string_fns = { // These types are implemented as int, possibly with a restricted range. ///// +/** + * Parameters for parsing an integer type. + **/ typedef struct int_type_params_t { - int minval; - int maxval; + int minval; /**< Lowest allowed value */ + int maxval; /**< Highest allowed value */ } int_parse_params_t; static const int_parse_params_t INT_PARSE_UNRESTRICTED = { @@ -107,10 +109,8 @@ static const int_parse_params_t INT_PARSE_POSINT = { }; static int -int_parse(void *target, const char *value, char **errmsg, const void *params, - const char *key) +int_parse(void *target, const char *value, char **errmsg, const void *params) { - (void)key; const int_parse_params_t *pp; if (params) { pp = params; @@ -121,8 +121,9 @@ int_parse(void *target, const char *value, char **errmsg, const void *params, int ok=0; *p = (int)tor_parse_long(value, 10, pp->minval, pp->maxval, &ok, NULL); if (!ok) { - tor_asprintf(errmsg, "Integer %s is malformed or out of bounds.", - value); + tor_asprintf(errmsg, "Integer %s is malformed or out of bounds. " + "Allowed values are between %d and %d.", + value, pp->minval, pp->maxval); return -1; } return 0; @@ -172,11 +173,10 @@ static const var_type_fns_t int_fns = { static int uint64_parse(void *target, const char *value, char **errmsg, - const void *params, const char *key) + const void *params) { (void)params; (void)errmsg; - (void)key; uint64_t *p = target; int ok=0; *p = tor_parse_uint64(value, 10, 0, UINT64_MAX, &ok, NULL); @@ -223,35 +223,45 @@ static const var_type_fns_t uint64_fns = { static int units_parse_u64(void *target, const char *value, char **errmsg, - const void *params, const char *key) + const void *params) { - (void)key; const unit_table_t *table = params; tor_assert(table); uint64_t *v = (uint64_t*)target; int ok=1; - *v = config_parse_units(value, table, &ok); + char *msg = NULL; + *v = config_parse_units(value, table, &ok, &msg); if (!ok) { - *errmsg = tor_strdup("Provided value is malformed or out of bounds."); + tor_asprintf(errmsg, "Provided value is malformed or out of bounds: %s", + msg); + tor_free(msg); return -1; } + if (BUG(msg)) { + tor_free(msg); + } return 0; } static int units_parse_int(void *target, const char *value, char **errmsg, - const void *params, const char *key) + const void *params) { - (void)key; const unit_table_t *table = params; tor_assert(table); int *v = (int*)target; int ok=1; - uint64_t u64 = config_parse_units(value, table, &ok); + char *msg = NULL; + uint64_t u64 = config_parse_units(value, table, &ok, &msg); if (!ok) { - *errmsg = tor_strdup("Provided value is malformed or out of bounds."); + tor_asprintf(errmsg, "Provided value is malformed or out of bounds: %s", + msg); + tor_free(msg); return -1; } + if (BUG(msg)) { + tor_free(msg); + } if (u64 > INT_MAX) { tor_asprintf(errmsg, "Provided value %s is too large", value); return -1; @@ -289,11 +299,10 @@ static const var_type_fns_t interval_fns = { static int double_parse(void *target, const char *value, char **errmsg, - const void *params, const char *key) + const void *params) { (void)params; (void)errmsg; - (void)key; double *v = (double*)target; char *endptr=NULL; errno = 0; @@ -352,12 +361,17 @@ typedef struct enumeration_table_t { int value; } enumeration_table_t; +typedef struct enumeration_params_t { + const char *allowed_val_string; + const enumeration_table_t *table; +} enumeration_params_t; + static int enum_parse(void *target, const char *value, char **errmsg, - const void *params, const char *key) + const void *params_) { - (void)key; - const enumeration_table_t *table = params; + const enumeration_params_t *params = params_; + const enumeration_table_t *table = params->table; int *p = (int *)target; for (; table->name; ++table) { if (!strcasecmp(value, table->name)) { @@ -365,15 +379,17 @@ enum_parse(void *target, const char *value, char **errmsg, return 0; } } - tor_asprintf(errmsg, "Unrecognized value %s.", value); + tor_asprintf(errmsg, "Unrecognized value %s. %s", + value, params->allowed_val_string); return -1; } static char * -enum_encode(const void *value, const void *params) +enum_encode(const void *value, const void *params_) { int v = *(const int*)value; - const enumeration_table_t *table = params; + const enumeration_params_t *params = params_; + const enumeration_table_t *table = params->table; for (; table->name; ++table) { if (v == table->value) return tor_strdup(table->name); @@ -382,19 +398,21 @@ enum_encode(const void *value, const void *params) } static void -enum_clear(void *value, const void *params) +enum_clear(void *value, const void *params_) { int *p = (int*)value; - const enumeration_table_t *table = params; + const enumeration_params_t *params = params_; + const enumeration_table_t *table = params->table; tor_assert(table->name); *p = table->value; } static bool -enum_ok(const void *value, const void *params) +enum_ok(const void *value, const void *params_) { int v = *(const int*)value; - const enumeration_table_t *table = params; + const enumeration_params_t *params = params_; + const enumeration_table_t *table = params->table; for (; table->name; ++table) { if (v == table->value) return true; @@ -408,6 +426,11 @@ static const enumeration_table_t enum_table_bool[] = { { NULL, 0 }, }; +static const enumeration_params_t enum_params_bool = { + "Allowed values are 0 and 1.", + enum_table_bool +}; + static const enumeration_table_t enum_table_autobool[] = { { "0", 0 }, { "1", 1 }, @@ -415,6 +438,11 @@ static const enumeration_table_t enum_table_autobool[] = { { NULL, 0 }, }; +static const enumeration_params_t enum_params_autobool = { + "Allowed values are 0, 1, and auto.", + enum_table_autobool +}; + static const var_type_fns_t enum_fns = { .parse = enum_parse, .encode = enum_encode, @@ -430,10 +458,9 @@ static const var_type_fns_t enum_fns = { static int time_parse(void *target, const char *value, char **errmsg, - const void *params, const char *key) + const void *params) { (void) params; - (void) key; time_t *p = target; if (parse_iso_time(value, p) < 0) { tor_asprintf(errmsg, "Invalid time %s", escaped(value)); @@ -475,11 +502,10 @@ static const var_type_fns_t time_fns = { static int csv_parse(void *target, const char *value, char **errmsg, - const void *params, const char *key) + const void *params) { (void)params; (void)errmsg; - (void)key; smartlist_t **sl = (smartlist_t**)target; *sl = smartlist_new(); smartlist_split_string(*sl, value, ",", @@ -525,7 +551,7 @@ static const var_type_fns_t csv_fns = { static int legacy_csv_interval_parse(void *target, const char *value, char **errmsg, - const void *params, const char *key) + const void *params) { (void)params; /* We used to have entire smartlists here. But now that all of our @@ -539,7 +565,7 @@ legacy_csv_interval_parse(void *target, const char *value, char **errmsg, val = tmp; } - int rv = units_parse_int(target, val, errmsg, &time_units, key); + int rv = units_parse_int(target, val, errmsg, &time_units); tor_free(tmp); return rv; } @@ -688,32 +714,23 @@ static const var_type_fns_t linelist_s_fns = { ///// // CONFIG_TYPE_ROUTERSET // -// XXXX This type is not implemented here, since routerset_t is not available // XXXX to this module. ///// ///// -// CONFIG_TYPE_OBSOLETE -// -// Used to indicate an obsolete option. +// CONFIG_TYPE_IGNORE // -// XXXX This is not a type, and should be handled at a higher level of -// XXXX abstraction. +// Used to indicate an option that cannot be stored or encoded. ///// static int ignore_parse(void *target, const char *value, char **errmsg, - const void *params, const char *key) + const void *params) { (void)target; (void)value; (void)errmsg; (void)params; - // XXXX move this to a higher level, once such a level exists. - log_warn(LD_GENERAL, "Skipping obsolete configuration option%s%s%s", - key && *key ? " \"" : "", - key && *key ? key : "", - key && *key ? "\"." : "."); return 0; } @@ -730,50 +747,91 @@ static const var_type_fns_t ignore_fns = { .encode = ignore_encode, }; +const var_type_def_t STRING_type_defn = { + .name="String", .fns=&string_fns }; +const var_type_def_t FILENAME_type_defn = { + .name="Filename", .fns=&string_fns }; +const var_type_def_t INT_type_defn = { + .name="SignedInteger", .fns=&int_fns, + .params=&INT_PARSE_UNRESTRICTED }; +const var_type_def_t POSINT_type_defn = { + .name="Integer", .fns=&int_fns, + .params=&INT_PARSE_POSINT }; +const var_type_def_t UINT64_type_defn = { + .name="Integer", .fns=&uint64_fns, }; +const var_type_def_t MEMUNIT_type_defn = { + .name="DataSize", .fns=&memunit_fns, + .params=&memory_units }; +const var_type_def_t INTERVAL_type_defn = { + .name="TimeInterval", .fns=&interval_fns, + .params=&time_units }; +const var_type_def_t MSEC_INTERVAL_type_defn = { + .name="TimeMsecInterval", + .fns=&interval_fns, + .params=&time_msec_units }; +const var_type_def_t DOUBLE_type_defn = { + .name="Float", .fns=&double_fns, }; +const var_type_def_t BOOL_type_defn = { + .name="Boolean", .fns=&enum_fns, + .params=&enum_params_bool }; +const var_type_def_t AUTOBOOL_type_defn = { + .name="Boolean+Auto", .fns=&enum_fns, + .params=&enum_params_autobool }; +const var_type_def_t ISOTIME_type_defn = { + .name="Time", .fns=&time_fns, }; +const var_type_def_t CSV_type_defn = { + .name="CommaList", .fns=&csv_fns, }; +const var_type_def_t CSV_INTERVAL_type_defn = { + .name="TimeInterval", + .fns=&legacy_csv_interval_fns, }; +const var_type_def_t LINELIST_type_defn = { + .name="LineList", .fns=&linelist_fns, + .flags=CFLG_NOREPLACE }; +/* + * A "linelist_s" is a derived view of a linelist_v: inspecting + * it gets part of a linelist_v, and setting it adds to the linelist_v. + */ +const var_type_def_t LINELIST_S_type_defn = { + .name="Dependent", .fns=&linelist_s_fns, + .flags=CFLG_NOREPLACE| + /* The operations we disable here are + * handled by the linelist_v. */ + CFLG_NOCOPY|CFLG_NOCMP|CFLG_NODUMP }; +const var_type_def_t LINELIST_V_type_defn = { + .name="Virtual", .fns=&linelist_v_fns, + .flags=CFLG_NOREPLACE|CFLG_NOSET }; +const var_type_def_t IGNORE_type_defn = { + .name="Ignored", .fns=&ignore_fns, + .flags=CFLG_NOCOPY|CFLG_NOCMP|CFLG_NODUMP|CFLG_NOSET, +}; +const var_type_def_t OBSOLETE_type_defn = { + .name="Obsolete", .fns=&ignore_fns, + .flags=CFLG_GROUP_OBSOLETE, +}; + /** * Table mapping conf_type_t values to var_type_def_t objects. **/ -static const var_type_def_t type_definitions_table[] = { - [CONFIG_TYPE_STRING] = { .name="String", .fns=&string_fns }, - [CONFIG_TYPE_FILENAME] = { .name="Filename", .fns=&string_fns }, - [CONFIG_TYPE_INT] = { .name="SignedInteger", .fns=&int_fns, - .params=&INT_PARSE_UNRESTRICTED }, - [CONFIG_TYPE_POSINT] = { .name="Integer", .fns=&int_fns, - .params=&INT_PARSE_POSINT }, - [CONFIG_TYPE_UINT64] = { .name="Integer", .fns=&uint64_fns, }, - [CONFIG_TYPE_MEMUNIT] = { .name="DataSize", .fns=&memunit_fns, - .params=&memory_units }, - [CONFIG_TYPE_INTERVAL] = { .name="TimeInterval", .fns=&interval_fns, - .params=&time_units }, - [CONFIG_TYPE_MSEC_INTERVAL] = { .name="TimeMsecInterval", - .fns=&interval_fns, - .params=&time_msec_units }, - [CONFIG_TYPE_DOUBLE] = { .name="Float", .fns=&double_fns, }, - [CONFIG_TYPE_BOOL] = { .name="Boolean", .fns=&enum_fns, - .params=&enum_table_bool }, - [CONFIG_TYPE_AUTOBOOL] = { .name="Boolean+Auto", .fns=&enum_fns, - .params=&enum_table_autobool }, - [CONFIG_TYPE_ISOTIME] = { .name="Time", .fns=&time_fns, }, - [CONFIG_TYPE_CSV] = { .name="CommaList", .fns=&csv_fns, }, - [CONFIG_TYPE_CSV_INTERVAL] = { .name="TimeInterval", - .fns=&legacy_csv_interval_fns, }, - [CONFIG_TYPE_LINELIST] = { .name="LineList", .fns=&linelist_fns, - .flags=CFLG_NOREPLACE }, - /* - * A "linelist_s" is a derived view of a linelist_v: inspecting - * it gets part of a linelist_v, and setting it adds to the linelist_v. - */ - [CONFIG_TYPE_LINELIST_S] = { .name="Dependent", .fns=&linelist_s_fns, - .flags=CFLG_NOREPLACE| - /* The operations we disable here are - * handled by the linelist_v. */ - CFLG_NOCOPY|CFLG_NOCMP|CFLG_NODUMP }, - [CONFIG_TYPE_LINELIST_V] = { .name="Virtual", .fns=&linelist_v_fns, - .flags=CFLG_NOREPLACE|CFLG_NOSET }, - [CONFIG_TYPE_OBSOLETE] = { - .name="Obsolete", .fns=&ignore_fns, - .flags=CFLG_GROUP_OBSOLETE, - } +static const var_type_def_t *type_definitions_table[] = { + [CONFIG_TYPE_STRING] = &STRING_type_defn, + [CONFIG_TYPE_FILENAME] = &FILENAME_type_defn, + [CONFIG_TYPE_INT] = &INT_type_defn, + [CONFIG_TYPE_POSINT] = &POSINT_type_defn, + [CONFIG_TYPE_UINT64] = &UINT64_type_defn, + [CONFIG_TYPE_MEMUNIT] = &MEMUNIT_type_defn, + [CONFIG_TYPE_INTERVAL] = &INTERVAL_type_defn, + [CONFIG_TYPE_MSEC_INTERVAL] = &MSEC_INTERVAL_type_defn, + [CONFIG_TYPE_DOUBLE] = &DOUBLE_type_defn, + [CONFIG_TYPE_BOOL] = &BOOL_type_defn, + [CONFIG_TYPE_AUTOBOOL] = &AUTOBOOL_type_defn, + [CONFIG_TYPE_ISOTIME] = &ISOTIME_type_defn, + [CONFIG_TYPE_CSV] = &CSV_type_defn, + [CONFIG_TYPE_CSV_INTERVAL] = &CSV_INTERVAL_type_defn, + [CONFIG_TYPE_LINELIST] = &LINELIST_type_defn, + [CONFIG_TYPE_LINELIST_S] = &LINELIST_S_type_defn, + [CONFIG_TYPE_LINELIST_V] = &LINELIST_V_type_defn, + [CONFIG_TYPE_IGNORE] = &IGNORE_type_defn, + [CONFIG_TYPE_OBSOLETE] = &OBSOLETE_type_defn, }; /** @@ -787,5 +845,5 @@ lookup_type_def(config_type_t type) tor_assert(t >= 0); if (t >= (int)ARRAY_LENGTH(type_definitions_table)) return NULL; - return &type_definitions_table[t]; + return type_definitions_table[t]; } diff --git a/src/lib/confmgt/type_defs.h b/src/lib/confmgt/type_defs.h index ecf040529e..fec002b1d3 100644 --- a/src/lib/confmgt/type_defs.h +++ b/src/lib/confmgt/type_defs.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/confmgt/typedvar.c b/src/lib/confmgt/typedvar.c index ce11a69379..1955302cdc 100644 --- a/src/lib/confmgt/typedvar.c +++ b/src/lib/confmgt/typedvar.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -24,6 +24,7 @@ #include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/malloc/malloc.h" +#include "lib/string/printf.h" #include "lib/string/util_string.h" #include "lib/confmgt/var_type_def_st.h" @@ -33,8 +34,7 @@ /** * Try to parse a string in <b>value</b> that encodes an object of the type - * defined by <b>def</b>. If not NULL, <b>key</b> is the name of the option, - * which may be used for logging. + * defined by <b>def</b>. * * On success, adjust the lvalue pointed to by <b>target</b> to hold that * value, and return 0. On failure, set *<b>errmsg</b> to a newly allocated @@ -42,7 +42,7 @@ **/ int typed_var_assign(void *target, const char *value, char **errmsg, - const var_type_def_t *def, const char *key) + const var_type_def_t *def) { if (BUG(!def)) return -1; // LCOV_EXCL_LINE @@ -50,7 +50,7 @@ typed_var_assign(void *target, const char *value, char **errmsg, typed_var_free(target, def); tor_assert(def->fns->parse); - return def->fns->parse(target, value, errmsg, def->params, key); + return def->fns->parse(target, value, errmsg, def->params); } /** @@ -76,7 +76,15 @@ typed_var_kvassign(void *target, const config_line_t *line, return def->fns->kv_parse(target, line, errmsg, def->params); } - return typed_var_assign(target, line->value, errmsg, def, line->key); + int rv = typed_var_assign(target, line->value, errmsg, def); + if (rv < 0 && *errmsg != NULL) { + /* typed_var_assign() didn't know the line's keyword, but we do. + * Let's add it to the error message. */ + char *oldmsg = *errmsg; + tor_asprintf(errmsg, "Could not parse %s: %s", line->key, oldmsg); + tor_free(oldmsg); + } + return rv; } /** @@ -159,7 +167,7 @@ typed_var_copy(void *dest, const void *src, const var_type_def_t *def) return 0; } char *err = NULL; - int rv = typed_var_assign(dest, enc, &err, def, NULL); + int rv = typed_var_assign(dest, enc, &err, def); if (BUG(rv < 0)) { // LCOV_EXCL_START log_warn(LD_BUG, "Encoded value %s was not parseable as a %s: %s", diff --git a/src/lib/confmgt/typedvar.h b/src/lib/confmgt/typedvar.h index 4382613833..cc90ed10a3 100644 --- a/src/lib/confmgt/typedvar.h +++ b/src/lib/confmgt/typedvar.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -21,7 +21,7 @@ typedef struct var_type_fns_t var_type_fns_t; typedef struct var_type_def_t var_type_def_t; int typed_var_assign(void *target, const char *value, char **errmsg, - const var_type_def_t *def, const char *key); + const var_type_def_t *def); void typed_var_free(void *target, const var_type_def_t *def); char *typed_var_encode(const void *value, const var_type_def_t *def); int typed_var_copy(void *dest, const void *src, const var_type_def_t *def); diff --git a/src/lib/confmgt/unitparse.c b/src/lib/confmgt/unitparse.c index c3ed8285a4..61edc60694 100644 --- a/src/lib/confmgt/unitparse.c +++ b/src/lib/confmgt/unitparse.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -13,8 +13,11 @@ #include "lib/confmgt/unitparse.h" #include "lib/log/log.h" #include "lib/log/util_bug.h" +#include "lib/malloc/malloc.h" #include "lib/string/parse_int.h" +#include "lib/string/printf.h" #include "lib/string/util_string.h" +#include "lib/intmath/muldiv.h" #include <string.h> @@ -109,22 +112,30 @@ const struct unit_table_t time_msec_units[] = { * table <b>u</b>, then multiply the number by the unit multiplier. * On success, set *<b>ok</b> to 1 and return this product. * Otherwise, set *<b>ok</b> to 0. + * + * If an error (like overflow or a negative value is detected), put an error + * message in *<b>errmsg_out</b> if that pointer is non-NULL, and otherwise + * log a warning. */ uint64_t -config_parse_units(const char *val, const unit_table_t *u, int *ok) +config_parse_units(const char *val, const unit_table_t *u, int *ok, + char **errmsg_out) { uint64_t v = 0; double d = 0; int use_float = 0; char *cp; + char *errmsg = NULL; tor_assert(ok); v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp); if (!*ok || (cp && *cp == '.')) { d = tor_parse_double(val, 0, (double)UINT64_MAX, ok, &cp); - if (!*ok) + if (!*ok) { + tor_asprintf(&errmsg, "Unable to parse %s as a number", val); goto done; + } use_float = 1; } @@ -142,18 +153,55 @@ config_parse_units(const char *val, const unit_table_t *u, int *ok) for ( ;u->unit;++u) { if (!strcasecmp(u->unit, cp)) { - if (use_float) - v = (uint64_t)(u->multiplier * d); - else - v *= u->multiplier; + if (use_float) { + d = u->multiplier * d; + + if (d < 0) { + tor_asprintf(&errmsg, "Got a negative value while parsing %s %s", + val, u->unit); + *ok = 0; + goto done; + } + + // Some compilers may warn about casting a double to an unsigned type + // because they don't know if d is >= 0 + if (d >= 0 && (d > (double)INT64_MAX || (uint64_t)d > INT64_MAX)) { + tor_asprintf(&errmsg, "Overflow while parsing %s %s", + val, u->unit); + *ok = 0; + goto done; + } + + v = (uint64_t) d; + } else { + v = tor_mul_u64_nowrap(v, u->multiplier); + + if (v > INT64_MAX) { + tor_asprintf(&errmsg, "Overflow while parsing %s %s", + val, u->unit); + *ok = 0; + goto done; + } + } + *ok = 1; goto done; } } - log_warn(LD_CONFIG, "Unknown unit '%s'.", cp); + tor_asprintf(&errmsg, "Unknown unit in %s", val); *ok = 0; done: + if (errmsg) { + tor_assert_nonfatal(!*ok); + if (errmsg_out) { + *errmsg_out = errmsg; + } else { + log_warn(LD_CONFIG, "%s", errmsg); + tor_free(errmsg); + } + } + if (*ok) return v; else @@ -167,7 +215,7 @@ config_parse_units(const char *val, const unit_table_t *u, int *ok) uint64_t config_parse_memunit(const char *s, int *ok) { - uint64_t u = config_parse_units(s, memory_units, ok); + uint64_t u = config_parse_units(s, memory_units, ok, NULL); return u; } @@ -179,7 +227,7 @@ int config_parse_msec_interval(const char *s, int *ok) { uint64_t r; - r = config_parse_units(s, time_msec_units, ok); + r = config_parse_units(s, time_msec_units, ok, NULL); if (r > INT_MAX) { log_warn(LD_CONFIG, "Msec interval '%s' is too long", s); *ok = 0; @@ -196,7 +244,7 @@ int config_parse_interval(const char *s, int *ok) { uint64_t r; - r = config_parse_units(s, time_units, ok); + r = config_parse_units(s, time_units, ok, NULL); if (r > INT_MAX) { log_warn(LD_CONFIG, "Interval '%s' is too long", s); *ok = 0; diff --git a/src/lib/confmgt/unitparse.h b/src/lib/confmgt/unitparse.h index 216361a7d4..047e11b424 100644 --- a/src/lib/confmgt/unitparse.h +++ b/src/lib/confmgt/unitparse.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -25,7 +25,8 @@ extern const unit_table_t memory_units[]; extern const unit_table_t time_units[]; extern const struct unit_table_t time_msec_units[]; -uint64_t config_parse_units(const char *val, const unit_table_t *u, int *ok); +uint64_t config_parse_units(const char *val, const unit_table_t *u, int *ok, + char **errmsg_out); uint64_t config_parse_memunit(const char *s, int *ok); int config_parse_msec_interval(const char *s, int *ok); diff --git a/src/lib/confmgt/var_type_def_st.h b/src/lib/confmgt/var_type_def_st.h index aa9ded39e9..2519b86aa0 100644 --- a/src/lib/confmgt/var_type_def_st.h +++ b/src/lib/confmgt/var_type_def_st.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -52,12 +52,9 @@ struct var_type_fns_t { * type. On success, adjust the lvalue pointed to by <b>target</b> to hold * that value, and return 0. On failure, set *<b>errmsg</b> to a newly * allocated string holding an error message, and return -1. - * - * If not NULL, <b>key</b> is the name of the option, which may be used for - * logging. **/ int (*parse)(void *target, const char *value, char **errmsg, - const void *params, const char *key); + const void *params); /** * Try to parse a single line from the head of<b>line</b> that encodes * an object of this type. On success and failure, behave as in the parse() diff --git a/src/lib/container/bitarray.h b/src/lib/container/bitarray.h index 45992796af..41409e350a 100644 --- a/src/lib/container/bitarray.h +++ b/src/lib/container/bitarray.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_BITARRAY_H diff --git a/src/lib/container/bloomfilt.c b/src/lib/container/bloomfilt.c index 8c61db81d6..34b1265d81 100644 --- a/src/lib/container/bloomfilt.c +++ b/src/lib/container/bloomfilt.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/container/bloomfilt.h b/src/lib/container/bloomfilt.h index 0ce18bd3ec..6d36056b5a 100644 --- a/src/lib/container/bloomfilt.h +++ b/src/lib/container/bloomfilt.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_BLOOMFILT_H diff --git a/src/lib/container/handles.h b/src/lib/container/handles.h index ca7c94559e..6b1bbd5167 100644 --- a/src/lib/container/handles.h +++ b/src/lib/container/handles.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2019, The Tor Project, Inc. */ +/* Copyright (c) 2016-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -16,33 +16,33 @@ * To enable a type to have handles, add a HANDLE_ENTRY() field in its * definition, as in: * - * struct walrus { - * HANDLE_ENTRY(wlr, walrus); + * struct walrus_t { + * HANDLE_ENTRY(wlr, walrus_t); * // ... * }; * - * And invoke HANDLE_DECL(wlr, walrus, [static]) to declare the handle + * And invoke HANDLE_DECL(wlr, walrus_t, [static]) to declare the handle * manipulation functions (typically in a header): * * // opaque handle to walrus. * typedef struct wlr_handle_t wlr_handle_t; * * // make a new handle - * struct wlr_handle_t *wlr_handle_new(struct walrus *); + * struct wlr_handle_t *wlr_handle_new(struct walrus_t *); * * // release a handle * void wlr_handle_free(wlr_handle_t *); * * // return the pointed-to walrus, or NULL. - * struct walrus *wlr_handle_get(wlr_handle_t *). + * struct walrus_t *wlr_handle_get(wlr_handle_t *). * * // call this function when you're about to free the walrus; * // it invalidates all handles. (IF YOU DON'T, YOU WILL HAVE * // DANGLING REFERENCES) - * void wlr_handles_clear(struct walrus *); + * void wlr_handles_clear(struct walrus_t *); * * Finally, use HANDLE_IMPL() to define the above functions in some - * appropriate C file: HANDLE_IMPL(wlr, walrus, [static]) + * appropriate C file: HANDLE_IMPL(wlr, walrus_t, [static]) * **/ @@ -57,12 +57,13 @@ #define HANDLE_ENTRY(name, structname) \ struct name ## _handle_head_t *handle_head -#define HANDLE_DECL(name, structname, linkage) \ +#define HANDLE_DECL(name, structname_t, linkage) \ typedef struct name ## _handle_t name ## _handle_t; \ - linkage name ## _handle_t *name ## _handle_new(struct structname *object); \ + linkage name ## _handle_t *name ## _handle_new( \ + struct structname_t *object); \ linkage void name ## _handle_free_(name ## _handle_t *); \ - linkage struct structname *name ## _handle_get(name ## _handle_t *); \ - linkage void name ## _handles_clear(struct structname *object); + linkage struct structname_t *name ## _handle_get(name ## _handle_t *); \ + linkage void name ## _handles_clear(struct structname_t *object); /* * Implementation notes: there are lots of possible implementations here. We diff --git a/src/lib/container/lib_container.md b/src/lib/container/lib_container.md new file mode 100644 index 0000000000..f4902ca44a --- /dev/null +++ b/src/lib/container/lib_container.md @@ -0,0 +1,49 @@ +@dir /lib/container +@brief lib/container: Hash tables, dynamic arrays, bit arrays, etc. + +### Smartlists: Neither lists, nor especially smart. + +For historical reasons, we call our dynamic-allocated array type +`smartlist_t`. It can grow or shrink as elements are added and removed. + +All smartlists hold an array of `void *`. Whenever you expose a smartlist +in an API you *must* document which types its pointers actually hold. + +<!-- It would be neat to fix that, wouldn't it? -NM --> + +Smartlists are created empty with `smartlist_new()` and freed with +`smartlist_free()`. See the `containers.h` header documentation for more +information; there are many convenience functions for commonly needed +operations. + +For low-level operations on smartlists, see also +\refdir{lib/smartlist_core}. + +<!-- TODO: WRITE more about what you can do with smartlists. --> + +### Digest maps, string maps, and more. + +Tor makes frequent use of maps from 160-bit digests, 256-bit digests, +or nul-terminated strings to `void *`. These types are `digestmap_t`, +`digest256map_t`, and `strmap_t` respectively. See the containers.h +module documentation for more information. + +### Intrusive lists and hashtables + +For performance-sensitive cases, we sometimes want to use "intrusive" +collections: ones where the bookkeeping pointers are stuck inside the +structures that belong to the collection. If you've used the +BSD-style sys/queue.h macros, you'll be familiar with these. + +Unfortunately, the `sys/queue.h` macros vary significantly between the +platforms that have them, so we provide our own variants in +`ext/tor_queue.h`. + +We also provide an intrusive hashtable implementation in `ext/ht.h`. +When you're using it, you'll need to define your own hash +functions. If attacker-induced collisions are a worry here, use the +cryptographic siphash24g function to extract hashes. + +<!-- TODO: WRITE about bloom filters, namemaps, bit-arrays, order functions. +--> + diff --git a/src/lib/container/map.c b/src/lib/container/map.c index fde33d6ace..c3fb0b5c8a 100644 --- a/src/lib/container/map.c +++ b/src/lib/container/map.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/container/map.h b/src/lib/container/map.h index 9da1d3072c..989ecfad80 100644 --- a/src/lib/container/map.h +++ b/src/lib/container/map.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_MAP_H @@ -17,22 +17,23 @@ #include "ext/siphash.h" -#define DECLARE_MAP_FNS(maptype, keytype, prefix) \ - typedef struct maptype maptype; \ +#define DECLARE_MAP_FNS(mapname_t, keytype, prefix) \ + typedef struct mapname_t mapname_t; \ typedef struct prefix##entry_t *prefix##iter_t; \ - MOCK_DECL(maptype*, prefix##new, (void)); \ - void* prefix##set(maptype *map, keytype key, void *val); \ - void* prefix##get(const maptype *map, keytype key); \ - void* prefix##remove(maptype *map, keytype key); \ - MOCK_DECL(void, prefix##free_, (maptype *map, void (*free_val)(void*))); \ - int prefix##isempty(const maptype *map); \ - int prefix##size(const maptype *map); \ - prefix##iter_t *prefix##iter_init(maptype *map); \ - prefix##iter_t *prefix##iter_next(maptype *map, prefix##iter_t *iter); \ - prefix##iter_t *prefix##iter_next_rmv(maptype *map, prefix##iter_t *iter); \ + MOCK_DECL(mapname_t*, prefix##new, (void)); \ + void* prefix##set(mapname_t *map, keytype key, void *val); \ + void* prefix##get(const mapname_t *map, keytype key); \ + void* prefix##remove(mapname_t *map, keytype key); \ + MOCK_DECL(void, prefix##free_, (mapname_t *map, void (*free_val)(void*))); \ + int prefix##isempty(const mapname_t *map); \ + int prefix##size(const mapname_t *map); \ + prefix##iter_t *prefix##iter_init(mapname_t *map); \ + prefix##iter_t *prefix##iter_next(mapname_t *map, prefix##iter_t *iter); \ + prefix##iter_t *prefix##iter_next_rmv(mapname_t *map, \ + prefix##iter_t *iter); \ void prefix##iter_get(prefix##iter_t *iter, keytype *keyp, void **valp); \ int prefix##iter_done(prefix##iter_t *iter); \ - void prefix##assert_ok(const maptype *map) + void prefix##assert_ok(const mapname_t *map) /* Map from const char * to void *. Implemented with a hash table. */ DECLARE_MAP_FNS(strmap_t, const char *, strmap_); @@ -42,9 +43,9 @@ DECLARE_MAP_FNS(digestmap_t, const char *, digestmap_); * table. */ DECLARE_MAP_FNS(digest256map_t, const uint8_t *, digest256map_); -#define MAP_FREE_AND_NULL(maptype, map, fn) \ +#define MAP_FREE_AND_NULL(mapname_t, map, fn) \ do { \ - maptype ## _free_((map), (fn)); \ + mapname_t ## _free_((map), (fn)); \ (map) = NULL; \ } while (0) @@ -183,62 +184,62 @@ void* strmap_set_lc(strmap_t *map, const char *key, void *val); void* strmap_get_lc(const strmap_t *map, const char *key); void* strmap_remove_lc(strmap_t *map, const char *key); -#define DECLARE_TYPED_DIGESTMAP_FNS(prefix, maptype, valtype) \ - typedef struct maptype maptype; \ +#define DECLARE_TYPED_DIGESTMAP_FNS(prefix, mapname_t, valtype) \ + typedef struct mapname_t mapname_t; \ typedef struct prefix##iter_t *prefix##iter_t; \ - ATTR_UNUSED static inline maptype* \ + ATTR_UNUSED static inline mapname_t* \ prefix##new(void) \ { \ - return (maptype*)digestmap_new(); \ + return (mapname_t*)digestmap_new(); \ } \ ATTR_UNUSED static inline digestmap_t* \ - prefix##to_digestmap(maptype *map) \ + prefix##to_digestmap(mapname_t *map) \ { \ return (digestmap_t*)map; \ } \ ATTR_UNUSED static inline valtype* \ - prefix##get(maptype *map, const char *key) \ + prefix##get(mapname_t *map, const char *key) \ { \ return (valtype*)digestmap_get((digestmap_t*)map, key); \ } \ ATTR_UNUSED static inline valtype* \ - prefix##set(maptype *map, const char *key, valtype *val) \ + prefix##set(mapname_t *map, const char *key, valtype *val) \ { \ return (valtype*)digestmap_set((digestmap_t*)map, key, val); \ } \ ATTR_UNUSED static inline valtype* \ - prefix##remove(maptype *map, const char *key) \ + prefix##remove(mapname_t *map, const char *key) \ { \ return (valtype*)digestmap_remove((digestmap_t*)map, key); \ } \ ATTR_UNUSED static inline void \ - prefix##f##ree_(maptype *map, void (*free_val)(void*)) \ + prefix##f##ree_(mapname_t *map, void (*free_val)(void*)) \ { \ digestmap_free_((digestmap_t*)map, free_val); \ } \ ATTR_UNUSED static inline int \ - prefix##isempty(maptype *map) \ + prefix##isempty(mapname_t *map) \ { \ return digestmap_isempty((digestmap_t*)map); \ } \ ATTR_UNUSED static inline int \ - prefix##size(maptype *map) \ + prefix##size(mapname_t *map) \ { \ return digestmap_size((digestmap_t*)map); \ } \ ATTR_UNUSED static inline \ - prefix##iter_t *prefix##iter_init(maptype *map) \ + prefix##iter_t *prefix##iter_init(mapname_t *map) \ { \ return (prefix##iter_t*) digestmap_iter_init((digestmap_t*)map); \ } \ ATTR_UNUSED static inline \ - prefix##iter_t *prefix##iter_next(maptype *map, prefix##iter_t *iter) \ + prefix##iter_t *prefix##iter_next(mapname_t *map, prefix##iter_t *iter) \ { \ return (prefix##iter_t*) digestmap_iter_next( \ (digestmap_t*)map, (digestmap_iter_t*)iter); \ } \ ATTR_UNUSED static inline prefix##iter_t* \ - prefix##iter_next_rmv(maptype *map, prefix##iter_t *iter) \ + prefix##iter_next_rmv(mapname_t *map, prefix##iter_t *iter) \ { \ return (prefix##iter_t*) digestmap_iter_next_rmv( \ (digestmap_t*)map, (digestmap_iter_t*)iter); \ diff --git a/src/lib/container/namemap.c b/src/lib/container/namemap.c index a90057b32c..28695ee3a1 100644 --- a/src/lib/container/namemap.c +++ b/src/lib/container/namemap.c @@ -1,8 +1,13 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file namemap.c + * @brief Mappings between identifiers and 16-bit ints. + **/ + #include "orconfig.h" #include "lib/container/smartlist.h" #include "lib/container/namemap.h" diff --git a/src/lib/container/namemap.h b/src/lib/container/namemap.h index b96bc13f3a..b451c18c68 100644 --- a/src/lib/container/namemap.h +++ b/src/lib/container/namemap.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_NAMEMAP_H diff --git a/src/lib/container/namemap_st.h b/src/lib/container/namemap_st.h index 5008fd5855..39aa85cc09 100644 --- a/src/lib/container/namemap_st.h +++ b/src/lib/container/namemap_st.h @@ -1,11 +1,16 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef NAMEMAP_ST_H #define NAMEMAP_ST_H +/** + * @file namemap_st.h + * @brief Internal declarations for namemap structure. + **/ + #include "lib/cc/compat_compiler.h" #include "ext/ht.h" @@ -28,7 +33,9 @@ struct namemap_t { struct smartlist_t *names; }; +#ifndef COCCI /** Macro to initialize a namemap. */ #define NAMEMAP_INIT() { HT_INITIALIZER(), NULL } +#endif #endif /* !defined(NAMEMAP_ST_H) */ diff --git a/src/lib/container/order.c b/src/lib/container/order.c index f6503a124e..cac241f027 100644 --- a/src/lib/container/order.c +++ b/src/lib/container/order.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/container/order.h b/src/lib/container/order.h index 3f2fd054a0..5bca095f35 100644 --- a/src/lib/container/order.h +++ b/src/lib/container/order.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_ORDER_H diff --git a/src/lib/container/smartlist.c b/src/lib/container/smartlist.c index 2b71c11287..7784f83957 100644 --- a/src/lib/container/smartlist.c +++ b/src/lib/container/smartlist.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -652,7 +652,7 @@ smartlist_sort_pointers(smartlist_t *sl) #define LEFT_CHILD(i) ( 2*(i) + 1 ) #define RIGHT_CHILD(i) ( 2*(i) + 2 ) #define PARENT(i) ( ((i)-1) / 2 ) -/** }@ */ +/** @} */ /** @{ */ /** Helper macros for heaps: Given a local variable <b>idx_field_offset</b> diff --git a/src/lib/container/smartlist.h b/src/lib/container/smartlist.h index 25638e4b22..458d564cd5 100644 --- a/src/lib/container/smartlist.h +++ b/src/lib/container/smartlist.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_SMARTLIST_H @@ -92,6 +92,7 @@ char *smartlist_join_strings2(smartlist_t *sl, const char *join, size_t join_len, int terminate, size_t *len_out) ATTR_MALLOC; +#ifndef COCCI /* Helper: Given two lists of items, possibly of different types, such that * both lists are sorted on some common field (as determined by a comparison * expression <b>cmpexpr</b>), and such that one list (<b>sl1</b>) has no @@ -165,5 +166,6 @@ char *smartlist_join_strings2(smartlist_t *sl, const char *join, #define SMARTLIST_FOREACH_JOIN_END(var1, var2) \ } \ STMT_END +#endif /* !defined(COCCI) */ #endif /* !defined(TOR_SMARTLIST_H) */ diff --git a/src/lib/crypt_ops/.may_include b/src/lib/crypt_ops/.may_include index 0739699686..810e777271 100644 --- a/src/lib/crypt_ops/.may_include +++ b/src/lib/crypt_ops/.may_include @@ -1,6 +1,7 @@ orconfig.h lib/arch/*.h lib/cc/*.h +lib/conf/*.h lib/container/*.h lib/crypt_ops/*.h lib/ctime/*.h @@ -17,6 +18,8 @@ lib/testsupport/*.h lib/thread/*.h lib/log/*.h +lib/crypt_ops/*.inc + trunnel/pwbox.h keccak-tiny/*.h diff --git a/src/lib/crypt_ops/aes.h b/src/lib/crypt_ops/aes.h index 7c774062d9..c25417b4e6 100644 --- a/src/lib/crypt_ops/aes.h +++ b/src/lib/crypt_ops/aes.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Implements a minimal interface to counter-mode AES. */ @@ -16,7 +16,7 @@ #include "lib/cc/torint.h" #include "lib/malloc/malloc.h" -typedef struct aes_cnt_cipher aes_cnt_cipher_t; +typedef struct aes_cnt_cipher_t aes_cnt_cipher_t; aes_cnt_cipher_t* aes_new_cipher(const uint8_t *key, const uint8_t *iv, int key_bits); diff --git a/src/lib/crypt_ops/aes_nss.c b/src/lib/crypt_ops/aes_nss.c index 4eda5e5902..71d2f01449 100644 --- a/src/lib/crypt_ops/aes_nss.c +++ b/src/lib/crypt_ops/aes_nss.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -15,10 +15,10 @@ #include "lib/crypt_ops/crypto_util.h" #include "lib/log/util_bug.h" -DISABLE_GCC_WARNING(strict-prototypes) +DISABLE_GCC_WARNING("-Wstrict-prototypes") #include <pk11pub.h> #include <secerr.h> -ENABLE_GCC_WARNING(strict-prototypes) +ENABLE_GCC_WARNING("-Wstrict-prototypes") aes_cnt_cipher_t * aes_new_cipher(const uint8_t *key, const uint8_t *iv, diff --git a/src/lib/crypt_ops/aes_openssl.c b/src/lib/crypt_ops/aes_openssl.c index 64564892ad..502f7703bd 100644 --- a/src/lib/crypt_ops/aes_openssl.c +++ b/src/lib/crypt_ops/aes_openssl.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -28,7 +28,7 @@ #error "We require OpenSSL >= 1.0.0" #endif -DISABLE_GCC_WARNING(redundant-decls) +DISABLE_GCC_WARNING("-Wredundant-decls") #include <stdlib.h> #include <string.h> @@ -37,9 +37,8 @@ DISABLE_GCC_WARNING(redundant-decls) #include <openssl/engine.h> #include <openssl/modes.h> -ENABLE_GCC_WARNING(redundant-decls) +ENABLE_GCC_WARNING("-Wredundant-decls") -#include "lib/crypt_ops/aes.h" #include "lib/log/log.h" #include "lib/ctime/di_ops.h" @@ -154,7 +153,7 @@ evaluate_ctr_for_aes(void) /* Interface to AES code, and counter implementation */ /** Implements an AES counter-mode cipher. */ -struct aes_cnt_cipher { +struct aes_cnt_cipher_t { /** This next element (however it's defined) is the AES key. */ union { EVP_CIPHER_CTX evp; diff --git a/src/lib/crypt_ops/certs.md b/src/lib/crypt_ops/certs.md new file mode 100644 index 0000000000..2768548b2a --- /dev/null +++ b/src/lib/crypt_ops/certs.md @@ -0,0 +1,30 @@ + +@page certificates Certificates in Tor. + +We have, alas, several certificate types in Tor. + +The tor_x509_cert_t type represents an X.509 certificate. This document +won't explain X.509 to you -- possibly, no document can. (OTOH, Peter +Gutmann's "x.509 style guide", though severely dated, does a good job of +explaining how awful x.509 can be.) Do not introduce any new usages of +X.509. Right now we only use it in places where TLS forces us to do so. +See x509.c for more information about using this type. + + +The authority_cert_t type is used only for directory authority keys. It +has a medium-term signing key (which the authorities actually keep +online) signed by a long-term identity key (which the authority operator +had really better be keeping offline). Don't use it for any new kind of +certificate. + +For new places where you need a certificate, consider tor_cert_t: it +represents a typed and dated _something_ signed by an Ed25519 key. The +format is described in tor-spec. Unlike x.509, you can write it on a +napkin. The torcert.c file is used for manipulating these certificates and +their associated keys. + +(Additionally, the Tor directory design uses a fairly wide variety of +documents that include keys and which are signed by keys. You can +consider these documents to be an additional kind of certificate if you +want.) + diff --git a/src/lib/crypt_ops/compat_openssl.h b/src/lib/crypt_ops/compat_openssl.h index 61ca51315f..5fd073bea1 100644 --- a/src/lib/crypt_ops/compat_openssl.h +++ b/src/lib/crypt_ops/compat_openssl.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_COMPAT_OPENSSL_H diff --git a/src/lib/crypt_ops/crypto_cipher.c b/src/lib/crypt_ops/crypto_cipher.c index 7bc2edad54..0a24a580ae 100644 --- a/src/lib/crypt_ops/crypto_cipher.c +++ b/src/lib/crypt_ops/crypto_cipher.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_cipher.h b/src/lib/crypt_ops/crypto_cipher.h index 88d63c1df2..1e22a7c138 100644 --- a/src/lib/crypt_ops/crypto_cipher.h +++ b/src/lib/crypt_ops/crypto_cipher.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -25,7 +25,7 @@ /** Length of our symmetric cipher's keys of 256-bit. */ #define CIPHER256_KEY_LEN 32 -typedef struct aes_cnt_cipher crypto_cipher_t; +typedef struct aes_cnt_cipher_t crypto_cipher_t; /* environment setup */ crypto_cipher_t *crypto_cipher_new(const char *key); diff --git a/src/lib/crypt_ops/crypto_curve25519.c b/src/lib/crypt_ops/crypto_curve25519.c index de4e17a296..2a2589f07d 100644 --- a/src/lib/crypt_ops/crypto_curve25519.c +++ b/src/lib/crypt_ops/crypto_curve25519.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2019, The Tor Project, Inc. */ +/* Copyright (c) 2012-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_curve25519.h b/src/lib/crypt_ops/crypto_curve25519.h index cd23169cd5..154a0b94bc 100644 --- a/src/lib/crypt_ops/crypto_curve25519.h +++ b/src/lib/crypt_ops/crypto_curve25519.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2019, The Tor Project, Inc. */ +/* Copyright (c) 2012-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_dh.c b/src/lib/crypt_ops/crypto_dh.c index 4be7948761..086aceed6f 100644 --- a/src/lib/crypt_ops/crypto_dh.c +++ b/src/lib/crypt_ops/crypto_dh.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_dh.h b/src/lib/crypt_ops/crypto_dh.h index 850d50c7ae..2a0e1f6912 100644 --- a/src/lib/crypt_ops/crypto_dh.h +++ b/src/lib/crypt_ops/crypto_dh.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_dh_nss.c b/src/lib/crypt_ops/crypto_dh_nss.c index 379eb84a4f..018db8bf43 100644 --- a/src/lib/crypt_ops/crypto_dh_nss.c +++ b/src/lib/crypt_ops/crypto_dh_nss.c @@ -1,11 +1,11 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** - * \file crypto_dh_nss.h + * \file crypto_dh_nss.c * * \brief NSS implementation of Diffie-Hellman over Z_p. **/ diff --git a/src/lib/crypt_ops/crypto_dh_openssl.c b/src/lib/crypt_ops/crypto_dh_openssl.c index 8ae97373e8..c5f7271596 100644 --- a/src/lib/crypt_ops/crypto_dh_openssl.c +++ b/src/lib/crypt_ops/crypto_dh_openssl.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -17,11 +17,11 @@ #include "lib/log/log.h" #include "lib/log/util_bug.h" -DISABLE_GCC_WARNING(redundant-decls) +DISABLE_GCC_WARNING("-Wredundant-decls") #include <openssl/dh.h> -ENABLE_GCC_WARNING(redundant-decls) +ENABLE_GCC_WARNING("-Wredundant-decls") #include <openssl/bn.h> #include <string.h> @@ -103,7 +103,7 @@ crypto_validate_dh_params(const BIGNUM *p, const BIGNUM *g) #endif /* 0 */ /** - * Helper: convert <b>hex<b> to a bignum, and return it. Assert that the + * Helper: convert <b>hex</b> to a bignum, and return it. Assert that the * operation was successful. */ static BIGNUM * diff --git a/src/lib/crypt_ops/crypto_digest.c b/src/lib/crypt_ops/crypto_digest.c index ba226f8756..7775e69410 100644 --- a/src/lib/crypt_ops/crypto_digest.c +++ b/src/lib/crypt_ops/crypto_digest.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -150,6 +150,9 @@ struct crypto_xof_t { */ EVP_MD_CTX *ctx; #else /* !defined(OPENSSL_HAS_SHAKE3_EVP) */ + /** + * State of the Keccak sponge for the SHAKE-256 computation. + **/ keccak_state s; #endif /* defined(OPENSSL_HAS_SHAKE3_EVP) */ }; diff --git a/src/lib/crypt_ops/crypto_digest.h b/src/lib/crypt_ops/crypto_digest.h index 5869db7800..eefd2e3f0a 100644 --- a/src/lib/crypt_ops/crypto_digest.h +++ b/src/lib/crypt_ops/crypto_digest.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -38,6 +38,9 @@ /** Length of hex encoding of SHA512 digest, not including final NUL. */ #define HEX_DIGEST512_LEN 128 +/** + * An identifier for a cryptographic digest algorithm. + **/ typedef enum { DIGEST_SHA1 = 0, DIGEST_SHA256 = 1, @@ -45,16 +48,31 @@ typedef enum { DIGEST_SHA3_256 = 3, DIGEST_SHA3_512 = 4, } digest_algorithm_t; +/** Number of digest algorithms that we know */ #define N_DIGEST_ALGORITHMS (DIGEST_SHA3_512+1) +/** Number of digest algorithms to compute when computing "all the + * commonly used digests." + * + * (This is used in common_digests_t and related functions.) + */ #define N_COMMON_DIGEST_ALGORITHMS (DIGEST_SHA256+1) +/** + * Bytes of storage needed to record the state of an in-progress SHA-1 digest. + * + * This is a deliberate overestimate. + **/ #define DIGEST_CHECKPOINT_BYTES (SIZEOF_VOID_P + 512) + /** Structure used to temporarily save the a digest object. Only implemented * for SHA1 digest for now. */ typedef struct crypto_digest_checkpoint_t { #ifdef ENABLE_NSS + /** The number of bytes used in <b>mem</b>. */ unsigned int bytes_used; #endif + /** A buffer to store the SHA1 state. Its contents are unspecified, and + * are managed by the underlying crypto library.*/ uint8_t mem[DIGEST_CHECKPOINT_BYTES]; } crypto_digest_checkpoint_t; @@ -67,10 +85,19 @@ typedef struct crypto_digest_checkpoint_t { * once. **/ typedef struct { + /** An array of digest outputs, one for each "common" digest algorithm. */ char d[N_COMMON_DIGEST_ALGORITHMS][DIGEST256_LEN]; } common_digests_t; +/** + * State for computing a digest over a stream of data. + **/ typedef struct crypto_digest_t crypto_digest_t; + +/** + * State for computing an "extendable-output function" (like SHAKE) over a + * stream of data, and/or streaming the output. + **/ typedef struct crypto_xof_t crypto_xof_t; struct smartlist_t; @@ -97,6 +124,9 @@ crypto_digest_t *crypto_digest_new(void); crypto_digest_t *crypto_digest256_new(digest_algorithm_t algorithm); crypto_digest_t *crypto_digest512_new(digest_algorithm_t algorithm); void crypto_digest_free_(crypto_digest_t *digest); +/** + * Release all storage held in <b>d</b>, and set it to NULL. + **/ #define crypto_digest_free(d) \ FREE_AND_NULL(crypto_digest_t, crypto_digest_free_, (d)) void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, @@ -122,6 +152,9 @@ crypto_xof_t *crypto_xof_new(void); void crypto_xof_add_bytes(crypto_xof_t *xof, const uint8_t *data, size_t len); void crypto_xof_squeeze_bytes(crypto_xof_t *xof, uint8_t *out, size_t len); void crypto_xof_free_(crypto_xof_t *xof); +/** + * Release all storage held in <b>xof</b>, and set it to NULL. + **/ #define crypto_xof_free(xof) \ FREE_AND_NULL(crypto_xof_t, crypto_xof_free_, (xof)) void crypto_xof(uint8_t *output, size_t output_len, diff --git a/src/lib/crypt_ops/crypto_digest_nss.c b/src/lib/crypt_ops/crypto_digest_nss.c index afa8f6d5ef..92c20fe9e8 100644 --- a/src/lib/crypt_ops/crypto_digest_nss.c +++ b/src/lib/crypt_ops/crypto_digest_nss.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -23,9 +23,9 @@ #include "lib/arch/bytes.h" -DISABLE_GCC_WARNING(strict-prototypes) +DISABLE_GCC_WARNING("-Wstrict-prototypes") #include <pk11pub.h> -ENABLE_GCC_WARNING(strict-prototypes) +ENABLE_GCC_WARNING("-Wstrict-prototypes") /** * Convert a digest_algorithm_t (used by tor) to a HashType (used by NSS). @@ -44,7 +44,11 @@ digest_alg_to_nss_oid(digest_algorithm_t alg) } } -/* Helper: get an unkeyed digest via pk11wrap */ +/** Helper: Compute an unkeyed digest of the <b>msg_len</b> bytes at + * <b>msg</b>, using the digest algorithm specified by <b>alg</b>. + * Store the result in the <b>len_out</b>-byte buffer at <b>digest</b>. + * Return the number of bytes written on success, and -1 on failure. + **/ static int digest_nss_internal(SECOidTag alg, char *digest, unsigned len_out, diff --git a/src/lib/crypt_ops/crypto_digest_openssl.c b/src/lib/crypt_ops/crypto_digest_openssl.c index 50a8ff4d27..11189c7fb2 100644 --- a/src/lib/crypt_ops/crypto_digest_openssl.c +++ b/src/lib/crypt_ops/crypto_digest_openssl.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -25,12 +25,12 @@ #include "lib/crypt_ops/crypto_openssl_mgt.h" -DISABLE_GCC_WARNING(redundant-decls) +DISABLE_GCC_WARNING("-Wredundant-decls") #include <openssl/hmac.h> #include <openssl/sha.h> -ENABLE_GCC_WARNING(redundant-decls) +ENABLE_GCC_WARNING("-Wredundant-decls") /* Crypto digest functions */ @@ -147,9 +147,9 @@ crypto_digest_get_algorithm(crypto_digest_t *digest) static size_t crypto_digest_alloc_bytes(digest_algorithm_t alg) { - /* Helper: returns the number of bytes in the 'f' field of 'st' */ + /** Helper: returns the number of bytes in the 'f' field of 'st' */ #define STRUCT_FIELD_SIZE(st, f) (sizeof( ((st*)0)->f )) - /* Gives the length of crypto_digest_t through the end of the field 'd' */ + /** Gives the length of crypto_digest_t through the end of the field 'd' */ #define END_OF_FIELD(f) (offsetof(crypto_digest_t, f) + \ STRUCT_FIELD_SIZE(crypto_digest_t, f)) switch (alg) { @@ -519,4 +519,3 @@ crypto_hmac_sha256(char *hmac_out, (unsigned char*)hmac_out, NULL); tor_assert(rv); } - diff --git a/src/lib/crypt_ops/crypto_ed25519.c b/src/lib/crypt_ops/crypto_ed25519.c index c28111a5a5..f242c7011e 100644 --- a/src/lib/crypt_ops/crypto_ed25519.c +++ b/src/lib/crypt_ops/crypto_ed25519.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2019, The Tor Project, Inc. */ +/* Copyright (c) 2013-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_ed25519.h b/src/lib/crypt_ops/crypto_ed25519.h index 325b28244d..346de464e3 100644 --- a/src/lib/crypt_ops/crypto_ed25519.h +++ b/src/lib/crypt_ops/crypto_ed25519.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2019, The Tor Project, Inc. */ +/* Copyright (c) 2012-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_format.c b/src/lib/crypt_ops/crypto_format.c index 118cd79045..92b8b9372e 100644 --- a/src/lib/crypt_ops/crypto_format.c +++ b/src/lib/crypt_ops/crypto_format.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_format.h b/src/lib/crypt_ops/crypto_format.h index b4b3aa189c..91da137e1c 100644 --- a/src/lib/crypt_ops/crypto_format.h +++ b/src/lib/crypt_ops/crypto_format.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_hkdf.c b/src/lib/crypt_ops/crypto_hkdf.c index e0d241d4ea..7b02820087 100644 --- a/src/lib/crypt_ops/crypto_hkdf.c +++ b/src/lib/crypt_ops/crypto_hkdf.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_hkdf.h b/src/lib/crypt_ops/crypto_hkdf.h index 2994d18e3d..404f548774 100644 --- a/src/lib/crypt_ops/crypto_hkdf.h +++ b/src/lib/crypt_ops/crypto_hkdf.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_init.c b/src/lib/crypt_ops/crypto_init.c index a16bf4e11a..f09bf07c4d 100644 --- a/src/lib/crypt_ops/crypto_init.c +++ b/src/lib/crypt_ops/crypto_init.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -23,6 +23,9 @@ #include "lib/crypt_ops/crypto_nss_mgt.h" #include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_sys.h" +#include "lib/crypt_ops/crypto_options_st.h" +#include "lib/conf/conftypes.h" +#include "lib/log/util_bug.h" #include "lib/subsys/subsys.h" @@ -252,6 +255,66 @@ subsys_crypto_thread_cleanup(void) crypto_thread_cleanup(); } +/** Magic number for crypto_options_t. */ +#define CRYPTO_OPTIONS_MAGIC 0x68757368 + +/** + * Return 0 if <b>arg</b> is a valid crypto_options_t. Otherwise return -1 + * and set *<b>msg_out</b> to a freshly allocated error string. + **/ +static int +crypto_options_validate(const void *arg, char **msg_out) +{ + const crypto_options_t *opt = arg; + tor_assert(opt->magic == CRYPTO_OPTIONS_MAGIC); + tor_assert(msg_out); + + if (opt->AccelDir && !opt->AccelName) { + *msg_out = tor_strdup("Can't use hardware crypto accelerator dir " + "without engine name."); + return -1; + } + + return 0; +} + +/* Declare the options field table for crypto_options */ +#define CONF_CONTEXT LL_TABLE +#include "lib/crypt_ops/crypto_options.inc" +#undef CONF_CONTEXT + +/** + * Declares the configuration options for this module. + **/ +static const config_format_t crypto_options_fmt = { + .size = sizeof(crypto_options_t), + .magic = { "crypto_options_t", + CRYPTO_OPTIONS_MAGIC, + offsetof(crypto_options_t, magic) }, + .vars = crypto_options_t_vars, + .validate_fn = crypto_options_validate, +}; + +/** + * Invoked from subsysmgr.c when a new set of options arrives. + **/ +static int +crypto_set_options(void *arg) +{ + const crypto_options_t *options = arg; + const bool hardware_accel = options->HardwareAccel || options->AccelName; + + // This call already checks for crypto_global_initialized_, so it + // will only initialize the subsystem the first time it's called. + if (crypto_global_init(hardware_accel, + options->AccelName, + options->AccelDir)) { + log_err(LD_BUG, "Unable to initialize the crypto subsystem. Exiting."); + return -1; + } + return 0; +} + const struct subsys_fns_t sys_crypto = { .name = "crypto", .supported = true, @@ -261,4 +324,7 @@ const struct subsys_fns_t sys_crypto = { .prefork = subsys_crypto_prefork, .postfork = subsys_crypto_postfork, .thread_cleanup = subsys_crypto_thread_cleanup, + + .options_format = &crypto_options_fmt, + .set_options = crypto_set_options, }; diff --git a/src/lib/crypt_ops/crypto_init.h b/src/lib/crypt_ops/crypto_init.h index 8de3eb03ed..b11e2e34bf 100644 --- a/src/lib/crypt_ops/crypto_init.h +++ b/src/lib/crypt_ops/crypto_init.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_nss_mgt.c b/src/lib/crypt_ops/crypto_nss_mgt.c index 0179126e38..d82e51249c 100644 --- a/src/lib/crypt_ops/crypto_nss_mgt.c +++ b/src/lib/crypt_ops/crypto_nss_mgt.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -16,7 +16,7 @@ #include "lib/log/util_bug.h" #include "lib/string/printf.h" -DISABLE_GCC_WARNING(strict-prototypes) +DISABLE_GCC_WARNING("-Wstrict-prototypes") #include <nss.h> #include <pk11func.h> #include <ssl.h> @@ -24,7 +24,7 @@ DISABLE_GCC_WARNING(strict-prototypes) #include <prerror.h> #include <prtypes.h> #include <prinit.h> -ENABLE_GCC_WARNING(strict-prototypes) +ENABLE_GCC_WARNING("-Wstrict-prototypes") const char * crypto_nss_get_version_str(void) diff --git a/src/lib/crypt_ops/crypto_nss_mgt.h b/src/lib/crypt_ops/crypto_nss_mgt.h index 4cfa9b42a4..8686b1b8aa 100644 --- a/src/lib/crypt_ops/crypto_nss_mgt.h +++ b/src/lib/crypt_ops/crypto_nss_mgt.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_ope.c b/src/lib/crypt_ops/crypto_ope.c index ed832d852e..4cacb3dd98 100644 --- a/src/lib/crypt_ops/crypto_ope.c +++ b/src/lib/crypt_ops/crypto_ope.c @@ -1,8 +1,9 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** - * A rudimentary order-preserving encryption scheme. + * @file crypto_ope.c + * @brief A rudimentary order-preserving encryption scheme. * * To compute the encryption of N, this scheme uses an AES-CTR stream to * generate M-byte values, and adds the first N of them together. (+1 each to @@ -143,7 +144,7 @@ crypto_ope_new(const uint8_t *key) return ope; } -/** Free all storage held in <>ope</b>. */ +/** Free all storage held in <b>ope</b>. */ void crypto_ope_free_(crypto_ope_t *ope) { diff --git a/src/lib/crypt_ops/crypto_ope.h b/src/lib/crypt_ops/crypto_ope.h index 9778dfe0f0..7498ea6a2e 100644 --- a/src/lib/crypt_ops/crypto_ope.h +++ b/src/lib/crypt_ops/crypto_ope.h @@ -1,6 +1,11 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file crypto_ope.h + * @brief header for crypto_ope.c + **/ + #ifndef CRYPTO_OPE_H #define CRYPTO_OPE_H @@ -37,10 +42,10 @@ void crypto_ope_free_(crypto_ope_t *ope); uint64_t crypto_ope_encrypt(const crypto_ope_t *ope, int plaintext); #ifdef CRYPTO_OPE_PRIVATE -struct aes_cnt_cipher; -STATIC struct aes_cnt_cipher *ope_get_cipher(const crypto_ope_t *ope, +struct aes_cnt_cipher_t; +STATIC struct aes_cnt_cipher_t *ope_get_cipher(const crypto_ope_t *ope, uint32_t initial_idx); -STATIC uint64_t sum_values_from_cipher(struct aes_cnt_cipher *c, size_t n); +STATIC uint64_t sum_values_from_cipher(struct aes_cnt_cipher_t *c, size_t n); #endif /* defined(CRYPTO_OPE_PRIVATE) */ #endif /* !defined(CRYPTO_OPE_H) */ diff --git a/src/lib/crypt_ops/crypto_openssl_mgt.c b/src/lib/crypt_ops/crypto_openssl_mgt.c index f51309219a..f2f5a55d05 100644 --- a/src/lib/crypt_ops/crypto_openssl_mgt.c +++ b/src/lib/crypt_ops/crypto_openssl_mgt.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -21,7 +21,7 @@ #include "lib/testsupport/testsupport.h" #include "lib/thread/threads.h" -DISABLE_GCC_WARNING(redundant-decls) +DISABLE_GCC_WARNING("-Wredundant-decls") #include <openssl/err.h> #include <openssl/rsa.h> @@ -36,7 +36,7 @@ DISABLE_GCC_WARNING(redundant-decls) #include <openssl/crypto.h> #include <openssl/ssl.h> -ENABLE_GCC_WARNING(redundant-decls) +ENABLE_GCC_WARNING("-Wredundant-decls") #include <string.h> @@ -121,10 +121,12 @@ crypto_openssl_get_header_version_str(void) return crypto_openssl_header_version_str; } +#ifndef COCCI #ifndef OPENSSL_THREADS -#error OpenSSL has been built without thread support. Tor requires an \ - OpenSSL library with thread support enabled. +#error "OpenSSL has been built without thread support. Tor requires an \ + OpenSSL library with thread support enabled." #endif +#endif /* !defined(COCCI) */ #ifndef NEW_THREAD_API /** Helper: OpenSSL uses this callback to manipulate mutexes. */ @@ -273,8 +275,14 @@ log_engine(const char *fn, ENGINE *e) } #endif /* !defined(DISABLE_ENGINES) */ -/** Initialize engines for openssl (if enabled). */ -static void +/** Initialize engines for openssl (if enabled). Load all the built-in + * engines, along with the one called <b>accelName</b> (which may be NULL). + * If <b>accelName</b> is prefixed with "!", then it is required: return -1 + * if it can't be loaded. Otherwise return 0. + * + * If <b>accelDir</b> is not NULL, it is the path from which the engine should + * be loaded. */ +static int crypto_openssl_init_engines(const char *accelName, const char *accelDir) { @@ -282,7 +290,13 @@ crypto_openssl_init_engines(const char *accelName, (void)accelName; (void)accelDir; log_warn(LD_CRYPTO, "No OpenSSL hardware acceleration support enabled."); -#else + if (accelName && accelName[0] == '!') { + log_warn(LD_CRYPTO, "Unable to load required dynamic OpenSSL engine " + "\"%s\".", accelName+1); + return -1; + } + return 0; +#else /* !defined(DISABLE_ENGINES) */ ENGINE *e = NULL; log_info(LD_CRYPTO, "Initializing OpenSSL engine support."); @@ -290,6 +304,9 @@ crypto_openssl_init_engines(const char *accelName, ENGINE_register_all_complete(); if (accelName) { + const bool required = accelName[0] == '!'; + if (required) + ++accelName; if (accelDir) { log_info(LD_CRYPTO, "Trying to load dynamic OpenSSL engine \"%s\"" " via path \"%s\".", accelName, accelDir); @@ -300,8 +317,11 @@ crypto_openssl_init_engines(const char *accelName, e = ENGINE_by_id(accelName); } if (!e) { - log_warn(LD_CRYPTO, "Unable to load dynamic OpenSSL engine \"%s\".", + log_warn(LD_CRYPTO, "Unable to load %sdynamic OpenSSL engine \"%s\".", + required?"required ":"", accelName); + if (required) + return -1; } else { log_info(LD_CRYPTO, "Loaded dynamic OpenSSL engine \"%s\".", accelName); @@ -338,6 +358,7 @@ crypto_openssl_init_engines(const char *accelName, #ifdef NID_aes_256_gcm log_engine("AES-256-GCM", ENGINE_get_cipher_engine(NID_aes_256_gcm)); #endif + return 0; #endif /* defined(DISABLE_ENGINES) */ } @@ -348,7 +369,8 @@ crypto_openssl_late_init(int useAccel, const char *accelName, const char *accelDir) { if (useAccel > 0) { - crypto_openssl_init_engines(accelName, accelDir); + if (crypto_openssl_init_engines(accelName, accelDir) < 0) + return -1; } else { log_info(LD_CRYPTO, "NOT using OpenSSL engine support."); } @@ -377,7 +399,7 @@ crypto_openssl_thread_cleanup(void) void crypto_openssl_global_cleanup(void) { - #ifndef OPENSSL_1_1_API +#ifndef OPENSSL_1_1_API EVP_cleanup(); #endif #ifndef NEW_THREAD_API diff --git a/src/lib/crypt_ops/crypto_openssl_mgt.h b/src/lib/crypt_ops/crypto_openssl_mgt.h index 111a2d12ed..083df00033 100644 --- a/src/lib/crypt_ops/crypto_openssl_mgt.h +++ b/src/lib/crypt_ops/crypto_openssl_mgt.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_options.inc b/src/lib/crypt_ops/crypto_options.inc new file mode 100644 index 0000000000..5bee0daacd --- /dev/null +++ b/src/lib/crypt_ops/crypto_options.inc @@ -0,0 +1,19 @@ + +/** + * @file crypto_options.inc + * @brief Declare configuration options for the crypto_ops module. + **/ + +/** Holds configuration about our cryptography options. */ +BEGIN_CONF_STRUCT(crypto_options_t) + +/** Should we enable extra OpenSSL hardware acceleration (where available)? */ +CONF_VAR(HardwareAccel, BOOL, CFLG_IMMUTABLE, "0") + +/** Optional OpenSSL hardware-acceleration engine name */ +CONF_VAR(AccelName, STRING, CFLG_IMMUTABLE, NULL) + +/** Optional OpenSSL hardware-acceleration engine search directory. */ +CONF_VAR(AccelDir, FILENAME, CFLG_IMMUTABLE, NULL) + +END_CONF_STRUCT(crypto_options_t) diff --git a/src/lib/crypt_ops/crypto_options_st.h b/src/lib/crypt_ops/crypto_options_st.h new file mode 100644 index 0000000000..a453c451fe --- /dev/null +++ b/src/lib/crypt_ops/crypto_options_st.h @@ -0,0 +1,23 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2020, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file crypto_options_st.h + * @brief Header for lib/crypt_ops/crypto_options_st.c + **/ + +#ifndef TOR_LIB_CRYPT_OPS_CRYPTO_OPTIONS_ST_H +#define TOR_LIB_CRYPT_OPS_CRYPTO_OPTIONS_ST_H + +#include "lib/conf/confdecl.h" + +#define CONF_CONTEXT STRUCT +#include "lib/crypt_ops/crypto_options.inc" +#undef CONF_CONTEXT + +typedef struct crypto_options_t crypto_options_t; + +#endif /* !defined(TOR_LIB_CRYPT_OPS_CRYPTO_OPTIONS_ST_H) */ diff --git a/src/lib/crypt_ops/crypto_pwbox.c b/src/lib/crypt_ops/crypto_pwbox.c index a8db08f7b7..bfad27d9fc 100644 --- a/src/lib/crypt_ops/crypto_pwbox.c +++ b/src/lib/crypt_ops/crypto_pwbox.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2019, The Tor Project, Inc. */ +/* Copyright (c) 2014-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_pwbox.h b/src/lib/crypt_ops/crypto_pwbox.h index 5a26889fb2..0a85b1230a 100644 --- a/src/lib/crypt_ops/crypto_pwbox.h +++ b/src/lib/crypt_ops/crypto_pwbox.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2019, The Tor Project, Inc. */ +/* Copyright (c) 2014-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_rand.c b/src/lib/crypt_ops/crypto_rand.c index afbafbfa35..ac5f10da64 100644 --- a/src/lib/crypt_ops/crypto_rand.c +++ b/src/lib/crypt_ops/crypto_rand.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -43,10 +43,10 @@ #endif #ifdef ENABLE_OPENSSL -DISABLE_GCC_WARNING(redundant-decls) +DISABLE_GCC_WARNING("-Wredundant-decls") #include <openssl/rand.h> #include <openssl/sha.h> -ENABLE_GCC_WARNING(redundant-decls) +ENABLE_GCC_WARNING("-Wredundant-decls") #endif /* defined(ENABLE_OPENSSL) */ #ifdef ENABLE_NSS diff --git a/src/lib/crypt_ops/crypto_rand.h b/src/lib/crypt_ops/crypto_rand.h index a019287aa9..99aff5d4a9 100644 --- a/src/lib/crypt_ops/crypto_rand.h +++ b/src/lib/crypt_ops/crypto_rand.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_rand_fast.c b/src/lib/crypt_ops/crypto_rand_fast.c index e6ceb42ccb..172ea48bdb 100644 --- a/src/lib/crypt_ops/crypto_rand_fast.c +++ b/src/lib/crypt_ops/crypto_rand_fast.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -32,7 +32,6 @@ * request. */ -#define CRYPTO_RAND_FAST_PRIVATE #define CRYPTO_PRIVATE #include "lib/crypt_ops/crypto_rand.h" @@ -102,16 +101,16 @@ struct crypto_fast_rng_t { * crypto_strongest_rand(). */ int16_t n_till_reseed; - /** How many bytes are remaining in cbuf.bytes? */ + /** How many bytes are remaining in cbuf_t.bytes? */ uint16_t bytes_left; #ifdef CHECK_PID /** Which process owns this fast_rng? If this value is zero, we do not * need to test the owner. */ pid_t owner; #endif - struct cbuf { + struct cbuf_t { /** The seed (key and IV) that we will use the next time that we refill - * cbuf. */ + * cbuf_t. */ uint8_t seed[SEED_LEN]; /** * Bytes that we are yielding to the user. The next byte to be @@ -122,9 +121,9 @@ struct crypto_fast_rng_t { } buf; }; -/* alignof(uint8_t) should be 1, so there shouldn't be any padding in cbuf. +/* alignof(uint8_t) should be 1, so there shouldn't be any padding in cbuf_t. */ -CTASSERT(sizeof(struct cbuf) == BUFLEN+SEED_LEN); +CTASSERT(sizeof(struct cbuf_t) == BUFLEN+SEED_LEN); /* We're trying to fit all of the RNG state into a nice mmapable chunk. */ CTASSERT(sizeof(crypto_fast_rng_t) <= MAPLEN); diff --git a/src/lib/crypt_ops/crypto_rsa.c b/src/lib/crypt_ops/crypto_rsa.c index 1289a82e62..195e4bbaf9 100644 --- a/src/lib/crypt_ops/crypto_rsa.c +++ b/src/lib/crypt_ops/crypto_rsa.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_rsa.h b/src/lib/crypt_ops/crypto_rsa.h index 01e6d10906..ab2e9db80d 100644 --- a/src/lib/crypt_ops/crypto_rsa.h +++ b/src/lib/crypt_ops/crypto_rsa.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_rsa_nss.c b/src/lib/crypt_ops/crypto_rsa_nss.c index fd8fda486e..66f325e868 100644 --- a/src/lib/crypt_ops/crypto_rsa_nss.c +++ b/src/lib/crypt_ops/crypto_rsa_nss.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -645,7 +645,7 @@ crypto_pk_asn1_decode(const char *str, size_t len) return result; } -DISABLE_GCC_WARNING(unused-parameter) +DISABLE_GCC_WARNING("-Wunused-parameter") /** Given a crypto_pk_t <b>pk</b>, allocate a new buffer containing the Base64 * encoding of the DER representation of the private key into the diff --git a/src/lib/crypt_ops/crypto_rsa_openssl.c b/src/lib/crypt_ops/crypto_rsa_openssl.c index 41d936d25b..d54db43b92 100644 --- a/src/lib/crypt_ops/crypto_rsa_openssl.c +++ b/src/lib/crypt_ops/crypto_rsa_openssl.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -16,7 +16,7 @@ #include "lib/log/util_bug.h" #include "lib/fs/files.h" -DISABLE_GCC_WARNING(redundant-decls) +DISABLE_GCC_WARNING("-Wredundant-decls") #include <openssl/err.h> #include <openssl/rsa.h> @@ -27,7 +27,7 @@ DISABLE_GCC_WARNING(redundant-decls) #include <openssl/bn.h> #include <openssl/conf.h> -ENABLE_GCC_WARNING(redundant-decls) +ENABLE_GCC_WARNING("-Wredundant-decls") #include "lib/log/log.h" #include "lib/encoding/binascii.h" diff --git a/src/lib/crypt_ops/crypto_s2k.c b/src/lib/crypt_ops/crypto_s2k.c index 361db18927..3a9ed5ef58 100644 --- a/src/lib/crypt_ops/crypto_s2k.c +++ b/src/lib/crypt_ops/crypto_s2k.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -380,7 +380,7 @@ secret_to_key_derivekey(uint8_t *key_out, size_t key_out_len, #ifndef HAVE_SCRYPT if (type == S2K_TYPE_SCRYPT) return S2K_NO_SCRYPT_SUPPORT; - #endif +#endif if (! legacy_format) { ++spec; diff --git a/src/lib/crypt_ops/crypto_s2k.h b/src/lib/crypt_ops/crypto_s2k.h index a16a3d781e..181a17acb1 100644 --- a/src/lib/crypt_ops/crypto_s2k.h +++ b/src/lib/crypt_ops/crypto_s2k.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/crypto_sys.h b/src/lib/crypt_ops/crypto_sys.h index 894243b175..2115d4fc99 100644 --- a/src/lib/crypt_ops/crypto_sys.h +++ b/src/lib/crypt_ops/crypto_sys.h @@ -1,8 +1,8 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** - * \file log_crypto.h + * \file crypto_sys.h * \brief Declare subsystem object for the crypto module. **/ diff --git a/src/lib/crypt_ops/crypto_util.c b/src/lib/crypt_ops/crypto_util.c index 5e3f4a87a1..60e81af165 100644 --- a/src/lib/crypt_ops/crypto_util.c +++ b/src/lib/crypt_ops/crypto_util.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -10,8 +10,6 @@ * \brief Common cryptographic utilities. **/ -#define CRYPTO_UTIL_PRIVATE - #include "lib/crypt_ops/crypto_util.h" #include "lib/cc/compat_compiler.h" @@ -26,10 +24,10 @@ #include <stdlib.h> #ifdef ENABLE_OPENSSL -DISABLE_GCC_WARNING(redundant-decls) +DISABLE_GCC_WARNING("-Wredundant-decls") #include <openssl/err.h> #include <openssl/crypto.h> -ENABLE_GCC_WARNING(redundant-decls) +ENABLE_GCC_WARNING("-Wredundant-decls") #endif /* defined(ENABLE_OPENSSL) */ #include "lib/log/log.h" diff --git a/src/lib/crypt_ops/crypto_util.h b/src/lib/crypt_ops/crypto_util.h index 613a1bd0dd..4c08180f92 100644 --- a/src/lib/crypt_ops/crypto_util.h +++ b/src/lib/crypt_ops/crypto_util.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/digestset.c b/src/lib/crypt_ops/digestset.c index c931b58369..5162d6d8bd 100644 --- a/src/lib/crypt_ops/digestset.c +++ b/src/lib/crypt_ops/digestset.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/digestset.h b/src/lib/crypt_ops/digestset.h index 7d6d687342..505ac10395 100644 --- a/src/lib/crypt_ops/digestset.h +++ b/src/lib/crypt_ops/digestset.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/crypt_ops/include.am b/src/lib/crypt_ops/include.am index 1f58a33d38..7644cab412 100644 --- a/src/lib/crypt_ops/include.am +++ b/src/lib/crypt_ops/include.am @@ -68,6 +68,8 @@ noinst_HEADERS += \ src/lib/crypt_ops/crypto_nss_mgt.h \ src/lib/crypt_ops/crypto_openssl_mgt.h \ src/lib/crypt_ops/crypto_ope.h \ + src/lib/crypt_ops/crypto_options.inc \ + src/lib/crypt_ops/crypto_options_st.h \ src/lib/crypt_ops/crypto_pwbox.h \ src/lib/crypt_ops/crypto_rand.h \ src/lib/crypt_ops/crypto_rsa.h \ diff --git a/src/lib/crypt_ops/lib_crypt_ops.md b/src/lib/crypt_ops/lib_crypt_ops.md new file mode 100644 index 0000000000..4e675e4871 --- /dev/null +++ b/src/lib/crypt_ops/lib_crypt_ops.md @@ -0,0 +1,137 @@ +@dir /lib/crypt_ops +@brief lib/crypt_ops: Cryptographic operations. + +This module contains wrappers around the cryptographic libraries that we +support, and implementations for some higher-level cryptographic +constructions that we use. + +It wraps our two major cryptographic backends (OpenSSL or NSS, as configured +by the user), and also wraps other cryptographic code in src/ext. + +Generally speaking, Tor code shouldn't be calling OpenSSL or NSS +(or any other crypto library) directly. Instead, we should indirect through +one of the functions in this directory, or through \refdir{lib/tls}. + +Cryptography functionality that's available is described below. + +### RNG facilities ### + +The most basic RNG capability in Tor is the crypto_rand() family of +functions. These currently use OpenSSL's RAND_() backend, but may use +something faster in the future. + +In addition to crypto_rand(), which fills in a buffer with random +bytes, we also have functions to produce random integers in certain +ranges; to produce random hostnames; to produce random doubles, etc. + +When you're creating a long-term cryptographic secret, you might want +to use crypto_strongest_rand() instead of crypto_rand(). It takes the +operating system's entropy source and combines it with output from +crypto_rand(). This is a pure paranoia measure, but it might help us +someday. + +You can use smartlist_choose() to pick a random element from a smartlist +and smartlist_shuffle() to randomize the order of a smartlist. Both are +potentially a bit slow. + +### Cryptographic digests and related functions ### + +We treat digests as separate types based on the length of their +outputs. We support one 160-bit digest (SHA1), two 256-bit digests +(SHA256 and SHA3-256), and two 512-bit digests (SHA512 and SHA3-512). + +You should not use SHA1 for anything new. + +The crypto_digest\*() family of functions manipulates digests. You +can either compute a digest of a chunk of memory all at once using +crypto_digest(), crypto_digest256(), or crypto_digest512(). Or you +can create a crypto_digest_t object with +crypto_digest{,256,512}_new(), feed information to it in chunks using +crypto_digest_add_bytes(), and then extract the final digest using +crypto_digest_get_digest(). You can copy the state of one of these +objects using crypto_digest_dup() or crypto_digest_assign(). + +We support the HMAC hash-based message authentication code +instantiated using SHA256. See crypto_hmac_sha256. (You should not +add any HMAC users with SHA1, and HMAC is not necessary with SHA3.) + +We also support the SHA3 cousins, SHAKE128 and SHAKE256. Unlike +digests, these are extendable output functions (or XOFs) where you can +get any amount of output. Use the crypto_xof_\*() functions to access +these. + +We have several ways to derive keys from cryptographically strong secret +inputs (like diffie-hellman outputs). The old +crypto_expand_key_material_TAP() performs an ad-hoc KDF based on SHA1 -- you +shouldn't use it for implementing anything but old versions of the Tor +protocol. You can use HKDF-SHA256 (as defined in RFC5869) for more modern +protocols. Also consider SHAKE256. + +If your input is potentially weak, like a password or passphrase, use a salt +along with the secret_to_key() functions as defined in crypto_s2k.c. Prefer +scrypt over other hashing methods when possible. If you're using a password +to encrypt something, see the "boxed file storage" section below. + +Finally, in order to store objects in hash tables, Tor includes the +randomized SipHash 2-4 function. Call it via the siphash24g() function in +src/ext/siphash.h whenever you're creating a hashtable whose keys may be +manipulated by an attacker in order to DoS you with collisions. + + +### Stream ciphers ### + +You can create instances of a stream cipher using crypto_cipher_new(). +These are stateful objects of type crypto_cipher_t. Note that these +objects only support AES-128 right now; a future version should add +support for AES-128 and/or ChaCha20. + +You can encrypt/decrypt with crypto_cipher_encrypt or +crypto_cipher_decrypt. The crypto_cipher_crypt_inplace function performs +an encryption without a copy. + +Note that sensible people should not use raw stream ciphers; they should +probably be using some kind of AEAD. Sorry. + +### Public key functionality ### + +We support four public key algorithms: DH1024, RSA, Curve25519, and +Ed25519. + +We support DH1024 over two prime groups. You access these via the +crypto_dh_\*() family of functions. + +We support RSA in many bit sizes for signing and encryption. You access +it via the crypto_pk_*() family of functions. Note that a crypto_pk_t +may or may not include a private key. See the crypto_pk_* functions in +crypto.c for a full list of functions here. + +For Curve25519 functionality, see the functions and types in +crypto_curve25519.c. Curve25519 is generally suitable for when you need +a secure fast elliptic-curve diffie hellman implementation. When +designing new protocols, prefer it over DH in Z_p. + +For Ed25519 functionality, see the functions and types in +crypto_ed25519.c. Ed25519 is a generally suitable as a secure fast +elliptic curve signature method. For new protocols, prefer it over RSA +signatures. + +### Metaformats for storage ### + +When OpenSSL manages the storage of some object, we use whatever format +OpenSSL provides -- typically, some kind of PEM-wrapped base 64 encoding +that starts with "----- BEGIN CRYPTOGRAPHIC OBJECT ----". + +When we manage the storage of some cryptographic object, we prefix the +object with 32-byte NUL-padded prefix in order to avoid accidental +object confusion; see the crypto_read_tagged_contents_from_file() and +crypto_write_tagged_contents_to_file() functions for manipulating +these. The prefix is "== type: tag ==", where type describes the object +and its encoding, and tag indicates which one it is. + +### Boxed-file storage ### + +When managing keys, you frequently want to have some way to write a +secret object to disk, encrypted with a passphrase. The crypto_pwbox +and crypto_unpwbox functions do so in a way that's likely to be +readable by future versions of Tor. + diff --git a/src/lib/ctime/di_ops.c b/src/lib/ctime/di_ops.c index 89e0837ae9..7448a9973e 100644 --- a/src/lib/ctime/di_ops.c +++ b/src/lib/ctime/di_ops.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2019, The Tor Project, Inc. */ +/* Copyright (c) 2011-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -145,8 +145,11 @@ tor_memeq(const void *a, const void *b, size_t sz) /* Implement di_digest256_map_t as a linked list of entries. */ struct di_digest256_map_t { + /** Pointer to the next entry in the list. */ struct di_digest256_map_t *next; + /** Key for this entry. */ uint8_t key[32]; + /** Value for this entry. */ void *val; }; diff --git a/src/lib/ctime/di_ops.h b/src/lib/ctime/di_ops.h index 264b56a8c1..4ff8f03165 100644 --- a/src/lib/ctime/di_ops.h +++ b/src/lib/ctime/di_ops.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -16,6 +16,8 @@ int tor_memcmp(const void *a, const void *b, size_t sz); int tor_memeq(const void *a, const void *b, size_t sz); +/** Perform a constant-time comparison of the <b>sz</b> bytes at <b>a</b> and + * <b>b</b>, yielding true if they are different, and false otherwise. */ #define tor_memneq(a,b,sz) (!tor_memeq((a),(b),(sz))) /** Alias for the platform's memcmp() function. This function is @@ -24,7 +26,19 @@ int tor_memeq(const void *a, const void *b, size_t sz); * implementation. */ #define fast_memcmp(a,b,c) (memcmp((a),(b),(c))) +/** Alias for the platform's memcmp() function, for use in testing equality. + * + * This function is <em>not</em> data-independent: we define this alias so + * that we can mark cases where we are deliberately using a data-dependent + * memcmp() implementation. + */ #define fast_memeq(a,b,c) (0==memcmp((a),(b),(c))) +/** Alias for the platform's memcmp() function, for use in testing inequality. + * + * This function is <em>not</em> data-independent: we define this alias so + * that we can mark cases where we are deliberately using a data-dependent + * memcmp() implementation. + */ #define fast_memneq(a,b,c) (0!=memcmp((a),(b),(c))) int safe_mem_is_zero(const void *mem, size_t sz); @@ -35,9 +49,17 @@ int safe_mem_is_zero(const void *mem, size_t sz); * * Not efficient for large maps! */ typedef struct di_digest256_map_t di_digest256_map_t; +/** + * Type for a function used to free members of a di_digest256_map_t. + **/ typedef void (*dimap_free_fn)(void *); void dimap_free_(di_digest256_map_t *map, dimap_free_fn free_fn); +/** + * @copydoc dimap_free_ + * + * Additionally, set the pointer <b>map</b> to NULL. + **/ #define dimap_free(map, free_fn) \ do { \ dimap_free_((map), (free_fn)); \ @@ -52,4 +74,3 @@ int select_array_member_cumulative_timei(const uint64_t *entries, uint64_t total, uint64_t rand_val); #endif /* !defined(TOR_DI_OPS_H) */ - diff --git a/src/lib/ctime/lib_ctime.md b/src/lib/ctime/lib_ctime.md new file mode 100644 index 0000000000..913199f6a5 --- /dev/null +++ b/src/lib/ctime/lib_ctime.md @@ -0,0 +1,14 @@ +@dir /lib/ctime +@brief lib/ctime: Constant-time code to avoid side-channels. + +This module contains constant-time implementations of various +data comparison and table lookup functions. We use these in preference to +memcmp() and so forth, since memcmp() can leak information about its inputs +based on how fast it returns. In general, your code should call tor_memeq() +and tor_memneq(), not memcmp(). + +We also define some _non_-constant-time wrappers for memcmp() here: Since we +consider calls to memcmp() to be in error, we require that code that actually +doesn't need to be constant-time to use the fast_memeq() / fast_memneq() / +fast_memcmp() aliases instead. + diff --git a/src/lib/defs/dh_sizes.h b/src/lib/defs/dh_sizes.h index b0d1eba0c5..bc2707b36f 100644 --- a/src/lib/defs/dh_sizes.h +++ b/src/lib/defs/dh_sizes.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/defs/digest_sizes.h b/src/lib/defs/digest_sizes.h index a0dd97a74d..7eef1747db 100644 --- a/src/lib/defs/digest_sizes.h +++ b/src/lib/defs/digest_sizes.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_DIGEST_SIZES_H diff --git a/src/lib/defs/lib_defs.md b/src/lib/defs/lib_defs.md new file mode 100644 index 0000000000..5762e4550b --- /dev/null +++ b/src/lib/defs/lib_defs.md @@ -0,0 +1,2 @@ +@dir /lib/defs +@brief lib/defs: Lowest-level constants, used in many places. diff --git a/src/lib/defs/logging_types.h b/src/lib/defs/logging_types.h index d3eacde464..33aa46186b 100644 --- a/src/lib/defs/logging_types.h +++ b/src/lib/defs/logging_types.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/defs/time.h b/src/lib/defs/time.h index 459afbf42d..5707330795 100644 --- a/src/lib/defs/time.h +++ b/src/lib/defs/time.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_TIME_DEFS_H @@ -17,7 +17,7 @@ #define TOR_USEC_PER_SEC (1000000) /** How many nanoseconds per microsecond */ #define TOR_NSEC_PER_USEC (1000) -/* How many nanoseconds per millisecond */ +/** How many nanoseconds per millisecond */ #define TOR_NSEC_PER_MSEC (1000*1000) #endif /* !defined(TOR_TIME_DEFS_H) */ diff --git a/src/lib/defs/x25519_sizes.h b/src/lib/defs/x25519_sizes.h index 6431f0a2dd..acb08c5e6a 100644 --- a/src/lib/defs/x25519_sizes.h +++ b/src/lib/defs/x25519_sizes.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -23,14 +23,22 @@ /** Length of the result of a curve25519 handshake. */ #define CURVE25519_OUTPUT_LEN 32 +/** Length of an Ed25519 public key */ #define ED25519_PUBKEY_LEN 32 +/** Length of an Ed25519 secret key */ #define ED25519_SECKEY_LEN 64 +/** Length of the seed that is ordinarily expanded to an Ed25519 secret + * key. */ #define ED25519_SECKEY_SEED_LEN 32 +/** Length of an Ed25519 signature. */ #define ED25519_SIG_LEN 64 +/** Length of a Curve25519 key when encoded in base 64, with padding. */ #define CURVE25519_BASE64_PADDED_LEN 44 +/** Length of a Ed25519 key when encoded in base 64, without padding. */ #define ED25519_BASE64_LEN 43 +/** Length of a Ed25519 signature when encoded in base 64, without padding. */ #define ED25519_SIG_BASE64_LEN 86 #endif /* !defined(TOR_X25519_SIZES_H) */ diff --git a/src/lib/dispatch/dispatch.h b/src/lib/dispatch/dispatch.h index a9e655409a..9c7c4833c2 100644 --- a/src/lib/dispatch/dispatch.h +++ b/src/lib/dispatch/dispatch.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_DISPATCH_H diff --git a/src/lib/dispatch/dispatch_cfg.c b/src/lib/dispatch/dispatch_cfg.c index b3a72ec22f..a54188dcaa 100644 --- a/src/lib/dispatch/dispatch_cfg.c +++ b/src/lib/dispatch/dispatch_cfg.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/dispatch/dispatch_cfg.h b/src/lib/dispatch/dispatch_cfg.h index 348dce8d40..a4f1948eac 100644 --- a/src/lib/dispatch/dispatch_cfg.h +++ b/src/lib/dispatch/dispatch_cfg.h @@ -1,12 +1,17 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_DISPATCH_CFG_H #define TOR_DISPATCH_CFG_H +/** + * @file dispatch_cfg.h + * @brief Header for distpach_cfg.c + **/ + #include "lib/dispatch/msgtypes.h" #include "lib/testsupport/testsupport.h" diff --git a/src/lib/dispatch/dispatch_cfg_st.h b/src/lib/dispatch/dispatch_cfg_st.h index 57b6f0347f..3c99adf2f7 100644 --- a/src/lib/dispatch/dispatch_cfg_st.h +++ b/src/lib/dispatch/dispatch_cfg_st.h @@ -1,16 +1,24 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dispatch_cfg_st.h + * @brief Declarations for dispatch-configuration types. + **/ + #ifndef TOR_DISPATCH_CFG_ST_H #define TOR_DISPATCH_CFG_ST_H struct smartlist_t; -/* Information needed to create a dispatcher, but in a less efficient, more - * mutable format. */ +/** Information needed to create a dispatcher, but in a less efficient, more + * mutable format. + * + * Nearly everybody should use the \refdir{lib/pubsub} module to configure + * dispatchers, instead of using this. */ struct dispatch_cfg_t { /** A list of msg_type_id_t (cast to void*), indexed by msg_t. */ struct smartlist_t *type_by_msg; diff --git a/src/lib/dispatch/dispatch_core.c b/src/lib/dispatch/dispatch_core.c index da54f9b437..3d51c876a7 100644 --- a/src/lib/dispatch/dispatch_core.c +++ b/src/lib/dispatch/dispatch_core.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/dispatch/dispatch_naming.c b/src/lib/dispatch/dispatch_naming.c index 83d9a2d604..bb49343712 100644 --- a/src/lib/dispatch/dispatch_naming.c +++ b/src/lib/dispatch/dispatch_naming.c @@ -1,9 +1,14 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dispatch_naming.c + * @brief Name-to-ID maps for our message dispatch system. + **/ + #include "orconfig.h" #include "lib/cc/compat_compiler.h" @@ -33,6 +38,7 @@ dispatch_naming_init(void) { } +#ifndef COCCI /* Helper macro: declare functions to map IDs to and from names for a given * type in a namemap_t. */ @@ -56,6 +62,7 @@ dispatch_naming_init(void) return namemap_get_size(&type##_id_map); \ } \ EAT_SEMICOLON +#endif /* !defined(COCCI) */ DECLARE_ID_MAP_FNS(message); DECLARE_ID_MAP_FNS(channel); diff --git a/src/lib/dispatch/dispatch_naming.h b/src/lib/dispatch/dispatch_naming.h index fd6c83cc12..72206d3ed5 100644 --- a/src/lib/dispatch/dispatch_naming.h +++ b/src/lib/dispatch/dispatch_naming.h @@ -1,9 +1,14 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dispatch_naming.h + * @brief Header for dispatch_naming.c + **/ + #ifndef TOR_DISPATCH_NAMING_H #define TOR_DISPATCH_NAMING_H diff --git a/src/lib/dispatch/dispatch_new.c b/src/lib/dispatch/dispatch_new.c index d8e59d610a..e1dbb1c4b8 100644 --- a/src/lib/dispatch/dispatch_new.c +++ b/src/lib/dispatch/dispatch_new.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/dispatch/dispatch_st.h b/src/lib/dispatch/dispatch_st.h index ee42518b5a..ad5b4efc40 100644 --- a/src/lib/dispatch/dispatch_st.h +++ b/src/lib/dispatch/dispatch_st.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/dispatch/lib_dispatch.md b/src/lib/dispatch/lib_dispatch.md new file mode 100644 index 0000000000..153ca50080 --- /dev/null +++ b/src/lib/dispatch/lib_dispatch.md @@ -0,0 +1,14 @@ +@dir /lib/dispatch +@brief lib/dispatch: In-process message delivery. + +This module provides a general in-process "message dispatch" system in which +typed messages are sent on channels. The dispatch.h header has far more +information. + +It is used by by \refdir{lib/pubsub} to implement our general +inter-module publish/subscribe system. + +This is not a fancy multi-threaded many-to-many dispatcher as you may be used +to from more sophisticated architectures: this dispatcher is intended only +for use in improving Tor's architecture. + diff --git a/src/lib/dispatch/msgtypes.h b/src/lib/dispatch/msgtypes.h index b4c4a10248..01d969dcb5 100644 --- a/src/lib/dispatch/msgtypes.h +++ b/src/lib/dispatch/msgtypes.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/encoding/binascii.c b/src/lib/encoding/binascii.c index fc64e014e7..3e549eb8e3 100644 --- a/src/lib/encoding/binascii.c +++ b/src/lib/encoding/binascii.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/encoding/binascii.h b/src/lib/encoding/binascii.h index 40c5593b11..9cb03bab62 100644 --- a/src/lib/encoding/binascii.h +++ b/src/lib/encoding/binascii.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/encoding/confline.c b/src/lib/encoding/confline.c index 0d8384db13..ff8bacba3c 100644 --- a/src/lib/encoding/confline.c +++ b/src/lib/encoding/confline.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/encoding/confline.h b/src/lib/encoding/confline.h index 12c554c6e7..cd343e0e99 100644 --- a/src/lib/encoding/confline.h +++ b/src/lib/encoding/confline.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/encoding/cstring.c b/src/lib/encoding/cstring.c index 29d3714126..54c330fca3 100644 --- a/src/lib/encoding/cstring.c +++ b/src/lib/encoding/cstring.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/encoding/cstring.h b/src/lib/encoding/cstring.h index 904a2c9c1c..2a3f6d0fc4 100644 --- a/src/lib/encoding/cstring.h +++ b/src/lib/encoding/cstring.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/encoding/keyval.c b/src/lib/encoding/keyval.c index c5da5a0bfc..0eb1219d43 100644 --- a/src/lib/encoding/keyval.c +++ b/src/lib/encoding/keyval.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/encoding/keyval.h b/src/lib/encoding/keyval.h index dcddfa3396..b4966b01de 100644 --- a/src/lib/encoding/keyval.h +++ b/src/lib/encoding/keyval.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/encoding/kvline.c b/src/lib/encoding/kvline.c index d4a8f510ba..5b220605d6 100644 --- a/src/lib/encoding/kvline.c +++ b/src/lib/encoding/kvline.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -29,12 +29,20 @@ #include <string.h> /** Return true iff we need to quote and escape the string <b>s</b> to encode - * it. */ + * it. + * + * kvline_can_encode_lines() also uses this (with + * <b>as_keyless_val</b> true) to check whether a key would require + * quoting. + */ static bool needs_escape(const char *s, bool as_keyless_val) { if (as_keyless_val && *s == 0) return true; + /* Keyless values containing '=' need to be escaped. */ + if (as_keyless_val && strchr(s, '=')) + return true; for (; *s; ++s) { if (*s >= 127 || TOR_ISSPACE(*s) || ! TOR_ISPRINT(*s) || @@ -72,23 +80,17 @@ kvline_can_encode_lines(const config_line_t *line, unsigned flags) { for ( ; line; line = line->next) { const bool keyless = line_has_no_key(line); - if (keyless) { - if (! (flags & KV_OMIT_KEYS)) { - /* If KV_OMIT_KEYS is not set, we can't encode a line with no key. */ - return false; - } - if (strchr(line->value, '=') && !( flags & KV_QUOTED)) { - /* We can't have a keyless value with = without quoting it. */ - return false; - } + if (keyless && ! (flags & KV_OMIT_KEYS)) { + /* If KV_OMIT_KEYS is not set, we can't encode a line with no key. */ + return false; } - if (needs_escape(line->value, keyless) && ! (flags & KV_QUOTED)) { - /* If KV_QUOTED is false, we can't encode a value that needs quotes. */ + if (needs_escape(line->value, keyless) && ! (flags & (KV_QUOTED|KV_RAW))) { + /* If both KV_QUOTED and KV_RAW are false, we can't encode a + value that needs quotes. */ return false; } - if (line->key && strlen(line->key) && - (needs_escape(line->key, false) || strchr(line->key, '='))) { + if (!keyless && needs_escape(line->key, true)) { /* We can't handle keys that need quoting. */ return false; } @@ -103,7 +105,7 @@ kvline_can_encode_lines(const config_line_t *line, unsigned flags) * * If KV_QUOTED is set in <b>flags</b>, then all values that contain * spaces or unusual characters are escaped and quoted. Otherwise, such - * values are not allowed. + * values are not allowed. Mutually exclusive with KV_RAW. * * If KV_OMIT_KEYS is set in <b>flags</b>, then pairs with empty keys are * allowed, and are encoded as 'Value'. Otherwise, such pairs are not @@ -113,6 +115,11 @@ kvline_can_encode_lines(const config_line_t *line, unsigned flags) * encoded as 'Key', not as 'Key=' or 'Key=""'. Mutually exclusive with * KV_OMIT_KEYS. * + * If KV_RAW is set in <b>flags</b>, then don't apply any quoting to + * the value, and assume that the caller has adequately quoted it. + * (The control protocol has some quirks that make this necessary.) + * Mutually exclusive with KV_QUOTED. + * * KV_QUOTED_QSTRING is not supported. */ char * @@ -121,11 +128,12 @@ kvline_encode(const config_line_t *line, { tor_assert(! (flags & KV_QUOTED_QSTRING)); - if (!kvline_can_encode_lines(line, flags)) - return NULL; - tor_assert((flags & (KV_OMIT_KEYS|KV_OMIT_VALS)) != (KV_OMIT_KEYS|KV_OMIT_VALS)); + tor_assert((flags & (KV_QUOTED|KV_RAW)) != (KV_QUOTED|KV_RAW)); + + if (!kvline_can_encode_lines(line, flags)) + return NULL; smartlist_t *elements = smartlist_new(); @@ -142,15 +150,12 @@ kvline_encode(const config_line_t *line, k = line->key; } else { eq = ""; - if (strchr(line->value, '=')) { - esc = true; - } } if ((flags & KV_OMIT_VALS) && line_has_no_val(line)) { eq = ""; v = ""; - } else if (esc) { + } else if (!(flags & KV_RAW) && esc) { tmp = esc_for_log(line->value); v = tmp; } else { @@ -187,12 +192,15 @@ kvline_encode(const config_line_t *line, * If KV_QUOTED_QSTRING is set in <b>flags</b>, then double-quoted values * are allowed and handled as QuotedStrings per qstring.c. Do not add * new users of this flag. + * + * KV_RAW is not supported. */ config_line_t * kvline_parse(const char *line, unsigned flags) { tor_assert((flags & (KV_OMIT_KEYS|KV_OMIT_VALS)) != (KV_OMIT_KEYS|KV_OMIT_VALS)); + tor_assert(!(flags & KV_RAW)); const char *cp = line, *cplast = NULL; const bool omit_keys = (flags & KV_OMIT_KEYS) != 0; diff --git a/src/lib/encoding/kvline.h b/src/lib/encoding/kvline.h index dea2ce1809..34c52908e3 100644 --- a/src/lib/encoding/kvline.h +++ b/src/lib/encoding/kvline.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -19,6 +19,7 @@ struct config_line_t; #define KV_OMIT_KEYS (1u<<1) #define KV_OMIT_VALS (1u<<2) #define KV_QUOTED_QSTRING (1u<<3) +#define KV_RAW (1u<<4) struct config_line_t *kvline_parse(const char *line, unsigned flags); char *kvline_encode(const struct config_line_t *line, unsigned flags); diff --git a/src/lib/encoding/lib_encoding.md b/src/lib/encoding/lib_encoding.md new file mode 100644 index 0000000000..66dd9d8caf --- /dev/null +++ b/src/lib/encoding/lib_encoding.md @@ -0,0 +1,6 @@ +@dir /lib/encoding +@brief lib/encoding: Encoding data in various forms, types, and transformations + +Here we have time formats (timefmt.c), quoted strings (qstring.c), C strings +(string.c) base-16/32/64 (binascii.c), and more. + diff --git a/src/lib/encoding/pem.c b/src/lib/encoding/pem.c index 51f37d0840..6c9f10e085 100644 --- a/src/lib/encoding/pem.c +++ b/src/lib/encoding/pem.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -42,7 +42,7 @@ pem_encoded_size(size_t src_len, const char *objtype) /** * PEM-encode the <b>srclen</b>-byte object at <b>src</b> into the - * <b>destlen<\b>-byte buffer at <b>dest</b>, tagging it with <b>objtype</b>. + * <b>destlen</b>-byte buffer at <b>dest</b>, tagging it with <b>objtype</b>. * Return 0 on success and -1 on failure. */ int diff --git a/src/lib/encoding/pem.h b/src/lib/encoding/pem.h index 6b20350aa8..027c31c315 100644 --- a/src/lib/encoding/pem.h +++ b/src/lib/encoding/pem.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/encoding/qstring.c b/src/lib/encoding/qstring.c index a92d28c706..5a34924eab 100644 --- a/src/lib/encoding/qstring.c +++ b/src/lib/encoding/qstring.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/encoding/qstring.h b/src/lib/encoding/qstring.h index 840e1044ce..f19a7dad87 100644 --- a/src/lib/encoding/qstring.h +++ b/src/lib/encoding/qstring.h @@ -1,5 +1,5 @@ /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/encoding/time_fmt.c b/src/lib/encoding/time_fmt.c index 40543d41e0..573dfaad82 100644 --- a/src/lib/encoding/time_fmt.c +++ b/src/lib/encoding/time_fmt.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/encoding/time_fmt.h b/src/lib/encoding/time_fmt.h index d14bc1f902..80e47c5332 100644 --- a/src/lib/encoding/time_fmt.h +++ b/src/lib/encoding/time_fmt.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/err/backtrace.c b/src/lib/err/backtrace.c index ce8ddcd7c0..afb6b9503f 100644 --- a/src/lib/err/backtrace.c +++ b/src/lib/err/backtrace.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2019, The Tor Project, Inc. */ +/* Copyright (c) 2013-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -54,7 +54,7 @@ #include "lib/cc/ctassert.h" -#define EXPOSE_CLEAN_BACKTRACE +#define BACKTRACE_PRIVATE #include "lib/err/backtrace.h" #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \ diff --git a/src/lib/err/backtrace.h b/src/lib/err/backtrace.h index 7e09a0a5a7..d02e6960b5 100644 --- a/src/lib/err/backtrace.h +++ b/src/lib/err/backtrace.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2019, The Tor Project, Inc. */ +/* Copyright (c) 2013-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_BACKTRACE_H @@ -29,11 +29,11 @@ const char *get_tor_backtrace_version(void); #define log_backtrace(sev, dom, msg) \ log_backtrace_impl((sev), (dom), (msg), tor_log) -#ifdef EXPOSE_CLEAN_BACKTRACE +#ifdef BACKTRACE_PRIVATE #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \ defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) void clean_backtrace(void **stack, size_t depth, const ucontext_t *ctx); #endif -#endif /* defined(EXPOSE_CLEAN_BACKTRACE) */ +#endif /* defined(BACKTRACE_PRIVATE) */ #endif /* !defined(TOR_BACKTRACE_H) */ diff --git a/src/lib/err/lib_err.md b/src/lib/err/lib_err.md new file mode 100644 index 0000000000..cb4eba2e0d --- /dev/null +++ b/src/lib/err/lib_err.md @@ -0,0 +1,13 @@ +@dir /lib/err +@brief lib/err: Lowest-level error handling code. + +This module is responsible for generating stack traces, handling raw +assertion failures, and otherwise reporting problems that might not be +safe to report via the regular logging module. + +There are three kinds of users for the functions in this module: + * Code that needs a way to assert(), but which cannot use the regular + `tor_assert()` macros in logging module. + * Code that needs signal-safe error reporting. + * Higher-level error handling code. + diff --git a/src/lib/err/torerr.c b/src/lib/err/torerr.c index a5c00ca389..2de75c0be4 100644 --- a/src/lib/err/torerr.c +++ b/src/lib/err/torerr.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -151,6 +151,30 @@ tor_log_reset_sigsafe_err_fds(void) } /** + * Flush the list of fds that get errors from inside a signal handler or + * other emergency condition. These fds are shared with the logging code: + * flushing them also flushes the log buffers. + * + * This function is safe to call during signal handlers. + */ +void +tor_log_flush_sigsafe_err_fds(void) +{ + /* If we don't have fsync() in unistd.h, we can't flush the logs. */ +#ifdef HAVE_FSYNC + int n_fds, i; + const int *fds = NULL; + + n_fds = tor_log_get_sigsafe_err_fds(&fds); + for (i = 0; i < n_fds; ++i) { + /* This function is called on error and on shutdown, so we don't log, or + * take any other action, if fsync() fails. */ + (void)fsync(fds[i]); + } +#endif /* defined(HAVE_FSYNC) */ +} + +/** * Set the granularity (in ms) to use when reporting fatal errors outside * the logging system. */ @@ -191,12 +215,13 @@ tor_raw_assertion_failed_msg_(const char *file, int line, const char *expr, /** * Call the abort() function to kill the current process with a fatal - * error. This is a separate function, so that log users don't have to include - * the header for abort(). + * error. But first, flush the raw error file descriptors, so error messages + * are written before process termination. **/ void tor_raw_abort_(void) { + tor_log_flush_sigsafe_err_fds(); abort(); } diff --git a/src/lib/err/torerr.h b/src/lib/err/torerr.h index a1822d9c9a..ce1b049c47 100644 --- a/src/lib/err/torerr.h +++ b/src/lib/err/torerr.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -40,6 +40,7 @@ void tor_log_err_sigsafe(const char *m, ...); int tor_log_get_sigsafe_err_fds(const int **out); void tor_log_set_sigsafe_err_fds(const int *fds, int n); void tor_log_reset_sigsafe_err_fds(void); +void tor_log_flush_sigsafe_err_fds(void); void tor_log_sigsafe_err_set_granularity(int ms); void tor_raw_abort_(void) ATTR_NORETURN; diff --git a/src/lib/err/torerr_sys.c b/src/lib/err/torerr_sys.c index c42e958093..46fc853550 100644 --- a/src/lib/err/torerr_sys.c +++ b/src/lib/err/torerr_sys.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -27,8 +27,9 @@ subsys_torerr_initialize(void) static void subsys_torerr_shutdown(void) { - /* Stop handling signals with backtraces. */ + /* Stop handling signals with backtraces, then flush the logs. */ clean_up_backtrace_handler(); + tor_log_flush_sigsafe_err_fds(); } const subsys_fns_t sys_torerr = { diff --git a/src/lib/err/torerr_sys.h b/src/lib/err/torerr_sys.h index c947695689..b86ccd2790 100644 --- a/src/lib/err/torerr_sys.h +++ b/src/lib/err/torerr_sys.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/evloop/compat_libevent.c b/src/lib/evloop/compat_libevent.c index 939d77f857..0fd247d331 100644 --- a/src/lib/evloop/compat_libevent.c +++ b/src/lib/evloop/compat_libevent.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2019, The Tor Project, Inc. */ +/* Copyright (c) 2009-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -130,7 +130,7 @@ rescan_mainloop_cb(evutil_socket_t fd, short events, void *arg) /** Initialize the Libevent library and set up the event base. */ void -tor_libevent_initialize(tor_libevent_cfg *torcfg) +tor_libevent_initialize(tor_libevent_cfg_t *torcfg) { tor_assert(the_event_base == NULL); /* some paths below don't use torcfg, so avoid unused variable warnings */ @@ -432,7 +432,7 @@ mainloop_event_activate(mainloop_event_t *event) * * If the event is scheduled for a different time, cancel it and run * after this delay instead. If the event is currently pending to run - * <em>now</b>, has no effect. + * <b>now</b>, has no effect. * * Do not call this function with <b>tv</b> == NULL -- use * mainloop_event_activate() instead. diff --git a/src/lib/evloop/compat_libevent.h b/src/lib/evloop/compat_libevent.h index 92724c369c..277ba3add6 100644 --- a/src/lib/evloop/compat_libevent.h +++ b/src/lib/evloop/compat_libevent.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2019, The Tor Project, Inc. */ +/* Copyright (c) 2009-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -61,15 +61,15 @@ void mainloop_event_free_(mainloop_event_t *event); /** Defines a configuration for using libevent with Tor: passed as an argument * to tor_libevent_initialize() to describe how we want to set up. */ -typedef struct tor_libevent_cfg { +typedef struct tor_libevent_cfg_t { /** How many CPUs should we use (not currently useful). */ int num_cpus; /** How many milliseconds should we allow between updating bandwidth limits? * (Not currently useful). */ int msec_per_tick; -} tor_libevent_cfg; +} tor_libevent_cfg_t; -void tor_libevent_initialize(tor_libevent_cfg *cfg); +void tor_libevent_initialize(tor_libevent_cfg_t *cfg); bool tor_libevent_is_initialized(void); MOCK_DECL(struct event_base *, tor_libevent_get_base, (void)); const char *tor_libevent_get_method(void); diff --git a/src/lib/evloop/evloop_sys.c b/src/lib/evloop/evloop_sys.c index 56641a3175..fecec2f264 100644 --- a/src/lib/evloop/evloop_sys.c +++ b/src/lib/evloop/evloop_sys.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/evloop/evloop_sys.h b/src/lib/evloop/evloop_sys.h index e6155c25b0..a37440e7a6 100644 --- a/src/lib/evloop/evloop_sys.h +++ b/src/lib/evloop/evloop_sys.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/evloop/lib_evloop.md b/src/lib/evloop/lib_evloop.md new file mode 100644 index 0000000000..830be88148 --- /dev/null +++ b/src/lib/evloop/lib_evloop.md @@ -0,0 +1,7 @@ +@dir /lib/evloop +@brief lib/evloop: Low-level event loop. + +This modules has tools to manage the [libevent](https://libevent.org/) event +loop and related functionality, in order to implement asynchronous +networking, timers, periodic events, and other scheduling tasks. + diff --git a/src/lib/evloop/procmon.c b/src/lib/evloop/procmon.c index b2d81fc14b..718c7d4777 100644 --- a/src/lib/evloop/procmon.c +++ b/src/lib/evloop/procmon.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2019, The Tor Project, Inc. */ +/* Copyright (c) 2011-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -165,8 +165,8 @@ tor_validate_process_specifier(const char *process_spec, return parse_process_specifier(process_spec, &ppspec, msg); } -/* DOCDOC poll_interval_tv */ -static const struct timeval poll_interval_tv = {15, 0}; +/* We check this often for presence of owning controller process. */ +static const struct timeval poll_interval_tv = {15, 0}; // 15 seconds. /** Create a process-termination monitor for the process specifier * given in <b>process_spec</b>. Return a newly allocated diff --git a/src/lib/evloop/procmon.h b/src/lib/evloop/procmon.h index 6caae5be86..28f443da18 100644 --- a/src/lib/evloop/procmon.h +++ b/src/lib/evloop/procmon.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2019, The Tor Project, Inc. */ +/* Copyright (c) 2011-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/evloop/time_periodic.md b/src/lib/evloop/time_periodic.md new file mode 100644 index 0000000000..8b3589d9db --- /dev/null +++ b/src/lib/evloop/time_periodic.md @@ -0,0 +1,76 @@ + +@page time_periodic Time and periodic events in Tor + +### What time is it? ### + +We have several notions of the current time in Tor. + +The *wallclock time* is available from time(NULL) with +second-granularity and tor_gettimeofday() with microsecond +granularity. It corresponds most closely to "the current time and date". + +The *monotonic time* is available with the set of monotime_\* +functions declared in compat_time.h. Unlike the wallclock time, it +can only move forward. It does not necessarily correspond to a real +world time, and it is not portable between systems. + +The *coarse monotonic time* is available from the set of +monotime_coarse_\* functions in compat_time.h. It is the same as +monotime_\* on some platforms. On others, it gives a monotonic timer +with less precision, but which it's more efficient to access. + +### Cached views of time. ### + +On some systems (like Linux), many time functions use a VDSO to avoid +the overhead of a system call. But on other systems, gettimeofday() +and time() can be costly enough that you wouldn't want to call them +tens of thousands of times. To get a recent, but not especially +accurate, view of the current time, see approx_time() and +tor_gettimeofday_cached(). + + +### Parsing and encoding time values ### + +Tor has functions to parse and format time in these formats: + + - RFC1123 format. ("Fri, 29 Sep 2006 15:54:20 GMT"). For this, + use format_rfc1123_time() and parse_rfc1123_time. + + - ISO8601 format. ("2006-10-29 10:57:20") For this, use + format_local_iso_time() and format_iso_time(). We also support the + variant format "2006-10-29T10:57:20" with format_iso_time_nospace(), and + "2006-10-29T10:57:20.123456" with format_iso_time_nospace_usec(). + + - HTTP format collections (preferably "Mon, 25 Jul 2016 04:01:11 + GMT" or possibly "Wed Jun 30 21:49:08 1993" or even "25-Jul-16 + 04:01:11 GMT"). For this, use parse_http_time(). Don't generate anything + but the first format. + +Some of these functions use struct tm. You can use the standard +tor_localtime_r() and tor_gmtime_r() to wrap these in a safe way. We +also have a tor_timegm() function. + +### Scheduling events ### + +The main way to schedule a not-too-frequent periodic event with +respect to the Tor mainloop is via the mechanism in periodic.c. +There's a big table of periodic_events in mainloop.c, each of which gets +invoked on its own schedule. You should not expect more than about +one second of accuracy with these timers. + +You can create an independent timer using libevent directly, or using +the periodic_timer_new() function. But you should avoid doing this +for per-connection or per-circuit timers: Libevent's internal timer +implementation uses a min-heap, and those tend to start scaling poorly +once you have a few thousand entries. + +If you need to create a large number of fine-grained timers for some +purpose, you should consider the mechanism in src/common/timers.c, +which is optimized for the case where you have a large number of +timers with not-too-long duration, many of which will be deleted +before they actually expire. These timers should be reasonably +accurate within a handful of milliseconds -- possibly better on some +platforms. (The timers.c module uses William Ahern's timeout.c +implementation as its backend, which is based on a hierarchical timing +wheel algorithm. It's cool stuff; check it out.) + diff --git a/src/lib/evloop/timers.c b/src/lib/evloop/timers.c index 4b2a96ef7d..7be9bae08e 100644 --- a/src/lib/evloop/timers.c +++ b/src/lib/evloop/timers.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2019, The Tor Project, Inc. */ +/* Copyright (c) 2016-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -48,7 +48,7 @@ #include <winsock2.h> #endif -struct timeout_cb { +struct timeout_cb_t { timer_cb_fn_t cb; void *arg; }; @@ -56,19 +56,21 @@ struct timeout_cb { /* * These definitions are for timeouts.c and timeouts.h. */ -#ifdef __GNUC__ +#ifdef COCCI +#define TIMEOUT_PUBLIC +#elif defined(__GNUC__) /* We're not exposing any of the functions outside this file. */ #define TIMEOUT_PUBLIC __attribute__((__unused__)) static #else /* We're not exposing any of the functions outside this file. */ #define TIMEOUT_PUBLIC static -#endif /* defined(__GNUC__) */ +#endif /* defined(COCCI) || ... */ /* We're not using periodic events. */ #define TIMEOUT_DISABLE_INTERVALS /* We always know the global_timeouts object, so we don't need each timeout * to keep a pointer to it. */ #define TIMEOUT_DISABLE_RELATIVE_ACCESS -/* We're providing our own struct timeout_cb. */ +/* We're providing our own struct timeout_cb_t. */ #define TIMEOUT_CB_OVERRIDE /* We're going to support timers that are pretty far out in advance. Making * this big can be inefficient, but having a significant number of timers diff --git a/src/lib/evloop/timers.h b/src/lib/evloop/timers.h index 7595554204..dd55446121 100644 --- a/src/lib/evloop/timers.h +++ b/src/lib/evloop/timers.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2019, The Tor Project, Inc. */ +/* Copyright (c) 2016-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -13,6 +13,7 @@ #include "lib/testsupport/testsupport.h" struct monotime_t; +struct timeval; typedef struct timeout tor_timer_t; typedef void (*timer_cb_fn_t)(tor_timer_t *, void *, const struct monotime_t *); diff --git a/src/lib/evloop/token_bucket.c b/src/lib/evloop/token_bucket.c index ec62d1b018..a2b330fddb 100644 --- a/src/lib/evloop/token_bucket.c +++ b/src/lib/evloop/token_bucket.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/evloop/token_bucket.h b/src/lib/evloop/token_bucket.h index dde9bd65a4..460dad23e4 100644 --- a/src/lib/evloop/token_bucket.h +++ b/src/lib/evloop/token_bucket.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/evloop/workqueue.c b/src/lib/evloop/workqueue.c index 015b694290..603dddd5a3 100644 --- a/src/lib/evloop/workqueue.c +++ b/src/lib/evloop/workqueue.c @@ -44,13 +44,13 @@ #define WORKQUEUE_PRIORITY_LAST WQ_PRI_LOW #define WORKQUEUE_N_PRIORITIES (((int) WORKQUEUE_PRIORITY_LAST)+1) -TOR_TAILQ_HEAD(work_tailq_t, workqueue_entry_s); +TOR_TAILQ_HEAD(work_tailq_t, workqueue_entry_t); typedef struct work_tailq_t work_tailq_t; -struct threadpool_s { +struct threadpool_t { /** An array of pointers to workerthread_t: one for each running worker * thread. */ - struct workerthread_s **threads; + struct workerthread_t **threads; /** Condition variable that we wait on when we have no work, and which * gets signaled when our queue becomes nonempty. */ @@ -92,14 +92,14 @@ struct threadpool_s { /** Number of bits needed to hold all legal values of workqueue_priority_t */ #define WORKQUEUE_PRIORITY_BITS 2 -struct workqueue_entry_s { +struct workqueue_entry_t { /** The next workqueue_entry_t that's pending on the same thread or * reply queue. */ - TOR_TAILQ_ENTRY(workqueue_entry_s) next_work; + TOR_TAILQ_ENTRY(workqueue_entry_t) next_work; /** The threadpool to which this workqueue_entry_t was assigned. This field * is set when the workqueue_entry_t is created, and won't be cleared until * after it's handled in the main thread. */ - struct threadpool_s *on_pool; + struct threadpool_t *on_pool; /** True iff this entry is waiting for a worker to start processing it. */ uint8_t pending; /** Priority of this entry. */ @@ -112,22 +112,22 @@ struct workqueue_entry_s { void *arg; }; -struct replyqueue_s { +struct replyqueue_t { /** Mutex to protect the answers field */ tor_mutex_t lock; /** Doubly-linked list of answers that the reply queue needs to handle. */ - TOR_TAILQ_HEAD(, workqueue_entry_s) answers; + TOR_TAILQ_HEAD(, workqueue_entry_t) answers; /** Mechanism to wake up the main thread when it is receiving answers. */ alert_sockets_t alert; }; /** A worker thread represents a single thread in a thread pool. */ -typedef struct workerthread_s { +typedef struct workerthread_t { /** Which thread it this? In range 0..in_pool->n_threads-1 */ int index; /** The pool this thread is a part of. */ - struct threadpool_s *in_pool; + struct threadpool_t *in_pool; /** User-supplied state field that we pass to the worker functions of each * work item. */ void *state; diff --git a/src/lib/evloop/workqueue.h b/src/lib/evloop/workqueue.h index d0ee8f2be2..43cfebf788 100644 --- a/src/lib/evloop/workqueue.h +++ b/src/lib/evloop/workqueue.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2019, The Tor Project, Inc. */ +/* Copyright (c) 2013-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -13,12 +13,12 @@ /** A replyqueue is used to tell the main thread about the outcome of * work that we queued for the workers. */ -typedef struct replyqueue_s replyqueue_t; +typedef struct replyqueue_t replyqueue_t; /** A thread-pool manages starting threads and passing work to them. */ -typedef struct threadpool_s threadpool_t; +typedef struct threadpool_t threadpool_t; /** A workqueue entry represents a request that has been passed to a thread * pool. */ -typedef struct workqueue_entry_s workqueue_entry_t; +typedef struct workqueue_entry_t workqueue_entry_t; /** Possible return value from a work function: */ typedef enum workqueue_reply_t { diff --git a/src/lib/fdio/fdio.c b/src/lib/fdio/fdio.c index 2d0864cc19..56e3818f5c 100644 --- a/src/lib/fdio/fdio.c +++ b/src/lib/fdio/fdio.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -28,9 +28,10 @@ #include <stdlib.h> #include <stdio.h> -/** @{ */ -/** Some old versions of Unix didn't define constants for these values, +/* Some old versions of Unix didn't define constants for these values, * and instead expect you to say 0, 1, or 2. */ + +/** @cond */ #ifndef SEEK_SET #define SEEK_SET 0 #endif @@ -40,7 +41,7 @@ #ifndef SEEK_END #define SEEK_END 2 #endif -/** @} */ +/** @endcond */ /** Return the position of <b>fd</b> with respect to the start of the file. */ off_t diff --git a/src/lib/fdio/fdio.h b/src/lib/fdio/fdio.h index 8395af353b..99bc33c64b 100644 --- a/src/lib/fdio/fdio.h +++ b/src/lib/fdio/fdio.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -13,6 +13,9 @@ #define TOR_FDIO_H #include <stddef.h> +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif off_t tor_fd_getpos(int fd); int tor_fd_setpos(int fd, off_t pos); diff --git a/src/lib/fdio/lib_fdio.md b/src/lib/fdio/lib_fdio.md new file mode 100644 index 0000000000..9fe4b4d2be --- /dev/null +++ b/src/lib/fdio/lib_fdio.md @@ -0,0 +1,5 @@ +@dir /lib/fdio +@brief lib/fdio: Code to read/write on file descriptors. + +(This module also handles sockets, on platforms where a socket is not a kind +of fd.) diff --git a/src/lib/fs/conffile.c b/src/lib/fs/conffile.c index 0d5d56b335..392b2f4541 100644 --- a/src/lib/fs/conffile.c +++ b/src/lib/fs/conffile.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/fs/conffile.h b/src/lib/fs/conffile.h index 29115e1085..cbfe4ec7c9 100644 --- a/src/lib/fs/conffile.h +++ b/src/lib/fs/conffile.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_CONFFILE_H diff --git a/src/lib/fs/dir.c b/src/lib/fs/dir.c index 390836b048..3432df0299 100644 --- a/src/lib/fs/dir.c +++ b/src/lib/fs/dir.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/fs/dir.h b/src/lib/fs/dir.h index 9ff81faa42..c4ab430891 100644 --- a/src/lib/fs/dir.h +++ b/src/lib/fs/dir.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_DIR_H diff --git a/src/lib/fs/files.c b/src/lib/fs/files.c index b98a51a287..aeaeb5daea 100644 --- a/src/lib/fs/files.c +++ b/src/lib/fs/files.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/fs/files.h b/src/lib/fs/files.h index ed983f3b3c..a109cd6248 100644 --- a/src/lib/fs/files.h +++ b/src/lib/fs/files.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/fs/freespace.c b/src/lib/fs/freespace.c index ee0f93073d..511f2a0b98 100644 --- a/src/lib/fs/freespace.c +++ b/src/lib/fs/freespace.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/fs/lib_fs.md b/src/lib/fs/lib_fs.md new file mode 100644 index 0000000000..3b5b0ac7d5 --- /dev/null +++ b/src/lib/fs/lib_fs.md @@ -0,0 +1,9 @@ +@dir /lib/fs +@brief lib/fs: Files, filenames, directories, etc. + +This module is mostly a set of compatibility wrappers around +operating-system-specific filesystem access. + +It also contains a set of convenience functions for safely writing to files, +creating directories, and so on. + diff --git a/src/lib/fs/lockfile.c b/src/lib/fs/lockfile.c index 933ff1e02f..c081f57a5d 100644 --- a/src/lib/fs/lockfile.c +++ b/src/lib/fs/lockfile.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/fs/lockfile.h b/src/lib/fs/lockfile.h index fc0281e253..91effd701d 100644 --- a/src/lib/fs/lockfile.h +++ b/src/lib/fs/lockfile.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/fs/mmap.c b/src/lib/fs/mmap.c index f71c0cff7a..cc1c40b7ab 100644 --- a/src/lib/fs/mmap.c +++ b/src/lib/fs/mmap.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -42,8 +42,8 @@ * failure, return NULL. Sets errno properly, using ERANGE to mean * "empty file". Must only be called on trusted Tor-owned files, as changing * the underlying file's size causes unspecified behavior. */ -tor_mmap_t * -tor_mmap_file(const char *filename) +MOCK_IMPL(tor_mmap_t *, +tor_mmap_file,(const char *filename)) { int fd; /* router file */ char *string; @@ -111,8 +111,8 @@ tor_mmap_file(const char *filename) } /** Release storage held for a memory mapping; returns 0 on success, * or -1 on failure (and logs a warning). */ -int -tor_munmap_file(tor_mmap_t *handle) +MOCK_IMPL(int, +tor_munmap_file,(tor_mmap_t *handle)) { int res; @@ -132,8 +132,8 @@ tor_munmap_file(tor_mmap_t *handle) return res; } #elif defined(_WIN32) -tor_mmap_t * -tor_mmap_file(const char *filename) +MOCK_IMPL(tor_mmap_t *, +tor_mmap_file,(const char *filename)) { TCHAR tfilename[MAX_PATH]= {0}; tor_mmap_t *res = tor_malloc_zero(sizeof(tor_mmap_t)); @@ -213,8 +213,8 @@ tor_mmap_file(const char *filename) } /* Unmap the file, and return 0 for success or -1 for failure */ -int -tor_munmap_file(tor_mmap_t *handle) +MOCK_IMPL(int, +tor_munmap_file,(tor_mmap_t *handle)) { if (handle == NULL) return 0; diff --git a/src/lib/fs/mmap.h b/src/lib/fs/mmap.h index 61aad544b2..e142bd78c3 100644 --- a/src/lib/fs/mmap.h +++ b/src/lib/fs/mmap.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -13,6 +13,7 @@ #define TOR_MMAP_H #include "lib/cc/compat_compiler.h" +#include "lib/testsupport/testsupport.h" #include <stddef.h> #ifdef _WIN32 @@ -35,7 +36,7 @@ typedef struct tor_mmap_t { } tor_mmap_t; -tor_mmap_t *tor_mmap_file(const char *filename); -int tor_munmap_file(tor_mmap_t *handle); +MOCK_DECL(tor_mmap_t *, tor_mmap_file, (const char *filename)); +MOCK_DECL(int, tor_munmap_file, (tor_mmap_t *handle)); #endif /* !defined(TOR_MMAP_H) */ diff --git a/src/lib/fs/path.c b/src/lib/fs/path.c index 28dde62aea..0d57be4b06 100644 --- a/src/lib/fs/path.c +++ b/src/lib/fs/path.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -255,9 +255,10 @@ alloc_getcwd(void) #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>. */ + * Return a newly allocated string, which may be a duplicate of <b>fname</b>. + */ char * -make_path_absolute(char *fname) +make_path_absolute(const char *fname) { #ifdef _WIN32 char *absfname_malloced = _fullpath(NULL, fname, 1); diff --git a/src/lib/fs/path.h b/src/lib/fs/path.h index 28a1838b88..f0e253c556 100644 --- a/src/lib/fs/path.h +++ b/src/lib/fs/path.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -25,6 +25,6 @@ char *expand_filename(const char *filename); int path_is_relative(const char *filename); void clean_fname_for_stat(char *name); int get_parent_directory(char *fname); -char *make_path_absolute(char *fname); +char *make_path_absolute(const char *fname); #endif /* !defined(TOR_PATH_H) */ diff --git a/src/lib/fs/storagedir.c b/src/lib/fs/storagedir.c index 2caddf1ad9..5e4f9ee257 100644 --- a/src/lib/fs/storagedir.c +++ b/src/lib/fs/storagedir.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Tor Project, Inc. */ +/* Copyright (c) 2017-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/fs/storagedir.h b/src/lib/fs/storagedir.h index 7e6633a0bb..9997550b8f 100644 --- a/src/lib/fs/storagedir.h +++ b/src/lib/fs/storagedir.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Tor Project, Inc. */ +/* Copyright (c) 2017-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -15,7 +15,7 @@ typedef struct storage_dir_t storage_dir_t; struct config_line_t; -struct sandbox_cfg_elem; +struct sandbox_cfg_elem_t; struct tor_mmap_t; struct smartlist_t; @@ -25,7 +25,7 @@ void storage_dir_free_(storage_dir_t *d); FREE_AND_NULL(storage_dir_t, storage_dir_free_, (d)) int storage_dir_register_with_sandbox(storage_dir_t *d, - struct sandbox_cfg_elem **cfg); + struct sandbox_cfg_elem_t **cfg); const struct smartlist_t *storage_dir_list(storage_dir_t *d); uint64_t storage_dir_get_usage(storage_dir_t *d); struct tor_mmap_t *storage_dir_map(storage_dir_t *d, const char *fname); diff --git a/src/lib/fs/userdb.c b/src/lib/fs/userdb.c index 95205c670e..40fc4dae97 100644 --- a/src/lib/fs/userdb.c +++ b/src/lib/fs/userdb.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/fs/userdb.h b/src/lib/fs/userdb.h index 5e5ddb89a3..4341237c5f 100644 --- a/src/lib/fs/userdb.h +++ b/src/lib/fs/userdb.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/fs/winlib.c b/src/lib/fs/winlib.c index b7302bd4ca..65ccdae40b 100644 --- a/src/lib/fs/winlib.c +++ b/src/lib/fs/winlib.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/fs/winlib.h b/src/lib/fs/winlib.h index 7237226c76..27837ac46e 100644 --- a/src/lib/fs/winlib.h +++ b/src/lib/fs/winlib.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/geoip/country.h b/src/lib/geoip/country.h index a24a1c4c0d..feab554a16 100644 --- a/src/lib/geoip/country.h +++ b/src/lib/geoip/country.h @@ -1,9 +1,14 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file country.h + * @brief Country type for geoip. + **/ + #ifndef TOR_COUNTRY_H #define TOR_COUNTRY_H @@ -11,6 +16,7 @@ /** A signed integer representing a country code. */ typedef int16_t country_t; +/** Maximum value for country_t. */ #define COUNTRY_MAX INT16_MAX #endif /* !defined(TOR_COUNTRY_H) */ diff --git a/src/lib/geoip/geoip.c b/src/lib/geoip/geoip.c index 70b1c2dc8c..ee03d5baa1 100644 --- a/src/lib/geoip/geoip.c +++ b/src/lib/geoip/geoip.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -70,12 +70,18 @@ static smartlist_t *geoip_countries = NULL; * The index is encoded in the pointer, and 1 is added so that NULL can mean * not found. */ static strmap_t *country_idxplus1_by_lc_code = NULL; -/** Lists of all known geoip_ipv4_entry_t and geoip_ipv6_entry_t, sorted - * by their respective ip_low. */ -static smartlist_t *geoip_ipv4_entries = NULL, *geoip_ipv6_entries = NULL; - -/** SHA1 digest of the GeoIP files to include in extra-info descriptors. */ +/** List of all known geoip_ipv4_entry_t sorted + * by their respective ip_low values. */ +static smartlist_t *geoip_ipv4_entries = NULL; +/** List of all known geoip_ipv6_entry_t, sorted by their respective + * ip_low values. */ +static smartlist_t *geoip_ipv6_entries = NULL; + +/** SHA1 digest of the IPv4 GeoIP file to include in extra-info + * descriptors. */ static char geoip_digest[DIGEST_LEN]; +/** SHA1 digest of the IPv6 GeoIP file to include in extra-info + * descriptors. */ static char geoip6_digest[DIGEST_LEN]; /** Return a list of geoip_country_t for all known countries. */ diff --git a/src/lib/geoip/geoip.h b/src/lib/geoip/geoip.h index f872ebd25f..2fc7fae754 100644 --- a/src/lib/geoip/geoip.h +++ b/src/lib/geoip/geoip.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -31,6 +31,7 @@ int geoip_get_country_by_ipv6(const struct in6_addr *addr); /** A per-country GeoIP record. */ typedef struct geoip_country_t { + /** A nul-terminated two-letter country-code. */ char countrycode[3]; } geoip_country_t; diff --git a/src/lib/geoip/lib_geoip.md b/src/lib/geoip/lib_geoip.md new file mode 100644 index 0000000000..a3ee39d574 --- /dev/null +++ b/src/lib/geoip/lib_geoip.md @@ -0,0 +1,3 @@ +@dir /lib/geoip +@brief lib/geoip: IP-to-country mapping + diff --git a/src/lib/intmath/addsub.c b/src/lib/intmath/addsub.c index 12146f4e72..44613417fa 100644 --- a/src/lib/intmath/addsub.c +++ b/src/lib/intmath/addsub.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/intmath/addsub.h b/src/lib/intmath/addsub.h index 3f745d457d..bca911103b 100644 --- a/src/lib/intmath/addsub.h +++ b/src/lib/intmath/addsub.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/intmath/bits.c b/src/lib/intmath/bits.c index 2158790e3f..dace9ffe18 100644 --- a/src/lib/intmath/bits.c +++ b/src/lib/intmath/bits.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/intmath/bits.h b/src/lib/intmath/bits.h index c1483a18b8..687651ba35 100644 --- a/src/lib/intmath/bits.h +++ b/src/lib/intmath/bits.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/intmath/cmp.h b/src/lib/intmath/cmp.h index 67a738861b..4e6c2b649a 100644 --- a/src/lib/intmath/cmp.h +++ b/src/lib/intmath/cmp.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/intmath/lib_intmath.md b/src/lib/intmath/lib_intmath.md new file mode 100644 index 0000000000..4446b715cb --- /dev/null +++ b/src/lib/intmath/lib_intmath.md @@ -0,0 +1,2 @@ +@dir /lib/intmath +@brief lib/intmath: Integer mathematics. diff --git a/src/lib/intmath/logic.h b/src/lib/intmath/logic.h index b2f77462e1..b5fb79f66e 100644 --- a/src/lib/intmath/logic.h +++ b/src/lib/intmath/logic.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/intmath/muldiv.c b/src/lib/intmath/muldiv.c index 6a292db7ba..875cf1bbf2 100644 --- a/src/lib/intmath/muldiv.c +++ b/src/lib/intmath/muldiv.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -69,6 +69,20 @@ gcd64(uint64_t a, uint64_t b) return a; } +/** Return the unsigned integer product of <b>a</b> and <b>b</b>. If overflow + * is detected, return UINT64_MAX instead. */ +uint64_t +tor_mul_u64_nowrap(uint64_t a, uint64_t b) +{ + if (a == 0 || b == 0) { + return 0; + } else if (PREDICT_UNLIKELY(UINT64_MAX / a < b)) { + return UINT64_MAX; + } else { + return a*b; + } +} + /* Given a fraction *<b>numer</b> / *<b>denom</b>, simplify it. * Requires that the denominator is greater than 0. */ void diff --git a/src/lib/intmath/muldiv.h b/src/lib/intmath/muldiv.h index 64500b6dce..43700cf1dc 100644 --- a/src/lib/intmath/muldiv.h +++ b/src/lib/intmath/muldiv.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -18,6 +18,8 @@ unsigned round_to_next_multiple_of(unsigned number, unsigned divisor); uint32_t round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor); uint64_t round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor); +uint64_t tor_mul_u64_nowrap(uint64_t a, uint64_t b); + void simplify_fraction64(uint64_t *numer, uint64_t *denom); /* Compute the CEIL of <b>a</b> divided by <b>b</b>, for nonnegative <b>a</b> diff --git a/src/lib/intmath/weakrng.c b/src/lib/intmath/weakrng.c index 99c9252c2b..a29a6a086b 100644 --- a/src/lib/intmath/weakrng.c +++ b/src/lib/intmath/weakrng.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/intmath/weakrng.h b/src/lib/intmath/weakrng.h index 40941e59b2..0394e05f79 100644 --- a/src/lib/intmath/weakrng.h +++ b/src/lib/intmath/weakrng.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -19,8 +19,11 @@ typedef struct tor_weak_rng_t { uint32_t state; } tor_weak_rng_t; +#ifndef COCCI #define TOR_WEAK_RNG_INIT {383745623} +#endif #define TOR_WEAK_RANDOM_MAX (INT_MAX) + void tor_init_weak_random(tor_weak_rng_t *weak_rng, unsigned seed); int32_t tor_weak_random(tor_weak_rng_t *weak_rng); int32_t tor_weak_random_range(tor_weak_rng_t *rng, int32_t top); diff --git a/src/lib/lib.md b/src/lib/lib.md new file mode 100644 index 0000000000..4f77a4c1d0 --- /dev/null +++ b/src/lib/lib.md @@ -0,0 +1,131 @@ +@dir /lib +@brief lib: low-level functionality. + +The "lib" directory contains low-level functionality. In general, this +code is not necessarily Tor-specific, but is instead possibly useful for +other applications. + +The modules in `lib` are currently well-factored: each one depends +only on lower-level modules. You can see an up-to-date list of the +modules, sorted from lowest to highest level, by running +`./scripts/maint/practracker/includes.py --toposort`. + +As of this writing, the library modules are (from lowest to highest +level): + + - \refdir{lib/cc} -- Macros for managing the C compiler and + language. + + - \refdir{lib/version} -- Holds the current version of Tor. + + - \refdir{lib/testsupport} -- Helpers for making + test-only code, and test mocking support. + + - \refdir{lib/defs} -- Lowest-level constants. + + - \refdir{lib/subsys} -- Types used for declaring a + "subsystem". (_A subsystem is a module with support for initialization, + shutdown, configuration, and so on._) + + - \refdir{lib/conf} -- For declaring configuration options. + + - \refdir{lib/arch} -- For handling differences in CPU + architecture. + + - \refdir{lib/err} -- Lowest-level error handling code. + + - \refdir{lib/malloc} -- Memory management. + management. + + - \refdir{lib/intmath} -- Integer mathematics. + + - \refdir{lib/fdio} -- For + reading and writing n file descriptors. + + - \refdir{lib/lock} -- Simple locking support. + (_Lower-level than the rest of the threading code._) + + - \refdir{lib/ctime} -- Constant-time code to avoid + side-channels. + + - \refdir{lib/string} -- Low-level string manipulation. + + - \refdir{lib/wallclock} -- + For inspecting and manipulating the current (UTC) time. + + - \refdir{lib/osinfo} -- For inspecting the OS version + and capabilities. + + - \refdir{lib/smartlist_core} -- The bare-bones + pieces of our dynamic array ("smartlist") implementation. + + - \refdir{lib/log} -- Log messages to files, syslogs, etc. + + - \refdir{lib/container} -- General purpose containers, + including dynamic arrays ("smartlists"), hashtables, bit arrays, + etc. + + - \refdir{lib/trace} -- A general-purpose API + function-tracing functionality Tor. (_Currently not much used._) + + - \refdir{lib/thread} -- Mid-level Threading. + + - \refdir{lib/term} -- Terminal manipulation + (like reading a password from the user). + + - \refdir{lib/memarea} -- A fast + "arena" style allocator, where the data is freed all at once. + + - \refdir{lib/encoding} -- Encoding + data in various formats, datatypes, and transformations. + + - \refdir{lib/dispatch} -- A general-purpose in-process + message delivery system. + + - \refdir{lib/sandbox} -- Our Linux seccomp2 sandbox + implementation. + + - \refdir{lib/pubsub} -- A publish/subscribe message passing system. + + - \refdir{lib/fs} -- Files, filenames, directories, etc. + + - \refdir{lib/confmgt} -- Parse, encode, and manipulate onfiguration files. + + - \refdir{lib/crypt_ops} -- Cryptographic operations. + + - \refdir{lib/meminfo} -- Functions for inspecting our + memory usage, if the malloc implementation exposes that to us. + + - \refdir{lib/time} -- Higher level time functions, including + fine-gained and monotonic timers. + + - \refdir{lib/math} -- Floating-point mathematical utilities. + + - \refdir{lib/buf} -- An efficient byte queue. + + - \refdir{lib/net} -- Networking code, including address + manipulation, compatibility wrappers, etc. + + - \refdir{lib/compress} -- Wraps several compression libraries. + + - \refdir{lib/geoip} -- IP-to-country mapping. + + - \refdir{lib/tls} -- TLS library wrappers. + + - \refdir{lib/evloop} -- Low-level event-loop. + + - \refdir{lib/process} -- Launch and manage subprocesses. + +### What belongs in lib? + +In general, if you can imagine some program wanting the functionality +you're writing, even if that program had nothing to do with Tor, your +functionality belongs in lib. + +If it falls into one of the existing "lib" categories, your +functionality belongs in lib. + +If you are using platform-specific `ifdef`s to manage compatibility +issues among platforms, you should probably consider whether you can +put your code into lib. + diff --git a/src/lib/lock/compat_mutex.c b/src/lib/lock/compat_mutex.c index 670bd0174c..b0084a3484 100644 --- a/src/lib/lock/compat_mutex.c +++ b/src/lib/lock/compat_mutex.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/lock/compat_mutex.h b/src/lib/lock/compat_mutex.h index e0c3d7cb78..5631993cc4 100644 --- a/src/lib/lock/compat_mutex.h +++ b/src/lib/lock/compat_mutex.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -58,6 +58,11 @@ void tor_mutex_init_nonrecursive(tor_mutex_t *m); void tor_mutex_acquire(tor_mutex_t *m); void tor_mutex_release(tor_mutex_t *m); void tor_mutex_free_(tor_mutex_t *m); +/** + * @copydoc tor_mutex_free_ + * + * Additionally, set the pointer <b>m</b> to NULL. + **/ #define tor_mutex_free(m) FREE_AND_NULL(tor_mutex_t, tor_mutex_free_, (m)) void tor_mutex_uninit(tor_mutex_t *m); diff --git a/src/lib/lock/compat_mutex_pthreads.c b/src/lib/lock/compat_mutex_pthreads.c index f82ad9f0e8..ac83c42a47 100644 --- a/src/lib/lock/compat_mutex_pthreads.c +++ b/src/lib/lock/compat_mutex_pthreads.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -17,8 +17,14 @@ * "recursive" mutexes (i.e., once we can re-lock if we're already holding * them.) */ static pthread_mutexattr_t attr_recursive; +/** + * True iff <b>attr_recursive</b> has been initialized. + **/ static int attr_initialized = 0; +/** + * Initialize the locking module, if it is not already initialized. + **/ void tor_locking_init(void) { diff --git a/src/lib/lock/compat_mutex_winthreads.c b/src/lib/lock/compat_mutex_winthreads.c index b0f5999e42..5fe6870a93 100644 --- a/src/lib/lock/compat_mutex_winthreads.c +++ b/src/lib/lock/compat_mutex_winthreads.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/lock/lib_lock.md b/src/lib/lock/lib_lock.md new file mode 100644 index 0000000000..6f6727bfc2 --- /dev/null +++ b/src/lib/lock/lib_lock.md @@ -0,0 +1,6 @@ +@dir /lib/lock +@brief lib/lock: Simple locking support. + +This module is more low-level than the rest of the threading code, since it +is needed by more intermediate-level modules. + diff --git a/src/lib/log/escape.c b/src/lib/log/escape.c index 6ca01c6963..88ca52a78c 100644 --- a/src/lib/log/escape.c +++ b/src/lib/log/escape.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/log/escape.h b/src/lib/log/escape.h index 0b9fc3406b..0d1eaef4c1 100644 --- a/src/lib/log/escape.h +++ b/src/lib/log/escape.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/log/lib_log.md b/src/lib/log/lib_log.md new file mode 100644 index 0000000000..8740d6a02f --- /dev/null +++ b/src/lib/log/lib_log.md @@ -0,0 +1,10 @@ +@dir /lib/log +@brief lib/log: Log messages to files, syslogs, etc. + +You can think of this as the logical "midpoint" of the +\refdir{lib} code": much of the higher-level code is higher-level +_because_ it uses the logging module, and much of the lower-level code is +specifically written to avoid having to log, because the logging module +depends on it. + + diff --git a/src/lib/log/log.c b/src/lib/log/log.c index c53db46a8c..eb81515746 100644 --- a/src/lib/log/log.c +++ b/src/lib/log/log.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -276,8 +276,8 @@ static int log_time_granularity = 1; /** Define log time granularity for all logs to be <b>granularity_msec</b> * milliseconds. */ -void -set_log_time_granularity(int granularity_msec) +MOCK_IMPL(void, +set_log_time_granularity,(int granularity_msec)) { log_time_granularity = granularity_msec; tor_log_sigsafe_err_set_granularity(granularity_msec); @@ -523,7 +523,7 @@ logfile_deliver(logfile_t *lf, const char *buf, size_t msg_len, * pass them, and some very old ones do not detect overflow so well. * Regrettably, they call their maximum line length MAXLINE. */ #if MAXLINE < 64 -#warn "MAXLINE is a very low number; it might not be from syslog.h after all" +#warning "MAXLINE is a very low number; it might not be from syslog.h." #endif char *m = msg_after_prefix; if (msg_len >= MAXLINE) @@ -665,20 +665,15 @@ tor_log_update_sigsafe_err_fds(void) const logfile_t *lf; int found_real_stderr = 0; - /* log_fds and err_fds contain matching entries: log_fds are the fds used by - * the log module, and err_fds are the fds used by the err module. - * For stdio logs, the log_fd and err_fd values are identical. - * For file logs, the err_fd is a dup() of the log_fd. - */ - int log_fds[TOR_SIGSAFE_LOG_MAX_FDS]; - int err_fds[TOR_SIGSAFE_LOG_MAX_FDS]; + /* The fds are the file descriptors of tor's stdout, stderr, and file + * logs. The log and err modules flush these fds during their shutdowns. */ + int fds[TOR_SIGSAFE_LOG_MAX_FDS]; int n_fds; LOCK_LOGS(); /* Reserve the first one for stderr. This is safe because when we daemonize, - * we dup2 /dev/null to stderr. - * For stderr, log_fds and err_fds are the same. */ - log_fds[0] = err_fds[0] = STDERR_FILENO; + * we dup2 /dev/null to stderr. */ + fds[0] = STDERR_FILENO; n_fds = 1; for (lf = logfiles; lf; lf = lf->next) { @@ -693,19 +688,11 @@ tor_log_update_sigsafe_err_fds(void) (LD_BUG|LD_GENERAL)) { if (lf->fd == STDERR_FILENO) found_real_stderr = 1; - /* Avoid duplicates by checking the log module fd against log_fds */ - if (int_array_contains(log_fds, n_fds, lf->fd)) + /* Avoid duplicates by checking the log module fd against fds */ + if (int_array_contains(fds, n_fds, lf->fd)) continue; - /* Update log_fds using the log module's fd */ - log_fds[n_fds] = lf->fd; - if (lf->needs_close) { - /* File log fds are duplicated, because close_log() closes the log - * module's fd. Both refer to the same file. */ - err_fds[n_fds] = dup(lf->fd); - } else { - /* stdio log fds are not closed by the log module. */ - err_fds[n_fds] = lf->fd; - } + /* Update fds using the log module's fd */ + fds[n_fds] = lf->fd; n_fds++; if (n_fds == TOR_SIGSAFE_LOG_MAX_FDS) break; @@ -713,20 +700,19 @@ tor_log_update_sigsafe_err_fds(void) } if (!found_real_stderr && - int_array_contains(log_fds, n_fds, STDOUT_FILENO)) { + int_array_contains(fds, n_fds, STDOUT_FILENO)) { /* Don't use a virtual stderr when we're also logging to stdout. * If we reached max_fds logs, we'll now have (max_fds - 1) logs. * That's ok, max_fds is large enough that most tor instances don't exceed * it. */ raw_assert(n_fds >= 2); /* Don't tor_assert inside log fns */ --n_fds; - log_fds[0] = log_fds[n_fds]; - err_fds[0] = err_fds[n_fds]; + fds[0] = fds[n_fds]; } UNLOCK_LOGS(); - tor_log_set_sigsafe_err_fds(err_fds, n_fds); + tor_log_set_sigsafe_err_fds(fds, n_fds); } /** Add to <b>out</b> a copy of every currently configured log file name. Used @@ -835,6 +821,32 @@ logs_free_all(void) * log mutex. */ } +/** Flush the signal-safe log files. + * + * This function is safe to call from a signal handler. It is currenly called + * by the BUG() macros, when terminating the process on an abnormal condition. + */ +void +logs_flush_sigsafe(void) +{ + /* If we don't have fsync() in unistd.h, we can't flush the logs. */ +#ifdef HAVE_FSYNC + logfile_t *victim, *next; + /* We can't LOCK_LOGS() in a signal handler, because it may call + * signal-unsafe functions. And we can't deallocate memory, either. */ + next = logfiles; + logfiles = NULL; + while (next) { + victim = next; + next = next->next; + if (victim->needs_close) { + /* We can't do anything useful if the flush fails. */ + (void)fsync(victim->fd); + } + } +#endif /* defined(HAVE_FSYNC) */ +} + /** Remove and free the log entry <b>victim</b> from the linked-list * logfiles (it is probably present, but it might not be due to thread * racing issues). After this function is called, the caller shouldn't @@ -907,9 +919,9 @@ set_log_severity_config(int loglevelMin, int loglevelMax, /** Add a log handler named <b>name</b> to send all messages in <b>severity</b> * to <b>fd</b>. Copies <b>severity</b>. Helper: does no locking. */ -static void -add_stream_log_impl(const log_severity_list_t *severity, - const char *name, int fd) +MOCK_IMPL(STATIC void, +add_stream_log_impl,(const log_severity_list_t *severity, + const char *name, int fd)) { logfile_t *lf; lf = tor_malloc_zero(sizeof(logfile_t)); @@ -965,18 +977,16 @@ logs_set_domain_logging(int enabled) UNLOCK_LOGS(); } -/** Add a log handler to receive messages during startup (before the real - * logs are initialized). +/** Add a log handler to accept messages when no other log is configured. */ void -add_temp_log(int min_severity) +add_default_log(int min_severity) { log_severity_list_t *s = tor_malloc_zero(sizeof(log_severity_list_t)); set_log_severity_config(min_severity, LOG_ERR, s); LOCK_LOGS(); - add_stream_log_impl(s, "<temp>", fileno(stdout)); + add_stream_log_impl(s, "<default>", fileno(stdout)); tor_free(s); - logfiles->is_temporary = 1; UNLOCK_LOGS(); } @@ -1119,8 +1129,7 @@ flush_log_messages_from_startup(void) UNLOCK_LOGS(); } -/** Close any log handlers added by add_temp_log() or marked by - * mark_logs_temp(). */ +/** Close any log handlers marked by mark_logs_temp(). */ void close_temp_logs(void) { @@ -1172,10 +1181,10 @@ mark_logs_temp(void) * opening the logfile failed, -1 is returned and errno is set appropriately * (by open(2)). Takes ownership of fd. */ -int -add_file_log(const log_severity_list_t *severity, - const char *filename, - int fd) +MOCK_IMPL(int, +add_file_log,(const log_severity_list_t *severity, + const char *filename, + int fd)) { logfile_t *lf; diff --git a/src/lib/log/log.h b/src/lib/log/log.h index f09c63cdd9..aafbf9be2f 100644 --- a/src/lib/log/log.h +++ b/src/lib/log/log.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -23,9 +23,11 @@ #include <syslog.h> #define LOG_WARN LOG_WARNING #if LOG_DEBUG < LOG_ERR +#ifndef COCCI #error "Your syslog.h thinks high numbers are more important. " \ "We aren't prepared to deal with that." #endif +#endif /* LOG_DEBUG < LOG_ERR */ #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 @@ -163,11 +165,11 @@ int parse_log_severity_config(const char **cfg, log_severity_list_t *severity_out); void set_log_severity_config(int minSeverity, int maxSeverity, log_severity_list_t *severity_out); -void add_stream_log(const log_severity_list_t *severity, const char *name, - int fd); -int add_file_log(const log_severity_list_t *severity, - const char *filename, - int fd); +void add_stream_log(const log_severity_list_t *severity, + const char *name, int fd); +MOCK_DECL(int, add_file_log,(const log_severity_list_t *severity, + const char *filename, + int fd)); #ifdef HAVE_SYSLOG_H int add_syslog_log(const log_severity_list_t *severity, @@ -184,7 +186,8 @@ void logs_set_domain_logging(int enabled); int get_min_log_level(void); void switch_logs_debug(void); void logs_free_all(void); -void add_temp_log(int min_severity); +void logs_flush_sigsafe(void); +void add_default_log(int min_severity); void close_temp_logs(void); void rollback_log_changes(void); void mark_logs_temp(void); @@ -193,7 +196,7 @@ void change_callback_log_severity(int loglevelMin, int loglevelMax, void flush_pending_log_callbacks(void); void flush_log_messages_from_startup(void); void log_set_application_name(const char *name); -void set_log_time_granularity(int granularity_msec); +MOCK_DECL(void, set_log_time_granularity,(int granularity_msec)); void truncate_logs(void); void tor_log(int severity, log_domain_mask_t domain, const char *format, ...) @@ -305,7 +308,9 @@ extern const log_domain_mask_t LD_GENERAL_; MOCK_DECL(STATIC void, logv, (int severity, log_domain_mask_t domain, const char *funcname, const char *suffix, const char *format, va_list ap) CHECK_PRINTF(5,0)); -#endif +MOCK_DECL(STATIC void, add_stream_log_impl,( + const log_severity_list_t *severity, const char *name, int fd)); +#endif /* defined(LOG_PRIVATE) */ #if defined(LOG_PRIVATE) || defined(TOR_UNIT_TESTS) /** Given a severity, yields an index into log_severity_list_t.masks to use diff --git a/src/lib/log/log_sys.c b/src/lib/log/log_sys.c index 826358546a..1be4f5b7d8 100644 --- a/src/lib/log/log_sys.c +++ b/src/lib/log/log_sys.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/log/log_sys.h b/src/lib/log/log_sys.h index 7043253066..523c2e5008 100644 --- a/src/lib/log/log_sys.h +++ b/src/lib/log/log_sys.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/log/ratelim.c b/src/lib/log/ratelim.c index 5eec742aa7..ac401fb398 100644 --- a/src/lib/log/ratelim.c +++ b/src/lib/log/ratelim.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/log/ratelim.h b/src/lib/log/ratelim.h index 1db54ba726..e9b55d40dc 100644 --- a/src/lib/log/ratelim.h +++ b/src/lib/log/ratelim.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -45,7 +45,9 @@ typedef struct ratelim_t { int n_calls_since_last_time; } ratelim_t; +#ifndef COCCI #define RATELIM_INIT(r) { (r), 0, 0 } +#endif #define RATELIM_TOOMANY (16*1000*1000) char *rate_limit_log(ratelim_t *lim, time_t now); diff --git a/src/lib/log/util_bug.c b/src/lib/log/util_bug.c index af1ac40732..581ae85f47 100644 --- a/src/lib/log/util_bug.c +++ b/src/lib/log/util_bug.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -163,7 +163,8 @@ tor_bug_occurred_(const char *fname, unsigned int line, /** * Call the tor_raw_abort_() function to close raw logs, then kill the current - * process with a fatal error. + * process with a fatal error. But first, close the file-based log file + * descriptors, so error messages are written before process termination. * * (This is a separate function so that we declare it in util_bug.h without * including torerr.h in all the users of util_bug.h) @@ -171,6 +172,7 @@ tor_bug_occurred_(const char *fname, unsigned int line, void tor_abort_(void) { + logs_flush_sigsafe(); tor_raw_abort_(); } diff --git a/src/lib/log/util_bug.h b/src/lib/log/util_bug.h index 7eaa6173c8..ae3d125a08 100644 --- a/src/lib/log/util_bug.h +++ b/src/lib/log/util_bug.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -131,7 +131,9 @@ #undef BUG // Coverity defines this in global headers; let's override it. This is a // magic coverity-only preprocessor thing. +#ifndef COCCI #nodef BUG(x) (x) +#endif #endif /* defined(__COVERITY__) */ #if defined(__COVERITY__) || defined(__clang_analyzer__) @@ -200,6 +202,7 @@ : 0) #endif /* defined(ALL_BUGS_ARE_FATAL) || ... */ +#ifndef COCCI #ifdef __GNUC__ #define IF_BUG_ONCE__(cond,var) \ if (( { \ @@ -208,7 +211,7 @@ if (bool_result && !var) { \ var = 1; \ tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, \ - "!("#cond")", 1, NULL); \ + ("!("#cond")"), 1, NULL); \ } \ bool_result; } )) #else /* !defined(__GNUC__) */ @@ -218,10 +221,12 @@ (var ? 1 : \ (var=1, \ tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, \ - "!("#cond")", 1, NULL), \ + ("!("#cond")"), 1, NULL), \ 1)) \ : 0) #endif /* defined(__GNUC__) */ +#endif /* !defined(COCCI) */ + #define IF_BUG_ONCE_VARNAME_(a) \ warning_logged_on_ ## a ## __ #define IF_BUG_ONCE_VARNAME__(a) \ diff --git a/src/lib/log/win32err.c b/src/lib/log/win32err.c index 03d5c9fad2..8136813aab 100644 --- a/src/lib/log/win32err.c +++ b/src/lib/log/win32err.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/log/win32err.h b/src/lib/log/win32err.h index ecfa88792d..5c1386a64d 100644 --- a/src/lib/log/win32err.h +++ b/src/lib/log/win32err.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/malloc/lib_malloc.md b/src/lib/malloc/lib_malloc.md new file mode 100644 index 0000000000..ff61722f02 --- /dev/null +++ b/src/lib/malloc/lib_malloc.md @@ -0,0 +1,76 @@ +@dir /lib/malloc +@brief lib/malloc: Wrappers and utilities for memory management. + + +Tor imposes a few light wrappers over C's native malloc and free +functions, to improve convenience, and to allow wholescale replacement +of malloc and free as needed. + +You should never use 'malloc', 'calloc', 'realloc, or 'free' on their +own; always use the variants prefixed with 'tor_'. +They are the same as the standard C functions, with the following +exceptions: + + * `tor_free(NULL)` is a no-op. + * `tor_free()` is a macro that takes an lvalue as an argument and sets it to + NULL after freeing it. To avoid this behavior, you can use `tor_free_()` + instead. + * tor_malloc() and friends fail with an assertion if they are asked to + allocate a value so large that it is probably an underflow. + * It is always safe to `tor_malloc(0)`, regardless of whether your libc + allows it. + * `tor_malloc()`, `tor_realloc()`, and friends are never allowed to fail. + Instead, Tor will die with an assertion. This means that you never + need to check their return values. See the next subsection for + information on why we think this is a good idea. + +We define additional general-purpose memory allocation functions as well: + + * `tor_malloc_zero(x)` behaves as `calloc(1, x)`, except the it makes clear + the intent to allocate a single zeroed-out value. + * `tor_reallocarray(x,y)` behaves as the OpenBSD reallocarray function. + Use it for cases when you need to realloc() in a multiplication-safe + way. + +And specific-purpose functions as well: + + * `tor_strdup()` and `tor_strndup()` behaves as the underlying libc + functions, but use `tor_malloc()` instead of the underlying function. + * `tor_memdup()` copies a chunk of memory of a given size. + * `tor_memdup_nulterm()` copies a chunk of memory of a given size, then + NUL-terminates it just to be safe. + +#### Why assert on allocation failure? + +Why don't we allow `tor_malloc()` and its allies to return NULL? + +First, it's error-prone. Many programmers forget to check for NULL return +values, and testing for `malloc()` failures is a major pain. + +Second, it's not necessarily a great way to handle OOM conditions. It's +probably better (we think) to have a memory target where we dynamically free +things ahead of time in order to stay under the target. Trying to respond to +an OOM at the point of `tor_malloc()` failure, on the other hand, would involve +a rare operation invoked from deep in the call stack. (Again, that's +error-prone and hard to debug.) + +Third, thanks to the rise of Linux and other operating systems that allow +memory to be overcommitted, you can't actually ever rely on getting a NULL +from `malloc()` when you're out of memory; instead you have to use an approach +closer to tracking the total memory usage. + +#### Conventions for your own allocation functions. + +Whenever you create a new type, the convention is to give it a pair of +`x_new()` and `x_free_()` functions, named after the type. + +Calling `x_free(NULL)` should always be a no-op. + +There should additionally be an `x_free()` macro, defined in terms of +`x_free_()`. This macro should set its lvalue to NULL. You can define it +using the FREE_AND_NULL macro, as follows: + +``` +#define x_free(ptr) FREE_AND_NULL(x_t, x_free_, (ptr)) +``` + diff --git a/src/lib/malloc/malloc.c b/src/lib/malloc/malloc.c index 8628acfc97..9c9d600260 100644 --- a/src/lib/malloc/malloc.c +++ b/src/lib/malloc/malloc.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/malloc/malloc.h b/src/lib/malloc/malloc.h index 39a45901a1..80e8091adc 100644 --- a/src/lib/malloc/malloc.h +++ b/src/lib/malloc/malloc.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/malloc/map_anon.c b/src/lib/malloc/map_anon.c index 9559cbe2d4..1926b61f07 100644 --- a/src/lib/malloc/map_anon.c +++ b/src/lib/malloc/map_anon.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -78,8 +78,8 @@ #endif /* defined(HAVE_MINHERIT) || ... */ #if defined(HAVE_MINHERIT) && !defined(FLAG_ZERO) && !defined(FLAG_NOINHERIT) -#warn "minherit() is defined, but we couldn't find the right flag for it." -#warn "This is probably a bug in Tor's support for this platform." +#warning "minherit() is defined, but we couldn't find the right flag for it." +#warning "This is probably a bug in Tor's support for this platform." #endif /** diff --git a/src/lib/malloc/map_anon.h b/src/lib/malloc/map_anon.h index 4c4690e12f..0354668d65 100644 --- a/src/lib/malloc/map_anon.h +++ b/src/lib/malloc/map_anon.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/math/fp.c b/src/lib/math/fp.c index 49a2a6a2ca..c09555209e 100644 --- a/src/lib/math/fp.c +++ b/src/lib/math/fp.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -74,7 +74,7 @@ clamp_double_to_int64(double number) branches that are not taken. */ #define PROBLEMATIC_FLOAT_CONVERSION_WARNING -DISABLE_GCC_WARNING(float-conversion) +DISABLE_GCC_WARNING("-Wfloat-conversion") #endif /* (defined(MINGW_ANY)||defined(__FreeBSD__)) && GCC_VERSION >= 409 */ /* @@ -84,7 +84,7 @@ DISABLE_GCC_WARNING(float-conversion) #if defined(__clang__) #if __has_warning("-Wdouble-promotion") #define PROBLEMATIC_DOUBLE_PROMOTION_WARNING -DISABLE_GCC_WARNING(double-promotion) +DISABLE_GCC_WARNING("-Wdouble-promotion") #endif #endif /* defined(__clang__) */ @@ -115,10 +115,10 @@ DISABLE_GCC_WARNING(double-promotion) return signbit(number) ? INT64_MIN : INT64_MAX; #ifdef PROBLEMATIC_DOUBLE_PROMOTION_WARNING -ENABLE_GCC_WARNING(double-promotion) +ENABLE_GCC_WARNING("-Wdouble-promotion") #endif #ifdef PROBLEMATIC_FLOAT_CONVERSION_WARNING -ENABLE_GCC_WARNING(float-conversion) +ENABLE_GCC_WARNING("-Wfloat-conversion") #endif } @@ -128,16 +128,16 @@ tor_isinf(double x) { /* Same as above, work around the "double promotion" warnings */ #ifdef PROBLEMATIC_FLOAT_CONVERSION_WARNING -DISABLE_GCC_WARNING(float-conversion) +DISABLE_GCC_WARNING("-Wfloat-conversion") #endif #ifdef PROBLEMATIC_DOUBLE_PROMOTION_WARNING -DISABLE_GCC_WARNING(double-promotion) +DISABLE_GCC_WARNING("-Wdouble-promotion") #endif return isinf(x); #ifdef PROBLEMATIC_DOUBLE_PROMOTION_WARNING -ENABLE_GCC_WARNING(double-promotion) +ENABLE_GCC_WARNING("-Wdouble-promotion") #endif #ifdef PROBLEMATIC_FLOAT_CONVERSION_WARNING -ENABLE_GCC_WARNING(float-conversion) +ENABLE_GCC_WARNING("-Wfloat-conversion") #endif } diff --git a/src/lib/math/fp.h b/src/lib/math/fp.h index a73789c945..0a7a685485 100644 --- a/src/lib/math/fp.h +++ b/src/lib/math/fp.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/math/laplace.c b/src/lib/math/laplace.c index 302edb20b8..5c1d686a9c 100644 --- a/src/lib/math/laplace.c +++ b/src/lib/math/laplace.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/math/laplace.h b/src/lib/math/laplace.h index 02b0e890f0..e0dd166bbd 100644 --- a/src/lib/math/laplace.h +++ b/src/lib/math/laplace.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/math/lib_math.md b/src/lib/math/lib_math.md new file mode 100644 index 0000000000..9cc256d24b --- /dev/null +++ b/src/lib/math/lib_math.md @@ -0,0 +1,6 @@ +@dir /lib/math +@brief lib/math: Floating-point math utilities. + +This module includes a bunch of floating-point compatibility code, and +implementations for several probability distributions. + diff --git a/src/lib/math/prob_distr.c b/src/lib/math/prob_distr.c index d44dc28265..548d256023 100644 --- a/src/lib/math/prob_distr.c +++ b/src/lib/math/prob_distr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -52,14 +52,15 @@ #include <math.h> #include <stddef.h> +#ifndef COCCI /** Declare a function that downcasts from a generic dist struct to the actual * subtype probablity distribution it represents. */ #define DECLARE_PROB_DISTR_DOWNCAST_FN(name) \ static inline \ - const struct name * \ - dist_to_const_##name(const struct dist *obj) { \ + const struct name##_t * \ + dist_to_const_##name(const struct dist_t *obj) { \ tor_assert(obj->ops == &name##_ops); \ - return SUBTYPE_P(obj, struct name, base); \ + return SUBTYPE_P(obj, struct name ## _t, base); \ } DECLARE_PROB_DISTR_DOWNCAST_FN(uniform) DECLARE_PROB_DISTR_DOWNCAST_FN(geometric) @@ -67,6 +68,7 @@ DECLARE_PROB_DISTR_DOWNCAST_FN(logistic) DECLARE_PROB_DISTR_DOWNCAST_FN(log_logistic) DECLARE_PROB_DISTR_DOWNCAST_FN(genpareto) DECLARE_PROB_DISTR_DOWNCAST_FN(weibull) +#endif /* !defined(COCCI) */ /** * Count number of one bits in 32-bit word. @@ -178,8 +180,8 @@ clz32(uint32_t x) /** * Compute the logistic function: f(x) = 1/(1 + e^{-x}) = e^x/(1 + e^x). - * Maps a log-odds-space probability in [-\infty, +\infty] into a direct-space - * probability in [0,1]. Inverse of logit. + * Maps a log-odds-space probability in [-infinity, +infinity] into a + * direct-space probability in [0,1]. Inverse of logit. * * Ill-conditioned for large x; the identity logistic(-x) = 1 - * logistic(x) and the function logistichalf(x) = logistic(x) - 1/2 may @@ -266,7 +268,7 @@ logistic(double x) /** * Compute the logit function: log p/(1 - p). Defined on [0,1]. Maps * a direct-space probability in [0,1] to a log-odds-space probability - * in [-\infty, +\infty]. Inverse of logistic. + * in [-infinity, +infinity]. Inverse of logistic. * * Ill-conditioned near 1/2 and 1; the identity logit(1 - p) = * -logit(p) and the function logithalf(p0) = logit(1/2 + p0) may help @@ -488,7 +490,7 @@ random_uniform_01(void) /* Functions for specific probability distributions start here: */ /* - * Logistic(mu, sigma) distribution, supported on (-\infty,+\infty) + * Logistic(mu, sigma) distribution, supported on (-infinity,+infinity) * * This is the uniform distribution on [0,1] mapped into log-odds * space, scaled by sigma and translated by mu. @@ -546,7 +548,7 @@ isf_logistic(double p, double mu, double sigma) } /* - * LogLogistic(alpha, beta) distribution, supported on (0, +\infty). + * LogLogistic(alpha, beta) distribution, supported on (0, +infinity). * * This is the uniform distribution on [0,1] mapped into odds space, * scaled by positive alpha and shaped by positive beta. @@ -687,7 +689,7 @@ isf_log_logistic(double p, double alpha, double beta) } /* - * Weibull(lambda, k) distribution, supported on (0, +\infty). + * Weibull(lambda, k) distribution, supported on (0, +infinity). * * pdf(x) = (k/lambda) (x/lambda)^{k - 1} e^{-(x/lambda)^k} * cdf(x) = 1 - e^{-(x/lambda)^k} @@ -753,7 +755,7 @@ isf_weibull(double p, double lambda, double k) } /* - * GeneralizedPareto(mu, sigma, xi), supported on (mu, +\infty) for + * GeneralizedPareto(mu, sigma, xi), supported on (mu, +infinity) for * nonnegative xi, or (mu, mu - sigma/xi) for negative xi. * * Samples: @@ -793,19 +795,19 @@ cdf_genpareto(double x, double mu, double sigma, double xi) /* * log(1 + xi x_0)/xi - * = (-1/xi) \sum_{n=1}^\infty (-xi x_0)^n/n - * = (-1/xi) (-xi x_0 + \sum_{n=2}^\infty (-xi x_0)^n/n) - * = x_0 - (1/xi) \sum_{n=2}^\infty (-xi x_0)^n/n - * = x_0 - x_0 \sum_{n=2}^\infty (-xi x_0)^{n-1}/n + * = (-1/xi) \sum_{n=1}^infinity (-xi x_0)^n/n + * = (-1/xi) (-xi x_0 + \sum_{n=2}^infinity (-xi x_0)^n/n) + * = x_0 - (1/xi) \sum_{n=2}^infinity (-xi x_0)^n/n + * = x_0 - x_0 \sum_{n=2}^infinity (-xi x_0)^{n-1}/n * = x_0 (1 - d), * - * where d = \sum_{n=2}^\infty (-xi x_0)^{n-1}/n. If |xi| < + * where d = \sum_{n=2}^infinity (-xi x_0)^{n-1}/n. If |xi| < * eps/4|x_0|, then * - * |d| <= \sum_{n=2}^\infty (eps/4)^{n-1}/n - * <= \sum_{n=2}^\infty (eps/4)^{n-1} - * = \sum_{n=1}^\infty (eps/4)^n - * = (eps/4) \sum_{n=0}^\infty (eps/4)^n + * |d| <= \sum_{n=2}^infinity (eps/4)^{n-1}/n + * <= \sum_{n=2}^infinity (eps/4)^{n-1} + * = \sum_{n=1}^infinity (eps/4)^n + * = (eps/4) \sum_{n=0}^infinity (eps/4)^n * = (eps/4)/(1 - eps/4) * < eps/2 * @@ -855,20 +857,20 @@ icdf_genpareto(double p, double mu, double sigma, double xi) * for xi near zero (note f(xi) --> -log U as xi --> 0), write * the absolutely convergent Taylor expansion * - * f(xi) = (1/xi)*(-xi log U + \sum_{n=2}^\infty (-xi log U)^n/n! - * = -log U + (1/xi)*\sum_{n=2}^\infty (-xi log U)^n/n! - * = -log U + \sum_{n=2}^\infty xi^{n-1} (-log U)^n/n! - * = -log U - log U \sum_{n=2}^\infty (-xi log U)^{n-1}/n! - * = -log U (1 + \sum_{n=2}^\infty (-xi log U)^{n-1}/n!). + * f(xi) = (1/xi)*(-xi log U + \sum_{n=2}^infinity (-xi log U)^n/n! + * = -log U + (1/xi)*\sum_{n=2}^infinity (-xi log U)^n/n! + * = -log U + \sum_{n=2}^infinity xi^{n-1} (-log U)^n/n! + * = -log U - log U \sum_{n=2}^infinity (-xi log U)^{n-1}/n! + * = -log U (1 + \sum_{n=2}^infinity (-xi log U)^{n-1}/n!). * - * Let d = \sum_{n=2}^\infty (-xi log U)^{n-1}/n!. What do we + * Let d = \sum_{n=2}^infinity (-xi log U)^{n-1}/n!. What do we * lose if we discard it and use -log U as an approximation to * f(xi)? If |xi| < eps/-4log U, then * - * |d| <= \sum_{n=2}^\infty |xi log U|^{n-1}/n! - * <= \sum_{n=2}^\infty (eps/4)^{n-1}/n! - * <= \sum_{n=1}^\infty (eps/4)^n - * = (eps/4) \sum_{n=0}^\infty (eps/4)^n + * |d| <= \sum_{n=2}^infinity |xi log U|^{n-1}/n! + * <= \sum_{n=2}^infinity (eps/4)^{n-1}/n! + * <= \sum_{n=1}^infinity (eps/4)^n + * = (eps/4) \sum_{n=0}^infinity (eps/4)^n * = (eps/4)/(1 - eps/4) * < eps/2, * @@ -1098,10 +1100,10 @@ sample_logistic(uint32_t s, double t, double p0) * We carve up the interval (0, 1) into subregions to compute * the inverse CDF precisely: * - * A = (0, 1/(1 + e)] ---> (-\infty, -1] + * A = (0, 1/(1 + e)] ---> (-infinity, -1] * B = [1/(1 + e), 1/2] ---> [-1, 0] * C = [1/2, 1 - 1/(1 + e)] ---> [0, 1] - * D = [1 - 1/(1 + e), 1) ---> [1, +\infty) + * D = [1 - 1/(1 + e), 1) ---> [1, +infinity) * * Cases D and C are mirror images of cases A and B, * respectively, so we choose between them by the sign chosen @@ -1234,19 +1236,19 @@ sample_genpareto(uint32_t s, double p0, double xi) * Write f(xi) = (e^{xi x} - 1)/xi for xi near zero as the * absolutely convergent Taylor series * - * f(x) = (1/xi) (xi x + \sum_{n=2}^\infty (xi x)^n/n!) - * = x + (1/xi) \sum_{n=2}^\inty (xi x)^n/n! - * = x + \sum_{n=2}^\infty xi^{n-1} x^n/n! - * = x + x \sum_{n=2}^\infty (xi x)^{n-1}/n! - * = x (1 + \sum_{n=2}^\infty (xi x)^{n-1}/n!). + * f(x) = (1/xi) (xi x + \sum_{n=2}^infinity (xi x)^n/n!) + * = x + (1/xi) \sum_{n=2}^infinity (xi x)^n/n! + * = x + \sum_{n=2}^infinity xi^{n-1} x^n/n! + * = x + x \sum_{n=2}^infinity (xi x)^{n-1}/n! + * = x (1 + \sum_{n=2}^infinity (xi x)^{n-1}/n!). * - * d = \sum_{n=2}^\infty (xi x)^{n-1}/n! is the relative error + * d = \sum_{n=2}^infinity (xi x)^{n-1}/n! is the relative error * of f(x) from x. If |xi| < eps/4x, then * - * |d| <= \sum_{n=2}^\infty |xi x|^{n-1}/n! - * <= \sum_{n=2}^\infty (eps/4)^{n-1}/n! - * <= \sum_{n=1}^\infty (eps/4) - * = (eps/4) \sum_{n=0}^\infty (eps/4)^n + * |d| <= \sum_{n=2}^infinity |xi x|^{n-1}/n! + * <= \sum_{n=2}^infinity (eps/4)^{n-1}/n! + * <= \sum_{n=1}^infinity (eps/4) + * = (eps/4) \sum_{n=0}^infinity (eps/4)^n * = (eps/4)/(1 - eps/4) * < eps/2, * @@ -1324,42 +1326,42 @@ sample_geometric(uint32_t s, double p0, double p) /** Returns the name of the distribution in <b>dist</b>. */ const char * -dist_name(const struct dist *dist) +dist_name(const struct dist_t *dist) { return dist->ops->name; } /* Sample a value from <b>dist</b> and return it. */ double -dist_sample(const struct dist *dist) +dist_sample(const struct dist_t *dist) { return dist->ops->sample(dist); } /** Compute the CDF of <b>dist</b> at <b>x</b>. */ double -dist_cdf(const struct dist *dist, double x) +dist_cdf(const struct dist_t *dist, double x) { return dist->ops->cdf(dist, x); } /** Compute the SF (Survival function) of <b>dist</b> at <b>x</b>. */ double -dist_sf(const struct dist *dist, double x) +dist_sf(const struct dist_t *dist, double x) { return dist->ops->sf(dist, x); } /** Compute the iCDF (Inverse CDF) of <b>dist</b> at <b>x</b>. */ double -dist_icdf(const struct dist *dist, double p) +dist_icdf(const struct dist_t *dist, double p) { return dist->ops->icdf(dist, p); } /** Compute the iSF (Inverse Survival function) of <b>dist</b> at <b>x</b>. */ double -dist_isf(const struct dist *dist, double p) +dist_isf(const struct dist_t *dist, double p) { return dist->ops->isf(dist, p); } @@ -1367,18 +1369,18 @@ dist_isf(const struct dist *dist, double p) /** Functions for uniform distribution */ static double -uniform_sample(const struct dist *dist) +uniform_sample(const struct dist_t *dist) { - const struct uniform *U = dist_to_const_uniform(dist); + const struct uniform_t *U = dist_to_const_uniform(dist); double p0 = random_uniform_01(); return sample_uniform_interval(p0, U->a, U->b); } static double -uniform_cdf(const struct dist *dist, double x) +uniform_cdf(const struct dist_t *dist, double x) { - const struct uniform *U = dist_to_const_uniform(dist); + const struct uniform_t *U = dist_to_const_uniform(dist); if (x < U->a) return 0; else if (x < U->b) @@ -1388,9 +1390,9 @@ uniform_cdf(const struct dist *dist, double x) } static double -uniform_sf(const struct dist *dist, double x) +uniform_sf(const struct dist_t *dist, double x) { - const struct uniform *U = dist_to_const_uniform(dist); + const struct uniform_t *U = dist_to_const_uniform(dist); if (x > U->b) return 0; @@ -1401,24 +1403,24 @@ uniform_sf(const struct dist *dist, double x) } static double -uniform_icdf(const struct dist *dist, double p) +uniform_icdf(const struct dist_t *dist, double p) { - const struct uniform *U = dist_to_const_uniform(dist); + const struct uniform_t *U = dist_to_const_uniform(dist); double w = U->b - U->a; return (p < 0.5 ? (U->a + w*p) : (U->b - w*(1 - p))); } static double -uniform_isf(const struct dist *dist, double p) +uniform_isf(const struct dist_t *dist, double p) { - const struct uniform *U = dist_to_const_uniform(dist); + const struct uniform_t *U = dist_to_const_uniform(dist); double w = U->b - U->a; return (p < 0.5 ? (U->b - w*p) : (U->a + w*(1 - p))); } -const struct dist_ops uniform_ops = { +const struct dist_ops_t uniform_ops = { .name = "uniform", .sample = uniform_sample, .cdf = uniform_cdf, @@ -1434,9 +1436,9 @@ const struct dist_ops uniform_ops = { /** Functions for logistic distribution: */ static double -logistic_sample(const struct dist *dist) +logistic_sample(const struct dist_t *dist) { - const struct logistic *L = dist_to_const_logistic(dist); + const struct logistic_t *L = dist_to_const_logistic(dist); uint32_t s = crypto_fast_rng_get_u32(get_thread_fast_rng()); double t = random_uniform_01(); double p0 = random_uniform_01(); @@ -1445,34 +1447,34 @@ logistic_sample(const struct dist *dist) } static double -logistic_cdf(const struct dist *dist, double x) +logistic_cdf(const struct dist_t *dist, double x) { - const struct logistic *L = dist_to_const_logistic(dist); + const struct logistic_t *L = dist_to_const_logistic(dist); return cdf_logistic(x, L->mu, L->sigma); } static double -logistic_sf(const struct dist *dist, double x) +logistic_sf(const struct dist_t *dist, double x) { - const struct logistic *L = dist_to_const_logistic(dist); + const struct logistic_t *L = dist_to_const_logistic(dist); return sf_logistic(x, L->mu, L->sigma); } static double -logistic_icdf(const struct dist *dist, double p) +logistic_icdf(const struct dist_t *dist, double p) { - const struct logistic *L = dist_to_const_logistic(dist); + const struct logistic_t *L = dist_to_const_logistic(dist); return icdf_logistic(p, L->mu, L->sigma); } static double -logistic_isf(const struct dist *dist, double p) +logistic_isf(const struct dist_t *dist, double p) { - const struct logistic *L = dist_to_const_logistic(dist); + const struct logistic_t *L = dist_to_const_logistic(dist); return isf_logistic(p, L->mu, L->sigma); } -const struct dist_ops logistic_ops = { +const struct dist_ops_t logistic_ops = { .name = "logistic", .sample = logistic_sample, .cdf = logistic_cdf, @@ -1484,9 +1486,9 @@ const struct dist_ops logistic_ops = { /** Functions for log-logistic distribution: */ static double -log_logistic_sample(const struct dist *dist) +log_logistic_sample(const struct dist_t *dist) { - const struct log_logistic *LL = dist_to_const_log_logistic(dist); + const struct log_logistic_t *LL = dist_to_const_log_logistic(dist); uint32_t s = crypto_fast_rng_get_u32(get_thread_fast_rng()); double p0 = random_uniform_01(); @@ -1494,34 +1496,34 @@ log_logistic_sample(const struct dist *dist) } static double -log_logistic_cdf(const struct dist *dist, double x) +log_logistic_cdf(const struct dist_t *dist, double x) { - const struct log_logistic *LL = dist_to_const_log_logistic(dist); + const struct log_logistic_t *LL = dist_to_const_log_logistic(dist); return cdf_log_logistic(x, LL->alpha, LL->beta); } static double -log_logistic_sf(const struct dist *dist, double x) +log_logistic_sf(const struct dist_t *dist, double x) { - const struct log_logistic *LL = dist_to_const_log_logistic(dist); + const struct log_logistic_t *LL = dist_to_const_log_logistic(dist); return sf_log_logistic(x, LL->alpha, LL->beta); } static double -log_logistic_icdf(const struct dist *dist, double p) +log_logistic_icdf(const struct dist_t *dist, double p) { - const struct log_logistic *LL = dist_to_const_log_logistic(dist); + const struct log_logistic_t *LL = dist_to_const_log_logistic(dist); return icdf_log_logistic(p, LL->alpha, LL->beta); } static double -log_logistic_isf(const struct dist *dist, double p) +log_logistic_isf(const struct dist_t *dist, double p) { - const struct log_logistic *LL = dist_to_const_log_logistic(dist); + const struct log_logistic_t *LL = dist_to_const_log_logistic(dist); return isf_log_logistic(p, LL->alpha, LL->beta); } -const struct dist_ops log_logistic_ops = { +const struct dist_ops_t log_logistic_ops = { .name = "log logistic", .sample = log_logistic_sample, .cdf = log_logistic_cdf, @@ -1533,9 +1535,9 @@ const struct dist_ops log_logistic_ops = { /** Functions for Weibull distribution */ static double -weibull_sample(const struct dist *dist) +weibull_sample(const struct dist_t *dist) { - const struct weibull *W = dist_to_const_weibull(dist); + const struct weibull_t *W = dist_to_const_weibull(dist); uint32_t s = crypto_fast_rng_get_u32(get_thread_fast_rng()); double p0 = random_uniform_01(); @@ -1543,34 +1545,34 @@ weibull_sample(const struct dist *dist) } static double -weibull_cdf(const struct dist *dist, double x) +weibull_cdf(const struct dist_t *dist, double x) { - const struct weibull *W = dist_to_const_weibull(dist); + const struct weibull_t *W = dist_to_const_weibull(dist); return cdf_weibull(x, W->lambda, W->k); } static double -weibull_sf(const struct dist *dist, double x) +weibull_sf(const struct dist_t *dist, double x) { - const struct weibull *W = dist_to_const_weibull(dist); + const struct weibull_t *W = dist_to_const_weibull(dist); return sf_weibull(x, W->lambda, W->k); } static double -weibull_icdf(const struct dist *dist, double p) +weibull_icdf(const struct dist_t *dist, double p) { - const struct weibull *W = dist_to_const_weibull(dist); + const struct weibull_t *W = dist_to_const_weibull(dist); return icdf_weibull(p, W->lambda, W->k); } static double -weibull_isf(const struct dist *dist, double p) +weibull_isf(const struct dist_t *dist, double p) { - const struct weibull *W = dist_to_const_weibull(dist); + const struct weibull_t *W = dist_to_const_weibull(dist); return isf_weibull(p, W->lambda, W->k); } -const struct dist_ops weibull_ops = { +const struct dist_ops_t weibull_ops = { .name = "Weibull", .sample = weibull_sample, .cdf = weibull_cdf, @@ -1582,9 +1584,9 @@ const struct dist_ops weibull_ops = { /** Functions for generalized Pareto distributions */ static double -genpareto_sample(const struct dist *dist) +genpareto_sample(const struct dist_t *dist) { - const struct genpareto *GP = dist_to_const_genpareto(dist); + const struct genpareto_t *GP = dist_to_const_genpareto(dist); uint32_t s = crypto_fast_rng_get_u32(get_thread_fast_rng()); double p0 = random_uniform_01(); @@ -1592,34 +1594,34 @@ genpareto_sample(const struct dist *dist) } static double -genpareto_cdf(const struct dist *dist, double x) +genpareto_cdf(const struct dist_t *dist, double x) { - const struct genpareto *GP = dist_to_const_genpareto(dist); + const struct genpareto_t *GP = dist_to_const_genpareto(dist); return cdf_genpareto(x, GP->mu, GP->sigma, GP->xi); } static double -genpareto_sf(const struct dist *dist, double x) +genpareto_sf(const struct dist_t *dist, double x) { - const struct genpareto *GP = dist_to_const_genpareto(dist); + const struct genpareto_t *GP = dist_to_const_genpareto(dist); return sf_genpareto(x, GP->mu, GP->sigma, GP->xi); } static double -genpareto_icdf(const struct dist *dist, double p) +genpareto_icdf(const struct dist_t *dist, double p) { - const struct genpareto *GP = dist_to_const_genpareto(dist); + const struct genpareto_t *GP = dist_to_const_genpareto(dist); return icdf_genpareto(p, GP->mu, GP->sigma, GP->xi); } static double -genpareto_isf(const struct dist *dist, double p) +genpareto_isf(const struct dist_t *dist, double p) { - const struct genpareto *GP = dist_to_const_genpareto(dist); + const struct genpareto_t *GP = dist_to_const_genpareto(dist); return isf_genpareto(p, GP->mu, GP->sigma, GP->xi); } -const struct dist_ops genpareto_ops = { +const struct dist_ops_t genpareto_ops = { .name = "generalized Pareto", .sample = genpareto_sample, .cdf = genpareto_cdf, @@ -1631,9 +1633,9 @@ const struct dist_ops genpareto_ops = { /** Functions for geometric distribution on number of trials before success */ static double -geometric_sample(const struct dist *dist) +geometric_sample(const struct dist_t *dist) { - const struct geometric *G = dist_to_const_geometric(dist); + const struct geometric_t *G = dist_to_const_geometric(dist); uint32_t s = crypto_fast_rng_get_u32(get_thread_fast_rng()); double p0 = random_uniform_01(); @@ -1641,9 +1643,9 @@ geometric_sample(const struct dist *dist) } static double -geometric_cdf(const struct dist *dist, double x) +geometric_cdf(const struct dist_t *dist, double x) { - const struct geometric *G = dist_to_const_geometric(dist); + const struct geometric_t *G = dist_to_const_geometric(dist); if (x < 1) return 0; @@ -1652,9 +1654,9 @@ geometric_cdf(const struct dist *dist, double x) } static double -geometric_sf(const struct dist *dist, double x) +geometric_sf(const struct dist_t *dist, double x) { - const struct geometric *G = dist_to_const_geometric(dist); + const struct geometric_t *G = dist_to_const_geometric(dist); if (x < 1) return 0; @@ -1663,22 +1665,22 @@ geometric_sf(const struct dist *dist, double x) } static double -geometric_icdf(const struct dist *dist, double p) +geometric_icdf(const struct dist_t *dist, double p) { - const struct geometric *G = dist_to_const_geometric(dist); + const struct geometric_t *G = dist_to_const_geometric(dist); return log1p(-p)/log1p(-G->p); } static double -geometric_isf(const struct dist *dist, double p) +geometric_isf(const struct dist_t *dist, double p) { - const struct geometric *G = dist_to_const_geometric(dist); + const struct geometric_t *G = dist_to_const_geometric(dist); return log(p)/log1p(-G->p); } -const struct dist_ops geometric_ops = { +const struct dist_ops_t geometric_ops = { .name = "geometric (1-based)", .sample = geometric_sample, .cdf = geometric_cdf, diff --git a/src/lib/math/prob_distr.h b/src/lib/math/prob_distr.h index 7254dc8623..a036073b93 100644 --- a/src/lib/math/prob_distr.h +++ b/src/lib/math/prob_distr.h @@ -15,13 +15,13 @@ /** * Container for distribution parameters for sampling, CDF, &c. */ -struct dist { - const struct dist_ops *ops; +struct dist_t { + const struct dist_ops_t *ops; }; /** - * Untyped initializer element for struct dist using the specified - * struct dist_ops pointer. Don't actually use this directly -- use + * Untyped initializer element for struct dist_t using the specified + * struct dist_ops_t pointer. Don't actually use this directly -- use * the type-specific macro built out of DIST_BASE_TYPED below -- but if * you did use this directly, it would be something like: * @@ -61,46 +61,46 @@ struct dist { #endif /* defined(__COVERITY__) */ /** -* Typed initializer element for struct dist using the specified struct -* dist_ops pointer. Don't actually use this directly -- use a +* Typed initializer element for struct dist_t using the specified struct +* dist_ops_t pointer. Don't actually use this directly -- use a * type-specific macro built out of it -- but if you did use this * directly, it would be something like: * -* struct weibull mydist = { -* DIST_BASE_TYPED(&weibull_ops, mydist, struct weibull), -* .lambda = ..., -* .k = ..., -* }; +* struct weibull mydist = { +* DIST_BASE_TYPED(&weibull_ops, mydist, struct weibull_t), +* .lambda = ..., +* .k = ..., +* }; * * If you want to define a distribution type, define a canonical set of * operations and define a type-specific initializer element like so: * -* struct foo { -* struct dist base; -* int omega; -* double tau; -* double phi; -* }; +* struct foo_t { +* struct dist_t base; +* int omega; +* double tau; +* double phi; +* }; * -* struct dist_ops foo_ops = ...; +* struct dist_ops_t foo_ops = ...; * -* #define FOO(OBJ) DIST_BASE_TYPED(&foo_ops, OBJ, struct foo) +* #define FOO(OBJ) DIST_BASE_TYPED(&foo_ops, OBJ, struct foo_t) * * Then users can do: * -* struct foo mydist = { -* FOO(mydist), -* .omega = ..., -* .tau = ..., -* .phi = ..., -* }; +* struct foo_t mydist = { +* FOO(mydist), +* .omega = ..., +* .tau = ..., +* .phi = ..., +* }; * * If you accidentally write * -* struct bar mydist = { -* FOO(mydist), -* ... -* }; +* struct bar_t mydist = { +* FOO(mydist), +* ... +* }; * * then the compiler will report a type mismatch in the sizeof * expression, which otherwise evaporates at runtime. @@ -110,107 +110,107 @@ struct dist { /** * Generic operations on distributions. These simply defer to the - * corresponding dist_ops function. In the parlance of C++, these call + * corresponding dist_ops_t function. In the parlance of C++, these call * virtual member functions. */ -const char *dist_name(const struct dist *); -double dist_sample(const struct dist *); -double dist_cdf(const struct dist *, double x); -double dist_sf(const struct dist *, double x); -double dist_icdf(const struct dist *, double p); -double dist_isf(const struct dist *, double p); +const char *dist_name(const struct dist_t *); +double dist_sample(const struct dist_t *); +double dist_cdf(const struct dist_t *, double x); +double dist_sf(const struct dist_t *, double x); +double dist_icdf(const struct dist_t *, double p); +double dist_isf(const struct dist_t *, double p); /** * Set of operations on a potentially parametric family of * distributions. In the parlance of C++, this would be called a * `vtable' and the members are virtual member functions. */ -struct dist_ops { +struct dist_ops_t { const char *name; - double (*sample)(const struct dist *); - double (*cdf)(const struct dist *, double x); - double (*sf)(const struct dist *, double x); - double (*icdf)(const struct dist *, double p); - double (*isf)(const struct dist *, double p); + double (*sample)(const struct dist_t *); + double (*cdf)(const struct dist_t *, double x); + double (*sf)(const struct dist_t *, double x); + double (*icdf)(const struct dist_t *, double p); + double (*isf)(const struct dist_t *, double p); }; /* Geometric distribution on positive number of trials before first success */ -struct geometric { - struct dist base; +struct geometric_t { + struct dist_t base; double p; /* success probability */ }; -extern const struct dist_ops geometric_ops; +extern const struct dist_ops_t geometric_ops; #define GEOMETRIC(OBJ) \ - DIST_BASE_TYPED(&geometric_ops, OBJ, struct geometric) + DIST_BASE_TYPED(&geometric_ops, OBJ, struct geometric_t) /* Pareto distribution */ -struct genpareto { - struct dist base; +struct genpareto_t { + struct dist_t base; double mu; double sigma; double xi; }; -extern const struct dist_ops genpareto_ops; +extern const struct dist_ops_t genpareto_ops; #define GENPARETO(OBJ) \ - DIST_BASE_TYPED(&genpareto_ops, OBJ, struct genpareto) + DIST_BASE_TYPED(&genpareto_ops, OBJ, struct genpareto_t) /* Weibull distribution */ -struct weibull { - struct dist base; +struct weibull_t { + struct dist_t base; double lambda; double k; }; -extern const struct dist_ops weibull_ops; +extern const struct dist_ops_t weibull_ops; #define WEIBULL(OBJ) \ - DIST_BASE_TYPED(&weibull_ops, OBJ, struct weibull) + DIST_BASE_TYPED(&weibull_ops, OBJ, struct weibull_t) /* Log-logistic distribution */ -struct log_logistic { - struct dist base; +struct log_logistic_t { + struct dist_t base; double alpha; double beta; }; -extern const struct dist_ops log_logistic_ops; +extern const struct dist_ops_t log_logistic_ops; #define LOG_LOGISTIC(OBJ) \ - DIST_BASE_TYPED(&log_logistic_ops, OBJ, struct log_logistic) + DIST_BASE_TYPED(&log_logistic_ops, OBJ, struct log_logistic_t) /* Logistic distribution */ -struct logistic { - struct dist base; +struct logistic_t { + struct dist_t base; double mu; double sigma; }; -extern const struct dist_ops logistic_ops; +extern const struct dist_ops_t logistic_ops; #define LOGISTIC(OBJ) \ - DIST_BASE_TYPED(&logistic_ops, OBJ, struct logistic) + DIST_BASE_TYPED(&logistic_ops, OBJ, struct logistic_t) /* Uniform distribution */ -struct uniform { - struct dist base; +struct uniform_t { + struct dist_t base; double a; double b; }; -extern const struct dist_ops uniform_ops; +extern const struct dist_ops_t uniform_ops; #define UNIFORM(OBJ) \ - DIST_BASE_TYPED(&uniform_ops, OBJ, struct uniform) + DIST_BASE_TYPED(&uniform_ops, OBJ, struct uniform_t) /** Only by unittests */ diff --git a/src/lib/memarea/lib_memarea.md b/src/lib/memarea/lib_memarea.md new file mode 100644 index 0000000000..fe5cb8293f --- /dev/null +++ b/src/lib/memarea/lib_memarea.md @@ -0,0 +1,28 @@ +@dir /lib/memarea +@brief lib/memarea: A fast arena-style allocator. + +This module has a fast "arena" style allocator, where memory is freed all at +once. This kind of allocation is very fast and avoids fragmentation, at the +expense of requiring all the data to be freed at the same time. We use this +for parsing and diff calculations. + +It's often handy to allocate a large number of tiny objects, all of which +need to disappear at the same time. You can do this in tor using the +memarea.c abstraction, which uses a set of grow-only buffers for allocation, +and only supports a single "free" operation at the end. + +Using memareas also helps you avoid memory fragmentation. You see, some libc +malloc implementations perform badly on the case where a large number of +small temporary objects are allocated at the same time as a few long-lived +objects of similar size. But if you use tor_malloc() for the long-lived ones +and a memarea for the temporary object, the malloc implementation is likelier +to do better. + +To create a new memarea, use `memarea_new()`. To drop all the storage from a +memarea, and invalidate its pointers, use `memarea_drop_all()`. + +The allocation functions `memarea_alloc()`, `memarea_alloc_zero()`, +`memarea_memdup()`, `memarea_strdup()`, and `memarea_strndup()` are analogous +to the similarly-named malloc() functions. There is intentionally no +`memarea_free()` or `memarea_realloc()`. + diff --git a/src/lib/memarea/memarea.c b/src/lib/memarea/memarea.c index f3bb79a1e2..d677c364a4 100644 --- a/src/lib/memarea/memarea.c +++ b/src/lib/memarea/memarea.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2019, The Tor Project, Inc. */ +/* Copyright (c) 2008-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/memarea/memarea.h b/src/lib/memarea/memarea.h index 9c23cf62e9..8b5e63e6b3 100644 --- a/src/lib/memarea/memarea.h +++ b/src/lib/memarea/memarea.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2019, The Tor Project, Inc. */ +/* Copyright (c) 2008-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -16,6 +16,9 @@ typedef struct memarea_t memarea_t; memarea_t *memarea_new(void); void memarea_drop_all_(memarea_t *area); +/** @copydoc memarea_drop_all_ + * + * Additionally, set <b>area</b> to NULL. */ #define memarea_drop_all(area) \ do { \ memarea_drop_all_(area); \ diff --git a/src/lib/meminfo/lib_meminfo.md b/src/lib/meminfo/lib_meminfo.md new file mode 100644 index 0000000000..87f509d648 --- /dev/null +++ b/src/lib/meminfo/lib_meminfo.md @@ -0,0 +1,5 @@ +@dir /lib/meminfo +@brief lib/meminfo: Inspecting malloc() usage. + +Only available when malloc() provides mallinfo() or something similar. + diff --git a/src/lib/meminfo/meminfo.c b/src/lib/meminfo/meminfo.c index bff71c2f05..0c5e0ed665 100644 --- a/src/lib/meminfo/meminfo.c +++ b/src/lib/meminfo/meminfo.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -37,7 +37,7 @@ #include <sys/sysctl.h> #endif -DISABLE_GCC_WARNING(aggregate-return) +DISABLE_GCC_WARNING("-Waggregate-return") /** Call the platform malloc info function, and dump the results to the log at * level <b>severity</b>. If no such function exists, do nothing. */ void @@ -58,7 +58,7 @@ tor_log_mallinfo(int severity) (void)severity; #endif /* defined(HAVE_MALLINFO) */ } -ENABLE_GCC_WARNING(aggregate-return) +ENABLE_GCC_WARNING("-Waggregate-return") #if defined(HW_PHYSMEM64) /* OpenBSD and NetBSD define this */ diff --git a/src/lib/meminfo/meminfo.h b/src/lib/meminfo/meminfo.h index 9580640f4d..a5ebfd5a6a 100644 --- a/src/lib/meminfo/meminfo.h +++ b/src/lib/meminfo/meminfo.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/net/address.c b/src/lib/net/address.c index 41017935e1..d623cdd131 100644 --- a/src/lib/net/address.c +++ b/src/lib/net/address.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -1393,7 +1393,7 @@ get_interface_addresses_win32(int severity, sa_family_t family) /* This is defined on Mac OS X */ #ifndef _SIZEOF_ADDR_IFREQ -#define _SIZEOF_ADDR_IFREQ sizeof +#define _SIZEOF_ADDR_IFREQ(x) sizeof(x) #endif /* Free ifc->ifc_buf safely. */ @@ -2002,7 +2002,7 @@ tor_addr_port_new(const tor_addr_t *addr, uint16_t port) return ap; } -/** Return true iff <a>a</b> and <b>b</b> are the same address and port */ +/** Return true iff <b>a</b> and <b>b</b> are the same address and port */ int tor_addr_port_eq(const tor_addr_port_t *a, const tor_addr_port_t *b) diff --git a/src/lib/net/address.h b/src/lib/net/address.h index 9b826c8359..815fb02283 100644 --- a/src/lib/net/address.h +++ b/src/lib/net/address.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -62,6 +62,7 @@ typedef uint8_t maskbits_t; struct in_addr; + /** Holds an IPv4 or IPv6 address. (Uses less memory than struct * sockaddr_storage.) */ typedef struct tor_addr_t @@ -133,6 +134,7 @@ tor_addr_to_in6_assert(const tor_addr_t *a) * Requires that <b>x</b> is actually an IPv6 address. */ #define tor_addr_to_in6_addr16(x) S6_ADDR16(*tor_addr_to_in6_assert(x)) + /** Given an IPv6 address <b>x</b>, yield it as an array of uint32_t. * * Requires that <b>x</b> is actually an IPv6 address. @@ -146,6 +148,7 @@ tor_addr_to_ipv4n(const tor_addr_t *a) { return a->family == AF_INET ? a->addr.in_addr.s_addr : 0; } + /** Return an IPv4 address in host order for <b>a</b>, or 0 if * <b>a</b> is not an IPv4 address. */ static inline uint32_t @@ -153,10 +156,11 @@ tor_addr_to_ipv4h(const tor_addr_t *a) { return ntohl(tor_addr_to_ipv4n(a)); } + /** Given an IPv6 address, return its mapped IPv4 address in host order, or * 0 if <b>a</b> is not an IPv6 address. * - * (Does not check whether the address is really a mapped address */ + * (Does not check whether the address is really a mapped address.) */ static inline uint32_t tor_addr_to_mapped_ipv4h(const tor_addr_t *a) { @@ -165,14 +169,13 @@ tor_addr_to_mapped_ipv4h(const tor_addr_t *a) // Work around an incorrect NULL pointer dereference warning in // "clang --analyze" due to limited analysis depth addr32 = tor_addr_to_in6_addr32(a); - // To improve performance, wrap this assertion in: - // #if !defined(__clang_analyzer__) || PARANOIA tor_assert(addr32); return ntohl(addr32[3]); } else { return 0; } } + /** Return the address family of <b>a</b>. Possible values are: * AF_INET6, AF_INET, AF_UNSPEC. */ static inline sa_family_t @@ -180,6 +183,7 @@ tor_addr_family(const tor_addr_t *a) { return a->family; } + /** Return an in_addr* equivalent to <b>a</b>, or NULL if <b>a</b> is not * an IPv4 address. */ static inline const struct in_addr * @@ -187,6 +191,7 @@ tor_addr_to_in(const tor_addr_t *a) { return a->family == AF_INET ? &a->addr.in_addr : NULL; } + /** Return true iff <b>a</b> is an IPv4 address equal to the host-ordered * address in <b>u</b>. */ static inline int @@ -209,19 +214,23 @@ char *tor_addr_to_str_dup(const tor_addr_t *addr) ATTR_MALLOC; /** Wrapper function of fmt_addr_impl(). It does not decorate IPv6 * addresses. */ #define fmt_addr(a) fmt_addr_impl((a), 0) + /** Wrapper function of fmt_addr_impl(). It decorates IPv6 * addresses. */ #define fmt_and_decorate_addr(a) fmt_addr_impl((a), 1) + const char *fmt_addr_impl(const tor_addr_t *addr, int decorate); const char *fmt_addrport(const tor_addr_t *addr, uint16_t port); const char * fmt_addr32(uint32_t addr); MOCK_DECL(int,get_interface_address6,(int severity, sa_family_t family, tor_addr_t *addr)); + struct smartlist_t; -void interface_address6_list_free_(struct smartlist_t * addrs);// XXXX +void interface_address6_list_free_(struct smartlist_t * addrs); #define interface_address6_list_free(addrs) \ FREE_AND_NULL(struct smartlist_t, interface_address6_list_free_, (addrs)) + MOCK_DECL(struct smartlist_t *,get_interface_address6_list,(int severity, sa_family_t family, int include_internal)); @@ -246,6 +255,7 @@ int tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2, uint64_t tor_addr_hash(const tor_addr_t *addr); struct sipkey; uint64_t tor_addr_keyed_hash(const struct sipkey *key, const tor_addr_t *addr); + int tor_addr_is_v4(const tor_addr_t *addr); int tor_addr_is_internal_(const tor_addr_t *ip, int for_listening, const char *filename, int lineno); @@ -276,11 +286,13 @@ int tor_addr_parse_PTR_name(tor_addr_t *result, const char *address, int tor_addr_parse_mask_ports(const char *s, unsigned flags, tor_addr_t *addr_out, maskbits_t *mask_out, uint16_t *port_min_out, uint16_t *port_max_out); + const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, size_t len, int decorate); int tor_addr_parse(tor_addr_t *addr, const char *src); void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src); void tor_addr_copy_tight(tor_addr_t *dest, const tor_addr_t *src); + void tor_addr_from_ipv4n(tor_addr_t *dest, uint32_t v4addr); /** Set <b>dest</b> to the IPv4 address encoded in <b>v4addr</b> in host * order. */ @@ -291,6 +303,7 @@ void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const char *bytes); #define tor_addr_from_in(dest, in) \ tor_addr_from_ipv4n((dest), (in)->s_addr); void tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6); + int tor_addr_is_null(const tor_addr_t *addr); int tor_addr_is_loopback(const tor_addr_t *addr); @@ -299,6 +312,7 @@ int tor_addr_is_valid_ipv4n(uint32_t v4n_addr, int for_listening); #define tor_addr_is_valid_ipv4h(v4h_addr, for_listening) \ tor_addr_is_valid_ipv4n(htonl(v4h_addr), (for_listening)) int tor_port_is_valid(uint16_t port, int for_listening); + /* Are addr and port both valid? */ #define tor_addr_port_is_valid(addr, port, for_listening) \ (tor_addr_is_valid((addr), (for_listening)) && \ @@ -329,9 +343,11 @@ int parse_port_range(const char *port, uint16_t *port_min_out, uint16_t *port_max_out); int addr_mask_get_bits(uint32_t mask); char *tor_dup_ip(uint32_t addr) ATTR_MALLOC; + MOCK_DECL(int,get_interface_address,(int severity, uint32_t *addr)); #define interface_address_list_free(lst)\ interface_address6_list_free(lst) + /** Return a smartlist of the IPv4 addresses of all interfaces on the server. * Excludes loopback and multicast addresses. Only includes internal addresses * if include_internal is true. (Note that a relay behind NAT may use an diff --git a/src/lib/net/alertsock.c b/src/lib/net/alertsock.c index cc59d7d893..537fdcaee4 100644 --- a/src/lib/net/alertsock.c +++ b/src/lib/net/alertsock.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/net/alertsock.h b/src/lib/net/alertsock.h index 4d0d0dd57c..dab4273cf1 100644 --- a/src/lib/net/alertsock.h +++ b/src/lib/net/alertsock.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/net/buffers_net.c b/src/lib/net/buffers_net.c index cfe1a7dc26..aa84451074 100644 --- a/src/lib/net/buffers_net.c +++ b/src/lib/net/buffers_net.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/net/buffers_net.h b/src/lib/net/buffers_net.h index 5058dd0a26..a45c23a273 100644 --- a/src/lib/net/buffers_net.h +++ b/src/lib/net/buffers_net.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/net/gethostname.c b/src/lib/net/gethostname.c index e54a1ea16e..001d95391d 100644 --- a/src/lib/net/gethostname.c +++ b/src/lib/net/gethostname.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/net/gethostname.h b/src/lib/net/gethostname.h index b3b77b0589..90f8056779 100644 --- a/src/lib/net/gethostname.h +++ b/src/lib/net/gethostname.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/net/inaddr.c b/src/lib/net/inaddr.c index d9ae7cd562..0d20d88901 100644 --- a/src/lib/net/inaddr.c +++ b/src/lib/net/inaddr.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -35,11 +35,11 @@ * (Like inet_aton(str,addr), but works on Windows and Solaris.) */ int -tor_inet_aton(const char *str, struct in_addr* addr) +tor_inet_aton(const char *str, struct in_addr *addr) { - unsigned a,b,c,d; + unsigned a, b, c, d; char more; - if (tor_sscanf(str, "%3u.%3u.%3u.%3u%c", &a,&b,&c,&d,&more) != 4) + if (tor_sscanf(str, "%3u.%3u.%3u.%3u%c", &a, &b, &c, &d, &more) != 4) return 0; if (a > 255) return 0; if (b > 255) return 0; diff --git a/src/lib/net/inaddr.h b/src/lib/net/inaddr.h index 602573944c..8d6766eb5d 100644 --- a/src/lib/net/inaddr.h +++ b/src/lib/net/inaddr.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/net/inaddr_st.h b/src/lib/net/inaddr_st.h index 230f29a63a..b9ee2b86cf 100644 --- a/src/lib/net/inaddr_st.h +++ b/src/lib/net/inaddr_st.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/net/lib_net.md b/src/lib/net/lib_net.md new file mode 100644 index 0000000000..b61878d827 --- /dev/null +++ b/src/lib/net/lib_net.md @@ -0,0 +1,6 @@ +@dir /lib/net +@brief lib/net: Low-level network-related code. + +This module includes address manipulation, compatibility wrappers, +convenience functions, and so on. + diff --git a/src/lib/net/nettypes.h b/src/lib/net/nettypes.h index 60039bac09..953673d4c3 100644 --- a/src/lib/net/nettypes.h +++ b/src/lib/net/nettypes.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/net/network_sys.c b/src/lib/net/network_sys.c index e0a2625d73..012fc56bba 100644 --- a/src/lib/net/network_sys.c +++ b/src/lib/net/network_sys.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/net/network_sys.h b/src/lib/net/network_sys.h index 43e62592ca..734533c7e8 100644 --- a/src/lib/net/network_sys.h +++ b/src/lib/net/network_sys.h @@ -1,8 +1,8 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** - * \file log_network.h + * \file network_sys.h * \brief Declare subsystem object for the network module. **/ diff --git a/src/lib/net/resolve.c b/src/lib/net/resolve.c index 442bc4a6b3..df079d5db3 100644 --- a/src/lib/net/resolve.c +++ b/src/lib/net/resolve.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/net/resolve.h b/src/lib/net/resolve.h index b979b2fb41..ef3d9fa176 100644 --- a/src/lib/net/resolve.h +++ b/src/lib/net/resolve.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/net/socket.c b/src/lib/net/socket.c index e1b82251ed..adc060a735 100644 --- a/src/lib/net/socket.c +++ b/src/lib/net/socket.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,7 +9,6 @@ * sockets. **/ -#define SOCKET_PRIVATE #include "lib/net/socket.h" #include "lib/net/socketpair.h" #include "lib/net/address.h" diff --git a/src/lib/net/socket.h b/src/lib/net/socket.h index 53a9f1bb92..46735fdef0 100644 --- a/src/lib/net/socket.h +++ b/src/lib/net/socket.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/net/socketpair.c b/src/lib/net/socketpair.c index f3a0c3770a..d4310020cb 100644 --- a/src/lib/net/socketpair.c +++ b/src/lib/net/socketpair.c @@ -1,6 +1,11 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ + +/** + * @file socketpair.c + * @brief Replacement socketpair() for systems that lack it + **/ #include "lib/cc/torint.h" #include "lib/net/socketpair.h" diff --git a/src/lib/net/socketpair.h b/src/lib/net/socketpair.h index 5820606973..b07016ab94 100644 --- a/src/lib/net/socketpair.h +++ b/src/lib/net/socketpair.h @@ -1,11 +1,16 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_SOCKETPAIR_H #define TOR_SOCKETPAIR_H +/** + * @file socketpair.h + * @brief Header for socketpair.c + **/ + #include "orconfig.h" #include "lib/testsupport/testsupport.h" #include "lib/net/nettypes.h" diff --git a/src/lib/net/socks5_status.h b/src/lib/net/socks5_status.h index e55119e0b0..2b663e00c4 100644 --- a/src/lib/net/socks5_status.h +++ b/src/lib/net/socks5_status.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -27,6 +27,16 @@ typedef enum { SOCKS5_TTL_EXPIRED = 0x06, SOCKS5_COMMAND_NOT_SUPPORTED = 0x07, SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED = 0x08, + + /* Extended error code (see prop304). Only used if the SocksPort flag + * "ExtendedErrors" is set. */ + SOCKS5_HS_NOT_FOUND = 0xF0, + SOCKS5_HS_IS_INVALID = 0xF1, + SOCKS5_HS_INTRO_FAILED = 0xF2, + SOCKS5_HS_REND_FAILED = 0xF3, + SOCKS5_HS_MISSING_CLIENT_AUTH = 0xF4, + SOCKS5_HS_BAD_CLIENT_AUTH = 0xF5, + SOCKS5_HS_BAD_ADDRESS = 0xF6, } socks5_reply_status_t; #endif /* !defined(TOR_SOCKS5_STATUS_H) */ diff --git a/src/lib/osinfo/lib_osinfo.md b/src/lib/osinfo/lib_osinfo.md new file mode 100644 index 0000000000..0678ecc21e --- /dev/null +++ b/src/lib/osinfo/lib_osinfo.md @@ -0,0 +1,8 @@ +@dir /lib/osinfo +@brief lib/osinfo: For inspecting the OS version and capabilities. + +In general, we use this module when we're telling the user what operating +system they are running. We shouldn't make decisions based on the output of +these checks: instead, we should have more specific checks, either at compile +time or run time, based on the observed system behavior. + diff --git a/src/lib/osinfo/uname.c b/src/lib/osinfo/uname.c index 34860c407a..ac99726f51 100644 --- a/src/lib/osinfo/uname.c +++ b/src/lib/osinfo/uname.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/osinfo/uname.h b/src/lib/osinfo/uname.h index 443a30d358..c6b1f43235 100644 --- a/src/lib/osinfo/uname.h +++ b/src/lib/osinfo/uname.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/daemon.c b/src/lib/process/daemon.c index ae34b5bcb8..b3b98a297e 100644 --- a/src/lib/process/daemon.c +++ b/src/lib/process/daemon.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/daemon.h b/src/lib/process/daemon.h index 423c498837..23f3117898 100644 --- a/src/lib/process/daemon.h +++ b/src/lib/process/daemon.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/env.c b/src/lib/process/env.c index 3912ade197..517b655a5e 100644 --- a/src/lib/process/env.c +++ b/src/lib/process/env.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -16,7 +16,6 @@ #include "lib/container/smartlist.h" #include "lib/log/util_bug.h" #include "lib/log/log.h" -#include "lib/malloc/malloc.h" #ifdef HAVE_UNISTD_H #include <unistd.h> diff --git a/src/lib/process/env.h b/src/lib/process/env.h index 19c2235970..7838dcaa90 100644 --- a/src/lib/process/env.h +++ b/src/lib/process/env.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/lib_process.md b/src/lib/process/lib_process.md new file mode 100644 index 0000000000..354129e70e --- /dev/null +++ b/src/lib/process/lib_process.md @@ -0,0 +1,2 @@ +@dir /lib/process +@brief lib/process: Launch and manage subprocesses. diff --git a/src/lib/process/pidfile.c b/src/lib/process/pidfile.c index 1b9d1c6d25..e7d9d2c47a 100644 --- a/src/lib/process/pidfile.c +++ b/src/lib/process/pidfile.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/pidfile.h b/src/lib/process/pidfile.h index af59041f80..d04302df3a 100644 --- a/src/lib/process/pidfile.h +++ b/src/lib/process/pidfile.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/process.c b/src/lib/process/process.c index 2194a603ff..12c1f9a772 100644 --- a/src/lib/process/process.c +++ b/src/lib/process/process.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -550,6 +550,7 @@ process_vprintf(process_t *process, char *data; size = tor_vasprintf(&data, format, args); + tor_assert(data != NULL); process_write(process, (uint8_t *)data, size); tor_free(data); } diff --git a/src/lib/process/process.h b/src/lib/process/process.h index 05c091a5bf..8879ec4f21 100644 --- a/src/lib/process/process.h +++ b/src/lib/process/process.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -15,6 +15,8 @@ #include "lib/malloc/malloc.h" #include "lib/string/printf.h" +#include <stdbool.h> + /** Maximum number of bytes to write to a process' stdin. */ #define PROCESS_MAX_WRITE (1024) @@ -35,8 +37,8 @@ typedef enum { const char *process_status_to_string(process_status_t status); typedef enum { - /** Pass complete \n-terminated lines to the - * callback (with the \n or \r\n removed). */ + /** Pass complete newline-terminated lines to the + * callback (with the LF or CRLF removed). */ PROCESS_PROTOCOL_LINE, /** Pass the raw response from read() to the callback. */ @@ -127,18 +129,19 @@ void process_notify_event_exit(process_t *process, process_exit_code_t); #ifdef PROCESS_PRIVATE -MOCK_DECL(STATIC int, process_read_stdout, (process_t *, buf_t *)); -MOCK_DECL(STATIC int, process_read_stderr, (process_t *, buf_t *)); -MOCK_DECL(STATIC void, process_write_stdin, (process_t *, buf_t *)); +struct buf_t; +MOCK_DECL(STATIC int, process_read_stdout, (process_t *, struct buf_t *)); +MOCK_DECL(STATIC int, process_read_stderr, (process_t *, struct buf_t *)); +MOCK_DECL(STATIC void, process_write_stdin, (process_t *, struct buf_t *)); STATIC void process_read_data(process_t *process, - buf_t *buffer, + struct buf_t *buffer, process_read_callback_t callback); STATIC void process_read_buffer(process_t *process, - buf_t *buffer, + struct buf_t *buffer, process_read_callback_t callback); STATIC void process_read_lines(process_t *process, - buf_t *buffer, + struct buf_t *buffer, process_read_callback_t callback); #endif /* defined(PROCESS_PRIVATE) */ diff --git a/src/lib/process/process_sys.c b/src/lib/process/process_sys.c index 3c809a00e8..283064cbfe 100644 --- a/src/lib/process/process_sys.c +++ b/src/lib/process/process_sys.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/process_sys.h b/src/lib/process/process_sys.h index b7a116d838..97b3aaebd0 100644 --- a/src/lib/process/process_sys.h +++ b/src/lib/process/process_sys.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/process_unix.c b/src/lib/process/process_unix.c index 8191bdc1f0..2b47e1874d 100644 --- a/src/lib/process/process_unix.c +++ b/src/lib/process/process_unix.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/process_unix.h b/src/lib/process/process_unix.h index da40b3e567..a6b8304d48 100644 --- a/src/lib/process/process_unix.h +++ b/src/lib/process/process_unix.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/process_win32.c b/src/lib/process/process_win32.c index 7e4082ad13..8683e17fc2 100644 --- a/src/lib/process/process_win32.c +++ b/src/lib/process/process_win32.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/process_win32.h b/src/lib/process/process_win32.h index a50d86df5b..0f264c8710 100644 --- a/src/lib/process/process_win32.h +++ b/src/lib/process/process_win32.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/restrict.c b/src/lib/process/restrict.c index fda284f3d9..a3ce52deaa 100644 --- a/src/lib/process/restrict.c +++ b/src/lib/process/restrict.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/restrict.h b/src/lib/process/restrict.h index 8491c99044..6173d5a438 100644 --- a/src/lib/process/restrict.h +++ b/src/lib/process/restrict.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/setuid.c b/src/lib/process/setuid.c index 3c94ce4bac..3cfd520a4f 100644 --- a/src/lib/process/setuid.c +++ b/src/lib/process/setuid.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -64,7 +64,7 @@ log_credential_status(void) /* log UIDs */ #ifdef HAVE_GETRESUID - if (getresuid(&ruid, &euid, &suid) != 0 ) { + if (getresuid(&ruid, &euid, &suid) != 0) { log_warn(LD_GENERAL, "Error getting changed UIDs: %s", strerror(errno)); return -1; } else { @@ -85,7 +85,7 @@ log_credential_status(void) /* log GIDs */ #ifdef HAVE_GETRESGID - if (getresgid(&rgid, &egid, &sgid) != 0 ) { + if (getresgid(&rgid, &egid, &sgid) != 0) { log_warn(LD_GENERAL, "Error getting changed GIDs: %s", strerror(errno)); return -1; } else { diff --git a/src/lib/process/setuid.h b/src/lib/process/setuid.h index a2125d2d06..fec35a1216 100644 --- a/src/lib/process/setuid.h +++ b/src/lib/process/setuid.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/waitpid.c b/src/lib/process/waitpid.c index 2b38481aeb..89ffe9fcfe 100644 --- a/src/lib/process/waitpid.c +++ b/src/lib/process/waitpid.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/waitpid.h b/src/lib/process/waitpid.h index 5faef468c1..171cf206fb 100644 --- a/src/lib/process/waitpid.h +++ b/src/lib/process/waitpid.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2019, The Tor Project, Inc. */ +/* Copyright (c) 2011-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/winprocess_sys.c b/src/lib/process/winprocess_sys.c index ad65886422..e43a77e467 100644 --- a/src/lib/process/winprocess_sys.c +++ b/src/lib/process/winprocess_sys.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/process/winprocess_sys.h b/src/lib/process/winprocess_sys.h index 7ab2aa04a6..bece1b3da9 100644 --- a/src/lib/process/winprocess_sys.h +++ b/src/lib/process/winprocess_sys.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/pubsub/lib_pubsub.md b/src/lib/pubsub/lib_pubsub.md new file mode 100644 index 0000000000..3f4c473436 --- /dev/null +++ b/src/lib/pubsub/lib_pubsub.md @@ -0,0 +1,14 @@ +@dir /lib/pubsub +@brief lib/pubsub: Publish-subscribe message passing. + +This module wraps the \refdir{lib/dispatch} module, to provide a more +ergonomic and type-safe approach to message passing. + +In general, we favor this mechanism for cases where higher-level modules +need to be notified when something happens in lower-level modules. (The +alternative would be calling up from the lower-level modules, which +would be error-prone; or maintaining lists of function-pointers, which +would be clumsy and tend to complicate the call graph.) + +See pubsub.c for more information. + diff --git a/src/lib/pubsub/pub_binding_st.h b/src/lib/pubsub/pub_binding_st.h index d841bf3f54..d7c562fc35 100644 --- a/src/lib/pubsub/pub_binding_st.h +++ b/src/lib/pubsub/pub_binding_st.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/pubsub/publish_subscribe.md b/src/lib/pubsub/publish_subscribe.md new file mode 100644 index 0000000000..bb05b100b1 --- /dev/null +++ b/src/lib/pubsub/publish_subscribe.md @@ -0,0 +1,144 @@ + +@page publish_subscribe Publish-subscribe message passing in Tor + +@tableofcontents + +## Introduction + +Tor has introduced a generic publish-subscribe mechanism for delivering +messages internally. It is meant to help us improve the modularity of +our code, by avoiding direct coupling between modules that don't +actually need to invoke one another. + +This publish-subscribe mechanism is *not* meant for handing +multithreading or multiprocess issues, thought we hope that eventually +it might be extended and adapted for that purpose. Instead, we use +publish-subscribe today to decouple modules that shouldn't be calling +each other directly. + +For example, there are numerous parts of our code that might need to +take action when a circuit is completed: a controller might need to be +informed, an onion service negotiation might need to be attached, a +guard might need to be marked as working, or a client connection might +need to be attached. But many of those actions occur at a higher layer +than circuit completion: calling them directly is a layering violation, +and makes our code harder to understand and analyze. + +But with message-passing, we can invert this layering violation: circuit +completion can become a "message" that the circuit code publishes, and +to which higher-level layers subscribe. This means that circuit +handling can be decoupled from higher-level modules, and stay nice and +simple. (@ref pubsub_notyet "1") + +> @anchor pubsub_notyet 1. Unfortunately, like most of our code, circuit +> handling is _not_ yet refactored to use publish-subscribe throughout. +> Instead, layer violations of the type described here are pretty common +> in Tor today. To see a small part of what happens when a circuit is +> completed today, have a look at circuit_build_no_more_hops() and its +> associated code. + +## Channels and delivery policies + +To work with messages, especially when refactoring existing code, you'll +need to understand "channels" and "delivery policies". + +Every message is delivered on a "message channel". Each channel +(conceptually) a queue-like structure that can support an arbitrarily +number of message types. Where channels vary is their delivery +mechanisms, and their guarantees about when messages are processed. + +Currently, three delivery policies are possible: + + - `DELIV_PROMPT` -- causes messages to be processed via a callback in + Tor's event loop. This is generally the best choice, since it + avoids unexpected growth of the stack. + + - `DELIV_IMMEDIATE` -- causes messages to be processed immediately + on the call stack when they are published. This choice grows the + stack, and can lead to unexpected complexity in the call graph. + We should only use it when necessary. + + - `DELIV_NEVER` -- causes messages not to be delivered by the message + dispatch system at all. Instead, some other part of the code must + call dispatch_flush() to get the messages delivered. + +See mainloop_pubsub.c and mainloop_pubsub.h for more information and +implementation details. + +## Layers: Dispatch vs publish-subsubscribe vs mainloop. + +At the lowest level, messages are sent via the "dispatcher" module in +@refdir{lib/dispatch}. For performance, this dispatcher works with a +untyped messages. Publishers, subscribers, channels, and messages are +distinguished by short integers. Associated data is handled as +dynamically-typed data pointers, and its types are also stored as short +integers. + +Naturally, this results in a type-unsafe C API, so most other modules +shouldn't invoke @refdir{lib/dispatch} directly. At a higher level, +@refdir{lib/pubsub} defines a set of functions and macros that make +messages named and type-safe. This is the one that other modules should +use when they want to send or receive a message. + +The two modules above do not handle message delivery. Instead, the +dispatch module takes a callback that it can invoke when a channel +becomes nonempty, and defines a dispatch_flush() function to deliver all +the messages queued in a channel. The work of actually making sure that +dispatch_flush() is called when appropriate falls to the main loop, +which needs to integrate the message dispatcher with the rest of our +events and callbacks. This work happens in mainloop_pubsub.c. + + +## How to publish and subscribe + +This section gives an overview of how to make new messages and how to +use them. For full details, see pubsub_macros.h. + +Before anybody can publish or subscribe to a message, the message must +be declared, typically in a header. This uses DECLARE_MESSAGE() or +DECLARE_MESSAGE_INT(). + +Only subsystems can publish or subscribe messages. For more information +about the subsystems architecture, see @ref initialization. + +To publish a message, you must: + - Include the header that declares the message. + - Declare a set of helper functions via DECLARE_PUBLISH(). These + must be visible wherever you call PUBLISH(). + - Call PUBLISH() to actually send a message. + - Connect your subsystem to the dispatcher by calling + DISPATCH_ADD_PUB() from your subsystem's subsys_fns_t.add_pubsub + callback. + +To subscribe to a message, you must: + - Include the header that declares the message. + - Declare a callback function to be invoked when the message is delivered. + - Use DISPATCH_SUBSCRIBE at file scope to define a set of wrapper + functions to call your callback function with the appropriate type. + - Connect your subsystem to the dispatcher by calling + DISPATCH_ADD_SUB() from your subsystem's subsys_fns_t.add_pubsub + callback. + +Again, the file-level documentation for pubsub_macros.h describes how to +declare a message, how to publish it, and how to subscribe to it. + +## Designing good messages + +**Frequency**: +The publish-subscribe system uses a few function calls +and allocations for each message sent. This makes it unsuitable for +very-high-bandwidth events, like "receiving a single data cell" or "a +socket has become writable." It's fine, however, for events that +ordinarily happen a bit less frequently than that, like a circuit +getting finished, a new connection getting opened, or so on. + +**Semantics**: +A message should declare that something has happened or is happening, +not that something in particular should be done. + +For example, suppose you want to set up a message so that onion services +clean up their replay caches whenever we're low on memory. The event +should be something like `memory_low`, not `clean_up_replay_caches`. +The latter name would imply that the publisher knew who was subscribing +to the message and what they intended to do about it, which would be a +layering violation. diff --git a/src/lib/pubsub/pubsub.h b/src/lib/pubsub/pubsub.h index 5346b07517..d0a4d317f3 100644 --- a/src/lib/pubsub/pubsub.h +++ b/src/lib/pubsub/pubsub.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/pubsub/pubsub_build.c b/src/lib/pubsub/pubsub_build.c index e44b7d76ec..3c134f015c 100644 --- a/src/lib/pubsub/pubsub_build.c +++ b/src/lib/pubsub/pubsub_build.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/pubsub/pubsub_build.h b/src/lib/pubsub/pubsub_build.h index 5a0c5f5bd3..2781b8251a 100644 --- a/src/lib/pubsub/pubsub_build.h +++ b/src/lib/pubsub/pubsub_build.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -85,6 +85,11 @@ struct dispatch_t *pubsub_builder_finalize(pubsub_builder_t *, **/ void pubsub_items_clear_bindings(pubsub_items_t *items); +/** + * @copydoc pubsub_items_free_ + * + * Additionally, set the pointer <b>cfg</b> to NULL. + **/ #define pubsub_items_free(cfg) \ FREE_AND_NULL(pubsub_items_t, pubsub_items_free_, (cfg)) void pubsub_items_free_(pubsub_items_t *cfg); diff --git a/src/lib/pubsub/pubsub_builder_st.h b/src/lib/pubsub/pubsub_builder_st.h index 545aa3f3ef..57de1240ee 100644 --- a/src/lib/pubsub/pubsub_builder_st.h +++ b/src/lib/pubsub/pubsub_builder_st.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/pubsub/pubsub_check.c b/src/lib/pubsub/pubsub_check.c index bf1196df2c..dbcbb14746 100644 --- a/src/lib/pubsub/pubsub_check.c +++ b/src/lib/pubsub/pubsub_check.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,7 +9,9 @@ * @brief Enforce various requirements on a pubsub_builder. **/ +/** @{ */ #define PUBSUB_PRIVATE +/** @} */ #include "lib/dispatch/dispatch_naming.h" #include "lib/dispatch/msgtypes.h" diff --git a/src/lib/pubsub/pubsub_connect.h b/src/lib/pubsub/pubsub_connect.h index 0ad106044e..b0d6ae7e92 100644 --- a/src/lib/pubsub/pubsub_connect.h +++ b/src/lib/pubsub/pubsub_connect.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/pubsub/pubsub_flags.h b/src/lib/pubsub/pubsub_flags.h index 53c6e49565..9912c1ae89 100644 --- a/src/lib/pubsub/pubsub_flags.h +++ b/src/lib/pubsub/pubsub_flags.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/pubsub/pubsub_macros.h b/src/lib/pubsub/pubsub_macros.h index 357e59fd54..e5ffbe501a 100644 --- a/src/lib/pubsub/pubsub_macros.h +++ b/src/lib/pubsub/pubsub_macros.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -163,7 +163,7 @@ * hookfn with the appropriate arguments. */ -/* Macro to declare common elements shared by DECLARE_MESSAGE and +/** Macro to declare common elements shared by DECLARE_MESSAGE and * DECLARE_MESSAGE_INT. Don't call this directly. * * Note that the "msg_arg_name" string constant is defined in each @@ -288,7 +288,7 @@ ( 0 ? (publish_fn__ ##messagename((msg_arg_type__##messagename)0), 1) \ : 1) -/* +/** * This macro is for internal use. It backs DISPATCH_ADD_PUB*() */ #define DISPATCH_ADD_PUB_(connector, channel, messagename, flags) \ @@ -322,7 +322,7 @@ #define DISPATCH_ADD_PUB_EXCL(connector, channel, messagename) \ DISPATCH_ADD_PUB_(connector, channel, messagename, DISP_FLAG_EXCL) -/* +/** * This macro is for internal use. It backs DISPATCH_ADD_SUB*() */ #define DISPATCH_ADD_SUB_(connector, channel, messagename, flags) \ @@ -334,7 +334,7 @@ (flags), \ __FILE__, \ __LINE__) -/* +/** * Use a given connector and channel name to declare that this subsystem will * receive a given message type. * diff --git a/src/lib/pubsub/pubsub_publish.c b/src/lib/pubsub/pubsub_publish.c index 454a335a78..84c7dae02c 100644 --- a/src/lib/pubsub/pubsub_publish.c +++ b/src/lib/pubsub/pubsub_publish.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/pubsub/pubsub_publish.h b/src/lib/pubsub/pubsub_publish.h index 0686a465de..d9d6fa9ba5 100644 --- a/src/lib/pubsub/pubsub_publish.h +++ b/src/lib/pubsub/pubsub_publish.h @@ -1,9 +1,14 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file pubsub_publish.h + * @brief Header for pubsub_publish.c + **/ + #ifndef TOR_PUBSUB_PUBLISH_H #define TOR_PUBSUB_PUBLISH_H diff --git a/src/lib/sandbox/lib_sandbox.md b/src/lib/sandbox/lib_sandbox.md new file mode 100644 index 0000000000..dd168c9b13 --- /dev/null +++ b/src/lib/sandbox/lib_sandbox.md @@ -0,0 +1,15 @@ +@dir /lib/sandbox +@brief lib/sandbox: Linux seccomp2-based sandbox. + +This module uses Linux's seccomp2 facility via the +[`libseccomp` library](https://github.com/seccomp/libseccomp), to restrict +the set of system calls that Tor is allowed to invoke while it is running. + +Because there are many libc versions that invoke different system calls, and +because handling strings is quite complex, this module is more complex and +less portable than it needs to be. + +A better architecture would put the responsibility for invoking tricky system +calls (like open()) in another, less restricted process, and give that +process responsibility for enforcing our sandbox rules. + diff --git a/src/lib/sandbox/sandbox.c b/src/lib/sandbox/sandbox.c index 3515e8854e..b917912f4d 100644 --- a/src/lib/sandbox/sandbox.c +++ b/src/lib/sandbox/sandbox.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -82,7 +82,7 @@ #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \ defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) #define USE_BACKTRACE -#define EXPOSE_CLEAN_BACKTRACE +#define BACKTRACE_PRIVATE #include "lib/err/backtrace.h" #endif /* defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && ... */ @@ -166,6 +166,7 @@ static int filter_nopar_gen[] = { #ifdef __NR_fstat64 SCMP_SYS(fstat64), #endif + SCMP_SYS(fsync), SCMP_SYS(futex), SCMP_SYS(getdents), SCMP_SYS(getdents64), @@ -265,6 +266,11 @@ static int filter_nopar_gen[] = { SCMP_SYS(listen), SCMP_SYS(connect), SCMP_SYS(getsockname), +#ifdef ENABLE_NSS +#ifdef __NR_getpeername + SCMP_SYS(getpeername), +#endif +#endif SCMP_SYS(recvmsg), SCMP_SYS(recvfrom), SCMP_SYS(sendto), @@ -648,6 +654,15 @@ sb_socket(scmp_filter_ctx ctx, sandbox_cfg_t *filter) } } +#ifdef ENABLE_NSS + rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), + SCMP_CMP(0, SCMP_CMP_EQ, PF_INET), + SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM), + SCMP_CMP(2, SCMP_CMP_EQ, IPPROTO_IP)); + if (rc) + return rc; +#endif + rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), SCMP_CMP(0, SCMP_CMP_EQ, PF_UNIX), SCMP_CMP_MASKED(1, SOCK_CLOEXEC|SOCK_NONBLOCK, SOCK_STREAM), diff --git a/src/lib/sandbox/sandbox.h b/src/lib/sandbox/sandbox.h index b4ae6e5c07..b50df48255 100644 --- a/src/lib/sandbox/sandbox.h +++ b/src/lib/sandbox/sandbox.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -29,10 +29,10 @@ #define USE_LIBSECCOMP #endif -struct sandbox_cfg_elem; +struct sandbox_cfg_elem_t; /** Typedef to structure used to manage a sandbox configuration. */ -typedef struct sandbox_cfg_elem sandbox_cfg_t; +typedef struct sandbox_cfg_elem_t sandbox_cfg_t; /** * Linux definitions @@ -58,7 +58,7 @@ typedef enum { * Configuration parameter structure associated with the LIBSECCOMP2 * implementation. */ -typedef struct smp_param { +typedef struct smp_param_t { /** syscall associated with parameter. */ int syscall; @@ -77,7 +77,7 @@ typedef struct smp_param { * It is implemented as a linked list of parameters. Currently only controls * parameters for open, openat, execve, stat64. */ -struct sandbox_cfg_elem { +struct sandbox_cfg_elem_t { /** Sandbox implementation which dictates the parameter type. */ SB_IMPL implem; @@ -85,7 +85,7 @@ struct sandbox_cfg_elem { smp_param_t *param; /** Next element of the configuration*/ - struct sandbox_cfg_elem *next; + struct sandbox_cfg_elem_t *next; }; /** Function pointer defining the prototype of a filter function.*/ diff --git a/src/lib/smartlist_core/lib_smartlist_core.md b/src/lib/smartlist_core/lib_smartlist_core.md new file mode 100644 index 0000000000..c031dd6f24 --- /dev/null +++ b/src/lib/smartlist_core/lib_smartlist_core.md @@ -0,0 +1,10 @@ +@dir /lib/smartlist_core +@brief lib/smartlist_core: Minimal dynamic array implementation + +A `smartlist_t` is a dynamic array type for holding `void *`. We use it +throughout the rest of the codebase. + +There are higher-level pieces in \refdir{lib/container} but +the ones in lib/smartlist_core are used by the logging code, and therefore +cannot use the logging code. + diff --git a/src/lib/smartlist_core/smartlist_core.c b/src/lib/smartlist_core/smartlist_core.c index 6b0a305a93..571d17aa5d 100644 --- a/src/lib/smartlist_core/smartlist_core.c +++ b/src/lib/smartlist_core/smartlist_core.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/smartlist_core/smartlist_core.h b/src/lib/smartlist_core/smartlist_core.h index 36f23e2009..de6fe69d3a 100644 --- a/src/lib/smartlist_core/smartlist_core.h +++ b/src/lib/smartlist_core/smartlist_core.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/smartlist_core/smartlist_foreach.h b/src/lib/smartlist_core/smartlist_foreach.h index a1fbcd444c..03edb80f05 100644 --- a/src/lib/smartlist_core/smartlist_foreach.h +++ b/src/lib/smartlist_core/smartlist_foreach.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/smartlist_core/smartlist_split.c b/src/lib/smartlist_core/smartlist_split.c index c9cf59851f..b76b87406d 100644 --- a/src/lib/smartlist_core/smartlist_split.c +++ b/src/lib/smartlist_core/smartlist_split.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/smartlist_core/smartlist_split.h b/src/lib/smartlist_core/smartlist_split.h index e2cc7245b7..fc964201e9 100644 --- a/src/lib/smartlist_core/smartlist_split.h +++ b/src/lib/smartlist_core/smartlist_split.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/string/compat_ctype.c b/src/lib/string/compat_ctype.c index f5d82be3ae..a7668bfbfb 100644 --- a/src/lib/string/compat_ctype.c +++ b/src/lib/string/compat_ctype.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -29,6 +29,7 @@ const uint32_t TOR_ISPRINT_TABLE[8] = { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 }; const uint32_t TOR_ISUPPER_TABLE[8] = { 0, 0, 0x7fffffe, 0, 0, 0, 0, 0 }; const uint32_t TOR_ISLOWER_TABLE[8] = { 0, 0, 0, 0x7fffffe, 0, 0, 0, 0 }; +/**@}*/ /** Upper-casing and lowercasing tables to map characters to upper/lowercase * equivalents. Used by tor_toupper() and tor_tolower(). */ diff --git a/src/lib/string/compat_ctype.h b/src/lib/string/compat_ctype.h index dbddd356c1..53ee6066f8 100644 --- a/src/lib/string/compat_ctype.h +++ b/src/lib/string/compat_ctype.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/string/compat_string.c b/src/lib/string/compat_string.c index 187f784be5..2bd3c2f2b4 100644 --- a/src/lib/string/compat_string.c +++ b/src/lib/string/compat_string.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/string/compat_string.h b/src/lib/string/compat_string.h index ffc892c3e5..f05265bdcc 100644 --- a/src/lib/string/compat_string.h +++ b/src/lib/string/compat_string.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/string/lib_string.md b/src/lib/string/lib_string.md new file mode 100644 index 0000000000..98e3e652ed --- /dev/null +++ b/src/lib/string/lib_string.md @@ -0,0 +1,13 @@ +@dir /lib/string +@brief lib/string: Low-level string manipulation. + +We have a number of compatibility functions here: some are for handling +functionality that is not implemented (or not implemented the same) on every +platform; some are for providing locale-independent versions of libc +functions that would otherwise be defined differently for different users. + +Other functions here are for common string-manipulation operations that we do +in the rest of the codebase. + +Any string function high-level enough to need logging belongs in a +higher-level module. diff --git a/src/lib/string/parse_int.c b/src/lib/string/parse_int.c index fbdd554a47..11ce0fa415 100644 --- a/src/lib/string/parse_int.c +++ b/src/lib/string/parse_int.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -9,6 +9,7 @@ **/ #include "lib/string/parse_int.h" +#include "lib/cc/compat_compiler.h" #include <errno.h> #include <stdlib.h> @@ -17,6 +18,7 @@ /* Helper: common code to check whether the result of a strtol or strtoul or * strtoll is correct. */ #define CHECK_STRTOX_RESULT() \ + STMT_BEGIN \ /* Did an overflow occur? */ \ if (errno == ERANGE) \ goto err; \ @@ -38,7 +40,8 @@ err: \ if (ok) *ok = 0; \ if (next) *next = endptr; \ - return 0 + return 0; \ + STMT_END /** Extract a long from the start of <b>s</b>, in the given numeric * <b>base</b>. If <b>base</b> is 0, <b>s</b> is parsed as a decimal, diff --git a/src/lib/string/parse_int.h b/src/lib/string/parse_int.h index 50d48b44c5..27939ade61 100644 --- a/src/lib/string/parse_int.h +++ b/src/lib/string/parse_int.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/string/printf.c b/src/lib/string/printf.c index 26203932e4..86d860935e 100644 --- a/src/lib/string/printf.c +++ b/src/lib/string/printf.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/string/printf.h b/src/lib/string/printf.h index 6e90770f81..5ab751b338 100644 --- a/src/lib/string/printf.h +++ b/src/lib/string/printf.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/string/scanf.c b/src/lib/string/scanf.c index 1bc39b5182..89d1683204 100644 --- a/src/lib/string/scanf.c +++ b/src/lib/string/scanf.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/string/scanf.h b/src/lib/string/scanf.h index b642e242db..67e9c5eb78 100644 --- a/src/lib/string/scanf.h +++ b/src/lib/string/scanf.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/string/strings.md b/src/lib/string/strings.md new file mode 100644 index 0000000000..b22574a05a --- /dev/null +++ b/src/lib/string/strings.md @@ -0,0 +1,102 @@ + +@page strings String processing in Tor + +Since you're reading about a C program, you probably expected this +section: it's full of functions for manipulating the (notoriously +dubious) C string abstraction. I'll describe some often-missed +highlights here. + +### Comparing strings and memory chunks ### + +We provide strcmpstart() and strcmpend() to perform a strcmp with the start +or end of a string. + + tor_assert(!strcmpstart("Hello world","Hello")); + tor_assert(!strcmpend("Hello world","world")); + + tor_assert(!strcasecmpstart("HELLO WORLD","Hello")); + tor_assert(!strcasecmpend("HELLO WORLD","world")); + +To compare two string pointers, either of which might be NULL, use +strcmp_opt(). + +To search for a string or a chunk of memory within a non-null +terminated memory block, use tor_memstr or tor_memmem respectively. + +We avoid using memcmp() directly, since it tends to be used in cases +when having a constant-time operation would be better. Instead, we +recommend tor_memeq() and tor_memneq() for when you need a +constant-time operation. In cases when you need a fast comparison, +and timing leaks are not a danger, you can use fast_memeq() and +fast_memneq(). + +It's a common pattern to take a string representing one or more lines +of text, and search within it for some other string, at the start of a +line. You could search for "\\ntarget", but that would miss the first +line. Instead, use find_str_at_start_of_line. + +### Parsing text ### + +Over the years, we have accumulated lots of ways to parse text -- +probably too many. Refactoring them to be safer and saner could be a +good project! The one that seems most error-resistant is tokenizing +text with smartlist_split_strings(). This function takes a smartlist, +a string, and a separator, and splits the string along occurrences of +the separator, adding new strings for the sub-elements to the given +smartlist. + +To handle time, you can use one of the functions mentioned above in +"Parsing and encoding time values". + +For numbers in general, use the tor_parse_{long,ulong,double,uint64} +family of functions. Each of these can be called in a few ways. The +most general is as follows: + + const int BASE = 10; + const int MINVAL = 10, MAXVAL = 10000; + const char *next; + int ok; + long lng = tor_parse_long("100", BASE, MINVAL, MAXVAL, &ok, &next); + +The return value should be ignored if "ok" is set to false. The input +string needs to contain an entire number, or it's considered +invalid... unless the "next" pointer is available, in which case extra +characters at the end are allowed, and "next" is set to point to the +first such character. + +### Generating blocks of text ### + +For not-too-large blocks of text, we provide tor_asprintf(), which +behaves like other members of the sprintf() family, except that it +always allocates enough memory on the heap for its output. + +For larger blocks: Rather than using strlcat and strlcpy to build +text, or keeping pointers to the interior of a memory block, we +recommend that you use the smartlist_* functions to build a smartlist +full of substrings in order. Then you can concatenate them into a +single string with smartlist_join_strings(), which also takes optional +separator and terminator arguments. + +Alternatively, you might find it more convenient (and more +allocation-efficient) to use the buffer API in buffers.c: Construct a buf_t +object, add your data to it with buf_add_string(), buf_add_printf(), and so +on, then call buf_extract() to get the resulting output. + +As a convenience, we provide smartlist_add_asprintf(), which combines +the two methods above together. Many of the cryptographic digest +functions also accept a not-yet-concatenated smartlist of strings. + +### Logging helpers ### + +Often we'd like to log a value that comes from an untrusted source. +To do this, use escaped() to escape the nonprintable characters and +other confusing elements in a string, and surround it by quotes. (Use +esc_for_log() if you need to allocate a new string.) + +It's also handy to put memory chunks into hexadecimal before logging; +you can use hex_str(memory, length) for that. + +The escaped() and hex_str() functions both provide outputs that are +only valid till they are next invoked; they are not threadsafe. + +*/ diff --git a/src/lib/string/util_string.c b/src/lib/string/util_string.c index f5061a11d2..c8f12d780e 100644 --- a/src/lib/string/util_string.c +++ b/src/lib/string/util_string.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -506,6 +506,23 @@ validate_char(const uint8_t *c, uint8_t len) int string_is_utf8(const char *str, size_t len) { + // If str is NULL, don't try to read it + if (!str) { + // We could test for this case, but the low-level logs would produce + // confusing test output. + // LCOV_EXCL_START + if (len) { + // Use the low-level logging function, so that the log module can + // validate UTF-8 (if needed in future code) + tor_log_err_sigsafe( + "BUG: string_is_utf8() called with NULL str but non-zero len."); + // Since it's a bug, we should probably reject this string + return false; + } + // LCOV_EXCL_STOP + return true; + } + for (size_t i = 0; i < len;) { uint8_t num_bytes = bytes_in_char(str[i]); if (num_bytes == 0) // Invalid leading byte found. @@ -530,8 +547,8 @@ string_is_utf8(const char *str, size_t len) int string_is_utf8_no_bom(const char *str, size_t len) { - if (len >= 3 && (!strcmpstart(str, "\uFEFF") || - !strcmpstart(str, "\uFFFE"))) { + if (str && len >= 3 && (!strcmpstart(str, "\uFEFF") || + !strcmpstart(str, "\uFFFE"))) { return false; } return string_is_utf8(str, len); diff --git a/src/lib/string/util_string.h b/src/lib/string/util_string.h index b3c6841d41..e89233df88 100644 --- a/src/lib/string/util_string.h +++ b/src/lib/string/util_string.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/subsys/initialization.md b/src/lib/subsys/initialization.md new file mode 100644 index 0000000000..012ab7000d --- /dev/null +++ b/src/lib/subsys/initialization.md @@ -0,0 +1,75 @@ + +@page initialization Initialization and shutdown + +@tableofcontents + +@section overview Overview + +Tor has a single entry point: tor_run_main() in main.c. All the ways of +starting a Tor process (ntmain.c, tor_main.c, and tor_api.c) work by invoking tor_run_main(). + +The tor_run_main() function normally exits (@ref init_exceptwhen "1") by +returning: not by calling abort() or exit(). Before it returns, it calls +tor_cleanup() in shutdown.c. + +Conceptually, there are several stages in running Tor. + +1. First, we initialize those modules that do not depend on the + configuration. This happens in the first half of tor_run_main(), and the + first half of tor_init(). (@ref init_pending_refactor "2") + +2. Second, we parse the command line and our configuration, and configure + systems that depend on our configuration or state. This configuration + happens midway through tor_init(), which invokes + options_init_from_torrc(). We then initialize more systems from the + second half of tor_init(). + +3. At this point we may exit early if we have been asked to do something + requiring no further initialization, like printing our version number or + creating a new signing key. Otherwise, we proceed to run_tor_main_loop(), + which initializes some network-specific parts of Tor, grabs some + daemon-only resources (like the data directory lock) and starts Tor itself + running. + + +> @anchor init_exceptwhen 1. tor_run_main() _can_ terminate with a call to +> abort() or exit(), but only when crashing due to a bug, or when forking to +> run as a daemon. + +> @anchor init_pending_refactor 2. The pieces of code that I'm describing as +> "the first part of tor_init()" and so on deserve to be functions with their +> own name. I'd like to refactor them, but before I do so, there is some +> slight reorganization that needs to happen. Notably, the +> nt_service_parse_options() call ought logically to be later in our +> initialization sequence. See @ticket{32447} for our refactoring progress. + + +@section subsys Subsystems and initialization + +Our current convention is to use the subsystem mechanism to initialize and +clean up pieces of Tor. The more recently updated pieces of Tor will use +this mechanism. For examples, see e.g. time_sys.c or log_sys.c. + +In simplest terms, a **subsytem** is a logically separate part of Tor that +can be initialized, shut down, managed, and configured somewhat independently +of the rest of the program. + +The subsys_fns_t type describes a subsystem and a set of functions that +initialize it, desconstruct it, and so on. To define a subsystem, we declare +a `const` instance of subsys_fns_t. See the documentation for subsys_fns_t +for a full list of these functions. + +After defining a subsytem, it must be inserted in subsystem_list.c. At that +point, table-driven mechanisms in subsysmgr.c will invoke its functions when +appropriate. + +@subsection vsconfig Initialization versus configuration + +We note that the initialization phase of Tor occurs before any configuration +is read from disk -- and therefore before any other files are read from +disk. Therefore, any behavior that depends on Tor's configuration or state +must occur _after_ the initialization process, during configuration. + + + + diff --git a/src/lib/subsys/lib_subsys.md b/src/lib/subsys/lib_subsys.md new file mode 100644 index 0000000000..764d25d1b6 --- /dev/null +++ b/src/lib/subsys/lib_subsys.md @@ -0,0 +1,32 @@ +@dir /lib/subsys +@brief lib/subsys: Types for declaring a "subsystem". + +## Subsystems in Tor + +A subsystem is a module with support for initialization, shutdown, +configuration, and so on. + +Many parts of Tor can be initialized, cleaned up, and configured somewhat +independently through a table-driven mechanism. Each such part is called a +"subsystem". + +To declare a subsystem, make a global `const` instance of the `subsys_fns_t` +type, filling in the function pointer fields that you require with ones +corresponding to your subsystem. Any function pointers left as "NULL" will +be a no-op. Each system must have a name and a "level", which corresponds to +the order in which it is initialized. (See `app/main/subsystem_list.c` for a +list of current subsystems and their levels.) + +Then, insert your subsystem in the list in `app/main/subsystem_list.c`. It +will need to occupy a position corresponding to its level. + +At this point, your subsystem will be handled like the others: it will get +initialized at startup, torn down at exit, and so on. + +Historical note: Not all of Tor's code is currently handled as +subsystems. As you work with older code, you may see some parts of the code +that are initialized from `tor_init()` or `run_tor_main_loop()` or +`tor_run_main()`; and torn down from `tor_cleanup()`. We aim to migrate +these to subsystems over time; please don't add any new code that follows +this pattern. + diff --git a/src/lib/subsys/subsys.h b/src/lib/subsys/subsys.h index 21f984f32d..c05b69af39 100644 --- a/src/lib/subsys/subsys.h +++ b/src/lib/subsys/subsys.h @@ -1,14 +1,20 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file subsys.h + * @brief Types used to declare a subsystem. + **/ + #ifndef TOR_SUBSYS_T #define TOR_SUBSYS_T #include <stdbool.h> struct pubsub_connector_t; +struct config_format_t; /** * A subsystem is a part of Tor that is initialized, shut down, configured, @@ -17,8 +23,16 @@ struct pubsub_connector_t; * All callbacks are optional -- if a callback is set to NULL, the subsystem * manager will treat it as a no-op. * - * You should use c99 named-field initializers with this structure: we - * will be adding more fields, often in the middle of the structure. + * You should use c99 named-field initializers with this structure, for + * readability and safety. (There are a lot of functions here, all of them + * optional, and many of them with similar signatures.) + * + * See @ref initialization for more information about initialization and + * shutdown in Tor. + * + * To make a new subsystem, you declare a const instance of this type, and + * include it on the list in subsystem_list.c. The code that manages these + * subsystems is in subsysmgr.c. **/ typedef struct subsys_fns_t { /** @@ -49,7 +63,7 @@ typedef struct subsys_fns_t { * it is only for global state or pre-configuration state. * * (If you need to do any setup that depends on configuration, you'll need - * to declare a configuration callback. (Not yet designed)) + * to declare a configuration callback instead. (Not yet designed)) * * This function MUST NOT have any parts that can fail. **/ @@ -57,22 +71,49 @@ typedef struct subsys_fns_t { /** * Connect a subsystem to the message dispatch system. + * + * This function should use the macros in @refdir{lib/pubsub} to register a + * set of messages that this subsystem may publish, and may subscribe to. + * + * See pubsub_macros.h for more information, and for examples. **/ int (*add_pubsub)(struct pubsub_connector_t *); /** * Perform any necessary pre-fork cleanup. This function may not fail. + * + * On Windows (and any other platforms without fork()), this function will + * never be invoked. Otherwise it is used when we are about to start + * running as a background daemon, or when we are about to run a unit test + * in a subprocess. Unlike the subsys_fns_t.postfork callback, it is run + * from the parent process. + * + * Note that we do not invoke this function when the child process's only + * purpose is to call exec() and run another program. */ void (*prefork)(void); /** * Perform any necessary post-fork setup. This function may not fail. + * + * On Windows (and any other platforms without fork()), this function will + * never be invoked. Otherwise it is used when we are about to start + * running as a background daemon, or when we are about to run a unit test + * in a subprocess. Unlike the subsys_fns_t.prefork callback, it is run + * from the child process. + * + * Note that we do not invoke this function when the child process's only + * purpose is to call exec() and run another program. */ void (*postfork)(void); /** * Free any thread-local resources held by this subsystem. Called before * the thread exits. + * + * This function is not allowed to fail. + * + * \bug Note that this callback is currently buggy: See \ticket{32103}. */ void (*thread_cleanup)(void); @@ -80,16 +121,85 @@ typedef struct subsys_fns_t { * Free all resources held by this subsystem. * * This function is not allowed to fail. + * + * Subsystems are shut down when Tor is about to exit or return control to + * an embedding program. This callback must return the process to a state + * such that subsys_fns_t.init will succeed if invoked again. **/ void (*shutdown)(void); + /** + * A config_format_t describing all of the torrc fields owned by this + * subsystem. + * + * This object, if present, is registered in a confmgr_t for Tor's options, + * and used to parse option fields from the command line and torrc file. + **/ + const struct config_format_t *options_format; + + /** + * A config_format_t describing all of the DataDir/state fields owned by + * this subsystem. + * + * This object, if present, is registered in a confmgr_t for Tor's state, + * and used to parse state fields from the DataDir/state file. + **/ + const struct config_format_t *state_format; + + /** + * Receive an options object as defined by options_format. Return 0 + * on success, -1 on failure. + * + * It is safe to store the pointer to the object until set_options() + * is called again. + * + * This function is only called after all the validation code defined + * by subsys_fns_t.options_format has passed. + **/ + int (*set_options)(void *); + + /* XXXX Add an implementation for options_act_reversible() later in this + * branch. */ + + /** + * Receive a state object as defined by state_format. Return 0 on success, + * -1 on failure. + * + * It is safe to store the pointer to the object; set_state() is only + * called on startup. + * + * This function is only called after all the validation code defined + * by subsys_fns_t.state_format has passed. + * + * This function will only be called once per invocation of Tor, since + * Tor does not reload its state while it is running. + **/ + int (*set_state)(void *); + + /** + * Update any information that needs to be stored in the provided state + * object (as defined by state_format). Return 0 on success, -1 on failure. + * + * The object provided here will be the same one as provided earlier to + * set_state(). This method is called when we are about to save the state + * to disk. + **/ + int (*flush_state)(void *); } subsys_fns_t; +/** + * Lowest allowed subsystem level. + **/ #define MIN_SUBSYS_LEVEL -100 +/** + * Highest allowed subsystem level. + **/ #define MAX_SUBSYS_LEVEL 100 -/* All tor "libraries" (in src/libs) should have a subsystem level equal to or - * less than this value. */ +/** + * All tor "libraries" (in src/libs) should have a subsystem level equal to or + * less than this value. + */ #define SUBSYS_LEVEL_LIBS -10 #endif /* !defined(TOR_SUBSYS_T) */ diff --git a/src/lib/term/getpass.c b/src/lib/term/getpass.c index 8741344acf..d2d6cb2b7b 100644 --- a/src/lib/term/getpass.c +++ b/src/lib/term/getpass.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/term/getpass.h b/src/lib/term/getpass.h index aa597ec423..b080ad2473 100644 --- a/src/lib/term/getpass.h +++ b/src/lib/term/getpass.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/term/lib_term.md b/src/lib/term/lib_term.md new file mode 100644 index 0000000000..f96d25ffe8 --- /dev/null +++ b/src/lib/term/lib_term.md @@ -0,0 +1,2 @@ +@dir /lib/term +@brief lib/term: Terminal operations (password input). diff --git a/src/lib/testsupport/lib_testsupport.md b/src/lib/testsupport/lib_testsupport.md new file mode 100644 index 0000000000..7358e6a80f --- /dev/null +++ b/src/lib/testsupport/lib_testsupport.md @@ -0,0 +1,2 @@ +@dir /lib/testsupport +@brief lib/testsupport: Helpers for test-only code and for function mocking. diff --git a/src/lib/testsupport/testsupport.h b/src/lib/testsupport/testsupport.h index 90b7c43b19..165c497f71 100644 --- a/src/lib/testsupport/testsupport.h +++ b/src/lib/testsupport/testsupport.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2019, The Tor Project, Inc. */ +/* Copyright (c) 2013-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -15,17 +15,42 @@ #ifndef TOR_TESTSUPPORT_H #define TOR_TESTSUPPORT_H -#ifdef TOR_UNIT_TESTS /** The "STATIC" macro marks a function or variable that is static when * building Tor for production, but non-static when building the unit - * tests. */ + * tests. + * + * For example, a function declared as: + * + * STATIC int internal_function(void); + * + * should be only visible for the file on which it is declared, and in the + * unit tests. + */ +#ifdef TOR_UNIT_TESTS #define STATIC -#define EXTERN(type, name) extern type name; #else /* !defined(TOR_UNIT_TESTS) */ #define STATIC static -#define EXTERN(type, name) #endif /* defined(TOR_UNIT_TESTS) */ +/** The "EXTERN" macro is used along with "STATIC" for variables declarations: + * it expands to an extern declaration when Tor building unit tests, and to + * nothing otherwise. + * + * For example, to declare a variable as visible only visible in one + * file and in the unit tests, you would put this in the header: + * + * EXTERN(int, local_variable) + * + * and this in the source: + * + * STATIC int local_variable; + */ +#ifdef TOR_UNIT_TESTS +#define EXTERN(type, name) extern type name; +#else +#define EXTERN(type, name) +#endif + /** Quick and dirty macros to implement test mocking. * * To use them, suppose that you have a function you'd like to mock @@ -70,32 +95,42 @@ * * @{ */ #ifdef TOR_UNIT_TESTS +/** Declare a mocked function. For use in headers. */ #define MOCK_DECL(rv, funcname, arglist) \ rv funcname ##__real arglist; \ extern rv(*funcname) arglist +/** Define the implementation of a mocked function. */ #define MOCK_IMPL(rv, funcname, arglist) \ rv(*funcname) arglist = funcname ##__real; \ rv funcname ##__real arglist +/** As MOCK_DECL(), but allow attributes. */ #define MOCK_DECL_ATTR(rv, funcname, arglist, attr) \ rv funcname ##__real arglist attr; \ extern rv(*funcname) arglist -#define MOCK_IMPL(rv, funcname, arglist) \ - rv(*funcname) arglist = funcname ##__real; \ - rv funcname ##__real arglist +/** + * Replace <b>func</b> (a mockable function) with a replacement function. + * + * Only usable when Tor has been built for unit tests. */ #define MOCK(func, replacement) \ do { \ (func) = (replacement); \ } while (0) +/** Replace <b>func</b> (a mockable function) with its original value. + * + * Only usable when Tor has been built for unit tests. */ #define UNMOCK(func) \ do { \ func = func ##__real; \ } while (0) #else /* !defined(TOR_UNIT_TESTS) */ +/** Declare a mocked function. For use in headers. */ #define MOCK_DECL(rv, funcname, arglist) \ rv funcname arglist -#define MOCK_DECL_ATTR(rv, funcname, arglist, attr) \ +/** As MOCK_DECL(), but allow */ +#define MOCK_DECL_ATTR(rv, funcname, arglist, attr) \ rv funcname arglist attr -#define MOCK_IMPL(rv, funcname, arglist) \ +/** Define the implementation of a mocked function. */ +#define MOCK_IMPL(rv, funcname, arglist) \ rv funcname arglist #endif /* defined(TOR_UNIT_TESTS) */ /** @} */ diff --git a/src/lib/thread/compat_pthreads.c b/src/lib/thread/compat_pthreads.c index 6f7ecd17da..d143b80252 100644 --- a/src/lib/thread/compat_pthreads.c +++ b/src/lib/thread/compat_pthreads.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/thread/compat_threads.c b/src/lib/thread/compat_threads.c index 5c8ffa55c6..d56e8a3f76 100644 --- a/src/lib/thread/compat_threads.c +++ b/src/lib/thread/compat_threads.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/thread/compat_winthreads.c b/src/lib/thread/compat_winthreads.c index f0b1430e84..2ca5620d23 100644 --- a/src/lib/thread/compat_winthreads.c +++ b/src/lib/thread/compat_winthreads.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/thread/lib_thread.md b/src/lib/thread/lib_thread.md new file mode 100644 index 0000000000..5870ad790f --- /dev/null +++ b/src/lib/thread/lib_thread.md @@ -0,0 +1,7 @@ +@dir /lib/thread +@brief lib/thread: Mid-level threading. + +This module contains compatibility and convenience code for multithreading, +except for low-level locks (which are in \refdir{lib/lock} and +workqueue/threadpool code (which belongs in \refdir{lib/evloop}.) + diff --git a/src/lib/thread/numcpus.c b/src/lib/thread/numcpus.c index b293d965d2..18454ce3ad 100644 --- a/src/lib/thread/numcpus.c +++ b/src/lib/thread/numcpus.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/thread/numcpus.h b/src/lib/thread/numcpus.h index 2f1ea16eb9..65e6c430cf 100644 --- a/src/lib/thread/numcpus.h +++ b/src/lib/thread/numcpus.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/thread/thread_sys.h b/src/lib/thread/thread_sys.h index c0daf2b5e9..6206fac9d6 100644 --- a/src/lib/thread/thread_sys.h +++ b/src/lib/thread/thread_sys.h @@ -1,8 +1,8 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** - * \file threads_sys.h + * \file thread_sys.h * \brief Declare subsystem object for threads library **/ diff --git a/src/lib/thread/threading.md b/src/lib/thread/threading.md new file mode 100644 index 0000000000..a1058c97de --- /dev/null +++ b/src/lib/thread/threading.md @@ -0,0 +1,26 @@ + +@page threading Threading in Tor + +Tor is based around a single main thread and one or more worker +threads. We aim (with middling success) to use worker threads for +CPU-intensive activities and the main thread for our networking. +Fortunately (?) we have enough cryptography that moving what we can +of the cryptographic processes to the workers should achieve good +parallelism under most loads. Unfortunately, we only have a small +fraction of our cryptography done in our worker threads right now. + +Our threads-and-workers abstraction is defined in workqueue.c, which +combines a work queue with a thread pool, and integrates the +signalling with libevent. Tor's main instance of a work queue is +instantiated in cpuworker.c. It will probably need some refactoring +as more types of work are added. + +On a lower level, we provide locks with tor_mutex_t in \refdir{lib/lock}, and +higher-level locking/threading tools in \refdir{lib/thread}, including +conditions (tor_cond_t), thread-local storage (tor_threadlocal_t), and more. + + +Try to minimize sharing between threads: it is usually best to simply +make the worker "own" all the data it needs while the work is in +progress, and to give up ownership when it's complete. + diff --git a/src/lib/thread/threads.h b/src/lib/thread/threads.h index 4b42b9abd9..fcc0c23a87 100644 --- a/src/lib/thread/threads.h +++ b/src/lib/thread/threads.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -63,7 +63,7 @@ int tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex, void tor_cond_signal_one(tor_cond_t *cond); void tor_cond_signal_all(tor_cond_t *cond); -typedef struct tor_threadlocal_s { +typedef struct tor_threadlocal_t { #ifdef _WIN32 DWORD index; #else @@ -106,7 +106,9 @@ void tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value); typedef struct atomic_counter_t { atomic_size_t val; } atomic_counter_t; +#ifndef COCCI #define ATOMIC_LINKAGE static +#endif #else /* !defined(HAVE_WORKING_STDATOMIC) */ typedef struct atomic_counter_t { tor_mutex_t mutex; diff --git a/src/lib/time/compat_time.c b/src/lib/time/compat_time.c index ab45224a7f..6bbad4f98a 100644 --- a/src/lib/time/compat_time.c +++ b/src/lib/time/compat_time.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/time/compat_time.h b/src/lib/time/compat_time.h index 4d16effd29..5089e16ca5 100644 --- a/src/lib/time/compat_time.h +++ b/src/lib/time/compat_time.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/time/lib_time.md b/src/lib/time/lib_time.md new file mode 100644 index 0000000000..8e58aafcd8 --- /dev/null +++ b/src/lib/time/lib_time.md @@ -0,0 +1,9 @@ +@dir /lib/time +@brief lib/time: Higher-level time functions + +This includes both fine-grained timers and monotonic timers, along with +wrappers for them to try to improve efficiency. + +For "what time is it" in UTC, see \refdir{lib/wallclock}. For parsing and +encoding times and dates, see \refdir{lib/encoding}. + diff --git a/src/lib/time/time_sys.c b/src/lib/time/time_sys.c index 8b9aa2856c..044d328f81 100644 --- a/src/lib/time/time_sys.c +++ b/src/lib/time/time_sys.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/time/time_sys.h b/src/lib/time/time_sys.h index 6a860ffd08..f2401e1911 100644 --- a/src/lib/time/time_sys.h +++ b/src/lib/time/time_sys.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/time/tvdiff.c b/src/lib/time/tvdiff.c index d7c245f57a..cbad5a48b8 100644 --- a/src/lib/time/tvdiff.c +++ b/src/lib/time/tvdiff.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/time/tvdiff.h b/src/lib/time/tvdiff.h index 657cb99553..e779e758f1 100644 --- a/src/lib/time/tvdiff.h +++ b/src/lib/time/tvdiff.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/tls/buffers_tls.c b/src/lib/tls/buffers_tls.c index ed0f821ce8..87055744a7 100644 --- a/src/lib/tls/buffers_tls.c +++ b/src/lib/tls/buffers_tls.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -69,9 +69,9 @@ buf_read_from_tls(buf_t *buf, tor_tls_t *tls, size_t at_most) check_no_tls_errors(); IF_BUG_ONCE(buf->datalen >= INT_MAX) - return -1; + return TOR_TLS_ERROR_MISC; IF_BUG_ONCE(buf->datalen >= INT_MAX - at_most) - return -1; + return TOR_TLS_ERROR_MISC; while (at_most > total_read) { size_t readlen = at_most - total_read; diff --git a/src/lib/tls/buffers_tls.h b/src/lib/tls/buffers_tls.h index 65788c3f34..587426801d 100644 --- a/src/lib/tls/buffers_tls.h +++ b/src/lib/tls/buffers_tls.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/tls/lib_tls.md b/src/lib/tls/lib_tls.md new file mode 100644 index 0000000000..26fea723f9 --- /dev/null +++ b/src/lib/tls/lib_tls.md @@ -0,0 +1,11 @@ +@dir /lib/tls +@brief lib/tls: TLS library wrappers + +This module has compatibility wrappers around the library (NSS or OpenSSL, +depending on configuration) that Tor uses to implement the TLS link security +protocol. + +It also implements the logic for some legacy TLS protocol usage we used to +support in old versions of Tor, involving conditional delivery of certificate +chains (v1 link protocol) and conditional renegotiation (v2 link protocol). + diff --git a/src/lib/tls/nss_countbytes.c b/src/lib/tls/nss_countbytes.c index 7761727acd..4b98df80ec 100644 --- a/src/lib/tls/nss_countbytes.c +++ b/src/lib/tls/nss_countbytes.c @@ -1,4 +1,4 @@ -/* Copyright 2018-2019, The Tor Project Inc. */ +/* Copyright 2018-2020, The Tor Project Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/tls/nss_countbytes.h b/src/lib/tls/nss_countbytes.h index 47f220c4c1..36ed55e10d 100644 --- a/src/lib/tls/nss_countbytes.h +++ b/src/lib/tls/nss_countbytes.h @@ -1,4 +1,4 @@ -/* Copyright 2018-2019, The Tor Project, Inc. */ +/* Copyright 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/tls/tortls.c b/src/lib/tls/tortls.c index 1aff40c437..fd41a84cfa 100644 --- a/src/lib/tls/tortls.c +++ b/src/lib/tls/tortls.c @@ -1,8 +1,13 @@ /* Copyright (c) 2003, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file tortls.c + * @brief Shared functionality for our TLS backends. + **/ + #define TORTLS_PRIVATE #define TOR_X509_PRIVATE #include "lib/tls/x509.h" diff --git a/src/lib/tls/tortls.h b/src/lib/tls/tortls.h index 799bd6aaeb..e8dbbf5279 100644 --- a/src/lib/tls/tortls.h +++ b/src/lib/tls/tortls.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_TORTLS_H diff --git a/src/lib/tls/tortls_internal.h b/src/lib/tls/tortls_internal.h index 866483a94c..3f56f181ee 100644 --- a/src/lib/tls/tortls_internal.h +++ b/src/lib/tls/tortls_internal.h @@ -1,11 +1,18 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file tortls_internal.h + * @brief Declare internal functions for lib/tls + **/ + #ifndef TORTLS_INTERNAL_H #define TORTLS_INTERNAL_H +#include "lib/tls/x509.h" + int tor_errno_to_tls_error(int e); #ifdef ENABLE_OPENSSL int tor_tls_get_error(tor_tls_t *tls, int r, int extra, diff --git a/src/lib/tls/tortls_nss.c b/src/lib/tls/tortls_nss.c index 1436442e1c..38c7efe107 100644 --- a/src/lib/tls/tortls_nss.c +++ b/src/lib/tls/tortls_nss.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -34,7 +34,7 @@ #include "lib/tls/nss_countbytes.h" #include "lib/log/util_bug.h" -DISABLE_GCC_WARNING(strict-prototypes) +DISABLE_GCC_WARNING("-Wstrict-prototypes") #include <prio.h> // For access to rar sockets. #include <private/pprio.h> @@ -42,7 +42,7 @@ DISABLE_GCC_WARNING(strict-prototypes) #include <sslt.h> #include <sslproto.h> #include <certt.h> -ENABLE_GCC_WARNING(strict-prototypes) +ENABLE_GCC_WARNING("-Wstrict-prototypes") static SECStatus always_accept_cert_cb(void *, PRFileDesc *, PRBool, PRBool); diff --git a/src/lib/tls/tortls_openssl.c b/src/lib/tls/tortls_openssl.c index 5bafcf676d..68d6e2aa50 100644 --- a/src/lib/tls/tortls_openssl.c +++ b/src/lib/tls/tortls_openssl.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -37,7 +37,7 @@ /* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in * srtp.h. Suppress the GCC warning so we can build with -Wredundant-decl. */ -DISABLE_GCC_WARNING(redundant-decls) +DISABLE_GCC_WARNING("-Wredundant-decls") #include <openssl/opensslv.h> @@ -54,7 +54,7 @@ DISABLE_GCC_WARNING(redundant-decls) #include <openssl/bn.h> #include <openssl/rsa.h> -ENABLE_GCC_WARNING(redundant-decls) +ENABLE_GCC_WARNING("-Wredundant-decls") #include "lib/tls/tortls.h" #include "lib/tls/tortls_st.h" @@ -464,7 +464,9 @@ static const char UNRESTRICTED_SERVER_CIPHER_LIST[] = /** List of ciphers that clients should advertise, omitting items that * our OpenSSL doesn't know about. */ static const char CLIENT_CIPHER_LIST[] = +#ifndef COCCI #include "lib/tls/ciphers.inc" +#endif /* Tell it not to use SSLv2 ciphers, so that it can select an SSLv3 version * of any cipher we say. */ "!SSLv2" diff --git a/src/lib/tls/tortls_st.h b/src/lib/tls/tortls_st.h index 73f6e6ecca..925896d493 100644 --- a/src/lib/tls/tortls_st.h +++ b/src/lib/tls/tortls_st.h @@ -1,11 +1,19 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_TORTLS_ST_H #define TOR_TORTLS_ST_H +/** + * @file tortls_st.h + * @brief Structure declarations for internal TLS types. + * + * These should generally be treated as opaque outside of the + * lib/tls module. + **/ + #include "lib/net/socket.h" #define TOR_TLS_MAGIC 0x71571571 diff --git a/src/lib/tls/tortls_sys.h b/src/lib/tls/tortls_sys.h index 4b04f85f0c..177c198f71 100644 --- a/src/lib/tls/tortls_sys.h +++ b/src/lib/tls/tortls_sys.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/tls/x509.c b/src/lib/tls/x509.c index b4a0f8dabf..2515499298 100644 --- a/src/lib/tls/x509.c +++ b/src/lib/tls/x509.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/tls/x509.h b/src/lib/tls/x509.h index 0390a5464d..5919b9089d 100644 --- a/src/lib/tls/x509.h +++ b/src/lib/tls/x509.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_X509_H diff --git a/src/lib/tls/x509_internal.h b/src/lib/tls/x509_internal.h index f858baae98..145be7e71c 100644 --- a/src/lib/tls/x509_internal.h +++ b/src/lib/tls/x509_internal.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_X509_INTERNAL_H diff --git a/src/lib/tls/x509_nss.c b/src/lib/tls/x509_nss.c index e04afaf07b..341bb57104 100644 --- a/src/lib/tls/x509_nss.c +++ b/src/lib/tls/x509_nss.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/tls/x509_openssl.c b/src/lib/tls/x509_openssl.c index 7724288279..2abf02851d 100644 --- a/src/lib/tls/x509_openssl.c +++ b/src/lib/tls/x509_openssl.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -19,7 +19,7 @@ /* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in * srtp.h. Suppress the GCC warning so we can build with -Wredundant-decl. */ -DISABLE_GCC_WARNING(redundant-decls) +DISABLE_GCC_WARNING("-Wredundant-decls") #include <openssl/opensslv.h> @@ -36,7 +36,7 @@ DISABLE_GCC_WARNING(redundant-decls) #include <openssl/rsa.h> #include <openssl/x509.h> -ENABLE_GCC_WARNING(redundant-decls) +ENABLE_GCC_WARNING("-Wredundant-decls") #include "lib/log/log.h" #include "lib/log/util_bug.h" diff --git a/src/lib/trace/debug.h b/src/lib/trace/debug.h index 92bb95c883..87b3074e0b 100644 --- a/src/lib/trace/debug.h +++ b/src/lib/trace/debug.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Tor Project, Inc. */ +/* Copyright (c) 2017-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/trace/events.h b/src/lib/trace/events.h index 9de86d63f2..368f85dd02 100644 --- a/src/lib/trace/events.h +++ b/src/lib/trace/events.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Tor Project, Inc. */ +/* Copyright (c) 2017-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/trace/lib_trace.md b/src/lib/trace/lib_trace.md new file mode 100644 index 0000000000..a7a32529b0 --- /dev/null +++ b/src/lib/trace/lib_trace.md @@ -0,0 +1,6 @@ +@dir /lib/trace +@brief lib/trace: Function-tracing functionality API. + +This module is used for adding "trace" support (low-granularity function +logging) to Tor. Right now it doesn't have many users. + diff --git a/src/lib/trace/trace.c b/src/lib/trace/trace.c index 18be63c5a8..4e5c66b4c6 100644 --- a/src/lib/trace/trace.c +++ b/src/lib/trace/trace.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Tor Project, Inc. */ +/* Copyright (c) 2017-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/trace/trace.h b/src/lib/trace/trace.h index 5001b28a1d..5e24678c3c 100644 --- a/src/lib/trace/trace.h +++ b/src/lib/trace/trace.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Tor Project, Inc. */ +/* Copyright (c) 2017-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/version/git_revision.c b/src/lib/version/git_revision.c index 900a1e12a0..09f11aa316 100644 --- a/src/lib/version/git_revision.c +++ b/src/lib/version/git_revision.c @@ -1,24 +1,39 @@ /* Copyright 2001-2004 Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" #include "lib/version/git_revision.h" +/** + * @file git_revision.c + * @brief Strings to describe the current Git commit. + **/ + /** String describing which Tor Git repository version the source was * built from. This string is generated by a bit of shell kludging in * src/core/include.am, and is usually right. */ const char tor_git_revision[] = +#ifndef COCCI #ifndef _MSC_VER #include "micro-revision.i" #endif +#endif ""; +/** + * String appended to Tor bug messages describing the Tor version. + * + * It has the form "(on Tor 0.4.3.1-alpha)" or + * "(on Tor 0.4.3.1-alpha git-b994397f1af193f8)" + **/ const char tor_bug_suffix[] = " (on Tor " VERSION +#ifndef COCCI #ifndef _MSC_VER " " #include "micro-revision.i" #endif +#endif /* !defined(COCCI) */ ")"; diff --git a/src/lib/version/git_revision.h b/src/lib/version/git_revision.h index 79e3c6684b..80b6c4734e 100644 --- a/src/lib/version/git_revision.h +++ b/src/lib/version/git_revision.h @@ -1,11 +1,16 @@ /* Copyright 2001-2004 Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_GIT_REVISION_H #define TOR_GIT_REVISION_H +/** + * @file git_revision.h + * @brief Header for git_revision.c + **/ + extern const char tor_git_revision[]; extern const char tor_bug_suffix[]; diff --git a/src/lib/version/lib_version.md b/src/lib/version/lib_version.md new file mode 100644 index 0000000000..ccc45920f9 --- /dev/null +++ b/src/lib/version/lib_version.md @@ -0,0 +1,2 @@ +@dir /lib/version +@brief lib/version: holds the current version of Tor. diff --git a/src/lib/version/torversion.h b/src/lib/version/torversion.h index 7b0fb66ec0..679df74381 100644 --- a/src/lib/version/torversion.h +++ b/src/lib/version/torversion.h @@ -1,11 +1,16 @@ /* Copyright 2001-2004 Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_VERSION_H #define TOR_VERSION_H +/** + * @file torversion.h + * @brief Header for version.c. + **/ + const char *get_version(void); const char *get_short_version(void); diff --git a/src/lib/version/version.c b/src/lib/version/version.c index 434e6fb424..ec1d0bea2f 100644 --- a/src/lib/version/version.c +++ b/src/lib/version/version.c @@ -1,6 +1,6 @@ /* Copyright 2001-2004 Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -10,6 +10,11 @@ #include <stdio.h> #include <string.h> +/** + * @file version.c + * @brief Functions to get the version of Tor. + **/ + /** A shorter version of this Tor process's version, for export in our router * descriptor. (Does not include the git version, if any.) */ static const char the_short_tor_version[] = @@ -19,6 +24,10 @@ static const char the_short_tor_version[] = #endif ""; +/** + * Longest possible version length. We make this a constant so that we + * can statically allocate the_tor_version. + **/ #define MAX_VERSION_LEN 128 /** The version of this Tor process, possibly including git version */ diff --git a/src/lib/wallclock/approx_time.c b/src/lib/wallclock/approx_time.c index 77eeddaf56..d9f90ab2f7 100644 --- a/src/lib/wallclock/approx_time.c +++ b/src/lib/wallclock/approx_time.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -44,6 +44,9 @@ update_approx_time(time_t now) } #endif /* !defined(TIME_IS_FAST) */ +/** + * Initialize the "wallclock" subsystem by setting the current cached time. + **/ static int subsys_wallclock_initialize(void) { @@ -51,6 +54,9 @@ subsys_wallclock_initialize(void) return 0; } +/** + * Subsystem function table describing the "wallclock" subsystem. + **/ const subsys_fns_t sys_wallclock = { .name = "wallclock", .supported = true, diff --git a/src/lib/wallclock/approx_time.h b/src/lib/wallclock/approx_time.h index e7da160122..42040a1f52 100644 --- a/src/lib/wallclock/approx_time.h +++ b/src/lib/wallclock/approx_time.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/wallclock/lib_wallclock.md b/src/lib/wallclock/lib_wallclock.md new file mode 100644 index 0000000000..f21721f6f6 --- /dev/null +++ b/src/lib/wallclock/lib_wallclock.md @@ -0,0 +1,11 @@ +@dir /lib/wallclock +@brief lib/wallclock: Inspect and manipulate the current time. + +This module handles our concept of "what time is it" or "what time does the +world agree it is?" Generally, if you want something derived from UTC, this +is the module for you. + +For versions of the time that are more local, more monotonic, or more +accurate, see \refdir{lib/time}. For parsing and encoding times and dates, +see \refdir{lib/encoding}. + diff --git a/src/lib/wallclock/time_to_tm.c b/src/lib/wallclock/time_to_tm.c index f7cb21827b..8c747b4c7b 100644 --- a/src/lib/wallclock/time_to_tm.c +++ b/src/lib/wallclock/time_to_tm.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -198,3 +198,4 @@ tor_gmtime_r_msg(const time_t *timep, struct tm *result, char **err_out) return correct_tm(0, timep, result, r, err_out); } #endif /* defined(HAVE_GMTIME_R) || ... */ +/**@}*/ diff --git a/src/lib/wallclock/time_to_tm.h b/src/lib/wallclock/time_to_tm.h index da27fcaba1..bfa8fa3689 100644 --- a/src/lib/wallclock/time_to_tm.h +++ b/src/lib/wallclock/time_to_tm.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/wallclock/timeval.h b/src/lib/wallclock/timeval.h index e632d04a04..d7d5bda99f 100644 --- a/src/lib/wallclock/timeval.h +++ b/src/lib/wallclock/timeval.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -69,6 +69,7 @@ } while (0) #endif /* !defined(timersub) */ +#ifndef COCCI #ifndef timercmp /** Replacement for timercmp on platforms that do not have it: returns true * iff the relational operator "op" makes the expression tv1 op tv2 true. @@ -82,5 +83,6 @@ ((tv1)->tv_usec op (tv2)->tv_usec) : \ ((tv1)->tv_sec op (tv2)->tv_sec)) #endif /* !defined(timercmp) */ +#endif /* !defined(COCCI) */ #endif /* !defined(TOR_TIMEVAL_H) */ diff --git a/src/lib/wallclock/tor_gettimeofday.c b/src/lib/wallclock/tor_gettimeofday.c index 63538f3b81..a07f83220d 100644 --- a/src/lib/wallclock/tor_gettimeofday.c +++ b/src/lib/wallclock/tor_gettimeofday.c @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/wallclock/tor_gettimeofday.h b/src/lib/wallclock/tor_gettimeofday.h index 6fec2fc893..c1a8afca3a 100644 --- a/src/lib/wallclock/tor_gettimeofday.h +++ b/src/lib/wallclock/tor_gettimeofday.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/lib/wallclock/wallclock_sys.h b/src/lib/wallclock/wallclock_sys.h index a30912b8fb..3997d11e7a 100644 --- a/src/lib/wallclock/wallclock_sys.h +++ b/src/lib/wallclock/wallclock_sys.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2019, The Tor Project, Inc. */ +/* Copyright (c) 2018-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** |