diff options
author | Nick Mathewson <nickm@torproject.org> | 2006-09-24 17:20:41 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2006-09-24 17:20:41 +0000 |
commit | 9006dbeb812168e0eb7ec707a61a7d539b18ecea (patch) | |
tree | 17eb1979d71a24c99cff0d87f047f3aaa8875c5d /src/common | |
parent | bf738d30808190fcd20e8bcb3e75b17f7b730105 (diff) | |
download | tor-9006dbeb812168e0eb7ec707a61a7d539b18ecea.tar.gz tor-9006dbeb812168e0eb7ec707a61a7d539b18ecea.zip |
Oops. My last commit to the 1.1 branch somehow merged the whole stable branch in. Bad idea. This should revert it.
svn:r8479
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/compat.c | 201 | ||||
-rw-r--r-- | src/common/compat.h | 123 | ||||
-rw-r--r-- | src/common/container.c | 174 | ||||
-rw-r--r-- | src/common/container.h | 42 | ||||
-rw-r--r-- | src/common/crypto.c | 74 | ||||
-rw-r--r-- | src/common/crypto.h | 2 | ||||
-rw-r--r-- | src/common/ht.h | 101 | ||||
-rw-r--r-- | src/common/log.c | 9 | ||||
-rw-r--r-- | src/common/log.h | 12 | ||||
-rw-r--r-- | src/common/torgzip.c | 96 | ||||
-rw-r--r-- | src/common/torgzip.h | 12 | ||||
-rw-r--r-- | src/common/torint.h | 6 | ||||
-rw-r--r-- | src/common/tortls.c | 159 | ||||
-rw-r--r-- | src/common/tortls.h | 4 | ||||
-rw-r--r-- | src/common/util.c | 163 | ||||
-rw-r--r-- | src/common/util.h | 87 |
16 files changed, 422 insertions, 843 deletions
diff --git a/src/common/compat.c b/src/common/compat.c index c98748bcd2..3a05c32d45 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -24,9 +24,8 @@ const char compat_c_id[] = #ifdef MS_WINDOWS #include <process.h> -#include <windows.h> -#endif +#endif #ifdef HAVE_UNAME #include <sys/utsname.h> #endif @@ -88,13 +87,6 @@ const char compat_c_id[] = #ifdef HAVE_SYS_UTIME_H #include <sys/utime.h> #endif -#ifdef HAVE_SYS_MMAN_H -#include <sys/mman.h> -#endif - -#ifdef USE_BSOCKETS -#include <bsocket.h> -#endif #include "log.h" #include "util.h" @@ -112,135 +104,6 @@ const char compat_c_id[] = #define INADDR_NONE ((unsigned long) -1) #endif -#ifdef HAVE_SYS_MMAN_H -tor_mmap_t * -tor_mmap_file(const char *filename) -{ - int fd; /* router file */ - char *string; - int page_size; - tor_mmap_t *res; - size_t size; - - tor_assert(filename); - - fd = open(filename, O_RDONLY, 0); - if (fd<0) { - log_warn(LD_FS,"Could not open \"%s\" for mmap().",filename); - return NULL; - } - - size = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_SET); - /* ensure page alignment */ - page_size = getpagesize(); - size += (size%page_size) ? page_size-(size%page_size) : 0; - - string = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0); - if (string == MAP_FAILED) { - close(fd); - log_warn(LD_FS,"Could not mmap file \"%s\": %s", filename, - strerror(errno)); - return NULL; - } - - close(fd); - - res = tor_malloc_zero(sizeof(tor_mmap_t)); - res->data = string; - res->size = size; - - return res; -} -void -tor_munmap_file(tor_mmap_t *handle) -{ - munmap((char*)handle->data, handle->size); - tor_free(handle); -} -#elif defined(MS_WINDOWS) -typedef struct win_mmap_t { - tor_mmap_t base; - HANDLE file_handle; - HANDLE mmap_handle; -} tor_mmap_impl_t; -tor_mmap_t * -tor_mmap_file(const char *filename) -{ - struct win_mmap_t *res = tor_malloc_zero(sizeof(struct win_mmap_t)); - res->mmap_handle = res->file_handle = INVALID_HANDLE_VALUE; - - res->file_handle = CreateFile(filename, - GENERIC_READ, - 0, NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - 0); - - if (res->file_handle == INVALID_HANDLE_VALUE) - goto err; - - res->base.size = GetFileSize(res->file_handle, NULL); - - res->mmap_handle = CreateFileMapping(res->file_handle, - NULL, - PAGE_READONLY, - (res->base.size >> 32), - (res->base.size & 0xfffffffful), - NULL); - if (res->mmap_handle != INVALID_HANDLE_VALUE) - goto err; - res->base.data = (char*) MapViewOfFile(res->mmap_handle, - FILE_MAP_READ, - 0, 0, 0); - if (!res->base.data) - goto err; - - return &(res->base); - err: - tor_munmap_file(&res->base); - return NULL; -} -void -tor_munmap_file(tor_mmap_t *handle) -{ - struct win_mmap_t *h = (struct win_mmap_t*) - (((char*)handle) - STRUCT_OFFSET(struct win_mmap_t, base)); - if (handle->data) - - /*this is an ugly cast, but without it, "data" in struct tor_mmap_t would - have to be redefined as const*/ - UnmapViewOfFile( (LPVOID) handle->data); - - if (h->mmap_handle != INVALID_HANDLE_VALUE) - CloseHandle(h->mmap_handle); - if (h->file_handle != INVALID_HANDLE_VALUE) - CloseHandle(h->file_handle); - tor_free(h); -} -#else -tor_mmap_t * -tor_mmap_file(const char *filename) -{ - char *res = read_file_to_str(filename, 1); - tor_mmap_t *handle; - if (! res) - return NULL; - handle = tor_malloc_zero(sizeof(tor_mmap_t)); - handle->data = res; - handle->size = strlen(res) + 1; - return handle; -} -void -tor_munmap_file(tor_mmap_t *handle) -{ - char *d = (char*)handle->data; - tor_free(d); - memset(handle, sizeof(tor_mmap_t), 0); - tor_free(handle); -} -#endif - /** Replacement for snprintf. Differs from platform snprintf in two * ways: First, always NUL-terminates its output. Second, always * returns -1 if the result is truncated. (Note that this return @@ -343,6 +206,7 @@ tor_fix_source_file(const char *fname) } #endif +#ifndef UNALIGNED_INT_ACCESS_OK /** * Read a 16-bit value beginning at <b>cp</b>. Equivalent to * *(uint16_t*)(cp), but will not cause segfaults on platforms that forbid @@ -385,6 +249,7 @@ set_uint32(char *cp, uint32_t v) { memcpy(cp,&v,4); } +#endif /** * Rename the file <b>from</b> to the file <b>to</b>. On unix, this is @@ -429,8 +294,8 @@ touch_file(const char *fname) void set_socket_nonblocking(int socket) { -#if defined(MS_WINDOWS) && !defined(USE_BSOCKETS) - unsigned long nonblocking = 1; +#ifdef MS_WINDOWS + int nonblocking = 1; ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking); #else fcntl(socket, F_SETFL, O_NONBLOCK); @@ -457,13 +322,10 @@ set_socket_nonblocking(int socket) int tor_socketpair(int family, int type, int protocol, int fd[2]) { -//don't use win32 socketpairs (they are always bad) -#if defined(HAVE_SOCKETPAIR) && !defined(MS_WINDOWS) +#ifdef HAVE_SOCKETPAIR int r; r = socketpair(family, type, protocol, fd); return r < 0 ? -errno : r; -#elif defined(USE_BSOCKETS) - return bsockepair(family, type, protocol, fd); #else /* This socketpair does not work when localhost is down. So * it's really not the same thing at all. But it's close enough @@ -494,8 +356,17 @@ tor_socketpair(int family, int type, int protocol, int fd[2]) } listener = socket(AF_INET, type, 0); - if (listener < 0) + if (listener == -1) return -tor_socket_errno(-1); + if (!SOCKET_IS_POLLABLE(listener)) { + log_warn(LD_NET, "Too many connections; can't open socketpair"); + tor_close_socket(listener); +#ifdef MS_WINDOWS + return -ENFILE; +#else + return -ENCONN; +#endif + } memset(&listen_addr, 0, sizeof(listen_addr)); listen_addr.sin_family = AF_INET; listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); @@ -507,8 +378,12 @@ tor_socketpair(int family, int type, int protocol, int fd[2]) goto tidy_up_and_fail; connector = socket(AF_INET, type, 0); - if (connector < 0) + if (connector == -1) + goto tidy_up_and_fail; + if (!SOCKET_IS_POLLABLE(connector)) { + log_warn(LD_NET, "Too many connections; can't open socketpair"); goto tidy_up_and_fail; + } /* We want to find out the port number to connect to. */ size = sizeof(connect_addr); if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1) @@ -521,8 +396,12 @@ tor_socketpair(int family, int type, int protocol, int fd[2]) size = sizeof(listen_addr); acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size); - if (acceptor < 0) + if (acceptor == -1) + goto tidy_up_and_fail; + if (!SOCKET_IS_POLLABLE(acceptor)) { + log_warn(LD_NET, "Too many connections; can't open socketpair"); goto tidy_up_and_fail; + } if (size != sizeof(listen_addr)) goto abort_tidy_up_and_fail; tor_close_socket(listener); @@ -578,7 +457,7 @@ set_max_file_descriptors(unsigned long limit, unsigned long cap) log_fn(LOG_INFO, LD_NET, "This platform is missing getrlimit(). Proceeding."); if (limit < cap) { - log_info(LD_CONFIG, "ConnLimit must be at most %d. Using that.", (int)cap); + log_info(LD_CONFIG, "ConnLimit must be at most %d. Using that.", cap); limit = cap; } #else @@ -749,7 +628,7 @@ tor_lookup_hostname(const char *name, uint32_t *addr) memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_INET; hints.ai_socktype = SOCK_STREAM; - err = getaddrinfo(name, NULL, &hints, &res); + err = getaddrinfo(name, NULL, NULL, &res); if (!err) { for (res_p = res; res_p; res_p = res_p->ai_next) { if (res_p->ai_family == AF_INET) { @@ -846,7 +725,6 @@ get_uname(void) { 3, 51, "Windows NT 3.51" }, { -1, -1, NULL } }; -#ifdef VER_SUITE_BACKOFFICE static struct { unsigned int mask; const char *str; } win_mask_table[] = { @@ -864,10 +742,10 @@ get_uname(void) { VER_SUITE_TERMINAL, " {terminal services}" }, { 0, NULL }, }; -#endif memset(&info, 0, sizeof(info)); info.dwOSVersionInfoSize = sizeof(info); if (! GetVersionEx((LPOSVERSIONINFO)&info)) { + int err = GetLastError(); strlcpy(uname_result, "Bizarre version of Windows where GetVersionEx" " doesn't work.", sizeof(uname_result)); uname_result_is_set = 1; @@ -903,7 +781,6 @@ get_uname(void) (int)info.dwMajorVersion,(int)info.dwMinorVersion, info.szCSDVersion); } -#ifdef VER_SUITE_BACKOFFICE if (info.wProductType == VER_NT_DOMAIN_CONTROLLER) { strlcat(uname_result, " [domain controller]", sizeof(uname_result)); } else if (info.wProductType == VER_NT_SERVER) { @@ -923,7 +800,6 @@ get_uname(void) tor_snprintf(uname_result+len, sizeof(uname_result)-len, " {0x%x}", info.wSuiteMask); } -#endif #else strlcpy(uname_result, "Unknown platform", sizeof(uname_result)); #endif @@ -942,14 +818,14 @@ get_uname(void) * invoke them in a way pthreads would expect. */ typedef struct tor_pthread_data_t { - void (*func)(void *); + int (*func)(void *); void *data; } tor_pthread_data_t; static void * tor_pthread_helper_fn(void *_data) { tor_pthread_data_t *data = _data; - void (*func)(void*); + int (*func)(void*); void *arg; func = data->func; arg = data->data; @@ -969,7 +845,7 @@ tor_pthread_helper_fn(void *_data) * running. */ int -spawn_func(void (*func)(void *), void *data) +spawn_func(int (*func)(void *), void *data) { #if defined(USE_WIN32_THREADS) int rv; @@ -1012,10 +888,6 @@ spawn_exit(void) { #if defined(USE_WIN32_THREADS) _endthread(); - //we should never get here. my compiler thinks that _endthread returns, this - //is an attempt to fool it. - tor_assert(0); - _exit(0); #elif defined(USE_PTHREADS) pthread_exit(NULL); #else @@ -1023,7 +895,6 @@ spawn_exit(void) * call _exit, not exit, from child processes. */ _exit(0); #endif - } /** Set *timeval to the current time of day. On error, log and terminate. @@ -1163,7 +1034,7 @@ tor_mutex_acquire(tor_mutex_t *m) tor_assert(0); break; case WAIT_FAILED: - log_warn(LD_GENERAL, "Failed to acquire mutex: %d",(int) GetLastError()); + log_warn(LD_GENERAL, "Failed to acquire mutex: %d", GetLastError()); } } void @@ -1172,7 +1043,7 @@ tor_mutex_release(tor_mutex_t *m) BOOL r; r = ReleaseMutex(m->handle); if (!r) { - log_warn(LD_GENERAL, "Failed to release mutex: %d", (int) GetLastError()); + log_warn(LD_GENERAL, "Failed to release mutex: %d", GetLastError()); } } unsigned long @@ -1239,7 +1110,7 @@ struct tor_mutex_t { * should call tor_socket_errno <em>at most once</em> on the failing * socket to get the error. */ -#if defined(MS_WINDOWS) && !defined(USE_BSOCKETS) +#ifdef MS_WINDOWS int tor_socket_errno(int sock) { @@ -1255,7 +1126,7 @@ tor_socket_errno(int sock) } #endif -#if defined(MS_WINDOWS) && !defined(USE_BSOCKETS) +#ifdef MS_WINDOWS #define E(code, s) { code, (s " [" #code " ]") } struct { int code; const char *msg; } windows_socket_errors[] = { E(WSAEINTR, "Interrupted function call"), diff --git a/src/common/compat.h b/src/common/compat.h index 5567f5e9c1..7975dbb9ba 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -76,34 +76,6 @@ #endif /* ifndef MAVE_MACRO__func__ */ #endif /* if not windows */ -#if defined(_MSC_VER) && (_MSC_VER < 1300) -/* MSVC versions before 7 apparently don't believe that you can cast uint64_t - * to double and really mean it. */ -extern INLINE double U64_TO_DBL(uint64_t x) { - int64_t i = (int64_t) x; - return (i < 0) ? ((double) INT64_MAX) : (double) i; -} -#define DBL_TO_U64(x) ((uint64_t)(int64_t) (x)) -#else -#define U64_TO_DBL(x) ((double) (x)) -#define DBL_TO_U64(x) ((uint64_t) (x)) -#endif - -/* GCC has several useful attributes. */ -#if defined(__GNUC__) && __GNUC__ >= 3 -#define ATTR_NORETURN __attribute__((noreturn)) -#define ATTR_PURE __attribute__((pure)) -#define ATTR_MALLOC __attribute__((malloc)) -#define ATTR_NONNULL(x) __attribute__((nonnull x)) -#define PREDICT(exp, val) __builtin_expect((exp), (val)) -#else -#define ATTR_NORETURN -#define ATTR_PURE -#define ATTR_MALLOC -#define ATTR_NONNULL(x) -#define PREDICT(exp, val) (exp) -#endif - /* ===== String compatibility */ #ifdef MS_WINDOWS /* Windows names string functions differently from most other platforms. */ @@ -111,13 +83,13 @@ extern INLINE double U64_TO_DBL(uint64_t x) { #define strcasecmp stricmp #endif #ifndef HAVE_STRLCAT -size_t strlcat(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2)); +size_t strlcat(char *dst, const char *src, size_t siz); #endif #ifndef HAVE_STRLCPY -size_t strlcpy(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2)); +size_t strlcpy(char *dst, const char *src, size_t siz); #endif -#ifdef _MSC_VER +#ifdef MS_WINDOWS #define U64_PRINTF_ARG(a) (a) #define U64_SCANF_ARG(a) (a) #define U64_FORMAT "%I64u" @@ -129,22 +101,12 @@ size_t strlcpy(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2)); #define U64_LITERAL(n) (n ## llu) #endif -/** Opaque bookkeeping type used for mmap accounting. */ -typedef struct tor_mmap_t { - const char *data; - size_t size; -} tor_mmap_t; - -tor_mmap_t *tor_mmap_file(const char *filename) ATTR_NONNULL((1)); -void tor_munmap_file(tor_mmap_t *handle) ATTR_NONNULL((1)); - int tor_snprintf(char *str, size_t size, const char *format, ...) - CHECK_PRINTF(3,4) ATTR_NONNULL((1,3)); -int tor_vsnprintf(char *str, size_t size, const char *format, va_list args) - ATTR_NONNULL((1,3)); + CHECK_PRINTF(3,4); +int tor_vsnprintf(char *str, size_t size, const char *format, va_list args); const void *tor_memmem(const void *haystack, size_t hlen, const void *needle, - size_t nlen) ATTR_PURE ATTR_NONNULL((1,3)); + size_t nlen); #define TOR_ISALPHA(c) isalpha((int)(unsigned char)(c)) #define TOR_ISALNUM(c) isalnum((int)(unsigned char)(c)) @@ -152,11 +114,9 @@ const void *tor_memmem(const void *haystack, size_t hlen, const void *needle, #define TOR_ISXDIGIT(c) isxdigit((int)(unsigned char)(c)) #define TOR_ISDIGIT(c) isdigit((int)(unsigned char)(c)) #define TOR_ISPRINT(c) isprint((int)(unsigned char)(c)) -#define TOR_ISLOWER(c) islower((int)(unsigned char)(c)) -#define TOR_ISUPPER(c) isupper((int)(unsigned char)(c)) -#define TOR_TOLOWER(c) ((char)tolower((int)(unsigned char)(c))) -#define TOR_TOUPPER(c) ((char)toupper((int)(unsigned char)(c))) +#define TOR_TOLOWER(c) (char)tolower((int)(unsigned char)(c)) +#define TOR_TOUPPER(c) (char)toupper((int)(unsigned char)(c)) #ifdef MS_WINDOWS #define _SHORT_FILE_ (tor_fix_source_file(__FILE__)) @@ -199,10 +159,8 @@ int touch_file(const char *fname); #endif /* ===== Net compatibility */ -#ifdef USE_BSOCKETS -#define tor_close_socket(s) bclose(s) -#elif defined(MS_WINDOWS) -/** On Windows, you have to call close() on fds returned by open(), +#ifdef MS_WINDOWS +/** On windows, you have to call close() on fds returned by open(), * and closesocket() on fds returned by socket(). On Unix, everything * gets close()'d. We abstract this difference by always using * tor_close_socket to close sockets, and always using close() on @@ -213,21 +171,17 @@ int touch_file(const char *fname); #define tor_close_socket(s) close(s) #endif -#ifdef USE_BSOCKETS -#define tor_socket_send(s, buf, len, flags) bsend(s, buf, len, flags) -#define tor_socket_recv(s, buf, len, flags) brecv(s, buf, len, flags) -#else -#define tor_socket_send(s, buf, len, flags) send(s, buf, len, flags) -#define tor_socket_recv(s, buf, len, flags) recv(s, buf, len, flags) -#endif - #if (SIZEOF_SOCKLEN_T == 0) typedef int socklen_t; #endif +/* Now that we use libevent, all real sockets are safe for polling ... or + * if they aren't, libevent will help us. */ +#define SOCKET_IS_POLLABLE(fd) ((fd)>=0) + struct in_addr; -int tor_inet_aton(const char *cp, struct in_addr *addr) ATTR_NONNULL((1,2)); -int tor_lookup_hostname(const char *name, uint32_t *addr) ATTR_NONNULL((1,2)); +int tor_inet_aton(const char *cp, struct in_addr *addr); +int tor_lookup_hostname(const char *name, uint32_t *addr); void set_socket_nonblocking(int socket); int tor_socketpair(int family, int type, int protocol, int fd[2]); int network_init(void); @@ -237,7 +191,7 @@ int network_init(void); * errnos against expected values, and use tor_socket_errno to find * the actual errno after a socket operation fails. */ -#if defined(MS_WINDOWS) && !defined(USE_BSOCKETS) +#ifdef MS_WINDOWS /** Return true if e is EAGAIN or the local equivalent. */ #define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || (e) == WSAEWOULDBLOCK) /** Return true if e is EINPROGRESS or the local equivalent. */ @@ -272,10 +226,21 @@ const char *tor_socket_strerror(int e); /* ===== OS compatibility */ const char *get_uname(void); -uint16_t get_uint16(const char *cp) ATTR_PURE ATTR_NONNULL((1)); -uint32_t get_uint32(const char *cp) ATTR_PURE ATTR_NONNULL((1)); -void set_uint16(char *cp, uint16_t v) ATTR_NONNULL((1)); -void set_uint32(char *cp, uint32_t v) ATTR_NONNULL((1)); +/* Some platforms segfault when you try to access a multi-byte type + * that isn't aligned to a word boundary. The macros and/or functions + * below can be used to access unaligned data on any platform. + */ +#ifdef UNALIGNED_INT_ACCESS_OK +#define get_uint16(cp) (*(uint16_t*)(cp)) +#define get_uint32(cp) (*(uint32_t*)(cp)) +#define set_uint16(cp,v) do { *(uint16_t*)(cp) = (v); } while (0) +#define set_uint32(cp,v) do { *(uint32_t*)(cp) = (v); } while (0) +#else +uint16_t get_uint16(const char *cp); +uint32_t get_uint32(const char *cp); +void set_uint16(char *cp, uint16_t v); +void set_uint32(char *cp, uint32_t v); +#endif int set_max_file_descriptors(unsigned long limit, unsigned long cap); int switch_id(char *user, char *group); @@ -283,8 +248,8 @@ int switch_id(char *user, char *group); char *get_user_homedir(const char *username); #endif -int spawn_func(void (*func)(void *), void *data); -void spawn_exit(void) ATTR_NORETURN; +int spawn_func(int (*func)(void *), void *data); +void spawn_exit(void); #if defined(ENABLE_THREADS) && defined(MS_WINDOWS) #define USE_WIN32_THREADS @@ -297,9 +262,8 @@ void spawn_exit(void) ATTR_NORETURN; #undef TOR_IS_MULTITHREADED #endif -/* Because we use threads instead of processes on most platforms (Windows, - * Linux, etc), we need locking for them. On platforms with poor thread - * support or broken gethostbyname_r, these functions are no-ops. */ +/* Because we use threads instead of processes on Windows, we need locking on + * Windows. On Unixy platforms, these functions are no-ops. */ typedef struct tor_mutex_t tor_mutex_t; #ifdef TOR_IS_MULTITHREADED @@ -316,20 +280,5 @@ unsigned long tor_get_thread_id(void); #define tor_get_thread_id() (1UL) #endif -/*for some reason my compiler doesn't have these version flags defined - a nice homework assignment for someone one day is to define the rest*/ -//these are the values as given on MSDN -#ifdef MS_WINDOWS - -#ifndef VER_SUITE_EMBEDDEDNT -#define VER_SUITE_EMBEDDEDNT 0x00000040 -#endif - -#ifndef VER_SUITE_SINGLEUSERTS -#define VER_SUITE_SINGLEUSERTS 0x00000100 -#endif - -#endif - #endif diff --git a/src/common/container.c b/src/common/container.c index 64ad420633..33a77cd42c 100644 --- a/src/common/container.c +++ b/src/common/container.c @@ -50,7 +50,6 @@ smartlist_create(void) void smartlist_free(smartlist_t *sl) { - tor_assert(sl != NULL); tor_free(sl->list); tor_free(sl); } @@ -128,32 +127,6 @@ smartlist_remove(smartlist_t *sl, const void *element) } } -/** If <b>sl</b> is nonempty, remove and return the final element. Otherwise, - * return NULL. */ -void * -smartlist_pop_last(smartlist_t *sl) -{ - tor_assert(sl); - if (sl->num_used) - return sl->list[--sl->num_used]; - else - return NULL; -} - -/** Reverse the order of the items in <b>sl</b>. */ -void -smartlist_reverse(smartlist_t *sl) -{ - int i, j; - void *tmp; - tor_assert(sl); - for (i = 0, j = sl->num_used-1; i < j; ++i, --j) { - tmp = sl->list[i]; - sl->list[i] = sl->list[j]; - sl->list[j] = tmp; - } -} - /** If there are any strings in sl equal to element, remove and free them. * Does not preserve order. */ void @@ -429,29 +402,6 @@ smartlist_sort(smartlist_t *sl, int (*compare)(const void **a, const void **b)) (int (*)(const void *,const void*))compare); } -/** Given a sorted smartlist <b>sl</b> and the comparison function used to - * sort it, remove all duplicate members. If free_fn is provided, calls - * free_fn on each duplicate. Otherwise, frees them with tor_free(), which - * may not be what you want.. Preserves order. - */ -void -smartlist_uniq(smartlist_t *sl, - int (*compare)(const void **a, const void **b), - void (*free_fn)(void *a)) -{ - int i; - for (i=1; i < sl->num_used; ++i) { - if (compare((const void **)&(sl->list[i-1]), - (const void **)&(sl->list[i])) == 0) { - if (free_fn) - free_fn(sl->list[i]); - else - tor_free(sl->list[i]); - smartlist_del_keeporder(sl, i--); - } - } -} - /** Assuming the members of <b>sl</b> are in order, return a pointer to the * member which matches <b>key</b>. Ordering and matching are defined by a * <b>compare</b> function, which returns 0 on a match; less than 0 if key is @@ -485,117 +435,6 @@ smartlist_sort_strings(smartlist_t *sl) smartlist_sort(sl, _compare_string_ptrs); } -/** Remove duplicate strings from a sorted list, and free them with tor_free(). - */ -void -smartlist_uniq_strings(smartlist_t *sl) -{ - smartlist_uniq(sl, _compare_string_ptrs, NULL); -} - -#define LEFT_CHILD(i) ( ((i)+1)*2 - 1) -#define RIGHT_CHILD(i) ( ((i)+1)*2 ) -#define PARENT(i) ( ((i)+1)/2 - 1) - -static INLINE void -smartlist_heapify(smartlist_t *sl, - int (*compare)(const void *a, const void *b), - int idx) -{ - while (1) { - int left_idx = LEFT_CHILD(idx); - int best_idx; - - if (left_idx >= sl->num_used) - return; - if (compare(sl->list[idx],sl->list[left_idx]) < 0) - best_idx = idx; - else - best_idx = left_idx; - if (left_idx+1 < sl->num_used && - compare(sl->list[left_idx+1],sl->list[best_idx]) < 0) - best_idx = left_idx + 1; - - if (best_idx == idx) { - return; - } else { - void *tmp = sl->list[idx]; - sl->list[idx] = sl->list[best_idx]; - sl->list[best_idx] = tmp; - - idx = best_idx; - } - } -} - -void -smartlist_pqueue_add(smartlist_t *sl, - int (*compare)(const void *a, const void *b), - void *item) -{ - int idx; - smartlist_add(sl,item); - - for (idx = sl->num_used - 1; idx; ) { - int parent = PARENT(idx); - if (compare(sl->list[idx], sl->list[parent]) < 0) { - void *tmp = sl->list[parent]; - sl->list[parent] = sl->list[idx]; - sl->list[idx] = tmp; - idx = parent; - } else { - return; - } - } -} - -void * -smartlist_pqueue_pop(smartlist_t *sl, - int (*compare)(const void *a, const void *b)) -{ - void *top; - tor_assert(sl->num_used); - - top = sl->list[0]; - if (--sl->num_used) { - sl->list[0] = sl->list[sl->num_used]; - smartlist_heapify(sl, compare, 0); - } - return top; -} - -void -smartlist_pqueue_assert_ok(smartlist_t *sl, - int (*compare)(const void *a, const void *b)) -{ - int i; - for (i = sl->num_used - 1; i > 0; --i) { - tor_assert(compare(sl->list[PARENT(i)], sl->list[i]) <= 0); - } -} - -/** Helper: compare two DIGEST_LEN digests. */ -static int -_compare_digests(const void **_a, const void **_b) -{ - return memcmp((const char*)*_a, (const char*)*_b, DIGEST_LEN); -} - -/** Sort the list of DIGEST_LEN-byte digests into ascending order. */ -void -smartlist_sort_digests(smartlist_t *sl) -{ - smartlist_sort(sl, _compare_digests); -} - -/** Remove duplicate digests from a sorted list, and free them with tor_free(). - */ -void -smartlist_uniq_digests(smartlist_t *sl) -{ - smartlist_uniq(sl, _compare_digests, NULL); -} - #define DEFINE_MAP_STRUCTS(maptype, keydecl, prefix) \ typedef struct prefix ## entry_t { \ HT_ENTRY(prefix ## entry_t) node; \ @@ -863,7 +702,7 @@ strmap_remove_lc(strmap_t *map, const char *key) * iter = strmap_iter_next_rmv(iter); * free(val); * } else { - * for (;*cp;cp++) *cp = TOR_TOUPPER(*cp); + * for (;*cp;cp++) *cp = toupper(*cp); * iter = strmap_iter_next(iter); * } * } @@ -1005,17 +844,6 @@ digestmap_free(digestmap_t *map, void (*free_val)(void*)) tor_free(map); } -void -strmap_assert_ok(strmap_t *map) -{ - tor_assert(!_strmap_impl_HT_REP_IS_BAD(&map->head)); -} -void -digestmap_assert_ok(digestmap_t *map) -{ - tor_assert(!_digestmap_impl_HT_REP_IS_BAD(&map->head)); -} - /** Return true iff <b>map</b> has no entries. */ int strmap_isempty(strmap_t *map) diff --git a/src/common/container.h b/src/common/container.h index 5f0417cf4d..83c0f28229 100644 --- a/src/common/container.h +++ b/src/common/container.h @@ -29,29 +29,24 @@ void smartlist_clear(smartlist_t *sl); void smartlist_add(smartlist_t *sl, void *element); void smartlist_add_all(smartlist_t *sl, const smartlist_t *s2); void smartlist_remove(smartlist_t *sl, const void *element); -void *smartlist_pop_last(smartlist_t *sl); -void smartlist_reverse(smartlist_t *sl); void smartlist_string_remove(smartlist_t *sl, const char *element); -int smartlist_isin(const smartlist_t *sl, const void *element) ATTR_PURE; -int smartlist_string_isin(const smartlist_t *sl, const char *element) - ATTR_PURE; -int smartlist_string_num_isin(const smartlist_t *sl, int num) ATTR_PURE; -int smartlist_overlap(const smartlist_t *sl1, const smartlist_t *sl2) - ATTR_PURE; +int smartlist_isin(const smartlist_t *sl, const void *element); +int smartlist_string_isin(const smartlist_t *sl, const char *element); +int smartlist_string_num_isin(const smartlist_t *sl, int num); +int smartlist_overlap(const smartlist_t *sl1, const smartlist_t *sl2); void smartlist_intersect(smartlist_t *sl1, const smartlist_t *sl2); void smartlist_subtract(smartlist_t *sl1, const smartlist_t *sl2); - /* smartlist_choose() is defined in crypto.[ch] */ #ifdef DEBUG_SMARTLIST /** Return the number of items in sl. */ -extern INLINE int smartlist_len(const smartlist_t *sl) ATTR_PURE { +extern INLINE int smartlist_len(const smartlist_t *sl) { tor_assert(sl); return (sl)->num_used; } /** Return the <b>idx</b>th element of sl. */ -extern INLINE void *smartlist_get(const smartlist_t *sl, int idx) ATTR_PURE { +extern INLINE void *smartlist_get(const smartlist_t *sl, int idx) { tor_assert(sl); tor_assert(idx>=0); tor_assert(sl->num_used < idx); @@ -74,34 +69,18 @@ void smartlist_del_keeporder(smartlist_t *sl, int idx); void smartlist_insert(smartlist_t *sl, int idx, void *val); void smartlist_sort(smartlist_t *sl, int (*compare)(const void **a, const void **b)); -void smartlist_uniq(smartlist_t *sl, - int (*compare)(const void **a, const void **b), - void (*free_fn)(void *elt)); void smartlist_sort_strings(smartlist_t *sl); -void smartlist_sort_digests(smartlist_t *sl); -void smartlist_uniq_strings(smartlist_t *sl); -void smartlist_uniq_digests(smartlist_t *sl); void *smartlist_bsearch(smartlist_t *sl, const void *key, - int (*compare)(const void *key, const void **member)) - ATTR_PURE; - -void smartlist_pqueue_add(smartlist_t *sl, - int (*compare)(const void *a, const void *b), - void *item); -void *smartlist_pqueue_pop(smartlist_t *sl, - int (*compare)(const void *a, const void *b)); -void smartlist_pqueue_assert_ok(smartlist_t *sl, - int (*compare)(const void *a, const void *b)); + int (*compare)(const void *key, const void **member)); #define SPLIT_SKIP_SPACE 0x01 #define SPLIT_IGNORE_BLANK 0x02 int smartlist_split_string(smartlist_t *sl, const char *str, const char *sep, int flags, int max); char *smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, - size_t *len_out) ATTR_MALLOC; + size_t *len_out); char *smartlist_join_strings2(smartlist_t *sl, const char *join, - size_t join_len, int terminate, size_t *len_out) - ATTR_MALLOC; + size_t join_len, int terminate, size_t *len_out); /** Iterate over the items in a smartlist <b>sl</b>, in order. For each item, * assign it to a new local variable of type <b>type</b> named <b>var</b>, and @@ -143,8 +122,7 @@ char *smartlist_join_strings2(smartlist_t *sl, const char *join, 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); \ void prefix##iter_get(prefix##iter_t *iter, keytype *keyp, void **valp); \ - int prefix##iter_done(prefix##iter_t *iter); \ - void prefix##assert_ok(maptype *map); + int prefix##iter_done(prefix##iter_t *iter); /* Map from const char * to void *. Implemented with a hash table. */ DECLARE_MAP_FNS(strmap_t, const char *, strmap_); diff --git a/src/common/crypto.c b/src/common/crypto.c index 57b504f5ba..62e7c3c245 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -189,10 +189,6 @@ crypto_global_init(int useAccel) OpenSSL_add_all_algorithms(); _crypto_global_initialized = 1; setup_openssl_threading(); - /* XXX the below is a bug, since we can't know if we're supposed - * to be using hardware acceleration or not. we should arrange - * for this function to be called before init_keys. But make it - * not complain loudly, at least until we make acceleration work. */ if (useAccel < 0) { log_info(LD_CRYPTO, "Initializing OpenSSL via tor_tls_init()."); } @@ -503,13 +499,13 @@ crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest, } BIO_get_mem_ptr(b, &buf); - (void)BIO_set_close(b, BIO_NOCLOSE); /* so BIO_free doesn't free buf */ + BIO_set_close(b, BIO_NOCLOSE); /* so BIO_free doesn't free buf */ BIO_free(b); tor_assert(buf->length >= 0); *dest = tor_malloc(buf->length+1); memcpy(*dest, buf->data, buf->length); - (*dest)[buf->length] = 0; /* nul terminate it */ + (*dest)[buf->length] = 0; /* null terminate it */ *len = buf->length; BUF_MEM_free(buf); @@ -579,6 +575,70 @@ crypto_pk_write_private_key_to_filename(crypto_pk_env_t *env, return r; } +/** Allocate a new string in *<b>out</b>, containing the public portion of the + * RSA key in <b>env</b>, encoded first with DER, then in base-64. Return the + * length of the encoded representation on success, and -1 on failure. + * + * <i>This function is for temporary use only. We need a simple + * one-line representation for keys to work around a bug in parsing + * directories containing "opt keyword\n-----BEGIN OBJECT----" entries + * in versions of Tor up to 0.0.9pre2.</i> + */ +int +crypto_pk_DER64_encode_public_key(crypto_pk_env_t *env, char **out) +{ + int len; + char buf[PK_BYTES*2]; /* Too long, but hey, stacks are big. */ + tor_assert(env); + tor_assert(out); + len = crypto_pk_asn1_encode(env, buf, sizeof(buf)); + if (len < 0) { + return -1; + } + *out = tor_malloc(len * 2); /* too long, but safe. */ + if (base64_encode(*out, len*2, buf, len) < 0) { + log_warn(LD_CRYPTO, "Error base64-encoding DER-encoded key"); + tor_free(*out); + return -1; + } + /* Remove spaces */ + tor_strstrip(*out, " \r\n\t"); + return strlen(*out); +} + +/** Decode a base-64 encoded DER representation of an RSA key from <b>in</b>, + * and store the result in <b>env</b>. Return 0 on success, -1 on failure. + * + * <i>This function is for temporary use only. We need a simple + * one-line representation for keys to work around a bug in parsing + * directories containing "opt keyword\n-----BEGIN OBJECT----" entries + * in versions of Tor up to 0.0.9pre2.</i> + */ +crypto_pk_env_t * +crypto_pk_DER64_decode_public_key(const char *in) +{ + char partitioned[PK_BYTES*2 + 16]; + char buf[PK_BYTES*2]; + int len; + tor_assert(in); + len = strlen(in); + + if (strlen(in) > PK_BYTES*2) { + return NULL; + } + /* base64_decode doesn't work unless we insert linebreaks every 64 + * characters. how dumb. */ + if (tor_strpartition(partitioned, sizeof(partitioned), in, "\n", 64, + ALWAYS_TERMINATE)) + return NULL; + len = base64_decode(buf, sizeof(buf), partitioned, strlen(partitioned)); + if (len<0) { + log_warn(LD_CRYPTO,"Error base-64 decoding key"); + return NULL; + } + return crypto_pk_asn1_decode(buf, len); +} + /** Return true iff <b>env</b> has a valid key. */ int @@ -1806,8 +1866,6 @@ secret_to_key(char *key_out, size_t key_out_len, const char *secret, static void _openssl_locking_cb(int mode, int n, const char *file, int line) { - (void)file; - (void)line; if (!_openssl_mutexes) /* This is not a really good fix for the * "release-freed-lock-from-separate-thread-on-shutdown" problem, but diff --git a/src/common/crypto.h b/src/common/crypto.h index 050849cfe5..df112a1d8e 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -79,6 +79,8 @@ int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, const char *src, size_t len); int crypto_pk_write_private_key_to_filename(crypto_pk_env_t *env, const char *fname); +int crypto_pk_DER64_encode_public_key(crypto_pk_env_t *env, char **dest); +crypto_pk_env_t *crypto_pk_DER64_decode_public_key(const char *in); int crypto_pk_check_key(crypto_pk_env_t *env); int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b); diff --git a/src/common/ht.h b/src/common/ht.h index a83e093264..dd90f2e4fd 100644 --- a/src/common/ht.h +++ b/src/common/ht.h @@ -99,7 +99,7 @@ ht_string_hash(const char *s) #define HT_PROTOTYPE(name, type, field, hashfn, eqfn) \ int name##_HT_GROW(struct name *ht, unsigned min_capacity); \ void name##_HT_CLEAR(struct name *ht); \ - int _##name##_HT_REP_IS_BAD(struct name *ht); \ + int _##name##_HT_REP_OK(struct name *ht); \ /* Helper: returns a pointer to the right location in the table \ * 'head' to find or insert the element 'elm'. */ \ static INLINE struct type ** \ @@ -187,6 +187,7 @@ ht_string_hash(const char *s) int (*fn)(struct type *, void *), \ void *data) \ { \ + /* XXXX use tricks to prevent concurrent mod? */ \ unsigned idx; \ int remove; \ struct type **p, **nextp, *next; \ @@ -260,6 +261,77 @@ ht_string_hash(const char *s) } \ } +#if 0 +/* Helpers for an iterator type that saves some mod operations at the expense + * of many branches. Not worth it, it seems. */ + +#define HT_ITER(type) \ + struct type##_ITER { \ + struct type **hti_nextp; \ + unsigned hti_bucket; \ + } + + static INLINE void \ + name##_HT_ITER_START(struct name *head, struct type##_ITER *iter) \ + { \ + /* XXXX Magic to stop modifications? */ \ + iter->hti_bucket = 0; \ + while (iter->hti_bucket < head->hth_table_length) { \ + iter->hti_nextp = &head->hth_table[iter->hti_bucket]; \ + if (*iter->hti_nextp) \ + return; \ + ++iter->hti_bucket; \ + } \ + iter->hti_nextp = NULL; \ + } \ + static INLINE int \ + name##_HT_ITER_DONE(struct name *head, struct type##_ITER *iter) \ + { \ + return iter->hti_nextp == NULL; \ + } \ + static INLINE struct type * \ + name##_HT_ITER_GET(struct name *head, struct type##_ITER *iter) \ + { \ + return *iter->hti_nextp; \ + } \ + static INLINE void \ + name##_HT_ITER_NEXT(struct name *head, struct type##_ITER *iter) \ + { \ + if (!iter->hti_nextp) \ + return; \ + if ((*iter->hti_nextp)->field.hte_next) { \ + iter->hti_nextp = &(*iter->hti_nextp)->field.hte_next; \ + return; \ + } \ + while (++iter->hti_bucket < head->hth_table_length) { \ + iter->hti_nextp = &head->hth_table[iter->hti_bucket]; \ + if (*iter->hti_nextp) \ + return; \ + ++iter->hti_bucket; \ + } \ + iter->hti_nextp = NULL; \ + } \ + static INLINE void \ + name##_HT_ITER_NEXT_RMV(struct name *head, struct type##_ITER *iter) \ + { \ + if (!iter->hti_nextp) \ + return; \ + --head->hth_n_entries; \ + if ((*iter->hti_nextp)->field.hte_next) { \ + *iter->hti_nextp = (*iter->hti_nextp)->field.hte_next; \ + if (*iter->hti_nextp) \ + return; \ + } \ + while (++iter->hti_bucket < head->hth_table_length) { \ + iter->hti_nextp = &head->hth_table[iter->hti_bucket]; \ + if (*iter->hti_nextp) \ + return; \ + ++iter->hti_bucket; \ + } \ + iter->hti_nextp = NULL; \ + } +#endif + #define HT_GENERATE(name, type, field, hashfn, eqfn, load, mallocfn, \ reallocfn, freefn) \ static unsigned name##_PRIMES[] = { \ @@ -345,41 +417,38 @@ ht_string_hash(const char *s) head->hth_table_length = 0; \ HT_INIT(head); \ } \ - /* Debugging helper: return false iff the representation of 'head' is \ + /* Debugging helper: return true iff the representation of 'head' is \ * internally consistent. */ \ int \ - _##name##_HT_REP_IS_BAD(struct name *head) \ + _##name##_HT_REP_OK(struct name *head) \ { \ unsigned n, i; \ struct type *elm; \ if (!head->hth_table_length) { \ - if (!head->hth_table && !head->hth_n_entries && \ - !head->hth_load_limit && head->hth_prime_idx == -1) \ - return 0; \ - else \ - return 1; \ + return !head->hth_table && !head->hth_n_entries && \ + !head->hth_load_limit && head->hth_prime_idx == -1; \ } \ if (!head->hth_table || head->hth_prime_idx < 0 || \ !head->hth_load_limit) \ - return 2; \ + return 0; \ if (head->hth_n_entries > head->hth_load_limit) \ - return 3; \ + return 0; \ if (head->hth_table_length != name##_PRIMES[head->hth_prime_idx]) \ - return 4; \ + return 0; \ if (head->hth_load_limit != (unsigned)(load*head->hth_table_length)) \ - return 5; \ + return 0; \ for (n = i = 0; i < head->hth_table_length; ++i) { \ for (elm = head->hth_table[i]; elm; elm = elm->field.hte_next) { \ if (elm->field.hte_hash != hashfn(elm)) \ - return 1000 + i; \ + return 0; \ if ((elm->field.hte_hash % head->hth_table_length) != i) \ - return 10000 + i; \ + return 0; \ ++n; \ } \ } \ if (n != head->hth_n_entries) \ - return 6; \ - return 0; \ + return 0; \ + return 1; \ } /* diff --git a/src/common/log.c b/src/common/log.c index 1d9c10d565..677cb5241c 100644 --- a/src/common/log.c +++ b/src/common/log.c @@ -327,12 +327,9 @@ close_logs(void) } /** 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 - * refer to <b>victim</b> anymore. - * - * Long-term, we need to do something about races in the log subsystem - * in general. See bug 222 for more details. + * logfiles (it must be present in the list when this function is + * called). After this function is called, the caller shouldn't refer + * to <b>victim</b> anymore. */ static void delete_log(logfile_t *victim) diff --git a/src/common/log.h b/src/common/log.h index 8122a94aa6..1b4c96e8fa 100644 --- a/src/common/log.h +++ b/src/common/log.h @@ -23,12 +23,14 @@ "We aren't prepared to deal with that." #endif #else -/* Note: Syslog's logging code refers to priorities, with 0 being the most - * important. Thus, all our comparisons needed to be reversed when we added - * syslog support. +/* XXXX Note: The code was originally written to refer to severities, + * with 0 being the least severe; while syslog's logging code refers to + * priorities, with 0 being the most important. Thus, all our comparisons + * needed to be reversed when we added syslog support. * - * The upshot of this is that comments about log levels may be messed up: for - * "maximum severity" read "most severe" and "numerically *lowest* severity". + * The upshot of this is that comments about log levels may be messed + * up: for "maximum severity" read "most severe" and "numerically + * *lowest* severity". */ /** Debug-level severity: for hyper-verbose messages of no interest to diff --git a/src/common/torgzip.c b/src/common/torgzip.c index ec02870776..12cc7ec969 100644 --- a/src/common/torgzip.c +++ b/src/common/torgzip.c @@ -15,7 +15,7 @@ const char torgzip_c_id[] = #include <stdlib.h> #include <stdio.h> #include <assert.h> -#ifdef _MSC_VER +#ifdef MS_WINDOWS #include "..\..\contrib\zlib\zlib.h" #else #include <zlib.h> @@ -282,97 +282,3 @@ detect_compression_method(const char *in, size_t in_len) } } -struct tor_zlib_state_t { - struct z_stream_s stream; - int compress; -}; - -/** DOCDOC */ -tor_zlib_state_t * -tor_zlib_new(int compress, compress_method_t method) -{ - tor_zlib_state_t *out; - - if (method == GZIP_METHOD && !is_gzip_supported()) { - /* Old zlib version don't support gzip in inflateInit2 */ - log_warn(LD_GENERAL, "Gzip not supported with zlib %s", ZLIB_VERSION); - return NULL; - } - - out = tor_malloc_zero(sizeof(tor_zlib_state_t)); - out->stream.zalloc = Z_NULL; - out->stream.zfree = Z_NULL; - out->stream.opaque = NULL; - out->compress = compress; - if (compress) { - if (deflateInit2(&out->stream, Z_BEST_COMPRESSION, Z_DEFLATED, - method_bits(method), 8, Z_DEFAULT_STRATEGY) != Z_OK) - goto err; - } else { - if (inflateInit2(&out->stream, method_bits(method)) != Z_OK) - goto err; - } - return out; - - err: - tor_free(out); - return NULL; -} - -/** DOCDOC */ -tor_zlib_output_t -tor_zlib_process(tor_zlib_state_t *state, - char **out, size_t *out_len, - const char **in, size_t *in_len, - int finish) -{ - int err; - state->stream.next_in = (unsigned char*) *in; - state->stream.avail_in = *in_len; - state->stream.next_out = (unsigned char*) *out; - state->stream.avail_out = *out_len; - - if (state->compress) { - err = deflate(&state->stream, finish ? Z_FINISH : Z_SYNC_FLUSH); - } else { - err = inflate(&state->stream, finish ? Z_FINISH : Z_SYNC_FLUSH); - } - - *out = (char*) state->stream.next_out; - *out_len = state->stream.avail_out; - *in = (const char *) state->stream.next_in; - *in_len = state->stream.avail_in; - - switch (err) - { - case Z_STREAM_END: - return TOR_ZLIB_DONE; - case Z_BUF_ERROR: - if (state->stream.avail_in == 0) - return Z_OK; - return TOR_ZLIB_BUF_FULL; - case Z_OK: - if (state->stream.avail_out == 0 || finish) - return TOR_ZLIB_BUF_FULL; - return TOR_ZLIB_OK; - default: - log_warn(LD_GENERAL, "Gzip returned an error: %s", - state->stream.msg ? state->stream.msg : "<no message>"); - return TOR_ZLIB_ERR; - } -} - -/** DOCDOC */ -void -tor_zlib_free(tor_zlib_state_t *state) -{ - tor_assert(state); - - if (state->compress) - deflateEnd(&state->stream); - else - inflateEnd(&state->stream); - - tor_free(state); -} - diff --git a/src/common/torgzip.h b/src/common/torgzip.h index 153ab4992d..134ef03268 100644 --- a/src/common/torgzip.h +++ b/src/common/torgzip.h @@ -31,17 +31,5 @@ int is_gzip_supported(void); int detect_compression_method(const char *in, size_t in_len); -typedef enum { - TOR_ZLIB_OK, TOR_ZLIB_DONE, TOR_ZLIB_BUF_FULL, TOR_ZLIB_ERR -} tor_zlib_output_t; -typedef struct tor_zlib_state_t tor_zlib_state_t; -tor_zlib_state_t *tor_zlib_new(int compress, compress_method_t method); - -tor_zlib_output_t tor_zlib_process(tor_zlib_state_t *state, - char **out, size_t *out_len, - const char **in, size_t *in_len, - int finish); -void tor_zlib_free(tor_zlib_state_t *state); - #endif diff --git a/src/common/torint.h b/src/common/torint.h index b69af3eeae..8202baa597 100644 --- a/src/common/torint.h +++ b/src/common/torint.h @@ -155,9 +155,6 @@ typedef unsigned long long uint64_t; #ifndef UINT64_MAX #define UINT64_MAX 0xffffffffffffffffull #endif -#ifndef INT64_MAX -#define INT64_MAX 0x7fffffffffffffffll -#endif #endif #if (SIZEOF___INT64 == 8) @@ -172,9 +169,6 @@ typedef unsigned __int64 uint64_t; #ifndef UINT64_MAX #define UINT64_MAX 0xffffffffffffffffui64 #endif -#ifndef INT64_MAX -#define INT64_MAX 0x7fffffffffffffffi64 -#endif #endif #if (SIZEOF_VOID_P > 4 && SIZEOF_VOID_P <= 8) diff --git a/src/common/tortls.c b/src/common/tortls.c index d9e71a6380..4401185c59 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -40,6 +40,7 @@ const char tortls_c_id[] = /* DOCDOC */ typedef struct tor_tls_context_t { SSL_CTX *ctx; + SSL_CTX *client_only_ctx; } tor_tls_context_t; /** Holds a SSL object and its associated data. Members are only @@ -169,6 +170,7 @@ tor_tls_free_all(void) { if (global_tls_context) { SSL_CTX_free(global_tls_context->ctx); + SSL_CTX_free(global_tls_context->client_only_ctx); tor_free(global_tls_context); global_tls_context = NULL; } @@ -232,7 +234,7 @@ tor_tls_create_certificate(crypto_pk_env_t *rsa, if ((nid = OBJ_txt2nid("organizationName")) == NID_undef) goto error; if (!(X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC, - (unsigned char*)"Tor", -1, -1, 0))) + (unsigned char*)"TOR", -1, -1, 0))) goto error; if ((nid = OBJ_txt2nid("commonName")) == NID_undef) goto error; if (!(X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC, @@ -246,7 +248,7 @@ tor_tls_create_certificate(crypto_pk_env_t *rsa, if ((nid = OBJ_txt2nid("organizationName")) == NID_undef) goto error; if (!(X509_NAME_add_entry_by_NID(name_issuer, nid, MBSTRING_ASC, - (unsigned char*)"Tor", -1, -1, 0))) + (unsigned char*)"TOR", -1, -1, 0))) goto error; if ((nid = OBJ_txt2nid("commonName")) == NID_undef) goto error; if (!(X509_NAME_add_entry_by_NID(name_issuer, nid, MBSTRING_ASC, @@ -299,16 +301,20 @@ tor_tls_create_certificate(crypto_pk_env_t *rsa, #define CIPHER_LIST SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA #endif -/** Create a new TLS context for use with Tor TLS handshakes. - * <b>identity</b> should be set to the identity key used to sign the - * certificate, and <b>nickname</b> set to the nickname to use. +/** Create a new TLS context. If we are going to be using it as a + * server, it must have isServer set to true, <b>identity</b> set to the + * identity key used to sign that certificate, and <b>nickname</b> set to + * the server's nickname. If we're only going to be a client, + * isServer should be false, identity should be NULL, and nickname + * should be NULL. Return -1 if failure, else 0. * * You can call this function multiple times. Each time you call it, * it generates new certificates; all new connections will use * the new SSL context. */ int -tor_tls_context_new(crypto_pk_env_t *identity, const char *nickname, +tor_tls_context_new(crypto_pk_env_t *identity, + int isServer, const char *nickname, unsigned int key_lifetime) { crypto_pk_env_t *rsa = NULL; @@ -317,71 +323,86 @@ tor_tls_context_new(crypto_pk_env_t *identity, const char *nickname, tor_tls_context_t *result = NULL; X509 *cert = NULL, *idcert = NULL; char nn2[128]; + int client_only; + SSL_CTX **ctx; if (!nickname) nickname = "null"; tor_snprintf(nn2, sizeof(nn2), "%s <identity>", nickname); tor_tls_init(); - /* Generate short-term RSA key. */ - if (!(rsa = crypto_new_pk_env())) - goto error; - if (crypto_pk_generate_key(rsa)<0) - goto error; - /* Create certificate signed by identity key. */ - cert = tor_tls_create_certificate(rsa, identity, nickname, nn2, - key_lifetime); - /* Create self-signed certificate for identity key. */ - idcert = tor_tls_create_certificate(identity, identity, nn2, nn2, - IDENTITY_CERT_LIFETIME); - if (!cert || !idcert) { - log(LOG_WARN, LD_CRYPTO, "Error creating certificate"); - goto error; + if (isServer) { + /* Generate short-term RSA key. */ + if (!(rsa = crypto_new_pk_env())) + goto error; + if (crypto_pk_generate_key(rsa)<0) + goto error; + /* Create certificate signed by identity key. */ + cert = tor_tls_create_certificate(rsa, identity, nickname, nn2, + key_lifetime); + /* Create self-signed certificate for identity key. */ + idcert = tor_tls_create_certificate(identity, identity, nn2, nn2, + IDENTITY_CERT_LIFETIME); + if (!cert || !idcert) { + log(LOG_WARN, LD_CRYPTO, "Error creating certificate"); + goto error; + } } result = tor_malloc(sizeof(tor_tls_context_t)); + result->ctx = result->client_only_ctx = NULL; + for (client_only=0; client_only <= 1; ++client_only) { + ctx = client_only ? &result->client_only_ctx : &result->ctx; #ifdef EVERYONE_HAS_AES - /* Tell OpenSSL to only use TLS1 */ - if (!(result->ctx = SSL_CTX_new(TLSv1_method()))) - goto error; + /* Tell OpenSSL to only use TLS1 */ + if (!(*ctx = SSL_CTX_new(TLSv1_method()))) + goto error; #else - /* Tell OpenSSL to use SSL3 or TLS1 but not SSL2. */ - if (!(result->ctx = SSL_CTX_new(SSLv23_method()))) - goto error; - SSL_CTX_set_options(result->ctx, SSL_OP_NO_SSLv2); + /* Tell OpenSSL to use SSL3 or TLS1 but not SSL2. */ + if (!(*ctx = SSL_CTX_new(SSLv23_method()))) + goto error; + SSL_CTX_set_options(*ctx, SSL_OP_NO_SSLv2); #endif - SSL_CTX_set_options(result->ctx, SSL_OP_SINGLE_DH_USE); - if (!SSL_CTX_set_cipher_list(result->ctx, CIPHER_LIST)) - goto error; - if (cert && !SSL_CTX_use_certificate(result->ctx,cert)) - goto error; - X509_free(cert); /* We just added a reference to cert. */ - cert=NULL; - if (idcert && !SSL_CTX_add_extra_chain_cert(result->ctx,idcert)) - goto error; - idcert=NULL; /* The context now owns the reference to idcert */ - SSL_CTX_set_session_cache_mode(result->ctx, SSL_SESS_CACHE_OFF); - tor_assert(rsa); - if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,1))) - goto error; - if (!SSL_CTX_use_PrivateKey(result->ctx, pkey)) - goto error; - EVP_PKEY_free(pkey); - pkey = NULL; - if (!SSL_CTX_check_private_key(result->ctx)) - goto error; - dh = crypto_dh_new(); - SSL_CTX_set_tmp_dh(result->ctx, _crypto_dh_env_get_dh(dh)); - crypto_dh_free(dh); - SSL_CTX_set_verify(result->ctx, SSL_VERIFY_PEER, - always_accept_verify_cb); - /* let us realloc bufs that we're writing from */ - SSL_CTX_set_mode(result->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); +#ifndef ENABLE_0119_PARANOIA_A + SSL_CTX_set_options(*ctx, SSL_OP_SINGLE_DH_USE); +#endif + if (!SSL_CTX_set_cipher_list(*ctx, CIPHER_LIST)) + goto error; + if (!client_only) { + if (cert && !SSL_CTX_use_certificate(*ctx,cert)) + goto error; + X509_free(cert); /* We just added a reference to cert. */ + cert=NULL; + if (idcert && !SSL_CTX_add_extra_chain_cert(*ctx,idcert)) + goto error; + idcert=NULL; /* The context now owns the reference to idcert */ + } + SSL_CTX_set_session_cache_mode(*ctx, SSL_SESS_CACHE_OFF); + if (isServer && !client_only) { + tor_assert(rsa); + if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,1))) + goto error; + if (!SSL_CTX_use_PrivateKey(*ctx, pkey)) + goto error; + EVP_PKEY_free(pkey); + pkey = NULL; + if (!SSL_CTX_check_private_key(*ctx)) + goto error; + } + dh = crypto_dh_new(); + SSL_CTX_set_tmp_dh(*ctx, _crypto_dh_env_get_dh(dh)); + crypto_dh_free(dh); + SSL_CTX_set_verify(*ctx, SSL_VERIFY_PEER, + always_accept_verify_cb); + /* let us realloc bufs that we're writing from */ + SSL_CTX_set_mode(*ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + } /* Free the old context if one exists. */ if (global_tls_context) { /* This is safe even if there are open connections: OpenSSL does * reference counting with SSL and SSL_CTX objects. */ SSL_CTX_free(global_tls_context->ctx); + SSL_CTX_free(global_tls_context->client_only_ctx); tor_free(global_tls_context); } global_tls_context = result; @@ -399,6 +420,8 @@ tor_tls_context_new(crypto_pk_env_t *identity, const char *nickname, crypto_dh_free(dh); if (result && result->ctx) SSL_CTX_free(result->ctx); + if (result && result->client_only_ctx) + SSL_CTX_free(result->client_only_ctx); if (result) tor_free(result); if (cert) @@ -412,29 +435,20 @@ tor_tls_context_new(crypto_pk_env_t *identity, const char *nickname, * determine whether it is functioning as a server. */ tor_tls_t * -tor_tls_new(int sock, int isServer) +tor_tls_new(int sock, int isServer, int use_no_cert) { - BIO *bio = NULL; tor_tls_t *result = tor_malloc(sizeof(tor_tls_t)); - + SSL_CTX *ctx; tor_assert(global_tls_context); /* make sure somebody made it first */ - if (!(result->ssl = SSL_new(global_tls_context->ctx))) { + ctx = use_no_cert ? global_tls_context->client_only_ctx + : global_tls_context->ctx; + if (!(result->ssl = SSL_new(ctx))) { tls_log_errors(LOG_WARN, "generating TLS context"); tor_free(result); return NULL; } result->socket = sock; -#ifdef USE_BSOCKETS - bio = BIO_new_bsocket(sock, BIO_NOCLOSE); -#else - bio = BIO_new_socket(sock, BIO_NOCLOSE); -#endif - if (! bio) { - tls_log_errors(LOG_WARN, "opening BIO"); - tor_free(result); - return NULL; - } - SSL_set_bio(result->ssl, bio, bio); + SSL_set_fd(result->ssl, sock); result->state = TOR_TLS_ST_HANDSHAKE; result->isServer = isServer; result->wantwrite_n = 0; @@ -543,8 +557,7 @@ tor_tls_handshake(tor_tls_t *tls) } r = tor_tls_get_error(tls,r,0, "handshaking", LOG_INFO); if (ERR_peek_error() != 0) { - tls_log_errors(tls->isServer ? LOG_INFO : LOG_WARN, - "handshaking"); + tls_log_errors(LOG_WARN, "handshaking"); return TOR_TLS_ERROR; } if (r == TOR_TLS_DONE) { @@ -704,7 +717,7 @@ log_cert_lifetime(X509 *cert, const char *problem) BIO_get_mem_ptr(bio, &buf); s1 = tor_strndup(buf->data, buf->length); - (void)BIO_reset(bio); + BIO_reset(bio); if (!(ASN1_TIME_print(bio, X509_get_notAfter(cert)))) { tls_log_errors(LOG_WARN, "printing certificate lifetime"); goto end; @@ -869,7 +882,7 @@ tor_tls_get_n_bytes_written(tor_tls_t *tls) } /** Implement check_no_tls_errors: If there are any pending OpenSSL - * errors, log an error message. */ + * errors, log an error message and assert(0). */ void _check_no_tls_errors(const char *fname, int line) { diff --git a/src/common/tortls.h b/src/common/tortls.h index 2569abf79c..82a64cb97a 100644 --- a/src/common/tortls.h +++ b/src/common/tortls.h @@ -26,9 +26,9 @@ typedef struct tor_tls_t tor_tls_t; #define TOR_TLS_DONE 0 void tor_tls_free_all(void); -int tor_tls_context_new(crypto_pk_env_t *rsa, +int tor_tls_context_new(crypto_pk_env_t *rsa, int isServer, const char *nickname, unsigned int key_lifetime); -tor_tls_t *tor_tls_new(int sock, int is_server); +tor_tls_t *tor_tls_new(int sock, int is_server, int use_no_cert); int tor_tls_is_server(tor_tls_t *tls); void tor_tls_free(tor_tls_t *tls); int tor_tls_peer_has_cert(tor_tls_t *tls); diff --git a/src/common/util.c b/src/common/util.c index 99ac776dcb..f82cfc1263 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -46,6 +46,26 @@ const char util_c_id[] = "$Id$"; #ifdef HAVE_ERRNO_H #include <errno.h> #endif +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#ifdef HAVE_SYS_LIMITS_H +#include <sys/limits.h> +#endif +#ifdef HAVE_MACHINE_LIMITS_H +#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) + /* FreeBSD has a bug where it complains that this file is obsolete, + and I should migrate to using sys/limits. It complains even when + I include both. + __FreeBSD_kernel__ is defined by Debian GNU/kFreeBSD which + does the same thing (but doesn't defined __FreeBSD__). + */ +#include <machine/limits.h> +#endif +#endif +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> /* Must be included before sys/stat.h for Ultrix */ +#endif #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif @@ -106,21 +126,19 @@ _tor_malloc(size_t size DMALLOC_PARAMS) { void *result; -#ifndef MALLOC_ZERO_WORKS /* Some libcs don't do the right thing on size==0. Override them. */ if (size==0) { size=1; } -#endif result = dmalloc_malloc(file, line, size, DMALLOC_FUNC_MALLOC, 0, 0); - if (PREDICT(result == NULL, 0)) { + if (!result) { log_err(LD_MM,"Out of memory. Dying."); - /* If these functions die within a worker process, they won't call - * spawn_exit, but that's ok, since the parent will run out of memory soon - * anyway. */ + /* XXX if these functions die within a worker process, they won't + * call spawn_exit */ exit(1); } +// memset(result,'X',size); /* deadbeef to encourage bugs */ return result; } @@ -146,7 +164,7 @@ _tor_realloc(void *ptr, size_t size DMALLOC_PARAMS) void *result; result = dmalloc_realloc(file, line, ptr, size, DMALLOC_FUNC_REALLOC, 0); - if (PREDICT(result == NULL, 0)) { + if (!result) { log_err(LD_MM,"Out of memory. Dying."); exit(1); } @@ -164,7 +182,7 @@ _tor_strdup(const char *s DMALLOC_PARAMS) tor_assert(s); dup = dmalloc_strdup(file, line, s, 0); - if (PREDICT(dup == NULL, 0)) { + if (!dup) { log_err(LD_MM,"Out of memory. Dying."); exit(1); } @@ -192,26 +210,6 @@ _tor_strndup(const char *s, size_t n DMALLOC_PARAMS) return dup; } -/** Allocate a chunk of <b>len</b> bytes, with the same contents starting at - * <b>mem</b>. */ -void * -_tor_memdup(const void *mem, size_t len DMALLOC_PARAMS) -{ - char *dup; - tor_assert(mem); - dup = _tor_malloc(len DMALLOC_FN_ARGS); - memcpy(dup, mem, len); - return dup; -} - -/** Helper for places that need to take a function pointer to the right - * spelling of "free()". */ -void -_tor_free(void *mem) -{ - tor_free(mem); -} - /* ===== * String manipulation * ===== */ @@ -347,19 +345,6 @@ tor_strisprint(const char *s) return 1; } -/** Return 1 if no character in <b>s</b> is uppercase, else return 0. - */ -int -tor_strisnonupper(const char *s) -{ - while (*s) { - if (TOR_ISUPPER(*s)) - return 0; - s++; - } - return 1; -} - /* Compares the first strlen(s2) characters of s1 with s2. Returns as for * strcmp. */ @@ -414,23 +399,17 @@ eat_whitespace(const char *s) { tor_assert(s); - while (1) { - switch (*s) { - case '\0': - default: - return s; - case ' ': - case '\t': - case '\n': - case '\r': - ++s; - break; - case '#': - ++s; + while (TOR_ISSPACE(*s) || *s == '#') { + while (TOR_ISSPACE(*s)) + s++; + if (*s == '#') { /* read to a \n or \0 */ while (*s && *s != '\n') - ++s; + s++; + if (!*s) + return s; } } + return s; } /** Return a pointer to the first char of s that is not a space or a tab, @@ -450,47 +429,20 @@ const char * find_whitespace(const char *s) { /* tor_assert(s); */ - while (1) { - switch (*s) - { - case '\0': - case '#': - case ' ': - case '\r': - case '\n': - case '\t': - return s; - default: - ++s; - } - } -} -/** Return true iff the 'len' bytes at 'mem' are all zero. */ -int -tor_mem_is_zero(const char *mem, size_t len) -{ - static const char ZERO[] = { - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - }; - while (len >= sizeof(ZERO)) { - if (memcmp(mem, ZERO, sizeof(ZERO))) - return 0; - len -= sizeof(ZERO); - mem += sizeof(ZERO); - } - /* Deal with leftover bytes. */ - if (len) - return ! memcmp(mem, ZERO, len); + while (*s && !TOR_ISSPACE(*s) && *s != '#') + s++; - return 1; + return s; } /** Return true iff the DIGEST_LEN bytes in digest are all zero. */ int tor_digest_is_zero(const char *digest) { - return tor_mem_is_zero(digest, DIGEST_LEN); + static char ZERO_DIGEST[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; + + return !memcmp(digest, ZERO_DIGEST, DIGEST_LEN); } #define CHECK_STRTOX_RESULT() \ @@ -961,7 +913,7 @@ write_all(int fd, const char *buf, size_t count, int isSocket) while (written != count) { if (isSocket) - result = tor_socket_send(fd, buf+written, count-written, 0); + result = send(fd, buf+written, count-written, 0); else result = write(fd, buf+written, count-written); if (result<0) @@ -987,7 +939,7 @@ read_all(int fd, char *buf, size_t count, int isSocket) while (numread != count) { if (isSocket) - result = tor_socket_recv(fd, buf+numread, count-numread, 0); + result = recv(fd, buf+numread, count-numread, 0); else result = read(fd, buf+numread, count-numread); if (result<0) @@ -1018,8 +970,6 @@ clean_name_for_stat(char *name) return; name[len-1]='\0'; } -#else - (void)name; #endif } @@ -1542,8 +1492,8 @@ is_local_IP(uint32_t ip) * Return 0 on success, -1 on failure. */ int -parse_addr_port(int severity, const char *addrport, char **address, - uint32_t *addr, uint16_t *port_out) +parse_addr_port(const char *addrport, char **address, uint32_t *addr, + uint16_t *port_out) { const char *colon; char *_address = NULL; @@ -1557,14 +1507,14 @@ parse_addr_port(int severity, const char *addrport, char **address, _address = tor_strndup(addrport, colon-addrport); _port = (int) tor_parse_long(colon+1,10,1,65535,NULL,NULL); if (!_port) { - log_fn(severity, LD_GENERAL, "Port %s out of range", escaped(colon+1)); + log_warn(LD_GENERAL, "Port %s out of range", escaped(colon+1)); ok = 0; } if (!port_out) { char *esc_addrport = esc_for_log(addrport); - log_fn(severity, LD_GENERAL, - "Port %s given on %s when not required", - escaped(colon+1), esc_addrport); + log_warn(LD_GENERAL, + "Port %s given on %s when not required", + escaped(colon+1), esc_addrport); tor_free(esc_addrport); ok = 0; } @@ -1576,7 +1526,7 @@ parse_addr_port(int severity, const char *addrport, char **address, if (addr) { /* There's an addr pointer, so we need to resolve the hostname. */ if (tor_lookup_hostname(_address,addr)) { - log_fn(severity, LD_NET, "Couldn't look up %s", escaped(_address)); + log_warn(LD_NET, "Couldn't look up %s", escaped(_address)); ok = 0; *addr = 0; } @@ -1767,9 +1717,8 @@ tor_dup_addr(uint32_t addr) return tor_strdup(buf); } -/* Return true iff <b>name</b> looks like it might be a hostname, - * nickname, key, or IP address of some kind, suitable for the - * controller's "mapaddress" command. */ +/* Return true iff <b>name</b> looks like it might be a hostname or IP + * address of some kind. */ int is_plausible_address(const char *name) { @@ -1795,7 +1744,7 @@ is_plausible_address(const char *name) * failure. */ int -get_interface_address(int severity, uint32_t *addr) +get_interface_address(uint32_t *addr) { int sock=-1, r=-1; struct sockaddr_in target_addr, my_addr; @@ -1807,8 +1756,7 @@ get_interface_address(int severity, uint32_t *addr) sock = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP); if (sock < 0) { int e = tor_socket_errno(-1); - log_fn(severity, LD_NET, "unable to create socket: %s", - tor_socket_strerror(e)); + log_warn(LD_NET, "unable to create socket: %s", tor_socket_strerror(e)); goto err; } @@ -1822,15 +1770,14 @@ get_interface_address(int severity, uint32_t *addr) if (connect(sock,(struct sockaddr *)&target_addr,sizeof(target_addr))<0) { int e = tor_socket_errno(sock); - log_fn(severity, LD_NET, "connect() failed: %s", tor_socket_strerror(e)); + log_warn(LD_NET, "connnect() failed: %s", tor_socket_strerror(e)); goto err; } /* XXXX Can this be right on IPv6 clients? */ if (getsockname(sock, (struct sockaddr*)&my_addr, &my_addr_len)) { int e = tor_socket_errno(sock); - log_fn(severity, LD_NET, "getsockname() failed: %s", - tor_socket_strerror(e)); + log_warn(LD_NET, "getsockname() failed: %s", tor_socket_strerror(e)); goto err; } diff --git a/src/common/util.h b/src/common/util.h index 22f4ea3b99..cdcd64f6b4 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -28,7 +28,7 @@ * calling assert() normally. */ #ifdef NDEBUG -/* Nobody should ever want to build with NDEBUG set. 99% of our asserts will +/* Nobody should ever want to build with NDEBUG set. 99% of your asserts will * be outside the critical path anyway, so it's silly to disable bugchecking * throughout the entire program just because a few asserts are slowing you * down. Profile, optimize the critical path, and keep debugging on. @@ -38,17 +38,12 @@ */ #error "Sorry; we don't support building with NDEBUG." #else -#ifdef __GNUC__ -#define PREDICT_FALSE(x) PREDICT((x) == ((typeof(x)) 0), 0) -#else -#define PREDICT_FALSE(x) !(x) -#endif #define tor_assert(expr) do { \ - if (PREDICT_FALSE(expr)) { \ + if (!(expr)) { \ log(LOG_ERR, LD_BUG, "%s:%d: %s: Assertion %s failed; aborting.", \ - _SHORT_FILE_, __LINE__, __func__, #expr); \ + _SHORT_FILE_, __LINE__, __func__, #expr); \ fprintf(stderr,"%s:%d %s: Assertion %s failed; aborting.\n", \ - _SHORT_FILE_, __LINE__, __func__, #expr); \ + _SHORT_FILE_, __LINE__, __func__, #expr); \ abort(); \ } } while (0) #endif @@ -67,27 +62,22 @@ #define tor_fragile_assert() /* Memory management */ -void *_tor_malloc(size_t size DMALLOC_PARAMS) ATTR_MALLOC; -void *_tor_malloc_zero(size_t size DMALLOC_PARAMS) ATTR_MALLOC; +void *_tor_malloc(size_t size DMALLOC_PARAMS); +void *_tor_malloc_zero(size_t size DMALLOC_PARAMS); void *_tor_realloc(void *ptr, size_t size DMALLOC_PARAMS); -char *_tor_strdup(const char *s DMALLOC_PARAMS) ATTR_MALLOC ATTR_NONNULL((1)); -char *_tor_strndup(const char *s, size_t n DMALLOC_PARAMS) - ATTR_MALLOC ATTR_NONNULL((1)); -void *_tor_memdup(const void *mem, size_t len DMALLOC_PARAMS) - ATTR_MALLOC ATTR_NONNULL((1)); -void _tor_free(void *mem); +char *_tor_strdup(const char *s DMALLOC_PARAMS); +char *_tor_strndup(const char *s, size_t n DMALLOC_PARAMS); #ifdef USE_DMALLOC extern int dmalloc_free(const char *file, const int line, void *pnt, const int func_id); #define tor_free(p) do { \ - if (PREDICT((p)!=NULL, 1) { \ + if (p) { \ dmalloc_free(_SHORT_FILE_, __LINE__, (p), 0); \ (p)=NULL; \ } \ } while (0) #else -#define tor_free(p) do { if (PREDICT((p)!=NULL,1)) { free(p); (p)=NULL;} } \ - while (0) +#define tor_free(p) do { if (p) {free(p); (p)=NULL;} } while (0) #endif #define tor_malloc(size) _tor_malloc(size DMALLOC_ARGS) @@ -95,29 +85,17 @@ extern int dmalloc_free(const char *file, const int line, void *pnt, #define tor_realloc(ptr, size) _tor_realloc(ptr, size DMALLOC_ARGS) #define tor_strdup(s) _tor_strdup(s DMALLOC_ARGS) #define tor_strndup(s, n) _tor_strndup(s, n DMALLOC_ARGS) -#define tor_memdup(s, n) _tor_memdup(s, n DMALLOC_ARGS) - -/** 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 /* String manipulation */ #define HEX_CHARACTERS "0123456789ABCDEFabcdef" -void tor_strlower(char *s) ATTR_NONNULL((1)); -void tor_strupper(char *s) ATTR_NONNULL((1)); -int tor_strisprint(const char *s) ATTR_PURE ATTR_NONNULL((1)); -int tor_strisnonupper(const char *s) ATTR_PURE ATTR_NONNULL((1)); -int strcmpstart(const char *s1, const char *s2) ATTR_PURE ATTR_NONNULL((1,2)); -int strcasecmpstart(const char *s1, const char *s2) - ATTR_PURE ATTR_NONNULL((1,2)); -int strcmpend(const char *s1, const char *s2) ATTR_PURE ATTR_NONNULL((1,2)); -int strcasecmpend(const char *s1, const char *s2) - ATTR_PURE ATTR_NONNULL((1,2)); -int tor_strstrip(char *s, const char *strip) ATTR_NONNULL((1,2)); +void tor_strlower(char *s); +void tor_strupper(char *s); +int tor_strisprint(const char *s); +int strcmpstart(const char *s1, const char *s2); +int strcasecmpstart(const char *s1, const char *s2); +int strcmpend(const char *s1, const char *s2); +int strcasecmpend(const char *s1, const char *s2); +int tor_strstrip(char *s, const char *strip); typedef enum { ALWAYS_TERMINATE, NEVER_TERMINATE, TERMINATE_IF_EVEN } part_finish_rule_t; @@ -130,13 +108,12 @@ unsigned long tor_parse_ulong(const char *s, int base, unsigned long min, unsigned long max, int *ok, char **next); uint64_t tor_parse_uint64(const char *s, int base, uint64_t min, uint64_t max, int *ok, char **next); -const char *hex_str(const char *from, size_t fromlen) ATTR_NONNULL((1)); -const char *eat_whitespace(const char *s) ATTR_PURE; -const char *eat_whitespace_no_nl(const char *s) ATTR_PURE; -const char *find_whitespace(const char *s) ATTR_PURE; -int tor_mem_is_zero(const char *mem, size_t len) ATTR_PURE; -int tor_digest_is_zero(const char *digest) ATTR_PURE; -char *esc_for_log(const char *string) ATTR_MALLOC; +const char *hex_str(const char *from, size_t fromlen); +const char *eat_whitespace(const char *s); +const char *eat_whitespace_no_nl(const char *s); +const char *find_whitespace(const char *s); +int tor_digest_is_zero(const char *digest); +char *esc_for_log(const char *string); const char *escaped(const char *string); void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen); @@ -180,17 +157,17 @@ int write_chunks_to_file(const char *fname, const struct smartlist_t *chunks, int append_bytes_to_file(const char *fname, const char *str, size_t len, int bin); -char *read_file_to_str(const char *filename, int bin) ATTR_MALLOC; +char *read_file_to_str(const char *filename, int bin); char *parse_line_from_str(char *line, char **key_out, char **value_out); char *expand_filename(const char *filename); struct smartlist_t *tor_listdir(const char *dirname); -int path_is_relative(const char *filename) ATTR_PURE; +int path_is_relative(const char *filename); /* Net helpers */ -int is_internal_IP(uint32_t ip, int for_listening) ATTR_PURE; -int is_local_IP(uint32_t ip) ATTR_PURE; -int parse_addr_port(int severity, const char *addrport, char **address, - uint32_t *addr, uint16_t *port_out); +int is_internal_IP(uint32_t ip, int for_listening); +int is_local_IP(uint32_t ip); +int parse_addr_port(const char *addrport, char **address, uint32_t *addr, + uint16_t *port); int parse_port_range(const char *port, uint16_t *port_min_out, uint16_t *port_max_out); int parse_addr_and_port_range(const char *s, uint32_t *addr_out, @@ -199,9 +176,9 @@ int parse_addr_and_port_range(const char *s, uint32_t *addr_out, int addr_mask_get_bits(uint32_t mask); #define INET_NTOA_BUF_LEN 16 int tor_inet_ntoa(struct in_addr *in, char *buf, size_t buf_len); -char *tor_dup_addr(uint32_t addr) ATTR_MALLOC; +char *tor_dup_addr(uint32_t addr); int is_plausible_address(const char *name); -int get_interface_address(int severity, uint32_t *addr); +int get_interface_address(uint32_t *addr); /* Process helpers */ void start_daemon(void); |