summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2006-09-24 17:20:41 +0000
committerNick Mathewson <nickm@torproject.org>2006-09-24 17:20:41 +0000
commit9006dbeb812168e0eb7ec707a61a7d539b18ecea (patch)
tree17eb1979d71a24c99cff0d87f047f3aaa8875c5d /src/common
parentbf738d30808190fcd20e8bcb3e75b17f7b730105 (diff)
downloadtor-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.c201
-rw-r--r--src/common/compat.h123
-rw-r--r--src/common/container.c174
-rw-r--r--src/common/container.h42
-rw-r--r--src/common/crypto.c74
-rw-r--r--src/common/crypto.h2
-rw-r--r--src/common/ht.h101
-rw-r--r--src/common/log.c9
-rw-r--r--src/common/log.h12
-rw-r--r--src/common/torgzip.c96
-rw-r--r--src/common/torgzip.h12
-rw-r--r--src/common/torint.h6
-rw-r--r--src/common/tortls.c159
-rw-r--r--src/common/tortls.h4
-rw-r--r--src/common/util.c163
-rw-r--r--src/common/util.h87
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);