diff options
Diffstat (limited to 'src/common/util.h')
-rw-r--r-- | src/common/util.h | 146 |
1 files changed, 58 insertions, 88 deletions
diff --git a/src/common/util.h b/src/common/util.h index ebcf88b32d..6bc853da26 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2016, The Tor Project, Inc. */ + * Copyright (c) 2007-2017, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -22,6 +22,7 @@ /* for the correct alias to struct stat */ #include <sys/stat.h> #endif +#include "util_bug.h" #ifndef O_BINARY #define O_BINARY 0 @@ -33,41 +34,6 @@ #define O_NOFOLLOW 0 #endif -/* Replace assert() with a variant that sends failures to the log before - * calling assert() normally. - */ -#ifdef NDEBUG -/* Nobody should ever want to build with NDEBUG set. 99% of our asserts will - * be outside the critical path anyway, so it's silly to disable bug-checking - * throughout the entire program just because a few asserts are slowing you - * down. Profile, optimize the critical path, and keep debugging on. - * - * And I'm not just saying that because some of our asserts check - * security-critical properties. - */ -#error "Sorry; we don't support building with NDEBUG." -#endif - -/* Sometimes we don't want to use assertions during branch coverage tests; it - * leads to tons of unreached branches which in reality are only assertions we - * didn't hit. */ -#if defined(TOR_UNIT_TESTS) && defined(DISABLE_ASSERTS_IN_UNIT_TESTS) -#define tor_assert(a) STMT_BEGIN \ - (void)(a); \ - STMT_END -#else -/** Like assert(3), but send assertion failures to the log as well as to - * stderr. */ -#define tor_assert(expr) STMT_BEGIN \ - if (PREDICT_UNLIKELY(!(expr))) { \ - tor_assertion_failed_(SHORT_FILE__, __LINE__, __func__, #expr); \ - abort(); \ - } STMT_END -#endif - -void tor_assertion_failed_(const char *fname, unsigned int line, - const char *func, const char *expr); - /* If we're building with dmalloc, we want all of our memory allocation * functions to take an extra file/line pair of arguments. If not, not. * We define DMALLOC_PARAMS to the extra parameters to insert in the @@ -79,12 +45,7 @@ void tor_assertion_failed_(const char *fname, unsigned int line, #else #define DMALLOC_PARAMS #define DMALLOC_ARGS -#endif - -/** Define this if you want Tor to crash when any problem comes up, - * so you can get a coredump and track things down. */ -// #define tor_fragile_assert() tor_assert(0) -#define tor_fragile_assert() +#endif /* defined(USE_DMALLOC) */ /* Memory management */ void *tor_malloc_(size_t size DMALLOC_PARAMS) ATTR_MALLOC; @@ -100,6 +61,8 @@ void *tor_memdup_(const void *mem, size_t len DMALLOC_PARAMS) void *tor_memdup_nulterm_(const void *mem, size_t len DMALLOC_PARAMS) ATTR_MALLOC ATTR_NONNULL((1)); void tor_free_(void *mem); +uint64_t tor_htonll(uint64_t a); +uint64_t tor_ntohll(uint64_t a); #ifdef USE_DMALLOC extern int dmalloc_free(const char *file, const int line, void *pnt, const int func_id); @@ -109,7 +72,7 @@ extern int dmalloc_free(const char *file, const int line, void *pnt, (p)=NULL; \ } \ STMT_END -#else +#else /* !(defined(USE_DMALLOC)) */ /** Release memory allocated by tor_malloc, tor_realloc, tor_strdup, etc. * Unlike the free() function, tor_free() will still work on NULL pointers, * and it sets the pointer value to NULL after freeing it. @@ -119,11 +82,11 @@ extern int dmalloc_free(const char *file, const int line, void *pnt, */ #define tor_free(p) STMT_BEGIN \ if (PREDICT_LIKELY((p)!=NULL)) { \ - free(p); \ + raw_free(p); \ (p)=NULL; \ } \ STMT_END -#endif +#endif /* defined(USE_DMALLOC) */ #define tor_malloc(size) tor_malloc_(size DMALLOC_ARGS) #define tor_malloc_zero(size) tor_malloc_zero_(size DMALLOC_ARGS) @@ -136,21 +99,21 @@ extern int dmalloc_free(const char *file, const int line, void *pnt, #define tor_memdup(s, n) tor_memdup_(s, n DMALLOC_ARGS) #define tor_memdup_nulterm(s, n) tor_memdup_nulterm_(s, n DMALLOC_ARGS) -void tor_log_mallinfo(int severity); +/* Aliases for the underlying system malloc/realloc/free. Only use + * them to indicate "I really want the underlying system function, I know + * what I'm doing." */ +#define raw_malloc malloc +#define raw_realloc realloc +#define raw_free free +#define raw_strdup strdup -/** Return the offset of <b>member</b> within the type <b>tp</b>, in bytes */ -#if defined(__GNUC__) && __GNUC__ > 3 -#define STRUCT_OFFSET(tp, member) __builtin_offsetof(tp, member) -#else - #define STRUCT_OFFSET(tp, member) \ - ((off_t) (((char*)&((tp*)0)->member)-(char*)0)) -#endif +void tor_log_mallinfo(int severity); /** 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; - * off_t bar_offset = STRUCT_OFFSET(struct a, bar); + * off_t bar_offset = offsetof(struct a, bar); * int *bar_p = STRUCT_VAR_P(&x, bar_offset); * *bar_p = 3; * </pre> @@ -167,7 +130,7 @@ void tor_log_mallinfo(int severity); * </pre> */ #define SUBTYPE_P(p, subtype, basemember) \ - ((void*) ( ((char*)(p)) - STRUCT_OFFSET(subtype, basemember) )) + ((void*) ( ((char*)(p)) - offsetof(subtype, basemember) )) /* Logic */ /** Macro: true if two values have the same boolean value. */ @@ -184,17 +147,17 @@ uint64_t round_to_power_of_2(uint64_t u64); 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); -int64_t round_int64_to_next_multiple_of(int64_t number, int64_t divisor); int64_t sample_laplace_distribution(double mu, double b, double p); int64_t add_laplace_noise(int64_t signal, double random, double delta_f, double epsilon); int n_bits_set_u8(uint8_t v); int64_t clamp_double_to_int64(double number); +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> - * and positive <b>b</b>. Works on integer types only. Not defined if a+b can - * overflow. */ -#define CEIL_DIV(a,b) (((a)+(b)-1)/(b)) + * and positive <b>b</b>. Works on integer types only. Not defined if a+(b-1) + * can overflow. */ +#define CEIL_DIV(a,b) (((a)+((b)-1))/(b)) /* Return <b>v</b> if it's between <b>min</b> and <b>max</b>. Otherwise * return <b>min</b> if <b>v</b> is smaller than <b>min</b>, or <b>max</b> if @@ -215,6 +178,7 @@ void tor_strlower(char *s) ATTR_NONNULL((1)); void tor_strupper(char *s) ATTR_NONNULL((1)); int tor_strisprint(const char *s) ATTR_NONNULL((1)); int tor_strisnonupper(const char *s) ATTR_NONNULL((1)); +int tor_strisspace(const char *s); int strcmp_opt(const char *s1, const char *s2); int strcmpstart(const char *s1, const char *s2) ATTR_NONNULL((1,2)); int strcmp_len(const char *s1, const char *s2, size_t len) ATTR_NONNULL((1,2)); @@ -268,6 +232,7 @@ void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern, ...) void smartlist_add_vasprintf(struct smartlist_t *sl, const char *pattern, va_list args) CHECK_PRINTF(2, 0); +void smartlist_add_strdup(struct smartlist_t *sl, const char *string); /* Time helpers */ long tv_udiff(const struct timeval *start, const struct timeval *end); @@ -283,8 +248,9 @@ void format_local_iso_time(char *buf, time_t t); void format_iso_time(char *buf, time_t t); void format_iso_time_nospace(char *buf, time_t t); void format_iso_time_nospace_usec(char *buf, const struct timeval *tv); -int parse_iso_time_(const char *cp, time_t *t, int strict); +int parse_iso_time_(const char *cp, time_t *t, int strict, int nospace); int parse_iso_time(const char *buf, time_t *t); +int parse_iso_time_nospace(const char *cp, time_t *t); int parse_http_time(const char *buf, struct tm *tm); int format_time_interval(char *out, size_t out_len, long interval); @@ -295,7 +261,7 @@ int format_time_interval(char *out, size_t out_len, long interval); #else time_t approx_time(void); void update_approx_time(time_t now); -#endif +#endif /* defined(TIME_IS_FAST) */ /* Rate-limiter */ @@ -330,6 +296,7 @@ typedef struct ratelim_t { } ratelim_t; #define RATELIM_INIT(r) { (r), 0, 0 } +#define RATELIM_TOOMANY (16*1000*1000) char *rate_limit_log(ratelim_t *lim, time_t now); @@ -347,7 +314,9 @@ enum stream_status { const char *stream_status_to_string(enum stream_status stream_status); -enum stream_status get_string_from_pipe(FILE *stream, char *buf, size_t count); +enum stream_status get_string_from_pipe(int fd, char *buf, size_t count); + +MOCK_DECL(int,tor_unlink,(const char *pathname)); /** Return values from file_status(); see that function's documentation * for details. */ @@ -364,8 +333,9 @@ typedef unsigned int cpd_check_t; #define CPD_GROUP_READ (1u << 3) #define CPD_CHECK_MODE_ONLY (1u << 4) #define CPD_RELAX_DIRMODE_CHECK (1u << 5) -int check_private_dir(const char *dirname, cpd_check_t check, - const char *effective_user); +MOCK_DECL(int, check_private_dir, + (const char *dirname, cpd_check_t check, + const char *effective_user)); #define OPEN_FLAGS_REPLACE (O_WRONLY|O_CREAT|O_TRUNC) #define OPEN_FLAGS_APPEND (O_WRONLY|O_CREAT|O_APPEND) @@ -378,7 +348,8 @@ FILE *start_writing_to_stdio_file(const char *fname, int open_flags, int mode, FILE *fdopen_file(open_file_t *file_data); int finish_writing_to_file(open_file_t *file_data); int abort_writing_to_file(open_file_t *file_data); -int write_str_to_file(const char *fname, const char *str, int bin); +MOCK_DECL(int, +write_str_to_file,(const char *fname, const char *str, int bin)); MOCK_DECL(int, write_bytes_to_file,(const char *fname, const char *str, size_t len, int bin)); @@ -403,30 +374,30 @@ int write_bytes_to_new_file(const char *fname, const char *str, size_t len, #ifndef _WIN32 struct stat; #endif -char *read_file_to_str(const char *filename, int flags, struct stat *stat_out) - ATTR_MALLOC; +MOCK_DECL_ATTR(char *, read_file_to_str, + (const char *filename, int flags, struct stat *stat_out), + ATTR_MALLOC); char *read_file_to_str_until_eof(int fd, size_t max_bytes_to_read, size_t *sz_out) ATTR_MALLOC; -const char *parse_config_line_from_str_verbose(const char *line, - char **key_out, char **value_out, - const char **err_out); -#define parse_config_line_from_str(line,key_out,value_out) \ - parse_config_line_from_str_verbose((line),(key_out),(value_out),NULL) +const char *unescape_string(const char *s, char **result, size_t *size_out); +char *get_unquoted_path(const char *path); char *expand_filename(const char *filename); -struct smartlist_t *tor_listdir(const char *dirname); +MOCK_DECL(struct smartlist_t *, tor_listdir, (const char *dirname)); int path_is_relative(const char *filename); /* Process helpers */ void start_daemon(void); void finish_daemon(const char *desired_cwd); -void write_pidfile(const char *filename); +int write_pidfile(const char *filename); /* Port forwarding */ void tor_check_port_forwarding(const char *filename, struct smartlist_t *ports_to_forward, time_t now); +void tor_disable_spawning_background_processes(void); + typedef struct process_handle_t process_handle_t; typedef struct process_environment_t process_environment_t; int tor_spawn_background(const char *const filename, const char **argv, @@ -480,13 +451,10 @@ struct process_handle_t { HANDLE stdout_pipe; HANDLE stderr_pipe; PROCESS_INFORMATION pid; -#else +#else /* !(defined(_WIN32)) */ int stdin_pipe; int stdout_pipe; int stderr_pipe; - FILE *stdin_handle; - FILE *stdout_handle; - FILE *stderr_handle; pid_t pid; /** If the process has not given us a SIGCHLD yet, this has the * waitpid_callback_t that gets invoked once it has. Otherwise this @@ -494,9 +462,9 @@ struct process_handle_t { struct waitpid_callback_t *waitpid_cb; /** The exit status reported by waitpid. */ int waitpid_exit_status; -#endif // _WIN32 +#endif /* defined(_WIN32) */ }; -#endif +#endif /* defined(UTIL_PRIVATE) */ /* Return values of tor_get_exit_code() */ #define PROCESS_EXIT_RUNNING 1 @@ -509,10 +477,10 @@ int tor_split_lines(struct smartlist_t *sl, char *buf, int len); ssize_t tor_read_all_handle(HANDLE h, char *buf, size_t count, const process_handle_t *process); #else -ssize_t tor_read_all_handle(FILE *h, char *buf, size_t count, +ssize_t tor_read_all_handle(int fd, char *buf, size_t count, const process_handle_t *process, int *eof); -#endif +#endif /* defined(_WIN32) */ ssize_t tor_read_all_from_process_stdout( const process_handle_t *process_handle, char *buf, size_t count); ssize_t tor_read_all_from_process_stderr( @@ -523,7 +491,7 @@ int tor_process_get_pid(process_handle_t *process_handle); #ifdef _WIN32 HANDLE tor_process_get_stdout_pipe(process_handle_t *process_handle); #else -FILE *tor_process_get_stdout_pipe(process_handle_t *process_handle); +int tor_process_get_stdout_pipe(process_handle_t *process_handle); #endif #ifdef _WIN32 @@ -532,9 +500,9 @@ tor_get_lines_from_handle,(HANDLE *handle, enum stream_status *stream_status)); #else MOCK_DECL(struct smartlist_t *, -tor_get_lines_from_handle,(FILE *handle, +tor_get_lines_from_handle,(int fd, enum stream_status *stream_status)); -#endif +#endif /* defined(_WIN32) */ int tor_terminate_process(process_handle_t *process_handle); @@ -571,11 +539,13 @@ STATIC int format_helper_exit_status(unsigned char child_state, leading minus) and newline (no null) */ #define HEX_ERRNO_SIZE (sizeof(char) * 2 + 1 + \ 1 + sizeof(int) * 2 + 1) -#endif +#endif /* !defined(_WIN32) */ -#endif +#endif /* defined(UTIL_PRIVATE) */ + +int size_mul_check(const size_t x, const size_t y); #define ARRAY_LENGTH(x) ((sizeof(x)) / sizeof(x[0])) -#endif +#endif /* !defined(TOR_UTIL_H) */ |