mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Merge branch 'bug14001-clang-warning' into bug13111-empty-key-files-fn-empty
Conflicts: src/or/router.c Choose newer comment. Merge changes to comment and function invocation.
This commit is contained in:
@@ -723,6 +723,11 @@ tor_addr_parse_mask_ports(const char *s,
|
||||
/* XXXX_IP6 is this really what we want? */
|
||||
bits = 96 + bits%32; /* map v4-mapped masks onto 96-128 bits */
|
||||
}
|
||||
if (any_flag) {
|
||||
log_warn(LD_GENERAL,
|
||||
"Found bit prefix with wildcard address; rejecting");
|
||||
goto err;
|
||||
}
|
||||
} else { /* pick an appropriate mask, as none was given */
|
||||
if (any_flag)
|
||||
bits = 0; /* This is okay whether it's V6 or V4 (FIX V4-mapped V6!) */
|
||||
@@ -1114,7 +1119,8 @@ fmt_addr32(uint32_t addr)
|
||||
int
|
||||
tor_addr_parse(tor_addr_t *addr, const char *src)
|
||||
{
|
||||
char *tmp = NULL; /* Holds substring if we got a dotted quad. */
|
||||
/* Holds substring of IPv6 address after removing square brackets */
|
||||
char *tmp = NULL;
|
||||
int result;
|
||||
struct in_addr in_tmp;
|
||||
struct in6_addr in6_tmp;
|
||||
|
||||
+1
-1
@@ -1698,7 +1698,7 @@ log_credential_status(void)
|
||||
|
||||
/* log supplementary groups */
|
||||
sup_gids_size = 64;
|
||||
sup_gids = tor_calloc(sizeof(gid_t), 64);
|
||||
sup_gids = tor_calloc(64, sizeof(gid_t));
|
||||
while ((ngids = getgroups(sup_gids_size, sup_gids)) < 0 &&
|
||||
errno == EINVAL &&
|
||||
sup_gids_size < NGROUPS_MAX) {
|
||||
|
||||
@@ -203,6 +203,15 @@ extern INLINE double U64_TO_DBL(uint64_t x) {
|
||||
#define STMT_END } while (0)
|
||||
#endif
|
||||
|
||||
/* Some tools (like coccinelle) don't like to see operators as macro
|
||||
* arguments. */
|
||||
#define OP_LT <
|
||||
#define OP_GT >
|
||||
#define OP_GE >=
|
||||
#define OP_LE <=
|
||||
#define OP_EQ ==
|
||||
#define OP_NE !=
|
||||
|
||||
/* ===== String compatibility */
|
||||
#ifdef _WIN32
|
||||
/* Windows names string functions differently from most other platforms. */
|
||||
|
||||
@@ -283,8 +283,8 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg)
|
||||
}
|
||||
|
||||
/** Return the current Libevent event base that we're set up to use. */
|
||||
struct event_base *
|
||||
tor_libevent_get_base(void)
|
||||
MOCK_IMPL(struct event_base *,
|
||||
tor_libevent_get_base, (void))
|
||||
{
|
||||
return the_event_base;
|
||||
}
|
||||
@@ -717,7 +717,7 @@ tor_gettimeofday_cached_monotonic(struct timeval *tv)
|
||||
struct timeval last_tv = { 0, 0 };
|
||||
|
||||
tor_gettimeofday_cached(tv);
|
||||
if (timercmp(tv, &last_tv, <)) {
|
||||
if (timercmp(tv, &last_tv, OP_LT)) {
|
||||
memcpy(tv, &last_tv, sizeof(struct timeval));
|
||||
} else {
|
||||
memcpy(&last_tv, tv, sizeof(struct timeval));
|
||||
|
||||
@@ -72,7 +72,7 @@ typedef struct tor_libevent_cfg {
|
||||
} tor_libevent_cfg;
|
||||
|
||||
void tor_libevent_initialize(tor_libevent_cfg *cfg);
|
||||
struct event_base *tor_libevent_get_base(void);
|
||||
MOCK_DECL(struct event_base *, tor_libevent_get_base, (void));
|
||||
const char *tor_libevent_get_method(void);
|
||||
void tor_check_libevent_version(const char *m, int server,
|
||||
const char **badness_out);
|
||||
|
||||
+1
-1
@@ -1012,7 +1012,7 @@ crypto_pk_public_checksig(crypto_pk_t *env, char *to,
|
||||
env->key, RSA_PKCS1_PADDING);
|
||||
|
||||
if (r<0) {
|
||||
crypto_log_errors(LOG_WARN, "checking RSA signature");
|
||||
crypto_log_errors(LOG_INFO, "checking RSA signature");
|
||||
return -1;
|
||||
}
|
||||
return r;
|
||||
|
||||
+1
-1
@@ -451,7 +451,7 @@ MOCK_IMPL(STATIC void,
|
||||
logv,(int severity, log_domain_mask_t domain, const char *funcname,
|
||||
const char *suffix, const char *format, va_list ap))
|
||||
{
|
||||
char buf[10024];
|
||||
char buf[10240];
|
||||
size_t msg_len = 0;
|
||||
int formatted = 0;
|
||||
logfile_t *lf;
|
||||
|
||||
+3
-1
@@ -97,8 +97,10 @@
|
||||
#define LD_HEARTBEAT (1u<<20)
|
||||
/** Abstract channel_t code */
|
||||
#define LD_CHANNEL (1u<<21)
|
||||
/** Scheduler */
|
||||
#define LD_SCHED (1u<<22)
|
||||
/** Number of logging domains in the code. */
|
||||
#define N_LOGGING_DOMAINS 22
|
||||
#define N_LOGGING_DOMAINS 23
|
||||
|
||||
/** This log message is not safe to send to a callback-based logger
|
||||
* immediately. Used as a flag, not a log domain. */
|
||||
|
||||
+116
-34
@@ -195,33 +195,40 @@ tor_malloc_zero_(size_t size DMALLOC_PARAMS)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* The square root of SIZE_MAX + 1. If a is less than this, and b is less
|
||||
* than this, then a*b is less than SIZE_MAX. (For example, if size_t is
|
||||
* 32 bits, then SIZE_MAX is 0xffffffff and this value is 0x10000. If a and
|
||||
* b are less than this, then their product is at most (65535*65535) ==
|
||||
* 0xfffe0001. */
|
||||
#define SQRT_SIZE_MAX_P1 (((size_t)1) << (sizeof(size_t)*4))
|
||||
|
||||
/** Return non-zero if and only if the product of the arguments is exact. */
|
||||
static INLINE int
|
||||
size_mul_check(const size_t x, const size_t y)
|
||||
{
|
||||
/* This first check is equivalent to
|
||||
(x < SQRT_SIZE_MAX_P1 && y < SQRT_SIZE_MAX_P1)
|
||||
|
||||
Rationale: if either one of x or y is >= SQRT_SIZE_MAX_P1, then it
|
||||
will have some bit set in its most significant half.
|
||||
*/
|
||||
return ((x|y) < SQRT_SIZE_MAX_P1 ||
|
||||
y == 0 ||
|
||||
x <= SIZE_MAX / y);
|
||||
}
|
||||
|
||||
/** Allocate a chunk of <b>nmemb</b>*<b>size</b> bytes of memory, fill
|
||||
* the memory with zero bytes, and return a pointer to the result.
|
||||
* Log and terminate the process on error. (Same as
|
||||
* calloc(<b>nmemb</b>,<b>size</b>), but never returns NULL.)
|
||||
*
|
||||
* XXXX This implementation probably asserts in cases where it could
|
||||
* work, because it only tries dividing SIZE_MAX by size (according to
|
||||
* the calloc(3) man page, the size of an element of the nmemb-element
|
||||
* array to be allocated), not by nmemb (which could in theory be
|
||||
* smaller than size). Don't do that then.
|
||||
* The second argument (<b>size</b>) should preferably be non-zero
|
||||
* and a compile-time constant.
|
||||
*/
|
||||
void *
|
||||
tor_calloc_(size_t nmemb, size_t size DMALLOC_PARAMS)
|
||||
{
|
||||
/* You may ask yourself, "wouldn't it be smart to use calloc instead of
|
||||
* malloc+memset? Perhaps libc's calloc knows some nifty optimization trick
|
||||
* we don't!" Indeed it does, but its optimizations are only a big win when
|
||||
* we're allocating something very big (it knows if it just got the memory
|
||||
* from the OS in a pre-zeroed state). We don't want to use tor_malloc_zero
|
||||
* for big stuff, so we don't bother with calloc. */
|
||||
void *result;
|
||||
size_t max_nmemb = (size == 0) ? SIZE_MAX : SIZE_MAX/size;
|
||||
|
||||
tor_assert(nmemb < max_nmemb);
|
||||
|
||||
result = tor_malloc_zero_((nmemb * size) DMALLOC_FN_ARGS);
|
||||
return result;
|
||||
tor_assert(size_mul_check(nmemb, size));
|
||||
return tor_malloc_zero_((nmemb * size) DMALLOC_FN_ARGS);
|
||||
}
|
||||
|
||||
/** Change the size of the memory block pointed to by <b>ptr</b> to <b>size</b>
|
||||
@@ -264,7 +271,7 @@ tor_reallocarray_(void *ptr, size_t sz1, size_t sz2 DMALLOC_PARAMS)
|
||||
{
|
||||
/* XXXX we can make this return 0, but we would need to check all the
|
||||
* reallocarray users. */
|
||||
tor_assert(sz2 == 0 || sz1 < SIZE_T_CEILING / sz2);
|
||||
tor_assert(size_mul_check(sz1, sz2));
|
||||
|
||||
return tor_realloc(ptr, (sz1 * sz2) DMALLOC_FN_ARGS);
|
||||
}
|
||||
@@ -957,6 +964,68 @@ string_is_key_value(int severity, const char *string)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Return true if <b>string</b> represents a valid IPv4 adddress in
|
||||
* 'a.b.c.d' form.
|
||||
*/
|
||||
int
|
||||
string_is_valid_ipv4_address(const char *string)
|
||||
{
|
||||
struct in_addr addr;
|
||||
|
||||
return (tor_inet_pton(AF_INET,string,&addr) == 1);
|
||||
}
|
||||
|
||||
/** Return true if <b>string</b> represents a valid IPv6 address in
|
||||
* a form that inet_pton() can parse.
|
||||
*/
|
||||
int
|
||||
string_is_valid_ipv6_address(const char *string)
|
||||
{
|
||||
struct in6_addr addr;
|
||||
|
||||
return (tor_inet_pton(AF_INET6,string,&addr) == 1);
|
||||
}
|
||||
|
||||
/** Return true iff <b>string</b> matches a pattern of DNS names
|
||||
* that we allow Tor clients to connect to.
|
||||
*/
|
||||
int
|
||||
string_is_valid_hostname(const char *string)
|
||||
{
|
||||
int result = 1;
|
||||
smartlist_t *components;
|
||||
|
||||
components = smartlist_new();
|
||||
|
||||
smartlist_split_string(components,string,".",0,0);
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(components, char *, c) {
|
||||
if (c[0] == '-') {
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
do {
|
||||
if ((*c >= 'a' && *c <= 'z') ||
|
||||
(*c >= 'A' && *c <= 'Z') ||
|
||||
(*c >= '0' && *c <= '9') ||
|
||||
(*c == '-'))
|
||||
c++;
|
||||
else
|
||||
result = 0;
|
||||
} while (result && *c);
|
||||
|
||||
} SMARTLIST_FOREACH_END(c);
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(components, char *, c) {
|
||||
tor_free(c);
|
||||
} SMARTLIST_FOREACH_END(c);
|
||||
|
||||
smartlist_free(components);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Return true iff the DIGEST256_LEN bytes in digest are all zero. */
|
||||
int
|
||||
tor_digest256_is_zero(const char *digest)
|
||||
@@ -1942,8 +2011,12 @@ file_status(const char *fname)
|
||||
* <b>check</b>&CPD_CHECK, and we think we can create it, return 0. Else
|
||||
* return -1. If CPD_GROUP_OK is set, then it's okay if the directory
|
||||
* is group-readable, but in all cases we create the directory mode 0700.
|
||||
* If CPD_CHECK_MODE_ONLY is set, then we don't alter the directory permissions
|
||||
* if they are too permissive: we just return -1.
|
||||
* If CPD_GROUP_READ is set, existing directory behaves as CPD_GROUP_OK and
|
||||
* if the directory is created it will use mode 0750 with group read
|
||||
* permission. Group read privileges also assume execute permission
|
||||
* as norm for directories. If CPD_CHECK_MODE_ONLY is set, then we don't
|
||||
* alter the directory permissions if they are too permissive:
|
||||
* we just return -1.
|
||||
* When effective_user is not NULL, check permissions against the given user
|
||||
* and its primary group.
|
||||
*/
|
||||
@@ -1955,7 +2028,7 @@ check_private_dir(const char *dirname, cpd_check_t check,
|
||||
struct stat st;
|
||||
char *f;
|
||||
#ifndef _WIN32
|
||||
int mask;
|
||||
unsigned unwanted_bits = 0;
|
||||
const struct passwd *pw = NULL;
|
||||
uid_t running_uid;
|
||||
gid_t running_gid;
|
||||
@@ -1980,7 +2053,11 @@ check_private_dir(const char *dirname, cpd_check_t check,
|
||||
#if defined (_WIN32)
|
||||
r = mkdir(dirname);
|
||||
#else
|
||||
r = mkdir(dirname, 0700);
|
||||
if (check & CPD_GROUP_READ) {
|
||||
r = mkdir(dirname, 0750);
|
||||
} else {
|
||||
r = mkdir(dirname, 0700);
|
||||
}
|
||||
#endif
|
||||
if (r) {
|
||||
log_warn(LD_FS, "Error creating directory %s: %s", dirname,
|
||||
@@ -2033,7 +2110,8 @@ check_private_dir(const char *dirname, cpd_check_t check,
|
||||
tor_free(process_ownername);
|
||||
return -1;
|
||||
}
|
||||
if ((check & CPD_GROUP_OK) && st.st_gid != running_gid) {
|
||||
if ( (check & (CPD_GROUP_OK|CPD_GROUP_READ))
|
||||
&& (st.st_gid != running_gid) ) {
|
||||
struct group *gr;
|
||||
char *process_groupname = NULL;
|
||||
gr = getgrgid(running_gid);
|
||||
@@ -2048,12 +2126,12 @@ check_private_dir(const char *dirname, cpd_check_t check,
|
||||
tor_free(process_groupname);
|
||||
return -1;
|
||||
}
|
||||
if (check & CPD_GROUP_OK) {
|
||||
mask = 0027;
|
||||
if (check & (CPD_GROUP_OK|CPD_GROUP_READ)) {
|
||||
unwanted_bits = 0027;
|
||||
} else {
|
||||
mask = 0077;
|
||||
unwanted_bits = 0077;
|
||||
}
|
||||
if (st.st_mode & mask) {
|
||||
if ((st.st_mode & unwanted_bits) != 0) {
|
||||
unsigned new_mode;
|
||||
if (check & CPD_CHECK_MODE_ONLY) {
|
||||
log_warn(LD_FS, "Permissions on directory %s are too permissive.",
|
||||
@@ -2063,10 +2141,13 @@ check_private_dir(const char *dirname, cpd_check_t check,
|
||||
log_warn(LD_FS, "Fixing permissions on directory %s", dirname);
|
||||
new_mode = st.st_mode;
|
||||
new_mode |= 0700; /* Owner should have rwx */
|
||||
new_mode &= ~mask; /* Clear the other bits that we didn't want set...*/
|
||||
if (check & CPD_GROUP_READ) {
|
||||
new_mode |= 0050; /* Group should have rx */
|
||||
}
|
||||
new_mode &= ~unwanted_bits; /* Clear the bits that we didn't want set...*/
|
||||
if (chmod(dirname, new_mode)) {
|
||||
log_warn(LD_FS, "Could not chmod directory %s: %s", dirname,
|
||||
strerror(errno));
|
||||
strerror(errno));
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
@@ -3474,8 +3555,9 @@ format_win_cmdline_argument(const char *arg)
|
||||
smartlist_add(arg_chars, (void*)&backslash);
|
||||
|
||||
/* Allocate space for argument, quotes (if needed), and terminator */
|
||||
formatted_arg = tor_calloc(sizeof(char),
|
||||
(smartlist_len(arg_chars) + (need_quotes ? 2 : 0) + 1));
|
||||
const size_t formatted_arg_len = smartlist_len(arg_chars) +
|
||||
(need_quotes ? 2 : 0) + 1;
|
||||
formatted_arg = tor_malloc_zero(formatted_arg_len);
|
||||
|
||||
/* Add leading quote */
|
||||
i=0;
|
||||
@@ -5113,7 +5195,7 @@ tor_check_port_forwarding(const char *filename,
|
||||
for each smartlist element (one for "-p" and one for the
|
||||
ports), and one for the final NULL. */
|
||||
args_n = 1 + 2*smartlist_len(ports_to_forward) + 1;
|
||||
argv = tor_calloc(sizeof(char *), args_n);
|
||||
argv = tor_calloc(args_n, sizeof(char *));
|
||||
|
||||
argv[argv_index++] = filename;
|
||||
SMARTLIST_FOREACH_BEGIN(ports_to_forward, const char *, port) {
|
||||
|
||||
+6
-1
@@ -227,6 +227,9 @@ const char *find_str_at_start_of_line(const char *haystack,
|
||||
const char *needle);
|
||||
int string_is_C_identifier(const char *string);
|
||||
int string_is_key_value(int severity, const char *string);
|
||||
int string_is_valid_hostname(const char *string);
|
||||
int string_is_valid_ipv4_address(const char *string);
|
||||
int string_is_valid_ipv6_address(const char *string);
|
||||
|
||||
int tor_mem_is_zero(const char *mem, size_t len);
|
||||
int tor_digest_is_zero(const char *digest);
|
||||
@@ -344,9 +347,11 @@ typedef unsigned int cpd_check_t;
|
||||
#define CPD_CREATE 1
|
||||
#define CPD_CHECK 2
|
||||
#define CPD_GROUP_OK 4
|
||||
#define CPD_CHECK_MODE_ONLY 8
|
||||
#define CPD_GROUP_READ 8
|
||||
#define CPD_CHECK_MODE_ONLY 16
|
||||
int check_private_dir(const char *dirname, cpd_check_t check,
|
||||
const char *effective_user);
|
||||
|
||||
#define OPEN_FLAGS_REPLACE (O_WRONLY|O_CREAT|O_TRUNC)
|
||||
#define OPEN_FLAGS_APPEND (O_WRONLY|O_CREAT|O_APPEND)
|
||||
#define OPEN_FLAGS_DONT_REPLACE (O_CREAT|O_EXCL|O_APPEND|O_WRONLY)
|
||||
|
||||
+13641
-6395
File diff suppressed because it is too large
Load Diff
+5506
-143
File diff suppressed because it is too large
Load Diff
@@ -74,13 +74,13 @@ test_strcmp(void *data)
|
||||
values of the failing things.
|
||||
|
||||
Fail unless strcmp("abc, "abc") == 0 */
|
||||
tt_int_op(strcmp("abc", "abc"), ==, 0);
|
||||
tt_int_op(strcmp("abc", "abc"), OP_EQ, 0);
|
||||
|
||||
/* Fail unless strcmp("abc, "abcd") is less than 0 */
|
||||
tt_int_op(strcmp("abc", "abcd"), < , 0);
|
||||
tt_int_op(strcmp("abc", "abcd"), OP_LT, 0);
|
||||
|
||||
/* Incidentally, there's a test_str_op that uses strcmp internally. */
|
||||
tt_str_op("abc", <, "abcd");
|
||||
tt_str_op("abc", OP_LT, "abcd");
|
||||
|
||||
|
||||
/* Every test-case function needs to finish with an "end:"
|
||||
@@ -153,11 +153,11 @@ test_memcpy(void *ptr)
|
||||
/* Let's make sure that memcpy does what we'd like. */
|
||||
strcpy(db->buffer1, "String 0");
|
||||
memcpy(db->buffer2, db->buffer1, sizeof(db->buffer1));
|
||||
tt_str_op(db->buffer1, ==, db->buffer2);
|
||||
tt_str_op(db->buffer1, OP_EQ, db->buffer2);
|
||||
|
||||
/* tt_mem_op() does a memcmp, as opposed to the strcmp in tt_str_op() */
|
||||
db->buffer2[100] = 3; /* Make the buffers unequal */
|
||||
tt_mem_op(db->buffer1, <, db->buffer2, sizeof(db->buffer1));
|
||||
tt_mem_op(db->buffer1, OP_LT, db->buffer2, sizeof(db->buffer1));
|
||||
|
||||
/* Now we've allocated memory that's referenced by a local variable.
|
||||
The end block of the function will clean it up. */
|
||||
@@ -165,7 +165,7 @@ test_memcpy(void *ptr)
|
||||
tt_assert(mem);
|
||||
|
||||
/* Another rather trivial test. */
|
||||
tt_str_op(db->buffer1, !=, mem);
|
||||
tt_str_op(db->buffer1, OP_NE, mem);
|
||||
|
||||
end:
|
||||
/* This time our end block has something to do. */
|
||||
@@ -186,9 +186,9 @@ test_timeout(void *ptr)
|
||||
#endif
|
||||
t2 = time(NULL);
|
||||
|
||||
tt_int_op(t2-t1, >=, 4);
|
||||
tt_int_op(t2-t1, OP_GE, 4);
|
||||
|
||||
tt_int_op(t2-t1, <=, 6);
|
||||
tt_int_op(t2-t1, OP_LE, 6);
|
||||
|
||||
end:
|
||||
;
|
||||
|
||||
@@ -63,6 +63,7 @@ LIBTOR_OBJECTS = \
|
||||
routerlist.obj \
|
||||
routerparse.obj \
|
||||
routerset.obj \
|
||||
scheduler.obj \
|
||||
statefile.obj \
|
||||
status.obj \
|
||||
transports.obj
|
||||
|
||||
+15
-3
@@ -562,8 +562,8 @@ buf_clear(buf_t *buf)
|
||||
}
|
||||
|
||||
/** Return the number of bytes stored in <b>buf</b> */
|
||||
size_t
|
||||
buf_datalen(const buf_t *buf)
|
||||
MOCK_IMPL(size_t,
|
||||
buf_datalen, (const buf_t *buf))
|
||||
{
|
||||
return buf->datalen;
|
||||
}
|
||||
@@ -2054,8 +2054,20 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
|
||||
req->address[len] = 0;
|
||||
req->port = ntohs(get_uint16(data+5+len));
|
||||
*drain_out = 5+len+2;
|
||||
if (!tor_strisprint(req->address) || strchr(req->address,'\"')) {
|
||||
|
||||
if (string_is_valid_ipv4_address(req->address) ||
|
||||
string_is_valid_ipv6_address(req->address)) {
|
||||
log_unsafe_socks_warning(5,req->address,req->port,safe_socks);
|
||||
|
||||
if (safe_socks) {
|
||||
socks_request_set_socks5_error(req, SOCKS5_NOT_ALLOWED);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string_is_valid_hostname(req->address)) {
|
||||
socks_request_set_socks5_error(req, SOCKS5_GENERAL_ERROR);
|
||||
|
||||
log_warn(LD_PROTOCOL,
|
||||
"Your application (using socks5 to port %d) gave Tor "
|
||||
"a malformed hostname: %s. Rejecting the connection.",
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ void buf_shrink(buf_t *buf);
|
||||
size_t buf_shrink_freelists(int free_all);
|
||||
void buf_dump_freelist_sizes(int severity);
|
||||
|
||||
size_t buf_datalen(const buf_t *buf);
|
||||
MOCK_DECL(size_t, buf_datalen, (const buf_t *buf));
|
||||
size_t buf_allocation(const buf_t *buf);
|
||||
size_t buf_slack(const buf_t *buf);
|
||||
|
||||
|
||||
+428
-49
@@ -13,6 +13,9 @@
|
||||
|
||||
#define TOR_CHANNEL_INTERNAL_
|
||||
|
||||
/* This one's for stuff only channel.c and the test suite should see */
|
||||
#define CHANNEL_PRIVATE_
|
||||
|
||||
#include "or.h"
|
||||
#include "channel.h"
|
||||
#include "channeltls.h"
|
||||
@@ -29,29 +32,7 @@
|
||||
#include "rephist.h"
|
||||
#include "router.h"
|
||||
#include "routerlist.h"
|
||||
|
||||
/* Cell queue structure */
|
||||
|
||||
typedef struct cell_queue_entry_s cell_queue_entry_t;
|
||||
struct cell_queue_entry_s {
|
||||
TOR_SIMPLEQ_ENTRY(cell_queue_entry_s) next;
|
||||
enum {
|
||||
CELL_QUEUE_FIXED,
|
||||
CELL_QUEUE_VAR,
|
||||
CELL_QUEUE_PACKED
|
||||
} type;
|
||||
union {
|
||||
struct {
|
||||
cell_t *cell;
|
||||
} fixed;
|
||||
struct {
|
||||
var_cell_t *var_cell;
|
||||
} var;
|
||||
struct {
|
||||
packed_cell_t *packed_cell;
|
||||
} packed;
|
||||
} u;
|
||||
};
|
||||
#include "scheduler.h"
|
||||
|
||||
/* Global lists of channels */
|
||||
|
||||
@@ -76,6 +57,60 @@ static smartlist_t *finished_listeners = NULL;
|
||||
/* Counter for ID numbers */
|
||||
static uint64_t n_channels_allocated = 0;
|
||||
|
||||
/*
|
||||
* Channel global byte/cell counters, for statistics and for scheduler high
|
||||
* /low-water marks.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Total number of cells ever given to any channel with the
|
||||
* channel_write_*_cell() functions.
|
||||
*/
|
||||
|
||||
static uint64_t n_channel_cells_queued = 0;
|
||||
|
||||
/*
|
||||
* Total number of cells ever passed to a channel lower layer with the
|
||||
* write_*_cell() methods.
|
||||
*/
|
||||
|
||||
static uint64_t n_channel_cells_passed_to_lower_layer = 0;
|
||||
|
||||
/*
|
||||
* Current number of cells in all channel queues; should be
|
||||
* n_channel_cells_queued - n_channel_cells_passed_to_lower_layer.
|
||||
*/
|
||||
|
||||
static uint64_t n_channel_cells_in_queues = 0;
|
||||
|
||||
/*
|
||||
* Total number of bytes for all cells ever queued to a channel and
|
||||
* counted in n_channel_cells_queued.
|
||||
*/
|
||||
|
||||
static uint64_t n_channel_bytes_queued = 0;
|
||||
|
||||
/*
|
||||
* Total number of bytes for all cells ever passed to a channel lower layer
|
||||
* and counted in n_channel_cells_passed_to_lower_layer.
|
||||
*/
|
||||
|
||||
static uint64_t n_channel_bytes_passed_to_lower_layer = 0;
|
||||
|
||||
/*
|
||||
* Current number of bytes in all channel queues; should be
|
||||
* n_channel_bytes_queued - n_channel_bytes_passed_to_lower_layer.
|
||||
*/
|
||||
|
||||
static uint64_t n_channel_bytes_in_queues = 0;
|
||||
|
||||
/*
|
||||
* Current total estimated queue size *including lower layer queues and
|
||||
* transmit overhead*
|
||||
*/
|
||||
|
||||
STATIC uint64_t estimated_total_queue_size = 0;
|
||||
|
||||
/* Digest->channel map
|
||||
*
|
||||
* Similar to the one used in connection_or.c, this maps from the identity
|
||||
@@ -123,6 +158,8 @@ cell_queue_entry_new_var(var_cell_t *var_cell);
|
||||
static int is_destroy_cell(channel_t *chan,
|
||||
const cell_queue_entry_t *q, circid_t *circid_out);
|
||||
|
||||
static void channel_assert_counter_consistency(void);
|
||||
|
||||
/* Functions to maintain the digest map */
|
||||
static void channel_add_to_digest_map(channel_t *chan);
|
||||
static void channel_remove_from_digest_map(channel_t *chan);
|
||||
@@ -140,6 +177,8 @@ channel_free_list(smartlist_t *channels, int mark_for_close);
|
||||
static void
|
||||
channel_listener_free_list(smartlist_t *channels, int mark_for_close);
|
||||
static void channel_listener_force_free(channel_listener_t *chan_l);
|
||||
static size_t channel_get_cell_queue_entry_size(channel_t *chan,
|
||||
cell_queue_entry_t *q);
|
||||
static void
|
||||
channel_write_cell_queue_entry(channel_t *chan, cell_queue_entry_t *q);
|
||||
|
||||
@@ -746,6 +785,9 @@ channel_init(channel_t *chan)
|
||||
|
||||
/* It hasn't been open yet. */
|
||||
chan->has_been_open = 0;
|
||||
|
||||
/* Scheduler state is idle */
|
||||
chan->scheduler_state = SCHED_CHAN_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -788,6 +830,9 @@ channel_free(channel_t *chan)
|
||||
"Freeing channel " U64_FORMAT " at %p",
|
||||
U64_PRINTF_ARG(chan->global_identifier), chan);
|
||||
|
||||
/* Get this one out of the scheduler */
|
||||
scheduler_release_channel(chan);
|
||||
|
||||
/*
|
||||
* Get rid of cmux policy before we do anything, so cmux policies don't
|
||||
* see channels in weird half-freed states.
|
||||
@@ -863,6 +908,9 @@ channel_force_free(channel_t *chan)
|
||||
"Force-freeing channel " U64_FORMAT " at %p",
|
||||
U64_PRINTF_ARG(chan->global_identifier), chan);
|
||||
|
||||
/* Get this one out of the scheduler */
|
||||
scheduler_release_channel(chan);
|
||||
|
||||
/*
|
||||
* Get rid of cmux policy before we do anything, so cmux policies don't
|
||||
* see channels in weird half-freed states.
|
||||
@@ -1665,6 +1713,36 @@ cell_queue_entry_new_var(var_cell_t *var_cell)
|
||||
return q;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask how big the cell contained in a cell_queue_entry_t is
|
||||
*/
|
||||
|
||||
static size_t
|
||||
channel_get_cell_queue_entry_size(channel_t *chan, cell_queue_entry_t *q)
|
||||
{
|
||||
size_t rv = 0;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(q);
|
||||
|
||||
switch (q->type) {
|
||||
case CELL_QUEUE_FIXED:
|
||||
rv = get_cell_network_size(chan->wide_circ_ids);
|
||||
break;
|
||||
case CELL_QUEUE_VAR:
|
||||
rv = get_var_cell_header_size(chan->wide_circ_ids) +
|
||||
(q->u.var.var_cell ? q->u.var.var_cell->payload_len : 0);
|
||||
break;
|
||||
case CELL_QUEUE_PACKED:
|
||||
rv = get_cell_network_size(chan->wide_circ_ids);
|
||||
break;
|
||||
default:
|
||||
tor_assert(1);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to a channel based on a cell_queue_entry_t
|
||||
*
|
||||
@@ -1677,6 +1755,7 @@ channel_write_cell_queue_entry(channel_t *chan, cell_queue_entry_t *q)
|
||||
{
|
||||
int result = 0, sent = 0;
|
||||
cell_queue_entry_t *tmp = NULL;
|
||||
size_t cell_bytes;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(q);
|
||||
@@ -1693,6 +1772,9 @@ channel_write_cell_queue_entry(channel_t *chan, cell_queue_entry_t *q)
|
||||
}
|
||||
}
|
||||
|
||||
/* For statistical purposes, figure out how big this cell is */
|
||||
cell_bytes = channel_get_cell_queue_entry_size(chan, q);
|
||||
|
||||
/* Can we send it right out? If so, try */
|
||||
if (TOR_SIMPLEQ_EMPTY(&chan->outgoing_queue) &&
|
||||
chan->state == CHANNEL_STATE_OPEN) {
|
||||
@@ -1726,6 +1808,13 @@ channel_write_cell_queue_entry(channel_t *chan, cell_queue_entry_t *q)
|
||||
channel_timestamp_drained(chan);
|
||||
/* Update the counter */
|
||||
++(chan->n_cells_xmitted);
|
||||
chan->n_bytes_xmitted += cell_bytes;
|
||||
/* Update global counters */
|
||||
++n_channel_cells_queued;
|
||||
++n_channel_cells_passed_to_lower_layer;
|
||||
n_channel_bytes_queued += cell_bytes;
|
||||
n_channel_bytes_passed_to_lower_layer += cell_bytes;
|
||||
channel_assert_counter_consistency();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1737,6 +1826,14 @@ channel_write_cell_queue_entry(channel_t *chan, cell_queue_entry_t *q)
|
||||
*/
|
||||
tmp = cell_queue_entry_dup(q);
|
||||
TOR_SIMPLEQ_INSERT_TAIL(&chan->outgoing_queue, tmp, next);
|
||||
/* Update global counters */
|
||||
++n_channel_cells_queued;
|
||||
++n_channel_cells_in_queues;
|
||||
n_channel_bytes_queued += cell_bytes;
|
||||
n_channel_bytes_in_queues += cell_bytes;
|
||||
channel_assert_counter_consistency();
|
||||
/* Update channel queue size */
|
||||
chan->bytes_in_queue += cell_bytes;
|
||||
/* Try to process the queue? */
|
||||
if (chan->state == CHANNEL_STATE_OPEN) channel_flush_cells(chan);
|
||||
}
|
||||
@@ -1775,6 +1872,9 @@ channel_write_cell(channel_t *chan, cell_t *cell)
|
||||
q.type = CELL_QUEUE_FIXED;
|
||||
q.u.fixed.cell = cell;
|
||||
channel_write_cell_queue_entry(chan, &q);
|
||||
|
||||
/* Update the queue size estimate */
|
||||
channel_update_xmit_queue_size(chan);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1810,6 +1910,9 @@ channel_write_packed_cell(channel_t *chan, packed_cell_t *packed_cell)
|
||||
q.type = CELL_QUEUE_PACKED;
|
||||
q.u.packed.packed_cell = packed_cell;
|
||||
channel_write_cell_queue_entry(chan, &q);
|
||||
|
||||
/* Update the queue size estimate */
|
||||
channel_update_xmit_queue_size(chan);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1846,6 +1949,9 @@ channel_write_var_cell(channel_t *chan, var_cell_t *var_cell)
|
||||
q.type = CELL_QUEUE_VAR;
|
||||
q.u.var.var_cell = var_cell;
|
||||
channel_write_cell_queue_entry(chan, &q);
|
||||
|
||||
/* Update the queue size estimate */
|
||||
channel_update_xmit_queue_size(chan);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1941,6 +2047,41 @@ channel_change_state(channel_t *chan, channel_state_t to_state)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're going to a closed/closing state, we don't need scheduling any
|
||||
* more; in CHANNEL_STATE_MAINT we can't accept writes.
|
||||
*/
|
||||
if (to_state == CHANNEL_STATE_CLOSING ||
|
||||
to_state == CHANNEL_STATE_CLOSED ||
|
||||
to_state == CHANNEL_STATE_ERROR) {
|
||||
scheduler_release_channel(chan);
|
||||
} else if (to_state == CHANNEL_STATE_MAINT) {
|
||||
scheduler_channel_doesnt_want_writes(chan);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're closing, this channel no longer counts toward the global
|
||||
* estimated queue size; if we're open, it now does.
|
||||
*/
|
||||
if ((to_state == CHANNEL_STATE_CLOSING ||
|
||||
to_state == CHANNEL_STATE_CLOSED ||
|
||||
to_state == CHANNEL_STATE_ERROR) &&
|
||||
(from_state == CHANNEL_STATE_OPEN ||
|
||||
from_state == CHANNEL_STATE_MAINT)) {
|
||||
estimated_total_queue_size -= chan->bytes_in_queue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're opening, this channel now does count toward the global
|
||||
* estimated queue size.
|
||||
*/
|
||||
if ((to_state == CHANNEL_STATE_OPEN ||
|
||||
to_state == CHANNEL_STATE_MAINT) &&
|
||||
!(from_state == CHANNEL_STATE_OPEN ||
|
||||
from_state == CHANNEL_STATE_MAINT)) {
|
||||
estimated_total_queue_size += chan->bytes_in_queue;
|
||||
}
|
||||
|
||||
/* Tell circuits if we opened and stuff */
|
||||
if (to_state == CHANNEL_STATE_OPEN) {
|
||||
channel_do_open_actions(chan);
|
||||
@@ -2056,12 +2197,13 @@ channel_listener_change_state(channel_listener_t *chan_l,
|
||||
|
||||
#define MAX_CELLS_TO_GET_FROM_CIRCUITS_FOR_UNLIMITED 256
|
||||
|
||||
ssize_t
|
||||
channel_flush_some_cells(channel_t *chan, ssize_t num_cells)
|
||||
MOCK_IMPL(ssize_t,
|
||||
channel_flush_some_cells, (channel_t *chan, ssize_t num_cells))
|
||||
{
|
||||
unsigned int unlimited = 0;
|
||||
ssize_t flushed = 0;
|
||||
int num_cells_from_circs, clamped_num_cells;
|
||||
int q_len_before, q_len_after;
|
||||
|
||||
tor_assert(chan);
|
||||
|
||||
@@ -2087,14 +2229,45 @@ channel_flush_some_cells(channel_t *chan, ssize_t num_cells)
|
||||
clamped_num_cells = (int)(num_cells - flushed);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep track of the change in queue size; we have to count cells
|
||||
* channel_flush_from_first_active_circuit() writes out directly,
|
||||
* but not double-count ones we might get later in
|
||||
* channel_flush_some_cells_from_outgoing_queue()
|
||||
*/
|
||||
q_len_before = chan_cell_queue_len(&(chan->outgoing_queue));
|
||||
|
||||
/* Try to get more cells from any active circuits */
|
||||
num_cells_from_circs = channel_flush_from_first_active_circuit(
|
||||
chan, clamped_num_cells);
|
||||
|
||||
/* If it claims we got some, process the queue again */
|
||||
q_len_after = chan_cell_queue_len(&(chan->outgoing_queue));
|
||||
|
||||
/*
|
||||
* If it claims we got some, adjust the flushed counter and consider
|
||||
* processing the queue again
|
||||
*/
|
||||
if (num_cells_from_circs > 0) {
|
||||
flushed += channel_flush_some_cells_from_outgoing_queue(chan,
|
||||
(unlimited ? -1 : num_cells - flushed));
|
||||
/*
|
||||
* Adjust flushed by the number of cells counted in
|
||||
* num_cells_from_circs that didn't go to the cell queue.
|
||||
*/
|
||||
|
||||
if (q_len_after > q_len_before) {
|
||||
num_cells_from_circs -= (q_len_after - q_len_before);
|
||||
if (num_cells_from_circs < 0) num_cells_from_circs = 0;
|
||||
}
|
||||
|
||||
flushed += num_cells_from_circs;
|
||||
|
||||
/* Now process the queue if necessary */
|
||||
|
||||
if ((q_len_after > q_len_before) &&
|
||||
(unlimited || (flushed < num_cells))) {
|
||||
flushed += channel_flush_some_cells_from_outgoing_queue(chan,
|
||||
(unlimited ? -1 : num_cells - flushed));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2117,6 +2290,8 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
|
||||
unsigned int unlimited = 0;
|
||||
ssize_t flushed = 0;
|
||||
cell_queue_entry_t *q = NULL;
|
||||
size_t cell_size;
|
||||
int free_q = 0, handed_off = 0;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(chan->write_cell);
|
||||
@@ -2130,8 +2305,12 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
|
||||
if (chan->state == CHANNEL_STATE_OPEN) {
|
||||
while ((unlimited || num_cells > flushed) &&
|
||||
NULL != (q = TOR_SIMPLEQ_FIRST(&chan->outgoing_queue))) {
|
||||
free_q = 0;
|
||||
handed_off = 0;
|
||||
|
||||
if (1) {
|
||||
/* Figure out how big it is for statistical purposes */
|
||||
cell_size = channel_get_cell_queue_entry_size(chan, q);
|
||||
/*
|
||||
* Okay, we have a good queue entry, try to give it to the lower
|
||||
* layer.
|
||||
@@ -2144,8 +2323,9 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
|
||||
++flushed;
|
||||
channel_timestamp_xmit(chan);
|
||||
++(chan->n_cells_xmitted);
|
||||
cell_queue_entry_free(q, 1);
|
||||
q = NULL;
|
||||
chan->n_bytes_xmitted += cell_size;
|
||||
free_q = 1;
|
||||
handed_off = 1;
|
||||
}
|
||||
/* Else couldn't write it; leave it on the queue */
|
||||
} else {
|
||||
@@ -2156,8 +2336,8 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
|
||||
"(global ID " U64_FORMAT ").",
|
||||
chan, U64_PRINTF_ARG(chan->global_identifier));
|
||||
/* Throw it away */
|
||||
cell_queue_entry_free(q, 0);
|
||||
q = NULL;
|
||||
free_q = 1;
|
||||
handed_off = 0;
|
||||
}
|
||||
break;
|
||||
case CELL_QUEUE_PACKED:
|
||||
@@ -2167,8 +2347,9 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
|
||||
++flushed;
|
||||
channel_timestamp_xmit(chan);
|
||||
++(chan->n_cells_xmitted);
|
||||
cell_queue_entry_free(q, 1);
|
||||
q = NULL;
|
||||
chan->n_bytes_xmitted += cell_size;
|
||||
free_q = 1;
|
||||
handed_off = 1;
|
||||
}
|
||||
/* Else couldn't write it; leave it on the queue */
|
||||
} else {
|
||||
@@ -2179,8 +2360,8 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
|
||||
"(global ID " U64_FORMAT ").",
|
||||
chan, U64_PRINTF_ARG(chan->global_identifier));
|
||||
/* Throw it away */
|
||||
cell_queue_entry_free(q, 0);
|
||||
q = NULL;
|
||||
free_q = 1;
|
||||
handed_off = 0;
|
||||
}
|
||||
break;
|
||||
case CELL_QUEUE_VAR:
|
||||
@@ -2190,8 +2371,9 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
|
||||
++flushed;
|
||||
channel_timestamp_xmit(chan);
|
||||
++(chan->n_cells_xmitted);
|
||||
cell_queue_entry_free(q, 1);
|
||||
q = NULL;
|
||||
chan->n_bytes_xmitted += cell_size;
|
||||
free_q = 1;
|
||||
handed_off = 1;
|
||||
}
|
||||
/* Else couldn't write it; leave it on the queue */
|
||||
} else {
|
||||
@@ -2202,8 +2384,8 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
|
||||
"(global ID " U64_FORMAT ").",
|
||||
chan, U64_PRINTF_ARG(chan->global_identifier));
|
||||
/* Throw it away */
|
||||
cell_queue_entry_free(q, 0);
|
||||
q = NULL;
|
||||
free_q = 1;
|
||||
handed_off = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -2213,12 +2395,32 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
|
||||
"(global ID " U64_FORMAT "; ignoring it."
|
||||
" Someone should fix this.",
|
||||
q->type, chan, U64_PRINTF_ARG(chan->global_identifier));
|
||||
cell_queue_entry_free(q, 0);
|
||||
q = NULL;
|
||||
free_q = 1;
|
||||
handed_off = 0;
|
||||
}
|
||||
|
||||
/* if q got NULLed out, we used it and should remove the queue entry */
|
||||
if (!q) TOR_SIMPLEQ_REMOVE_HEAD(&chan->outgoing_queue, next);
|
||||
/*
|
||||
* if free_q is set, we used it and should remove the queue entry;
|
||||
* we have to do the free down here so TOR_SIMPLEQ_REMOVE_HEAD isn't
|
||||
* accessing freed memory
|
||||
*/
|
||||
if (free_q) {
|
||||
TOR_SIMPLEQ_REMOVE_HEAD(&chan->outgoing_queue, next);
|
||||
/*
|
||||
* ...and we handed a cell off to the lower layer, so we should
|
||||
* update the counters.
|
||||
*/
|
||||
++n_channel_cells_passed_to_lower_layer;
|
||||
--n_channel_cells_in_queues;
|
||||
n_channel_bytes_passed_to_lower_layer += cell_size;
|
||||
n_channel_bytes_in_queues -= cell_size;
|
||||
channel_assert_counter_consistency();
|
||||
/* Update the channel's queue size too */
|
||||
chan->bytes_in_queue -= cell_size;
|
||||
/* Finally, free q */
|
||||
cell_queue_entry_free(q, handed_off);
|
||||
q = NULL;
|
||||
}
|
||||
/* No cell removed from list, so we can't go on any further */
|
||||
else break;
|
||||
}
|
||||
@@ -2230,6 +2432,9 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
|
||||
channel_timestamp_drained(chan);
|
||||
}
|
||||
|
||||
/* Update the estimate queue size */
|
||||
channel_update_xmit_queue_size(chan);
|
||||
|
||||
return flushed;
|
||||
}
|
||||
|
||||
@@ -2541,8 +2746,9 @@ channel_queue_cell(channel_t *chan, cell_t *cell)
|
||||
/* Timestamp for receiving */
|
||||
channel_timestamp_recv(chan);
|
||||
|
||||
/* Update the counter */
|
||||
/* Update the counters */
|
||||
++(chan->n_cells_recved);
|
||||
chan->n_bytes_recved += get_cell_network_size(chan->wide_circ_ids);
|
||||
|
||||
/* If we don't need to queue we can just call cell_handler */
|
||||
if (!need_to_queue) {
|
||||
@@ -2596,6 +2802,8 @@ channel_queue_var_cell(channel_t *chan, var_cell_t *var_cell)
|
||||
|
||||
/* Update the counter */
|
||||
++(chan->n_cells_recved);
|
||||
chan->n_bytes_recved += get_var_cell_header_size(chan->wide_circ_ids) +
|
||||
var_cell->payload_len;
|
||||
|
||||
/* If we don't need to queue we can just call cell_handler */
|
||||
if (!need_to_queue) {
|
||||
@@ -2645,6 +2853,19 @@ packed_cell_is_destroy(channel_t *chan,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the global channel stats counters are internally consistent
|
||||
*/
|
||||
|
||||
static void
|
||||
channel_assert_counter_consistency(void)
|
||||
{
|
||||
tor_assert(n_channel_cells_queued ==
|
||||
(n_channel_cells_in_queues + n_channel_cells_passed_to_lower_layer));
|
||||
tor_assert(n_channel_bytes_queued ==
|
||||
(n_channel_bytes_in_queues + n_channel_bytes_passed_to_lower_layer));
|
||||
}
|
||||
|
||||
/** DOCDOC */
|
||||
static int
|
||||
is_destroy_cell(channel_t *chan,
|
||||
@@ -2726,6 +2947,19 @@ void
|
||||
channel_dumpstats(int severity)
|
||||
{
|
||||
if (all_channels && smartlist_len(all_channels) > 0) {
|
||||
tor_log(severity, LD_GENERAL,
|
||||
"Channels have queued " U64_FORMAT " bytes in " U64_FORMAT " cells, "
|
||||
"and handed " U64_FORMAT " bytes in " U64_FORMAT " cells to the lower"
|
||||
" layer.",
|
||||
U64_PRINTF_ARG(n_channel_bytes_queued),
|
||||
U64_PRINTF_ARG(n_channel_cells_queued),
|
||||
U64_PRINTF_ARG(n_channel_bytes_passed_to_lower_layer),
|
||||
U64_PRINTF_ARG(n_channel_cells_passed_to_lower_layer));
|
||||
tor_log(severity, LD_GENERAL,
|
||||
"There are currently " U64_FORMAT " bytes in " U64_FORMAT " cells "
|
||||
"in channel queues.",
|
||||
U64_PRINTF_ARG(n_channel_bytes_in_queues),
|
||||
U64_PRINTF_ARG(n_channel_cells_in_queues));
|
||||
tor_log(severity, LD_GENERAL,
|
||||
"Dumping statistics about %d channels:",
|
||||
smartlist_len(all_channels));
|
||||
@@ -3200,7 +3434,7 @@ channel_listener_describe_transport(channel_listener_t *chan_l)
|
||||
/**
|
||||
* Return the number of entries in <b>queue</b>
|
||||
*/
|
||||
static int
|
||||
STATIC int
|
||||
chan_cell_queue_len(const chan_cell_queue_t *queue)
|
||||
{
|
||||
int r = 0;
|
||||
@@ -3216,8 +3450,8 @@ chan_cell_queue_len(const chan_cell_queue_t *queue)
|
||||
* Dump statistics for one channel to the log
|
||||
*/
|
||||
|
||||
void
|
||||
channel_dump_statistics(channel_t *chan, int severity)
|
||||
MOCK_IMPL(void,
|
||||
channel_dump_statistics, (channel_t *chan, int severity))
|
||||
{
|
||||
double avg, interval, age;
|
||||
time_t now = time(NULL);
|
||||
@@ -3369,12 +3603,22 @@ channel_dump_statistics(channel_t *chan, int severity)
|
||||
/* Describe counters and rates */
|
||||
tor_log(severity, LD_GENERAL,
|
||||
" * Channel " U64_FORMAT " has received "
|
||||
U64_FORMAT " cells and transmitted " U64_FORMAT,
|
||||
U64_FORMAT " bytes in " U64_FORMAT " cells and transmitted "
|
||||
U64_FORMAT " bytes in " U64_FORMAT " cells",
|
||||
U64_PRINTF_ARG(chan->global_identifier),
|
||||
U64_PRINTF_ARG(chan->n_bytes_recved),
|
||||
U64_PRINTF_ARG(chan->n_cells_recved),
|
||||
U64_PRINTF_ARG(chan->n_bytes_xmitted),
|
||||
U64_PRINTF_ARG(chan->n_cells_xmitted));
|
||||
if (now > chan->timestamp_created &&
|
||||
chan->timestamp_created > 0) {
|
||||
if (chan->n_bytes_recved > 0) {
|
||||
avg = (double)(chan->n_bytes_recved) / age;
|
||||
tor_log(severity, LD_GENERAL,
|
||||
" * Channel " U64_FORMAT " has averaged %f "
|
||||
"bytes received per second",
|
||||
U64_PRINTF_ARG(chan->global_identifier), avg);
|
||||
}
|
||||
if (chan->n_cells_recved > 0) {
|
||||
avg = (double)(chan->n_cells_recved) / age;
|
||||
if (avg >= 1.0) {
|
||||
@@ -3390,6 +3634,13 @@ channel_dump_statistics(channel_t *chan, int severity)
|
||||
U64_PRINTF_ARG(chan->global_identifier), interval);
|
||||
}
|
||||
}
|
||||
if (chan->n_bytes_xmitted > 0) {
|
||||
avg = (double)(chan->n_bytes_xmitted) / age;
|
||||
tor_log(severity, LD_GENERAL,
|
||||
" * Channel " U64_FORMAT " has averaged %f "
|
||||
"bytes transmitted per second",
|
||||
U64_PRINTF_ARG(chan->global_identifier), avg);
|
||||
}
|
||||
if (chan->n_cells_xmitted > 0) {
|
||||
avg = (double)(chan->n_cells_xmitted) / age;
|
||||
if (avg >= 1.0) {
|
||||
@@ -3807,6 +4058,50 @@ channel_mark_outgoing(channel_t *chan)
|
||||
chan->is_incoming = 0;
|
||||
}
|
||||
|
||||
/************************
|
||||
* Flow control queries *
|
||||
***********************/
|
||||
|
||||
/*
|
||||
* Get the latest estimate for the total queue size of all open channels
|
||||
*/
|
||||
|
||||
uint64_t
|
||||
channel_get_global_queue_estimate(void)
|
||||
{
|
||||
return estimated_total_queue_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Estimate the number of writeable cells
|
||||
*
|
||||
* Ask the lower layer for an estimate of how many cells it can accept, and
|
||||
* then subtract the length of our outgoing_queue, if any, to produce an
|
||||
* estimate of the number of cells this channel can accept for writes.
|
||||
*/
|
||||
|
||||
int
|
||||
channel_num_cells_writeable(channel_t *chan)
|
||||
{
|
||||
int result;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(chan->num_cells_writeable);
|
||||
|
||||
if (chan->state == CHANNEL_STATE_OPEN) {
|
||||
/* Query lower layer */
|
||||
result = chan->num_cells_writeable(chan);
|
||||
/* Subtract cell queue length, if any */
|
||||
result -= chan_cell_queue_len(&chan->outgoing_queue);
|
||||
if (result < 0) result = 0;
|
||||
} else {
|
||||
/* No cells are writeable in any other state */
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*********************
|
||||
* Timestamp updates *
|
||||
********************/
|
||||
@@ -4209,3 +4504,87 @@ channel_set_circid_type(channel_t *chan,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the estimated number of bytes queued to transmit for this channel,
|
||||
* and notify the scheduler. The estimate includes both the channel queue and
|
||||
* the queue size reported by the lower layer, and an overhead estimate
|
||||
* optionally provided by the lower layer.
|
||||
*/
|
||||
|
||||
void
|
||||
channel_update_xmit_queue_size(channel_t *chan)
|
||||
{
|
||||
uint64_t queued, adj;
|
||||
double overhead;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(chan->num_bytes_queued);
|
||||
|
||||
/*
|
||||
* First, get the number of bytes we have queued without factoring in
|
||||
* lower-layer overhead.
|
||||
*/
|
||||
queued = chan->num_bytes_queued(chan) + chan->bytes_in_queue;
|
||||
/* Next, adjust by the overhead factor, if any is available */
|
||||
if (chan->get_overhead_estimate) {
|
||||
overhead = chan->get_overhead_estimate(chan);
|
||||
if (overhead >= 1.0f) {
|
||||
queued *= overhead;
|
||||
} else {
|
||||
/* Ignore silly overhead factors */
|
||||
log_notice(LD_CHANNEL, "Ignoring silly overhead factor %f", overhead);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now, compare to the previous estimate */
|
||||
if (queued > chan->bytes_queued_for_xmit) {
|
||||
adj = queued - chan->bytes_queued_for_xmit;
|
||||
log_debug(LD_CHANNEL,
|
||||
"Increasing queue size for channel " U64_FORMAT " by " U64_FORMAT
|
||||
" from " U64_FORMAT " to " U64_FORMAT,
|
||||
U64_PRINTF_ARG(chan->global_identifier),
|
||||
U64_PRINTF_ARG(adj),
|
||||
U64_PRINTF_ARG(chan->bytes_queued_for_xmit),
|
||||
U64_PRINTF_ARG(queued));
|
||||
/* Update the channel's estimate */
|
||||
chan->bytes_queued_for_xmit = queued;
|
||||
|
||||
/* Update the global queue size estimate if appropriate */
|
||||
if (chan->state == CHANNEL_STATE_OPEN ||
|
||||
chan->state == CHANNEL_STATE_MAINT) {
|
||||
estimated_total_queue_size += adj;
|
||||
log_debug(LD_CHANNEL,
|
||||
"Increasing global queue size by " U64_FORMAT " for channel "
|
||||
U64_FORMAT ", new size is " U64_FORMAT,
|
||||
U64_PRINTF_ARG(adj), U64_PRINTF_ARG(chan->global_identifier),
|
||||
U64_PRINTF_ARG(estimated_total_queue_size));
|
||||
/* Tell the scheduler we're increasing the queue size */
|
||||
scheduler_adjust_queue_size(chan, 1, adj);
|
||||
}
|
||||
} else if (queued < chan->bytes_queued_for_xmit) {
|
||||
adj = chan->bytes_queued_for_xmit - queued;
|
||||
log_debug(LD_CHANNEL,
|
||||
"Decreasing queue size for channel " U64_FORMAT " by " U64_FORMAT
|
||||
" from " U64_FORMAT " to " U64_FORMAT,
|
||||
U64_PRINTF_ARG(chan->global_identifier),
|
||||
U64_PRINTF_ARG(adj),
|
||||
U64_PRINTF_ARG(chan->bytes_queued_for_xmit),
|
||||
U64_PRINTF_ARG(queued));
|
||||
/* Update the channel's estimate */
|
||||
chan->bytes_queued_for_xmit = queued;
|
||||
|
||||
/* Update the global queue size estimate if appropriate */
|
||||
if (chan->state == CHANNEL_STATE_OPEN ||
|
||||
chan->state == CHANNEL_STATE_MAINT) {
|
||||
estimated_total_queue_size -= adj;
|
||||
log_debug(LD_CHANNEL,
|
||||
"Decreasing global queue size by " U64_FORMAT " for channel "
|
||||
U64_FORMAT ", new size is " U64_FORMAT,
|
||||
U64_PRINTF_ARG(adj), U64_PRINTF_ARG(chan->global_identifier),
|
||||
U64_PRINTF_ARG(estimated_total_queue_size));
|
||||
/* Tell the scheduler we're decreasing the queue size */
|
||||
scheduler_adjust_queue_size(chan, -1, adj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+82
-5
@@ -57,6 +57,32 @@ struct channel_s {
|
||||
CHANNEL_CLOSE_FOR_ERROR
|
||||
} reason_for_closing;
|
||||
|
||||
/** State variable for use by the scheduler */
|
||||
enum {
|
||||
/*
|
||||
* The channel is not open, or it has a full output buffer but no queued
|
||||
* cells.
|
||||
*/
|
||||
SCHED_CHAN_IDLE = 0,
|
||||
/*
|
||||
* The channel has space on its output buffer to write, but no queued
|
||||
* cells.
|
||||
*/
|
||||
SCHED_CHAN_WAITING_FOR_CELLS,
|
||||
/*
|
||||
* The scheduler has queued cells but no output buffer space to write.
|
||||
*/
|
||||
SCHED_CHAN_WAITING_TO_WRITE,
|
||||
/*
|
||||
* The scheduler has both queued cells and output buffer space, and is
|
||||
* eligible for the scheduler loop.
|
||||
*/
|
||||
SCHED_CHAN_PENDING
|
||||
} scheduler_state;
|
||||
|
||||
/** Heap index for use by the scheduler */
|
||||
int sched_heap_idx;
|
||||
|
||||
/** Timestamps for both cell channels and listeners */
|
||||
time_t timestamp_created; /* Channel created */
|
||||
time_t timestamp_active; /* Any activity */
|
||||
@@ -79,6 +105,11 @@ struct channel_s {
|
||||
/* Methods implemented by the lower layer */
|
||||
|
||||
/**
|
||||
* Ask the lower layer for an estimate of the average overhead for
|
||||
* transmissions on this channel.
|
||||
*/
|
||||
double (*get_overhead_estimate)(channel_t *);
|
||||
/*
|
||||
* Ask the underlying transport what the remote endpoint address is, in
|
||||
* a tor_addr_t. This is optional and subclasses may leave this NULL.
|
||||
* If they implement it, they should write the address out to the
|
||||
@@ -110,7 +141,11 @@ struct channel_s {
|
||||
int (*matches_extend_info)(channel_t *, extend_info_t *);
|
||||
/** Check if this channel matches a target address when extending */
|
||||
int (*matches_target)(channel_t *, const tor_addr_t *);
|
||||
/** Write a cell to an open channel */
|
||||
/* Ask the lower layer how many bytes it has queued but not yet sent */
|
||||
size_t (*num_bytes_queued)(channel_t *);
|
||||
/* Ask the lower layer how many cells can be written */
|
||||
int (*num_cells_writeable)(channel_t *);
|
||||
/* Write a cell to an open channel */
|
||||
int (*write_cell)(channel_t *, cell_t *);
|
||||
/** Write a packed cell to an open channel */
|
||||
int (*write_packed_cell)(channel_t *, packed_cell_t *);
|
||||
@@ -198,8 +233,16 @@ struct channel_s {
|
||||
uint64_t dirreq_id;
|
||||
|
||||
/** Channel counters for cell channels */
|
||||
uint64_t n_cells_recved;
|
||||
uint64_t n_cells_xmitted;
|
||||
uint64_t n_cells_recved, n_bytes_recved;
|
||||
uint64_t n_cells_xmitted, n_bytes_xmitted;
|
||||
|
||||
/** Our current contribution to the scheduler's total xmit queue */
|
||||
uint64_t bytes_queued_for_xmit;
|
||||
|
||||
/** Number of bytes in this channel's cell queue; does not include
|
||||
* lower-layer queueing.
|
||||
*/
|
||||
uint64_t bytes_in_queue;
|
||||
};
|
||||
|
||||
struct channel_listener_s {
|
||||
@@ -311,6 +354,34 @@ void channel_set_cmux_policy_everywhere(circuitmux_policy_t *pol);
|
||||
|
||||
#ifdef TOR_CHANNEL_INTERNAL_
|
||||
|
||||
#ifdef CHANNEL_PRIVATE_
|
||||
/* Cell queue structure (here rather than channel.c for test suite use) */
|
||||
|
||||
typedef struct cell_queue_entry_s cell_queue_entry_t;
|
||||
struct cell_queue_entry_s {
|
||||
TOR_SIMPLEQ_ENTRY(cell_queue_entry_s) next;
|
||||
enum {
|
||||
CELL_QUEUE_FIXED,
|
||||
CELL_QUEUE_VAR,
|
||||
CELL_QUEUE_PACKED
|
||||
} type;
|
||||
union {
|
||||
struct {
|
||||
cell_t *cell;
|
||||
} fixed;
|
||||
struct {
|
||||
var_cell_t *var_cell;
|
||||
} var;
|
||||
struct {
|
||||
packed_cell_t *packed_cell;
|
||||
} packed;
|
||||
} u;
|
||||
};
|
||||
|
||||
/* Cell queue functions for benefit of test suite */
|
||||
STATIC int chan_cell_queue_len(const chan_cell_queue_t *queue);
|
||||
#endif
|
||||
|
||||
/* Channel operations for subclasses and internal use only */
|
||||
|
||||
/* Initialize a newly allocated channel - do this first in subclass
|
||||
@@ -384,7 +455,8 @@ void channel_queue_var_cell(channel_t *chan, var_cell_t *var_cell);
|
||||
void channel_flush_cells(channel_t *chan);
|
||||
|
||||
/* Request from lower layer for more cells if available */
|
||||
ssize_t channel_flush_some_cells(channel_t *chan, ssize_t num_cells);
|
||||
MOCK_DECL(ssize_t, channel_flush_some_cells,
|
||||
(channel_t *chan, ssize_t num_cells));
|
||||
|
||||
/* Query if data available on this channel */
|
||||
int channel_more_to_flush(channel_t *chan);
|
||||
@@ -435,7 +507,7 @@ channel_t * channel_next_with_digest(channel_t *chan);
|
||||
*/
|
||||
|
||||
const char * channel_describe_transport(channel_t *chan);
|
||||
void channel_dump_statistics(channel_t *chan, int severity);
|
||||
MOCK_DECL(void, channel_dump_statistics, (channel_t *chan, int severity));
|
||||
void channel_dump_transport_statistics(channel_t *chan, int severity);
|
||||
const char * channel_get_actual_remote_descr(channel_t *chan);
|
||||
const char * channel_get_actual_remote_address(channel_t *chan);
|
||||
@@ -458,6 +530,7 @@ unsigned int channel_num_circuits(channel_t *chan);
|
||||
void channel_set_circid_type(channel_t *chan, crypto_pk_t *identity_rcvd,
|
||||
int consider_identity);
|
||||
void channel_timestamp_client(channel_t *chan);
|
||||
void channel_update_xmit_queue_size(channel_t *chan);
|
||||
|
||||
const char * channel_listener_describe_transport(channel_listener_t *chan_l);
|
||||
void channel_listener_dump_statistics(channel_listener_t *chan_l,
|
||||
@@ -465,6 +538,10 @@ void channel_listener_dump_statistics(channel_listener_t *chan_l,
|
||||
void channel_listener_dump_transport_statistics(channel_listener_t *chan_l,
|
||||
int severity);
|
||||
|
||||
/* Flow control queries */
|
||||
uint64_t channel_get_global_queue_estimate(void);
|
||||
int channel_num_cells_writeable(channel_t *chan);
|
||||
|
||||
/* Timestamp queries */
|
||||
time_t channel_when_created(channel_t *chan);
|
||||
time_t channel_when_last_active(channel_t *chan);
|
||||
|
||||
+92
-52
@@ -25,6 +25,7 @@
|
||||
#include "relay.h"
|
||||
#include "router.h"
|
||||
#include "routerlist.h"
|
||||
#include "scheduler.h"
|
||||
|
||||
/** How many CELL_PADDING cells have we received, ever? */
|
||||
uint64_t stats_n_padding_cells_processed = 0;
|
||||
@@ -54,6 +55,7 @@ static void channel_tls_common_init(channel_tls_t *tlschan);
|
||||
static void channel_tls_close_method(channel_t *chan);
|
||||
static const char * channel_tls_describe_transport_method(channel_t *chan);
|
||||
static void channel_tls_free_method(channel_t *chan);
|
||||
static double channel_tls_get_overhead_estimate_method(channel_t *chan);
|
||||
static int
|
||||
channel_tls_get_remote_addr_method(channel_t *chan, tor_addr_t *addr_out);
|
||||
static int
|
||||
@@ -67,6 +69,8 @@ channel_tls_matches_extend_info_method(channel_t *chan,
|
||||
extend_info_t *extend_info);
|
||||
static int channel_tls_matches_target_method(channel_t *chan,
|
||||
const tor_addr_t *target);
|
||||
static int channel_tls_num_cells_writeable_method(channel_t *chan);
|
||||
static size_t channel_tls_num_bytes_queued_method(channel_t *chan);
|
||||
static int channel_tls_write_cell_method(channel_t *chan,
|
||||
cell_t *cell);
|
||||
static int channel_tls_write_packed_cell_method(channel_t *chan,
|
||||
@@ -116,6 +120,7 @@ channel_tls_common_init(channel_tls_t *tlschan)
|
||||
chan->close = channel_tls_close_method;
|
||||
chan->describe_transport = channel_tls_describe_transport_method;
|
||||
chan->free = channel_tls_free_method;
|
||||
chan->get_overhead_estimate = channel_tls_get_overhead_estimate_method;
|
||||
chan->get_remote_addr = channel_tls_get_remote_addr_method;
|
||||
chan->get_remote_descr = channel_tls_get_remote_descr_method;
|
||||
chan->get_transport_name = channel_tls_get_transport_name_method;
|
||||
@@ -123,6 +128,8 @@ channel_tls_common_init(channel_tls_t *tlschan)
|
||||
chan->is_canonical = channel_tls_is_canonical_method;
|
||||
chan->matches_extend_info = channel_tls_matches_extend_info_method;
|
||||
chan->matches_target = channel_tls_matches_target_method;
|
||||
chan->num_bytes_queued = channel_tls_num_bytes_queued_method;
|
||||
chan->num_cells_writeable = channel_tls_num_cells_writeable_method;
|
||||
chan->write_cell = channel_tls_write_cell_method;
|
||||
chan->write_packed_cell = channel_tls_write_packed_cell_method;
|
||||
chan->write_var_cell = channel_tls_write_var_cell_method;
|
||||
@@ -434,6 +441,40 @@ channel_tls_free_method(channel_t *chan)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an estimate of the average TLS overhead for the upper layer
|
||||
*/
|
||||
|
||||
static double
|
||||
channel_tls_get_overhead_estimate_method(channel_t *chan)
|
||||
{
|
||||
double overhead = 1.0f;
|
||||
channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
|
||||
|
||||
tor_assert(tlschan);
|
||||
tor_assert(tlschan->conn);
|
||||
|
||||
/* Just return 1.0f if we don't have sensible data */
|
||||
if (tlschan->conn->bytes_xmitted > 0 &&
|
||||
tlschan->conn->bytes_xmitted_by_tls >=
|
||||
tlschan->conn->bytes_xmitted) {
|
||||
overhead = ((double)(tlschan->conn->bytes_xmitted_by_tls)) /
|
||||
((double)(tlschan->conn->bytes_xmitted));
|
||||
|
||||
/*
|
||||
* Never estimate more than 2.0; otherwise we get silly large estimates
|
||||
* at the very start of a new TLS connection.
|
||||
*/
|
||||
if (overhead > 2.0f) overhead = 2.0f;
|
||||
}
|
||||
|
||||
log_debug(LD_CHANNEL,
|
||||
"Estimated overhead ratio for TLS chan " U64_FORMAT " is %f",
|
||||
U64_PRINTF_ARG(chan->global_identifier), overhead);
|
||||
|
||||
return overhead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the remote address of a channel_tls_t
|
||||
*
|
||||
@@ -672,6 +713,53 @@ channel_tls_matches_target_method(channel_t *chan,
|
||||
return tor_addr_eq(&(tlschan->conn->real_addr), target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the upper layer how many bytes we have queued and not yet
|
||||
* sent.
|
||||
*/
|
||||
|
||||
static size_t
|
||||
channel_tls_num_bytes_queued_method(channel_t *chan)
|
||||
{
|
||||
channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
|
||||
|
||||
tor_assert(tlschan);
|
||||
tor_assert(tlschan->conn);
|
||||
|
||||
return connection_get_outbuf_len(TO_CONN(tlschan->conn));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the upper layer how many cells we can accept to write
|
||||
*
|
||||
* This implements the num_cells_writeable method for channel_tls_t; it
|
||||
* returns an estimate of the number of cells we can accept with
|
||||
* channel_tls_write_*_cell().
|
||||
*/
|
||||
|
||||
static int
|
||||
channel_tls_num_cells_writeable_method(channel_t *chan)
|
||||
{
|
||||
size_t outbuf_len;
|
||||
ssize_t n;
|
||||
channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
|
||||
size_t cell_network_size;
|
||||
|
||||
tor_assert(tlschan);
|
||||
tor_assert(tlschan->conn);
|
||||
|
||||
cell_network_size = get_cell_network_size(tlschan->conn->wide_circ_ids);
|
||||
outbuf_len = connection_get_outbuf_len(TO_CONN(tlschan->conn));
|
||||
/* Get the number of cells */
|
||||
n = CEIL_DIV(OR_CONN_HIGHWATER - outbuf_len, cell_network_size);
|
||||
if (n < 0) n = 0;
|
||||
#if SIZEOF_SIZE_T > SIZEOF_INT
|
||||
if (n > INT_MAX) n = INT_MAX;
|
||||
#endif
|
||||
|
||||
return (int)n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a cell to a channel_tls_t
|
||||
*
|
||||
@@ -867,6 +955,10 @@ channel_tls_handle_state_change_on_orconn(channel_tls_t *chan,
|
||||
* CHANNEL_STATE_MAINT on this.
|
||||
*/
|
||||
channel_change_state(base_chan, CHANNEL_STATE_OPEN);
|
||||
/* We might have just become writeable; check and tell the scheduler */
|
||||
if (connection_or_num_cells_writeable(conn) > 0) {
|
||||
scheduler_channel_wants_writes(base_chan);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Not open, so from CHANNEL_STATE_OPEN we go to CHANNEL_STATE_MAINT,
|
||||
@@ -878,58 +970,6 @@ channel_tls_handle_state_change_on_orconn(channel_tls_t *chan,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush cells from a channel_tls_t
|
||||
*
|
||||
* Try to flush up to about num_cells cells, and return how many we flushed.
|
||||
*/
|
||||
|
||||
ssize_t
|
||||
channel_tls_flush_some_cells(channel_tls_t *chan, ssize_t num_cells)
|
||||
{
|
||||
ssize_t flushed = 0;
|
||||
|
||||
tor_assert(chan);
|
||||
|
||||
if (flushed >= num_cells) goto done;
|
||||
|
||||
/*
|
||||
* If channel_tls_t ever buffers anything below the channel_t layer, flush
|
||||
* that first here.
|
||||
*/
|
||||
|
||||
flushed += channel_flush_some_cells(TLS_CHAN_TO_BASE(chan),
|
||||
num_cells - flushed);
|
||||
|
||||
/*
|
||||
* If channel_tls_t ever buffers anything below the channel_t layer, check
|
||||
* how much we actually got and push it on down here.
|
||||
*/
|
||||
|
||||
done:
|
||||
return flushed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a channel_tls_t has anything to flush
|
||||
*
|
||||
* Return true if there is any more to flush on this channel (cells in queue
|
||||
* or active circuits).
|
||||
*/
|
||||
|
||||
int
|
||||
channel_tls_more_to_flush(channel_tls_t *chan)
|
||||
{
|
||||
tor_assert(chan);
|
||||
|
||||
/*
|
||||
* If channel_tls_t ever buffers anything below channel_t, the
|
||||
* check for that should go here first.
|
||||
*/
|
||||
|
||||
return channel_more_to_flush(TLS_CHAN_TO_BASE(chan));
|
||||
}
|
||||
|
||||
#ifdef KEEP_TIMING_STATS
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,8 +40,6 @@ channel_t * channel_tls_to_base(channel_tls_t *tlschan);
|
||||
channel_tls_t * channel_tls_from_base(channel_t *chan);
|
||||
|
||||
/* Things for connection_or.c to call back into */
|
||||
ssize_t channel_tls_flush_some_cells(channel_tls_t *chan, ssize_t num_cells);
|
||||
int channel_tls_more_to_flush(channel_tls_t *chan);
|
||||
void channel_tls_handle_cell(cell_t *cell, or_connection_t *conn);
|
||||
void channel_tls_handle_state_change_on_orconn(channel_tls_t *chan,
|
||||
or_connection_t *conn,
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "or.h"
|
||||
#include "channel.h"
|
||||
#include "circpathbias.h"
|
||||
#define CIRCUITBUILD_PRIVATE
|
||||
#include "circuitbuild.h"
|
||||
#include "circuitlist.h"
|
||||
#include "circuitstats.h"
|
||||
@@ -943,9 +944,9 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
|
||||
circuit_rep_hist_note_result(circ);
|
||||
circuit_has_opened(circ); /* do other actions as necessary */
|
||||
|
||||
if (!can_complete_circuit && !circ->build_state->onehop_tunnel) {
|
||||
if (!have_completed_a_circuit() && !circ->build_state->onehop_tunnel) {
|
||||
const or_options_t *options = get_options();
|
||||
can_complete_circuit=1;
|
||||
note_that_we_completed_a_circuit();
|
||||
/* FFFF Log a count of known routers here */
|
||||
log_notice(LD_GENERAL,
|
||||
"Tor has successfully opened a circuit. "
|
||||
@@ -1033,7 +1034,8 @@ circuit_note_clock_jumped(int seconds_elapsed)
|
||||
seconds_elapsed >=0 ? "forward" : "backward");
|
||||
control_event_general_status(LOG_WARN, "CLOCK_JUMPED TIME=%d",
|
||||
seconds_elapsed);
|
||||
can_complete_circuit=0; /* so it'll log when it works again */
|
||||
/* so we log when it works again */
|
||||
note_that_we_maybe_cant_complete_circuits();
|
||||
control_event_client_status(severity, "CIRCUIT_NOT_ESTABLISHED REASON=%s",
|
||||
"CLOCK_JUMPED");
|
||||
circuit_mark_all_unused_circs();
|
||||
@@ -1548,7 +1550,7 @@ choose_good_exit_server_general(int need_uptime, int need_capacity)
|
||||
* -1 means "Don't use this router at all."
|
||||
*/
|
||||
the_nodes = nodelist_get_list();
|
||||
n_supported = tor_calloc(sizeof(int), smartlist_len(the_nodes));
|
||||
n_supported = tor_calloc(smartlist_len(the_nodes), sizeof(int));
|
||||
SMARTLIST_FOREACH_BEGIN(the_nodes, const node_t *, node) {
|
||||
const int i = node_sl_idx;
|
||||
if (router_digest_is_me(node->identity)) {
|
||||
|
||||
+26
-20
@@ -302,8 +302,8 @@ channel_note_destroy_pending(channel_t *chan, circid_t id)
|
||||
|
||||
/** Called to indicate that a DESTROY is no longer pending on <b>chan</b> with
|
||||
* circuit ID <b>id</b> -- typically, because it has been sent. */
|
||||
void
|
||||
channel_note_destroy_not_pending(channel_t *chan, circid_t id)
|
||||
MOCK_IMPL(void, channel_note_destroy_not_pending,
|
||||
(channel_t *chan, circid_t id))
|
||||
{
|
||||
circuit_t *circ = circuit_get_by_circid_channel_even_if_marked(id,chan);
|
||||
if (circ) {
|
||||
@@ -1719,30 +1719,36 @@ circuit_mark_for_close_, (circuit_t *circ, int reason, int line,
|
||||
tor_assert(circ->state == CIRCUIT_STATE_OPEN);
|
||||
tor_assert(ocirc->build_state->chosen_exit);
|
||||
tor_assert(ocirc->rend_data);
|
||||
/* treat this like getting a nack from it */
|
||||
log_info(LD_REND, "Failed intro circ %s to %s (awaiting ack). %s",
|
||||
safe_str_client(ocirc->rend_data->onion_address),
|
||||
safe_str_client(build_state_get_exit_nickname(ocirc->build_state)),
|
||||
timed_out ? "Recording timeout." : "Removing from descriptor.");
|
||||
rend_client_report_intro_point_failure(ocirc->build_state->chosen_exit,
|
||||
ocirc->rend_data,
|
||||
timed_out ?
|
||||
INTRO_POINT_FAILURE_TIMEOUT :
|
||||
INTRO_POINT_FAILURE_GENERIC);
|
||||
if (orig_reason != END_CIRC_REASON_IP_NOW_REDUNDANT) {
|
||||
/* treat this like getting a nack from it */
|
||||
log_info(LD_REND, "Failed intro circ %s to %s (awaiting ack). %s",
|
||||
safe_str_client(ocirc->rend_data->onion_address),
|
||||
safe_str_client(build_state_get_exit_nickname(ocirc->build_state)),
|
||||
timed_out ? "Recording timeout." : "Removing from descriptor.");
|
||||
rend_client_report_intro_point_failure(ocirc->build_state->chosen_exit,
|
||||
ocirc->rend_data,
|
||||
timed_out ?
|
||||
INTRO_POINT_FAILURE_TIMEOUT :
|
||||
INTRO_POINT_FAILURE_GENERIC);
|
||||
}
|
||||
} else if (circ->purpose == CIRCUIT_PURPOSE_C_INTRODUCING &&
|
||||
reason != END_CIRC_REASON_TIMEOUT) {
|
||||
origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
|
||||
if (ocirc->build_state->chosen_exit && ocirc->rend_data) {
|
||||
log_info(LD_REND, "Failed intro circ %s to %s "
|
||||
"(building circuit to intro point). "
|
||||
"Marking intro point as possibly unreachable.",
|
||||
safe_str_client(ocirc->rend_data->onion_address),
|
||||
safe_str_client(build_state_get_exit_nickname(ocirc->build_state)));
|
||||
rend_client_report_intro_point_failure(ocirc->build_state->chosen_exit,
|
||||
ocirc->rend_data,
|
||||
INTRO_POINT_FAILURE_UNREACHABLE);
|
||||
if (orig_reason != END_CIRC_REASON_IP_NOW_REDUNDANT) {
|
||||
log_info(LD_REND, "Failed intro circ %s to %s "
|
||||
"(building circuit to intro point). "
|
||||
"Marking intro point as possibly unreachable.",
|
||||
safe_str_client(ocirc->rend_data->onion_address),
|
||||
safe_str_client(build_state_get_exit_nickname(
|
||||
ocirc->build_state)));
|
||||
rend_client_report_intro_point_failure(ocirc->build_state->chosen_exit,
|
||||
ocirc->rend_data,
|
||||
INTRO_POINT_FAILURE_UNREACHABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (circ->n_chan) {
|
||||
circuit_clear_cell_queue(circ, circ->n_chan);
|
||||
/* Only send destroy if the channel isn't closing anyway */
|
||||
|
||||
@@ -72,7 +72,8 @@ void circuit_free_all(void);
|
||||
void circuits_handle_oom(size_t current_allocation);
|
||||
|
||||
void channel_note_destroy_pending(channel_t *chan, circid_t id);
|
||||
void channel_note_destroy_not_pending(channel_t *chan, circid_t id);
|
||||
MOCK_DECL(void, channel_note_destroy_not_pending,
|
||||
(channel_t *chan, circid_t id));
|
||||
|
||||
#ifdef CIRCUITLIST_PRIVATE
|
||||
STATIC void circuit_free(circuit_t *circ);
|
||||
|
||||
+52
-4
@@ -621,8 +621,8 @@ circuitmux_clear_policy(circuitmux_t *cmux)
|
||||
* Return the policy currently installed on a circuitmux_t
|
||||
*/
|
||||
|
||||
const circuitmux_policy_t *
|
||||
circuitmux_get_policy(circuitmux_t *cmux)
|
||||
MOCK_IMPL(const circuitmux_policy_t *,
|
||||
circuitmux_get_policy, (circuitmux_t *cmux))
|
||||
{
|
||||
tor_assert(cmux);
|
||||
|
||||
@@ -896,8 +896,8 @@ circuitmux_num_cells_for_circuit(circuitmux_t *cmux, circuit_t *circ)
|
||||
* Query total number of available cells on a circuitmux
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
circuitmux_num_cells(circuitmux_t *cmux)
|
||||
MOCK_IMPL(unsigned int,
|
||||
circuitmux_num_cells, (circuitmux_t *cmux))
|
||||
{
|
||||
tor_assert(cmux);
|
||||
|
||||
@@ -1951,3 +1951,51 @@ circuitmux_count_queued_destroy_cells(const channel_t *chan,
|
||||
return n_destroy_cells;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare cmuxes to see which is more preferred; return < 0 if
|
||||
* cmux_1 has higher priority (i.e., cmux_1 < cmux_2 in the scheduler's
|
||||
* sort order), > 0 if cmux_2 has higher priority, or 0 if they are
|
||||
* equally preferred.
|
||||
*
|
||||
* If the cmuxes have different cmux policies or the policy does not
|
||||
* support the cmp_cmux method, return 0.
|
||||
*/
|
||||
|
||||
MOCK_IMPL(int,
|
||||
circuitmux_compare_muxes, (circuitmux_t *cmux_1, circuitmux_t *cmux_2))
|
||||
{
|
||||
const circuitmux_policy_t *policy;
|
||||
|
||||
tor_assert(cmux_1);
|
||||
tor_assert(cmux_2);
|
||||
|
||||
if (cmux_1 == cmux_2) {
|
||||
/* Equivalent because they're the same cmux */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cmux_1->policy && cmux_2->policy) {
|
||||
if (cmux_1->policy == cmux_2->policy) {
|
||||
policy = cmux_1->policy;
|
||||
|
||||
if (policy->cmp_cmux) {
|
||||
/* Okay, we can compare! */
|
||||
return policy->cmp_cmux(cmux_1, cmux_1->policy_data,
|
||||
cmux_2, cmux_2->policy_data);
|
||||
} else {
|
||||
/*
|
||||
* Equivalent because the policy doesn't know how to compare between
|
||||
* muxes.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* Equivalent because they have different policies */
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* Equivalent because one or both are missing a policy */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-2
@@ -57,6 +57,9 @@ struct circuitmux_policy_s {
|
||||
/* Choose a circuit */
|
||||
circuit_t * (*pick_active_circuit)(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data);
|
||||
/* Optional: channel comparator for use by the scheduler */
|
||||
int (*cmp_cmux)(circuitmux_t *cmux_1, circuitmux_policy_data_t *pol_data_1,
|
||||
circuitmux_t *cmux_2, circuitmux_policy_data_t *pol_data_2);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -105,7 +108,8 @@ void circuitmux_free(circuitmux_t *cmux);
|
||||
|
||||
/* Policy control */
|
||||
void circuitmux_clear_policy(circuitmux_t *cmux);
|
||||
const circuitmux_policy_t * circuitmux_get_policy(circuitmux_t *cmux);
|
||||
MOCK_DECL(const circuitmux_policy_t *,
|
||||
circuitmux_get_policy, (circuitmux_t *cmux));
|
||||
void circuitmux_set_policy(circuitmux_t *cmux,
|
||||
const circuitmux_policy_t *pol);
|
||||
|
||||
@@ -117,7 +121,7 @@ int circuitmux_is_circuit_attached(circuitmux_t *cmux, circuit_t *circ);
|
||||
int circuitmux_is_circuit_active(circuitmux_t *cmux, circuit_t *circ);
|
||||
unsigned int circuitmux_num_cells_for_circuit(circuitmux_t *cmux,
|
||||
circuit_t *circ);
|
||||
unsigned int circuitmux_num_cells(circuitmux_t *cmux);
|
||||
MOCK_DECL(unsigned int, circuitmux_num_cells, (circuitmux_t *cmux));
|
||||
unsigned int circuitmux_num_circuits(circuitmux_t *cmux);
|
||||
unsigned int circuitmux_num_active_circuits(circuitmux_t *cmux);
|
||||
|
||||
@@ -148,5 +152,9 @@ void circuitmux_append_destroy_cell(channel_t *chan,
|
||||
void circuitmux_mark_destroyed_circids_usable(circuitmux_t *cmux,
|
||||
channel_t *chan);
|
||||
|
||||
/* Optional interchannel comparisons for scheduling */
|
||||
MOCK_DECL(int, circuitmux_compare_muxes,
|
||||
(circuitmux_t *cmux_1, circuitmux_t *cmux_2));
|
||||
|
||||
#endif /* TOR_CIRCUITMUX_H */
|
||||
|
||||
|
||||
@@ -187,6 +187,9 @@ ewma_notify_xmit_cells(circuitmux_t *cmux,
|
||||
static circuit_t *
|
||||
ewma_pick_active_circuit(circuitmux_t *cmux,
|
||||
circuitmux_policy_data_t *pol_data);
|
||||
static int
|
||||
ewma_cmp_cmux(circuitmux_t *cmux_1, circuitmux_policy_data_t *pol_data_1,
|
||||
circuitmux_t *cmux_2, circuitmux_policy_data_t *pol_data_2);
|
||||
|
||||
/*** EWMA global variables ***/
|
||||
|
||||
@@ -209,7 +212,8 @@ circuitmux_policy_t ewma_policy = {
|
||||
/*.notify_circ_inactive =*/ ewma_notify_circ_inactive,
|
||||
/*.notify_set_n_cells =*/ NULL, /* EWMA doesn't need this */
|
||||
/*.notify_xmit_cells =*/ ewma_notify_xmit_cells,
|
||||
/*.pick_active_circuit =*/ ewma_pick_active_circuit
|
||||
/*.pick_active_circuit =*/ ewma_pick_active_circuit,
|
||||
/*.cmp_cmux =*/ ewma_cmp_cmux
|
||||
};
|
||||
|
||||
/*** EWMA method implementations using the below EWMA helper functions ***/
|
||||
@@ -453,6 +457,58 @@ ewma_pick_active_circuit(circuitmux_t *cmux,
|
||||
return circ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two EWMA cmuxes, and return -1, 0 or 1 to indicate which should
|
||||
* be more preferred - see circuitmux_compare_muxes() of circuitmux.c.
|
||||
*/
|
||||
|
||||
static int
|
||||
ewma_cmp_cmux(circuitmux_t *cmux_1, circuitmux_policy_data_t *pol_data_1,
|
||||
circuitmux_t *cmux_2, circuitmux_policy_data_t *pol_data_2)
|
||||
{
|
||||
ewma_policy_data_t *p1 = NULL, *p2 = NULL;
|
||||
cell_ewma_t *ce1 = NULL, *ce2 = NULL;
|
||||
|
||||
tor_assert(cmux_1);
|
||||
tor_assert(pol_data_1);
|
||||
tor_assert(cmux_2);
|
||||
tor_assert(pol_data_2);
|
||||
|
||||
p1 = TO_EWMA_POL_DATA(pol_data_1);
|
||||
p2 = TO_EWMA_POL_DATA(pol_data_1);
|
||||
|
||||
if (p1 != p2) {
|
||||
/* Get the head cell_ewma_t from each queue */
|
||||
if (smartlist_len(p1->active_circuit_pqueue) > 0) {
|
||||
ce1 = smartlist_get(p1->active_circuit_pqueue, 0);
|
||||
}
|
||||
|
||||
if (smartlist_len(p2->active_circuit_pqueue) > 0) {
|
||||
ce2 = smartlist_get(p2->active_circuit_pqueue, 0);
|
||||
}
|
||||
|
||||
/* Got both of them? */
|
||||
if (ce1 != NULL && ce2 != NULL) {
|
||||
/* Pick whichever one has the better best circuit */
|
||||
return compare_cell_ewma_counts(ce1, ce2);
|
||||
} else {
|
||||
if (ce1 != NULL ) {
|
||||
/* We only have a circuit on cmux_1, so prefer it */
|
||||
return -1;
|
||||
} else if (ce2 != NULL) {
|
||||
/* We only have a circuit on cmux_2, so prefer it */
|
||||
return 1;
|
||||
} else {
|
||||
/* No circuits at all; no preference */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* We got identical params */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Helper for sorting cell_ewma_t values in their priority queue. */
|
||||
static int
|
||||
compare_cell_ewma_counts(const void *p1, const void *p2)
|
||||
|
||||
@@ -404,7 +404,7 @@ circuit_build_times_new_consensus_params(circuit_build_times_t *cbt,
|
||||
* distress anyway, so memory correctness here is paramount over
|
||||
* doing acrobatics to preserve the array.
|
||||
*/
|
||||
recent_circs = tor_calloc(sizeof(int8_t), num);
|
||||
recent_circs = tor_calloc(num, sizeof(int8_t));
|
||||
if (cbt->liveness.timeouts_after_firsthop &&
|
||||
cbt->liveness.num_recent_circs > 0) {
|
||||
memcpy(recent_circs, cbt->liveness.timeouts_after_firsthop,
|
||||
@@ -508,7 +508,7 @@ circuit_build_times_init(circuit_build_times_t *cbt)
|
||||
cbt->liveness.num_recent_circs =
|
||||
circuit_build_times_recent_circuit_count(NULL);
|
||||
cbt->liveness.timeouts_after_firsthop =
|
||||
tor_calloc(sizeof(int8_t), cbt->liveness.num_recent_circs);
|
||||
tor_calloc(cbt->liveness.num_recent_circs, sizeof(int8_t));
|
||||
} else {
|
||||
cbt->liveness.num_recent_circs = 0;
|
||||
cbt->liveness.timeouts_after_firsthop = NULL;
|
||||
@@ -873,7 +873,7 @@ circuit_build_times_parse_state(circuit_build_times_t *cbt,
|
||||
}
|
||||
|
||||
/* build_time_t 0 means uninitialized */
|
||||
loaded_times = tor_calloc(sizeof(build_time_t), state->TotalBuildTimes);
|
||||
loaded_times = tor_calloc(state->TotalBuildTimes, sizeof(build_time_t));
|
||||
|
||||
for (line = state->BuildtimeHistogram; line; line = line->next) {
|
||||
smartlist_t *args = smartlist_new();
|
||||
|
||||
+6
-6
@@ -200,7 +200,7 @@ circuit_is_better(const origin_circuit_t *oa, const origin_circuit_t *ob,
|
||||
return 1;
|
||||
} else {
|
||||
if (a->timestamp_dirty ||
|
||||
timercmp(&a->timestamp_began, &b->timestamp_began, >))
|
||||
timercmp(&a->timestamp_began, &b->timestamp_began, OP_GT))
|
||||
return 1;
|
||||
if (ob->build_state->is_internal)
|
||||
/* XXX023 what the heck is this internal thing doing here. I
|
||||
@@ -514,7 +514,7 @@ circuit_expire_building(void)
|
||||
if (TO_ORIGIN_CIRCUIT(victim)->hs_circ_has_timed_out)
|
||||
cutoff = hs_extremely_old_cutoff;
|
||||
|
||||
if (timercmp(&victim->timestamp_began, &cutoff, >))
|
||||
if (timercmp(&victim->timestamp_began, &cutoff, OP_GT))
|
||||
continue; /* it's still young, leave it alone */
|
||||
|
||||
/* We need to double-check the opened state here because
|
||||
@@ -524,7 +524,7 @@ circuit_expire_building(void)
|
||||
* aren't either. */
|
||||
if (!any_opened_circs && victim->state != CIRCUIT_STATE_OPEN) {
|
||||
/* It's still young enough that we wouldn't close it, right? */
|
||||
if (timercmp(&victim->timestamp_began, &close_cutoff, >)) {
|
||||
if (timercmp(&victim->timestamp_began, &close_cutoff, OP_GT)) {
|
||||
if (!TO_ORIGIN_CIRCUIT(victim)->relaxed_timeout) {
|
||||
int first_hop_succeeded = TO_ORIGIN_CIRCUIT(victim)->cpath->state
|
||||
== CPATH_STATE_OPEN;
|
||||
@@ -672,7 +672,7 @@ circuit_expire_building(void)
|
||||
* it off at, we probably had a suspend event along this codepath,
|
||||
* and we should discard the value.
|
||||
*/
|
||||
if (timercmp(&victim->timestamp_began, &extremely_old_cutoff, <)) {
|
||||
if (timercmp(&victim->timestamp_began, &extremely_old_cutoff, OP_LT)) {
|
||||
log_notice(LD_CIRC,
|
||||
"Extremely large value for circuit build timeout: %lds. "
|
||||
"Assuming clock jump. Purpose %d (%s)",
|
||||
@@ -1255,7 +1255,7 @@ circuit_expire_old_circuits_clientside(void)
|
||||
if (circ->purpose != CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
|
||||
circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
|
||||
} else if (!circ->timestamp_dirty && circ->state == CIRCUIT_STATE_OPEN) {
|
||||
if (timercmp(&circ->timestamp_began, &cutoff, <)) {
|
||||
if (timercmp(&circ->timestamp_began, &cutoff, OP_LT)) {
|
||||
if (circ->purpose == CIRCUIT_PURPOSE_C_GENERAL ||
|
||||
circ->purpose == CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT ||
|
||||
circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO ||
|
||||
@@ -2324,7 +2324,7 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn)
|
||||
tor_assert(rendcirc);
|
||||
/* one is already established, attach */
|
||||
log_info(LD_REND,
|
||||
"rend joined circ %d already here. attaching. "
|
||||
"rend joined circ %u already here. attaching. "
|
||||
"(stream %d sec old)",
|
||||
(unsigned)rendcirc->base_.n_circ_id, conn_age);
|
||||
/* Mark rendezvous circuits as 'newly dirty' every time you use
|
||||
|
||||
+143
-205
@@ -43,6 +43,7 @@
|
||||
#include "util.h"
|
||||
#include "routerlist.h"
|
||||
#include "routerset.h"
|
||||
#include "scheduler.h"
|
||||
#include "statefile.h"
|
||||
#include "transports.h"
|
||||
#include "ext_orport.h"
|
||||
@@ -262,6 +263,7 @@ static config_var_t option_vars_[] = {
|
||||
V(HashedControlPassword, LINELIST, NULL),
|
||||
V(HidServDirectoryV2, BOOL, "1"),
|
||||
VAR("HiddenServiceDir", LINELIST_S, RendConfigLines, NULL),
|
||||
VAR("HiddenServiceDirGroupReadable", LINELIST_S, RendConfigLines, NULL),
|
||||
VAR("HiddenServiceOptions",LINELIST_V, RendConfigLines, NULL),
|
||||
VAR("HiddenServicePort", LINELIST_S, RendConfigLines, NULL),
|
||||
VAR("HiddenServiceVersion",LINELIST_S, RendConfigLines, NULL),
|
||||
@@ -367,6 +369,9 @@ static config_var_t option_vars_[] = {
|
||||
V(ServerDNSSearchDomains, BOOL, "0"),
|
||||
V(ServerDNSTestAddresses, CSV,
|
||||
"www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"),
|
||||
V(SchedulerLowWaterMark__, MEMUNIT, "100 MB"),
|
||||
V(SchedulerHighWaterMark__, MEMUNIT, "101 MB"),
|
||||
V(SchedulerMaxFlushCells__, UINT, "1000"),
|
||||
V(ShutdownWaitLength, INTERVAL, "30 seconds"),
|
||||
V(SocksListenAddress, LINELIST, NULL),
|
||||
V(SocksPolicy, LINELIST, NULL),
|
||||
@@ -376,7 +381,7 @@ static config_var_t option_vars_[] = {
|
||||
OBSOLETE("StrictEntryNodes"),
|
||||
OBSOLETE("StrictExitNodes"),
|
||||
V(StrictNodes, BOOL, "0"),
|
||||
V(Support022HiddenServices, AUTOBOOL, "auto"),
|
||||
OBSOLETE("Support022HiddenServices"),
|
||||
V(TestSocks, BOOL, "0"),
|
||||
V(TokenBucketRefillInterval, MSEC_INTERVAL, "100 msec"),
|
||||
V(Tor2webMode, BOOL, "0"),
|
||||
@@ -510,12 +515,6 @@ static int options_transition_affects_workers(
|
||||
static int options_transition_affects_descriptor(
|
||||
const or_options_t *old_options, const or_options_t *new_options);
|
||||
static int check_nickname_list(char **lst, const char *name, char **msg);
|
||||
|
||||
static int parse_client_transport_line(const or_options_t *options,
|
||||
const char *line, int validate_only);
|
||||
|
||||
static int parse_server_transport_line(const or_options_t *options,
|
||||
const char *line, int validate_only);
|
||||
static char *get_bindaddr_from_transport_listen_line(const char *line,
|
||||
const char *transport);
|
||||
static int parse_dir_authority_line(const char *line,
|
||||
@@ -829,22 +828,22 @@ add_default_trusted_dir_authorities(dirinfo_type_t type)
|
||||
"moria1 orport=9101 "
|
||||
"v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
|
||||
"128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
|
||||
"tor26 orport=443 v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
|
||||
"tor26 orport=443 "
|
||||
"v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
|
||||
"86.59.21.38:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
|
||||
"dizum orport=443 v3ident=E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58 "
|
||||
"dizum orport=443 "
|
||||
"v3ident=E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58 "
|
||||
"194.109.206.212:80 7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
|
||||
"Tonga orport=443 bridge 82.94.251.203:80 "
|
||||
"4A0C CD2D DC79 9508 3D73 F5D6 6710 0C8A 5831 F16D",
|
||||
"turtles orport=9090 "
|
||||
"v3ident=27B6B5996C426270A5C95488AA5BCEB6BCC86956 "
|
||||
"76.73.17.194:9030 F397 038A DC51 3361 35E7 B80B D99C A384 4360 292B",
|
||||
"Tonga orport=443 bridge "
|
||||
"82.94.251.203:80 4A0C CD2D DC79 9508 3D73 F5D6 6710 0C8A 5831 F16D",
|
||||
"gabelmoo orport=443 "
|
||||
"v3ident=ED03BB616EB2F60BEC80151114BB25CEF515B226 "
|
||||
"131.188.40.189:80 F204 4413 DAC2 E02E 3D6B CF47 35A1 9BCA 1DE9 7281",
|
||||
"dannenberg orport=443 "
|
||||
"v3ident=585769C78764D58426B8B52B6651A5A71137189A "
|
||||
"193.23.244.244:80 7BE6 83E6 5D48 1413 21C5 ED92 F075 C553 64AC 7123",
|
||||
"urras orport=80 v3ident=80550987E1D626E3EBA5E5E75A458DE0626D088C "
|
||||
"urras orport=80 "
|
||||
"v3ident=80550987E1D626E3EBA5E5E75A458DE0626D088C "
|
||||
"208.83.223.34:443 0AD3 FA88 4D18 F89E EA2D 89C0 1937 9E0E 7FD9 4417",
|
||||
"maatuska orport=80 "
|
||||
"v3ident=49015F787433103580E3B66A1707A00E60F2D15B "
|
||||
@@ -852,6 +851,9 @@ add_default_trusted_dir_authorities(dirinfo_type_t type)
|
||||
"Faravahar orport=443 "
|
||||
"v3ident=EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97 "
|
||||
"154.35.32.5:80 CF6D 0AAF B385 BE71 B8E1 11FC 5CFF 4B47 9237 33BC",
|
||||
"longclaw orport=443 "
|
||||
"v3ident=23D15D965BC35114467363C165C4F724B64B4F66 "
|
||||
"199.254.238.52:80 74A9 1064 6BCE EFBC D2E8 74FC 1DC9 9743 0F96 8145",
|
||||
NULL
|
||||
};
|
||||
for (i=0; authorities[i]; i++) {
|
||||
@@ -1047,6 +1049,14 @@ options_act_reversible(const or_options_t *old_options, char **msg)
|
||||
if (running_tor && !libevent_initialized) {
|
||||
init_libevent(options);
|
||||
libevent_initialized = 1;
|
||||
|
||||
/*
|
||||
* Initialize the scheduler - this has to come after
|
||||
* options_init_from_torrc() sets up libevent - why yes, that seems
|
||||
* completely sensible to hide the libevent setup in the option parsing
|
||||
* code! It also needs to happen before init_keys(), so it needs to
|
||||
* happen here too. How yucky. */
|
||||
scheduler_init();
|
||||
}
|
||||
|
||||
/* Adjust the port configuration so we can launch listeners. */
|
||||
@@ -1076,6 +1086,8 @@ options_act_reversible(const or_options_t *old_options, char **msg)
|
||||
"non-control network connections. Shutting down all existing "
|
||||
"connections.");
|
||||
connection_mark_all_noncontrol_connections();
|
||||
/* We can't complete circuits until the network is re-enabled. */
|
||||
note_that_we_maybe_cant_complete_circuits();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1413,7 +1425,7 @@ options_act(const or_options_t *old_options)
|
||||
if (!options->DisableNetwork) {
|
||||
if (options->ClientTransportPlugin) {
|
||||
for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
|
||||
if (parse_client_transport_line(options, cl->value, 0)<0) {
|
||||
if (parse_transport_line(options, cl->value, 0, 0) < 0) {
|
||||
log_warn(LD_BUG,
|
||||
"Previously validated ClientTransportPlugin line "
|
||||
"could not be added!");
|
||||
@@ -1424,7 +1436,7 @@ options_act(const or_options_t *old_options)
|
||||
|
||||
if (options->ServerTransportPlugin && server_mode(options)) {
|
||||
for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
|
||||
if (parse_server_transport_line(options, cl->value, 0)<0) {
|
||||
if (parse_transport_line(options, cl->value, 0, 1) < 0) {
|
||||
log_warn(LD_BUG,
|
||||
"Previously validated ServerTransportPlugin line "
|
||||
"could not be added!");
|
||||
@@ -1526,6 +1538,12 @@ options_act(const or_options_t *old_options)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set up scheduler thresholds */
|
||||
scheduler_set_watermarks((uint32_t)options->SchedulerLowWaterMark__,
|
||||
(uint32_t)options->SchedulerHighWaterMark__,
|
||||
(options->SchedulerMaxFlushCells__ > 0) ?
|
||||
options->SchedulerMaxFlushCells__ : 1000);
|
||||
|
||||
/* Set up accounting */
|
||||
if (accounting_parse_options(options, 0)<0) {
|
||||
log_warn(LD_CONFIG,"Error in accounting options");
|
||||
@@ -1673,7 +1691,7 @@ options_act(const or_options_t *old_options)
|
||||
|
||||
if (server_mode(options) && !server_mode(old_options)) {
|
||||
ip_address_changed(0);
|
||||
if (can_complete_circuit || !any_predicted_circuits(time(NULL)))
|
||||
if (have_completed_a_circuit() || !any_predicted_circuits(time(NULL)))
|
||||
inform_testing_reachability();
|
||||
}
|
||||
cpuworkers_rotate();
|
||||
@@ -2269,8 +2287,8 @@ resolve_my_address(int warn_severity, const or_options_t *options,
|
||||
/** Return true iff <b>addr</b> is judged to be on the same network as us, or
|
||||
* on a private network.
|
||||
*/
|
||||
int
|
||||
is_local_addr(const tor_addr_t *addr)
|
||||
MOCK_IMPL(int,
|
||||
is_local_addr, (const tor_addr_t *addr))
|
||||
{
|
||||
if (tor_addr_is_internal(addr, 0))
|
||||
return 1;
|
||||
@@ -2623,6 +2641,17 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
||||
routerset_union(options->ExcludeExitNodesUnion_,options->ExcludeNodes);
|
||||
}
|
||||
|
||||
if (options->SchedulerLowWaterMark__ == 0 ||
|
||||
options->SchedulerLowWaterMark__ > UINT32_MAX) {
|
||||
log_warn(LD_GENERAL, "Bad SchedulerLowWaterMark__ option");
|
||||
return -1;
|
||||
} else if (options->SchedulerHighWaterMark__ <=
|
||||
options->SchedulerLowWaterMark__ ||
|
||||
options->SchedulerHighWaterMark__ > UINT32_MAX) {
|
||||
log_warn(LD_GENERAL, "Bad SchedulerHighWaterMark option");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (options->NodeFamilies) {
|
||||
options->NodeFamilySets = smartlist_new();
|
||||
for (cl = options->NodeFamilies; cl; cl = cl->next) {
|
||||
@@ -3299,12 +3328,12 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
||||
}
|
||||
|
||||
for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
|
||||
if (parse_client_transport_line(options, cl->value, 1)<0)
|
||||
if (parse_transport_line(options, cl->value, 1, 0) < 0)
|
||||
REJECT("Invalid client transport line. See logs for details.");
|
||||
}
|
||||
|
||||
for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
|
||||
if (parse_server_transport_line(options, cl->value, 1)<0)
|
||||
if (parse_transport_line(options, cl->value, 1, 1) < 0)
|
||||
REJECT("Invalid server transport line. See logs for details.");
|
||||
}
|
||||
|
||||
@@ -4768,46 +4797,52 @@ parse_bridge_line(const char *line)
|
||||
return bridge_line;
|
||||
}
|
||||
|
||||
/** Read the contents of a ClientTransportPlugin line from
|
||||
* <b>line</b>. Return 0 if the line is well-formed, and -1 if it
|
||||
* isn't.
|
||||
/** Read the contents of a ClientTransportPlugin or ServerTransportPlugin
|
||||
* line from <b>line</b>, depending on the value of <b>server</b>. Return 0
|
||||
* if the line is well-formed, and -1 if it isn't.
|
||||
*
|
||||
* If <b>validate_only</b> is 0, the line is well-formed, and the
|
||||
* transport is needed by some bridge:
|
||||
* If <b>validate_only</b> is 0, the line is well-formed, and the transport is
|
||||
* needed by some bridge:
|
||||
* - If it's an external proxy line, add the transport described in the line to
|
||||
* our internal transport list.
|
||||
* - If it's a managed proxy line, launch the managed proxy. */
|
||||
static int
|
||||
parse_client_transport_line(const or_options_t *options,
|
||||
const char *line, int validate_only)
|
||||
* - If it's a managed proxy line, launch the managed proxy.
|
||||
*/
|
||||
|
||||
STATIC int
|
||||
parse_transport_line(const or_options_t *options,
|
||||
const char *line, int validate_only,
|
||||
int server)
|
||||
{
|
||||
|
||||
smartlist_t *items = NULL;
|
||||
int r;
|
||||
char *field2=NULL;
|
||||
|
||||
const char *transports=NULL;
|
||||
smartlist_t *transport_list=NULL;
|
||||
char *addrport=NULL;
|
||||
const char *transports = NULL;
|
||||
smartlist_t *transport_list = NULL;
|
||||
char *type = NULL;
|
||||
char *addrport = NULL;
|
||||
tor_addr_t addr;
|
||||
uint16_t port = 0;
|
||||
int socks_ver=PROXY_NONE;
|
||||
int socks_ver = PROXY_NONE;
|
||||
|
||||
/* managed proxy options */
|
||||
int is_managed=0;
|
||||
char **proxy_argv=NULL;
|
||||
char **tmp=NULL;
|
||||
int is_managed = 0;
|
||||
char **proxy_argv = NULL;
|
||||
char **tmp = NULL;
|
||||
int proxy_argc, i;
|
||||
int is_useless_proxy=1;
|
||||
int is_useless_proxy = 1;
|
||||
|
||||
int line_length;
|
||||
|
||||
/* Split the line into space-separated tokens */
|
||||
items = smartlist_new();
|
||||
smartlist_split_string(items, line, NULL,
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
|
||||
line_length = smartlist_len(items);
|
||||
|
||||
line_length = smartlist_len(items);
|
||||
if (line_length < 3) {
|
||||
log_warn(LD_CONFIG, "Too few arguments on ClientTransportPlugin line.");
|
||||
log_warn(LD_CONFIG,
|
||||
"Too few arguments on %sTransportPlugin line.",
|
||||
server ? "Server" : "Client");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -4831,71 +4866,97 @@ parse_client_transport_line(const or_options_t *options,
|
||||
is_useless_proxy = 0;
|
||||
} SMARTLIST_FOREACH_END(transport_name);
|
||||
|
||||
/* field2 is either a SOCKS version or "exec" */
|
||||
field2 = smartlist_get(items, 1);
|
||||
|
||||
if (!strcmp(field2,"socks4")) {
|
||||
type = smartlist_get(items, 1);
|
||||
if (!strcmp(type, "exec")) {
|
||||
is_managed = 1;
|
||||
} else if (server && !strcmp(type, "proxy")) {
|
||||
/* 'proxy' syntax only with ServerTransportPlugin */
|
||||
is_managed = 0;
|
||||
} else if (!server && !strcmp(type, "socks4")) {
|
||||
/* 'socks4' syntax only with ClientTransportPlugin */
|
||||
is_managed = 0;
|
||||
socks_ver = PROXY_SOCKS4;
|
||||
} else if (!strcmp(field2,"socks5")) {
|
||||
} else if (!server && !strcmp(type, "socks5")) {
|
||||
/* 'socks5' syntax only with ClientTransportPlugin */
|
||||
is_managed = 0;
|
||||
socks_ver = PROXY_SOCKS5;
|
||||
} else if (!strcmp(field2,"exec")) {
|
||||
is_managed=1;
|
||||
} else {
|
||||
log_warn(LD_CONFIG, "Strange ClientTransportPlugin field '%s'.",
|
||||
field2);
|
||||
log_warn(LD_CONFIG,
|
||||
"Strange %sTransportPlugin type '%s'",
|
||||
server ? "Server" : "Client", type);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (is_managed && options->Sandbox) {
|
||||
log_warn(LD_CONFIG, "Managed proxies are not compatible with Sandbox mode."
|
||||
"(ClientTransportPlugin line was %s)", escaped(line));
|
||||
log_warn(LD_CONFIG,
|
||||
"Managed proxies are not compatible with Sandbox mode."
|
||||
"(%sTransportPlugin line was %s)",
|
||||
server ? "Server" : "Client", escaped(line));
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (is_managed) { /* managed */
|
||||
if (!validate_only && is_useless_proxy) {
|
||||
log_info(LD_GENERAL, "Pluggable transport proxy (%s) does not provide "
|
||||
"any needed transports and will not be launched.", line);
|
||||
if (is_managed) {
|
||||
/* managed */
|
||||
|
||||
if (!server && !validate_only && is_useless_proxy) {
|
||||
log_info(LD_GENERAL,
|
||||
"Pluggable transport proxy (%s) does not provide "
|
||||
"any needed transports and will not be launched.",
|
||||
line);
|
||||
}
|
||||
|
||||
/* If we are not just validating, use the rest of the line as the
|
||||
argv of the proxy to be launched. Also, make sure that we are
|
||||
only launching proxies that contribute useful transports. */
|
||||
if (!validate_only && !is_useless_proxy) {
|
||||
proxy_argc = line_length-2;
|
||||
/*
|
||||
* If we are not just validating, use the rest of the line as the
|
||||
* argv of the proxy to be launched. Also, make sure that we are
|
||||
* only launching proxies that contribute useful transports.
|
||||
*/
|
||||
|
||||
if (!validate_only && (server || !is_useless_proxy)) {
|
||||
proxy_argc = line_length - 2;
|
||||
tor_assert(proxy_argc > 0);
|
||||
proxy_argv = tor_calloc(sizeof(char *), (proxy_argc + 1));
|
||||
proxy_argv = tor_calloc((proxy_argc + 1), sizeof(char *));
|
||||
tmp = proxy_argv;
|
||||
for (i=0;i<proxy_argc;i++) { /* store arguments */
|
||||
|
||||
for (i = 0; i < proxy_argc; i++) {
|
||||
/* store arguments */
|
||||
*tmp++ = smartlist_get(items, 2);
|
||||
smartlist_del_keeporder(items, 2);
|
||||
}
|
||||
*tmp = NULL; /*terminated with NULL, just like execve() likes it*/
|
||||
*tmp = NULL; /* terminated with NULL, just like execve() likes it */
|
||||
|
||||
/* kickstart the thing */
|
||||
pt_kickstart_client_proxy(transport_list, proxy_argv);
|
||||
if (server) {
|
||||
pt_kickstart_server_proxy(transport_list, proxy_argv);
|
||||
} else {
|
||||
pt_kickstart_client_proxy(transport_list, proxy_argv);
|
||||
}
|
||||
}
|
||||
} else { /* external */
|
||||
} else {
|
||||
/* external */
|
||||
|
||||
/* ClientTransportPlugins connecting through a proxy is managed only. */
|
||||
if (options->Socks4Proxy || options->Socks5Proxy || options->HTTPSProxy) {
|
||||
if (!server && (options->Socks4Proxy || options->Socks5Proxy ||
|
||||
options->HTTPSProxy)) {
|
||||
log_warn(LD_CONFIG, "You have configured an external proxy with another "
|
||||
"proxy type. (Socks4Proxy|Socks5Proxy|HTTPSProxy)");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (smartlist_len(transport_list) != 1) {
|
||||
log_warn(LD_CONFIG, "You can't have an external proxy with "
|
||||
"more than one transports.");
|
||||
log_warn(LD_CONFIG,
|
||||
"You can't have an external proxy with more than "
|
||||
"one transport.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
addrport = smartlist_get(items, 2);
|
||||
|
||||
if (tor_addr_port_lookup(addrport, &addr, &port)<0) {
|
||||
log_warn(LD_CONFIG, "Error parsing transport "
|
||||
"address '%s'", addrport);
|
||||
if (tor_addr_port_lookup(addrport, &addr, &port) < 0) {
|
||||
log_warn(LD_CONFIG,
|
||||
"Error parsing transport address '%s'", addrport);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!port) {
|
||||
log_warn(LD_CONFIG,
|
||||
"Transport address '%s' has no port.", addrport);
|
||||
@@ -4903,11 +4964,15 @@ parse_client_transport_line(const or_options_t *options,
|
||||
}
|
||||
|
||||
if (!validate_only) {
|
||||
transport_add_from_config(&addr, port, smartlist_get(transport_list, 0),
|
||||
socks_ver);
|
||||
|
||||
log_info(LD_DIR, "Transport '%s' found at %s",
|
||||
log_info(LD_DIR, "%s '%s' at %s.",
|
||||
server ? "Server transport" : "Transport",
|
||||
transports, fmt_addrport(&addr, port));
|
||||
|
||||
if (!server) {
|
||||
transport_add_from_config(&addr, port,
|
||||
smartlist_get(transport_list, 0),
|
||||
socks_ver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5079,133 +5144,6 @@ get_options_for_server_transport(const char *transport)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Read the contents of a ServerTransportPlugin line from
|
||||
* <b>line</b>. Return 0 if the line is well-formed, and -1 if it
|
||||
* isn't.
|
||||
* If <b>validate_only</b> is 0, the line is well-formed, and it's a
|
||||
* managed proxy line, launch the managed proxy. */
|
||||
static int
|
||||
parse_server_transport_line(const or_options_t *options,
|
||||
const char *line, int validate_only)
|
||||
{
|
||||
smartlist_t *items = NULL;
|
||||
int r;
|
||||
const char *transports=NULL;
|
||||
smartlist_t *transport_list=NULL;
|
||||
char *type=NULL;
|
||||
char *addrport=NULL;
|
||||
tor_addr_t addr;
|
||||
uint16_t port = 0;
|
||||
|
||||
/* managed proxy options */
|
||||
int is_managed=0;
|
||||
char **proxy_argv=NULL;
|
||||
char **tmp=NULL;
|
||||
int proxy_argc,i;
|
||||
|
||||
int line_length;
|
||||
|
||||
items = smartlist_new();
|
||||
smartlist_split_string(items, line, NULL,
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
|
||||
|
||||
line_length = smartlist_len(items);
|
||||
if (line_length < 3) {
|
||||
log_warn(LD_CONFIG, "Too few arguments on ServerTransportPlugin line.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Get the first line element, split it to commas into
|
||||
transport_list (in case it's multiple transports) and validate
|
||||
the transport names. */
|
||||
transports = smartlist_get(items, 0);
|
||||
transport_list = smartlist_new();
|
||||
smartlist_split_string(transport_list, transports, ",",
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
||||
SMARTLIST_FOREACH_BEGIN(transport_list, const char *, transport_name) {
|
||||
if (!string_is_C_identifier(transport_name)) {
|
||||
log_warn(LD_CONFIG, "Transport name is not a C identifier (%s).",
|
||||
transport_name);
|
||||
goto err;
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(transport_name);
|
||||
|
||||
type = smartlist_get(items, 1);
|
||||
|
||||
if (!strcmp(type, "exec")) {
|
||||
is_managed=1;
|
||||
} else if (!strcmp(type, "proxy")) {
|
||||
is_managed=0;
|
||||
} else {
|
||||
log_warn(LD_CONFIG, "Strange ServerTransportPlugin type '%s'", type);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (is_managed && options->Sandbox) {
|
||||
log_warn(LD_CONFIG, "Managed proxies are not compatible with Sandbox mode."
|
||||
"(ServerTransportPlugin line was %s)", escaped(line));
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (is_managed) { /* managed */
|
||||
if (!validate_only) {
|
||||
proxy_argc = line_length-2;
|
||||
tor_assert(proxy_argc > 0);
|
||||
proxy_argv = tor_calloc(sizeof(char *), (proxy_argc + 1));
|
||||
tmp = proxy_argv;
|
||||
|
||||
for (i=0;i<proxy_argc;i++) { /* store arguments */
|
||||
*tmp++ = smartlist_get(items, 2);
|
||||
smartlist_del_keeporder(items, 2);
|
||||
}
|
||||
*tmp = NULL; /*terminated with NULL, just like execve() likes it*/
|
||||
|
||||
/* kickstart the thing */
|
||||
pt_kickstart_server_proxy(transport_list, proxy_argv);
|
||||
}
|
||||
} else { /* external */
|
||||
if (smartlist_len(transport_list) != 1) {
|
||||
log_warn(LD_CONFIG, "You can't have an external proxy with "
|
||||
"more than one transports.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
addrport = smartlist_get(items, 2);
|
||||
|
||||
if (tor_addr_port_lookup(addrport, &addr, &port)<0) {
|
||||
log_warn(LD_CONFIG, "Error parsing transport "
|
||||
"address '%s'", addrport);
|
||||
goto err;
|
||||
}
|
||||
if (!port) {
|
||||
log_warn(LD_CONFIG,
|
||||
"Transport address '%s' has no port.", addrport);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!validate_only) {
|
||||
log_info(LD_DIR, "Server transport '%s' at %s.",
|
||||
transports, fmt_addrport(&addr, port));
|
||||
}
|
||||
}
|
||||
|
||||
r = 0;
|
||||
goto done;
|
||||
|
||||
err:
|
||||
r = -1;
|
||||
|
||||
done:
|
||||
SMARTLIST_FOREACH(items, char*, s, tor_free(s));
|
||||
smartlist_free(items);
|
||||
if (transport_list) {
|
||||
SMARTLIST_FOREACH(transport_list, char*, s, tor_free(s));
|
||||
smartlist_free(transport_list);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Read the contents of a DirAuthority line from <b>line</b>. If
|
||||
* <b>validate_only</b> is 0, and the line is well-formed, and it
|
||||
* shares any bits with <b>required_type</b> or <b>required_type</b>
|
||||
|
||||
+4
-1
@@ -33,7 +33,7 @@ void reset_last_resolved_addr(void);
|
||||
int resolve_my_address(int warn_severity, const or_options_t *options,
|
||||
uint32_t *addr_out,
|
||||
const char **method_out, char **hostname_out);
|
||||
int is_local_addr(const tor_addr_t *addr);
|
||||
MOCK_DECL(int, is_local_addr, (const tor_addr_t *addr));
|
||||
void options_init(or_options_t *options);
|
||||
|
||||
#define OPTIONS_DUMP_MINIMAL 1
|
||||
@@ -141,6 +141,9 @@ STATIC int options_validate(or_options_t *old_options,
|
||||
or_options_t *options,
|
||||
or_options_t *default_options,
|
||||
int from_setconf, char **msg);
|
||||
STATIC int parse_transport_line(const or_options_t *options,
|
||||
const char *line, int validate_only,
|
||||
int server);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3839,6 +3839,8 @@ connection_handle_write_impl(connection_t *conn, int force)
|
||||
tor_tls_get_n_raw_bytes(or_conn->tls, &n_read, &n_written);
|
||||
log_debug(LD_GENERAL, "After TLS write of %d: %ld read, %ld written",
|
||||
result, (long)n_read, (long)n_written);
|
||||
or_conn->bytes_xmitted += result;
|
||||
or_conn->bytes_xmitted_by_tls += n_written;
|
||||
/* So we notice bytes were written even on error */
|
||||
/* XXXX024 This cast is safe since we can never write INT_MAX bytes in a
|
||||
* single set of TLS operations. But it looks kinda ugly. If we refactor
|
||||
|
||||
@@ -744,8 +744,17 @@ connection_ap_fail_onehop(const char *failed_digest,
|
||||
/* we don't know the digest; have to compare addr:port */
|
||||
tor_addr_t addr;
|
||||
if (!build_state || !build_state->chosen_exit ||
|
||||
!entry_conn->socks_request || !entry_conn->socks_request->address)
|
||||
!entry_conn->socks_request) {
|
||||
/* clang thinks that an array midway through a structure
|
||||
* will never have a NULL address, under either:
|
||||
* -Wpointer-bool-conversion if using !, or
|
||||
* -Wtautological-pointer-compare if using == or !=
|
||||
* It's probably right (unless pointers overflow and wrap),
|
||||
* so we just skip this check
|
||||
|| !entry_conn->socks_request->address
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
if (tor_addr_parse(&addr, entry_conn->socks_request->address)<0 ||
|
||||
!tor_addr_eq(&build_state->chosen_exit->addr, &addr) ||
|
||||
build_state->chosen_exit->port != entry_conn->socks_request->port)
|
||||
@@ -2461,7 +2470,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
|
||||
|
||||
relay_header_unpack(&rh, cell->payload);
|
||||
if (rh.length > RELAY_PAYLOAD_SIZE)
|
||||
return -1;
|
||||
return -END_CIRC_REASON_TORPROTOCOL;
|
||||
|
||||
/* Note: we have to use relay_send_command_from_edge here, not
|
||||
* connection_edge_end or connection_edge_send_command, since those require
|
||||
@@ -2479,7 +2488,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
|
||||
|
||||
r = begin_cell_parse(cell, &bcell, &end_reason);
|
||||
if (r < -1) {
|
||||
return -1;
|
||||
return -END_CIRC_REASON_TORPROTOCOL;
|
||||
} else if (r == -1) {
|
||||
tor_free(bcell.address);
|
||||
relay_send_end_cell_from_edge(rh.stream_id, circ, end_reason, NULL);
|
||||
|
||||
+36
-31
@@ -38,6 +38,8 @@
|
||||
#include "router.h"
|
||||
#include "routerlist.h"
|
||||
#include "ext_orport.h"
|
||||
#include "scheduler.h"
|
||||
|
||||
#ifdef USE_BUFFEREVENTS
|
||||
#include <event2/bufferevent_ssl.h>
|
||||
#endif
|
||||
@@ -574,48 +576,51 @@ connection_or_process_inbuf(or_connection_t *conn)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** When adding cells to an OR connection's outbuf, keep adding until the
|
||||
* outbuf is at least this long, or we run out of cells. */
|
||||
#define OR_CONN_HIGHWATER (32*1024)
|
||||
|
||||
/** Add cells to an OR connection's outbuf whenever the outbuf's data length
|
||||
* drops below this size. */
|
||||
#define OR_CONN_LOWWATER (16*1024)
|
||||
|
||||
/** Called whenever we have flushed some data on an or_conn: add more data
|
||||
* from active circuits. */
|
||||
int
|
||||
connection_or_flushed_some(or_connection_t *conn)
|
||||
{
|
||||
size_t datalen, temp;
|
||||
ssize_t n, flushed;
|
||||
size_t cell_network_size = get_cell_network_size(conn->wide_circ_ids);
|
||||
size_t datalen;
|
||||
|
||||
/* The channel will want to update its estimated queue size */
|
||||
channel_update_xmit_queue_size(TLS_CHAN_TO_BASE(conn->chan));
|
||||
|
||||
/* If we're under the low water mark, add cells until we're just over the
|
||||
* high water mark. */
|
||||
datalen = connection_get_outbuf_len(TO_CONN(conn));
|
||||
if (datalen < OR_CONN_LOWWATER) {
|
||||
while ((conn->chan) && channel_tls_more_to_flush(conn->chan)) {
|
||||
/* Compute how many more cells we want at most */
|
||||
n = CEIL_DIV(OR_CONN_HIGHWATER - datalen, cell_network_size);
|
||||
/* Bail out if we don't want any more */
|
||||
if (n <= 0) break;
|
||||
/* We're still here; try to flush some more cells */
|
||||
flushed = channel_tls_flush_some_cells(conn->chan, n);
|
||||
/* Bail out if it says it didn't flush anything */
|
||||
if (flushed <= 0) break;
|
||||
/* How much in the outbuf now? */
|
||||
temp = connection_get_outbuf_len(TO_CONN(conn));
|
||||
/* Bail out if we didn't actually increase the outbuf size */
|
||||
if (temp <= datalen) break;
|
||||
/* Update datalen for the next iteration */
|
||||
datalen = temp;
|
||||
}
|
||||
/* Let the scheduler know */
|
||||
scheduler_channel_wants_writes(TLS_CHAN_TO_BASE(conn->chan));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** This is for channeltls.c to ask how many cells we could accept if
|
||||
* they were available. */
|
||||
ssize_t
|
||||
connection_or_num_cells_writeable(or_connection_t *conn)
|
||||
{
|
||||
size_t datalen, cell_network_size;
|
||||
ssize_t n = 0;
|
||||
|
||||
tor_assert(conn);
|
||||
|
||||
/*
|
||||
* If we're under the high water mark, we're potentially
|
||||
* writeable; note this is different from the calculation above
|
||||
* used to trigger when to start writing after we've stopped.
|
||||
*/
|
||||
datalen = connection_get_outbuf_len(TO_CONN(conn));
|
||||
if (datalen < OR_CONN_HIGHWATER) {
|
||||
cell_network_size = get_cell_network_size(conn->wide_circ_ids);
|
||||
n = CEIL_DIV(OR_CONN_HIGHWATER - datalen, cell_network_size);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/** Connection <b>conn</b> has finished writing and has no bytes left on
|
||||
* its outbuf.
|
||||
*
|
||||
@@ -1169,10 +1174,10 @@ connection_or_notify_error(or_connection_t *conn,
|
||||
*
|
||||
* Return the launched conn, or NULL if it failed.
|
||||
*/
|
||||
or_connection_t *
|
||||
connection_or_connect(const tor_addr_t *_addr, uint16_t port,
|
||||
const char *id_digest,
|
||||
channel_tls_t *chan)
|
||||
|
||||
MOCK_IMPL(or_connection_t *,
|
||||
connection_or_connect, (const tor_addr_t *_addr, uint16_t port,
|
||||
const char *id_digest, channel_tls_t *chan))
|
||||
{
|
||||
or_connection_t *conn;
|
||||
const or_options_t *options = get_options();
|
||||
|
||||
@@ -24,6 +24,7 @@ void connection_or_set_bad_connections(const char *digest, int force);
|
||||
void connection_or_block_renegotiation(or_connection_t *conn);
|
||||
int connection_or_reached_eof(or_connection_t *conn);
|
||||
int connection_or_process_inbuf(or_connection_t *conn);
|
||||
ssize_t connection_or_num_cells_writeable(or_connection_t *conn);
|
||||
int connection_or_flushed_some(or_connection_t *conn);
|
||||
int connection_or_finished_flushing(or_connection_t *conn);
|
||||
int connection_or_finished_connecting(or_connection_t *conn);
|
||||
@@ -36,9 +37,10 @@ void connection_or_connect_failed(or_connection_t *conn,
|
||||
int reason, const char *msg);
|
||||
void connection_or_notify_error(or_connection_t *conn,
|
||||
int reason, const char *msg);
|
||||
or_connection_t *connection_or_connect(const tor_addr_t *addr, uint16_t port,
|
||||
const char *id_digest,
|
||||
channel_tls_t *chan);
|
||||
MOCK_DECL(or_connection_t *,
|
||||
connection_or_connect,
|
||||
(const tor_addr_t *addr, uint16_t port,
|
||||
const char *id_digest, channel_tls_t *chan));
|
||||
|
||||
void connection_or_close_normally(or_connection_t *orconn, int flush);
|
||||
void connection_or_close_for_error(or_connection_t *orconn, int flush);
|
||||
|
||||
+28
-10
@@ -1263,6 +1263,7 @@ static const struct signal_t signal_table[] = {
|
||||
{ SIGTERM, "INT" },
|
||||
{ SIGNEWNYM, "NEWNYM" },
|
||||
{ SIGCLEARDNSCACHE, "CLEARDNSCACHE"},
|
||||
{ SIGHEARTBEAT, "HEARTBEAT"},
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
@@ -2015,7 +2016,7 @@ getinfo_helper_events(control_connection_t *control_conn,
|
||||
/* Note that status/ is not a catch-all for events; there's only supposed
|
||||
* to be a status GETINFO if there's a corresponding STATUS event. */
|
||||
if (!strcmp(question, "status/circuit-established")) {
|
||||
*answer = tor_strdup(can_complete_circuit ? "1" : "0");
|
||||
*answer = tor_strdup(have_completed_a_circuit() ? "1" : "0");
|
||||
} else if (!strcmp(question, "status/enough-dir-info")) {
|
||||
*answer = tor_strdup(router_have_minimum_dir_info() ? "1" : "0");
|
||||
} else if (!strcmp(question, "status/good-server-descriptor") ||
|
||||
@@ -4454,6 +4455,9 @@ control_event_signal(uintptr_t signal)
|
||||
case SIGCLEARDNSCACHE:
|
||||
signal_string = "CLEARDNSCACHE";
|
||||
break;
|
||||
case SIGHEARTBEAT:
|
||||
signal_string = "HEARTBEAT";
|
||||
break;
|
||||
default:
|
||||
log_warn(LD_BUG, "Unrecognized signal %lu in control_event_signal",
|
||||
(unsigned long)signal);
|
||||
@@ -5096,20 +5100,30 @@ control_event_hs_descriptor_requested(const rend_data_t *rend_query,
|
||||
void
|
||||
control_event_hs_descriptor_receive_end(const char *action,
|
||||
const rend_data_t *rend_query,
|
||||
const char *id_digest)
|
||||
const char *id_digest,
|
||||
const char *reason)
|
||||
{
|
||||
char *reason_field = NULL;
|
||||
|
||||
if (!action || !rend_query || !id_digest) {
|
||||
log_warn(LD_BUG, "Called with action==%p, rend_query==%p, "
|
||||
"id_digest==%p", action, rend_query, id_digest);
|
||||
return;
|
||||
}
|
||||
|
||||
if (reason) {
|
||||
tor_asprintf(&reason_field, " REASON=%s", reason);
|
||||
}
|
||||
|
||||
send_control_event(EVENT_HS_DESC, ALL_FORMATS,
|
||||
"650 HS_DESC %s %s %s %s\r\n",
|
||||
"650 HS_DESC %s %s %s %s%s\r\n",
|
||||
action,
|
||||
rend_query->onion_address,
|
||||
rend_auth_type_to_string(rend_query->auth_type),
|
||||
node_describe_longname_by_id(id_digest));
|
||||
node_describe_longname_by_id(id_digest),
|
||||
reason_field ? reason_field : "");
|
||||
|
||||
tor_free(reason_field);
|
||||
}
|
||||
|
||||
/** send HS_DESC RECEIVED event
|
||||
@@ -5125,23 +5139,27 @@ control_event_hs_descriptor_received(const rend_data_t *rend_query,
|
||||
rend_query, id_digest);
|
||||
return;
|
||||
}
|
||||
control_event_hs_descriptor_receive_end("RECEIVED", rend_query, id_digest);
|
||||
control_event_hs_descriptor_receive_end("RECEIVED", rend_query,
|
||||
id_digest, NULL);
|
||||
}
|
||||
|
||||
/** send HS_DESC FAILED event
|
||||
*
|
||||
* called when request for hidden service descriptor returned failure.
|
||||
/** Send HS_DESC event to inform controller that query <b>rend_query</b>
|
||||
* failed to retrieve hidden service descriptor identified by
|
||||
* <b>id_digest</b>. If <b>reason</b> is not NULL, add it to REASON=
|
||||
* field.
|
||||
*/
|
||||
void
|
||||
control_event_hs_descriptor_failed(const rend_data_t *rend_query,
|
||||
const char *id_digest)
|
||||
const char *id_digest,
|
||||
const char *reason)
|
||||
{
|
||||
if (!rend_query || !id_digest) {
|
||||
log_warn(LD_BUG, "Called with rend_query==%p, id_digest==%p",
|
||||
rend_query, id_digest);
|
||||
return;
|
||||
}
|
||||
control_event_hs_descriptor_receive_end("FAILED", rend_query, id_digest);
|
||||
control_event_hs_descriptor_receive_end("FAILED", rend_query,
|
||||
id_digest, reason);
|
||||
}
|
||||
|
||||
/** Free any leftover allocated memory of the control.c subsystem. */
|
||||
|
||||
+4
-2
@@ -108,11 +108,13 @@ void control_event_hs_descriptor_requested(const rend_data_t *rend_query,
|
||||
const char *hs_dir);
|
||||
void control_event_hs_descriptor_receive_end(const char *action,
|
||||
const rend_data_t *rend_query,
|
||||
const char *hs_dir);
|
||||
const char *hs_dir,
|
||||
const char *reason);
|
||||
void control_event_hs_descriptor_received(const rend_data_t *rend_query,
|
||||
const char *hs_dir);
|
||||
void control_event_hs_descriptor_failed(const rend_data_t *rend_query,
|
||||
const char *hs_dir);
|
||||
const char *hs_dir,
|
||||
const char *reason);
|
||||
|
||||
void control_free_all(void);
|
||||
|
||||
|
||||
+1
-1
@@ -510,7 +510,7 @@ spawn_cpuworker(void)
|
||||
connection_t *conn;
|
||||
int err;
|
||||
|
||||
fdarray = tor_calloc(sizeof(tor_socket_t), 2);
|
||||
fdarray = tor_calloc(2, sizeof(tor_socket_t));
|
||||
if ((err = tor_socketpair(AF_UNIX, SOCK_STREAM, 0, fdarray)) < 0) {
|
||||
log_warn(LD_NET, "Couldn't construct socketpair for cpuworker: %s",
|
||||
tor_socket_strerror(-err));
|
||||
|
||||
+13
-9
@@ -2073,23 +2073,25 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
|
||||
}
|
||||
|
||||
if (conn->base_.purpose == DIR_PURPOSE_FETCH_RENDDESC_V2) {
|
||||
#define SEND_HS_DESC_FAILED_EVENT() ( \
|
||||
#define SEND_HS_DESC_FAILED_EVENT(reason) ( \
|
||||
control_event_hs_descriptor_failed(conn->rend_data, \
|
||||
conn->identity_digest) )
|
||||
conn->identity_digest, \
|
||||
reason) )
|
||||
tor_assert(conn->rend_data);
|
||||
log_info(LD_REND,"Received rendezvous descriptor (size %d, status %d "
|
||||
"(%s))",
|
||||
(int)body_len, status_code, escaped(reason));
|
||||
switch (status_code) {
|
||||
case 200:
|
||||
switch (rend_cache_store_v2_desc_as_client(body, conn->rend_data)) {
|
||||
switch (rend_cache_store_v2_desc_as_client(body,
|
||||
conn->requested_resource, conn->rend_data)) {
|
||||
case RCS_BADDESC:
|
||||
case RCS_NOTDIR: /* Impossible */
|
||||
log_warn(LD_REND,"Fetching v2 rendezvous descriptor failed. "
|
||||
"Retrying at another directory.");
|
||||
/* We'll retry when connection_about_to_close_connection()
|
||||
* cleans this dir conn up. */
|
||||
SEND_HS_DESC_FAILED_EVENT();
|
||||
SEND_HS_DESC_FAILED_EVENT("BAD_DESC");
|
||||
break;
|
||||
case RCS_OKAY:
|
||||
default:
|
||||
@@ -2108,14 +2110,14 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
|
||||
* connection_about_to_close_connection() cleans this conn up. */
|
||||
log_info(LD_REND,"Fetching v2 rendezvous descriptor failed: "
|
||||
"Retrying at another directory.");
|
||||
SEND_HS_DESC_FAILED_EVENT();
|
||||
SEND_HS_DESC_FAILED_EVENT("NOT_FOUND");
|
||||
break;
|
||||
case 400:
|
||||
log_warn(LD_REND, "Fetching v2 rendezvous descriptor failed: "
|
||||
"http status 400 (%s). Dirserver didn't like our "
|
||||
"v2 rendezvous query? Retrying at another directory.",
|
||||
escaped(reason));
|
||||
SEND_HS_DESC_FAILED_EVENT();
|
||||
SEND_HS_DESC_FAILED_EVENT("QUERY_REJECTED");
|
||||
break;
|
||||
default:
|
||||
log_warn(LD_REND, "Fetching v2 rendezvous descriptor failed: "
|
||||
@@ -2124,7 +2126,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
|
||||
"Retrying at another directory.",
|
||||
status_code, escaped(reason), conn->base_.address,
|
||||
conn->base_.port);
|
||||
SEND_HS_DESC_FAILED_EVENT();
|
||||
SEND_HS_DESC_FAILED_EVENT("UNEXPECTED");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2208,8 +2210,10 @@ connection_dir_process_inbuf(dir_connection_t *conn)
|
||||
}
|
||||
|
||||
if (connection_get_inbuf_len(TO_CONN(conn)) > MAX_DIRECTORY_OBJECT_SIZE) {
|
||||
log_warn(LD_HTTP, "Too much data received from directory connection: "
|
||||
"denial of service attempt, or you need to upgrade?");
|
||||
log_warn(LD_HTTP,
|
||||
"Too much data received from directory connection (%s): "
|
||||
"denial of service attempt, or you need to upgrade?",
|
||||
conn->base_.address);
|
||||
connection_mark_for_close(TO_CONN(conn));
|
||||
return -1;
|
||||
}
|
||||
|
||||
+9
-9
@@ -512,7 +512,7 @@ dirserv_add_multiple_descriptors(const char *desc, uint8_t purpose,
|
||||
if (!n_parsed) {
|
||||
*msg = "No descriptors found in your POST.";
|
||||
if (WRA_WAS_ADDED(r))
|
||||
r = ROUTER_WAS_NOT_NEW;
|
||||
r = ROUTER_IS_ALREADY_KNOWN;
|
||||
} else {
|
||||
*msg = "(no message)";
|
||||
}
|
||||
@@ -574,7 +574,7 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source)
|
||||
ri->cache_info.signed_descriptor_body,
|
||||
ri->cache_info.signed_descriptor_len, *msg);
|
||||
routerinfo_free(ri);
|
||||
return ROUTER_WAS_NOT_NEW;
|
||||
return ROUTER_IS_ALREADY_KNOWN;
|
||||
}
|
||||
|
||||
/* Make a copy of desc, since router_add_to_routerlist might free
|
||||
@@ -646,7 +646,7 @@ dirserv_add_extrainfo(extrainfo_t *ei, const char **msg)
|
||||
|
||||
if ((r = routerinfo_incompatible_with_extrainfo(ri, ei, NULL, msg))) {
|
||||
extrainfo_free(ei);
|
||||
return r < 0 ? ROUTER_WAS_NOT_NEW : ROUTER_BAD_EI;
|
||||
return r < 0 ? ROUTER_IS_ALREADY_KNOWN : ROUTER_BAD_EI;
|
||||
}
|
||||
router_add_extrainfo_to_routerlist(ei, msg, 0, 0);
|
||||
return ROUTER_ADDED_SUCCESSFULLY;
|
||||
@@ -1369,18 +1369,18 @@ dirserv_compute_performance_thresholds(routerlist_t *rl,
|
||||
* sort them and use that to compute thresholds. */
|
||||
n_active = n_active_nonexit = 0;
|
||||
/* Uptime for every active router. */
|
||||
uptimes = tor_calloc(sizeof(uint32_t), smartlist_len(rl->routers));
|
||||
uptimes = tor_calloc(smartlist_len(rl->routers), sizeof(uint32_t));
|
||||
/* Bandwidth for every active router. */
|
||||
bandwidths_kb = tor_calloc(sizeof(uint32_t), smartlist_len(rl->routers));
|
||||
bandwidths_kb = tor_calloc(smartlist_len(rl->routers), sizeof(uint32_t));
|
||||
/* Bandwidth for every active non-exit router. */
|
||||
bandwidths_excluding_exits_kb =
|
||||
tor_calloc(sizeof(uint32_t), smartlist_len(rl->routers));
|
||||
tor_calloc(smartlist_len(rl->routers), sizeof(uint32_t));
|
||||
/* Weighted mean time between failure for each active router. */
|
||||
mtbfs = tor_calloc(sizeof(double), smartlist_len(rl->routers));
|
||||
mtbfs = tor_calloc(smartlist_len(rl->routers), sizeof(double));
|
||||
/* Time-known for each active router. */
|
||||
tks = tor_calloc(sizeof(long), smartlist_len(rl->routers));
|
||||
tks = tor_calloc(smartlist_len(rl->routers), sizeof(long));
|
||||
/* Weighted fractional uptime for each active router. */
|
||||
wfus = tor_calloc(sizeof(double), smartlist_len(rl->routers));
|
||||
wfus = tor_calloc(smartlist_len(rl->routers), sizeof(double));
|
||||
|
||||
nodelist_assert_ok();
|
||||
|
||||
|
||||
+15
-15
@@ -611,7 +611,7 @@ dirvote_compute_params(smartlist_t *votes, int method, int total_authorities)
|
||||
between INT32_MIN and INT32_MAX inclusive. This should be guaranteed by
|
||||
the parsing code. */
|
||||
|
||||
vals = tor_calloc(sizeof(int), n_votes);
|
||||
vals = tor_calloc(n_votes, sizeof(int));
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
|
||||
if (!v->net_params)
|
||||
@@ -1258,10 +1258,10 @@ networkstatus_compute_consensus(smartlist_t *votes,
|
||||
smartlist_t *chosen_flags = smartlist_new();
|
||||
smartlist_t *versions = smartlist_new();
|
||||
smartlist_t *exitsummaries = smartlist_new();
|
||||
uint32_t *bandwidths_kb = tor_calloc(sizeof(uint32_t),
|
||||
smartlist_len(votes));
|
||||
uint32_t *measured_bws_kb = tor_calloc(sizeof(uint32_t),
|
||||
smartlist_len(votes));
|
||||
uint32_t *bandwidths_kb = tor_calloc(smartlist_len(votes),
|
||||
sizeof(uint32_t));
|
||||
uint32_t *measured_bws_kb = tor_calloc(smartlist_len(votes),
|
||||
sizeof(uint32_t));
|
||||
int num_bandwidths;
|
||||
int num_mbws;
|
||||
|
||||
@@ -1281,13 +1281,13 @@ networkstatus_compute_consensus(smartlist_t *votes,
|
||||
memset(conflict, 0, sizeof(conflict));
|
||||
memset(unknown, 0xff, sizeof(conflict));
|
||||
|
||||
index = tor_calloc(sizeof(int), smartlist_len(votes));
|
||||
size = tor_calloc(sizeof(int), smartlist_len(votes));
|
||||
n_voter_flags = tor_calloc(sizeof(int), smartlist_len(votes));
|
||||
n_flag_voters = tor_calloc(sizeof(int), smartlist_len(flags));
|
||||
flag_map = tor_calloc(sizeof(int *), smartlist_len(votes));
|
||||
named_flag = tor_calloc(sizeof(int), smartlist_len(votes));
|
||||
unnamed_flag = tor_calloc(sizeof(int), smartlist_len(votes));
|
||||
index = tor_calloc(smartlist_len(votes), sizeof(int));
|
||||
size = tor_calloc(smartlist_len(votes), sizeof(int));
|
||||
n_voter_flags = tor_calloc(smartlist_len(votes), sizeof(int));
|
||||
n_flag_voters = tor_calloc(smartlist_len(flags), sizeof(int));
|
||||
flag_map = tor_calloc(smartlist_len(votes), sizeof(int *));
|
||||
named_flag = tor_calloc(smartlist_len(votes), sizeof(int));
|
||||
unnamed_flag = tor_calloc(smartlist_len(votes), sizeof(int));
|
||||
for (i = 0; i < smartlist_len(votes); ++i)
|
||||
unnamed_flag[i] = named_flag[i] = -1;
|
||||
|
||||
@@ -1298,8 +1298,8 @@ networkstatus_compute_consensus(smartlist_t *votes,
|
||||
* that they're actually set before doing U64_LITERAL(1) << index with
|
||||
* them.*/
|
||||
SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
|
||||
flag_map[v_sl_idx] = tor_calloc(sizeof(int),
|
||||
smartlist_len(v->known_flags));
|
||||
flag_map[v_sl_idx] = tor_calloc(smartlist_len(v->known_flags),
|
||||
sizeof(int));
|
||||
if (smartlist_len(v->known_flags) > MAX_KNOWN_FLAGS_IN_VOTE) {
|
||||
log_warn(LD_BUG, "Somehow, a vote has %d entries in known_flags",
|
||||
smartlist_len(v->known_flags));
|
||||
@@ -1379,7 +1379,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
|
||||
);
|
||||
|
||||
/* Now go through all the votes */
|
||||
flag_counts = tor_calloc(sizeof(int), smartlist_len(flags));
|
||||
flag_counts = tor_calloc(smartlist_len(flags), sizeof(int));
|
||||
while (1) {
|
||||
vote_routerstatus_t *rs;
|
||||
routerstatus_t rs_out;
|
||||
|
||||
+2
-2
@@ -1919,8 +1919,8 @@ bridge_resolve_conflicts(const tor_addr_t *addr, uint16_t port,
|
||||
|
||||
/** Return True if we have a bridge that uses a transport with name
|
||||
* <b>transport_name</b>. */
|
||||
int
|
||||
transport_is_needed(const char *transport_name)
|
||||
MOCK_IMPL(int,
|
||||
transport_is_needed, (const char *transport_name))
|
||||
{
|
||||
if (!bridge_list)
|
||||
return 0;
|
||||
|
||||
+1
-1
@@ -154,7 +154,7 @@ struct transport_t;
|
||||
int get_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port,
|
||||
const struct transport_t **transport);
|
||||
|
||||
int transport_is_needed(const char *transport_name);
|
||||
MOCK_DECL(int, transport_is_needed, (const char *transport_name));
|
||||
int validate_pluggable_transports_config(void);
|
||||
|
||||
double pathbias_get_close_success_count(entry_guard_t *guard);
|
||||
|
||||
+2
-2
@@ -963,7 +963,7 @@ geoip_get_dirreq_history(dirreq_type_t type)
|
||||
/* We may have rounded 'completed' up. Here we want to use the
|
||||
* real value. */
|
||||
complete = smartlist_len(dirreq_completed);
|
||||
dltimes = tor_calloc(sizeof(uint32_t), complete);
|
||||
dltimes = tor_calloc(complete, sizeof(uint32_t));
|
||||
SMARTLIST_FOREACH_BEGIN(dirreq_completed, dirreq_map_entry_t *, ent) {
|
||||
uint32_t bytes_per_second;
|
||||
uint32_t time_diff = (uint32_t) tv_mdiff(&ent->request_time,
|
||||
@@ -1033,7 +1033,7 @@ geoip_get_client_history(geoip_client_action_t action,
|
||||
if (!geoip_is_loaded(AF_INET) && !geoip_is_loaded(AF_INET6))
|
||||
return -1;
|
||||
|
||||
counts = tor_calloc(sizeof(unsigned), n_countries);
|
||||
counts = tor_calloc(n_countries, sizeof(unsigned));
|
||||
HT_FOREACH(ent, clientmap, &client_history) {
|
||||
int country;
|
||||
if ((*ent)->action != (int)action)
|
||||
|
||||
@@ -74,6 +74,7 @@ LIBTOR_A_SOURCES = \
|
||||
src/or/routerlist.c \
|
||||
src/or/routerparse.c \
|
||||
src/or/routerset.c \
|
||||
src/or/scheduler.c \
|
||||
src/or/statefile.c \
|
||||
src/or/status.c \
|
||||
src/or/onion_ntor.c \
|
||||
@@ -179,6 +180,7 @@ ORHEADERS = \
|
||||
src/or/routerlist.h \
|
||||
src/or/routerset.h \
|
||||
src/or/routerparse.h \
|
||||
src/or/scheduler.h \
|
||||
src/or/statefile.h \
|
||||
src/or/status.h
|
||||
|
||||
|
||||
+41
-10
@@ -53,6 +53,7 @@
|
||||
#include "router.h"
|
||||
#include "routerlist.h"
|
||||
#include "routerparse.h"
|
||||
#include "scheduler.h"
|
||||
#include "statefile.h"
|
||||
#include "status.h"
|
||||
#include "util_process.h"
|
||||
@@ -150,7 +151,7 @@ static int called_loop_once = 0;
|
||||
* any longer (a big time jump happened, when we notice our directory is
|
||||
* heinously out-of-date, etc.
|
||||
*/
|
||||
int can_complete_circuit=0;
|
||||
static int can_complete_circuits = 0;
|
||||
|
||||
/** How often do we check for router descriptors that we should download
|
||||
* when we have too little directory info? */
|
||||
@@ -171,11 +172,11 @@ int quiet_level = 0;
|
||||
/********* END VARIABLES ************/
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* This section contains accessors and other methods on the connection_array
|
||||
* variables (which are global within this file and unavailable outside it).
|
||||
*
|
||||
****************************************************************************/
|
||||
*
|
||||
* This section contains accessors and other methods on the connection_array
|
||||
* variables (which are global within this file and unavailable outside it).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if 0 && defined(USE_BUFFEREVENTS)
|
||||
static void
|
||||
@@ -223,6 +224,31 @@ set_buffer_lengths_to_zero(tor_socket_t s)
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Return 1 if we have successfully built a circuit, and nothing has changed
|
||||
* to make us think that maybe we can't.
|
||||
*/
|
||||
int
|
||||
have_completed_a_circuit(void)
|
||||
{
|
||||
return can_complete_circuits;
|
||||
}
|
||||
|
||||
/** Note that we have successfully built a circuit, so that reachability
|
||||
* testing and introduction points and so on may be attempted. */
|
||||
void
|
||||
note_that_we_completed_a_circuit(void)
|
||||
{
|
||||
can_complete_circuits = 1;
|
||||
}
|
||||
|
||||
/** Note that something has happened (like a clock jump, or DisableNetwork) to
|
||||
* make us think that maybe we can't complete circuits. */
|
||||
void
|
||||
note_that_we_maybe_cant_complete_circuits(void)
|
||||
{
|
||||
can_complete_circuits = 0;
|
||||
}
|
||||
|
||||
/** Add <b>conn</b> to the array of connections that we can poll on. The
|
||||
* connection's socket must be set; the connection starts out
|
||||
* non-reading and non-writing.
|
||||
@@ -999,7 +1025,7 @@ directory_info_has_arrived(time_t now, int from_cache)
|
||||
}
|
||||
|
||||
if (server_mode(options) && !net_is_disabled() && !from_cache &&
|
||||
(can_complete_circuit || !any_predicted_circuits(now)))
|
||||
(have_completed_a_circuit() || !any_predicted_circuits(now)))
|
||||
consider_testing_reachability(1, 1);
|
||||
}
|
||||
|
||||
@@ -1436,7 +1462,7 @@ run_scheduled_events(time_t now)
|
||||
/* also, check religiously for reachability, if it's within the first
|
||||
* 20 minutes of our uptime. */
|
||||
if (is_server &&
|
||||
(can_complete_circuit || !any_predicted_circuits(now)) &&
|
||||
(have_completed_a_circuit() || !any_predicted_circuits(now)) &&
|
||||
!we_are_hibernating()) {
|
||||
if (stats_n_seconds_working < TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) {
|
||||
consider_testing_reachability(1, dirport_reachability_count==0);
|
||||
@@ -1549,7 +1575,7 @@ run_scheduled_events(time_t now)
|
||||
circuit_close_all_marked();
|
||||
|
||||
/* 7. And upload service descriptors if necessary. */
|
||||
if (can_complete_circuit && !net_is_disabled()) {
|
||||
if (have_completed_a_circuit() && !net_is_disabled()) {
|
||||
rend_consider_services_upload(now);
|
||||
rend_consider_descriptor_republication();
|
||||
}
|
||||
@@ -1680,7 +1706,7 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
|
||||
if (server_mode(options) &&
|
||||
!net_is_disabled() &&
|
||||
seconds_elapsed > 0 &&
|
||||
can_complete_circuit &&
|
||||
have_completed_a_circuit() &&
|
||||
stats_n_seconds_working / TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT !=
|
||||
(stats_n_seconds_working+seconds_elapsed) /
|
||||
TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) {
|
||||
@@ -2137,6 +2163,10 @@ process_signal(uintptr_t sig)
|
||||
addressmap_clear_transient();
|
||||
control_event_signal(sig);
|
||||
break;
|
||||
case SIGHEARTBEAT:
|
||||
log_heartbeat(time(NULL));
|
||||
control_event_signal(sig);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2553,6 +2583,7 @@ tor_free_all(int postfork)
|
||||
channel_tls_free_all();
|
||||
channel_free_all();
|
||||
connection_free_all();
|
||||
scheduler_free_all();
|
||||
buf_shrink_freelists(1);
|
||||
memarea_clear_freelist();
|
||||
nodelist_free_all();
|
||||
|
||||
+3
-1
@@ -12,7 +12,9 @@
|
||||
#ifndef TOR_MAIN_H
|
||||
#define TOR_MAIN_H
|
||||
|
||||
extern int can_complete_circuit;
|
||||
int have_completed_a_circuit(void);
|
||||
void note_that_we_completed_a_circuit(void);
|
||||
void note_that_we_maybe_cant_complete_circuits(void);
|
||||
|
||||
int connection_add_impl(connection_t *conn, int is_connecting);
|
||||
#define connection_add(conn) connection_add_impl((conn), 0)
|
||||
|
||||
+18
-18
@@ -163,19 +163,18 @@ microdescs_add_to_cache(microdesc_cache_t *cache,
|
||||
md->last_listed = listed_at);
|
||||
}
|
||||
if (requested_digests256) {
|
||||
digestmap_t *requested; /* XXXX actually we should just use a
|
||||
digest256map */
|
||||
requested = digestmap_new();
|
||||
digest256map_t *requested;
|
||||
requested = digest256map_new();
|
||||
/* Set requested[d] to DIGEST_REQUESTED for every md we requested. */
|
||||
SMARTLIST_FOREACH(requested_digests256, const char *, cp,
|
||||
digestmap_set(requested, cp, DIGEST_REQUESTED));
|
||||
SMARTLIST_FOREACH(requested_digests256, const uint8_t *, cp,
|
||||
digest256map_set(requested, cp, DIGEST_REQUESTED));
|
||||
/* Set requested[d] to DIGEST_INVALID for every md we requested which we
|
||||
* will never be able to parse. Remove the ones we didn't request from
|
||||
* invalid_digests.
|
||||
*/
|
||||
SMARTLIST_FOREACH_BEGIN(invalid_digests, char *, cp) {
|
||||
if (digestmap_get(requested, cp)) {
|
||||
digestmap_set(requested, cp, DIGEST_INVALID);
|
||||
SMARTLIST_FOREACH_BEGIN(invalid_digests, uint8_t *, cp) {
|
||||
if (digest256map_get(requested, cp)) {
|
||||
digest256map_set(requested, cp, DIGEST_INVALID);
|
||||
} else {
|
||||
tor_free(cp);
|
||||
SMARTLIST_DEL_CURRENT(invalid_digests, cp);
|
||||
@@ -185,8 +184,9 @@ microdescs_add_to_cache(microdesc_cache_t *cache,
|
||||
* ones we never requested from the 'descriptors' smartlist.
|
||||
*/
|
||||
SMARTLIST_FOREACH_BEGIN(descriptors, microdesc_t *, md) {
|
||||
if (digestmap_get(requested, md->digest)) {
|
||||
digestmap_set(requested, md->digest, DIGEST_RECEIVED);
|
||||
if (digest256map_get(requested, (const uint8_t*)md->digest)) {
|
||||
digest256map_set(requested, (const uint8_t*)md->digest,
|
||||
DIGEST_RECEIVED);
|
||||
} else {
|
||||
log_fn(LOG_PROTOCOL_WARN, LD_DIR, "Received non-requested microdesc");
|
||||
microdesc_free(md);
|
||||
@@ -195,14 +195,14 @@ microdescs_add_to_cache(microdesc_cache_t *cache,
|
||||
} SMARTLIST_FOREACH_END(md);
|
||||
/* Remove the ones we got or the invalid ones from requested_digests256.
|
||||
*/
|
||||
SMARTLIST_FOREACH_BEGIN(requested_digests256, char *, cp) {
|
||||
void *status = digestmap_get(requested, cp);
|
||||
SMARTLIST_FOREACH_BEGIN(requested_digests256, uint8_t *, cp) {
|
||||
void *status = digest256map_get(requested, cp);
|
||||
if (status == DIGEST_RECEIVED || status == DIGEST_INVALID) {
|
||||
tor_free(cp);
|
||||
SMARTLIST_DEL_CURRENT(requested_digests256, cp);
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(cp);
|
||||
digestmap_free(requested, NULL);
|
||||
digest256map_free(requested, NULL);
|
||||
}
|
||||
|
||||
/* For every requested microdescriptor that was unparseable, mark it
|
||||
@@ -794,7 +794,7 @@ microdesc_average_size(microdesc_cache_t *cache)
|
||||
* smartlist. Omit all microdescriptors whose digest appear in <b>skip</b>. */
|
||||
smartlist_t *
|
||||
microdesc_list_missing_digest256(networkstatus_t *ns, microdesc_cache_t *cache,
|
||||
int downloadable_only, digestmap_t *skip)
|
||||
int downloadable_only, digest256map_t *skip)
|
||||
{
|
||||
smartlist_t *result = smartlist_new();
|
||||
time_t now = time(NULL);
|
||||
@@ -806,7 +806,7 @@ microdesc_list_missing_digest256(networkstatus_t *ns, microdesc_cache_t *cache,
|
||||
!download_status_is_ready(&rs->dl_status, now,
|
||||
get_options()->TestingMicrodescMaxDownloadTries))
|
||||
continue;
|
||||
if (skip && digestmap_get(skip, rs->descriptor_digest))
|
||||
if (skip && digest256map_get(skip, (const uint8_t*)rs->descriptor_digest))
|
||||
continue;
|
||||
if (tor_mem_is_zero(rs->descriptor_digest, DIGEST256_LEN))
|
||||
continue;
|
||||
@@ -831,7 +831,7 @@ update_microdesc_downloads(time_t now)
|
||||
const or_options_t *options = get_options();
|
||||
networkstatus_t *consensus;
|
||||
smartlist_t *missing;
|
||||
digestmap_t *pending;
|
||||
digest256map_t *pending;
|
||||
|
||||
if (should_delay_dir_fetches(options, NULL))
|
||||
return;
|
||||
@@ -845,14 +845,14 @@ update_microdesc_downloads(time_t now)
|
||||
if (!we_fetch_microdescriptors(options))
|
||||
return;
|
||||
|
||||
pending = digestmap_new();
|
||||
pending = digest256map_new();
|
||||
list_pending_microdesc_downloads(pending);
|
||||
|
||||
missing = microdesc_list_missing_digest256(consensus,
|
||||
get_microdesc_cache(),
|
||||
1,
|
||||
pending);
|
||||
digestmap_free(pending, NULL);
|
||||
digest256map_free(pending, NULL);
|
||||
|
||||
launch_descriptor_downloads(DIR_PURPOSE_FETCH_MICRODESC,
|
||||
missing, NULL, now);
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ size_t microdesc_average_size(microdesc_cache_t *cache);
|
||||
smartlist_t *microdesc_list_missing_digest256(networkstatus_t *ns,
|
||||
microdesc_cache_t *cache,
|
||||
int downloadable_only,
|
||||
digestmap_t *skip);
|
||||
digest256map_t *skip);
|
||||
|
||||
void microdesc_free_(microdesc_t *md, const char *fname, int line);
|
||||
#define microdesc_free(md) \
|
||||
|
||||
@@ -1123,7 +1123,7 @@ networkstatus_copy_old_consensus_info(networkstatus_t *new_c,
|
||||
rs_new->last_dir_503_at = rs_old->last_dir_503_at;
|
||||
|
||||
if (tor_memeq(rs_old->descriptor_digest, rs_new->descriptor_digest,
|
||||
DIGEST_LEN)) { /* XXXX Change this to digest256_len */
|
||||
DIGEST256_LEN)) {
|
||||
/* And the same descriptor too! */
|
||||
memcpy(&rs_new->dl_status, &rs_old->dl_status,sizeof(download_status_t));
|
||||
}
|
||||
|
||||
+1
-1
@@ -1562,7 +1562,7 @@ update_router_have_minimum_dir_info(void)
|
||||
* is back up and usable, and b) disable some activities that Tor
|
||||
* should only do while circuits are working, like reachability tests
|
||||
* and fetching bridge descriptors only over circuits. */
|
||||
can_complete_circuit = 0;
|
||||
note_that_we_maybe_cant_complete_circuits();
|
||||
|
||||
control_event_client_status(LOG_NOTICE, "NOT_ENOUGH_DIR_INFO");
|
||||
}
|
||||
|
||||
+53
-4
@@ -119,6 +119,7 @@
|
||||
* conflict with system-defined signals. */
|
||||
#define SIGNEWNYM 129
|
||||
#define SIGCLEARDNSCACHE 130
|
||||
#define SIGHEARTBEAT 131
|
||||
|
||||
#if (SIZEOF_CELL_T != 0)
|
||||
/* On Irix, stdlib.h defines a cell_t type, so we need to make sure
|
||||
@@ -676,6 +677,10 @@ typedef enum {
|
||||
|
||||
/* Negative reasons are internal: we never send them in a DESTROY or TRUNCATE
|
||||
* call; they only go to the controller for tracking */
|
||||
|
||||
/* Closing introduction point that were opened in parallel. */
|
||||
#define END_CIRC_REASON_IP_NOW_REDUNDANT -4
|
||||
|
||||
/** Our post-timeout circuit time measurement period expired.
|
||||
* We must give up now */
|
||||
#define END_CIRC_REASON_MEASUREMENT_EXPIRED -3
|
||||
@@ -1426,6 +1431,18 @@ typedef struct or_handshake_state_t {
|
||||
|
||||
/** Length of Extended ORPort connection identifier. */
|
||||
#define EXT_OR_CONN_ID_LEN DIGEST_LEN /* 20 */
|
||||
/*
|
||||
* OR_CONN_HIGHWATER and OR_CONN_LOWWATER moved from connection_or.c so
|
||||
* channeltls.c can see them too.
|
||||
*/
|
||||
|
||||
/** When adding cells to an OR connection's outbuf, keep adding until the
|
||||
* outbuf is at least this long, or we run out of cells. */
|
||||
#define OR_CONN_HIGHWATER (32*1024)
|
||||
|
||||
/** Add cells to an OR connection's outbuf whenever the outbuf's data length
|
||||
* drops below this size. */
|
||||
#define OR_CONN_LOWWATER (16*1024)
|
||||
|
||||
/** Subtype of connection_t for an "OR connection" -- that is, one that speaks
|
||||
* cells over TLS. */
|
||||
@@ -1517,6 +1534,12 @@ typedef struct or_connection_t {
|
||||
/** Last emptied write token bucket in msec since midnight; only used if
|
||||
* TB_EMPTY events are enabled. */
|
||||
uint32_t write_emptied_time;
|
||||
|
||||
/*
|
||||
* Count the number of bytes flushed out on this orconn, and the number of
|
||||
* bytes TLS actually sent - used for overhead estimation for scheduling.
|
||||
*/
|
||||
uint64_t bytes_xmitted, bytes_xmitted_by_tls;
|
||||
} or_connection_t;
|
||||
|
||||
/** Subtype of connection_t for an "edge connection" -- that is, an entry (ap)
|
||||
@@ -4225,8 +4248,18 @@ typedef struct {
|
||||
/** How long (seconds) do we keep a guard before picking a new one? */
|
||||
int GuardLifetime;
|
||||
|
||||
/** Should we send the timestamps that pre-023 hidden services want? */
|
||||
int Support022HiddenServices;
|
||||
/** Low-water mark for global scheduler - start sending when estimated
|
||||
* queued size falls below this threshold.
|
||||
*/
|
||||
uint64_t SchedulerLowWaterMark__;
|
||||
/** High-water mark for global scheduler - stop sending when estimated
|
||||
* queued size exceeds this threshold.
|
||||
*/
|
||||
uint64_t SchedulerHighWaterMark__;
|
||||
/** Flush size for global scheduler - flush this many cells at a time
|
||||
* when sending.
|
||||
*/
|
||||
int SchedulerMaxFlushCells__;
|
||||
} or_options_t;
|
||||
|
||||
/** Persistent state for an onion router, as saved to disk. */
|
||||
@@ -4998,15 +5031,31 @@ typedef enum {
|
||||
|
||||
/** Return value for router_add_to_routerlist() and dirserv_add_descriptor() */
|
||||
typedef enum was_router_added_t {
|
||||
/* Router was added successfully. */
|
||||
ROUTER_ADDED_SUCCESSFULLY = 1,
|
||||
/* Router descriptor was added with warnings to submitter. */
|
||||
ROUTER_ADDED_NOTIFY_GENERATOR = 0,
|
||||
/* Extrainfo document was rejected because no corresponding router
|
||||
* descriptor was found OR router descriptor was rejected because
|
||||
* it was incompatible with its extrainfo document. */
|
||||
ROUTER_BAD_EI = -1,
|
||||
ROUTER_WAS_NOT_NEW = -2,
|
||||
/* Router descriptor was rejected because it is already known. */
|
||||
ROUTER_IS_ALREADY_KNOWN = -2,
|
||||
/* General purpose router was rejected, because it was not listed
|
||||
* in consensus. */
|
||||
ROUTER_NOT_IN_CONSENSUS = -3,
|
||||
/* Router was neither in directory consensus nor in any of
|
||||
* networkstatus documents. Caching it to access later.
|
||||
* (Applies to fetched descriptors only.) */
|
||||
ROUTER_NOT_IN_CONSENSUS_OR_NETWORKSTATUS = -4,
|
||||
/* Router was rejected by directory authority. */
|
||||
ROUTER_AUTHDIR_REJECTS = -5,
|
||||
/* Bridge descriptor was rejected because such bridge was not one
|
||||
* of the bridges we have listed in our configuration. */
|
||||
ROUTER_WAS_NOT_WANTED = -6,
|
||||
ROUTER_WAS_TOO_OLD = -7,
|
||||
/* Router descriptor was rejected because it was older than
|
||||
* OLD_ROUTER_DESC_MAX_AGE. */
|
||||
ROUTER_WAS_TOO_OLD = -7, /* note contrast with 'NOT_NEW' */
|
||||
} was_router_added_t;
|
||||
|
||||
/********************************* routerparse.c ************************/
|
||||
|
||||
+5
-10
@@ -39,6 +39,7 @@
|
||||
#include "router.h"
|
||||
#include "routerlist.h"
|
||||
#include "routerparse.h"
|
||||
#include "scheduler.h"
|
||||
|
||||
static edge_connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell,
|
||||
cell_direction_t cell_direction,
|
||||
@@ -2591,8 +2592,8 @@ packed_cell_get_circid(const packed_cell_t *cell, int wide_circ_ids)
|
||||
* queue of the first active circuit on <b>chan</b>, and write them to
|
||||
* <b>chan</b>->outbuf. Return the number of cells written. Advance
|
||||
* the active circuit pointer to the next active circuit in the ring. */
|
||||
int
|
||||
channel_flush_from_first_active_circuit(channel_t *chan, int max)
|
||||
MOCK_IMPL(int,
|
||||
channel_flush_from_first_active_circuit, (channel_t *chan, int max))
|
||||
{
|
||||
circuitmux_t *cmux = NULL;
|
||||
int n_flushed = 0;
|
||||
@@ -2868,14 +2869,8 @@ append_cell_to_circuit_queue(circuit_t *circ, channel_t *chan,
|
||||
log_debug(LD_GENERAL, "Made a circuit active.");
|
||||
}
|
||||
|
||||
if (!channel_has_queued_writes(chan)) {
|
||||
/* There is no data at all waiting to be sent on the outbuf. Add a
|
||||
* cell, so that we can notice when it gets flushed, flushed_some can
|
||||
* get called, and we can start putting more data onto the buffer then.
|
||||
*/
|
||||
log_debug(LD_GENERAL, "Primed a buffer.");
|
||||
channel_flush_from_first_active_circuit(chan, 1);
|
||||
}
|
||||
/* New way: mark this as having waiting cells for the scheduler */
|
||||
scheduler_channel_has_waiting_cells(chan);
|
||||
}
|
||||
|
||||
/** Append an encoded value of <b>addr</b> to <b>payload_out</b>, which must
|
||||
|
||||
+2
-1
@@ -64,7 +64,8 @@ void append_cell_to_circuit_queue(circuit_t *circ, channel_t *chan,
|
||||
cell_t *cell, cell_direction_t direction,
|
||||
streamid_t fromstream);
|
||||
void channel_unlink_all_circuits(channel_t *chan, smartlist_t *detached_out);
|
||||
int channel_flush_from_first_active_circuit(channel_t *chan, int max);
|
||||
MOCK_DECL(int, channel_flush_from_first_active_circuit,
|
||||
(channel_t *chan, int max));
|
||||
void assert_circuit_mux_okay(channel_t *chan);
|
||||
void update_circuit_on_cmux_(circuit_t *circ, cell_direction_t direction,
|
||||
const char *file, int lineno);
|
||||
|
||||
+4
-21
@@ -130,16 +130,6 @@ rend_client_reextend_intro_circuit(origin_circuit_t *circ)
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Return true iff we should send timestamps in our INTRODUCE1 cells */
|
||||
static int
|
||||
rend_client_should_send_timestamp(void)
|
||||
{
|
||||
if (get_options()->Support022HiddenServices >= 0)
|
||||
return get_options()->Support022HiddenServices;
|
||||
|
||||
return networkstatus_get_param(NULL, "Support022HiddenServices", 1, 0, 1);
|
||||
}
|
||||
|
||||
/** Called when we're trying to connect an ap conn; sends an INTRODUCE1 cell
|
||||
* down introcirc if possible.
|
||||
*/
|
||||
@@ -251,14 +241,8 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
|
||||
REND_DESC_COOKIE_LEN);
|
||||
v3_shift += 2+REND_DESC_COOKIE_LEN;
|
||||
}
|
||||
if (rend_client_should_send_timestamp()) {
|
||||
uint32_t now = (uint32_t)time(NULL);
|
||||
now += 300;
|
||||
now -= now % 600;
|
||||
set_uint32(tmp+v3_shift+1, htonl(now));
|
||||
} else {
|
||||
set_uint32(tmp+v3_shift+1, 0);
|
||||
}
|
||||
/* Once this held a timestamp. */
|
||||
set_uint32(tmp+v3_shift+1, 0);
|
||||
v3_shift += 4;
|
||||
} /* if version 2 only write version number */
|
||||
else if (entry->parsed->protocols & (1<<2)) {
|
||||
@@ -370,8 +354,7 @@ rend_client_rendcirc_has_opened(origin_circuit_t *circ)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to close other intro circuits we launched in parallel
|
||||
* due to timeout.
|
||||
* Called to close other intro circuits we launched in parallel.
|
||||
*/
|
||||
static void
|
||||
rend_client_close_other_intros(const char *onion_address)
|
||||
@@ -388,7 +371,7 @@ rend_client_close_other_intros(const char *onion_address)
|
||||
log_info(LD_REND|LD_CIRC, "Closing introduction circuit %d that we "
|
||||
"built in parallel (Purpose %d).", oc->global_identifier,
|
||||
c->purpose);
|
||||
circuit_mark_for_close(c, END_CIRC_REASON_TIMEOUT);
|
||||
circuit_mark_for_close(c, END_CIRC_REASON_IP_NOW_REDUNDANT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1034,10 +1034,14 @@ rend_cache_store_v2_desc_as_dir(const char *desc)
|
||||
* If the descriptor's service ID does not match
|
||||
* <b>rend_query</b>-\>onion_address, reject it.
|
||||
*
|
||||
* If the descriptor's descriptor ID doesn't match <b>desc_id_base32</b>,
|
||||
* reject it.
|
||||
*
|
||||
* Return an appropriate rend_cache_store_status_t.
|
||||
*/
|
||||
rend_cache_store_status_t
|
||||
rend_cache_store_v2_desc_as_client(const char *desc,
|
||||
const char *desc_id_base32,
|
||||
const rend_data_t *rend_query)
|
||||
{
|
||||
/*XXXX this seems to have a bit of duplicate code with
|
||||
@@ -1064,10 +1068,19 @@ rend_cache_store_v2_desc_as_client(const char *desc,
|
||||
time_t now = time(NULL);
|
||||
char key[REND_SERVICE_ID_LEN_BASE32+2];
|
||||
char service_id[REND_SERVICE_ID_LEN_BASE32+1];
|
||||
char want_desc_id[DIGEST_LEN];
|
||||
rend_cache_entry_t *e;
|
||||
rend_cache_store_status_t retval = RCS_BADDESC;
|
||||
tor_assert(rend_cache);
|
||||
tor_assert(desc);
|
||||
tor_assert(desc_id_base32);
|
||||
memset(want_desc_id, 0, sizeof(want_desc_id));
|
||||
if (base32_decode(want_desc_id, sizeof(want_desc_id),
|
||||
desc_id_base32, strlen(desc_id_base32)) != 0) {
|
||||
log_warn(LD_BUG, "Couldn't decode base32 %s for descriptor id.",
|
||||
escaped_safe_str_client(desc_id_base32));
|
||||
goto err;
|
||||
}
|
||||
/* Parse the descriptor. */
|
||||
if (rend_parse_v2_service_descriptor(&parsed, desc_id, &intro_content,
|
||||
&intro_size, &encoded_size,
|
||||
@@ -1086,6 +1099,12 @@ rend_cache_store_v2_desc_as_client(const char *desc,
|
||||
service_id, safe_str(rend_query->onion_address));
|
||||
goto err;
|
||||
}
|
||||
if (tor_memneq(desc_id, want_desc_id, DIGEST_LEN)) {
|
||||
log_warn(LD_REND, "Received service descriptor for %s with incorrect "
|
||||
"descriptor ID.", service_id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Decode/decrypt introduction points. */
|
||||
if (intro_content) {
|
||||
int n_intro_points;
|
||||
|
||||
@@ -49,6 +49,7 @@ typedef enum {
|
||||
|
||||
rend_cache_store_status_t rend_cache_store_v2_desc_as_dir(const char *desc);
|
||||
rend_cache_store_status_t rend_cache_store_v2_desc_as_client(const char *desc,
|
||||
const char *desc_id_base32,
|
||||
const rend_data_t *rend_query);
|
||||
|
||||
int rend_encode_v2_descriptors(smartlist_t *descs_out,
|
||||
|
||||
+152
-92
@@ -16,6 +16,7 @@
|
||||
#include "circuituse.h"
|
||||
#include "config.h"
|
||||
#include "directory.h"
|
||||
#include "main.h"
|
||||
#include "networkstatus.h"
|
||||
#include "nodelist.h"
|
||||
#include "rendclient.h"
|
||||
@@ -95,6 +96,8 @@ typedef struct rend_service_port_config_t {
|
||||
typedef struct rend_service_t {
|
||||
/* Fields specified in config file */
|
||||
char *directory; /**< where in the filesystem it stores it */
|
||||
int dir_group_readable; /**< if 1, allow group read
|
||||
permissions on directory */
|
||||
smartlist_t *ports; /**< List of rend_service_port_config_t */
|
||||
rend_auth_type_t auth_type; /**< Client authorization type or 0 if no client
|
||||
* authorization is performed. */
|
||||
@@ -359,6 +362,7 @@ rend_config_services(const or_options_t *options, int validate_only)
|
||||
rend_service_t *service = NULL;
|
||||
rend_service_port_config_t *portcfg;
|
||||
smartlist_t *old_service_list = NULL;
|
||||
int ok = 0;
|
||||
|
||||
if (!validate_only) {
|
||||
old_service_list = rend_service_list;
|
||||
@@ -369,87 +373,101 @@ rend_config_services(const or_options_t *options, int validate_only)
|
||||
if (!strcasecmp(line->key, "HiddenServiceDir")) {
|
||||
if (service) { /* register the one we just finished parsing */
|
||||
if (validate_only)
|
||||
rend_service_free(service);
|
||||
else
|
||||
rend_add_service(service);
|
||||
}
|
||||
service = tor_malloc_zero(sizeof(rend_service_t));
|
||||
service->directory = tor_strdup(line->value);
|
||||
service->ports = smartlist_new();
|
||||
service->intro_period_started = time(NULL);
|
||||
service->n_intro_points_wanted = NUM_INTRO_POINTS_DEFAULT;
|
||||
continue;
|
||||
}
|
||||
if (!service) {
|
||||
log_warn(LD_CONFIG, "%s with no preceding HiddenServiceDir directive",
|
||||
line->key);
|
||||
rend_service_free(service);
|
||||
return -1;
|
||||
}
|
||||
if (!strcasecmp(line->key, "HiddenServicePort")) {
|
||||
portcfg = parse_port_config(line->value);
|
||||
if (!portcfg) {
|
||||
rend_service_free(service);
|
||||
return -1;
|
||||
}
|
||||
smartlist_add(service->ports, portcfg);
|
||||
} else if (!strcasecmp(line->key, "HiddenServiceAuthorizeClient")) {
|
||||
/* Parse auth type and comma-separated list of client names and add a
|
||||
* rend_authorized_client_t for each client to the service's list
|
||||
* of authorized clients. */
|
||||
smartlist_t *type_names_split, *clients;
|
||||
const char *authname;
|
||||
int num_clients;
|
||||
if (service->auth_type != REND_NO_AUTH) {
|
||||
log_warn(LD_CONFIG, "Got multiple HiddenServiceAuthorizeClient "
|
||||
"lines for a single service.");
|
||||
rend_service_free(service);
|
||||
return -1;
|
||||
}
|
||||
type_names_split = smartlist_new();
|
||||
smartlist_split_string(type_names_split, line->value, " ", 0, 2);
|
||||
if (smartlist_len(type_names_split) < 1) {
|
||||
log_warn(LD_BUG, "HiddenServiceAuthorizeClient has no value. This "
|
||||
"should have been prevented when parsing the "
|
||||
"configuration.");
|
||||
smartlist_free(type_names_split);
|
||||
rend_service_free(service);
|
||||
return -1;
|
||||
}
|
||||
authname = smartlist_get(type_names_split, 0);
|
||||
if (!strcasecmp(authname, "basic")) {
|
||||
service->auth_type = REND_BASIC_AUTH;
|
||||
} else if (!strcasecmp(authname, "stealth")) {
|
||||
service->auth_type = REND_STEALTH_AUTH;
|
||||
} else {
|
||||
log_warn(LD_CONFIG, "HiddenServiceAuthorizeClient contains "
|
||||
"unrecognized auth-type '%s'. Only 'basic' or 'stealth' "
|
||||
"are recognized.",
|
||||
(char *) smartlist_get(type_names_split, 0));
|
||||
SMARTLIST_FOREACH(type_names_split, char *, cp, tor_free(cp));
|
||||
smartlist_free(type_names_split);
|
||||
rend_service_free(service);
|
||||
return -1;
|
||||
}
|
||||
service->clients = smartlist_new();
|
||||
if (smartlist_len(type_names_split) < 2) {
|
||||
log_warn(LD_CONFIG, "HiddenServiceAuthorizeClient contains "
|
||||
"auth-type '%s', but no client names.",
|
||||
service->auth_type == REND_BASIC_AUTH ? "basic" : "stealth");
|
||||
SMARTLIST_FOREACH(type_names_split, char *, cp, tor_free(cp));
|
||||
smartlist_free(type_names_split);
|
||||
continue;
|
||||
}
|
||||
clients = smartlist_new();
|
||||
smartlist_split_string(clients, smartlist_get(type_names_split, 1),
|
||||
",", SPLIT_SKIP_SPACE, 0);
|
||||
SMARTLIST_FOREACH(type_names_split, char *, cp, tor_free(cp));
|
||||
smartlist_free(type_names_split);
|
||||
/* Remove duplicate client names. */
|
||||
num_clients = smartlist_len(clients);
|
||||
smartlist_sort_strings(clients);
|
||||
smartlist_uniq_strings(clients);
|
||||
if (smartlist_len(clients) < num_clients) {
|
||||
rend_service_free(service);
|
||||
else
|
||||
rend_add_service(service);
|
||||
}
|
||||
service = tor_malloc_zero(sizeof(rend_service_t));
|
||||
service->directory = tor_strdup(line->value);
|
||||
service->ports = smartlist_new();
|
||||
service->intro_period_started = time(NULL);
|
||||
service->n_intro_points_wanted = NUM_INTRO_POINTS_DEFAULT;
|
||||
continue;
|
||||
}
|
||||
if (!service) {
|
||||
log_warn(LD_CONFIG, "%s with no preceding HiddenServiceDir directive",
|
||||
line->key);
|
||||
rend_service_free(service);
|
||||
return -1;
|
||||
}
|
||||
if (!strcasecmp(line->key, "HiddenServicePort")) {
|
||||
portcfg = parse_port_config(line->value);
|
||||
if (!portcfg) {
|
||||
rend_service_free(service);
|
||||
return -1;
|
||||
}
|
||||
smartlist_add(service->ports, portcfg);
|
||||
} else if (!strcasecmp(line->key,
|
||||
"HiddenServiceDirGroupReadable")) {
|
||||
service->dir_group_readable = (int)tor_parse_long(line->value,
|
||||
10, 0, 1, &ok, NULL);
|
||||
if (!ok) {
|
||||
log_warn(LD_CONFIG,
|
||||
"HiddenServiceDirGroupReadable should be 0 or 1, not %s",
|
||||
line->value);
|
||||
rend_service_free(service);
|
||||
return -1;
|
||||
}
|
||||
log_info(LD_CONFIG,
|
||||
"HiddenServiceDirGroupReadable=%d for %s",
|
||||
service->dir_group_readable, service->directory);
|
||||
} else if (!strcasecmp(line->key, "HiddenServiceAuthorizeClient")) {
|
||||
/* Parse auth type and comma-separated list of client names and add a
|
||||
* rend_authorized_client_t for each client to the service's list
|
||||
* of authorized clients. */
|
||||
smartlist_t *type_names_split, *clients;
|
||||
const char *authname;
|
||||
int num_clients;
|
||||
if (service->auth_type != REND_NO_AUTH) {
|
||||
log_warn(LD_CONFIG, "Got multiple HiddenServiceAuthorizeClient "
|
||||
"lines for a single service.");
|
||||
rend_service_free(service);
|
||||
return -1;
|
||||
}
|
||||
type_names_split = smartlist_new();
|
||||
smartlist_split_string(type_names_split, line->value, " ", 0, 2);
|
||||
if (smartlist_len(type_names_split) < 1) {
|
||||
log_warn(LD_BUG, "HiddenServiceAuthorizeClient has no value. This "
|
||||
"should have been prevented when parsing the "
|
||||
"configuration.");
|
||||
smartlist_free(type_names_split);
|
||||
rend_service_free(service);
|
||||
return -1;
|
||||
}
|
||||
authname = smartlist_get(type_names_split, 0);
|
||||
if (!strcasecmp(authname, "basic")) {
|
||||
service->auth_type = REND_BASIC_AUTH;
|
||||
} else if (!strcasecmp(authname, "stealth")) {
|
||||
service->auth_type = REND_STEALTH_AUTH;
|
||||
} else {
|
||||
log_warn(LD_CONFIG, "HiddenServiceAuthorizeClient contains "
|
||||
"unrecognized auth-type '%s'. Only 'basic' or 'stealth' "
|
||||
"are recognized.",
|
||||
(char *) smartlist_get(type_names_split, 0));
|
||||
SMARTLIST_FOREACH(type_names_split, char *, cp, tor_free(cp));
|
||||
smartlist_free(type_names_split);
|
||||
rend_service_free(service);
|
||||
return -1;
|
||||
}
|
||||
service->clients = smartlist_new();
|
||||
if (smartlist_len(type_names_split) < 2) {
|
||||
log_warn(LD_CONFIG, "HiddenServiceAuthorizeClient contains "
|
||||
"auth-type '%s', but no client names.",
|
||||
service->auth_type == REND_BASIC_AUTH ? "basic" : "stealth");
|
||||
SMARTLIST_FOREACH(type_names_split, char *, cp, tor_free(cp));
|
||||
smartlist_free(type_names_split);
|
||||
continue;
|
||||
}
|
||||
clients = smartlist_new();
|
||||
smartlist_split_string(clients, smartlist_get(type_names_split, 1),
|
||||
",", SPLIT_SKIP_SPACE, 0);
|
||||
SMARTLIST_FOREACH(type_names_split, char *, cp, tor_free(cp));
|
||||
smartlist_free(type_names_split);
|
||||
/* Remove duplicate client names. */
|
||||
num_clients = smartlist_len(clients);
|
||||
smartlist_sort_strings(clients);
|
||||
smartlist_uniq_strings(clients);
|
||||
if (smartlist_len(clients) < num_clients) {
|
||||
log_info(LD_CONFIG, "HiddenServiceAuthorizeClient contains %d "
|
||||
"duplicate client name(s); removing.",
|
||||
num_clients - smartlist_len(clients));
|
||||
@@ -513,10 +531,21 @@ rend_config_services(const or_options_t *options, int validate_only)
|
||||
}
|
||||
}
|
||||
if (service) {
|
||||
if (validate_only)
|
||||
cpd_check_t check_opts = CPD_CHECK_MODE_ONLY;
|
||||
if (service->dir_group_readable) {
|
||||
check_opts |= CPD_GROUP_READ;
|
||||
}
|
||||
|
||||
if (check_private_dir(service->directory, check_opts, options->User) < 0) {
|
||||
rend_service_free(service);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (validate_only) {
|
||||
rend_service_free(service);
|
||||
} else {
|
||||
rend_add_service(service);
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is a reload and there were hidden services configured before,
|
||||
@@ -693,10 +722,23 @@ rend_service_load_keys(rend_service_t *s)
|
||||
{
|
||||
char fname[512];
|
||||
char buf[128];
|
||||
cpd_check_t check_opts = CPD_CREATE;
|
||||
|
||||
if (s->dir_group_readable) {
|
||||
check_opts |= CPD_GROUP_READ;
|
||||
}
|
||||
/* Check/create directory */
|
||||
if (check_private_dir(s->directory, CPD_CREATE, get_options()->User) < 0)
|
||||
if (check_private_dir(s->directory, check_opts, get_options()->User) < 0) {
|
||||
return -1;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
if (s->dir_group_readable) {
|
||||
/* Only new dirs created get new opts, also enforce group read. */
|
||||
if (chmod(s->directory, 0750)) {
|
||||
log_warn(LD_FS,"Unable to make %s group-readable.", s->directory);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Load key */
|
||||
if (strlcpy(fname,s->directory,sizeof(fname)) >= sizeof(fname) ||
|
||||
@@ -706,7 +748,7 @@ rend_service_load_keys(rend_service_t *s)
|
||||
s->directory);
|
||||
return -1;
|
||||
}
|
||||
s->private_key = init_key_from_file(fname, 1, LOG_ERR);
|
||||
s->private_key = init_key_from_file(fname, 1, LOG_ERR, 0);
|
||||
if (!s->private_key)
|
||||
return -1;
|
||||
|
||||
@@ -733,6 +775,15 @@ rend_service_load_keys(rend_service_t *s)
|
||||
memwipe(buf, 0, sizeof(buf));
|
||||
return -1;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
if (s->dir_group_readable) {
|
||||
/* Also verify hostname file created with group read. */
|
||||
if (chmod(fname, 0640))
|
||||
log_warn(LD_FS,"Unable to make hidden hostname file %s group-readable.",
|
||||
fname);
|
||||
}
|
||||
#endif
|
||||
|
||||
memwipe(buf, 0, sizeof(buf));
|
||||
|
||||
/* If client authorization is configured, load or generate keys. */
|
||||
@@ -3028,15 +3079,20 @@ rend_services_introduce(void)
|
||||
int intro_point_set_changed, prev_intro_nodes;
|
||||
unsigned int n_intro_points_unexpired;
|
||||
unsigned int n_intro_points_to_open;
|
||||
smartlist_t *intro_nodes;
|
||||
time_t now;
|
||||
const or_options_t *options = get_options();
|
||||
/* List of nodes we need to _exclude_ when choosing a new node to establish
|
||||
* an intro point to. */
|
||||
smartlist_t *exclude_nodes;
|
||||
|
||||
intro_nodes = smartlist_new();
|
||||
if (!have_completed_a_circuit())
|
||||
return;
|
||||
|
||||
exclude_nodes = smartlist_new();
|
||||
now = time(NULL);
|
||||
|
||||
for (i=0; i < smartlist_len(rend_service_list); ++i) {
|
||||
smartlist_clear(intro_nodes);
|
||||
smartlist_clear(exclude_nodes);
|
||||
service = smartlist_get(rend_service_list, i);
|
||||
|
||||
tor_assert(service);
|
||||
@@ -3135,8 +3191,10 @@ rend_services_introduce(void)
|
||||
if (intro != NULL && intro->time_expiring == -1)
|
||||
++n_intro_points_unexpired;
|
||||
|
||||
/* Add the valid node to the exclusion list so we don't try to establish
|
||||
* an introduction point to it again. */
|
||||
if (node)
|
||||
smartlist_add(intro_nodes, (void*)node);
|
||||
smartlist_add(exclude_nodes, (void*)node);
|
||||
} SMARTLIST_FOREACH_END(intro);
|
||||
|
||||
if (!intro_point_set_changed &&
|
||||
@@ -3172,7 +3230,7 @@ rend_services_introduce(void)
|
||||
router_crn_flags_t flags = CRN_NEED_UPTIME|CRN_NEED_DESC;
|
||||
if (get_options()->AllowInvalid_ & ALLOW_INVALID_INTRODUCTION)
|
||||
flags |= CRN_ALLOW_INVALID;
|
||||
node = router_choose_random_node(intro_nodes,
|
||||
node = router_choose_random_node(exclude_nodes,
|
||||
options->ExcludeNodes, flags);
|
||||
if (!node) {
|
||||
log_warn(LD_REND,
|
||||
@@ -3183,7 +3241,9 @@ rend_services_introduce(void)
|
||||
break;
|
||||
}
|
||||
intro_point_set_changed = 1;
|
||||
smartlist_add(intro_nodes, (void*)node);
|
||||
/* Add the choosen node to the exclusion list in order to avoid to pick
|
||||
* it again in the next iteration. */
|
||||
smartlist_add(exclude_nodes, (void*)node);
|
||||
intro = tor_malloc_zero(sizeof(rend_intro_point_t));
|
||||
intro->extend_info = extend_info_from_node(node, 0);
|
||||
intro->intro_key = crypto_pk_new();
|
||||
@@ -3212,7 +3272,7 @@ rend_services_introduce(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
smartlist_free(intro_nodes);
|
||||
smartlist_free(exclude_nodes);
|
||||
}
|
||||
|
||||
/** Regenerate and upload rendezvous service descriptors for all
|
||||
|
||||
+14
-10
@@ -391,13 +391,15 @@ log_new_relay_greeting(void)
|
||||
already_logged = 1;
|
||||
}
|
||||
|
||||
/** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist,
|
||||
* or is empty, and <b>generate</b> is true, create a new RSA key and save it
|
||||
* in <b>fname</b>. Return the read/created key, or NULL on error. Log all
|
||||
* errors at level <b>severity</b>.
|
||||
/** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist
|
||||
* and <b>generate</b> is true, create a new RSA key and save it in
|
||||
* <b>fname</b>. Return the read/created key, or NULL on error. Log all
|
||||
* errors at level <b>severity</b>. If <b>log_greeting</b> is non-zero and a
|
||||
* new key was created, log_new_relay_greeting() is called.
|
||||
*/
|
||||
crypto_pk_t *
|
||||
init_key_from_file(const char *fname, int generate, int severity)
|
||||
init_key_from_file(const char *fname, int generate, int severity,
|
||||
int log_greeting)
|
||||
{
|
||||
crypto_pk_t *prkey = NULL;
|
||||
|
||||
@@ -439,7 +441,9 @@ init_key_from_file(const char *fname, int generate, int severity)
|
||||
goto error;
|
||||
}
|
||||
log_info(LD_GENERAL, "Generated key seems valid");
|
||||
log_new_relay_greeting();
|
||||
if (log_greeting) {
|
||||
log_new_relay_greeting();
|
||||
}
|
||||
if (crypto_pk_write_private_key_to_filename(prkey, fname)) {
|
||||
tor_log(severity, LD_FS,
|
||||
"Couldn't write generated key to \"%s\".", fname);
|
||||
@@ -554,7 +558,7 @@ load_authority_keyset(int legacy, crypto_pk_t **key_out,
|
||||
|
||||
fname = get_datadir_fname2("keys",
|
||||
legacy ? "legacy_signing_key" : "authority_signing_key");
|
||||
signing_key = init_key_from_file(fname, 0, LOG_INFO);
|
||||
signing_key = init_key_from_file(fname, 0, LOG_INFO, 0);
|
||||
if (!signing_key) {
|
||||
log_warn(LD_DIR, "No version 3 directory key found in %s", fname);
|
||||
goto done;
|
||||
@@ -837,7 +841,7 @@ init_keys(void)
|
||||
/* 1b. Read identity key. Make it if none is found. */
|
||||
keydir = get_datadir_fname2("keys", "secret_id_key");
|
||||
log_info(LD_GENERAL,"Reading/making identity key \"%s\"...",keydir);
|
||||
prkey = init_key_from_file(keydir, 1, LOG_ERR);
|
||||
prkey = init_key_from_file(keydir, 1, LOG_ERR, 1);
|
||||
tor_free(keydir);
|
||||
if (!prkey) return -1;
|
||||
set_server_identity_key(prkey);
|
||||
@@ -860,7 +864,7 @@ init_keys(void)
|
||||
/* 2. Read onion key. Make it if none is found. */
|
||||
keydir = get_datadir_fname2("keys", "secret_onion_key");
|
||||
log_info(LD_GENERAL,"Reading/making onion key \"%s\"...",keydir);
|
||||
prkey = init_key_from_file(keydir, 1, LOG_ERR);
|
||||
prkey = init_key_from_file(keydir, 1, LOG_ERR, 1);
|
||||
tor_free(keydir);
|
||||
if (!prkey) return -1;
|
||||
set_onion_key(prkey);
|
||||
@@ -887,7 +891,7 @@ init_keys(void)
|
||||
if (!lastonionkey && file_status(keydir) == FN_FILE) {
|
||||
/* Load keys from non-empty files only.
|
||||
* Missing old keys won't be replaced with freshly generated keys. */
|
||||
prkey = init_key_from_file(keydir, 0, LOG_ERR);
|
||||
prkey = init_key_from_file(keydir, 0, LOG_ERR, 0);
|
||||
if (prkey)
|
||||
lastonionkey = prkey;
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ crypto_pk_t *get_my_v3_legacy_signing_key(void);
|
||||
void dup_onion_keys(crypto_pk_t **key, crypto_pk_t **last);
|
||||
void rotate_onion_key(void);
|
||||
crypto_pk_t *init_key_from_file(const char *fname, int generate,
|
||||
int severity);
|
||||
int severity, int log_greeting);
|
||||
void v3_authority_check_key_expiry(void);
|
||||
|
||||
di_digest256_map_t *construct_ntor_key_map(void);
|
||||
|
||||
+46
-242
@@ -79,6 +79,7 @@ static const char *signed_descriptor_get_body_impl(
|
||||
const signed_descriptor_t *desc,
|
||||
int with_annotations);
|
||||
static void list_pending_downloads(digestmap_t *result,
|
||||
digest256map_t *result256,
|
||||
int purpose, const char *prefix);
|
||||
static void list_pending_fpsk_downloads(fp_pair_map_t *result);
|
||||
static void launch_dummy_descriptor_download_as_needed(time_t now,
|
||||
@@ -717,7 +718,8 @@ authority_certs_fetch_missing(networkstatus_t *status, time_t now)
|
||||
* First, we get the lists of already pending downloads so we don't
|
||||
* duplicate effort.
|
||||
*/
|
||||
list_pending_downloads(pending_id, DIR_PURPOSE_FETCH_CERTIFICATE, "fp/");
|
||||
list_pending_downloads(pending_id, NULL,
|
||||
DIR_PURPOSE_FETCH_CERTIFICATE, "fp/");
|
||||
list_pending_fpsk_downloads(pending_cert);
|
||||
|
||||
/*
|
||||
@@ -1535,7 +1537,7 @@ dirserver_choose_by_weight(const smartlist_t *servers, double authority_weight)
|
||||
u64_dbl_t *weights;
|
||||
const dir_server_t *ds;
|
||||
|
||||
weights = tor_calloc(sizeof(u64_dbl_t), n);
|
||||
weights = tor_calloc(n, sizeof(u64_dbl_t));
|
||||
for (i = 0; i < n; ++i) {
|
||||
ds = smartlist_get(servers, i);
|
||||
weights[i].dbl = ds->weight;
|
||||
@@ -2029,9 +2031,10 @@ compute_weighted_bandwidths(const smartlist_t *sl,
|
||||
if (Wg < 0 || Wm < 0 || We < 0 || Wd < 0 || Wgb < 0 || Wmb < 0 || Wdb < 0
|
||||
|| Web < 0) {
|
||||
log_debug(LD_CIRC,
|
||||
"Got negative bandwidth weights. Defaulting to old selection"
|
||||
"Got negative bandwidth weights. Defaulting to naive selection"
|
||||
" algorithm.");
|
||||
return -1; // Use old algorithm.
|
||||
Wg = Wm = We = Wd = weight_scale;
|
||||
Wgb = Wmb = Web = Wdb = weight_scale;
|
||||
}
|
||||
|
||||
Wg /= weight_scale;
|
||||
@@ -2044,9 +2047,10 @@ compute_weighted_bandwidths(const smartlist_t *sl,
|
||||
Web /= weight_scale;
|
||||
Wdb /= weight_scale;
|
||||
|
||||
bandwidths = tor_calloc(sizeof(u64_dbl_t), smartlist_len(sl));
|
||||
bandwidths = tor_calloc(smartlist_len(sl), sizeof(u64_dbl_t));
|
||||
|
||||
// Cycle through smartlist and total the bandwidth.
|
||||
static int warned_missing_bw = 0;
|
||||
SMARTLIST_FOREACH_BEGIN(sl, const node_t *, node) {
|
||||
int is_exit = 0, is_guard = 0, is_dir = 0, this_bw = 0;
|
||||
double weight = 1;
|
||||
@@ -2055,15 +2059,18 @@ compute_weighted_bandwidths(const smartlist_t *sl,
|
||||
is_dir = node_is_dir(node);
|
||||
if (node->rs) {
|
||||
if (!node->rs->has_bandwidth) {
|
||||
tor_free(bandwidths);
|
||||
/* This should never happen, unless all the authorites downgrade
|
||||
* to 0.2.0 or rogue routerstatuses get inserted into our consensus. */
|
||||
log_warn(LD_BUG,
|
||||
"Consensus is not listing bandwidths. Defaulting back to "
|
||||
"old router selection algorithm.");
|
||||
return -1;
|
||||
if (! warned_missing_bw) {
|
||||
log_warn(LD_BUG,
|
||||
"Consensus is missing some bandwidths. Using a naive "
|
||||
"router selection algorithm");
|
||||
warned_missing_bw = 1;
|
||||
}
|
||||
this_bw = 30000; /* Chosen arbitrarily */
|
||||
} else {
|
||||
this_bw = kb_to_bytes(node->rs->bandwidth_kb);
|
||||
}
|
||||
this_bw = kb_to_bytes(node->rs->bandwidth_kb);
|
||||
} else if (node->ri) {
|
||||
/* bridge or other descriptor not in our consensus */
|
||||
this_bw = bridge_get_advertised_bandwidth_bounded(node->ri);
|
||||
@@ -2140,226 +2147,13 @@ frac_nodes_with_descriptors(const smartlist_t *sl,
|
||||
return present / total;
|
||||
}
|
||||
|
||||
/** Helper function:
|
||||
* choose a random node_t element of smartlist <b>sl</b>, weighted by
|
||||
* the advertised bandwidth of each element.
|
||||
*
|
||||
* If <b>rule</b>==WEIGHT_FOR_EXIT. we're picking an exit node: consider all
|
||||
* nodes' bandwidth equally regardless of their Exit status, since there may
|
||||
* be some in the list because they exit to obscure ports. If
|
||||
* <b>rule</b>==NO_WEIGHTING, we're picking a non-exit node: weight
|
||||
* exit-node's bandwidth less depending on the smallness of the fraction of
|
||||
* Exit-to-total bandwidth. If <b>rule</b>==WEIGHT_FOR_GUARD, we're picking a
|
||||
* guard node: consider all guard's bandwidth equally. Otherwise, weight
|
||||
* guards proportionally less.
|
||||
*/
|
||||
static const node_t *
|
||||
smartlist_choose_node_by_bandwidth(const smartlist_t *sl,
|
||||
bandwidth_weight_rule_t rule)
|
||||
{
|
||||
unsigned int i;
|
||||
u64_dbl_t *bandwidths;
|
||||
int is_exit;
|
||||
int is_guard;
|
||||
int is_fast;
|
||||
double total_nonexit_bw = 0, total_exit_bw = 0;
|
||||
double total_nonguard_bw = 0, total_guard_bw = 0;
|
||||
double exit_weight;
|
||||
double guard_weight;
|
||||
int n_unknown = 0;
|
||||
bitarray_t *fast_bits;
|
||||
bitarray_t *exit_bits;
|
||||
bitarray_t *guard_bits;
|
||||
|
||||
// This function does not support WEIGHT_FOR_DIR
|
||||
// or WEIGHT_FOR_MID
|
||||
if (rule == WEIGHT_FOR_DIR || rule == WEIGHT_FOR_MID) {
|
||||
rule = NO_WEIGHTING;
|
||||
}
|
||||
|
||||
/* Can't choose exit and guard at same time */
|
||||
tor_assert(rule == NO_WEIGHTING ||
|
||||
rule == WEIGHT_FOR_EXIT ||
|
||||
rule == WEIGHT_FOR_GUARD);
|
||||
|
||||
if (smartlist_len(sl) == 0) {
|
||||
log_info(LD_CIRC,
|
||||
"Empty routerlist passed in to old node selection for rule %s",
|
||||
bandwidth_weight_rule_to_string(rule));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* First count the total bandwidth weight, and make a list
|
||||
* of each value. We use UINT64_MAX to indicate "unknown". */
|
||||
bandwidths = tor_calloc(sizeof(u64_dbl_t), smartlist_len(sl));
|
||||
fast_bits = bitarray_init_zero(smartlist_len(sl));
|
||||
exit_bits = bitarray_init_zero(smartlist_len(sl));
|
||||
guard_bits = bitarray_init_zero(smartlist_len(sl));
|
||||
|
||||
/* Iterate over all the routerinfo_t or routerstatus_t, and */
|
||||
SMARTLIST_FOREACH_BEGIN(sl, const node_t *, node) {
|
||||
/* first, learn what bandwidth we think i has */
|
||||
int is_known = 1;
|
||||
uint32_t this_bw = 0;
|
||||
i = node_sl_idx;
|
||||
|
||||
is_exit = node_is_good_exit(node);
|
||||
is_guard = node->is_possible_guard;
|
||||
if (node->rs) {
|
||||
if (node->rs->has_bandwidth) {
|
||||
this_bw = kb_to_bytes(node->rs->bandwidth_kb);
|
||||
} else { /* guess */
|
||||
is_known = 0;
|
||||
}
|
||||
} else if (node->ri) {
|
||||
/* Must be a bridge if we're willing to use it */
|
||||
this_bw = bridge_get_advertised_bandwidth_bounded(node->ri);
|
||||
}
|
||||
|
||||
if (is_exit)
|
||||
bitarray_set(exit_bits, i);
|
||||
if (is_guard)
|
||||
bitarray_set(guard_bits, i);
|
||||
if (node->is_fast)
|
||||
bitarray_set(fast_bits, i);
|
||||
|
||||
if (is_known) {
|
||||
bandwidths[i].dbl = this_bw;
|
||||
if (is_guard)
|
||||
total_guard_bw += this_bw;
|
||||
else
|
||||
total_nonguard_bw += this_bw;
|
||||
if (is_exit)
|
||||
total_exit_bw += this_bw;
|
||||
else
|
||||
total_nonexit_bw += this_bw;
|
||||
} else {
|
||||
++n_unknown;
|
||||
bandwidths[i].dbl = -1.0;
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(node);
|
||||
|
||||
#define EPSILON .1
|
||||
|
||||
/* Now, fill in the unknown values. */
|
||||
if (n_unknown) {
|
||||
int32_t avg_fast, avg_slow;
|
||||
if (total_exit_bw+total_nonexit_bw < EPSILON) {
|
||||
/* if there's some bandwidth, there's at least one known router,
|
||||
* so no worries about div by 0 here */
|
||||
int n_known = smartlist_len(sl)-n_unknown;
|
||||
avg_fast = avg_slow = (int32_t)
|
||||
((total_exit_bw+total_nonexit_bw)/((uint64_t) n_known));
|
||||
} else {
|
||||
avg_fast = 40000;
|
||||
avg_slow = 20000;
|
||||
}
|
||||
for (i=0; i<(unsigned)smartlist_len(sl); ++i) {
|
||||
if (bandwidths[i].dbl >= 0.0)
|
||||
continue;
|
||||
is_fast = bitarray_is_set(fast_bits, i);
|
||||
is_exit = bitarray_is_set(exit_bits, i);
|
||||
is_guard = bitarray_is_set(guard_bits, i);
|
||||
bandwidths[i].dbl = is_fast ? avg_fast : avg_slow;
|
||||
if (is_exit)
|
||||
total_exit_bw += bandwidths[i].dbl;
|
||||
else
|
||||
total_nonexit_bw += bandwidths[i].dbl;
|
||||
if (is_guard)
|
||||
total_guard_bw += bandwidths[i].dbl;
|
||||
else
|
||||
total_nonguard_bw += bandwidths[i].dbl;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's no bandwidth at all, pick at random. */
|
||||
if (total_exit_bw+total_nonexit_bw < EPSILON) {
|
||||
tor_free(bandwidths);
|
||||
tor_free(fast_bits);
|
||||
tor_free(exit_bits);
|
||||
tor_free(guard_bits);
|
||||
return smartlist_choose(sl);
|
||||
}
|
||||
|
||||
/* Figure out how to weight exits and guards */
|
||||
{
|
||||
double all_bw = U64_TO_DBL(total_exit_bw+total_nonexit_bw);
|
||||
double exit_bw = U64_TO_DBL(total_exit_bw);
|
||||
double guard_bw = U64_TO_DBL(total_guard_bw);
|
||||
/*
|
||||
* For detailed derivation of this formula, see
|
||||
* http://archives.seul.org/or/dev/Jul-2007/msg00056.html
|
||||
*/
|
||||
if (rule == WEIGHT_FOR_EXIT || total_exit_bw<EPSILON)
|
||||
exit_weight = 1.0;
|
||||
else
|
||||
exit_weight = 1.0 - all_bw/(3.0*exit_bw);
|
||||
|
||||
if (rule == WEIGHT_FOR_GUARD || total_guard_bw<EPSILON)
|
||||
guard_weight = 1.0;
|
||||
else
|
||||
guard_weight = 1.0 - all_bw/(3.0*guard_bw);
|
||||
|
||||
if (exit_weight <= 0.0)
|
||||
exit_weight = 0.0;
|
||||
|
||||
if (guard_weight <= 0.0)
|
||||
guard_weight = 0.0;
|
||||
|
||||
for (i=0; i < (unsigned)smartlist_len(sl); i++) {
|
||||
tor_assert(bandwidths[i].dbl >= 0.0);
|
||||
|
||||
is_exit = bitarray_is_set(exit_bits, i);
|
||||
is_guard = bitarray_is_set(guard_bits, i);
|
||||
if (is_exit && is_guard)
|
||||
bandwidths[i].dbl *= exit_weight * guard_weight;
|
||||
else if (is_guard)
|
||||
bandwidths[i].dbl *= guard_weight;
|
||||
else if (is_exit)
|
||||
bandwidths[i].dbl *= exit_weight;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
log_debug(LD_CIRC, "Total weighted bw = "U64_FORMAT
|
||||
", exit bw = "U64_FORMAT
|
||||
", nonexit bw = "U64_FORMAT", exit weight = %f "
|
||||
"(for exit == %d)"
|
||||
", guard bw = "U64_FORMAT
|
||||
", nonguard bw = "U64_FORMAT", guard weight = %f "
|
||||
"(for guard == %d)",
|
||||
U64_PRINTF_ARG(total_bw),
|
||||
U64_PRINTF_ARG(total_exit_bw), U64_PRINTF_ARG(total_nonexit_bw),
|
||||
exit_weight, (int)(rule == WEIGHT_FOR_EXIT),
|
||||
U64_PRINTF_ARG(total_guard_bw), U64_PRINTF_ARG(total_nonguard_bw),
|
||||
guard_weight, (int)(rule == WEIGHT_FOR_GUARD));
|
||||
#endif
|
||||
|
||||
scale_array_elements_to_u64(bandwidths, smartlist_len(sl), NULL);
|
||||
|
||||
{
|
||||
int idx = choose_array_element_by_weight(bandwidths,
|
||||
smartlist_len(sl));
|
||||
tor_free(bandwidths);
|
||||
tor_free(fast_bits);
|
||||
tor_free(exit_bits);
|
||||
tor_free(guard_bits);
|
||||
return idx < 0 ? NULL : smartlist_get(sl, idx);
|
||||
}
|
||||
}
|
||||
|
||||
/** Choose a random element of status list <b>sl</b>, weighted by
|
||||
* the advertised bandwidth of each node */
|
||||
const node_t *
|
||||
node_sl_choose_by_bandwidth(const smartlist_t *sl,
|
||||
bandwidth_weight_rule_t rule)
|
||||
{ /*XXXX MOVE */
|
||||
const node_t *ret;
|
||||
if ((ret = smartlist_choose_node_by_bandwidth_weights(sl, rule))) {
|
||||
return ret;
|
||||
} else {
|
||||
return smartlist_choose_node_by_bandwidth(sl, rule);
|
||||
}
|
||||
return smartlist_choose_node_by_bandwidth_weights(sl, rule);
|
||||
}
|
||||
|
||||
/** Return a random running node from the nodelist. Never
|
||||
@@ -2944,6 +2738,7 @@ MOCK_IMPL(STATIC was_router_added_t,
|
||||
extrainfo_insert,(routerlist_t *rl, extrainfo_t *ei))
|
||||
{
|
||||
was_router_added_t r;
|
||||
const char *compatibility_error_msg;
|
||||
routerinfo_t *ri = rimap_get(rl->identity_map,
|
||||
ei->cache_info.identity_digest);
|
||||
signed_descriptor_t *sd =
|
||||
@@ -2960,9 +2755,14 @@ extrainfo_insert,(routerlist_t *rl, extrainfo_t *ei))
|
||||
r = ROUTER_NOT_IN_CONSENSUS;
|
||||
goto done;
|
||||
}
|
||||
if (routerinfo_incompatible_with_extrainfo(ri, ei, sd, NULL)) {
|
||||
if (routerinfo_incompatible_with_extrainfo(ri, ei, sd,
|
||||
&compatibility_error_msg)) {
|
||||
r = (ri->cache_info.extrainfo_is_bogus) ?
|
||||
ROUTER_BAD_EI : ROUTER_NOT_IN_CONSENSUS;
|
||||
|
||||
log_warn(LD_DIR,"router info incompatible with extra info (reason: %s)",
|
||||
compatibility_error_msg);
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -3375,7 +3175,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
|
||||
router_describe(router));
|
||||
*msg = "Router descriptor was not new.";
|
||||
routerinfo_free(router);
|
||||
return ROUTER_WAS_NOT_NEW;
|
||||
return ROUTER_IS_ALREADY_KNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3460,7 +3260,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
|
||||
&routerlist->desc_store);
|
||||
routerlist_insert_old(routerlist, router);
|
||||
*msg = "Router descriptor was not new.";
|
||||
return ROUTER_WAS_NOT_NEW;
|
||||
return ROUTER_IS_ALREADY_KNOWN;
|
||||
} else {
|
||||
/* Same key, and either new, or listed in the consensus. */
|
||||
log_debug(LD_DIR, "Replacing entry for router %s",
|
||||
@@ -3583,9 +3383,9 @@ routerlist_remove_old_cached_routers_with_id(time_t now,
|
||||
n_extra = n - mdpr;
|
||||
}
|
||||
|
||||
lifespans = tor_calloc(sizeof(struct duration_idx_t), n);
|
||||
rmv = tor_calloc(sizeof(uint8_t), n);
|
||||
must_keep = tor_calloc(sizeof(uint8_t), n);
|
||||
lifespans = tor_calloc(n, sizeof(struct duration_idx_t));
|
||||
rmv = tor_calloc(n, sizeof(uint8_t));
|
||||
must_keep = tor_calloc(n, sizeof(uint8_t));
|
||||
/* Set lifespans to contain the lifespan and index of each server. */
|
||||
/* Set rmv[i-lo]=1 if we're going to remove a server for being too old. */
|
||||
for (i = lo; i <= hi; ++i) {
|
||||
@@ -4269,7 +4069,7 @@ clear_dir_servers(void)
|
||||
* corresponding elements of <b>result</b> to a nonzero value.
|
||||
*/
|
||||
static void
|
||||
list_pending_downloads(digestmap_t *result,
|
||||
list_pending_downloads(digestmap_t *result, digest256map_t *result256,
|
||||
int purpose, const char *prefix)
|
||||
{
|
||||
const size_t p_len = strlen(prefix);
|
||||
@@ -4279,7 +4079,7 @@ list_pending_downloads(digestmap_t *result,
|
||||
if (purpose == DIR_PURPOSE_FETCH_MICRODESC)
|
||||
flags = DSR_DIGEST256|DSR_BASE64;
|
||||
|
||||
tor_assert(result);
|
||||
tor_assert(result || result256);
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
|
||||
if (conn->type == CONN_TYPE_DIR &&
|
||||
@@ -4292,11 +4092,19 @@ list_pending_downloads(digestmap_t *result,
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(conn);
|
||||
|
||||
SMARTLIST_FOREACH(tmp, char *, d,
|
||||
if (result) {
|
||||
SMARTLIST_FOREACH(tmp, char *, d,
|
||||
{
|
||||
digestmap_set(result, d, (void*)1);
|
||||
tor_free(d);
|
||||
});
|
||||
} else if (result256) {
|
||||
SMARTLIST_FOREACH(tmp, uint8_t *, d,
|
||||
{
|
||||
digest256map_set(result256, d, (void*)1);
|
||||
tor_free(d);
|
||||
});
|
||||
}
|
||||
smartlist_free(tmp);
|
||||
}
|
||||
|
||||
@@ -4308,20 +4116,16 @@ list_pending_descriptor_downloads(digestmap_t *result, int extrainfo)
|
||||
{
|
||||
int purpose =
|
||||
extrainfo ? DIR_PURPOSE_FETCH_EXTRAINFO : DIR_PURPOSE_FETCH_SERVERDESC;
|
||||
list_pending_downloads(result, purpose, "d/");
|
||||
list_pending_downloads(result, NULL, purpose, "d/");
|
||||
}
|
||||
|
||||
/** For every microdescriptor we are currently downloading by descriptor
|
||||
* digest, set result[d] to (void*)1. (Note that microdescriptor digests
|
||||
* are 256-bit, and digestmap_t only holds 160-bit digests, so we're only
|
||||
* getting the first 20 bytes of each digest here.)
|
||||
*
|
||||
* XXXX Let there be a digestmap256_t, and use that instead.
|
||||
* digest, set result[d] to (void*)1.
|
||||
*/
|
||||
void
|
||||
list_pending_microdesc_downloads(digestmap_t *result)
|
||||
list_pending_microdesc_downloads(digest256map_t *result)
|
||||
{
|
||||
list_pending_downloads(result, DIR_PURPOSE_FETCH_MICRODESC, "d/");
|
||||
list_pending_downloads(NULL, result, DIR_PURPOSE_FETCH_MICRODESC, "d/");
|
||||
}
|
||||
|
||||
/** For every certificate we are currently downloading by (identity digest,
|
||||
|
||||
+2
-2
@@ -118,7 +118,7 @@ WRA_WAS_ADDED(was_router_added_t s) {
|
||||
static INLINE int WRA_WAS_OUTDATED(was_router_added_t s)
|
||||
{
|
||||
return (s == ROUTER_WAS_TOO_OLD ||
|
||||
s == ROUTER_WAS_NOT_NEW ||
|
||||
s == ROUTER_IS_ALREADY_KNOWN ||
|
||||
s == ROUTER_NOT_IN_CONSENSUS ||
|
||||
s == ROUTER_NOT_IN_CONSENSUS_OR_NETWORKSTATUS);
|
||||
}
|
||||
@@ -196,7 +196,7 @@ int hid_serv_get_responsible_directories(smartlist_t *responsible_dirs,
|
||||
int hid_serv_acting_as_directory(void);
|
||||
int hid_serv_responsible_for_desc_id(const char *id);
|
||||
|
||||
void list_pending_microdesc_downloads(digestmap_t *result);
|
||||
void list_pending_microdesc_downloads(digest256map_t *result);
|
||||
void launch_descriptor_downloads(int purpose,
|
||||
smartlist_t *downloadable,
|
||||
const routerstatus_t *source,
|
||||
|
||||
@@ -0,0 +1,709 @@
|
||||
/* * Copyright (c) 2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file scheduler.c
|
||||
* \brief Relay scheduling system
|
||||
**/
|
||||
|
||||
#include "or.h"
|
||||
|
||||
#define TOR_CHANNEL_INTERNAL_ /* For channel_flush_some_cells() */
|
||||
#include "channel.h"
|
||||
|
||||
#include "compat_libevent.h"
|
||||
#define SCHEDULER_PRIVATE_
|
||||
#include "scheduler.h"
|
||||
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
#include <event2/event.h>
|
||||
#else
|
||||
#include <event.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Scheduler high/low watermarks
|
||||
*/
|
||||
|
||||
static uint32_t sched_q_low_water = 16384;
|
||||
static uint32_t sched_q_high_water = 32768;
|
||||
|
||||
/*
|
||||
* Maximum cells to flush in a single call to channel_flush_some_cells();
|
||||
* setting this low means more calls, but too high and we could overshoot
|
||||
* sched_q_high_water.
|
||||
*/
|
||||
|
||||
static uint32_t sched_max_flush_cells = 16;
|
||||
|
||||
/*
|
||||
* Write scheduling works by keeping track of which channels can
|
||||
* accept cells, and have cells to write. From the scheduler's perspective,
|
||||
* a channel can be in four possible states:
|
||||
*
|
||||
* 1.) Not open for writes, no cells to send
|
||||
* - Not much to do here, and the channel will have scheduler_state ==
|
||||
* SCHED_CHAN_IDLE
|
||||
* - Transitions from:
|
||||
* - Open for writes/has cells by simultaneously draining all circuit
|
||||
* queues and filling the output buffer.
|
||||
* - Transitions to:
|
||||
* - Not open for writes/has cells by arrival of cells on an attached
|
||||
* circuit (this would be driven from append_cell_to_circuit_queue())
|
||||
* - Open for writes/no cells by a channel type specific path;
|
||||
* driven from connection_or_flushed_some() for channel_tls_t.
|
||||
*
|
||||
* 2.) Open for writes, no cells to send
|
||||
* - Not much here either; this will be the state an idle but open channel
|
||||
* can be expected to settle in. It will have scheduler_state ==
|
||||
* SCHED_CHAN_WAITING_FOR_CELLS
|
||||
* - Transitions from:
|
||||
* - Not open for writes/no cells by flushing some of the output
|
||||
* buffer.
|
||||
* - Open for writes/has cells by the scheduler moving cells from
|
||||
* circuit queues to channel output queue, but not having enough
|
||||
* to fill the output queue.
|
||||
* - Transitions to:
|
||||
* - Open for writes/has cells by arrival of new cells on an attached
|
||||
* circuit, in append_cell_to_circuit_queue()
|
||||
*
|
||||
* 3.) Not open for writes, cells to send
|
||||
* - This is the state of a busy circuit limited by output bandwidth;
|
||||
* cells have piled up in the circuit queues waiting to be relayed.
|
||||
* The channel will have scheduler_state == SCHED_CHAN_WAITING_TO_WRITE.
|
||||
* - Transitions from:
|
||||
* - Not open for writes/no cells by arrival of cells on an attached
|
||||
* circuit
|
||||
* - Open for writes/has cells by filling an output buffer without
|
||||
* draining all cells from attached circuits
|
||||
* - Transitions to:
|
||||
* - Opens for writes/has cells by draining some of the output buffer
|
||||
* via the connection_or_flushed_some() path (for channel_tls_t).
|
||||
*
|
||||
* 4.) Open for writes, cells to send
|
||||
* - This connection is ready to relay some cells and waiting for
|
||||
* the scheduler to choose it. The channel will have scheduler_state ==
|
||||
* SCHED_CHAN_PENDING.
|
||||
* - Transitions from:
|
||||
* - Not open for writes/has cells by the connection_or_flushed_some()
|
||||
* path
|
||||
* - Open for writes/no cells by the append_cell_to_circuit_queue()
|
||||
* path
|
||||
* - Transitions to:
|
||||
* - Not open for writes/no cells by draining all circuit queues and
|
||||
* simultaneously filling the output buffer.
|
||||
* - Not open for writes/has cells by writing enough cells to fill the
|
||||
* output buffer
|
||||
* - Open for writes/no cells by draining all attached circuit queues
|
||||
* without also filling the output buffer
|
||||
*
|
||||
* Other event-driven parts of the code move channels between these scheduling
|
||||
* states by calling scheduler functions; the scheduler only runs on open-for-
|
||||
* writes/has-cells channels and is the only path for those to transition to
|
||||
* other states. The scheduler_run() function gives us the opportunity to do
|
||||
* scheduling work, and is called from other scheduler functions whenever a
|
||||
* state transition occurs, and periodically from the main event loop.
|
||||
*/
|
||||
|
||||
/* Scheduler global data structures */
|
||||
|
||||
/*
|
||||
* We keep a list of channels that are pending - i.e, have cells to write
|
||||
* and can accept them to send. The enum scheduler_state in channel_t
|
||||
* is reserved for our use.
|
||||
*/
|
||||
|
||||
/* Pqueue of channels that can write and have cells (pending work) */
|
||||
STATIC smartlist_t *channels_pending = NULL;
|
||||
|
||||
/*
|
||||
* This event runs the scheduler from its callback, and is manually
|
||||
* activated whenever a channel enters open for writes/cells to send.
|
||||
*/
|
||||
|
||||
STATIC struct event *run_sched_ev = NULL;
|
||||
|
||||
/*
|
||||
* Queue heuristic; this is not the queue size, but an 'effective queuesize'
|
||||
* that ages out contributions from stalled channels.
|
||||
*/
|
||||
|
||||
STATIC uint64_t queue_heuristic = 0;
|
||||
|
||||
/*
|
||||
* Timestamp for last queue heuristic update
|
||||
*/
|
||||
|
||||
STATIC time_t queue_heuristic_timestamp = 0;
|
||||
|
||||
/* Scheduler static function declarations */
|
||||
|
||||
static void scheduler_evt_callback(evutil_socket_t fd,
|
||||
short events, void *arg);
|
||||
static int scheduler_more_work(void);
|
||||
static void scheduler_retrigger(void);
|
||||
#if 0
|
||||
static void scheduler_trigger(void);
|
||||
#endif
|
||||
|
||||
/* Scheduler function implementations */
|
||||
|
||||
/** Free everything and shut down the scheduling system */
|
||||
|
||||
void
|
||||
scheduler_free_all(void)
|
||||
{
|
||||
log_debug(LD_SCHED, "Shutting down scheduler");
|
||||
|
||||
if (run_sched_ev) {
|
||||
event_del(run_sched_ev);
|
||||
tor_event_free(run_sched_ev);
|
||||
run_sched_ev = NULL;
|
||||
}
|
||||
|
||||
if (channels_pending) {
|
||||
smartlist_free(channels_pending);
|
||||
channels_pending = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison function to use when sorting pending channels
|
||||
*/
|
||||
|
||||
MOCK_IMPL(STATIC int,
|
||||
scheduler_compare_channels, (const void *c1_v, const void *c2_v))
|
||||
{
|
||||
channel_t *c1 = NULL, *c2 = NULL;
|
||||
/* These are a workaround for -Wbad-function-cast throwing a fit */
|
||||
const circuitmux_policy_t *p1, *p2;
|
||||
uintptr_t p1_i, p2_i;
|
||||
|
||||
tor_assert(c1_v);
|
||||
tor_assert(c2_v);
|
||||
|
||||
c1 = (channel_t *)(c1_v);
|
||||
c2 = (channel_t *)(c2_v);
|
||||
|
||||
tor_assert(c1);
|
||||
tor_assert(c2);
|
||||
|
||||
if (c1 != c2) {
|
||||
if (circuitmux_get_policy(c1->cmux) ==
|
||||
circuitmux_get_policy(c2->cmux)) {
|
||||
/* Same cmux policy, so use the mux comparison */
|
||||
return circuitmux_compare_muxes(c1->cmux, c2->cmux);
|
||||
} else {
|
||||
/*
|
||||
* Different policies; not important to get this edge case perfect
|
||||
* because the current code never actually gives different channels
|
||||
* different cmux policies anyway. Just use this arbitrary but
|
||||
* definite choice.
|
||||
*/
|
||||
p1 = circuitmux_get_policy(c1->cmux);
|
||||
p2 = circuitmux_get_policy(c2->cmux);
|
||||
p1_i = (uintptr_t)p1;
|
||||
p2_i = (uintptr_t)p2;
|
||||
|
||||
return (p1_i < p2_i) ? -1 : 1;
|
||||
}
|
||||
} else {
|
||||
/* c1 == c2, so always equal */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Scheduler event callback; this should get triggered once per event loop
|
||||
* if any scheduling work was created during the event loop.
|
||||
*/
|
||||
|
||||
static void
|
||||
scheduler_evt_callback(evutil_socket_t fd, short events, void *arg)
|
||||
{
|
||||
(void)fd;
|
||||
(void)events;
|
||||
(void)arg;
|
||||
log_debug(LD_SCHED, "Scheduler event callback called");
|
||||
|
||||
tor_assert(run_sched_ev);
|
||||
|
||||
/* Run the scheduler */
|
||||
scheduler_run();
|
||||
|
||||
/* Do we have more work to do? */
|
||||
if (scheduler_more_work()) scheduler_retrigger();
|
||||
}
|
||||
|
||||
/** Mark a channel as no longer ready to accept writes */
|
||||
|
||||
MOCK_IMPL(void,
|
||||
scheduler_channel_doesnt_want_writes,(channel_t *chan))
|
||||
{
|
||||
tor_assert(chan);
|
||||
|
||||
tor_assert(channels_pending);
|
||||
|
||||
/* If it's already in pending, we can put it in waiting_to_write */
|
||||
if (chan->scheduler_state == SCHED_CHAN_PENDING) {
|
||||
/*
|
||||
* It's in channels_pending, so it shouldn't be in any of
|
||||
* the other lists. It can't write any more, so it goes to
|
||||
* channels_waiting_to_write.
|
||||
*/
|
||||
smartlist_pqueue_remove(channels_pending,
|
||||
scheduler_compare_channels,
|
||||
STRUCT_OFFSET(channel_t, sched_heap_idx),
|
||||
chan);
|
||||
chan->scheduler_state = SCHED_CHAN_WAITING_TO_WRITE;
|
||||
log_debug(LD_SCHED,
|
||||
"Channel " U64_FORMAT " at %p went from pending "
|
||||
"to waiting_to_write",
|
||||
U64_PRINTF_ARG(chan->global_identifier), chan);
|
||||
} else {
|
||||
/*
|
||||
* It's not in pending, so it can't become waiting_to_write; it's
|
||||
* either not in any of the lists (nothing to do) or it's already in
|
||||
* waiting_for_cells (remove it, can't write any more).
|
||||
*/
|
||||
if (chan->scheduler_state == SCHED_CHAN_WAITING_FOR_CELLS) {
|
||||
chan->scheduler_state = SCHED_CHAN_IDLE;
|
||||
log_debug(LD_SCHED,
|
||||
"Channel " U64_FORMAT " at %p left waiting_for_cells",
|
||||
U64_PRINTF_ARG(chan->global_identifier), chan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Mark a channel as having waiting cells */
|
||||
|
||||
MOCK_IMPL(void,
|
||||
scheduler_channel_has_waiting_cells,(channel_t *chan))
|
||||
{
|
||||
int became_pending = 0;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(channels_pending);
|
||||
|
||||
/* First, check if this one also writeable */
|
||||
if (chan->scheduler_state == SCHED_CHAN_WAITING_FOR_CELLS) {
|
||||
/*
|
||||
* It's in channels_waiting_for_cells, so it shouldn't be in any of
|
||||
* the other lists. It has waiting cells now, so it goes to
|
||||
* channels_pending.
|
||||
*/
|
||||
chan->scheduler_state = SCHED_CHAN_PENDING;
|
||||
smartlist_pqueue_add(channels_pending,
|
||||
scheduler_compare_channels,
|
||||
STRUCT_OFFSET(channel_t, sched_heap_idx),
|
||||
chan);
|
||||
log_debug(LD_SCHED,
|
||||
"Channel " U64_FORMAT " at %p went from waiting_for_cells "
|
||||
"to pending",
|
||||
U64_PRINTF_ARG(chan->global_identifier), chan);
|
||||
became_pending = 1;
|
||||
} else {
|
||||
/*
|
||||
* It's not in waiting_for_cells, so it can't become pending; it's
|
||||
* either not in any of the lists (we add it to waiting_to_write)
|
||||
* or it's already in waiting_to_write or pending (we do nothing)
|
||||
*/
|
||||
if (!(chan->scheduler_state == SCHED_CHAN_WAITING_TO_WRITE ||
|
||||
chan->scheduler_state == SCHED_CHAN_PENDING)) {
|
||||
chan->scheduler_state = SCHED_CHAN_WAITING_TO_WRITE;
|
||||
log_debug(LD_SCHED,
|
||||
"Channel " U64_FORMAT " at %p entered waiting_to_write",
|
||||
U64_PRINTF_ARG(chan->global_identifier), chan);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we made a channel pending, we potentially have scheduling work
|
||||
* to do.
|
||||
*/
|
||||
if (became_pending) scheduler_retrigger();
|
||||
}
|
||||
|
||||
/** Set up the scheduling system */
|
||||
|
||||
void
|
||||
scheduler_init(void)
|
||||
{
|
||||
log_debug(LD_SCHED, "Initting scheduler");
|
||||
|
||||
tor_assert(!run_sched_ev);
|
||||
run_sched_ev = tor_event_new(tor_libevent_get_base(), -1,
|
||||
0, scheduler_evt_callback, NULL);
|
||||
|
||||
channels_pending = smartlist_new();
|
||||
queue_heuristic = 0;
|
||||
queue_heuristic_timestamp = approx_time();
|
||||
}
|
||||
|
||||
/** Check if there's more scheduling work */
|
||||
|
||||
static int
|
||||
scheduler_more_work(void)
|
||||
{
|
||||
tor_assert(channels_pending);
|
||||
|
||||
return ((scheduler_get_queue_heuristic() < sched_q_low_water) &&
|
||||
((smartlist_len(channels_pending) > 0))) ? 1 : 0;
|
||||
}
|
||||
|
||||
/** Retrigger the scheduler in a way safe to use from the callback */
|
||||
|
||||
static void
|
||||
scheduler_retrigger(void)
|
||||
{
|
||||
tor_assert(run_sched_ev);
|
||||
event_active(run_sched_ev, EV_TIMEOUT, 1);
|
||||
}
|
||||
|
||||
/** Notify the scheduler of a channel being closed */
|
||||
|
||||
MOCK_IMPL(void,
|
||||
scheduler_release_channel,(channel_t *chan))
|
||||
{
|
||||
tor_assert(chan);
|
||||
tor_assert(channels_pending);
|
||||
|
||||
if (chan->scheduler_state == SCHED_CHAN_PENDING) {
|
||||
smartlist_pqueue_remove(channels_pending,
|
||||
scheduler_compare_channels,
|
||||
STRUCT_OFFSET(channel_t, sched_heap_idx),
|
||||
chan);
|
||||
}
|
||||
|
||||
chan->scheduler_state = SCHED_CHAN_IDLE;
|
||||
}
|
||||
|
||||
/** Run the scheduling algorithm if necessary */
|
||||
|
||||
MOCK_IMPL(void,
|
||||
scheduler_run, (void))
|
||||
{
|
||||
int n_cells, n_chans_before, n_chans_after;
|
||||
uint64_t q_len_before, q_heur_before, q_len_after, q_heur_after;
|
||||
ssize_t flushed, flushed_this_time;
|
||||
smartlist_t *to_readd = NULL;
|
||||
channel_t *chan = NULL;
|
||||
|
||||
log_debug(LD_SCHED, "We have a chance to run the scheduler");
|
||||
|
||||
if (scheduler_get_queue_heuristic() < sched_q_low_water) {
|
||||
n_chans_before = smartlist_len(channels_pending);
|
||||
q_len_before = channel_get_global_queue_estimate();
|
||||
q_heur_before = scheduler_get_queue_heuristic();
|
||||
|
||||
while (scheduler_get_queue_heuristic() <= sched_q_high_water &&
|
||||
smartlist_len(channels_pending) > 0) {
|
||||
/* Pop off a channel */
|
||||
chan = smartlist_pqueue_pop(channels_pending,
|
||||
scheduler_compare_channels,
|
||||
STRUCT_OFFSET(channel_t, sched_heap_idx));
|
||||
tor_assert(chan);
|
||||
|
||||
/* Figure out how many cells we can write */
|
||||
n_cells = channel_num_cells_writeable(chan);
|
||||
if (n_cells > 0) {
|
||||
log_debug(LD_SCHED,
|
||||
"Scheduler saw pending channel " U64_FORMAT " at %p with "
|
||||
"%d cells writeable",
|
||||
U64_PRINTF_ARG(chan->global_identifier), chan, n_cells);
|
||||
|
||||
flushed = 0;
|
||||
while (flushed < n_cells &&
|
||||
scheduler_get_queue_heuristic() <= sched_q_high_water) {
|
||||
flushed_this_time =
|
||||
channel_flush_some_cells(chan,
|
||||
MIN(sched_max_flush_cells,
|
||||
(size_t) n_cells - flushed));
|
||||
if (flushed_this_time <= 0) break;
|
||||
flushed += flushed_this_time;
|
||||
}
|
||||
|
||||
if (flushed < n_cells) {
|
||||
/* We ran out of cells to flush */
|
||||
chan->scheduler_state = SCHED_CHAN_WAITING_FOR_CELLS;
|
||||
log_debug(LD_SCHED,
|
||||
"Channel " U64_FORMAT " at %p "
|
||||
"entered waiting_for_cells from pending",
|
||||
U64_PRINTF_ARG(chan->global_identifier),
|
||||
chan);
|
||||
} else {
|
||||
/* The channel may still have some cells */
|
||||
if (channel_more_to_flush(chan)) {
|
||||
/* The channel goes to either pending or waiting_to_write */
|
||||
if (channel_num_cells_writeable(chan) > 0) {
|
||||
/* Add it back to pending later */
|
||||
if (!to_readd) to_readd = smartlist_new();
|
||||
smartlist_add(to_readd, chan);
|
||||
log_debug(LD_SCHED,
|
||||
"Channel " U64_FORMAT " at %p "
|
||||
"is still pending",
|
||||
U64_PRINTF_ARG(chan->global_identifier),
|
||||
chan);
|
||||
} else {
|
||||
/* It's waiting to be able to write more */
|
||||
chan->scheduler_state = SCHED_CHAN_WAITING_TO_WRITE;
|
||||
log_debug(LD_SCHED,
|
||||
"Channel " U64_FORMAT " at %p "
|
||||
"entered waiting_to_write from pending",
|
||||
U64_PRINTF_ARG(chan->global_identifier),
|
||||
chan);
|
||||
}
|
||||
} else {
|
||||
/* No cells left; it can go to idle or waiting_for_cells */
|
||||
if (channel_num_cells_writeable(chan) > 0) {
|
||||
/*
|
||||
* It can still accept writes, so it goes to
|
||||
* waiting_for_cells
|
||||
*/
|
||||
chan->scheduler_state = SCHED_CHAN_WAITING_FOR_CELLS;
|
||||
log_debug(LD_SCHED,
|
||||
"Channel " U64_FORMAT " at %p "
|
||||
"entered waiting_for_cells from pending",
|
||||
U64_PRINTF_ARG(chan->global_identifier),
|
||||
chan);
|
||||
} else {
|
||||
/*
|
||||
* We exactly filled up the output queue with all available
|
||||
* cells; go to idle.
|
||||
*/
|
||||
chan->scheduler_state = SCHED_CHAN_IDLE;
|
||||
log_debug(LD_SCHED,
|
||||
"Channel " U64_FORMAT " at %p "
|
||||
"become idle from pending",
|
||||
U64_PRINTF_ARG(chan->global_identifier),
|
||||
chan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log_debug(LD_SCHED,
|
||||
"Scheduler flushed %d cells onto pending channel "
|
||||
U64_FORMAT " at %p",
|
||||
(int)flushed, U64_PRINTF_ARG(chan->global_identifier),
|
||||
chan);
|
||||
} else {
|
||||
log_info(LD_SCHED,
|
||||
"Scheduler saw pending channel " U64_FORMAT " at %p with "
|
||||
"no cells writeable",
|
||||
U64_PRINTF_ARG(chan->global_identifier), chan);
|
||||
/* Put it back to WAITING_TO_WRITE */
|
||||
chan->scheduler_state = SCHED_CHAN_WAITING_TO_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Readd any channels we need to */
|
||||
if (to_readd) {
|
||||
SMARTLIST_FOREACH_BEGIN(to_readd, channel_t *, chan) {
|
||||
chan->scheduler_state = SCHED_CHAN_PENDING;
|
||||
smartlist_pqueue_add(channels_pending,
|
||||
scheduler_compare_channels,
|
||||
STRUCT_OFFSET(channel_t, sched_heap_idx),
|
||||
chan);
|
||||
} SMARTLIST_FOREACH_END(chan);
|
||||
smartlist_free(to_readd);
|
||||
}
|
||||
|
||||
n_chans_after = smartlist_len(channels_pending);
|
||||
q_len_after = channel_get_global_queue_estimate();
|
||||
q_heur_after = scheduler_get_queue_heuristic();
|
||||
log_debug(LD_SCHED,
|
||||
"Scheduler handled %d of %d pending channels, queue size from "
|
||||
U64_FORMAT " to " U64_FORMAT ", queue heuristic from "
|
||||
U64_FORMAT " to " U64_FORMAT,
|
||||
n_chans_before - n_chans_after, n_chans_before,
|
||||
U64_PRINTF_ARG(q_len_before), U64_PRINTF_ARG(q_len_after),
|
||||
U64_PRINTF_ARG(q_heur_before), U64_PRINTF_ARG(q_heur_after));
|
||||
}
|
||||
}
|
||||
|
||||
/** Trigger the scheduling event so we run the scheduler later */
|
||||
|
||||
#if 0
|
||||
static void
|
||||
scheduler_trigger(void)
|
||||
{
|
||||
log_debug(LD_SCHED, "Triggering scheduler event");
|
||||
|
||||
tor_assert(run_sched_ev);
|
||||
|
||||
event_add(run_sched_ev, EV_TIMEOUT, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Mark a channel as ready to accept writes */
|
||||
|
||||
void
|
||||
scheduler_channel_wants_writes(channel_t *chan)
|
||||
{
|
||||
int became_pending = 0;
|
||||
|
||||
tor_assert(chan);
|
||||
tor_assert(channels_pending);
|
||||
|
||||
/* If it's already in waiting_to_write, we can put it in pending */
|
||||
if (chan->scheduler_state == SCHED_CHAN_WAITING_TO_WRITE) {
|
||||
/*
|
||||
* It can write now, so it goes to channels_pending.
|
||||
*/
|
||||
smartlist_pqueue_add(channels_pending,
|
||||
scheduler_compare_channels,
|
||||
STRUCT_OFFSET(channel_t, sched_heap_idx),
|
||||
chan);
|
||||
chan->scheduler_state = SCHED_CHAN_PENDING;
|
||||
log_debug(LD_SCHED,
|
||||
"Channel " U64_FORMAT " at %p went from waiting_to_write "
|
||||
"to pending",
|
||||
U64_PRINTF_ARG(chan->global_identifier), chan);
|
||||
became_pending = 1;
|
||||
} else {
|
||||
/*
|
||||
* It's not in SCHED_CHAN_WAITING_TO_WRITE, so it can't become pending;
|
||||
* it's either idle and goes to WAITING_FOR_CELLS, or it's a no-op.
|
||||
*/
|
||||
if (!(chan->scheduler_state == SCHED_CHAN_WAITING_FOR_CELLS ||
|
||||
chan->scheduler_state == SCHED_CHAN_PENDING)) {
|
||||
chan->scheduler_state = SCHED_CHAN_WAITING_FOR_CELLS;
|
||||
log_debug(LD_SCHED,
|
||||
"Channel " U64_FORMAT " at %p entered waiting_for_cells",
|
||||
U64_PRINTF_ARG(chan->global_identifier), chan);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we made a channel pending, we potentially have scheduling work
|
||||
* to do.
|
||||
*/
|
||||
if (became_pending) scheduler_retrigger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the scheduler that a channel's position in the pqueue may have
|
||||
* changed
|
||||
*/
|
||||
|
||||
void
|
||||
scheduler_touch_channel(channel_t *chan)
|
||||
{
|
||||
tor_assert(chan);
|
||||
|
||||
if (chan->scheduler_state == SCHED_CHAN_PENDING) {
|
||||
/* Remove and re-add it */
|
||||
smartlist_pqueue_remove(channels_pending,
|
||||
scheduler_compare_channels,
|
||||
STRUCT_OFFSET(channel_t, sched_heap_idx),
|
||||
chan);
|
||||
smartlist_pqueue_add(channels_pending,
|
||||
scheduler_compare_channels,
|
||||
STRUCT_OFFSET(channel_t, sched_heap_idx),
|
||||
chan);
|
||||
}
|
||||
/* else no-op, since it isn't in the queue */
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the scheduler of a queue size adjustment, to recalculate the
|
||||
* queue heuristic.
|
||||
*/
|
||||
|
||||
void
|
||||
scheduler_adjust_queue_size(channel_t *chan, char dir, uint64_t adj)
|
||||
{
|
||||
time_t now = approx_time();
|
||||
|
||||
log_debug(LD_SCHED,
|
||||
"Queue size adjustment by %s" U64_FORMAT " for channel "
|
||||
U64_FORMAT,
|
||||
(dir >= 0) ? "+" : "-",
|
||||
U64_PRINTF_ARG(adj),
|
||||
U64_PRINTF_ARG(chan->global_identifier));
|
||||
|
||||
/* Get the queue heuristic up to date */
|
||||
scheduler_update_queue_heuristic(now);
|
||||
|
||||
/* Adjust as appropriate */
|
||||
if (dir >= 0) {
|
||||
/* Increasing it */
|
||||
queue_heuristic += adj;
|
||||
} else {
|
||||
/* Decreasing it */
|
||||
if (queue_heuristic > adj) queue_heuristic -= adj;
|
||||
else queue_heuristic = 0;
|
||||
}
|
||||
|
||||
log_debug(LD_SCHED,
|
||||
"Queue heuristic is now " U64_FORMAT,
|
||||
U64_PRINTF_ARG(queue_heuristic));
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the current value of the queue heuristic
|
||||
*/
|
||||
|
||||
STATIC uint64_t
|
||||
scheduler_get_queue_heuristic(void)
|
||||
{
|
||||
time_t now = approx_time();
|
||||
|
||||
scheduler_update_queue_heuristic(now);
|
||||
|
||||
return queue_heuristic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the queue heuristic value to the present time
|
||||
*/
|
||||
|
||||
STATIC void
|
||||
scheduler_update_queue_heuristic(time_t now)
|
||||
{
|
||||
time_t diff;
|
||||
|
||||
if (queue_heuristic_timestamp == 0) {
|
||||
/*
|
||||
* Nothing we can sensibly do; must not have been initted properly.
|
||||
* Oh well.
|
||||
*/
|
||||
queue_heuristic_timestamp = now;
|
||||
} else if (queue_heuristic_timestamp < now) {
|
||||
diff = now - queue_heuristic_timestamp;
|
||||
/*
|
||||
* This is a simple exponential age-out; the other proposed alternative
|
||||
* was a linear age-out using the bandwidth history in rephist.c; I'm
|
||||
* going with this out of concern that if an adversary can jam the
|
||||
* scheduler long enough, it would cause the bandwidth to drop to
|
||||
* zero and render the aging mechanism ineffective thereafter.
|
||||
*/
|
||||
if (0 <= diff && diff < 64) queue_heuristic >>= diff;
|
||||
else queue_heuristic = 0;
|
||||
|
||||
queue_heuristic_timestamp = now;
|
||||
|
||||
log_debug(LD_SCHED,
|
||||
"Queue heuristic is now " U64_FORMAT,
|
||||
U64_PRINTF_ARG(queue_heuristic));
|
||||
}
|
||||
/* else no update needed, or time went backward */
|
||||
}
|
||||
|
||||
/**
|
||||
* Set scheduler watermarks and flush size
|
||||
*/
|
||||
|
||||
void
|
||||
scheduler_set_watermarks(uint32_t lo, uint32_t hi, uint32_t max_flush)
|
||||
{
|
||||
/* Sanity assertions - caller should ensure these are true */
|
||||
tor_assert(lo > 0);
|
||||
tor_assert(hi > lo);
|
||||
tor_assert(max_flush > 0);
|
||||
|
||||
sched_q_low_water = lo;
|
||||
sched_q_high_water = hi;
|
||||
sched_max_flush_cells = max_flush;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/* * Copyright (c) 2013, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file scheduler.h
|
||||
* \brief Header file for scheduler.c
|
||||
**/
|
||||
|
||||
#ifndef TOR_SCHEDULER_H
|
||||
#define TOR_SCHEDULER_H
|
||||
|
||||
#include "or.h"
|
||||
#include "channel.h"
|
||||
#include "testsupport.h"
|
||||
|
||||
/* Global-visibility scheduler functions */
|
||||
|
||||
/* Set up and shut down the scheduler from main.c */
|
||||
void scheduler_free_all(void);
|
||||
void scheduler_init(void);
|
||||
MOCK_DECL(void, scheduler_run, (void));
|
||||
|
||||
/* Mark channels as having cells or wanting/not wanting writes */
|
||||
MOCK_DECL(void,scheduler_channel_doesnt_want_writes,(channel_t *chan));
|
||||
MOCK_DECL(void,scheduler_channel_has_waiting_cells,(channel_t *chan));
|
||||
void scheduler_channel_wants_writes(channel_t *chan);
|
||||
|
||||
/* Notify the scheduler of a channel being closed */
|
||||
MOCK_DECL(void,scheduler_release_channel,(channel_t *chan));
|
||||
|
||||
/* Notify scheduler of queue size adjustments */
|
||||
void scheduler_adjust_queue_size(channel_t *chan, char dir, uint64_t adj);
|
||||
|
||||
/* Notify scheduler that a channel's queue position may have changed */
|
||||
void scheduler_touch_channel(channel_t *chan);
|
||||
|
||||
/* Adjust the watermarks from config file*/
|
||||
void scheduler_set_watermarks(uint32_t lo, uint32_t hi, uint32_t max_flush);
|
||||
|
||||
/* Things only scheduler.c and its test suite should see */
|
||||
|
||||
#ifdef SCHEDULER_PRIVATE_
|
||||
MOCK_DECL(STATIC int, scheduler_compare_channels,
|
||||
(const void *c1_v, const void *c2_v));
|
||||
STATIC uint64_t scheduler_get_queue_heuristic(void);
|
||||
STATIC void scheduler_update_queue_heuristic(time_t now);
|
||||
#endif
|
||||
|
||||
#endif /* !defined(TOR_SCHEDULER_H) */
|
||||
|
||||
+6
-6
@@ -326,9 +326,9 @@ transport_add(transport_t *t)
|
||||
/** Remember a new pluggable transport proxy at <b>addr</b>:<b>port</b>.
|
||||
* <b>name</b> is set to the name of the protocol this proxy uses.
|
||||
* <b>socks_ver</b> is set to the SOCKS version of the proxy. */
|
||||
int
|
||||
transport_add_from_config(const tor_addr_t *addr, uint16_t port,
|
||||
const char *name, int socks_ver)
|
||||
MOCK_IMPL(int,
|
||||
transport_add_from_config, (const tor_addr_t *addr, uint16_t port,
|
||||
const char *name, int socks_ver))
|
||||
{
|
||||
transport_t *t = transport_new(addr, port, name, socks_ver, NULL);
|
||||
|
||||
@@ -1456,9 +1456,9 @@ managed_proxy_create(const smartlist_t *transport_list,
|
||||
* Requires that proxy_argv be a NULL-terminated array of command-line
|
||||
* elements, containing at least one element.
|
||||
**/
|
||||
void
|
||||
pt_kickstart_proxy(const smartlist_t *transport_list,
|
||||
char **proxy_argv, int is_server)
|
||||
MOCK_IMPL(void,
|
||||
pt_kickstart_proxy, (const smartlist_t *transport_list,
|
||||
char **proxy_argv, int is_server))
|
||||
{
|
||||
managed_proxy_t *mp=NULL;
|
||||
transport_t *old_transport = NULL;
|
||||
|
||||
+6
-4
@@ -32,14 +32,16 @@ typedef struct transport_t {
|
||||
|
||||
void mark_transport_list(void);
|
||||
void sweep_transport_list(void);
|
||||
int transport_add_from_config(const tor_addr_t *addr, uint16_t port,
|
||||
const char *name, int socks_ver);
|
||||
MOCK_DECL(int, transport_add_from_config,
|
||||
(const tor_addr_t *addr, uint16_t port,
|
||||
const char *name, int socks_ver));
|
||||
void transport_free(transport_t *transport);
|
||||
|
||||
transport_t *transport_get_by_name(const char *name);
|
||||
|
||||
void pt_kickstart_proxy(const smartlist_t *transport_list, char **proxy_argv,
|
||||
int is_server);
|
||||
MOCK_DECL(void, pt_kickstart_proxy,
|
||||
(const smartlist_t *transport_list, char **proxy_argv,
|
||||
int is_server));
|
||||
|
||||
#define pt_kickstart_client_proxy(tl, pa) \
|
||||
pt_kickstart_proxy(tl, pa, 0)
|
||||
|
||||
@@ -11,11 +11,12 @@ LIBS = ..\..\..\build-alpha\lib\libevent.lib \
|
||||
ws2_32.lib advapi32.lib shell32.lib \
|
||||
crypt32.lib gdi32.lib user32.lib
|
||||
|
||||
TEST_OBJECTS = test.obj test_addr.obj test_containers.obj \
|
||||
test_controller_events.ogj test_crypto.obj test_data.obj test_dir.obj \
|
||||
test_microdesc.obj test_pt.obj test_util.obj test_config.obj \
|
||||
test_cell_formats.obj test_replay.obj test_introduce.obj tinytest.obj \
|
||||
test_hs.obj
|
||||
TEST_OBJECTS = test.obj test_addr.obj test_channel.obj test_channeltls.obj \
|
||||
test_containers.obj \
|
||||
test_controller_events.obj test_crypto.obj test_data.obj test_dir.obj \
|
||||
test_checkdir.obj test_microdesc.obj test_pt.obj test_util.obj test_config.obj \
|
||||
test_cell_formats.obj test_relay.obj test_replay.obj \
|
||||
test_scheduler.obj test_introduce.obj test_hs.obj tinytest.obj
|
||||
|
||||
tinytest.obj: ..\ext\tinytest.c
|
||||
$(CC) $(CFLAGS) /D snprintf=_snprintf /c ..\ext\tinytest.c
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/* Copyright (c) 2014, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
#ifndef TOR_FAKECHANS_H
|
||||
#define TOR_FAKECHANS_H
|
||||
|
||||
/**
|
||||
* \file fakechans.h
|
||||
* \brief Declarations for fake channels for test suite use
|
||||
*/
|
||||
|
||||
void make_fake_cell(cell_t *c);
|
||||
void make_fake_var_cell(var_cell_t *c);
|
||||
channel_t * new_fake_channel(void);
|
||||
|
||||
/* Also exposes some a mock used by both test_channel.c and test_relay.c */
|
||||
void scheduler_channel_has_waiting_cells_mock(channel_t *ch);
|
||||
void scheduler_release_channel_mock(channel_t *ch);
|
||||
|
||||
/* Query some counters used by the exposed mocks */
|
||||
int get_mock_scheduler_has_waiting_cells_count(void);
|
||||
int get_mock_scheduler_release_channel_count(void);
|
||||
|
||||
#endif /* !defined(TOR_FAKECHANS_H) */
|
||||
|
||||
@@ -20,6 +20,8 @@ src_test_test_SOURCES = \
|
||||
src/test/test_addr.c \
|
||||
src/test/test_buffers.c \
|
||||
src/test/test_cell_formats.c \
|
||||
src/test/test_channel.c \
|
||||
src/test/test_channeltls.c \
|
||||
src/test/test_circuitlist.c \
|
||||
src/test/test_circuitmux.c \
|
||||
src/test/test_containers.c \
|
||||
@@ -28,6 +30,7 @@ src_test_test_SOURCES = \
|
||||
src/test/test_cell_queue.c \
|
||||
src/test/test_data.c \
|
||||
src/test/test_dir.c \
|
||||
src/test/test_checkdir.c \
|
||||
src/test/test_entrynodes.c \
|
||||
src/test/test_extorport.c \
|
||||
src/test/test_introduce.c \
|
||||
@@ -38,8 +41,10 @@ src_test_test_SOURCES = \
|
||||
src/test/test_options.c \
|
||||
src/test/test_pt.c \
|
||||
src/test/test_relaycell.c \
|
||||
src/test/test_relay.c \
|
||||
src/test/test_replay.c \
|
||||
src/test/test_routerkeys.c \
|
||||
src/test/test_scheduler.c \
|
||||
src/test/test_socks.c \
|
||||
src/test/test_util.c \
|
||||
src/test/test_config.c \
|
||||
@@ -74,6 +79,7 @@ src_test_bench_LDADD = src/or/libtor.a src/common/libor.a \
|
||||
@TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@
|
||||
|
||||
noinst_HEADERS+= \
|
||||
src/test/fakechans.h \
|
||||
src/test/test.h \
|
||||
src/test/test_descriptors.inc \
|
||||
src/test/example_extrainfo.inc \
|
||||
|
||||
+93
-78
@@ -123,6 +123,10 @@ setup_directory(void)
|
||||
tor_snprintf(temp_dir, sizeof(temp_dir), "/tmp/tor_test_%d_%s",
|
||||
(int) getpid(), rnd32);
|
||||
r = mkdir(temp_dir, 0700);
|
||||
if (!r) {
|
||||
/* undo sticky bit so tests don't get confused. */
|
||||
r = chown(temp_dir, getuid(), getgid());
|
||||
}
|
||||
#endif
|
||||
if (r) {
|
||||
fprintf(stderr, "Can't create directory %s:", temp_dir);
|
||||
@@ -273,9 +277,9 @@ test_onion_handshake(void *arg)
|
||||
memset(c_keys, 0, 40);
|
||||
tt_assert(! onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40));
|
||||
|
||||
tt_mem_op(c_keys,==, s_keys, 40);
|
||||
tt_mem_op(c_keys,OP_EQ, s_keys, 40);
|
||||
memset(s_buf, 0, 40);
|
||||
tt_mem_op(c_keys,!=, s_buf, 40);
|
||||
tt_mem_op(c_keys,OP_NE, s_buf, 40);
|
||||
}
|
||||
done:
|
||||
crypto_dh_free(c_dh);
|
||||
@@ -307,7 +311,7 @@ test_bad_onion_handshake(void *arg)
|
||||
memset(junk_buf, 0, sizeof(junk_buf));
|
||||
crypto_pk_public_hybrid_encrypt(pk, junk_buf2, TAP_ONIONSKIN_CHALLENGE_LEN,
|
||||
junk_buf, DH_KEY_LEN, PK_PKCS1_OAEP_PADDING, 1);
|
||||
tt_int_op(-1, ==,
|
||||
tt_int_op(-1, OP_EQ,
|
||||
onion_skin_TAP_server_handshake(junk_buf2, pk, NULL,
|
||||
s_buf, s_keys, 40));
|
||||
|
||||
@@ -316,7 +320,7 @@ test_bad_onion_handshake(void *arg)
|
||||
memset(junk_buf2, 0, sizeof(junk_buf2));
|
||||
crypto_pk_public_encrypt(pk, junk_buf2, sizeof(junk_buf2),
|
||||
junk_buf, 48, PK_PKCS1_OAEP_PADDING);
|
||||
tt_int_op(-1, ==,
|
||||
tt_int_op(-1, OP_EQ,
|
||||
onion_skin_TAP_server_handshake(junk_buf2, pk, NULL,
|
||||
s_buf, s_keys, 40));
|
||||
|
||||
@@ -325,36 +329,36 @@ test_bad_onion_handshake(void *arg)
|
||||
tt_assert(! onion_skin_TAP_create(pk, &c_dh, c_buf));
|
||||
|
||||
/* Server: Case 3: we just don't have the right key. */
|
||||
tt_int_op(-1, ==,
|
||||
tt_int_op(-1, OP_EQ,
|
||||
onion_skin_TAP_server_handshake(c_buf, pk2, NULL,
|
||||
s_buf, s_keys, 40));
|
||||
|
||||
/* Server: Case 4: The RSA-encrypted portion is corrupt. */
|
||||
c_buf[64] ^= 33;
|
||||
tt_int_op(-1, ==,
|
||||
tt_int_op(-1, OP_EQ,
|
||||
onion_skin_TAP_server_handshake(c_buf, pk, NULL,
|
||||
s_buf, s_keys, 40));
|
||||
c_buf[64] ^= 33;
|
||||
|
||||
/* (Let the server procede) */
|
||||
tt_int_op(0, ==,
|
||||
tt_int_op(0, OP_EQ,
|
||||
onion_skin_TAP_server_handshake(c_buf, pk, NULL,
|
||||
s_buf, s_keys, 40));
|
||||
|
||||
/* Client: Case 1: The server sent back junk. */
|
||||
s_buf[64] ^= 33;
|
||||
tt_int_op(-1, ==,
|
||||
tt_int_op(-1, OP_EQ,
|
||||
onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40));
|
||||
s_buf[64] ^= 33;
|
||||
|
||||
/* Let the client finish; make sure it can. */
|
||||
tt_int_op(0, ==,
|
||||
tt_int_op(0, OP_EQ,
|
||||
onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40));
|
||||
tt_mem_op(s_keys,==, c_keys, 40);
|
||||
tt_mem_op(s_keys,OP_EQ, c_keys, 40);
|
||||
|
||||
/* Client: Case 2: The server sent back a degenerate DH. */
|
||||
memset(s_buf, 0, sizeof(s_buf));
|
||||
tt_int_op(-1, ==,
|
||||
tt_int_op(-1, OP_EQ,
|
||||
onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40));
|
||||
|
||||
done:
|
||||
@@ -391,24 +395,24 @@ test_ntor_handshake(void *arg)
|
||||
|
||||
/* client handshake 1. */
|
||||
memset(c_buf, 0, NTOR_ONIONSKIN_LEN);
|
||||
tt_int_op(0, ==, onion_skin_ntor_create(node_id, server_pubkey,
|
||||
tt_int_op(0, OP_EQ, onion_skin_ntor_create(node_id, server_pubkey,
|
||||
&c_state, c_buf));
|
||||
|
||||
/* server handshake */
|
||||
memset(s_buf, 0, NTOR_REPLY_LEN);
|
||||
memset(s_keys, 0, 40);
|
||||
tt_int_op(0, ==, onion_skin_ntor_server_handshake(c_buf, s_keymap, NULL,
|
||||
tt_int_op(0, OP_EQ, onion_skin_ntor_server_handshake(c_buf, s_keymap, NULL,
|
||||
node_id,
|
||||
s_buf, s_keys, 400));
|
||||
|
||||
/* client handshake 2 */
|
||||
memset(c_keys, 0, 40);
|
||||
tt_int_op(0, ==, onion_skin_ntor_client_handshake(c_state, s_buf,
|
||||
tt_int_op(0, OP_EQ, onion_skin_ntor_client_handshake(c_state, s_buf,
|
||||
c_keys, 400));
|
||||
|
||||
tt_mem_op(c_keys,==, s_keys, 400);
|
||||
tt_mem_op(c_keys,OP_EQ, s_keys, 400);
|
||||
memset(s_buf, 0, 40);
|
||||
tt_mem_op(c_keys,!=, s_buf, 40);
|
||||
tt_mem_op(c_keys,OP_NE, s_buf, 40);
|
||||
|
||||
done:
|
||||
ntor_handshake_state_free(c_state);
|
||||
@@ -436,24 +440,24 @@ test_onion_queues(void *arg)
|
||||
create_cell_init(create2, CELL_CREATE, ONION_HANDSHAKE_TYPE_NTOR,
|
||||
NTOR_ONIONSKIN_LEN, buf2);
|
||||
|
||||
tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
|
||||
tt_int_op(0,==, onion_pending_add(circ1, create1));
|
||||
tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
|
||||
tt_int_op(0,OP_EQ, onion_pending_add(circ1, create1));
|
||||
create1 = NULL;
|
||||
tt_int_op(1,==, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
|
||||
tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
|
||||
|
||||
tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
|
||||
tt_int_op(0,==, onion_pending_add(circ2, create2));
|
||||
tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
|
||||
tt_int_op(0,OP_EQ, onion_pending_add(circ2, create2));
|
||||
create2 = NULL;
|
||||
tt_int_op(1,==, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
|
||||
tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
|
||||
|
||||
tt_ptr_op(circ2,==, onion_next_task(&onionskin));
|
||||
tt_int_op(1,==, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
|
||||
tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
|
||||
tt_ptr_op(onionskin, ==, create2_ptr);
|
||||
tt_ptr_op(circ2,OP_EQ, onion_next_task(&onionskin));
|
||||
tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
|
||||
tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
|
||||
tt_ptr_op(onionskin, OP_EQ, create2_ptr);
|
||||
|
||||
clear_pending_onions();
|
||||
tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
|
||||
tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
|
||||
tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
|
||||
tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
|
||||
|
||||
done:
|
||||
circuit_free(TO_CIRCUIT(circ1));
|
||||
@@ -644,13 +648,13 @@ test_rend_fns(void *arg)
|
||||
(void)arg;
|
||||
tt_assert(BAD_HOSTNAME == parse_extended_hostname(address1));
|
||||
tt_assert(ONION_HOSTNAME == parse_extended_hostname(address2));
|
||||
tt_str_op(address2,==, "aaaaaaaaaaaaaaaa");
|
||||
tt_str_op(address2,OP_EQ, "aaaaaaaaaaaaaaaa");
|
||||
tt_assert(EXIT_HOSTNAME == parse_extended_hostname(address3));
|
||||
tt_assert(NORMAL_HOSTNAME == parse_extended_hostname(address4));
|
||||
tt_assert(ONION_HOSTNAME == parse_extended_hostname(address5));
|
||||
tt_str_op(address5,==, "abcdefghijklmnop");
|
||||
tt_str_op(address5,OP_EQ, "abcdefghijklmnop");
|
||||
tt_assert(ONION_HOSTNAME == parse_extended_hostname(address6));
|
||||
tt_str_op(address6,==, "abcdefghijklmnop");
|
||||
tt_str_op(address6,OP_EQ, "abcdefghijklmnop");
|
||||
tt_assert(BAD_HOSTNAME == parse_extended_hostname(address7));
|
||||
|
||||
pk1 = pk_generate(0);
|
||||
@@ -689,7 +693,7 @@ test_rend_fns(void *arg)
|
||||
tt_assert(rend_compute_v2_desc_id(computed_desc_id, service_id_base32,
|
||||
NULL, now, 0) == 0);
|
||||
tt_mem_op(((rend_encoded_v2_service_descriptor_t *)
|
||||
smartlist_get(descs, 0))->desc_id, ==,
|
||||
smartlist_get(descs, 0))->desc_id, OP_EQ,
|
||||
computed_desc_id, DIGEST_LEN);
|
||||
tt_assert(rend_parse_v2_service_descriptor(&parsed, parsed_desc_id,
|
||||
&intro_points_encrypted,
|
||||
@@ -700,25 +704,25 @@ test_rend_fns(void *arg)
|
||||
smartlist_get(descs, 0))->desc_str) == 0);
|
||||
tt_assert(parsed);
|
||||
tt_mem_op(((rend_encoded_v2_service_descriptor_t *)
|
||||
smartlist_get(descs, 0))->desc_id,==, parsed_desc_id, DIGEST_LEN);
|
||||
smartlist_get(descs, 0))->desc_id,OP_EQ, parsed_desc_id, DIGEST_LEN);
|
||||
tt_int_op(rend_parse_introduction_points(parsed, intro_points_encrypted,
|
||||
intro_points_size),==, 3);
|
||||
intro_points_size),OP_EQ, 3);
|
||||
tt_assert(!crypto_pk_cmp_keys(generated->pk, parsed->pk));
|
||||
tt_int_op(parsed->timestamp,==, now);
|
||||
tt_int_op(parsed->version,==, 2);
|
||||
tt_int_op(parsed->protocols,==, 42);
|
||||
tt_int_op(smartlist_len(parsed->intro_nodes),==, 3);
|
||||
tt_int_op(parsed->timestamp,OP_EQ, now);
|
||||
tt_int_op(parsed->version,OP_EQ, 2);
|
||||
tt_int_op(parsed->protocols,OP_EQ, 42);
|
||||
tt_int_op(smartlist_len(parsed->intro_nodes),OP_EQ, 3);
|
||||
for (i = 0; i < smartlist_len(parsed->intro_nodes); i++) {
|
||||
rend_intro_point_t *par_intro = smartlist_get(parsed->intro_nodes, i),
|
||||
*gen_intro = smartlist_get(generated->intro_nodes, i);
|
||||
extend_info_t *par_info = par_intro->extend_info;
|
||||
extend_info_t *gen_info = gen_intro->extend_info;
|
||||
tt_assert(!crypto_pk_cmp_keys(gen_info->onion_key, par_info->onion_key));
|
||||
tt_mem_op(gen_info->identity_digest,==, par_info->identity_digest,
|
||||
tt_mem_op(gen_info->identity_digest,OP_EQ, par_info->identity_digest,
|
||||
DIGEST_LEN);
|
||||
tt_str_op(gen_info->nickname,==, par_info->nickname);
|
||||
tt_str_op(gen_info->nickname,OP_EQ, par_info->nickname);
|
||||
tt_assert(tor_addr_eq(&gen_info->addr, &par_info->addr));
|
||||
tt_int_op(gen_info->port,==, par_info->port);
|
||||
tt_int_op(gen_info->port,OP_EQ, par_info->port);
|
||||
}
|
||||
|
||||
rend_service_descriptor_free(parsed);
|
||||
@@ -762,11 +766,11 @@ test_rend_fns(void *arg)
|
||||
} while (0)
|
||||
#define CHECK_COUNTRY(country, val) do { \
|
||||
/* test ipv4 country lookup */ \
|
||||
tt_str_op(country, ==, \
|
||||
tt_str_op(country, OP_EQ, \
|
||||
geoip_get_country_name(geoip_get_country_by_ipv4(val))); \
|
||||
/* test ipv6 country lookup */ \
|
||||
SET_TEST_IPV6(val); \
|
||||
tt_str_op(country, ==, \
|
||||
tt_str_op(country, OP_EQ, \
|
||||
geoip_get_country_name(geoip_get_country_by_ipv6(&in6))); \
|
||||
} while (0)
|
||||
|
||||
@@ -827,23 +831,23 @@ test_geoip(void *arg)
|
||||
* 'sort' step. These aren't very good IP addresses, but they're perfectly
|
||||
* fine uint32_t values. */
|
||||
(void)arg;
|
||||
tt_int_op(0,==, geoip_parse_entry("10,50,AB", AF_INET));
|
||||
tt_int_op(0,==, geoip_parse_entry("52,90,XY", AF_INET));
|
||||
tt_int_op(0,==, geoip_parse_entry("95,100,AB", AF_INET));
|
||||
tt_int_op(0,==, geoip_parse_entry("\"105\",\"140\",\"ZZ\"", AF_INET));
|
||||
tt_int_op(0,==, geoip_parse_entry("\"150\",\"190\",\"XY\"", AF_INET));
|
||||
tt_int_op(0,==, geoip_parse_entry("\"200\",\"250\",\"AB\"", AF_INET));
|
||||
tt_int_op(0,OP_EQ, geoip_parse_entry("10,50,AB", AF_INET));
|
||||
tt_int_op(0,OP_EQ, geoip_parse_entry("52,90,XY", AF_INET));
|
||||
tt_int_op(0,OP_EQ, geoip_parse_entry("95,100,AB", AF_INET));
|
||||
tt_int_op(0,OP_EQ, geoip_parse_entry("\"105\",\"140\",\"ZZ\"", AF_INET));
|
||||
tt_int_op(0,OP_EQ, geoip_parse_entry("\"150\",\"190\",\"XY\"", AF_INET));
|
||||
tt_int_op(0,OP_EQ, geoip_parse_entry("\"200\",\"250\",\"AB\"", AF_INET));
|
||||
|
||||
/* Populate the IPv6 DB equivalently with fake IPs in the same range */
|
||||
tt_int_op(0,==, geoip_parse_entry("::a,::32,AB", AF_INET6));
|
||||
tt_int_op(0,==, geoip_parse_entry("::34,::5a,XY", AF_INET6));
|
||||
tt_int_op(0,==, geoip_parse_entry("::5f,::64,AB", AF_INET6));
|
||||
tt_int_op(0,==, geoip_parse_entry("::69,::8c,ZZ", AF_INET6));
|
||||
tt_int_op(0,==, geoip_parse_entry("::96,::be,XY", AF_INET6));
|
||||
tt_int_op(0,==, geoip_parse_entry("::c8,::fa,AB", AF_INET6));
|
||||
tt_int_op(0,OP_EQ, geoip_parse_entry("::a,::32,AB", AF_INET6));
|
||||
tt_int_op(0,OP_EQ, geoip_parse_entry("::34,::5a,XY", AF_INET6));
|
||||
tt_int_op(0,OP_EQ, geoip_parse_entry("::5f,::64,AB", AF_INET6));
|
||||
tt_int_op(0,OP_EQ, geoip_parse_entry("::69,::8c,ZZ", AF_INET6));
|
||||
tt_int_op(0,OP_EQ, geoip_parse_entry("::96,::be,XY", AF_INET6));
|
||||
tt_int_op(0,OP_EQ, geoip_parse_entry("::c8,::fa,AB", AF_INET6));
|
||||
|
||||
/* We should have 4 countries: ??, ab, xy, zz. */
|
||||
tt_int_op(4,==, geoip_get_n_countries());
|
||||
tt_int_op(4,OP_EQ, geoip_get_n_countries());
|
||||
memset(&in6, 0, sizeof(in6));
|
||||
|
||||
CHECK_COUNTRY("??", 3);
|
||||
@@ -854,9 +858,9 @@ test_geoip(void *arg)
|
||||
CHECK_COUNTRY("xy", 190);
|
||||
CHECK_COUNTRY("??", 2000);
|
||||
|
||||
tt_int_op(0,==, geoip_get_country_by_ipv4(3));
|
||||
tt_int_op(0,OP_EQ, geoip_get_country_by_ipv4(3));
|
||||
SET_TEST_IPV6(3);
|
||||
tt_int_op(0,==, geoip_get_country_by_ipv6(&in6));
|
||||
tt_int_op(0,OP_EQ, geoip_get_country_by_ipv6(&in6));
|
||||
|
||||
get_options_mutable()->BridgeRelay = 1;
|
||||
get_options_mutable()->BridgeRecordUsageByCountry = 1;
|
||||
@@ -881,8 +885,8 @@ test_geoip(void *arg)
|
||||
geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v);
|
||||
tt_assert(s);
|
||||
tt_assert(v);
|
||||
tt_str_op("zz=24,ab=16,xy=8",==, s);
|
||||
tt_str_op("v4=16,v6=16",==, v);
|
||||
tt_str_op("zz=24,ab=16,xy=8",OP_EQ, s);
|
||||
tt_str_op("v4=16,v6=16",OP_EQ, v);
|
||||
tor_free(s);
|
||||
tor_free(v);
|
||||
|
||||
@@ -891,8 +895,8 @@ test_geoip(void *arg)
|
||||
geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v);
|
||||
tt_assert(s);
|
||||
tt_assert(v);
|
||||
tt_str_op("zz=24,xy=8",==, s);
|
||||
tt_str_op("v4=16,v6=16",==, v);
|
||||
tt_str_op("zz=24,xy=8",OP_EQ, s);
|
||||
tt_str_op("v4=16,v6=16",OP_EQ, v);
|
||||
tor_free(s);
|
||||
tor_free(v);
|
||||
|
||||
@@ -906,7 +910,7 @@ test_geoip(void *arg)
|
||||
geoip_bridge_stats_init(now);
|
||||
s = geoip_format_bridge_stats(now + 86400);
|
||||
tt_assert(s);
|
||||
tt_str_op(bridge_stats_1,==, s);
|
||||
tt_str_op(bridge_stats_1,OP_EQ, s);
|
||||
tor_free(s);
|
||||
|
||||
/* Stop collecting bridge stats and make sure we don't write a history
|
||||
@@ -935,7 +939,7 @@ test_geoip(void *arg)
|
||||
SET_TEST_ADDRESS(100);
|
||||
geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
|
||||
s = geoip_format_dirreq_stats(now + 86400);
|
||||
tt_str_op(dirreq_stats_1,==, s);
|
||||
tt_str_op(dirreq_stats_1,OP_EQ, s);
|
||||
tor_free(s);
|
||||
|
||||
/* Stop collecting stats, add another connecting client, and ensure we
|
||||
@@ -953,20 +957,20 @@ test_geoip(void *arg)
|
||||
geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
|
||||
geoip_reset_dirreq_stats(now);
|
||||
s = geoip_format_dirreq_stats(now + 86400);
|
||||
tt_str_op(dirreq_stats_2,==, s);
|
||||
tt_str_op(dirreq_stats_2,OP_EQ, s);
|
||||
tor_free(s);
|
||||
|
||||
/* Note a successful network status response and make sure that it
|
||||
* appears in the history string. */
|
||||
geoip_note_ns_response(GEOIP_SUCCESS);
|
||||
s = geoip_format_dirreq_stats(now + 86400);
|
||||
tt_str_op(dirreq_stats_3,==, s);
|
||||
tt_str_op(dirreq_stats_3,OP_EQ, s);
|
||||
tor_free(s);
|
||||
|
||||
/* Start a tunneled directory request. */
|
||||
geoip_start_dirreq((uint64_t) 1, 1024, DIRREQ_TUNNELED);
|
||||
s = geoip_format_dirreq_stats(now + 86400);
|
||||
tt_str_op(dirreq_stats_4,==, s);
|
||||
tt_str_op(dirreq_stats_4,OP_EQ, s);
|
||||
tor_free(s);
|
||||
|
||||
/* Stop collecting directory request statistics and start gathering
|
||||
@@ -988,7 +992,7 @@ test_geoip(void *arg)
|
||||
SET_TEST_ADDRESS(100);
|
||||
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
|
||||
s = geoip_format_entry_stats(now + 86400);
|
||||
tt_str_op(entry_stats_1,==, s);
|
||||
tt_str_op(entry_stats_1,OP_EQ, s);
|
||||
tor_free(s);
|
||||
|
||||
/* Stop collecting stats, add another connecting client, and ensure we
|
||||
@@ -1006,7 +1010,7 @@ test_geoip(void *arg)
|
||||
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
|
||||
geoip_reset_entry_stats(now);
|
||||
s = geoip_format_entry_stats(now + 86400);
|
||||
tt_str_op(entry_stats_2,==, s);
|
||||
tt_str_op(entry_stats_2,OP_EQ, s);
|
||||
tor_free(s);
|
||||
|
||||
/* Stop collecting entry statistics. */
|
||||
@@ -1079,7 +1083,7 @@ test_geoip_with_pt(void *arg)
|
||||
/* Test the transport history string. */
|
||||
s = geoip_get_transport_history();
|
||||
tor_assert(s);
|
||||
tt_str_op(s,==, "<OR>=8,alpha=16,beta=8,charlie=16,ddr=136,"
|
||||
tt_str_op(s,OP_EQ, "<OR>=8,alpha=16,beta=8,charlie=16,ddr=136,"
|
||||
"entropy=8,fire=8,google=8");
|
||||
|
||||
/* Stop collecting entry statistics. */
|
||||
@@ -1122,7 +1126,7 @@ test_stats(void *arg)
|
||||
tt_str_op("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n"
|
||||
"exit-kibibytes-written 80=1,443=1,other=0\n"
|
||||
"exit-kibibytes-read 80=10,443=20,other=0\n"
|
||||
"exit-streams-opened 80=4,443=4,other=0\n",==, s);
|
||||
"exit-streams-opened 80=4,443=4,other=0\n",OP_EQ, s);
|
||||
tor_free(s);
|
||||
|
||||
/* Add a few bytes on 10 more ports and ensure that only the top 10
|
||||
@@ -1138,7 +1142,7 @@ test_stats(void *arg)
|
||||
"exit-kibibytes-read 52=1,53=1,54=1,55=1,56=1,57=1,58=1,"
|
||||
"59=1,80=10,443=20,other=1\n"
|
||||
"exit-streams-opened 52=4,53=4,54=4,55=4,56=4,57=4,58=4,"
|
||||
"59=4,80=4,443=4,other=4\n",==, s);
|
||||
"59=4,80=4,443=4,other=4\n",OP_EQ, s);
|
||||
tor_free(s);
|
||||
|
||||
/* Stop collecting stats, add some bytes, and ensure we don't generate
|
||||
@@ -1158,7 +1162,7 @@ test_stats(void *arg)
|
||||
tt_str_op("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n"
|
||||
"exit-kibibytes-written other=0\n"
|
||||
"exit-kibibytes-read other=0\n"
|
||||
"exit-streams-opened other=0\n",==, s);
|
||||
"exit-streams-opened other=0\n",OP_EQ, s);
|
||||
tor_free(s);
|
||||
|
||||
/* Continue with testing connection statistics; we shouldn't collect
|
||||
@@ -1174,7 +1178,7 @@ test_stats(void *arg)
|
||||
rep_hist_note_or_conn_bytes(2, 400000, 30000, now + 10);
|
||||
rep_hist_note_or_conn_bytes(2, 400000, 30000, now + 15);
|
||||
s = rep_hist_format_conn_stats(now + 86400);
|
||||
tt_str_op("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,1,0\n",==, s);
|
||||
tt_str_op("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,1,0\n",OP_EQ, s);
|
||||
tor_free(s);
|
||||
|
||||
/* Stop collecting stats, add some bytes, and ensure we don't generate
|
||||
@@ -1193,7 +1197,7 @@ test_stats(void *arg)
|
||||
rep_hist_note_or_conn_bytes(2, 400000, 30000, now + 15);
|
||||
rep_hist_reset_conn_stats(now);
|
||||
s = rep_hist_format_conn_stats(now + 86400);
|
||||
tt_str_op("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,0,0\n",==, s);
|
||||
tt_str_op("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,0,0\n",OP_EQ, s);
|
||||
tor_free(s);
|
||||
|
||||
/* Continue with testing buffer statistics; we shouldn't collect buffer
|
||||
@@ -1212,7 +1216,7 @@ test_stats(void *arg)
|
||||
"cell-queued-cells 2.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,"
|
||||
"0.00,0.00\n"
|
||||
"cell-time-in-queue 2,0,0,0,0,0,0,0,0,0\n"
|
||||
"cell-circuits-per-decile 1\n",==, s);
|
||||
"cell-circuits-per-decile 1\n",OP_EQ, s);
|
||||
tor_free(s);
|
||||
|
||||
/* Add nineteen more circuit statistics to the one that's already in the
|
||||
@@ -1227,7 +1231,7 @@ test_stats(void *arg)
|
||||
"cell-queued-cells 2.75,2.75,2.75,2.75,2.75,2.75,2.75,2.75,"
|
||||
"2.75,2.75\n"
|
||||
"cell-time-in-queue 3,3,3,3,3,3,3,3,3,3\n"
|
||||
"cell-circuits-per-decile 2\n",==, s);
|
||||
"cell-circuits-per-decile 2\n",OP_EQ, s);
|
||||
tor_free(s);
|
||||
|
||||
/* Stop collecting stats, add statistics for one circuit, and ensure we
|
||||
@@ -1248,7 +1252,7 @@ test_stats(void *arg)
|
||||
"cell-queued-cells 0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,"
|
||||
"0.00,0.00\n"
|
||||
"cell-time-in-queue 0,0,0,0,0,0,0,0,0,0\n"
|
||||
"cell-circuits-per-decile 0\n",==, s);
|
||||
"cell-circuits-per-decile 0\n",OP_EQ, s);
|
||||
|
||||
done:
|
||||
tor_free(s);
|
||||
@@ -1279,6 +1283,7 @@ extern struct testcase_t crypto_tests[];
|
||||
extern struct testcase_t container_tests[];
|
||||
extern struct testcase_t util_tests[];
|
||||
extern struct testcase_t dir_tests[];
|
||||
extern struct testcase_t checkdir_tests[];
|
||||
extern struct testcase_t microdesc_tests[];
|
||||
extern struct testcase_t pt_tests[];
|
||||
extern struct testcase_t config_tests[];
|
||||
@@ -1303,6 +1308,11 @@ extern struct testcase_t accounting_tests[];
|
||||
extern struct testcase_t policy_tests[];
|
||||
extern struct testcase_t status_tests[];
|
||||
extern struct testcase_t routerset_tests[];
|
||||
extern struct testcase_t router_tests[];
|
||||
extern struct testcase_t channel_tests[];
|
||||
extern struct testcase_t channeltls_tests[];
|
||||
extern struct testcase_t relay_tests[];
|
||||
extern struct testcase_t scheduler_tests[];
|
||||
|
||||
static struct testgroup_t testgroups[] = {
|
||||
{ "", test_array },
|
||||
@@ -1316,6 +1326,7 @@ static struct testgroup_t testgroups[] = {
|
||||
{ "cellfmt/", cell_format_tests },
|
||||
{ "cellqueue/", cell_queue_tests },
|
||||
{ "dir/", dir_tests },
|
||||
{ "checkdir/", checkdir_tests },
|
||||
{ "dir/md/", microdesc_tests },
|
||||
{ "pt/", pt_tests },
|
||||
{ "config/", config_tests },
|
||||
@@ -1336,6 +1347,10 @@ static struct testgroup_t testgroups[] = {
|
||||
{ "policy/" , policy_tests },
|
||||
{ "status/" , status_tests },
|
||||
{ "routerset/" , routerset_tests },
|
||||
{ "channel/", channel_tests },
|
||||
{ "channeltls/", channeltls_tests },
|
||||
{ "relay/" , relay_tests },
|
||||
{ "scheduler/", scheduler_tests },
|
||||
END_OF_GROUPS
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@
|
||||
tt_mem_op(expr1, op, mem_op_hex_tmp, length/2); \
|
||||
STMT_END
|
||||
|
||||
#define test_memeq_hex(expr1, hex) test_mem_op_hex(expr1, ==, hex)
|
||||
#define test_memeq_hex(expr1, hex) test_mem_op_hex(expr1, OP_EQ, hex)
|
||||
|
||||
#define tt_double_op(a,op,b) \
|
||||
tt_assert_test_type(a,b,#a" "#op" "#b,double,(val1_ op val2_),"%f", \
|
||||
|
||||
+233
-230
@@ -20,40 +20,40 @@ test_addr_basic(void *arg)
|
||||
(void)arg;
|
||||
cp = NULL; u32 = 3; u16 = 3;
|
||||
tt_assert(!addr_port_lookup(LOG_WARN, "1.2.3.4", &cp, &u32, &u16));
|
||||
tt_str_op(cp,==, "1.2.3.4");
|
||||
tt_int_op(u32,==, 0x01020304u);
|
||||
tt_int_op(u16,==, 0);
|
||||
tt_str_op(cp,OP_EQ, "1.2.3.4");
|
||||
tt_int_op(u32,OP_EQ, 0x01020304u);
|
||||
tt_int_op(u16,OP_EQ, 0);
|
||||
tor_free(cp);
|
||||
tt_assert(!addr_port_lookup(LOG_WARN, "4.3.2.1:99", &cp, &u32, &u16));
|
||||
tt_str_op(cp,==, "4.3.2.1");
|
||||
tt_int_op(u32,==, 0x04030201u);
|
||||
tt_int_op(u16,==, 99);
|
||||
tt_str_op(cp,OP_EQ, "4.3.2.1");
|
||||
tt_int_op(u32,OP_EQ, 0x04030201u);
|
||||
tt_int_op(u16,OP_EQ, 99);
|
||||
tor_free(cp);
|
||||
tt_assert(!addr_port_lookup(LOG_WARN, "nonexistent.address:4040",
|
||||
&cp, NULL, &u16));
|
||||
tt_str_op(cp,==, "nonexistent.address");
|
||||
tt_int_op(u16,==, 4040);
|
||||
tt_str_op(cp,OP_EQ, "nonexistent.address");
|
||||
tt_int_op(u16,OP_EQ, 4040);
|
||||
tor_free(cp);
|
||||
tt_assert(!addr_port_lookup(LOG_WARN, "localhost:9999", &cp, &u32, &u16));
|
||||
tt_str_op(cp,==, "localhost");
|
||||
tt_int_op(u32,==, 0x7f000001u);
|
||||
tt_int_op(u16,==, 9999);
|
||||
tt_str_op(cp,OP_EQ, "localhost");
|
||||
tt_int_op(u32,OP_EQ, 0x7f000001u);
|
||||
tt_int_op(u16,OP_EQ, 9999);
|
||||
tor_free(cp);
|
||||
u32 = 3;
|
||||
tt_assert(!addr_port_lookup(LOG_WARN, "localhost", NULL, &u32, &u16));
|
||||
tt_ptr_op(cp,==, NULL);
|
||||
tt_int_op(u32,==, 0x7f000001u);
|
||||
tt_int_op(u16,==, 0);
|
||||
tt_ptr_op(cp,OP_EQ, NULL);
|
||||
tt_int_op(u32,OP_EQ, 0x7f000001u);
|
||||
tt_int_op(u16,OP_EQ, 0);
|
||||
tor_free(cp);
|
||||
|
||||
tt_assert(addr_port_lookup(LOG_WARN, "localhost:3", &cp, &u32, NULL));
|
||||
tor_free(cp);
|
||||
|
||||
tt_int_op(0,==, addr_mask_get_bits(0x0u));
|
||||
tt_int_op(32,==, addr_mask_get_bits(0xFFFFFFFFu));
|
||||
tt_int_op(16,==, addr_mask_get_bits(0xFFFF0000u));
|
||||
tt_int_op(31,==, addr_mask_get_bits(0xFFFFFFFEu));
|
||||
tt_int_op(1,==, addr_mask_get_bits(0x80000000u));
|
||||
tt_int_op(0,OP_EQ, addr_mask_get_bits(0x0u));
|
||||
tt_int_op(32,OP_EQ, addr_mask_get_bits(0xFFFFFFFFu));
|
||||
tt_int_op(16,OP_EQ, addr_mask_get_bits(0xFFFF0000u));
|
||||
tt_int_op(31,OP_EQ, addr_mask_get_bits(0xFFFFFFFEu));
|
||||
tt_int_op(1,OP_EQ, addr_mask_get_bits(0x80000000u));
|
||||
|
||||
/* Test inet_ntop */
|
||||
{
|
||||
@@ -62,15 +62,16 @@ test_addr_basic(void *arg)
|
||||
struct in_addr in;
|
||||
|
||||
/* good round trip */
|
||||
tt_int_op(tor_inet_pton(AF_INET, ip, &in),==, 1);
|
||||
tt_ptr_op(tor_inet_ntop(AF_INET, &in, tmpbuf, sizeof(tmpbuf)),==, &tmpbuf);
|
||||
tt_str_op(tmpbuf,==, ip);
|
||||
tt_int_op(tor_inet_pton(AF_INET, ip, &in), OP_EQ, 1);
|
||||
tt_ptr_op(tor_inet_ntop(AF_INET, &in, tmpbuf, sizeof(tmpbuf)),
|
||||
OP_EQ, &tmpbuf);
|
||||
tt_str_op(tmpbuf,OP_EQ, ip);
|
||||
|
||||
/* just enough buffer length */
|
||||
tt_str_op(tor_inet_ntop(AF_INET, &in, tmpbuf, strlen(ip) + 1),==, ip);
|
||||
tt_str_op(tor_inet_ntop(AF_INET, &in, tmpbuf, strlen(ip) + 1), OP_EQ, ip);
|
||||
|
||||
/* too short buffer */
|
||||
tt_ptr_op(tor_inet_ntop(AF_INET, &in, tmpbuf, strlen(ip)),==, NULL);
|
||||
tt_ptr_op(tor_inet_ntop(AF_INET, &in, tmpbuf, strlen(ip)),OP_EQ, NULL);
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -98,30 +99,30 @@ test_addr_basic(void *arg)
|
||||
/** Helper: Assert that two strings both decode as IPv6 addresses with
|
||||
* tor_inet_pton(), and both decode to the same address. */
|
||||
#define test_pton6_same(a,b) STMT_BEGIN \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, a, &a1), ==, 1); \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, b, &a2), ==, 1); \
|
||||
test_op_ip6_(&a1,==,&a2,#a,#b); \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, a, &a1), OP_EQ, 1); \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, b, &a2), OP_EQ, 1); \
|
||||
test_op_ip6_(&a1,OP_EQ,&a2,#a,#b); \
|
||||
STMT_END
|
||||
|
||||
/** Helper: Assert that <b>a</b> is recognized as a bad IPv6 address by
|
||||
* tor_inet_pton(). */
|
||||
#define test_pton6_bad(a) \
|
||||
tt_int_op(0, ==, tor_inet_pton(AF_INET6, a, &a1))
|
||||
tt_int_op(0, OP_EQ, tor_inet_pton(AF_INET6, a, &a1))
|
||||
|
||||
/** Helper: assert that <b>a</b>, when parsed by tor_inet_pton() and displayed
|
||||
* with tor_inet_ntop(), yields <b>b</b>. Also assert that <b>b</b> parses to
|
||||
* the same value as <b>a</b>. */
|
||||
#define test_ntop6_reduces(a,b) STMT_BEGIN \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, a, &a1), ==, 1); \
|
||||
tt_str_op(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)), ==, b); \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, b, &a2), ==, 1); \
|
||||
test_op_ip6_(&a1, ==, &a2, a, b); \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, a, &a1), OP_EQ, 1); \
|
||||
tt_str_op(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)), OP_EQ, b); \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, b, &a2), OP_EQ, 1); \
|
||||
test_op_ip6_(&a1, OP_EQ, &a2, a, b); \
|
||||
STMT_END
|
||||
|
||||
/** Helper: assert that <b>a</b> parses by tor_inet_pton() into a address that
|
||||
* passes tor_addr_is_internal() with <b>for_listening</b>. */
|
||||
#define test_internal_ip(a,for_listening) STMT_BEGIN \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), ==, 1); \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), OP_EQ, 1); \
|
||||
t1.family = AF_INET6; \
|
||||
if (!tor_addr_is_internal(&t1, for_listening)) \
|
||||
TT_DIE(("%s was not internal", a)); \
|
||||
@@ -130,7 +131,7 @@ test_addr_basic(void *arg)
|
||||
/** Helper: assert that <b>a</b> parses by tor_inet_pton() into a address that
|
||||
* does not pass tor_addr_is_internal() with <b>for_listening</b>. */
|
||||
#define test_external_ip(a,for_listening) STMT_BEGIN \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), ==, 1); \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), OP_EQ, 1); \
|
||||
t1.family = AF_INET6; \
|
||||
if (tor_addr_is_internal(&t1, for_listening)) \
|
||||
TT_DIE(("%s was not internal", a)); \
|
||||
@@ -140,8 +141,8 @@ test_addr_basic(void *arg)
|
||||
* tor_inet_pton(), give addresses that compare in the order defined by
|
||||
* <b>op</b> with tor_addr_compare(). */
|
||||
#define test_addr_compare(a, op, b) STMT_BEGIN \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), ==, 1); \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), ==, 1); \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), OP_EQ, 1); \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), OP_EQ, 1); \
|
||||
t1.family = t2.family = AF_INET6; \
|
||||
r = tor_addr_compare(&t1,&t2,CMP_SEMANTIC); \
|
||||
if (!(r op 0)) \
|
||||
@@ -152,8 +153,8 @@ test_addr_basic(void *arg)
|
||||
* tor_inet_pton(), give addresses that compare in the order defined by
|
||||
* <b>op</b> with tor_addr_compare_masked() with <b>m</b> masked. */
|
||||
#define test_addr_compare_masked(a, op, b, m) STMT_BEGIN \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), ==, 1); \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), ==, 1); \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), OP_EQ, 1); \
|
||||
tt_int_op(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), OP_EQ, 1); \
|
||||
t1.family = t2.family = AF_INET6; \
|
||||
r = tor_addr_compare_masked(&t1,&t2,m,CMP_SEMANTIC); \
|
||||
if (!(r op 0)) \
|
||||
@@ -168,15 +169,15 @@ test_addr_basic(void *arg)
|
||||
#define test_addr_mask_ports_parse(xx, f, ip1, ip2, ip3, ip4, mm, pt1, pt2) \
|
||||
STMT_BEGIN \
|
||||
tt_int_op(tor_addr_parse_mask_ports(xx, 0, &t1, &mask, &port1, &port2), \
|
||||
==, f); \
|
||||
OP_EQ, f); \
|
||||
p1=tor_inet_ntop(AF_INET6, &t1.addr.in6_addr, bug, sizeof(bug)); \
|
||||
tt_int_op(htonl(ip1), ==, tor_addr_to_in6_addr32(&t1)[0]); \
|
||||
tt_int_op(htonl(ip2), ==, tor_addr_to_in6_addr32(&t1)[1]); \
|
||||
tt_int_op(htonl(ip3), ==, tor_addr_to_in6_addr32(&t1)[2]); \
|
||||
tt_int_op(htonl(ip4), ==, tor_addr_to_in6_addr32(&t1)[3]); \
|
||||
tt_int_op(mask, ==, mm); \
|
||||
tt_uint_op(port1, ==, pt1); \
|
||||
tt_uint_op(port2, ==, pt2); \
|
||||
tt_int_op(htonl(ip1), OP_EQ, tor_addr_to_in6_addr32(&t1)[0]); \
|
||||
tt_int_op(htonl(ip2), OP_EQ, tor_addr_to_in6_addr32(&t1)[1]); \
|
||||
tt_int_op(htonl(ip3), OP_EQ, tor_addr_to_in6_addr32(&t1)[2]); \
|
||||
tt_int_op(htonl(ip4), OP_EQ, tor_addr_to_in6_addr32(&t1)[3]); \
|
||||
tt_int_op(mask, OP_EQ, mm); \
|
||||
tt_uint_op(port1, OP_EQ, pt1); \
|
||||
tt_uint_op(port2, OP_EQ, pt2); \
|
||||
STMT_END
|
||||
|
||||
/** Run unit tests for IPv6 encoding/decoding/manipulation functions. */
|
||||
@@ -202,23 +203,23 @@ test_addr_ip6_helpers(void *arg)
|
||||
const char *ip_ffff = "::ffff:192.168.1.2";
|
||||
|
||||
/* good round trip */
|
||||
tt_int_op(tor_inet_pton(AF_INET6, ip, &a1),==, 1);
|
||||
tt_ptr_op(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)),==, &buf);
|
||||
tt_str_op(buf,==, ip);
|
||||
tt_int_op(tor_inet_pton(AF_INET6, ip, &a1),OP_EQ, 1);
|
||||
tt_ptr_op(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)),OP_EQ, &buf);
|
||||
tt_str_op(buf,OP_EQ, ip);
|
||||
|
||||
/* good round trip - ::ffff:0:0 style */
|
||||
tt_int_op(tor_inet_pton(AF_INET6, ip_ffff, &a2),==, 1);
|
||||
tt_ptr_op(tor_inet_ntop(AF_INET6, &a2, buf, sizeof(buf)),==, &buf);
|
||||
tt_str_op(buf,==, ip_ffff);
|
||||
tt_int_op(tor_inet_pton(AF_INET6, ip_ffff, &a2),OP_EQ, 1);
|
||||
tt_ptr_op(tor_inet_ntop(AF_INET6, &a2, buf, sizeof(buf)),OP_EQ, &buf);
|
||||
tt_str_op(buf,OP_EQ, ip_ffff);
|
||||
|
||||
/* just long enough buffer (remember \0) */
|
||||
tt_str_op(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)+1),==, ip);
|
||||
tt_str_op(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)+1),==,
|
||||
tt_str_op(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)+1),OP_EQ, ip);
|
||||
tt_str_op(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)+1),OP_EQ,
|
||||
ip_ffff);
|
||||
|
||||
/* too short buffer (remember \0) */
|
||||
tt_ptr_op(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)),==, NULL);
|
||||
tt_ptr_op(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)),==, NULL);
|
||||
tt_ptr_op(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)),OP_EQ, NULL);
|
||||
tt_ptr_op(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)),OP_EQ, NULL);
|
||||
}
|
||||
|
||||
/* ==== Converting to and from sockaddr_t. */
|
||||
@@ -227,16 +228,16 @@ test_addr_ip6_helpers(void *arg)
|
||||
sin->sin_port = htons(9090);
|
||||
sin->sin_addr.s_addr = htonl(0x7f7f0102); /*127.127.1.2*/
|
||||
tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, &port1);
|
||||
tt_int_op(tor_addr_family(&t1),==, AF_INET);
|
||||
tt_int_op(tor_addr_to_ipv4h(&t1),==, 0x7f7f0102);
|
||||
tt_int_op(port1, ==, 9090);
|
||||
tt_int_op(tor_addr_family(&t1),OP_EQ, AF_INET);
|
||||
tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ, 0x7f7f0102);
|
||||
tt_int_op(port1, OP_EQ, 9090);
|
||||
|
||||
memset(&sa_storage, 0, sizeof(sa_storage));
|
||||
tt_int_op(sizeof(struct sockaddr_in),==,
|
||||
tt_int_op(sizeof(struct sockaddr_in),OP_EQ,
|
||||
tor_addr_to_sockaddr(&t1, 1234, (struct sockaddr *)&sa_storage,
|
||||
sizeof(sa_storage)));
|
||||
tt_int_op(1234,==, ntohs(sin->sin_port));
|
||||
tt_int_op(0x7f7f0102,==, ntohl(sin->sin_addr.s_addr));
|
||||
tt_int_op(1234,OP_EQ, ntohs(sin->sin_port));
|
||||
tt_int_op(0x7f7f0102,OP_EQ, ntohl(sin->sin_addr.s_addr));
|
||||
|
||||
memset(&sa_storage, 0, sizeof(sa_storage));
|
||||
sin6 = (struct sockaddr_in6 *)&sa_storage;
|
||||
@@ -244,37 +245,37 @@ test_addr_ip6_helpers(void *arg)
|
||||
sin6->sin6_port = htons(7070);
|
||||
sin6->sin6_addr.s6_addr[0] = 128;
|
||||
tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, &port1);
|
||||
tt_int_op(tor_addr_family(&t1),==, AF_INET6);
|
||||
tt_int_op(port1, ==, 7070);
|
||||
tt_int_op(tor_addr_family(&t1),OP_EQ, AF_INET6);
|
||||
tt_int_op(port1, OP_EQ, 7070);
|
||||
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0);
|
||||
tt_str_op(p1,==, "8000::");
|
||||
tt_str_op(p1,OP_EQ, "8000::");
|
||||
|
||||
memset(&sa_storage, 0, sizeof(sa_storage));
|
||||
tt_int_op(sizeof(struct sockaddr_in6),==,
|
||||
tt_int_op(sizeof(struct sockaddr_in6),OP_EQ,
|
||||
tor_addr_to_sockaddr(&t1, 9999, (struct sockaddr *)&sa_storage,
|
||||
sizeof(sa_storage)));
|
||||
tt_int_op(AF_INET6,==, sin6->sin6_family);
|
||||
tt_int_op(9999,==, ntohs(sin6->sin6_port));
|
||||
tt_int_op(0x80000000,==, ntohl(S6_ADDR32(sin6->sin6_addr)[0]));
|
||||
tt_int_op(AF_INET6,OP_EQ, sin6->sin6_family);
|
||||
tt_int_op(9999,OP_EQ, ntohs(sin6->sin6_port));
|
||||
tt_int_op(0x80000000,OP_EQ, ntohl(S6_ADDR32(sin6->sin6_addr)[0]));
|
||||
|
||||
/* ==== tor_addr_lookup: static cases. (Can't test dns without knowing we
|
||||
* have a good resolver. */
|
||||
tt_int_op(0,==, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1));
|
||||
tt_int_op(AF_INET,==, tor_addr_family(&t1));
|
||||
tt_int_op(tor_addr_to_ipv4h(&t1),==, 0x7f808182);
|
||||
tt_int_op(0,OP_EQ, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1));
|
||||
tt_int_op(AF_INET,OP_EQ, tor_addr_family(&t1));
|
||||
tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ, 0x7f808182);
|
||||
|
||||
tt_int_op(0,==, tor_addr_lookup("9000::5", AF_UNSPEC, &t1));
|
||||
tt_int_op(AF_INET6,==, tor_addr_family(&t1));
|
||||
tt_int_op(0x90,==, tor_addr_to_in6_addr8(&t1)[0]);
|
||||
tt_int_op(0,OP_EQ, tor_addr_lookup("9000::5", AF_UNSPEC, &t1));
|
||||
tt_int_op(AF_INET6,OP_EQ, tor_addr_family(&t1));
|
||||
tt_int_op(0x90,OP_EQ, tor_addr_to_in6_addr8(&t1)[0]);
|
||||
tt_assert(tor_mem_is_zero((char*)tor_addr_to_in6_addr8(&t1)+1, 14));
|
||||
tt_int_op(0x05,==, tor_addr_to_in6_addr8(&t1)[15]);
|
||||
tt_int_op(0x05,OP_EQ, tor_addr_to_in6_addr8(&t1)[15]);
|
||||
|
||||
/* === Test pton: valid af_inet6 */
|
||||
/* Simple, valid parsing. */
|
||||
r = tor_inet_pton(AF_INET6,
|
||||
"0102:0304:0506:0708:090A:0B0C:0D0E:0F10", &a1);
|
||||
tt_int_op(r, ==, 1);
|
||||
for (i=0;i<16;++i) { tt_int_op(i+1,==, (int)a1.s6_addr[i]); }
|
||||
tt_int_op(r, OP_EQ, 1);
|
||||
for (i=0;i<16;++i) { tt_int_op(i+1,OP_EQ, (int)a1.s6_addr[i]); }
|
||||
/* ipv4 ending. */
|
||||
test_pton6_same("0102:0304:0506:0708:090A:0B0C:0D0E:0F10",
|
||||
"0102:0304:0506:0708:090A:0B0C:13.14.15.16");
|
||||
@@ -314,7 +315,7 @@ test_addr_ip6_helpers(void *arg)
|
||||
"1000:1:0:7::");
|
||||
|
||||
/* Bad af param */
|
||||
tt_int_op(tor_inet_pton(AF_UNSPEC, 0, 0),==, -1);
|
||||
tt_int_op(tor_inet_pton(AF_UNSPEC, 0, 0),OP_EQ, -1);
|
||||
|
||||
/* === Test pton: invalid in6. */
|
||||
test_pton6_bad("foobar.");
|
||||
@@ -410,11 +411,12 @@ test_addr_ip6_helpers(void *arg)
|
||||
test_external_ip("::ffff:169.255.0.0", 0);
|
||||
|
||||
/* tor_addr_compare(tor_addr_t x2) */
|
||||
test_addr_compare("ffff::", ==, "ffff::0");
|
||||
test_addr_compare("0::3:2:1", <, "0::ffff:0.3.2.1");
|
||||
test_addr_compare("0::2:2:1", <, "0::ffff:0.3.2.1");
|
||||
test_addr_compare("0::ffff:0.3.2.1", >, "0::0:0:0");
|
||||
test_addr_compare("0::ffff:5.2.2.1", <, "::ffff:6.0.0.0"); /* XXXX wrong. */
|
||||
test_addr_compare("ffff::", OP_EQ, "ffff::0");
|
||||
test_addr_compare("0::3:2:1", OP_LT, "0::ffff:0.3.2.1");
|
||||
test_addr_compare("0::2:2:1", OP_LT, "0::ffff:0.3.2.1");
|
||||
test_addr_compare("0::ffff:0.3.2.1", OP_GT, "0::0:0:0");
|
||||
test_addr_compare("0::ffff:5.2.2.1", OP_LT,
|
||||
"::ffff:6.0.0.0"); /* XXXX wrong. */
|
||||
tor_addr_parse_mask_ports("[::ffff:2.3.4.5]", 0, &t1, NULL, NULL, NULL);
|
||||
tor_addr_parse_mask_ports("2.3.4.5", 0, &t2, NULL, NULL, NULL);
|
||||
tt_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) == 0);
|
||||
@@ -423,119 +425,120 @@ test_addr_ip6_helpers(void *arg)
|
||||
tt_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) < 0);
|
||||
|
||||
/* test compare_masked */
|
||||
test_addr_compare_masked("ffff::", ==, "ffff::0", 128);
|
||||
test_addr_compare_masked("ffff::", ==, "ffff::0", 64);
|
||||
test_addr_compare_masked("0::2:2:1", <, "0::8000:2:1", 81);
|
||||
test_addr_compare_masked("0::2:2:1", ==, "0::8000:2:1", 80);
|
||||
test_addr_compare_masked("ffff::", OP_EQ, "ffff::0", 128);
|
||||
test_addr_compare_masked("ffff::", OP_EQ, "ffff::0", 64);
|
||||
test_addr_compare_masked("0::2:2:1", OP_LT, "0::8000:2:1", 81);
|
||||
test_addr_compare_masked("0::2:2:1", OP_EQ, "0::8000:2:1", 80);
|
||||
|
||||
/* Test undecorated tor_addr_to_str */
|
||||
tt_int_op(AF_INET6,==, tor_addr_parse(&t1, "[123:45:6789::5005:11]"));
|
||||
tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "[123:45:6789::5005:11]"));
|
||||
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0);
|
||||
tt_str_op(p1,==, "123:45:6789::5005:11");
|
||||
tt_int_op(AF_INET,==, tor_addr_parse(&t1, "18.0.0.1"));
|
||||
tt_str_op(p1,OP_EQ, "123:45:6789::5005:11");
|
||||
tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&t1, "18.0.0.1"));
|
||||
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0);
|
||||
tt_str_op(p1,==, "18.0.0.1");
|
||||
tt_str_op(p1,OP_EQ, "18.0.0.1");
|
||||
|
||||
/* Test decorated tor_addr_to_str */
|
||||
tt_int_op(AF_INET6,==, tor_addr_parse(&t1, "[123:45:6789::5005:11]"));
|
||||
tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "[123:45:6789::5005:11]"));
|
||||
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
|
||||
tt_str_op(p1,==, "[123:45:6789::5005:11]");
|
||||
tt_int_op(AF_INET,==, tor_addr_parse(&t1, "18.0.0.1"));
|
||||
tt_str_op(p1,OP_EQ, "[123:45:6789::5005:11]");
|
||||
tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&t1, "18.0.0.1"));
|
||||
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
|
||||
tt_str_op(p1,==, "18.0.0.1");
|
||||
tt_str_op(p1,OP_EQ, "18.0.0.1");
|
||||
|
||||
/* Test buffer bounds checking of tor_addr_to_str */
|
||||
tt_int_op(AF_INET6,==, tor_addr_parse(&t1, "::")); /* 2 + \0 */
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, 2, 0),==, NULL); /* too short buf */
|
||||
tt_str_op(tor_addr_to_str(buf, &t1, 3, 0),==, "::");
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, 4, 1),==, NULL); /* too short buf */
|
||||
tt_str_op(tor_addr_to_str(buf, &t1, 5, 1),==, "[::]");
|
||||
tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "::")); /* 2 + \0 */
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, 2, 0),OP_EQ, NULL); /* too short buf */
|
||||
tt_str_op(tor_addr_to_str(buf, &t1, 3, 0),OP_EQ, "::");
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, 4, 1),OP_EQ, NULL); /* too short buf */
|
||||
tt_str_op(tor_addr_to_str(buf, &t1, 5, 1),OP_EQ, "[::]");
|
||||
|
||||
tt_int_op(AF_INET6,==, tor_addr_parse(&t1, "2000::1337")); /* 10 + \0 */
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, 10, 0),==, NULL); /* too short buf */
|
||||
tt_str_op(tor_addr_to_str(buf, &t1, 11, 0),==, "2000::1337");
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, 12, 1),==, NULL); /* too short buf */
|
||||
tt_str_op(tor_addr_to_str(buf, &t1, 13, 1),==, "[2000::1337]");
|
||||
tt_int_op(AF_INET6,OP_EQ, tor_addr_parse(&t1, "2000::1337")); /* 10 + \0 */
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, 10, 0),OP_EQ, NULL); /* too short buf */
|
||||
tt_str_op(tor_addr_to_str(buf, &t1, 11, 0),OP_EQ, "2000::1337");
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, 12, 1),OP_EQ, NULL); /* too short buf */
|
||||
tt_str_op(tor_addr_to_str(buf, &t1, 13, 1),OP_EQ, "[2000::1337]");
|
||||
|
||||
tt_int_op(AF_INET,==, tor_addr_parse(&t1, "1.2.3.4")); /* 7 + \0 */
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, 7, 0),==, NULL); /* too short buf */
|
||||
tt_str_op(tor_addr_to_str(buf, &t1, 8, 0),==, "1.2.3.4");
|
||||
tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&t1, "1.2.3.4")); /* 7 + \0 */
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, 7, 0),OP_EQ, NULL); /* too short buf */
|
||||
tt_str_op(tor_addr_to_str(buf, &t1, 8, 0),OP_EQ, "1.2.3.4");
|
||||
|
||||
tt_int_op(AF_INET,==, tor_addr_parse(&t1, "255.255.255.255")); /* 15 + \0 */
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, 15, 0),==, NULL); /* too short buf */
|
||||
tt_str_op(tor_addr_to_str(buf, &t1, 16, 0),==, "255.255.255.255");
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, 15, 1),==, NULL); /* too short buf */
|
||||
tt_str_op(tor_addr_to_str(buf, &t1, 16, 1),==, "255.255.255.255");
|
||||
tt_int_op(AF_INET, OP_EQ,
|
||||
tor_addr_parse(&t1, "255.255.255.255")); /* 15 + \0 */
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, 15, 0),OP_EQ, NULL); /* too short buf */
|
||||
tt_str_op(tor_addr_to_str(buf, &t1, 16, 0),OP_EQ, "255.255.255.255");
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, 15, 1),OP_EQ, NULL); /* too short buf */
|
||||
tt_str_op(tor_addr_to_str(buf, &t1, 16, 1),OP_EQ, "255.255.255.255");
|
||||
|
||||
t1.family = AF_UNSPEC;
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, sizeof(buf), 0),==, NULL);
|
||||
tt_ptr_op(tor_addr_to_str(buf, &t1, sizeof(buf), 0),OP_EQ, NULL);
|
||||
|
||||
/* Test tor_addr_parse_PTR_name */
|
||||
i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 0);
|
||||
tt_int_op(0,==, i);
|
||||
tt_int_op(0,OP_EQ, i);
|
||||
i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 1);
|
||||
tt_int_op(0,==, i);
|
||||
tt_int_op(0,OP_EQ, i);
|
||||
i = tor_addr_parse_PTR_name(&t1, "9999999999999999999999999999.in-addr.arpa",
|
||||
AF_UNSPEC, 1);
|
||||
tt_int_op(-1,==, i);
|
||||
tt_int_op(-1,OP_EQ, i);
|
||||
i = tor_addr_parse_PTR_name(&t1, "1.0.168.192.in-addr.arpa",
|
||||
AF_UNSPEC, 1);
|
||||
tt_int_op(1,==, i);
|
||||
tt_int_op(tor_addr_family(&t1),==, AF_INET);
|
||||
tt_int_op(1,OP_EQ, i);
|
||||
tt_int_op(tor_addr_family(&t1),OP_EQ, AF_INET);
|
||||
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
|
||||
tt_str_op(p1,==, "192.168.0.1");
|
||||
tt_str_op(p1,OP_EQ, "192.168.0.1");
|
||||
i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 0);
|
||||
tt_int_op(0,==, i);
|
||||
tt_int_op(0,OP_EQ, i);
|
||||
i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 1);
|
||||
tt_int_op(1,==, i);
|
||||
tt_int_op(1,OP_EQ, i);
|
||||
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
|
||||
tt_str_op(p1,==, "192.168.0.99");
|
||||
tt_str_op(p1,OP_EQ, "192.168.0.99");
|
||||
memset(&t1, 0, sizeof(t1));
|
||||
i = tor_addr_parse_PTR_name(&t1,
|
||||
"0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f."
|
||||
"f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
|
||||
"ip6.ARPA",
|
||||
AF_UNSPEC, 0);
|
||||
tt_int_op(1,==, i);
|
||||
tt_int_op(1,OP_EQ, i);
|
||||
p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1);
|
||||
tt_str_op(p1,==, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]");
|
||||
tt_str_op(p1,OP_EQ, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]");
|
||||
/* Failing cases. */
|
||||
i = tor_addr_parse_PTR_name(&t1,
|
||||
"6.7.8.9.a.b.c.d.e.f."
|
||||
"f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
|
||||
"ip6.ARPA",
|
||||
AF_UNSPEC, 0);
|
||||
tt_int_op(i,==, -1);
|
||||
tt_int_op(i,OP_EQ, -1);
|
||||
i = tor_addr_parse_PTR_name(&t1,
|
||||
"6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.f.0."
|
||||
"f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
|
||||
"ip6.ARPA",
|
||||
AF_UNSPEC, 0);
|
||||
tt_int_op(i,==, -1);
|
||||
tt_int_op(i,OP_EQ, -1);
|
||||
i = tor_addr_parse_PTR_name(&t1,
|
||||
"6.7.8.9.a.b.c.d.e.f.X.0.0.0.0.9."
|
||||
"f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
|
||||
"ip6.ARPA",
|
||||
AF_UNSPEC, 0);
|
||||
tt_int_op(i,==, -1);
|
||||
tt_int_op(i,OP_EQ, -1);
|
||||
i = tor_addr_parse_PTR_name(&t1, "32.1.1.in-addr.arpa",
|
||||
AF_UNSPEC, 0);
|
||||
tt_int_op(i,==, -1);
|
||||
tt_int_op(i,OP_EQ, -1);
|
||||
i = tor_addr_parse_PTR_name(&t1, ".in-addr.arpa",
|
||||
AF_UNSPEC, 0);
|
||||
tt_int_op(i,==, -1);
|
||||
tt_int_op(i,OP_EQ, -1);
|
||||
i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa",
|
||||
AF_UNSPEC, 0);
|
||||
tt_int_op(i,==, -1);
|
||||
tt_int_op(i,OP_EQ, -1);
|
||||
i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa",
|
||||
AF_INET6, 0);
|
||||
tt_int_op(i,==, -1);
|
||||
tt_int_op(i,OP_EQ, -1);
|
||||
i = tor_addr_parse_PTR_name(&t1,
|
||||
"6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.0."
|
||||
"f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9."
|
||||
"ip6.ARPA",
|
||||
AF_INET, 0);
|
||||
tt_int_op(i,==, -1);
|
||||
tt_int_op(i,OP_EQ, -1);
|
||||
|
||||
/* === Test tor_addr_to_PTR_name */
|
||||
|
||||
@@ -547,19 +550,19 @@ test_addr_ip6_helpers(void *arg)
|
||||
tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, NULL);
|
||||
|
||||
/* Check IPv4 PTR - too short buffer */
|
||||
tt_int_op(tor_addr_to_PTR_name(rbuf, 1, &t1),==, -1);
|
||||
tt_int_op(tor_addr_to_PTR_name(rbuf, 1, &t1),OP_EQ, -1);
|
||||
tt_int_op(tor_addr_to_PTR_name(rbuf,
|
||||
strlen("3.2.1.127.in-addr.arpa") - 1,
|
||||
&t1),==, -1);
|
||||
&t1),OP_EQ, -1);
|
||||
|
||||
/* Check IPv4 PTR - valid addr */
|
||||
tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),==,
|
||||
tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),OP_EQ,
|
||||
strlen("3.2.1.127.in-addr.arpa"));
|
||||
tt_str_op(rbuf,==, "3.2.1.127.in-addr.arpa");
|
||||
tt_str_op(rbuf,OP_EQ, "3.2.1.127.in-addr.arpa");
|
||||
|
||||
/* Invalid addr family */
|
||||
t1.family = AF_UNSPEC;
|
||||
tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),==, -1);
|
||||
tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),OP_EQ, -1);
|
||||
|
||||
/* Stage IPv6 addr */
|
||||
memset(&sa_storage, 0, sizeof(sa_storage));
|
||||
@@ -576,82 +579,82 @@ test_addr_ip6_helpers(void *arg)
|
||||
"0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.ip6.arpa";
|
||||
|
||||
/* Check IPv6 PTR - too short buffer */
|
||||
tt_int_op(tor_addr_to_PTR_name(rbuf, 0, &t1),==, -1);
|
||||
tt_int_op(tor_addr_to_PTR_name(rbuf, strlen(addr_PTR) - 1, &t1),==, -1);
|
||||
tt_int_op(tor_addr_to_PTR_name(rbuf, 0, &t1),OP_EQ, -1);
|
||||
tt_int_op(tor_addr_to_PTR_name(rbuf, strlen(addr_PTR) - 1, &t1),OP_EQ, -1);
|
||||
|
||||
/* Check IPv6 PTR - valid addr */
|
||||
tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),==,
|
||||
tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),OP_EQ,
|
||||
strlen(addr_PTR));
|
||||
tt_str_op(rbuf,==, addr_PTR);
|
||||
tt_str_op(rbuf,OP_EQ, addr_PTR);
|
||||
}
|
||||
|
||||
/* XXXX turn this into a separate function; it's not all IPv6. */
|
||||
/* test tor_addr_parse_mask_ports */
|
||||
test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6,
|
||||
0, 0, 0, 0x0000000f, 17, 47, 95);
|
||||
tt_str_op(p1,==, "::f");
|
||||
tt_str_op(p1,OP_EQ, "::f");
|
||||
//test_addr_parse("[::fefe:4.1.1.7/120]:999-1000");
|
||||
//test_addr_parse_check("::fefe:401:107", 120, 999, 1000);
|
||||
test_addr_mask_ports_parse("[::ffff:4.1.1.7]/120:443", AF_INET6,
|
||||
0, 0, 0x0000ffff, 0x04010107, 120, 443, 443);
|
||||
tt_str_op(p1,==, "::ffff:4.1.1.7");
|
||||
tt_str_op(p1,OP_EQ, "::ffff:4.1.1.7");
|
||||
test_addr_mask_ports_parse("[abcd:2::44a:0]:2-65000", AF_INET6,
|
||||
0xabcd0002, 0, 0, 0x044a0000, 128, 2, 65000);
|
||||
|
||||
tt_str_op(p1,==, "abcd:2::44a:0");
|
||||
tt_str_op(p1,OP_EQ, "abcd:2::44a:0");
|
||||
/* Try some long addresses. */
|
||||
r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:1111]",
|
||||
0, &t1, NULL, NULL, NULL);
|
||||
tt_assert(r == AF_INET6);
|
||||
r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:11111]",
|
||||
0, &t1, NULL, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:1111:1]",
|
||||
0, &t1, NULL, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r=tor_addr_parse_mask_ports(
|
||||
"[ffff:1111:1111:1111:1111:1111:1111:ffff:"
|
||||
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:"
|
||||
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:"
|
||||
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]",
|
||||
0, &t1, NULL, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
/* Try some failing cases. */
|
||||
r=tor_addr_parse_mask_ports("[fefef::]/112", 0, &t1, NULL, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r=tor_addr_parse_mask_ports("[fefe::/112", 0, &t1, NULL, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r=tor_addr_parse_mask_ports("[fefe::", 0, &t1, NULL, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r=tor_addr_parse_mask_ports("[fefe::X]", 0, &t1, NULL, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r=tor_addr_parse_mask_ports("efef::/112", 0, &t1, NULL, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f::]",0,&t1, NULL, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r=tor_addr_parse_mask_ports("[::f:f:f:f:f:f:f:f]",0,&t1, NULL, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f:f]",0,&t1, NULL, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r=tor_addr_parse_mask_ports("[f:f:f:f:f::]/fred",0,&t1,&mask, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r=tor_addr_parse_mask_ports("[f:f:f:f:f::]/255.255.0.0",
|
||||
0,&t1, NULL, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
/* This one will get rejected because it isn't a pure prefix. */
|
||||
r=tor_addr_parse_mask_ports("1.1.2.3/255.255.64.0",0,&t1, &mask,NULL,NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
/* Test for V4-mapped address with mask < 96. (arguably not valid) */
|
||||
r=tor_addr_parse_mask_ports("[::ffff:1.1.2.2/33]",0,&t1, &mask, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r=tor_addr_parse_mask_ports("1.1.2.2/33",0,&t1, &mask, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
/* Try extended wildcard addresses with out TAPMP_EXTENDED_STAR*/
|
||||
r=tor_addr_parse_mask_ports("*4",0,&t1, &mask, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r=tor_addr_parse_mask_ports("*6",0,&t1, &mask, NULL, NULL);
|
||||
tt_int_op(r, ==, -1);
|
||||
#if 0
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
tt_assert(r == -1);
|
||||
/* Try a mask with a wildcard. */
|
||||
r=tor_addr_parse_mask_ports("*/16",0,&t1, &mask, NULL, NULL);
|
||||
tt_assert(r == -1);
|
||||
@@ -661,61 +664,60 @@ test_addr_ip6_helpers(void *arg)
|
||||
r=tor_addr_parse_mask_ports("*6/30",TAPMP_EXTENDED_STAR,
|
||||
&t1, &mask, NULL, NULL);
|
||||
tt_assert(r == -1);
|
||||
#endif
|
||||
/* Basic mask tests*/
|
||||
r=tor_addr_parse_mask_ports("1.1.2.2/31",0,&t1, &mask, NULL, NULL);
|
||||
tt_assert(r == AF_INET);
|
||||
tt_int_op(mask,==,31);
|
||||
tt_int_op(tor_addr_family(&t1),==,AF_INET);
|
||||
tt_int_op(tor_addr_to_ipv4h(&t1),==,0x01010202);
|
||||
tt_int_op(mask,OP_EQ,31);
|
||||
tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET);
|
||||
tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0x01010202);
|
||||
r=tor_addr_parse_mask_ports("3.4.16.032:1-2",0,&t1, &mask, &port1, &port2);
|
||||
tt_assert(r == AF_INET);
|
||||
tt_int_op(mask,==,32);
|
||||
tt_int_op(tor_addr_family(&t1),==,AF_INET);
|
||||
tt_int_op(tor_addr_to_ipv4h(&t1),==,0x03041020);
|
||||
tt_int_op(mask,OP_EQ,32);
|
||||
tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET);
|
||||
tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0x03041020);
|
||||
tt_assert(port1 == 1);
|
||||
tt_assert(port2 == 2);
|
||||
r=tor_addr_parse_mask_ports("1.1.2.3/255.255.128.0",0,&t1, &mask,NULL,NULL);
|
||||
tt_assert(r == AF_INET);
|
||||
tt_int_op(mask,==,17);
|
||||
tt_int_op(tor_addr_family(&t1),==,AF_INET);
|
||||
tt_int_op(tor_addr_to_ipv4h(&t1),==,0x01010203);
|
||||
tt_int_op(mask,OP_EQ,17);
|
||||
tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET);
|
||||
tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0x01010203);
|
||||
r=tor_addr_parse_mask_ports("[efef::]/112",0,&t1, &mask, &port1, &port2);
|
||||
tt_assert(r == AF_INET6);
|
||||
tt_assert(port1 == 1);
|
||||
tt_assert(port2 == 65535);
|
||||
/* Try regular wildcard behavior without TAPMP_EXTENDED_STAR */
|
||||
r=tor_addr_parse_mask_ports("*:80-443",0,&t1,&mask,&port1,&port2);
|
||||
tt_int_op(r,==,AF_INET); /* Old users of this always get inet */
|
||||
tt_int_op(tor_addr_family(&t1),==,AF_INET);
|
||||
tt_int_op(tor_addr_to_ipv4h(&t1),==,0);
|
||||
tt_int_op(mask,==,0);
|
||||
tt_int_op(port1,==,80);
|
||||
tt_int_op(port2,==,443);
|
||||
tt_int_op(r,OP_EQ,AF_INET); /* Old users of this always get inet */
|
||||
tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET);
|
||||
tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0);
|
||||
tt_int_op(mask,OP_EQ,0);
|
||||
tt_int_op(port1,OP_EQ,80);
|
||||
tt_int_op(port2,OP_EQ,443);
|
||||
/* Now try wildcards *with* TAPMP_EXTENDED_STAR */
|
||||
r=tor_addr_parse_mask_ports("*:8000-9000",TAPMP_EXTENDED_STAR,
|
||||
&t1,&mask,&port1,&port2);
|
||||
tt_int_op(r,==,AF_UNSPEC);
|
||||
tt_int_op(tor_addr_family(&t1),==,AF_UNSPEC);
|
||||
tt_int_op(mask,==,0);
|
||||
tt_int_op(port1,==,8000);
|
||||
tt_int_op(port2,==,9000);
|
||||
tt_int_op(r,OP_EQ,AF_UNSPEC);
|
||||
tt_int_op(tor_addr_family(&t1),OP_EQ,AF_UNSPEC);
|
||||
tt_int_op(mask,OP_EQ,0);
|
||||
tt_int_op(port1,OP_EQ,8000);
|
||||
tt_int_op(port2,OP_EQ,9000);
|
||||
r=tor_addr_parse_mask_ports("*4:6667",TAPMP_EXTENDED_STAR,
|
||||
&t1,&mask,&port1,&port2);
|
||||
tt_int_op(r,==,AF_INET);
|
||||
tt_int_op(tor_addr_family(&t1),==,AF_INET);
|
||||
tt_int_op(tor_addr_to_ipv4h(&t1),==,0);
|
||||
tt_int_op(mask,==,0);
|
||||
tt_int_op(port1,==,6667);
|
||||
tt_int_op(port2,==,6667);
|
||||
tt_int_op(r,OP_EQ,AF_INET);
|
||||
tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET);
|
||||
tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0);
|
||||
tt_int_op(mask,OP_EQ,0);
|
||||
tt_int_op(port1,OP_EQ,6667);
|
||||
tt_int_op(port2,OP_EQ,6667);
|
||||
r=tor_addr_parse_mask_ports("*6",TAPMP_EXTENDED_STAR,
|
||||
&t1,&mask,&port1,&port2);
|
||||
tt_int_op(r,==,AF_INET6);
|
||||
tt_int_op(tor_addr_family(&t1),==,AF_INET6);
|
||||
tt_int_op(r,OP_EQ,AF_INET6);
|
||||
tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET6);
|
||||
tt_assert(tor_mem_is_zero((const char*)tor_addr_to_in6_addr32(&t1), 16));
|
||||
tt_int_op(mask,==,0);
|
||||
tt_int_op(port1,==,1);
|
||||
tt_int_op(port2,==,65535);
|
||||
tt_int_op(mask,OP_EQ,0);
|
||||
tt_int_op(port1,OP_EQ,1);
|
||||
tt_int_op(port2,OP_EQ,65535);
|
||||
|
||||
/* make sure inet address lengths >= max */
|
||||
tt_assert(INET_NTOA_BUF_LEN >= sizeof("255.255.255.255"));
|
||||
@@ -751,87 +753,87 @@ test_addr_parse(void *arg)
|
||||
r= tor_addr_port_parse(LOG_DEBUG,
|
||||
"192.0.2.1:1234",
|
||||
&addr, &port, -1);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
tor_addr_to_str(buf, &addr, sizeof(buf), 0);
|
||||
tt_str_op(buf,==, "192.0.2.1");
|
||||
tt_int_op(port,==, 1234);
|
||||
tt_str_op(buf,OP_EQ, "192.0.2.1");
|
||||
tt_int_op(port,OP_EQ, 1234);
|
||||
|
||||
r= tor_addr_port_parse(LOG_DEBUG,
|
||||
"[::1]:1234",
|
||||
&addr, &port, -1);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
tor_addr_to_str(buf, &addr, sizeof(buf), 0);
|
||||
tt_str_op(buf,==, "::1");
|
||||
tt_int_op(port,==, 1234);
|
||||
tt_str_op(buf,OP_EQ, "::1");
|
||||
tt_int_op(port,OP_EQ, 1234);
|
||||
|
||||
/* Domain name. */
|
||||
r= tor_addr_port_parse(LOG_DEBUG,
|
||||
"torproject.org:1234",
|
||||
&addr, &port, -1);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
|
||||
/* Only IP. */
|
||||
r= tor_addr_port_parse(LOG_DEBUG,
|
||||
"192.0.2.2",
|
||||
&addr, &port, -1);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
|
||||
r= tor_addr_port_parse(LOG_DEBUG,
|
||||
"192.0.2.2",
|
||||
&addr, &port, 200);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(port,==,200);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
tt_int_op(port,OP_EQ,200);
|
||||
|
||||
r= tor_addr_port_parse(LOG_DEBUG,
|
||||
"[::1]",
|
||||
&addr, &port, -1);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
|
||||
r= tor_addr_port_parse(LOG_DEBUG,
|
||||
"[::1]",
|
||||
&addr, &port, 400);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(port,==,400);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
tt_int_op(port,OP_EQ,400);
|
||||
|
||||
/* Bad port. */
|
||||
r= tor_addr_port_parse(LOG_DEBUG,
|
||||
"192.0.2.2:66666",
|
||||
&addr, &port, -1);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r= tor_addr_port_parse(LOG_DEBUG,
|
||||
"192.0.2.2:66666",
|
||||
&addr, &port, 200);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
|
||||
/* Only domain name */
|
||||
r= tor_addr_port_parse(LOG_DEBUG,
|
||||
"torproject.org",
|
||||
&addr, &port, -1);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
r= tor_addr_port_parse(LOG_DEBUG,
|
||||
"torproject.org",
|
||||
&addr, &port, 200);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
|
||||
/* Bad IP address */
|
||||
r= tor_addr_port_parse(LOG_DEBUG,
|
||||
"192.0.2:1234",
|
||||
&addr, &port, -1);
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
|
||||
/* Make sure that the default port has lower priority than the real
|
||||
one */
|
||||
r= tor_addr_port_parse(LOG_DEBUG,
|
||||
"192.0.2.2:1337",
|
||||
&addr, &port, 200);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(port,==,1337);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
tt_int_op(port,OP_EQ,1337);
|
||||
|
||||
r= tor_addr_port_parse(LOG_DEBUG,
|
||||
"[::1]:1369",
|
||||
&addr, &port, 200);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(port,==,1369);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
tt_int_op(port,OP_EQ,1369);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -886,7 +888,7 @@ test_virtaddrmap(void *data)
|
||||
get_random_virtual_addr(&cfg[ipv6], &a);
|
||||
//printf("%s\n", fmt_addr(&a));
|
||||
/* Make sure that the first b bits match the configured network */
|
||||
tt_int_op(0, ==, tor_addr_compare_masked(&a, &cfg[ipv6].addr,
|
||||
tt_int_op(0, OP_EQ, tor_addr_compare_masked(&a, &cfg[ipv6].addr,
|
||||
bits, CMP_EXACT));
|
||||
|
||||
/* And track which bits have been different between pairs of
|
||||
@@ -930,7 +932,7 @@ test_addr_dup_ip(void *arg)
|
||||
(void)arg;
|
||||
#define CHECK(ip, s) do { \
|
||||
v = tor_dup_ip(ip); \
|
||||
tt_str_op(v,==,(s)); \
|
||||
tt_str_op(v,OP_EQ,(s)); \
|
||||
tor_free(v); \
|
||||
} while (0)
|
||||
|
||||
@@ -956,7 +958,7 @@ test_addr_sockaddr_to_str(void *arg)
|
||||
#endif
|
||||
#define CHECK(sa, s) do { \
|
||||
v = tor_sockaddr_to_str((const struct sockaddr*) &(sa)); \
|
||||
tt_str_op(v,==,(s)); \
|
||||
tt_str_op(v,OP_EQ,(s)); \
|
||||
tor_free(v); \
|
||||
} while (0)
|
||||
(void)arg;
|
||||
@@ -1013,12 +1015,13 @@ test_addr_is_loopback(void *data)
|
||||
(void)data;
|
||||
|
||||
for (i=0; loopback_items[i].name; ++i) {
|
||||
tt_int_op(tor_addr_parse(&addr, loopback_items[i].name), >=, 0);
|
||||
tt_int_op(tor_addr_is_loopback(&addr), ==, loopback_items[i].is_loopback);
|
||||
tt_int_op(tor_addr_parse(&addr, loopback_items[i].name), OP_GE, 0);
|
||||
tt_int_op(tor_addr_is_loopback(&addr), OP_EQ,
|
||||
loopback_items[i].is_loopback);
|
||||
}
|
||||
|
||||
tor_addr_make_unspec(&addr);
|
||||
tt_int_op(tor_addr_is_loopback(&addr), ==, 0);
|
||||
tt_int_op(tor_addr_is_loopback(&addr), OP_EQ, 0);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -1033,18 +1036,18 @@ test_addr_make_null(void *data)
|
||||
(void) data;
|
||||
/* Ensure that before tor_addr_make_null, addr != 0's */
|
||||
memset(addr, 1, sizeof(*addr));
|
||||
tt_int_op(memcmp(addr, zeros, sizeof(*addr)), !=, 0);
|
||||
tt_int_op(memcmp(addr, zeros, sizeof(*addr)), OP_NE, 0);
|
||||
/* Test with AF == AF_INET */
|
||||
zeros->family = AF_INET;
|
||||
tor_addr_make_null(addr, AF_INET);
|
||||
tt_int_op(memcmp(addr, zeros, sizeof(*addr)), ==, 0);
|
||||
tt_str_op(tor_addr_to_str(buf, addr, sizeof(buf), 0), ==, "0.0.0.0");
|
||||
tt_int_op(memcmp(addr, zeros, sizeof(*addr)), OP_EQ, 0);
|
||||
tt_str_op(tor_addr_to_str(buf, addr, sizeof(buf), 0), OP_EQ, "0.0.0.0");
|
||||
/* Test with AF == AF_INET6 */
|
||||
memset(addr, 1, sizeof(*addr));
|
||||
zeros->family = AF_INET6;
|
||||
tor_addr_make_null(addr, AF_INET6);
|
||||
tt_int_op(memcmp(addr, zeros, sizeof(*addr)), ==, 0);
|
||||
tt_str_op(tor_addr_to_str(buf, addr, sizeof(buf), 0), ==, "::");
|
||||
tt_int_op(memcmp(addr, zeros, sizeof(*addr)), OP_EQ, 0);
|
||||
tt_str_op(tor_addr_to_str(buf, addr, sizeof(buf), 0), OP_EQ, "::");
|
||||
done:
|
||||
tor_free(addr);
|
||||
tor_free(zeros);
|
||||
|
||||
+170
-168
@@ -30,7 +30,7 @@ test_buffers_basic(void *arg)
|
||||
TT_DIE(("Assertion failed."));
|
||||
|
||||
//test_eq(buf_capacity(buf), 4096);
|
||||
tt_int_op(buf_datalen(buf),==, 0);
|
||||
tt_int_op(buf_datalen(buf),OP_EQ, 0);
|
||||
|
||||
/****
|
||||
* General pointer frobbing
|
||||
@@ -40,16 +40,16 @@ test_buffers_basic(void *arg)
|
||||
}
|
||||
write_to_buf(str, 256, buf);
|
||||
write_to_buf(str, 256, buf);
|
||||
tt_int_op(buf_datalen(buf),==, 512);
|
||||
tt_int_op(buf_datalen(buf),OP_EQ, 512);
|
||||
fetch_from_buf(str2, 200, buf);
|
||||
tt_mem_op(str,==, str2, 200);
|
||||
tt_int_op(buf_datalen(buf),==, 312);
|
||||
tt_mem_op(str,OP_EQ, str2, 200);
|
||||
tt_int_op(buf_datalen(buf),OP_EQ, 312);
|
||||
memset(str2, 0, sizeof(str2));
|
||||
|
||||
fetch_from_buf(str2, 256, buf);
|
||||
tt_mem_op(str+200,==, str2, 56);
|
||||
tt_mem_op(str,==, str2+56, 200);
|
||||
tt_int_op(buf_datalen(buf),==, 56);
|
||||
tt_mem_op(str+200,OP_EQ, str2, 56);
|
||||
tt_mem_op(str,OP_EQ, str2+56, 200);
|
||||
tt_int_op(buf_datalen(buf),OP_EQ, 56);
|
||||
memset(str2, 0, sizeof(str2));
|
||||
/* Okay, now we should be 512 bytes into the 4096-byte buffer. If we add
|
||||
* another 3584 bytes, we hit the end. */
|
||||
@@ -57,16 +57,16 @@ test_buffers_basic(void *arg)
|
||||
write_to_buf(str, 256, buf);
|
||||
}
|
||||
assert_buf_ok(buf);
|
||||
tt_int_op(buf_datalen(buf),==, 3896);
|
||||
tt_int_op(buf_datalen(buf),OP_EQ, 3896);
|
||||
fetch_from_buf(str2, 56, buf);
|
||||
tt_int_op(buf_datalen(buf),==, 3840);
|
||||
tt_mem_op(str+200,==, str2, 56);
|
||||
tt_int_op(buf_datalen(buf),OP_EQ, 3840);
|
||||
tt_mem_op(str+200,OP_EQ, str2, 56);
|
||||
for (j=0;j<15;++j) {
|
||||
memset(str2, 0, sizeof(str2));
|
||||
fetch_from_buf(str2, 256, buf);
|
||||
tt_mem_op(str,==, str2, 256);
|
||||
tt_mem_op(str,OP_EQ, str2, 256);
|
||||
}
|
||||
tt_int_op(buf_datalen(buf),==, 0);
|
||||
tt_int_op(buf_datalen(buf),OP_EQ, 0);
|
||||
buf_free(buf);
|
||||
buf = NULL;
|
||||
|
||||
@@ -76,7 +76,7 @@ test_buffers_basic(void *arg)
|
||||
write_to_buf(str+1, 255, buf);
|
||||
//test_eq(buf_capacity(buf), 256);
|
||||
fetch_from_buf(str2, 254, buf);
|
||||
tt_mem_op(str+1,==, str2, 254);
|
||||
tt_mem_op(str+1,OP_EQ, str2, 254);
|
||||
//test_eq(buf_capacity(buf), 256);
|
||||
assert_buf_ok(buf);
|
||||
write_to_buf(str, 32, buf);
|
||||
@@ -85,15 +85,15 @@ test_buffers_basic(void *arg)
|
||||
write_to_buf(str, 256, buf);
|
||||
assert_buf_ok(buf);
|
||||
//test_eq(buf_capacity(buf), 512);
|
||||
tt_int_op(buf_datalen(buf),==, 33+256);
|
||||
tt_int_op(buf_datalen(buf),OP_EQ, 33+256);
|
||||
fetch_from_buf(str2, 33, buf);
|
||||
tt_int_op(*str2,==, str[255]);
|
||||
tt_int_op(*str2,OP_EQ, str[255]);
|
||||
|
||||
tt_mem_op(str2+1,==, str, 32);
|
||||
tt_mem_op(str2+1,OP_EQ, str, 32);
|
||||
//test_eq(buf_capacity(buf), 512);
|
||||
tt_int_op(buf_datalen(buf),==, 256);
|
||||
tt_int_op(buf_datalen(buf),OP_EQ, 256);
|
||||
fetch_from_buf(str2, 256, buf);
|
||||
tt_mem_op(str,==, str2, 256);
|
||||
tt_mem_op(str,OP_EQ, str2, 256);
|
||||
|
||||
/* now try shrinking: case 1. */
|
||||
buf_free(buf);
|
||||
@@ -102,10 +102,10 @@ test_buffers_basic(void *arg)
|
||||
write_to_buf(str,255, buf);
|
||||
}
|
||||
//test_eq(buf_capacity(buf), 33668);
|
||||
tt_int_op(buf_datalen(buf),==, 17085);
|
||||
tt_int_op(buf_datalen(buf),OP_EQ, 17085);
|
||||
for (j=0; j < 40; ++j) {
|
||||
fetch_from_buf(str2, 255,buf);
|
||||
tt_mem_op(str2,==, str, 255);
|
||||
tt_mem_op(str2,OP_EQ, str, 255);
|
||||
}
|
||||
|
||||
/* now try shrinking: case 2. */
|
||||
@@ -116,7 +116,7 @@ test_buffers_basic(void *arg)
|
||||
}
|
||||
for (j=0; j < 20; ++j) {
|
||||
fetch_from_buf(str2, 255,buf);
|
||||
tt_mem_op(str2,==, str, 255);
|
||||
tt_mem_op(str2,OP_EQ, str, 255);
|
||||
}
|
||||
for (j=0;j<80;++j) {
|
||||
write_to_buf(str,255, buf);
|
||||
@@ -124,7 +124,7 @@ test_buffers_basic(void *arg)
|
||||
//test_eq(buf_capacity(buf),33668);
|
||||
for (j=0; j < 120; ++j) {
|
||||
fetch_from_buf(str2, 255,buf);
|
||||
tt_mem_op(str2,==, str, 255);
|
||||
tt_mem_op(str2,OP_EQ, str, 255);
|
||||
}
|
||||
|
||||
/* Move from buf to buf. */
|
||||
@@ -133,27 +133,27 @@ test_buffers_basic(void *arg)
|
||||
buf2 = buf_new_with_capacity(4096);
|
||||
for (j=0;j<100;++j)
|
||||
write_to_buf(str, 255, buf);
|
||||
tt_int_op(buf_datalen(buf),==, 25500);
|
||||
tt_int_op(buf_datalen(buf),OP_EQ, 25500);
|
||||
for (j=0;j<100;++j) {
|
||||
r = 10;
|
||||
move_buf_to_buf(buf2, buf, &r);
|
||||
tt_int_op(r,==, 0);
|
||||
tt_int_op(r,OP_EQ, 0);
|
||||
}
|
||||
tt_int_op(buf_datalen(buf),==, 24500);
|
||||
tt_int_op(buf_datalen(buf2),==, 1000);
|
||||
tt_int_op(buf_datalen(buf),OP_EQ, 24500);
|
||||
tt_int_op(buf_datalen(buf2),OP_EQ, 1000);
|
||||
for (j=0;j<3;++j) {
|
||||
fetch_from_buf(str2, 255, buf2);
|
||||
tt_mem_op(str2,==, str, 255);
|
||||
tt_mem_op(str2,OP_EQ, str, 255);
|
||||
}
|
||||
r = 8192; /*big move*/
|
||||
move_buf_to_buf(buf2, buf, &r);
|
||||
tt_int_op(r,==, 0);
|
||||
tt_int_op(r,OP_EQ, 0);
|
||||
r = 30000; /* incomplete move */
|
||||
move_buf_to_buf(buf2, buf, &r);
|
||||
tt_int_op(r,==, 13692);
|
||||
tt_int_op(r,OP_EQ, 13692);
|
||||
for (j=0;j<97;++j) {
|
||||
fetch_from_buf(str2, 255, buf2);
|
||||
tt_mem_op(str2,==, str, 255);
|
||||
tt_mem_op(str2,OP_EQ, str, 255);
|
||||
}
|
||||
buf_free(buf);
|
||||
buf_free(buf2);
|
||||
@@ -163,16 +163,16 @@ test_buffers_basic(void *arg)
|
||||
cp = "Testing. This is a moderately long Testing string.";
|
||||
for (j = 0; cp[j]; j++)
|
||||
write_to_buf(cp+j, 1, buf);
|
||||
tt_int_op(0,==, buf_find_string_offset(buf, "Testing", 7));
|
||||
tt_int_op(1,==, buf_find_string_offset(buf, "esting", 6));
|
||||
tt_int_op(1,==, buf_find_string_offset(buf, "est", 3));
|
||||
tt_int_op(39,==, buf_find_string_offset(buf, "ing str", 7));
|
||||
tt_int_op(35,==, buf_find_string_offset(buf, "Testing str", 11));
|
||||
tt_int_op(32,==, buf_find_string_offset(buf, "ng ", 3));
|
||||
tt_int_op(43,==, buf_find_string_offset(buf, "string.", 7));
|
||||
tt_int_op(-1,==, buf_find_string_offset(buf, "shrdlu", 6));
|
||||
tt_int_op(-1,==, buf_find_string_offset(buf, "Testing thing", 13));
|
||||
tt_int_op(-1,==, buf_find_string_offset(buf, "ngx", 3));
|
||||
tt_int_op(0,OP_EQ, buf_find_string_offset(buf, "Testing", 7));
|
||||
tt_int_op(1,OP_EQ, buf_find_string_offset(buf, "esting", 6));
|
||||
tt_int_op(1,OP_EQ, buf_find_string_offset(buf, "est", 3));
|
||||
tt_int_op(39,OP_EQ, buf_find_string_offset(buf, "ing str", 7));
|
||||
tt_int_op(35,OP_EQ, buf_find_string_offset(buf, "Testing str", 11));
|
||||
tt_int_op(32,OP_EQ, buf_find_string_offset(buf, "ng ", 3));
|
||||
tt_int_op(43,OP_EQ, buf_find_string_offset(buf, "string.", 7));
|
||||
tt_int_op(-1,OP_EQ, buf_find_string_offset(buf, "shrdlu", 6));
|
||||
tt_int_op(-1,OP_EQ, buf_find_string_offset(buf, "Testing thing", 13));
|
||||
tt_int_op(-1,OP_EQ, buf_find_string_offset(buf, "ngx", 3));
|
||||
buf_free(buf);
|
||||
buf = NULL;
|
||||
|
||||
@@ -183,7 +183,7 @@ test_buffers_basic(void *arg)
|
||||
write_to_buf(cp, 65536, buf);
|
||||
tor_free(cp);
|
||||
|
||||
tt_int_op(buf_datalen(buf), ==, 65536);
|
||||
tt_int_op(buf_datalen(buf), OP_EQ, 65536);
|
||||
buf_free(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
@@ -213,19 +213,19 @@ test_buffer_pullup(void *arg)
|
||||
buf = buf_new_with_capacity(3000); /* rounds up to next power of 2. */
|
||||
|
||||
tt_assert(buf);
|
||||
tt_int_op(buf_get_default_chunk_size(buf), ==, 4096);
|
||||
tt_int_op(buf_get_default_chunk_size(buf), OP_EQ, 4096);
|
||||
|
||||
tt_int_op(buf_get_total_allocation(), ==, 0);
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
|
||||
|
||||
/* There are a bunch of cases for pullup. One is the trivial case. Let's
|
||||
mess around with an empty buffer. */
|
||||
buf_pullup(buf, 16, 1);
|
||||
buf_get_first_chunk_data(buf, &cp, &sz);
|
||||
tt_ptr_op(cp, ==, NULL);
|
||||
tt_uint_op(sz, ==, 0);
|
||||
tt_ptr_op(cp, OP_EQ, NULL);
|
||||
tt_uint_op(sz, OP_EQ, 0);
|
||||
|
||||
/* Let's make sure nothing got allocated */
|
||||
tt_int_op(buf_get_total_allocation(), ==, 0);
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
|
||||
|
||||
/* Case 1: everything puts into the first chunk with some moving. */
|
||||
|
||||
@@ -234,22 +234,22 @@ test_buffer_pullup(void *arg)
|
||||
write_to_buf(stuff, 3000, buf);
|
||||
write_to_buf(stuff+3000, 3000, buf);
|
||||
buf_get_first_chunk_data(buf, &cp, &sz);
|
||||
tt_ptr_op(cp, !=, NULL);
|
||||
tt_int_op(sz, <=, 4096);
|
||||
tt_ptr_op(cp, OP_NE, NULL);
|
||||
tt_int_op(sz, OP_LE, 4096);
|
||||
|
||||
/* Make room for 3000 bytes in the first chunk, so that the pullup-move code
|
||||
* can get tested. */
|
||||
tt_int_op(fetch_from_buf(tmp, 3000, buf), ==, 3000);
|
||||
tt_mem_op(tmp,==, stuff, 3000);
|
||||
tt_int_op(fetch_from_buf(tmp, 3000, buf), OP_EQ, 3000);
|
||||
tt_mem_op(tmp,OP_EQ, stuff, 3000);
|
||||
buf_pullup(buf, 2048, 0);
|
||||
assert_buf_ok(buf);
|
||||
buf_get_first_chunk_data(buf, &cp, &sz);
|
||||
tt_ptr_op(cp, !=, NULL);
|
||||
tt_int_op(sz, >=, 2048);
|
||||
tt_mem_op(cp,==, stuff+3000, 2048);
|
||||
tt_int_op(3000, ==, buf_datalen(buf));
|
||||
tt_int_op(fetch_from_buf(tmp, 3000, buf), ==, 0);
|
||||
tt_mem_op(tmp,==, stuff+3000, 2048);
|
||||
tt_ptr_op(cp, OP_NE, NULL);
|
||||
tt_int_op(sz, OP_GE, 2048);
|
||||
tt_mem_op(cp,OP_EQ, stuff+3000, 2048);
|
||||
tt_int_op(3000, OP_EQ, buf_datalen(buf));
|
||||
tt_int_op(fetch_from_buf(tmp, 3000, buf), OP_EQ, 0);
|
||||
tt_mem_op(tmp,OP_EQ, stuff+3000, 2048);
|
||||
|
||||
buf_free(buf);
|
||||
|
||||
@@ -259,26 +259,26 @@ test_buffer_pullup(void *arg)
|
||||
write_to_buf(stuff+4000, 4000, buf);
|
||||
write_to_buf(stuff+8000, 4000, buf);
|
||||
write_to_buf(stuff+12000, 4000, buf);
|
||||
tt_int_op(buf_datalen(buf), ==, 16000);
|
||||
tt_int_op(buf_datalen(buf), OP_EQ, 16000);
|
||||
buf_get_first_chunk_data(buf, &cp, &sz);
|
||||
tt_ptr_op(cp, !=, NULL);
|
||||
tt_int_op(sz, <=, 4096);
|
||||
tt_ptr_op(cp, OP_NE, NULL);
|
||||
tt_int_op(sz, OP_LE, 4096);
|
||||
|
||||
buf_pullup(buf, 12500, 0);
|
||||
assert_buf_ok(buf);
|
||||
buf_get_first_chunk_data(buf, &cp, &sz);
|
||||
tt_ptr_op(cp, !=, NULL);
|
||||
tt_int_op(sz, >=, 12500);
|
||||
tt_mem_op(cp,==, stuff, 12500);
|
||||
tt_int_op(buf_datalen(buf), ==, 16000);
|
||||
tt_ptr_op(cp, OP_NE, NULL);
|
||||
tt_int_op(sz, OP_GE, 12500);
|
||||
tt_mem_op(cp,OP_EQ, stuff, 12500);
|
||||
tt_int_op(buf_datalen(buf), OP_EQ, 16000);
|
||||
|
||||
fetch_from_buf(tmp, 12400, buf);
|
||||
tt_mem_op(tmp,==, stuff, 12400);
|
||||
tt_int_op(buf_datalen(buf), ==, 3600);
|
||||
tt_mem_op(tmp,OP_EQ, stuff, 12400);
|
||||
tt_int_op(buf_datalen(buf), OP_EQ, 3600);
|
||||
fetch_from_buf(tmp, 3500, buf);
|
||||
tt_mem_op(tmp,==, stuff+12400, 3500);
|
||||
tt_mem_op(tmp,OP_EQ, stuff+12400, 3500);
|
||||
fetch_from_buf(tmp, 100, buf);
|
||||
tt_mem_op(tmp,==, stuff+15900, 10);
|
||||
tt_mem_op(tmp,OP_EQ, stuff+15900, 10);
|
||||
|
||||
buf_free(buf);
|
||||
|
||||
@@ -290,16 +290,16 @@ test_buffer_pullup(void *arg)
|
||||
buf_pullup(buf, 16000, 0); /* Way too much. */
|
||||
assert_buf_ok(buf);
|
||||
buf_get_first_chunk_data(buf, &cp, &sz);
|
||||
tt_ptr_op(cp, !=, NULL);
|
||||
tt_int_op(sz, ==, 7900);
|
||||
tt_mem_op(cp,==, stuff+100, 7900);
|
||||
tt_ptr_op(cp, OP_NE, NULL);
|
||||
tt_int_op(sz, OP_EQ, 7900);
|
||||
tt_mem_op(cp,OP_EQ, stuff+100, 7900);
|
||||
|
||||
buf_free(buf);
|
||||
buf = NULL;
|
||||
|
||||
buf_shrink_freelists(1);
|
||||
|
||||
tt_int_op(buf_get_total_allocation(), ==, 0);
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
|
||||
done:
|
||||
buf_free(buf);
|
||||
buf_shrink_freelists(1);
|
||||
@@ -321,31 +321,31 @@ test_buffer_copy(void *arg)
|
||||
tt_assert(buf);
|
||||
|
||||
/* Copy an empty buffer. */
|
||||
tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf));
|
||||
tt_int_op(0, OP_EQ, generic_buffer_set_to_copy(&buf2, buf));
|
||||
tt_assert(buf2);
|
||||
tt_int_op(0, ==, generic_buffer_len(buf2));
|
||||
tt_int_op(0, OP_EQ, generic_buffer_len(buf2));
|
||||
|
||||
/* Now try with a short buffer. */
|
||||
s = "And now comes an act of enormous enormance!";
|
||||
len = strlen(s);
|
||||
generic_buffer_add(buf, s, len);
|
||||
tt_int_op(len, ==, generic_buffer_len(buf));
|
||||
tt_int_op(len, OP_EQ, generic_buffer_len(buf));
|
||||
/* Add junk to buf2 so we can test replacing.*/
|
||||
generic_buffer_add(buf2, "BLARG", 5);
|
||||
tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf));
|
||||
tt_int_op(len, ==, generic_buffer_len(buf2));
|
||||
tt_int_op(0, OP_EQ, generic_buffer_set_to_copy(&buf2, buf));
|
||||
tt_int_op(len, OP_EQ, generic_buffer_len(buf2));
|
||||
generic_buffer_get(buf2, b, len);
|
||||
tt_mem_op(b, ==, s, len);
|
||||
tt_mem_op(b, OP_EQ, s, len);
|
||||
/* Now free buf2 and retry so we can test allocating */
|
||||
generic_buffer_free(buf2);
|
||||
buf2 = NULL;
|
||||
tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf));
|
||||
tt_int_op(len, ==, generic_buffer_len(buf2));
|
||||
tt_int_op(0, OP_EQ, generic_buffer_set_to_copy(&buf2, buf));
|
||||
tt_int_op(len, OP_EQ, generic_buffer_len(buf2));
|
||||
generic_buffer_get(buf2, b, len);
|
||||
tt_mem_op(b, ==, s, len);
|
||||
tt_mem_op(b, OP_EQ, s, len);
|
||||
/* Clear buf for next test */
|
||||
generic_buffer_get(buf, b, len);
|
||||
tt_int_op(generic_buffer_len(buf),==,0);
|
||||
tt_int_op(generic_buffer_len(buf),OP_EQ,0);
|
||||
|
||||
/* Okay, now let's try a bigger buffer. */
|
||||
s = "Quis autem vel eum iure reprehenderit qui in ea voluptate velit "
|
||||
@@ -357,12 +357,12 @@ test_buffer_copy(void *arg)
|
||||
generic_buffer_add(buf, b, 1);
|
||||
generic_buffer_add(buf, s, len);
|
||||
}
|
||||
tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf));
|
||||
tt_int_op(generic_buffer_len(buf2), ==, generic_buffer_len(buf));
|
||||
tt_int_op(0, OP_EQ, generic_buffer_set_to_copy(&buf2, buf));
|
||||
tt_int_op(generic_buffer_len(buf2), OP_EQ, generic_buffer_len(buf));
|
||||
for (i = 0; i < 256; ++i) {
|
||||
generic_buffer_get(buf2, b, len+1);
|
||||
tt_int_op((unsigned char)b[0],==,i);
|
||||
tt_mem_op(b+1, ==, s, len);
|
||||
tt_int_op((unsigned char)b[0],OP_EQ,i);
|
||||
tt_mem_op(b+1, OP_EQ, s, len);
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -382,62 +382,62 @@ test_buffer_ext_or_cmd(void *arg)
|
||||
(void) arg;
|
||||
|
||||
/* Empty -- should give "not there. */
|
||||
tt_int_op(0, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_ptr_op(NULL, ==, cmd);
|
||||
tt_int_op(0, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_ptr_op(NULL, OP_EQ, cmd);
|
||||
|
||||
/* Three bytes: shouldn't work. */
|
||||
generic_buffer_add(buf, "\x00\x20\x00", 3);
|
||||
tt_int_op(0, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_ptr_op(NULL, ==, cmd);
|
||||
tt_int_op(3, ==, generic_buffer_len(buf));
|
||||
tt_int_op(0, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_ptr_op(NULL, OP_EQ, cmd);
|
||||
tt_int_op(3, OP_EQ, generic_buffer_len(buf));
|
||||
|
||||
/* 0020 0000: That's a nil command. It should work. */
|
||||
generic_buffer_add(buf, "\x00", 1);
|
||||
tt_int_op(1, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_ptr_op(NULL, !=, cmd);
|
||||
tt_int_op(0x20, ==, cmd->cmd);
|
||||
tt_int_op(0, ==, cmd->len);
|
||||
tt_int_op(0, ==, generic_buffer_len(buf));
|
||||
tt_int_op(1, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_ptr_op(NULL, OP_NE, cmd);
|
||||
tt_int_op(0x20, OP_EQ, cmd->cmd);
|
||||
tt_int_op(0, OP_EQ, cmd->len);
|
||||
tt_int_op(0, OP_EQ, generic_buffer_len(buf));
|
||||
ext_or_cmd_free(cmd);
|
||||
cmd = NULL;
|
||||
|
||||
/* Now try a length-6 command with one byte missing. */
|
||||
generic_buffer_add(buf, "\x10\x21\x00\x06""abcde", 9);
|
||||
tt_int_op(0, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_ptr_op(NULL, ==, cmd);
|
||||
tt_int_op(0, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_ptr_op(NULL, OP_EQ, cmd);
|
||||
generic_buffer_add(buf, "f", 1);
|
||||
tt_int_op(1, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_ptr_op(NULL, !=, cmd);
|
||||
tt_int_op(0x1021, ==, cmd->cmd);
|
||||
tt_int_op(6, ==, cmd->len);
|
||||
tt_mem_op("abcdef", ==, cmd->body, 6);
|
||||
tt_int_op(0, ==, generic_buffer_len(buf));
|
||||
tt_int_op(1, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_ptr_op(NULL, OP_NE, cmd);
|
||||
tt_int_op(0x1021, OP_EQ, cmd->cmd);
|
||||
tt_int_op(6, OP_EQ, cmd->len);
|
||||
tt_mem_op("abcdef", OP_EQ, cmd->body, 6);
|
||||
tt_int_op(0, OP_EQ, generic_buffer_len(buf));
|
||||
ext_or_cmd_free(cmd);
|
||||
cmd = NULL;
|
||||
|
||||
/* Now try a length-10 command with 4 extra bytes. */
|
||||
generic_buffer_add(buf, "\xff\xff\x00\x0a"
|
||||
"loremipsum\x10\x00\xff\xff", 18);
|
||||
tt_int_op(1, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_ptr_op(NULL, !=, cmd);
|
||||
tt_int_op(0xffff, ==, cmd->cmd);
|
||||
tt_int_op(10, ==, cmd->len);
|
||||
tt_mem_op("loremipsum", ==, cmd->body, 10);
|
||||
tt_int_op(4, ==, generic_buffer_len(buf));
|
||||
tt_int_op(1, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_ptr_op(NULL, OP_NE, cmd);
|
||||
tt_int_op(0xffff, OP_EQ, cmd->cmd);
|
||||
tt_int_op(10, OP_EQ, cmd->len);
|
||||
tt_mem_op("loremipsum", OP_EQ, cmd->body, 10);
|
||||
tt_int_op(4, OP_EQ, generic_buffer_len(buf));
|
||||
ext_or_cmd_free(cmd);
|
||||
cmd = NULL;
|
||||
|
||||
/* Finally, let's try a maximum-length command. We already have the header
|
||||
* waiting. */
|
||||
tt_int_op(0, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_int_op(0, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tmp = tor_malloc_zero(65535);
|
||||
generic_buffer_add(buf, tmp, 65535);
|
||||
tt_int_op(1, ==, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_ptr_op(NULL, !=, cmd);
|
||||
tt_int_op(0x1000, ==, cmd->cmd);
|
||||
tt_int_op(0xffff, ==, cmd->len);
|
||||
tt_mem_op(tmp, ==, cmd->body, 65535);
|
||||
tt_int_op(0, ==, generic_buffer_len(buf));
|
||||
tt_int_op(1, OP_EQ, generic_buffer_fetch_ext_or_cmd(buf, &cmd));
|
||||
tt_ptr_op(NULL, OP_NE, cmd);
|
||||
tt_int_op(0x1000, OP_EQ, cmd->cmd);
|
||||
tt_int_op(0xffff, OP_EQ, cmd->len);
|
||||
tt_mem_op(tmp, OP_EQ, cmd->body, 65535);
|
||||
tt_int_op(0, OP_EQ, generic_buffer_len(buf));
|
||||
ext_or_cmd_free(cmd);
|
||||
cmd = NULL;
|
||||
|
||||
@@ -458,65 +458,66 @@ test_buffer_allocation_tracking(void *arg)
|
||||
(void)arg;
|
||||
|
||||
crypto_rand(junk, 16384);
|
||||
tt_int_op(buf_get_total_allocation(), ==, 0);
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
|
||||
|
||||
buf1 = buf_new();
|
||||
tt_assert(buf1);
|
||||
buf2 = buf_new();
|
||||
tt_assert(buf2);
|
||||
|
||||
tt_int_op(buf_allocation(buf1), ==, 0);
|
||||
tt_int_op(buf_get_total_allocation(), ==, 0);
|
||||
tt_int_op(buf_allocation(buf1), OP_EQ, 0);
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
|
||||
|
||||
write_to_buf(junk, 4000, buf1);
|
||||
write_to_buf(junk, 4000, buf1);
|
||||
write_to_buf(junk, 4000, buf1);
|
||||
write_to_buf(junk, 4000, buf1);
|
||||
tt_int_op(buf_allocation(buf1), ==, 16384);
|
||||
tt_int_op(buf_allocation(buf1), OP_EQ, 16384);
|
||||
fetch_from_buf(junk, 100, buf1);
|
||||
tt_int_op(buf_allocation(buf1), ==, 16384); /* still 4 4k chunks */
|
||||
tt_int_op(buf_allocation(buf1), OP_EQ, 16384); /* still 4 4k chunks */
|
||||
|
||||
tt_int_op(buf_get_total_allocation(), ==, 16384);
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 16384);
|
||||
|
||||
fetch_from_buf(junk, 4096, buf1); /* drop a 1k chunk... */
|
||||
tt_int_op(buf_allocation(buf1), ==, 3*4096); /* now 3 4k chunks */
|
||||
tt_int_op(buf_allocation(buf1), OP_EQ, 3*4096); /* now 3 4k chunks */
|
||||
|
||||
#ifdef ENABLE_BUF_FREELISTS
|
||||
tt_int_op(buf_get_total_allocation(), ==, 16384); /* that chunk went onto
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 16384); /* that chunk went onto
|
||||
the freelist. */
|
||||
#else
|
||||
tt_int_op(buf_get_total_allocation(), ==, 12288); /* that chunk was really
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 12288); /* that chunk was really
|
||||
freed. */
|
||||
#endif
|
||||
|
||||
write_to_buf(junk, 4000, buf2);
|
||||
tt_int_op(buf_allocation(buf2), ==, 4096); /* another 4k chunk. */
|
||||
tt_int_op(buf_allocation(buf2), OP_EQ, 4096); /* another 4k chunk. */
|
||||
/*
|
||||
* If we're using freelists, size stays at 16384 because we just pulled a
|
||||
* chunk from the freelist. If we aren't, we bounce back up to 16384 by
|
||||
* allocating a new chunk.
|
||||
*/
|
||||
tt_int_op(buf_get_total_allocation(), ==, 16384);
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 16384);
|
||||
write_to_buf(junk, 4000, buf2);
|
||||
tt_int_op(buf_allocation(buf2), ==, 8192); /* another 4k chunk. */
|
||||
tt_int_op(buf_get_total_allocation(), ==, 5*4096); /* that chunk was new. */
|
||||
tt_int_op(buf_allocation(buf2), OP_EQ, 8192); /* another 4k chunk. */
|
||||
tt_int_op(buf_get_total_allocation(),
|
||||
OP_EQ, 5*4096); /* that chunk was new. */
|
||||
|
||||
/* Make a really huge buffer */
|
||||
for (i = 0; i < 1000; ++i) {
|
||||
write_to_buf(junk, 4000, buf2);
|
||||
}
|
||||
tt_int_op(buf_allocation(buf2), >=, 4008000);
|
||||
tt_int_op(buf_get_total_allocation(), >=, 4008000);
|
||||
tt_int_op(buf_allocation(buf2), OP_GE, 4008000);
|
||||
tt_int_op(buf_get_total_allocation(), OP_GE, 4008000);
|
||||
buf_free(buf2);
|
||||
buf2 = NULL;
|
||||
|
||||
tt_int_op(buf_get_total_allocation(), <, 4008000);
|
||||
tt_int_op(buf_get_total_allocation(), OP_LT, 4008000);
|
||||
buf_shrink_freelists(1);
|
||||
tt_int_op(buf_get_total_allocation(), ==, buf_allocation(buf1));
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, buf_allocation(buf1));
|
||||
buf_free(buf1);
|
||||
buf1 = NULL;
|
||||
buf_shrink_freelists(1);
|
||||
tt_int_op(buf_get_total_allocation(), ==, 0);
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
|
||||
|
||||
done:
|
||||
buf_free(buf1);
|
||||
@@ -545,37 +546,38 @@ test_buffer_time_tracking(void *arg)
|
||||
tt_assert(buf);
|
||||
|
||||
/* Empty buffer means the timestamp is 0. */
|
||||
tt_int_op(0, ==, buf_get_oldest_chunk_timestamp(buf, START_MSEC));
|
||||
tt_int_op(0, ==, buf_get_oldest_chunk_timestamp(buf, START_MSEC+1000));
|
||||
tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC));
|
||||
tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+1000));
|
||||
|
||||
tor_gettimeofday_cache_set(&tv0);
|
||||
write_to_buf("ABCDEFG", 7, buf);
|
||||
tt_int_op(1000, ==, buf_get_oldest_chunk_timestamp(buf, START_MSEC+1000));
|
||||
tt_int_op(1000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+1000));
|
||||
|
||||
buf2 = buf_copy(buf);
|
||||
tt_assert(buf2);
|
||||
tt_int_op(1234, ==, buf_get_oldest_chunk_timestamp(buf2, START_MSEC+1234));
|
||||
tt_int_op(1234, OP_EQ,
|
||||
buf_get_oldest_chunk_timestamp(buf2, START_MSEC+1234));
|
||||
|
||||
/* Now add more bytes; enough to overflow the first chunk. */
|
||||
tv0.tv_usec += 123 * 1000;
|
||||
tor_gettimeofday_cache_set(&tv0);
|
||||
for (i = 0; i < 600; ++i)
|
||||
write_to_buf("ABCDEFG", 7, buf);
|
||||
tt_int_op(4207, ==, buf_datalen(buf));
|
||||
tt_int_op(4207, OP_EQ, buf_datalen(buf));
|
||||
|
||||
/* The oldest bytes are still in the front. */
|
||||
tt_int_op(2000, ==, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2000));
|
||||
tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2000));
|
||||
|
||||
/* Once those bytes are dropped, the chunk is still on the first
|
||||
* timestamp. */
|
||||
fetch_from_buf(tmp, 100, buf);
|
||||
tt_int_op(2000, ==, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2000));
|
||||
tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2000));
|
||||
|
||||
/* But once we discard the whole first chunk, we get the data in the second
|
||||
* chunk. */
|
||||
fetch_from_buf(tmp, 4000, buf);
|
||||
tt_int_op(107, ==, buf_datalen(buf));
|
||||
tt_int_op(2000, ==, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2123));
|
||||
tt_int_op(107, OP_EQ, buf_datalen(buf));
|
||||
tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2123));
|
||||
|
||||
/* This time we'll be grabbing a chunk from the freelist, and making sure
|
||||
its time gets updated */
|
||||
@@ -584,13 +586,13 @@ test_buffer_time_tracking(void *arg)
|
||||
tor_gettimeofday_cache_set(&tv0);
|
||||
for (i = 0; i < 600; ++i)
|
||||
write_to_buf("ABCDEFG", 7, buf);
|
||||
tt_int_op(4307, ==, buf_datalen(buf));
|
||||
tt_int_op(4307, OP_EQ, buf_datalen(buf));
|
||||
|
||||
tt_int_op(2000, ==, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2123));
|
||||
tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2123));
|
||||
fetch_from_buf(tmp, 4000, buf);
|
||||
fetch_from_buf(tmp, 306, buf);
|
||||
tt_int_op(0, ==, buf_get_oldest_chunk_timestamp(buf, START_MSEC+5617));
|
||||
tt_int_op(383, ==, buf_get_oldest_chunk_timestamp(buf, START_MSEC+6000));
|
||||
tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+5617));
|
||||
tt_int_op(383, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+6000));
|
||||
|
||||
done:
|
||||
buf_free(buf);
|
||||
@@ -613,31 +615,31 @@ test_buffers_zlib_impl(int finalize_with_nil)
|
||||
|
||||
msg = tor_malloc(512);
|
||||
crypto_rand(msg, 512);
|
||||
tt_int_op(write_to_buf_zlib(buf, zlib_state, msg, 128, 0), ==, 0);
|
||||
tt_int_op(write_to_buf_zlib(buf, zlib_state, msg+128, 128, 0), ==, 0);
|
||||
tt_int_op(write_to_buf_zlib(buf, zlib_state, msg+256, 256, 0), ==, 0);
|
||||
tt_int_op(write_to_buf_zlib(buf, zlib_state, msg, 128, 0), OP_EQ, 0);
|
||||
tt_int_op(write_to_buf_zlib(buf, zlib_state, msg+128, 128, 0), OP_EQ, 0);
|
||||
tt_int_op(write_to_buf_zlib(buf, zlib_state, msg+256, 256, 0), OP_EQ, 0);
|
||||
done = !finalize_with_nil;
|
||||
tt_int_op(write_to_buf_zlib(buf, zlib_state, "all done", 9, done), ==, 0);
|
||||
tt_int_op(write_to_buf_zlib(buf, zlib_state, "all done", 9, done), OP_EQ, 0);
|
||||
if (finalize_with_nil) {
|
||||
tt_int_op(write_to_buf_zlib(buf, zlib_state, "", 0, 1), ==, 0);
|
||||
tt_int_op(write_to_buf_zlib(buf, zlib_state, "", 0, 1), OP_EQ, 0);
|
||||
}
|
||||
|
||||
in_len = buf_datalen(buf);
|
||||
contents = tor_malloc(in_len);
|
||||
|
||||
tt_int_op(fetch_from_buf(contents, in_len, buf), ==, 0);
|
||||
tt_int_op(fetch_from_buf(contents, in_len, buf), OP_EQ, 0);
|
||||
|
||||
tt_int_op(0, ==, tor_gzip_uncompress(&expanded, &out_len,
|
||||
tt_int_op(0, OP_EQ, tor_gzip_uncompress(&expanded, &out_len,
|
||||
contents, in_len,
|
||||
ZLIB_METHOD, 1,
|
||||
LOG_WARN));
|
||||
|
||||
tt_int_op(out_len, >=, 128);
|
||||
tt_mem_op(msg, ==, expanded, 128);
|
||||
tt_int_op(out_len, >=, 512);
|
||||
tt_mem_op(msg, ==, expanded, 512);
|
||||
tt_int_op(out_len, ==, 512+9);
|
||||
tt_mem_op("all done", ==, expanded+512, 9);
|
||||
tt_int_op(out_len, OP_GE, 128);
|
||||
tt_mem_op(msg, OP_EQ, expanded, 128);
|
||||
tt_int_op(out_len, OP_GE, 512);
|
||||
tt_mem_op(msg, OP_EQ, expanded, 512);
|
||||
tt_int_op(out_len, OP_EQ, 512+9);
|
||||
tt_mem_op("all done", OP_EQ, expanded+512, 9);
|
||||
|
||||
done:
|
||||
buf_free(buf);
|
||||
@@ -680,28 +682,28 @@ test_buffers_zlib_fin_at_chunk_end(void *arg)
|
||||
tt_assert(buf->head);
|
||||
|
||||
/* Fill up the chunk so the zlib stuff won't fit in one chunk. */
|
||||
tt_uint_op(buf->head->memlen, <, sz);
|
||||
tt_uint_op(buf->head->memlen, OP_LT, sz);
|
||||
headerjunk = buf->head->memlen - 7;
|
||||
write_to_buf(msg, headerjunk-1, buf);
|
||||
tt_uint_op(buf->head->datalen, ==, headerjunk);
|
||||
tt_uint_op(buf_datalen(buf), ==, headerjunk);
|
||||
tt_uint_op(buf->head->datalen, OP_EQ, headerjunk);
|
||||
tt_uint_op(buf_datalen(buf), OP_EQ, headerjunk);
|
||||
/* Write an empty string, with finalization on. */
|
||||
zlib_state = tor_zlib_new(1, ZLIB_METHOD);
|
||||
tt_int_op(write_to_buf_zlib(buf, zlib_state, "", 0, 1), ==, 0);
|
||||
tt_int_op(write_to_buf_zlib(buf, zlib_state, "", 0, 1), OP_EQ, 0);
|
||||
|
||||
in_len = buf_datalen(buf);
|
||||
contents = tor_malloc(in_len);
|
||||
|
||||
tt_int_op(fetch_from_buf(contents, in_len, buf), ==, 0);
|
||||
tt_int_op(fetch_from_buf(contents, in_len, buf), OP_EQ, 0);
|
||||
|
||||
tt_uint_op(in_len, >, headerjunk);
|
||||
tt_uint_op(in_len, OP_GT, headerjunk);
|
||||
|
||||
tt_int_op(0, ==, tor_gzip_uncompress(&expanded, &out_len,
|
||||
tt_int_op(0, OP_EQ, tor_gzip_uncompress(&expanded, &out_len,
|
||||
contents + headerjunk, in_len - headerjunk,
|
||||
ZLIB_METHOD, 1,
|
||||
LOG_WARN));
|
||||
|
||||
tt_int_op(out_len, ==, 0);
|
||||
tt_int_op(out_len, OP_EQ, 0);
|
||||
tt_assert(expanded);
|
||||
|
||||
done:
|
||||
|
||||
+388
-387
File diff suppressed because it is too large
Load Diff
+29
-29
@@ -21,7 +21,7 @@ test_cq_manip(void *arg)
|
||||
#endif /* ENABLE_MEMPOOLS */
|
||||
|
||||
cell_queue_init(&cq);
|
||||
tt_int_op(cq.n, ==, 0);
|
||||
tt_int_op(cq.n, OP_EQ, 0);
|
||||
|
||||
pc1 = packed_cell_new();
|
||||
pc2 = packed_cell_new();
|
||||
@@ -29,26 +29,26 @@ test_cq_manip(void *arg)
|
||||
pc4 = packed_cell_new();
|
||||
tt_assert(pc1 && pc2 && pc3 && pc4);
|
||||
|
||||
tt_ptr_op(NULL, ==, cell_queue_pop(&cq));
|
||||
tt_ptr_op(NULL, OP_EQ, cell_queue_pop(&cq));
|
||||
|
||||
/* Add and remove a singleton. */
|
||||
cell_queue_append(&cq, pc1);
|
||||
tt_int_op(cq.n, ==, 1);
|
||||
tt_ptr_op(pc1, ==, cell_queue_pop(&cq));
|
||||
tt_int_op(cq.n, ==, 0);
|
||||
tt_int_op(cq.n, OP_EQ, 1);
|
||||
tt_ptr_op(pc1, OP_EQ, cell_queue_pop(&cq));
|
||||
tt_int_op(cq.n, OP_EQ, 0);
|
||||
|
||||
/* Add and remove four items */
|
||||
cell_queue_append(&cq, pc4);
|
||||
cell_queue_append(&cq, pc3);
|
||||
cell_queue_append(&cq, pc2);
|
||||
cell_queue_append(&cq, pc1);
|
||||
tt_int_op(cq.n, ==, 4);
|
||||
tt_ptr_op(pc4, ==, cell_queue_pop(&cq));
|
||||
tt_ptr_op(pc3, ==, cell_queue_pop(&cq));
|
||||
tt_ptr_op(pc2, ==, cell_queue_pop(&cq));
|
||||
tt_ptr_op(pc1, ==, cell_queue_pop(&cq));
|
||||
tt_int_op(cq.n, ==, 0);
|
||||
tt_ptr_op(NULL, ==, cell_queue_pop(&cq));
|
||||
tt_int_op(cq.n, OP_EQ, 4);
|
||||
tt_ptr_op(pc4, OP_EQ, cell_queue_pop(&cq));
|
||||
tt_ptr_op(pc3, OP_EQ, cell_queue_pop(&cq));
|
||||
tt_ptr_op(pc2, OP_EQ, cell_queue_pop(&cq));
|
||||
tt_ptr_op(pc1, OP_EQ, cell_queue_pop(&cq));
|
||||
tt_int_op(cq.n, OP_EQ, 0);
|
||||
tt_ptr_op(NULL, OP_EQ, cell_queue_pop(&cq));
|
||||
|
||||
/* Try a packed copy (wide, then narrow, which is a bit of a cheat, since a
|
||||
* real cell queue has only one type.) */
|
||||
@@ -64,32 +64,32 @@ test_cq_manip(void *arg)
|
||||
cell.circ_id = 0x2013;
|
||||
cell_queue_append_packed_copy(NULL /*circ*/, &cq, 0 /*exitward*/, &cell,
|
||||
0 /*wide*/, 0 /*stats*/);
|
||||
tt_int_op(cq.n, ==, 2);
|
||||
tt_int_op(cq.n, OP_EQ, 2);
|
||||
|
||||
pc_tmp = cell_queue_pop(&cq);
|
||||
tt_int_op(cq.n, ==, 1);
|
||||
tt_ptr_op(pc_tmp, !=, NULL);
|
||||
tt_mem_op(pc_tmp->body, ==, "\x12\x34\x56\x78\x0a", 5);
|
||||
tt_mem_op(pc_tmp->body+5, ==, cell.payload, sizeof(cell.payload));
|
||||
tt_int_op(cq.n, OP_EQ, 1);
|
||||
tt_ptr_op(pc_tmp, OP_NE, NULL);
|
||||
tt_mem_op(pc_tmp->body, OP_EQ, "\x12\x34\x56\x78\x0a", 5);
|
||||
tt_mem_op(pc_tmp->body+5, OP_EQ, cell.payload, sizeof(cell.payload));
|
||||
packed_cell_free(pc_tmp);
|
||||
|
||||
pc_tmp = cell_queue_pop(&cq);
|
||||
tt_int_op(cq.n, ==, 0);
|
||||
tt_ptr_op(pc_tmp, !=, NULL);
|
||||
tt_mem_op(pc_tmp->body, ==, "\x20\x13\x0a", 3);
|
||||
tt_mem_op(pc_tmp->body+3, ==, cell.payload, sizeof(cell.payload));
|
||||
tt_int_op(cq.n, OP_EQ, 0);
|
||||
tt_ptr_op(pc_tmp, OP_NE, NULL);
|
||||
tt_mem_op(pc_tmp->body, OP_EQ, "\x20\x13\x0a", 3);
|
||||
tt_mem_op(pc_tmp->body+3, OP_EQ, cell.payload, sizeof(cell.payload));
|
||||
packed_cell_free(pc_tmp);
|
||||
pc_tmp = NULL;
|
||||
|
||||
tt_ptr_op(NULL, ==, cell_queue_pop(&cq));
|
||||
tt_ptr_op(NULL, OP_EQ, cell_queue_pop(&cq));
|
||||
|
||||
/* Now make sure cell_queue_clear works. */
|
||||
cell_queue_append(&cq, pc2);
|
||||
cell_queue_append(&cq, pc1);
|
||||
tt_int_op(cq.n, ==, 2);
|
||||
tt_int_op(cq.n, OP_EQ, 2);
|
||||
cell_queue_clear(&cq);
|
||||
pc2 = pc1 = NULL; /* prevent double-free */
|
||||
tt_int_op(cq.n, ==, 0);
|
||||
tt_int_op(cq.n, OP_EQ, 0);
|
||||
|
||||
done:
|
||||
packed_cell_free(pc1);
|
||||
@@ -129,17 +129,17 @@ test_circuit_n_cells(void *arg)
|
||||
origin_c = origin_circuit_new();
|
||||
origin_c->base_.purpose = CIRCUIT_PURPOSE_C_GENERAL;
|
||||
|
||||
tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), ==, 0);
|
||||
tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), OP_EQ, 0);
|
||||
cell_queue_append(&or_c->p_chan_cells, pc1);
|
||||
tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), ==, 1);
|
||||
tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), OP_EQ, 1);
|
||||
cell_queue_append(&or_c->base_.n_chan_cells, pc2);
|
||||
cell_queue_append(&or_c->base_.n_chan_cells, pc3);
|
||||
tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), ==, 3);
|
||||
tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), OP_EQ, 3);
|
||||
|
||||
tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(origin_c)), ==, 0);
|
||||
tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(origin_c)), OP_EQ, 0);
|
||||
cell_queue_append(&origin_c->base_.n_chan_cells, pc4);
|
||||
cell_queue_append(&origin_c->base_.n_chan_cells, pc5);
|
||||
tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(origin_c)), ==, 2);
|
||||
tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(origin_c)), OP_EQ, 2);
|
||||
|
||||
done:
|
||||
circuit_free(TO_CIRCUIT(or_c));
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,332 @@
|
||||
/* Copyright (c) 2014, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define TOR_CHANNEL_INTERNAL_
|
||||
#include "or.h"
|
||||
#include "address.h"
|
||||
#include "buffers.h"
|
||||
#include "channel.h"
|
||||
#include "channeltls.h"
|
||||
#include "connection_or.h"
|
||||
#include "config.h"
|
||||
/* For init/free stuff */
|
||||
#include "scheduler.h"
|
||||
#include "tortls.h"
|
||||
|
||||
/* Test suite stuff */
|
||||
#include "test.h"
|
||||
#include "fakechans.h"
|
||||
|
||||
/* The channeltls unit tests */
|
||||
static void test_channeltls_create(void *arg);
|
||||
static void test_channeltls_num_bytes_queued(void *arg);
|
||||
static void test_channeltls_overhead_estimate(void *arg);
|
||||
|
||||
/* Mocks used by channeltls unit tests */
|
||||
static size_t tlschan_buf_datalen_mock(const buf_t *buf);
|
||||
static or_connection_t * tlschan_connection_or_connect_mock(
|
||||
const tor_addr_t *addr,
|
||||
uint16_t port,
|
||||
const char *digest,
|
||||
channel_tls_t *tlschan);
|
||||
static int tlschan_is_local_addr_mock(const tor_addr_t *addr);
|
||||
|
||||
/* Fake close method */
|
||||
static void tlschan_fake_close_method(channel_t *chan);
|
||||
|
||||
/* Flags controlling behavior of channeltls unit test mocks */
|
||||
static int tlschan_local = 0;
|
||||
static const buf_t * tlschan_buf_datalen_mock_target = NULL;
|
||||
static size_t tlschan_buf_datalen_mock_size = 0;
|
||||
|
||||
/* Thing to cast to fake tor_tls_t * to appease assert_connection_ok() */
|
||||
static int fake_tortls = 0; /* Bleh... */
|
||||
|
||||
static void
|
||||
test_channeltls_create(void *arg)
|
||||
{
|
||||
tor_addr_t test_addr;
|
||||
channel_t *ch = NULL;
|
||||
const char test_digest[DIGEST_LEN] = {
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
|
||||
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14 };
|
||||
|
||||
(void)arg;
|
||||
|
||||
/* Set up a fake address to fake-connect to */
|
||||
test_addr.family = AF_INET;
|
||||
test_addr.addr.in_addr.s_addr = htonl(0x01020304);
|
||||
|
||||
/* For this test we always want the address to be treated as non-local */
|
||||
tlschan_local = 0;
|
||||
/* Install is_local_addr() mock */
|
||||
MOCK(is_local_addr, tlschan_is_local_addr_mock);
|
||||
|
||||
/* Install mock for connection_or_connect() */
|
||||
MOCK(connection_or_connect, tlschan_connection_or_connect_mock);
|
||||
|
||||
/* Try connecting */
|
||||
ch = channel_tls_connect(&test_addr, 567, test_digest);
|
||||
tt_assert(ch != NULL);
|
||||
|
||||
done:
|
||||
if (ch) {
|
||||
MOCK(scheduler_release_channel, scheduler_release_channel_mock);
|
||||
/*
|
||||
* Use fake close method that doesn't try to do too much to fake
|
||||
* orconn
|
||||
*/
|
||||
ch->close = tlschan_fake_close_method;
|
||||
channel_mark_for_close(ch);
|
||||
tor_free(ch);
|
||||
UNMOCK(scheduler_release_channel);
|
||||
}
|
||||
|
||||
UNMOCK(connection_or_connect);
|
||||
UNMOCK(is_local_addr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
test_channeltls_num_bytes_queued(void *arg)
|
||||
{
|
||||
tor_addr_t test_addr;
|
||||
channel_t *ch = NULL;
|
||||
const char test_digest[DIGEST_LEN] = {
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
|
||||
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14 };
|
||||
channel_tls_t *tlschan = NULL;
|
||||
size_t len;
|
||||
int fake_outbuf = 0, n;
|
||||
|
||||
(void)arg;
|
||||
|
||||
/* Set up a fake address to fake-connect to */
|
||||
test_addr.family = AF_INET;
|
||||
test_addr.addr.in_addr.s_addr = htonl(0x01020304);
|
||||
|
||||
/* For this test we always want the address to be treated as non-local */
|
||||
tlschan_local = 0;
|
||||
/* Install is_local_addr() mock */
|
||||
MOCK(is_local_addr, tlschan_is_local_addr_mock);
|
||||
|
||||
/* Install mock for connection_or_connect() */
|
||||
MOCK(connection_or_connect, tlschan_connection_or_connect_mock);
|
||||
|
||||
/* Try connecting */
|
||||
ch = channel_tls_connect(&test_addr, 567, test_digest);
|
||||
tt_assert(ch != NULL);
|
||||
|
||||
/*
|
||||
* Next, we have to test ch->num_bytes_queued, which is
|
||||
* channel_tls_num_bytes_queued_method. We can't mock
|
||||
* connection_get_outbuf_len() directly because it's static INLINE
|
||||
* in connection.h, but we can mock buf_datalen(). Note that
|
||||
* if bufferevents ever work, this will break with them enabled.
|
||||
*/
|
||||
|
||||
tt_assert(ch->num_bytes_queued != NULL);
|
||||
tlschan = BASE_CHAN_TO_TLS(ch);
|
||||
tt_assert(tlschan != NULL);
|
||||
if (TO_CONN(tlschan->conn)->outbuf == NULL) {
|
||||
/* We need an outbuf to make sure buf_datalen() gets called */
|
||||
fake_outbuf = 1;
|
||||
TO_CONN(tlschan->conn)->outbuf = buf_new();
|
||||
}
|
||||
tlschan_buf_datalen_mock_target = TO_CONN(tlschan->conn)->outbuf;
|
||||
tlschan_buf_datalen_mock_size = 1024;
|
||||
MOCK(buf_datalen, tlschan_buf_datalen_mock);
|
||||
len = ch->num_bytes_queued(ch);
|
||||
tt_int_op(len, ==, tlschan_buf_datalen_mock_size);
|
||||
/*
|
||||
* We also cover num_cells_writeable here; since wide_circ_ids = 0 on
|
||||
* the fake tlschans, cell_network_size returns 512, and so with
|
||||
* tlschan_buf_datalen_mock_size == 1024, we should be able to write
|
||||
* ceil((OR_CONN_HIGHWATER - 1024) / 512) = ceil(OR_CONN_HIGHWATER / 512)
|
||||
* - 2 cells.
|
||||
*/
|
||||
n = ch->num_cells_writeable(ch);
|
||||
tt_int_op(n, ==, CEIL_DIV(OR_CONN_HIGHWATER, 512) - 2);
|
||||
UNMOCK(buf_datalen);
|
||||
tlschan_buf_datalen_mock_target = NULL;
|
||||
tlschan_buf_datalen_mock_size = 0;
|
||||
if (fake_outbuf) {
|
||||
buf_free(TO_CONN(tlschan->conn)->outbuf);
|
||||
TO_CONN(tlschan->conn)->outbuf = NULL;
|
||||
}
|
||||
|
||||
done:
|
||||
if (ch) {
|
||||
MOCK(scheduler_release_channel, scheduler_release_channel_mock);
|
||||
/*
|
||||
* Use fake close method that doesn't try to do too much to fake
|
||||
* orconn
|
||||
*/
|
||||
ch->close = tlschan_fake_close_method;
|
||||
channel_mark_for_close(ch);
|
||||
tor_free(ch);
|
||||
UNMOCK(scheduler_release_channel);
|
||||
}
|
||||
|
||||
UNMOCK(connection_or_connect);
|
||||
UNMOCK(is_local_addr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
test_channeltls_overhead_estimate(void *arg)
|
||||
{
|
||||
tor_addr_t test_addr;
|
||||
channel_t *ch = NULL;
|
||||
const char test_digest[DIGEST_LEN] = {
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
|
||||
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14 };
|
||||
float r;
|
||||
channel_tls_t *tlschan = NULL;
|
||||
|
||||
(void)arg;
|
||||
|
||||
/* Set up a fake address to fake-connect to */
|
||||
test_addr.family = AF_INET;
|
||||
test_addr.addr.in_addr.s_addr = htonl(0x01020304);
|
||||
|
||||
/* For this test we always want the address to be treated as non-local */
|
||||
tlschan_local = 0;
|
||||
/* Install is_local_addr() mock */
|
||||
MOCK(is_local_addr, tlschan_is_local_addr_mock);
|
||||
|
||||
/* Install mock for connection_or_connect() */
|
||||
MOCK(connection_or_connect, tlschan_connection_or_connect_mock);
|
||||
|
||||
/* Try connecting */
|
||||
ch = channel_tls_connect(&test_addr, 567, test_digest);
|
||||
tt_assert(ch != NULL);
|
||||
|
||||
/* First case: silly low ratios should get clamped to 1.0f */
|
||||
tlschan = BASE_CHAN_TO_TLS(ch);
|
||||
tt_assert(tlschan != NULL);
|
||||
tlschan->conn->bytes_xmitted = 128;
|
||||
tlschan->conn->bytes_xmitted_by_tls = 64;
|
||||
r = ch->get_overhead_estimate(ch);
|
||||
tt_assert(fabsf(r - 1.0f) < 1E-12);
|
||||
|
||||
tlschan->conn->bytes_xmitted_by_tls = 127;
|
||||
r = ch->get_overhead_estimate(ch);
|
||||
tt_assert(fabsf(r - 1.0f) < 1E-12);
|
||||
|
||||
/* Now middle of the range */
|
||||
tlschan->conn->bytes_xmitted_by_tls = 192;
|
||||
r = ch->get_overhead_estimate(ch);
|
||||
tt_assert(fabsf(r - 1.5f) < 1E-12);
|
||||
|
||||
/* Now above the 2.0f clamp */
|
||||
tlschan->conn->bytes_xmitted_by_tls = 257;
|
||||
r = ch->get_overhead_estimate(ch);
|
||||
tt_assert(fabsf(r - 2.0f) < 1E-12);
|
||||
|
||||
tlschan->conn->bytes_xmitted_by_tls = 512;
|
||||
r = ch->get_overhead_estimate(ch);
|
||||
tt_assert(fabsf(r - 2.0f) < 1E-12);
|
||||
|
||||
done:
|
||||
if (ch) {
|
||||
MOCK(scheduler_release_channel, scheduler_release_channel_mock);
|
||||
/*
|
||||
* Use fake close method that doesn't try to do too much to fake
|
||||
* orconn
|
||||
*/
|
||||
ch->close = tlschan_fake_close_method;
|
||||
channel_mark_for_close(ch);
|
||||
tor_free(ch);
|
||||
UNMOCK(scheduler_release_channel);
|
||||
}
|
||||
|
||||
UNMOCK(connection_or_connect);
|
||||
UNMOCK(is_local_addr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static size_t
|
||||
tlschan_buf_datalen_mock(const buf_t *buf)
|
||||
{
|
||||
if (buf != NULL && buf == tlschan_buf_datalen_mock_target) {
|
||||
return tlschan_buf_datalen_mock_size;
|
||||
} else {
|
||||
return buf_datalen__real(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static or_connection_t *
|
||||
tlschan_connection_or_connect_mock(const tor_addr_t *addr,
|
||||
uint16_t port,
|
||||
const char *digest,
|
||||
channel_tls_t *tlschan)
|
||||
{
|
||||
or_connection_t *result = NULL;
|
||||
|
||||
tt_assert(addr != NULL);
|
||||
tt_assert(port != 0);
|
||||
tt_assert(digest != NULL);
|
||||
tt_assert(tlschan != NULL);
|
||||
|
||||
/* Make a fake orconn */
|
||||
result = tor_malloc_zero(sizeof(*result));
|
||||
result->base_.magic = OR_CONNECTION_MAGIC;
|
||||
result->base_.state = OR_CONN_STATE_OPEN;
|
||||
result->base_.type = CONN_TYPE_OR;
|
||||
result->base_.socket_family = addr->family;
|
||||
result->base_.address = tor_strdup("<fake>");
|
||||
memcpy(&(result->base_.addr), addr, sizeof(tor_addr_t));
|
||||
result->base_.port = port;
|
||||
memcpy(result->identity_digest, digest, DIGEST_LEN);
|
||||
result->chan = tlschan;
|
||||
memcpy(&(result->real_addr), addr, sizeof(tor_addr_t));
|
||||
result->tls = (tor_tls_t *)((void *)(&fake_tortls));
|
||||
|
||||
done:
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
tlschan_fake_close_method(channel_t *chan)
|
||||
{
|
||||
channel_tls_t *tlschan = NULL;
|
||||
|
||||
tt_assert(chan != NULL);
|
||||
tt_int_op(chan->magic, ==, TLS_CHAN_MAGIC);
|
||||
|
||||
tlschan = BASE_CHAN_TO_TLS(chan);
|
||||
tt_assert(tlschan != NULL);
|
||||
|
||||
/* Just free the fake orconn */
|
||||
tor_free(tlschan->conn);
|
||||
|
||||
channel_closed(chan);
|
||||
|
||||
done:
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
tlschan_is_local_addr_mock(const tor_addr_t *addr)
|
||||
{
|
||||
tt_assert(addr != NULL);
|
||||
|
||||
done:
|
||||
return tlschan_local;
|
||||
}
|
||||
|
||||
struct testcase_t channeltls_tests[] = {
|
||||
{ "create", test_channeltls_create, TT_FORK, NULL, NULL },
|
||||
{ "num_bytes_queued", test_channeltls_num_bytes_queued,
|
||||
TT_FORK, NULL, NULL },
|
||||
{ "overhead_estimate", test_channeltls_overhead_estimate,
|
||||
TT_FORK, NULL, NULL },
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/* Copyright (c) 2014, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
#include "orconfig.h"
|
||||
#include "or.h"
|
||||
#include <dirent.h>
|
||||
#include "config.h"
|
||||
#include "test.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define mkdir(a,b) mkdir(a)
|
||||
#define tt_int_op_nowin(a,op,b) do { (void)(a); (void)(b); } while (0)
|
||||
#else
|
||||
#define tt_int_op_nowin(a,op,b) tt_int_op((a),op,(b))
|
||||
#endif
|
||||
|
||||
/** Run unit tests for private dir permission enforcement logic. */
|
||||
static void
|
||||
test_checkdir_perms(void *testdata)
|
||||
{
|
||||
(void)testdata;
|
||||
or_options_t *options = get_options_mutable();
|
||||
const char *subdir = "test_checkdir";
|
||||
char *testdir = NULL;
|
||||
cpd_check_t cpd_chkopts;
|
||||
cpd_check_t unix_create_opts;
|
||||
cpd_check_t unix_verify_optsmask;
|
||||
struct stat st;
|
||||
|
||||
/* setup data directory before tests. */
|
||||
tor_free(options->DataDirectory);
|
||||
options->DataDirectory = tor_strdup(get_fname(subdir));
|
||||
tt_int_op(mkdir(options->DataDirectory, 0750), OP_EQ, 0);
|
||||
|
||||
/* test: create new dir, no flags. */
|
||||
testdir = get_datadir_fname("checkdir_new_none");
|
||||
cpd_chkopts = CPD_CREATE;
|
||||
unix_verify_optsmask = 0077;
|
||||
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
||||
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
||||
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
||||
tor_free(testdir);
|
||||
|
||||
/* test: create new dir, CPD_GROUP_OK option set. */
|
||||
testdir = get_datadir_fname("checkdir_new_groupok");
|
||||
cpd_chkopts = CPD_CREATE|CPD_GROUP_OK;
|
||||
unix_verify_optsmask = 0077;
|
||||
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
||||
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
||||
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
||||
tor_free(testdir);
|
||||
|
||||
/* test: should get an error on existing dir with
|
||||
wrong perms */
|
||||
testdir = get_datadir_fname("checkdir_new_groupok_err");
|
||||
tt_int_op(0, OP_EQ, mkdir(testdir, 027));
|
||||
cpd_chkopts = CPD_CHECK_MODE_ONLY|CPD_CREATE|CPD_GROUP_OK;
|
||||
tt_int_op_nowin(-1, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
||||
tor_free(testdir);
|
||||
|
||||
/* test: create new dir, CPD_GROUP_READ option set. */
|
||||
testdir = get_datadir_fname("checkdir_new_groupread");
|
||||
cpd_chkopts = CPD_CREATE|CPD_GROUP_READ;
|
||||
unix_verify_optsmask = 0027;
|
||||
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
||||
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
||||
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
||||
tor_free(testdir);
|
||||
|
||||
/* test: check existing dir created with defaults,
|
||||
and verify with CPD_CREATE only. */
|
||||
testdir = get_datadir_fname("checkdir_exists_none");
|
||||
cpd_chkopts = CPD_CREATE;
|
||||
unix_create_opts = 0700;
|
||||
(void)unix_create_opts;
|
||||
unix_verify_optsmask = 0077;
|
||||
tt_int_op(0, OP_EQ, mkdir(testdir, unix_create_opts));
|
||||
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
||||
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
||||
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
||||
tor_free(testdir);
|
||||
|
||||
/* test: check existing dir created with defaults,
|
||||
and verify with CPD_GROUP_OK option set. */
|
||||
testdir = get_datadir_fname("checkdir_exists_groupok");
|
||||
cpd_chkopts = CPD_CREATE;
|
||||
unix_verify_optsmask = 0077;
|
||||
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
||||
cpd_chkopts = CPD_GROUP_OK;
|
||||
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
||||
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
||||
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
||||
tor_free(testdir);
|
||||
|
||||
/* test: check existing dir created with defaults,
|
||||
and verify with CPD_GROUP_READ option set. */
|
||||
testdir = get_datadir_fname("checkdir_exists_groupread");
|
||||
cpd_chkopts = CPD_CREATE;
|
||||
unix_verify_optsmask = 0027;
|
||||
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
||||
cpd_chkopts = CPD_GROUP_READ;
|
||||
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
||||
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
||||
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
||||
tor_free(testdir);
|
||||
|
||||
/* test: check existing dir created with CPD_GROUP_READ,
|
||||
and verify with CPD_GROUP_OK option set. */
|
||||
testdir = get_datadir_fname("checkdir_existsread_groupok");
|
||||
cpd_chkopts = CPD_CREATE|CPD_GROUP_READ;
|
||||
unix_verify_optsmask = 0027;
|
||||
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
||||
cpd_chkopts = CPD_GROUP_OK;
|
||||
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
||||
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
||||
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
||||
tor_free(testdir);
|
||||
|
||||
/* test: check existing dir created with CPD_GROUP_READ,
|
||||
and verify with CPD_GROUP_READ option set. */
|
||||
testdir = get_datadir_fname("checkdir_existsread_groupread");
|
||||
cpd_chkopts = CPD_CREATE|CPD_GROUP_READ;
|
||||
unix_verify_optsmask = 0027;
|
||||
tt_int_op(0, OP_EQ, check_private_dir(testdir, cpd_chkopts, NULL));
|
||||
tt_int_op(0, OP_EQ, stat(testdir, &st));
|
||||
tt_int_op_nowin(0, OP_EQ, (st.st_mode & unix_verify_optsmask));
|
||||
|
||||
done:
|
||||
tor_free(testdir);
|
||||
}
|
||||
|
||||
#define CHECKDIR(name,flags) \
|
||||
{ #name, test_checkdir_##name, (flags), NULL, NULL }
|
||||
|
||||
struct testcase_t checkdir_tests[] = {
|
||||
CHECKDIR(perms, 0),
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
||||
+64
-64
@@ -50,17 +50,17 @@ circuitmux_detach_mock(circuitmux_t *cmux, circuit_t *circ)
|
||||
}
|
||||
|
||||
#define GOT_CMUX_ATTACH(mux_, circ_, dir_) do { \
|
||||
tt_int_op(cam.ncalls, ==, 1); \
|
||||
tt_ptr_op(cam.cmux, ==, (mux_)); \
|
||||
tt_ptr_op(cam.circ, ==, (circ_)); \
|
||||
tt_int_op(cam.dir, ==, (dir_)); \
|
||||
tt_int_op(cam.ncalls, OP_EQ, 1); \
|
||||
tt_ptr_op(cam.cmux, OP_EQ, (mux_)); \
|
||||
tt_ptr_op(cam.circ, OP_EQ, (circ_)); \
|
||||
tt_int_op(cam.dir, OP_EQ, (dir_)); \
|
||||
memset(&cam, 0, sizeof(cam)); \
|
||||
} while (0)
|
||||
|
||||
#define GOT_CMUX_DETACH(mux_, circ_) do { \
|
||||
tt_int_op(cdm.ncalls, ==, 1); \
|
||||
tt_ptr_op(cdm.cmux, ==, (mux_)); \
|
||||
tt_ptr_op(cdm.circ, ==, (circ_)); \
|
||||
tt_int_op(cdm.ncalls, OP_EQ, 1); \
|
||||
tt_ptr_op(cdm.cmux, OP_EQ, (mux_)); \
|
||||
tt_ptr_op(cdm.circ, OP_EQ, (circ_)); \
|
||||
memset(&cdm, 0, sizeof(cdm)); \
|
||||
} while (0)
|
||||
|
||||
@@ -90,14 +90,14 @@ test_clist_maps(void *arg)
|
||||
or_c1 = or_circuit_new(100, ch2);
|
||||
tt_assert(or_c1);
|
||||
GOT_CMUX_ATTACH(ch2->cmux, or_c1, CELL_DIRECTION_IN);
|
||||
tt_int_op(or_c1->p_circ_id, ==, 100);
|
||||
tt_ptr_op(or_c1->p_chan, ==, ch2);
|
||||
tt_int_op(or_c1->p_circ_id, OP_EQ, 100);
|
||||
tt_ptr_op(or_c1->p_chan, OP_EQ, ch2);
|
||||
|
||||
or_c2 = or_circuit_new(100, ch1);
|
||||
tt_assert(or_c2);
|
||||
GOT_CMUX_ATTACH(ch1->cmux, or_c2, CELL_DIRECTION_IN);
|
||||
tt_int_op(or_c2->p_circ_id, ==, 100);
|
||||
tt_ptr_op(or_c2->p_chan, ==, ch1);
|
||||
tt_int_op(or_c2->p_circ_id, OP_EQ, 100);
|
||||
tt_ptr_op(or_c2->p_chan, OP_EQ, ch1);
|
||||
|
||||
circuit_set_n_circid_chan(TO_CIRCUIT(or_c1), 200, ch1);
|
||||
GOT_CMUX_ATTACH(ch1->cmux, or_c1, CELL_DIRECTION_OUT);
|
||||
@@ -105,11 +105,11 @@ test_clist_maps(void *arg)
|
||||
circuit_set_n_circid_chan(TO_CIRCUIT(or_c2), 200, ch2);
|
||||
GOT_CMUX_ATTACH(ch2->cmux, or_c2, CELL_DIRECTION_OUT);
|
||||
|
||||
tt_ptr_op(circuit_get_by_circid_channel(200, ch1), ==, TO_CIRCUIT(or_c1));
|
||||
tt_ptr_op(circuit_get_by_circid_channel(200, ch2), ==, TO_CIRCUIT(or_c2));
|
||||
tt_ptr_op(circuit_get_by_circid_channel(100, ch2), ==, TO_CIRCUIT(or_c1));
|
||||
tt_ptr_op(circuit_get_by_circid_channel(200, ch1), OP_EQ, TO_CIRCUIT(or_c1));
|
||||
tt_ptr_op(circuit_get_by_circid_channel(200, ch2), OP_EQ, TO_CIRCUIT(or_c2));
|
||||
tt_ptr_op(circuit_get_by_circid_channel(100, ch2), OP_EQ, TO_CIRCUIT(or_c1));
|
||||
/* Try the same thing again, to test the "fast" path. */
|
||||
tt_ptr_op(circuit_get_by_circid_channel(100, ch2), ==, TO_CIRCUIT(or_c1));
|
||||
tt_ptr_op(circuit_get_by_circid_channel(100, ch2), OP_EQ, TO_CIRCUIT(or_c1));
|
||||
tt_assert(circuit_id_in_use_on_channel(100, ch2));
|
||||
tt_assert(! circuit_id_in_use_on_channel(101, ch2));
|
||||
|
||||
@@ -117,9 +117,9 @@ test_clist_maps(void *arg)
|
||||
circuit_set_p_circid_chan(or_c1, 500, ch3);
|
||||
GOT_CMUX_DETACH(ch2->cmux, TO_CIRCUIT(or_c1));
|
||||
GOT_CMUX_ATTACH(ch3->cmux, TO_CIRCUIT(or_c1), CELL_DIRECTION_IN);
|
||||
tt_ptr_op(circuit_get_by_circid_channel(100, ch2), ==, NULL);
|
||||
tt_ptr_op(circuit_get_by_circid_channel(100, ch2), OP_EQ, NULL);
|
||||
tt_assert(! circuit_id_in_use_on_channel(100, ch2));
|
||||
tt_ptr_op(circuit_get_by_circid_channel(500, ch3), ==, TO_CIRCUIT(or_c1));
|
||||
tt_ptr_op(circuit_get_by_circid_channel(500, ch3), OP_EQ, TO_CIRCUIT(or_c1));
|
||||
|
||||
/* Now let's see about destroy handling. */
|
||||
tt_assert(! circuit_id_in_use_on_channel(205, ch2));
|
||||
@@ -132,26 +132,26 @@ test_clist_maps(void *arg)
|
||||
tt_assert(circuit_id_in_use_on_channel(100, ch1));
|
||||
|
||||
tt_assert(TO_CIRCUIT(or_c2)->n_delete_pending != 0);
|
||||
tt_ptr_op(circuit_get_by_circid_channel(200, ch2), ==, TO_CIRCUIT(or_c2));
|
||||
tt_ptr_op(circuit_get_by_circid_channel(100, ch1), ==, TO_CIRCUIT(or_c2));
|
||||
tt_ptr_op(circuit_get_by_circid_channel(200, ch2), OP_EQ, TO_CIRCUIT(or_c2));
|
||||
tt_ptr_op(circuit_get_by_circid_channel(100, ch1), OP_EQ, TO_CIRCUIT(or_c2));
|
||||
|
||||
/* Okay, now free ch2 and make sure that the circuit ID is STILL not
|
||||
* usable, because we haven't declared the destroy to be nonpending */
|
||||
tt_int_op(cdm.ncalls, ==, 0);
|
||||
tt_int_op(cdm.ncalls, OP_EQ, 0);
|
||||
circuit_free(TO_CIRCUIT(or_c2));
|
||||
or_c2 = NULL; /* prevent free */
|
||||
tt_int_op(cdm.ncalls, ==, 2);
|
||||
tt_int_op(cdm.ncalls, OP_EQ, 2);
|
||||
memset(&cdm, 0, sizeof(cdm));
|
||||
tt_assert(circuit_id_in_use_on_channel(200, ch2));
|
||||
tt_assert(circuit_id_in_use_on_channel(100, ch1));
|
||||
tt_ptr_op(circuit_get_by_circid_channel(200, ch2), ==, NULL);
|
||||
tt_ptr_op(circuit_get_by_circid_channel(100, ch1), ==, NULL);
|
||||
tt_ptr_op(circuit_get_by_circid_channel(200, ch2), OP_EQ, NULL);
|
||||
tt_ptr_op(circuit_get_by_circid_channel(100, ch1), OP_EQ, NULL);
|
||||
|
||||
/* Now say that the destroy is nonpending */
|
||||
channel_note_destroy_not_pending(ch2, 200);
|
||||
tt_ptr_op(circuit_get_by_circid_channel(200, ch2), ==, NULL);
|
||||
tt_ptr_op(circuit_get_by_circid_channel(200, ch2), OP_EQ, NULL);
|
||||
channel_note_destroy_not_pending(ch1, 100);
|
||||
tt_ptr_op(circuit_get_by_circid_channel(100, ch1), ==, NULL);
|
||||
tt_ptr_op(circuit_get_by_circid_channel(100, ch1), OP_EQ, NULL);
|
||||
tt_assert(! circuit_id_in_use_on_channel(200, ch2));
|
||||
tt_assert(! circuit_id_in_use_on_channel(100, ch1));
|
||||
|
||||
@@ -190,73 +190,73 @@ test_rend_token_maps(void *arg)
|
||||
c4 = or_circuit_new(0, NULL);
|
||||
|
||||
/* Make sure we really filled up the tok* variables */
|
||||
tt_int_op(tok1[REND_TOKEN_LEN-1], ==, 'y');
|
||||
tt_int_op(tok2[REND_TOKEN_LEN-1], ==, ' ');
|
||||
tt_int_op(tok3[REND_TOKEN_LEN-1], ==, '.');
|
||||
tt_int_op(tok1[REND_TOKEN_LEN-1], OP_EQ, 'y');
|
||||
tt_int_op(tok2[REND_TOKEN_LEN-1], OP_EQ, ' ');
|
||||
tt_int_op(tok3[REND_TOKEN_LEN-1], OP_EQ, '.');
|
||||
|
||||
/* No maps; nothing there. */
|
||||
tt_ptr_op(NULL, ==, circuit_get_rendezvous(tok1));
|
||||
tt_ptr_op(NULL, ==, circuit_get_intro_point(tok1));
|
||||
tt_ptr_op(NULL, OP_EQ, circuit_get_rendezvous(tok1));
|
||||
tt_ptr_op(NULL, OP_EQ, circuit_get_intro_point(tok1));
|
||||
|
||||
circuit_set_rendezvous_cookie(c1, tok1);
|
||||
circuit_set_intro_point_digest(c2, tok2);
|
||||
|
||||
tt_ptr_op(NULL, ==, circuit_get_rendezvous(tok3));
|
||||
tt_ptr_op(NULL, ==, circuit_get_intro_point(tok3));
|
||||
tt_ptr_op(NULL, ==, circuit_get_rendezvous(tok2));
|
||||
tt_ptr_op(NULL, ==, circuit_get_intro_point(tok1));
|
||||
tt_ptr_op(NULL, OP_EQ, circuit_get_rendezvous(tok3));
|
||||
tt_ptr_op(NULL, OP_EQ, circuit_get_intro_point(tok3));
|
||||
tt_ptr_op(NULL, OP_EQ, circuit_get_rendezvous(tok2));
|
||||
tt_ptr_op(NULL, OP_EQ, circuit_get_intro_point(tok1));
|
||||
|
||||
/* Without purpose set, we don't get the circuits */
|
||||
tt_ptr_op(NULL, ==, circuit_get_rendezvous(tok1));
|
||||
tt_ptr_op(NULL, ==, circuit_get_intro_point(tok2));
|
||||
tt_ptr_op(NULL, OP_EQ, circuit_get_rendezvous(tok1));
|
||||
tt_ptr_op(NULL, OP_EQ, circuit_get_intro_point(tok2));
|
||||
|
||||
c1->base_.purpose = CIRCUIT_PURPOSE_REND_POINT_WAITING;
|
||||
c2->base_.purpose = CIRCUIT_PURPOSE_INTRO_POINT;
|
||||
|
||||
/* Okay, make sure they show up now. */
|
||||
tt_ptr_op(c1, ==, circuit_get_rendezvous(tok1));
|
||||
tt_ptr_op(c2, ==, circuit_get_intro_point(tok2));
|
||||
tt_ptr_op(c1, OP_EQ, circuit_get_rendezvous(tok1));
|
||||
tt_ptr_op(c2, OP_EQ, circuit_get_intro_point(tok2));
|
||||
|
||||
/* Two items at the same place with the same token. */
|
||||
c3->base_.purpose = CIRCUIT_PURPOSE_REND_POINT_WAITING;
|
||||
circuit_set_rendezvous_cookie(c3, tok2);
|
||||
tt_ptr_op(c2, ==, circuit_get_intro_point(tok2));
|
||||
tt_ptr_op(c3, ==, circuit_get_rendezvous(tok2));
|
||||
tt_ptr_op(c2, OP_EQ, circuit_get_intro_point(tok2));
|
||||
tt_ptr_op(c3, OP_EQ, circuit_get_rendezvous(tok2));
|
||||
|
||||
/* Marking a circuit makes it not get returned any more */
|
||||
circuit_mark_for_close(TO_CIRCUIT(c1), END_CIRC_REASON_FINISHED);
|
||||
tt_ptr_op(NULL, ==, circuit_get_rendezvous(tok1));
|
||||
tt_ptr_op(NULL, OP_EQ, circuit_get_rendezvous(tok1));
|
||||
circuit_free(TO_CIRCUIT(c1));
|
||||
c1 = NULL;
|
||||
|
||||
/* Freeing a circuit makes it not get returned any more. */
|
||||
circuit_free(TO_CIRCUIT(c2));
|
||||
c2 = NULL;
|
||||
tt_ptr_op(NULL, ==, circuit_get_intro_point(tok2));
|
||||
tt_ptr_op(NULL, OP_EQ, circuit_get_intro_point(tok2));
|
||||
|
||||
/* c3 -- are you still there? */
|
||||
tt_ptr_op(c3, ==, circuit_get_rendezvous(tok2));
|
||||
tt_ptr_op(c3, OP_EQ, circuit_get_rendezvous(tok2));
|
||||
/* Change its cookie. This never happens in Tor per se, but hey. */
|
||||
c3->base_.purpose = CIRCUIT_PURPOSE_INTRO_POINT;
|
||||
circuit_set_intro_point_digest(c3, tok3);
|
||||
|
||||
tt_ptr_op(NULL, ==, circuit_get_rendezvous(tok2));
|
||||
tt_ptr_op(c3, ==, circuit_get_intro_point(tok3));
|
||||
tt_ptr_op(NULL, OP_EQ, circuit_get_rendezvous(tok2));
|
||||
tt_ptr_op(c3, OP_EQ, circuit_get_intro_point(tok3));
|
||||
|
||||
/* Now replace c3 with c4. */
|
||||
c4->base_.purpose = CIRCUIT_PURPOSE_INTRO_POINT;
|
||||
circuit_set_intro_point_digest(c4, tok3);
|
||||
|
||||
tt_ptr_op(c4, ==, circuit_get_intro_point(tok3));
|
||||
tt_ptr_op(c4, OP_EQ, circuit_get_intro_point(tok3));
|
||||
|
||||
tt_ptr_op(c3->rendinfo, ==, NULL);
|
||||
tt_ptr_op(c4->rendinfo, !=, NULL);
|
||||
tt_mem_op(c4->rendinfo, ==, tok3, REND_TOKEN_LEN);
|
||||
tt_ptr_op(c3->rendinfo, OP_EQ, NULL);
|
||||
tt_ptr_op(c4->rendinfo, OP_NE, NULL);
|
||||
tt_mem_op(c4->rendinfo, OP_EQ, tok3, REND_TOKEN_LEN);
|
||||
|
||||
/* Now clear c4's cookie. */
|
||||
circuit_set_intro_point_digest(c4, NULL);
|
||||
tt_ptr_op(c4->rendinfo, ==, NULL);
|
||||
tt_ptr_op(NULL, ==, circuit_get_intro_point(tok3));
|
||||
tt_ptr_op(c4->rendinfo, OP_EQ, NULL);
|
||||
tt_ptr_op(NULL, OP_EQ, circuit_get_intro_point(tok3));
|
||||
|
||||
done:
|
||||
if (c1)
|
||||
@@ -283,32 +283,32 @@ test_pick_circid(void *arg)
|
||||
chan2->wide_circ_ids = 1;
|
||||
|
||||
chan1->circ_id_type = CIRC_ID_TYPE_NEITHER;
|
||||
tt_int_op(0, ==, get_unique_circ_id_by_chan(chan1));
|
||||
tt_int_op(0, OP_EQ, get_unique_circ_id_by_chan(chan1));
|
||||
|
||||
/* Basic tests, with no collisions */
|
||||
chan1->circ_id_type = CIRC_ID_TYPE_LOWER;
|
||||
for (i = 0; i < 50; ++i) {
|
||||
circid = get_unique_circ_id_by_chan(chan1);
|
||||
tt_uint_op(0, <, circid);
|
||||
tt_uint_op(circid, <, (1<<15));
|
||||
tt_uint_op(0, OP_LT, circid);
|
||||
tt_uint_op(circid, OP_LT, (1<<15));
|
||||
}
|
||||
chan1->circ_id_type = CIRC_ID_TYPE_HIGHER;
|
||||
for (i = 0; i < 50; ++i) {
|
||||
circid = get_unique_circ_id_by_chan(chan1);
|
||||
tt_uint_op((1<<15), <, circid);
|
||||
tt_uint_op(circid, <, (1<<16));
|
||||
tt_uint_op((1<<15), OP_LT, circid);
|
||||
tt_uint_op(circid, OP_LT, (1<<16));
|
||||
}
|
||||
|
||||
chan2->circ_id_type = CIRC_ID_TYPE_LOWER;
|
||||
for (i = 0; i < 50; ++i) {
|
||||
circid = get_unique_circ_id_by_chan(chan2);
|
||||
tt_uint_op(0, <, circid);
|
||||
tt_uint_op(circid, <, (1u<<31));
|
||||
tt_uint_op(0, OP_LT, circid);
|
||||
tt_uint_op(circid, OP_LT, (1u<<31));
|
||||
}
|
||||
chan2->circ_id_type = CIRC_ID_TYPE_HIGHER;
|
||||
for (i = 0; i < 50; ++i) {
|
||||
circid = get_unique_circ_id_by_chan(chan2);
|
||||
tt_uint_op((1u<<31), <, circid);
|
||||
tt_uint_op((1u<<31), OP_LT, circid);
|
||||
}
|
||||
|
||||
/* Now make sure that we can behave well when we are full up on circuits */
|
||||
@@ -319,20 +319,20 @@ test_pick_circid(void *arg)
|
||||
for (i = 0; i < (1<<15); ++i) {
|
||||
circid = get_unique_circ_id_by_chan(chan1);
|
||||
if (circid == 0) {
|
||||
tt_int_op(i, >, (1<<14));
|
||||
tt_int_op(i, OP_GT, (1<<14));
|
||||
break;
|
||||
}
|
||||
tt_uint_op(circid, <, (1<<15));
|
||||
tt_uint_op(circid, OP_LT, (1<<15));
|
||||
tt_assert(! bitarray_is_set(ba, circid));
|
||||
bitarray_set(ba, circid);
|
||||
channel_mark_circid_unusable(chan1, circid);
|
||||
}
|
||||
tt_int_op(i, <, (1<<15));
|
||||
tt_int_op(i, OP_LT, (1<<15));
|
||||
/* Make sure that being full on chan1 does not interfere with chan2 */
|
||||
for (i = 0; i < 100; ++i) {
|
||||
circid = get_unique_circ_id_by_chan(chan2);
|
||||
tt_uint_op(circid, >, 0);
|
||||
tt_uint_op(circid, <, (1<<15));
|
||||
tt_uint_op(circid, OP_GT, 0);
|
||||
tt_uint_op(circid, OP_LT, (1<<15));
|
||||
channel_mark_circid_unusable(chan2, circid);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "channel.h"
|
||||
#include "circuitmux.h"
|
||||
#include "relay.h"
|
||||
#include "scheduler.h"
|
||||
#include "test.h"
|
||||
|
||||
/* XXXX duplicated function from test_circuitlist.c */
|
||||
@@ -35,6 +36,12 @@ test_cmux_destroy_cell_queue(void *arg)
|
||||
circuit_t *circ = NULL;
|
||||
cell_queue_t *cq = NULL;
|
||||
packed_cell_t *pc = NULL;
|
||||
tor_libevent_cfg cfg;
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
tor_libevent_initialize(&cfg);
|
||||
scheduler_init();
|
||||
|
||||
#ifdef ENABLE_MEMPOOLS
|
||||
init_cell_pool();
|
||||
@@ -55,21 +62,21 @@ test_cmux_destroy_cell_queue(void *arg)
|
||||
circuitmux_append_destroy_cell(ch, cmux, 190, 6);
|
||||
circuitmux_append_destroy_cell(ch, cmux, 30, 1);
|
||||
|
||||
tt_int_op(circuitmux_num_cells(cmux), ==, 3);
|
||||
tt_int_op(circuitmux_num_cells(cmux), OP_EQ, 3);
|
||||
|
||||
circ = circuitmux_get_first_active_circuit(cmux, &cq);
|
||||
tt_assert(!circ);
|
||||
tt_assert(cq);
|
||||
|
||||
tt_int_op(cq->n, ==, 3);
|
||||
tt_int_op(cq->n, OP_EQ, 3);
|
||||
|
||||
pc = cell_queue_pop(cq);
|
||||
tt_assert(pc);
|
||||
tt_mem_op(pc->body, ==, "\x00\x00\x00\x64\x04\x0a\x00\x00\x00", 9);
|
||||
tt_mem_op(pc->body, OP_EQ, "\x00\x00\x00\x64\x04\x0a\x00\x00\x00", 9);
|
||||
packed_cell_free(pc);
|
||||
pc = NULL;
|
||||
|
||||
tt_int_op(circuitmux_num_cells(cmux), ==, 2);
|
||||
tt_int_op(circuitmux_num_cells(cmux), OP_EQ, 2);
|
||||
|
||||
done:
|
||||
circuitmux_free(cmux);
|
||||
|
||||
+290
-25
@@ -14,6 +14,8 @@
|
||||
#include "test.h"
|
||||
#include "util.h"
|
||||
#include "address.h"
|
||||
#include "entrynodes.h"
|
||||
#include "transports.h"
|
||||
|
||||
static void
|
||||
test_config_addressmap(void *arg)
|
||||
@@ -63,22 +65,22 @@ test_config_addressmap(void *arg)
|
||||
/* MapAddress .google.com .torserver.exit */
|
||||
strlcpy(address, "reader.google.com", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "reader.torserver.exit");
|
||||
tt_str_op(address,OP_EQ, "reader.torserver.exit");
|
||||
|
||||
/* MapAddress *.yahoo.com *.google.com.torserver.exit */
|
||||
strlcpy(address, "reader.yahoo.com", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "reader.google.com.torserver.exit");
|
||||
tt_str_op(address,OP_EQ, "reader.google.com.torserver.exit");
|
||||
|
||||
/*MapAddress *.cnn.com www.cnn.com */
|
||||
strlcpy(address, "cnn.com", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "www.cnn.com");
|
||||
tt_str_op(address,OP_EQ, "www.cnn.com");
|
||||
|
||||
/* MapAddress .cn.com www.cnn.com */
|
||||
strlcpy(address, "www.cn.com", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "www.cnn.com");
|
||||
tt_str_op(address,OP_EQ, "www.cnn.com");
|
||||
|
||||
/* MapAddress ex.com www.cnn.com - no match */
|
||||
strlcpy(address, "www.ex.com", sizeof(address));
|
||||
@@ -91,19 +93,19 @@ test_config_addressmap(void *arg)
|
||||
/* Where mapping for FQDN match on FQDN */
|
||||
strlcpy(address, "www.google.com", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "3.3.3.3");
|
||||
tt_str_op(address,OP_EQ, "3.3.3.3");
|
||||
|
||||
strlcpy(address, "www.torproject.org", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "1.1.1.1");
|
||||
tt_str_op(address,OP_EQ, "1.1.1.1");
|
||||
|
||||
strlcpy(address, "other.torproject.org", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "this.torproject.org.otherserver.exit");
|
||||
tt_str_op(address,OP_EQ, "this.torproject.org.otherserver.exit");
|
||||
|
||||
strlcpy(address, "test.torproject.org", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "2.2.2.2");
|
||||
tt_str_op(address,OP_EQ, "2.2.2.2");
|
||||
|
||||
/* Test a chain of address mappings and the order in which they were added:
|
||||
"MapAddress www.example.org 4.4.4.4"
|
||||
@@ -112,12 +114,12 @@ test_config_addressmap(void *arg)
|
||||
*/
|
||||
strlcpy(address, "www.example.org", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "5.5.5.5");
|
||||
tt_str_op(address,OP_EQ, "5.5.5.5");
|
||||
|
||||
/* Test infinite address mapping results in no change */
|
||||
strlcpy(address, "www.infiniteloop.org", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "www.infiniteloop.org");
|
||||
tt_str_op(address,OP_EQ, "www.infiniteloop.org");
|
||||
|
||||
/* Test we don't find false positives */
|
||||
strlcpy(address, "www.example.com", sizeof(address));
|
||||
@@ -135,23 +137,23 @@ test_config_addressmap(void *arg)
|
||||
|
||||
strlcpy(address, "www.abc.com", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "www.abc.torserver.exit");
|
||||
tt_str_op(address,OP_EQ, "www.abc.torserver.exit");
|
||||
|
||||
strlcpy(address, "www.def.com", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "www.def.torserver.exit");
|
||||
tt_str_op(address,OP_EQ, "www.def.torserver.exit");
|
||||
|
||||
strlcpy(address, "www.torproject.org", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "1.1.1.1");
|
||||
tt_str_op(address,OP_EQ, "1.1.1.1");
|
||||
|
||||
strlcpy(address, "test.torproject.org", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "1.1.1.1");
|
||||
tt_str_op(address,OP_EQ, "1.1.1.1");
|
||||
|
||||
strlcpy(address, "torproject.net", sizeof(address));
|
||||
tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL));
|
||||
tt_str_op(address,==, "2.2.2.2");
|
||||
tt_str_op(address,OP_EQ, "2.2.2.2");
|
||||
|
||||
/* We don't support '*' as a mapping directive */
|
||||
config_free_lines(get_options_mutable()->AddressMap);
|
||||
@@ -211,9 +213,9 @@ test_config_check_or_create_data_subdir(void *arg)
|
||||
subpath = get_datadir_fname(subdir);
|
||||
|
||||
#if defined (_WIN32)
|
||||
tt_int_op(mkdir(options->DataDirectory), ==, 0);
|
||||
tt_int_op(mkdir(options->DataDirectory), OP_EQ, 0);
|
||||
#else
|
||||
tt_int_op(mkdir(options->DataDirectory, 0700), ==, 0);
|
||||
tt_int_op(mkdir(options->DataDirectory, 0700), OP_EQ, 0);
|
||||
#endif
|
||||
|
||||
r = stat(subpath, &st);
|
||||
@@ -285,9 +287,9 @@ test_config_write_to_data_subdir(void *arg)
|
||||
filepath = get_datadir_fname2(subdir, fname);
|
||||
|
||||
#if defined (_WIN32)
|
||||
tt_int_op(mkdir(options->DataDirectory), ==, 0);
|
||||
tt_int_op(mkdir(options->DataDirectory), OP_EQ, 0);
|
||||
#else
|
||||
tt_int_op(mkdir(options->DataDirectory, 0700), ==, 0);
|
||||
tt_int_op(mkdir(options->DataDirectory, 0700), OP_EQ, 0);
|
||||
#endif
|
||||
|
||||
// Write attempt shoudl fail, if subdirectory doesn't exist.
|
||||
@@ -298,13 +300,13 @@ test_config_write_to_data_subdir(void *arg)
|
||||
// equal to the original string.
|
||||
tt_assert(!write_to_data_subdir(subdir, fname, str, NULL));
|
||||
cp = read_file_to_str(filepath, 0, NULL);
|
||||
tt_str_op(cp,==, str);
|
||||
tt_str_op(cp,OP_EQ, str);
|
||||
tor_free(cp);
|
||||
|
||||
// A second write operation should overwrite the old content.
|
||||
tt_assert(!write_to_data_subdir(subdir, fname, str, NULL));
|
||||
cp = read_file_to_str(filepath, 0, NULL);
|
||||
tt_str_op(cp,==, str);
|
||||
tt_str_op(cp,OP_EQ, str);
|
||||
tor_free(cp);
|
||||
|
||||
done:
|
||||
@@ -329,7 +331,7 @@ good_bridge_line_test(const char *string, const char *test_addrport,
|
||||
|
||||
/* test addrport */
|
||||
tmp = tor_strdup(fmt_addrport(&bridge_line->addr, bridge_line->port));
|
||||
tt_str_op(test_addrport,==, tmp);
|
||||
tt_str_op(test_addrport,OP_EQ, tmp);
|
||||
tor_free(tmp);
|
||||
|
||||
/* If we were asked to validate a digest, but we did not get a
|
||||
@@ -347,7 +349,7 @@ good_bridge_line_test(const char *string, const char *test_addrport,
|
||||
if (test_digest) {
|
||||
tmp = tor_strdup(hex_str(bridge_line->digest, DIGEST_LEN));
|
||||
tor_strlower(tmp);
|
||||
tt_str_op(test_digest,==, tmp);
|
||||
tt_str_op(test_digest,OP_EQ, tmp);
|
||||
tor_free(tmp);
|
||||
}
|
||||
|
||||
@@ -358,7 +360,7 @@ good_bridge_line_test(const char *string, const char *test_addrport,
|
||||
if (!test_transport && bridge_line->transport_name)
|
||||
tt_assert(0);
|
||||
if (test_transport)
|
||||
tt_str_op(test_transport,==, bridge_line->transport_name);
|
||||
tt_str_op(test_transport,OP_EQ, bridge_line->transport_name);
|
||||
|
||||
/* Validate the SOCKS argument smartlist. */
|
||||
if (test_socks_args && !bridge_line->socks_args)
|
||||
@@ -552,6 +554,267 @@ test_config_parse_transport_options_line(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
/* Mocks needed for the transport plugin line test */
|
||||
|
||||
static void pt_kickstart_proxy_mock(const smartlist_t *transport_list,
|
||||
char **proxy_argv, int is_server);
|
||||
static int transport_add_from_config_mock(const tor_addr_t *addr,
|
||||
uint16_t port, const char *name,
|
||||
int socks_ver);
|
||||
static int transport_is_needed_mock(const char *transport_name);
|
||||
|
||||
static int pt_kickstart_proxy_mock_call_count = 0;
|
||||
static int transport_add_from_config_mock_call_count = 0;
|
||||
static int transport_is_needed_mock_call_count = 0;
|
||||
static int transport_is_needed_mock_return = 0;
|
||||
|
||||
static void
|
||||
pt_kickstart_proxy_mock(const smartlist_t *transport_list,
|
||||
char **proxy_argv, int is_server)
|
||||
{
|
||||
(void) transport_list;
|
||||
(void) proxy_argv;
|
||||
(void) is_server;
|
||||
/* XXXX check that args are as expected. */
|
||||
|
||||
++pt_kickstart_proxy_mock_call_count;
|
||||
}
|
||||
|
||||
static int
|
||||
transport_add_from_config_mock(const tor_addr_t *addr,
|
||||
uint16_t port, const char *name,
|
||||
int socks_ver)
|
||||
{
|
||||
(void) addr;
|
||||
(void) port;
|
||||
(void) name;
|
||||
(void) socks_ver;
|
||||
/* XXXX check that args are as expected. */
|
||||
|
||||
++transport_add_from_config_mock_call_count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
transport_is_needed_mock(const char *transport_name)
|
||||
{
|
||||
(void) transport_name;
|
||||
/* XXXX check that arg is as expected. */
|
||||
|
||||
++transport_is_needed_mock_call_count;
|
||||
|
||||
return transport_is_needed_mock_return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing for the ClientTransportPlugin and ServerTransportPlugin config
|
||||
* options.
|
||||
*/
|
||||
|
||||
static void
|
||||
test_config_parse_transport_plugin_line(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
or_options_t *options = get_options_mutable();
|
||||
int r, tmp;
|
||||
int old_pt_kickstart_proxy_mock_call_count;
|
||||
int old_transport_add_from_config_mock_call_count;
|
||||
int old_transport_is_needed_mock_call_count;
|
||||
|
||||
/* Bad transport lines - too short */
|
||||
r = parse_transport_line(options, "bad", 1, 0);
|
||||
tt_assert(r < 0);
|
||||
r = parse_transport_line(options, "bad", 1, 1);
|
||||
tt_assert(r < 0);
|
||||
r = parse_transport_line(options, "bad bad", 1, 0);
|
||||
tt_assert(r < 0);
|
||||
r = parse_transport_line(options, "bad bad", 1, 1);
|
||||
tt_assert(r < 0);
|
||||
|
||||
/* Test transport list parsing */
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 exec /usr/bin/fake-transport", 1, 0);
|
||||
tt_assert(r == 0);
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 exec /usr/bin/fake-transport", 1, 1);
|
||||
tt_assert(r == 0);
|
||||
r = parse_transport_line(options,
|
||||
"transport_1,transport_2 exec /usr/bin/fake-transport", 1, 0);
|
||||
tt_assert(r == 0);
|
||||
r = parse_transport_line(options,
|
||||
"transport_1,transport_2 exec /usr/bin/fake-transport", 1, 1);
|
||||
tt_assert(r == 0);
|
||||
/* Bad transport identifiers */
|
||||
r = parse_transport_line(options,
|
||||
"transport_* exec /usr/bin/fake-transport", 1, 0);
|
||||
tt_assert(r < 0);
|
||||
r = parse_transport_line(options,
|
||||
"transport_* exec /usr/bin/fake-transport", 1, 1);
|
||||
tt_assert(r < 0);
|
||||
|
||||
/* Check SOCKS cases for client transport */
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 socks4 1.2.3.4:567", 1, 0);
|
||||
tt_assert(r == 0);
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 socks5 1.2.3.4:567", 1, 0);
|
||||
tt_assert(r == 0);
|
||||
/* Proxy case for server transport */
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 proxy 1.2.3.4:567", 1, 1);
|
||||
tt_assert(r == 0);
|
||||
/* Multiple-transport error exit */
|
||||
r = parse_transport_line(options,
|
||||
"transport_1,transport_2 socks5 1.2.3.4:567", 1, 0);
|
||||
tt_assert(r < 0);
|
||||
r = parse_transport_line(options,
|
||||
"transport_1,transport_2 proxy 1.2.3.4:567", 1, 1);
|
||||
/* No port error exit */
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 socks5 1.2.3.4", 1, 0);
|
||||
tt_assert(r < 0);
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 proxy 1.2.3.4", 1, 1);
|
||||
tt_assert(r < 0);
|
||||
/* Unparsable address error exit */
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 socks5 1.2.3:6x7", 1, 0);
|
||||
tt_assert(r < 0);
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 proxy 1.2.3:6x7", 1, 1);
|
||||
tt_assert(r < 0);
|
||||
|
||||
/* "Strange {Client|Server}TransportPlugin field" error exit */
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 foo bar", 1, 0);
|
||||
tt_assert(r < 0);
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 foo bar", 1, 1);
|
||||
tt_assert(r < 0);
|
||||
|
||||
/* No sandbox mode error exit */
|
||||
tmp = options->Sandbox;
|
||||
options->Sandbox = 1;
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 exec /usr/bin/fake-transport", 1, 0);
|
||||
tt_assert(r < 0);
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 exec /usr/bin/fake-transport", 1, 1);
|
||||
tt_assert(r < 0);
|
||||
options->Sandbox = tmp;
|
||||
|
||||
/*
|
||||
* These final test cases cover code paths that only activate without
|
||||
* validate_only, so they need mocks in place.
|
||||
*/
|
||||
MOCK(pt_kickstart_proxy, pt_kickstart_proxy_mock);
|
||||
old_pt_kickstart_proxy_mock_call_count =
|
||||
pt_kickstart_proxy_mock_call_count;
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 exec /usr/bin/fake-transport", 0, 1);
|
||||
tt_assert(r == 0);
|
||||
tt_assert(pt_kickstart_proxy_mock_call_count ==
|
||||
old_pt_kickstart_proxy_mock_call_count + 1);
|
||||
UNMOCK(pt_kickstart_proxy);
|
||||
|
||||
/* This one hits a log line in the !validate_only case only */
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 proxy 1.2.3.4:567", 0, 1);
|
||||
tt_assert(r == 0);
|
||||
|
||||
/* Check mocked client transport cases */
|
||||
MOCK(pt_kickstart_proxy, pt_kickstart_proxy_mock);
|
||||
MOCK(transport_add_from_config, transport_add_from_config_mock);
|
||||
MOCK(transport_is_needed, transport_is_needed_mock);
|
||||
|
||||
/* Unnecessary transport case */
|
||||
transport_is_needed_mock_return = 0;
|
||||
old_pt_kickstart_proxy_mock_call_count =
|
||||
pt_kickstart_proxy_mock_call_count;
|
||||
old_transport_add_from_config_mock_call_count =
|
||||
transport_add_from_config_mock_call_count;
|
||||
old_transport_is_needed_mock_call_count =
|
||||
transport_is_needed_mock_call_count;
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 exec /usr/bin/fake-transport", 0, 0);
|
||||
/* Should have succeeded */
|
||||
tt_assert(r == 0);
|
||||
/* transport_is_needed() should have been called */
|
||||
tt_assert(transport_is_needed_mock_call_count ==
|
||||
old_transport_is_needed_mock_call_count + 1);
|
||||
/*
|
||||
* pt_kickstart_proxy() and transport_add_from_config() should
|
||||
* not have been called.
|
||||
*/
|
||||
tt_assert(pt_kickstart_proxy_mock_call_count ==
|
||||
old_pt_kickstart_proxy_mock_call_count);
|
||||
tt_assert(transport_add_from_config_mock_call_count ==
|
||||
old_transport_add_from_config_mock_call_count);
|
||||
|
||||
/* Necessary transport case */
|
||||
transport_is_needed_mock_return = 1;
|
||||
old_pt_kickstart_proxy_mock_call_count =
|
||||
pt_kickstart_proxy_mock_call_count;
|
||||
old_transport_add_from_config_mock_call_count =
|
||||
transport_add_from_config_mock_call_count;
|
||||
old_transport_is_needed_mock_call_count =
|
||||
transport_is_needed_mock_call_count;
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 exec /usr/bin/fake-transport", 0, 0);
|
||||
/* Should have succeeded */
|
||||
tt_assert(r == 0);
|
||||
/*
|
||||
* transport_is_needed() and pt_kickstart_proxy() should have been
|
||||
* called.
|
||||
*/
|
||||
tt_assert(pt_kickstart_proxy_mock_call_count ==
|
||||
old_pt_kickstart_proxy_mock_call_count + 1);
|
||||
tt_assert(transport_is_needed_mock_call_count ==
|
||||
old_transport_is_needed_mock_call_count + 1);
|
||||
/* transport_add_from_config() should not have been called. */
|
||||
tt_assert(transport_add_from_config_mock_call_count ==
|
||||
old_transport_add_from_config_mock_call_count);
|
||||
|
||||
/* proxy case */
|
||||
transport_is_needed_mock_return = 1;
|
||||
old_pt_kickstart_proxy_mock_call_count =
|
||||
pt_kickstart_proxy_mock_call_count;
|
||||
old_transport_add_from_config_mock_call_count =
|
||||
transport_add_from_config_mock_call_count;
|
||||
old_transport_is_needed_mock_call_count =
|
||||
transport_is_needed_mock_call_count;
|
||||
r = parse_transport_line(options,
|
||||
"transport_1 socks5 1.2.3.4:567", 0, 0);
|
||||
/* Should have succeeded */
|
||||
tt_assert(r == 0);
|
||||
/*
|
||||
* transport_is_needed() and transport_add_from_config() should have
|
||||
* been called.
|
||||
*/
|
||||
tt_assert(transport_add_from_config_mock_call_count ==
|
||||
old_transport_add_from_config_mock_call_count + 1);
|
||||
tt_assert(transport_is_needed_mock_call_count ==
|
||||
old_transport_is_needed_mock_call_count + 1);
|
||||
/* pt_kickstart_proxy() should not have been called. */
|
||||
tt_assert(pt_kickstart_proxy_mock_call_count ==
|
||||
old_pt_kickstart_proxy_mock_call_count);
|
||||
|
||||
/* Done with mocked client transport cases */
|
||||
UNMOCK(transport_is_needed);
|
||||
UNMOCK(transport_add_from_config);
|
||||
UNMOCK(pt_kickstart_proxy);
|
||||
|
||||
done:
|
||||
/* Make sure we undo all mocks */
|
||||
UNMOCK(pt_kickstart_proxy);
|
||||
UNMOCK(transport_add_from_config);
|
||||
UNMOCK(transport_is_needed);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Tests if an options with MyFamily fingerprints missing '$' normalises
|
||||
// them correctly and also ensure it also works with multiple fingerprints
|
||||
static void
|
||||
@@ -576,7 +839,8 @@ test_config_fix_my_family(void *arg)
|
||||
TT_FAIL(("options_validate failed: %s", err));
|
||||
}
|
||||
|
||||
tt_str_op(options->MyFamily,==, "$1111111111111111111111111111111111111111, "
|
||||
tt_str_op(options->MyFamily,OP_EQ,
|
||||
"$1111111111111111111111111111111111111111, "
|
||||
"$1111111111111111111111111111111111111112, "
|
||||
"$1111111111111111111111111111111111111113");
|
||||
|
||||
@@ -596,6 +860,7 @@ struct testcase_t config_tests[] = {
|
||||
CONFIG_TEST(addressmap, 0),
|
||||
CONFIG_TEST(parse_bridge_line, 0),
|
||||
CONFIG_TEST(parse_transport_options_line, 0),
|
||||
CONFIG_TEST(parse_transport_plugin_line, TT_FORK),
|
||||
CONFIG_TEST(check_or_create_data_subdir, TT_FORK),
|
||||
CONFIG_TEST(write_to_data_subdir, TT_FORK),
|
||||
CONFIG_TEST(fix_my_family, 0),
|
||||
|
||||
+198
-193
@@ -62,18 +62,18 @@ test_container_smartlist_basic(void *arg)
|
||||
smartlist_insert(sl, 1, v22);
|
||||
smartlist_insert(sl, 0, v0);
|
||||
smartlist_insert(sl, 5, v555);
|
||||
tt_ptr_op(v0,==, smartlist_get(sl,0));
|
||||
tt_ptr_op(v1,==, smartlist_get(sl,1));
|
||||
tt_ptr_op(v22,==, smartlist_get(sl,2));
|
||||
tt_ptr_op(v3,==, smartlist_get(sl,3));
|
||||
tt_ptr_op(v4,==, smartlist_get(sl,4));
|
||||
tt_ptr_op(v555,==, smartlist_get(sl,5));
|
||||
tt_ptr_op(v0,OP_EQ, smartlist_get(sl,0));
|
||||
tt_ptr_op(v1,OP_EQ, smartlist_get(sl,1));
|
||||
tt_ptr_op(v22,OP_EQ, smartlist_get(sl,2));
|
||||
tt_ptr_op(v3,OP_EQ, smartlist_get(sl,3));
|
||||
tt_ptr_op(v4,OP_EQ, smartlist_get(sl,4));
|
||||
tt_ptr_op(v555,OP_EQ, smartlist_get(sl,5));
|
||||
/* Try deleting in the middle. */
|
||||
smartlist_del(sl, 1);
|
||||
tt_ptr_op(v555,==, smartlist_get(sl, 1));
|
||||
tt_ptr_op(v555,OP_EQ, smartlist_get(sl, 1));
|
||||
/* Try deleting at the end. */
|
||||
smartlist_del(sl, 4);
|
||||
tt_int_op(4,==, smartlist_len(sl));
|
||||
tt_int_op(4,OP_EQ, smartlist_len(sl));
|
||||
|
||||
/* test isin. */
|
||||
tt_assert(smartlist_contains(sl, v3));
|
||||
@@ -101,119 +101,119 @@ test_container_smartlist_strings(void *arg)
|
||||
|
||||
/* Test split and join */
|
||||
(void)arg;
|
||||
tt_int_op(0,==, smartlist_len(sl));
|
||||
tt_int_op(0,OP_EQ, smartlist_len(sl));
|
||||
smartlist_split_string(sl, "abc", ":", 0, 0);
|
||||
tt_int_op(1,==, smartlist_len(sl));
|
||||
tt_str_op("abc",==, smartlist_get(sl, 0));
|
||||
tt_int_op(1,OP_EQ, smartlist_len(sl));
|
||||
tt_str_op("abc",OP_EQ, smartlist_get(sl, 0));
|
||||
smartlist_split_string(sl, "a::bc::", "::", 0, 0);
|
||||
tt_int_op(4,==, smartlist_len(sl));
|
||||
tt_str_op("a",==, smartlist_get(sl, 1));
|
||||
tt_str_op("bc",==, smartlist_get(sl, 2));
|
||||
tt_str_op("",==, smartlist_get(sl, 3));
|
||||
tt_int_op(4,OP_EQ, smartlist_len(sl));
|
||||
tt_str_op("a",OP_EQ, smartlist_get(sl, 1));
|
||||
tt_str_op("bc",OP_EQ, smartlist_get(sl, 2));
|
||||
tt_str_op("",OP_EQ, smartlist_get(sl, 3));
|
||||
cp_alloc = smartlist_join_strings(sl, "", 0, NULL);
|
||||
tt_str_op(cp_alloc,==, "abcabc");
|
||||
tt_str_op(cp_alloc,OP_EQ, "abcabc");
|
||||
tor_free(cp_alloc);
|
||||
cp_alloc = smartlist_join_strings(sl, "!", 0, NULL);
|
||||
tt_str_op(cp_alloc,==, "abc!a!bc!");
|
||||
tt_str_op(cp_alloc,OP_EQ, "abc!a!bc!");
|
||||
tor_free(cp_alloc);
|
||||
cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
|
||||
tt_str_op(cp_alloc,==, "abcXYaXYbcXY");
|
||||
tt_str_op(cp_alloc,OP_EQ, "abcXYaXYbcXY");
|
||||
tor_free(cp_alloc);
|
||||
cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
|
||||
tt_str_op(cp_alloc,==, "abcXYaXYbcXYXY");
|
||||
tt_str_op(cp_alloc,OP_EQ, "abcXYaXYbcXYXY");
|
||||
tor_free(cp_alloc);
|
||||
cp_alloc = smartlist_join_strings(sl, "", 1, NULL);
|
||||
tt_str_op(cp_alloc,==, "abcabc");
|
||||
tt_str_op(cp_alloc,OP_EQ, "abcabc");
|
||||
tor_free(cp_alloc);
|
||||
|
||||
smartlist_split_string(sl, "/def/ /ghijk", "/", 0, 0);
|
||||
tt_int_op(8,==, smartlist_len(sl));
|
||||
tt_str_op("",==, smartlist_get(sl, 4));
|
||||
tt_str_op("def",==, smartlist_get(sl, 5));
|
||||
tt_str_op(" ",==, smartlist_get(sl, 6));
|
||||
tt_str_op("ghijk",==, smartlist_get(sl, 7));
|
||||
tt_int_op(8,OP_EQ, smartlist_len(sl));
|
||||
tt_str_op("",OP_EQ, smartlist_get(sl, 4));
|
||||
tt_str_op("def",OP_EQ, smartlist_get(sl, 5));
|
||||
tt_str_op(" ",OP_EQ, smartlist_get(sl, 6));
|
||||
tt_str_op("ghijk",OP_EQ, smartlist_get(sl, 7));
|
||||
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
|
||||
smartlist_clear(sl);
|
||||
|
||||
smartlist_split_string(sl, "a,bbd,cdef", ",", SPLIT_SKIP_SPACE, 0);
|
||||
tt_int_op(3,==, smartlist_len(sl));
|
||||
tt_str_op("a",==, smartlist_get(sl,0));
|
||||
tt_str_op("bbd",==, smartlist_get(sl,1));
|
||||
tt_str_op("cdef",==, smartlist_get(sl,2));
|
||||
tt_int_op(3,OP_EQ, smartlist_len(sl));
|
||||
tt_str_op("a",OP_EQ, smartlist_get(sl,0));
|
||||
tt_str_op("bbd",OP_EQ, smartlist_get(sl,1));
|
||||
tt_str_op("cdef",OP_EQ, smartlist_get(sl,2));
|
||||
smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
|
||||
SPLIT_SKIP_SPACE, 0);
|
||||
tt_int_op(8,==, smartlist_len(sl));
|
||||
tt_str_op("z",==, smartlist_get(sl,3));
|
||||
tt_str_op("zhasd",==, smartlist_get(sl,4));
|
||||
tt_str_op("",==, smartlist_get(sl,5));
|
||||
tt_str_op("bnud",==, smartlist_get(sl,6));
|
||||
tt_str_op("",==, smartlist_get(sl,7));
|
||||
tt_int_op(8,OP_EQ, smartlist_len(sl));
|
||||
tt_str_op("z",OP_EQ, smartlist_get(sl,3));
|
||||
tt_str_op("zhasd",OP_EQ, smartlist_get(sl,4));
|
||||
tt_str_op("",OP_EQ, smartlist_get(sl,5));
|
||||
tt_str_op("bnud",OP_EQ, smartlist_get(sl,6));
|
||||
tt_str_op("",OP_EQ, smartlist_get(sl,7));
|
||||
|
||||
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
|
||||
smartlist_clear(sl);
|
||||
|
||||
smartlist_split_string(sl, " ab\tc \td ef ", NULL,
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
||||
tt_int_op(4,==, smartlist_len(sl));
|
||||
tt_str_op("ab",==, smartlist_get(sl,0));
|
||||
tt_str_op("c",==, smartlist_get(sl,1));
|
||||
tt_str_op("d",==, smartlist_get(sl,2));
|
||||
tt_str_op("ef",==, smartlist_get(sl,3));
|
||||
tt_int_op(4,OP_EQ, smartlist_len(sl));
|
||||
tt_str_op("ab",OP_EQ, smartlist_get(sl,0));
|
||||
tt_str_op("c",OP_EQ, smartlist_get(sl,1));
|
||||
tt_str_op("d",OP_EQ, smartlist_get(sl,2));
|
||||
tt_str_op("ef",OP_EQ, smartlist_get(sl,3));
|
||||
smartlist_split_string(sl, "ghi\tj", NULL,
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
||||
tt_int_op(6,==, smartlist_len(sl));
|
||||
tt_str_op("ghi",==, smartlist_get(sl,4));
|
||||
tt_str_op("j",==, smartlist_get(sl,5));
|
||||
tt_int_op(6,OP_EQ, smartlist_len(sl));
|
||||
tt_str_op("ghi",OP_EQ, smartlist_get(sl,4));
|
||||
tt_str_op("j",OP_EQ, smartlist_get(sl,5));
|
||||
|
||||
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
|
||||
smartlist_clear(sl);
|
||||
|
||||
cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
|
||||
tt_str_op(cp_alloc,==, "");
|
||||
tt_str_op(cp_alloc,OP_EQ, "");
|
||||
tor_free(cp_alloc);
|
||||
cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
|
||||
tt_str_op(cp_alloc,==, "XY");
|
||||
tt_str_op(cp_alloc,OP_EQ, "XY");
|
||||
tor_free(cp_alloc);
|
||||
|
||||
smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
||||
tt_int_op(3,==, smartlist_len(sl));
|
||||
tt_str_op("z",==, smartlist_get(sl, 0));
|
||||
tt_str_op("zhasd",==, smartlist_get(sl, 1));
|
||||
tt_str_op("bnud",==, smartlist_get(sl, 2));
|
||||
tt_int_op(3,OP_EQ, smartlist_len(sl));
|
||||
tt_str_op("z",OP_EQ, smartlist_get(sl, 0));
|
||||
tt_str_op("zhasd",OP_EQ, smartlist_get(sl, 1));
|
||||
tt_str_op("bnud",OP_EQ, smartlist_get(sl, 2));
|
||||
smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>",
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
|
||||
tt_int_op(5,==, smartlist_len(sl));
|
||||
tt_str_op("z",==, smartlist_get(sl, 3));
|
||||
tt_str_op("zhasd <> <> bnud<>",==, smartlist_get(sl, 4));
|
||||
tt_int_op(5,OP_EQ, smartlist_len(sl));
|
||||
tt_str_op("z",OP_EQ, smartlist_get(sl, 3));
|
||||
tt_str_op("zhasd <> <> bnud<>",OP_EQ, smartlist_get(sl, 4));
|
||||
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
|
||||
smartlist_clear(sl);
|
||||
|
||||
smartlist_split_string(sl, "abcd\n", "\n",
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
||||
tt_int_op(1,==, smartlist_len(sl));
|
||||
tt_str_op("abcd",==, smartlist_get(sl, 0));
|
||||
tt_int_op(1,OP_EQ, smartlist_len(sl));
|
||||
tt_str_op("abcd",OP_EQ, smartlist_get(sl, 0));
|
||||
smartlist_split_string(sl, "efgh", "\n",
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
||||
tt_int_op(2,==, smartlist_len(sl));
|
||||
tt_str_op("efgh",==, smartlist_get(sl, 1));
|
||||
tt_int_op(2,OP_EQ, smartlist_len(sl));
|
||||
tt_str_op("efgh",OP_EQ, smartlist_get(sl, 1));
|
||||
|
||||
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
|
||||
smartlist_clear(sl);
|
||||
|
||||
/* Test swapping, shuffling, and sorting. */
|
||||
smartlist_split_string(sl, "the,onion,router,by,arma,and,nickm", ",", 0, 0);
|
||||
tt_int_op(7,==, smartlist_len(sl));
|
||||
tt_int_op(7,OP_EQ, smartlist_len(sl));
|
||||
smartlist_sort(sl, compare_strs_);
|
||||
cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
|
||||
tt_str_op(cp_alloc,==, "and,arma,by,nickm,onion,router,the");
|
||||
tt_str_op(cp_alloc,OP_EQ, "and,arma,by,nickm,onion,router,the");
|
||||
tor_free(cp_alloc);
|
||||
smartlist_swap(sl, 1, 5);
|
||||
cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
|
||||
tt_str_op(cp_alloc,==, "and,router,by,nickm,onion,arma,the");
|
||||
tt_str_op(cp_alloc,OP_EQ, "and,router,by,nickm,onion,arma,the");
|
||||
tor_free(cp_alloc);
|
||||
smartlist_shuffle(sl);
|
||||
tt_int_op(7,==, smartlist_len(sl));
|
||||
tt_int_op(7,OP_EQ, smartlist_len(sl));
|
||||
tt_assert(smartlist_contains_string(sl, "and"));
|
||||
tt_assert(smartlist_contains_string(sl, "router"));
|
||||
tt_assert(smartlist_contains_string(sl, "by"));
|
||||
@@ -224,69 +224,72 @@ test_container_smartlist_strings(void *arg)
|
||||
|
||||
/* Test bsearch. */
|
||||
smartlist_sort(sl, compare_strs_);
|
||||
tt_str_op("nickm",==, smartlist_bsearch(sl, "zNicKM",
|
||||
tt_str_op("nickm",OP_EQ, smartlist_bsearch(sl, "zNicKM",
|
||||
cmp_without_first_));
|
||||
tt_str_op("and",==,
|
||||
tt_str_op("and",OP_EQ,
|
||||
smartlist_bsearch(sl, " AND", cmp_without_first_));
|
||||
tt_ptr_op(NULL,==, smartlist_bsearch(sl, " ANz", cmp_without_first_));
|
||||
tt_ptr_op(NULL,OP_EQ, smartlist_bsearch(sl, " ANz", cmp_without_first_));
|
||||
|
||||
/* Test bsearch_idx */
|
||||
{
|
||||
int f;
|
||||
smartlist_t *tmp = NULL;
|
||||
|
||||
tt_int_op(0,==,smartlist_bsearch_idx(sl," aaa",cmp_without_first_,&f));
|
||||
tt_int_op(f,==, 0);
|
||||
tt_int_op(0,==, smartlist_bsearch_idx(sl," and",cmp_without_first_,&f));
|
||||
tt_int_op(f,==, 1);
|
||||
tt_int_op(1,==, smartlist_bsearch_idx(sl," arm",cmp_without_first_,&f));
|
||||
tt_int_op(f,==, 0);
|
||||
tt_int_op(1,==, smartlist_bsearch_idx(sl," arma",cmp_without_first_,&f));
|
||||
tt_int_op(f,==, 1);
|
||||
tt_int_op(2,==, smartlist_bsearch_idx(sl," armb",cmp_without_first_,&f));
|
||||
tt_int_op(f,==, 0);
|
||||
tt_int_op(7,==, smartlist_bsearch_idx(sl," zzzz",cmp_without_first_,&f));
|
||||
tt_int_op(f,==, 0);
|
||||
tt_int_op(0,OP_EQ,smartlist_bsearch_idx(sl," aaa",cmp_without_first_,&f));
|
||||
tt_int_op(f,OP_EQ, 0);
|
||||
tt_int_op(0,OP_EQ, smartlist_bsearch_idx(sl," and",cmp_without_first_,&f));
|
||||
tt_int_op(f,OP_EQ, 1);
|
||||
tt_int_op(1,OP_EQ, smartlist_bsearch_idx(sl," arm",cmp_without_first_,&f));
|
||||
tt_int_op(f,OP_EQ, 0);
|
||||
tt_int_op(1,OP_EQ,
|
||||
smartlist_bsearch_idx(sl," arma",cmp_without_first_,&f));
|
||||
tt_int_op(f,OP_EQ, 1);
|
||||
tt_int_op(2,OP_EQ,
|
||||
smartlist_bsearch_idx(sl," armb",cmp_without_first_,&f));
|
||||
tt_int_op(f,OP_EQ, 0);
|
||||
tt_int_op(7,OP_EQ,
|
||||
smartlist_bsearch_idx(sl," zzzz",cmp_without_first_,&f));
|
||||
tt_int_op(f,OP_EQ, 0);
|
||||
|
||||
/* Test trivial cases for list of length 0 or 1 */
|
||||
tmp = smartlist_new();
|
||||
tt_int_op(0,==, smartlist_bsearch_idx(tmp, "foo",
|
||||
tt_int_op(0,OP_EQ, smartlist_bsearch_idx(tmp, "foo",
|
||||
compare_strs_for_bsearch_, &f));
|
||||
tt_int_op(f,==, 0);
|
||||
tt_int_op(f,OP_EQ, 0);
|
||||
smartlist_insert(tmp, 0, (void *)("bar"));
|
||||
tt_int_op(1,==, smartlist_bsearch_idx(tmp, "foo",
|
||||
tt_int_op(1,OP_EQ, smartlist_bsearch_idx(tmp, "foo",
|
||||
compare_strs_for_bsearch_, &f));
|
||||
tt_int_op(f,==, 0);
|
||||
tt_int_op(0,==, smartlist_bsearch_idx(tmp, "aaa",
|
||||
tt_int_op(f,OP_EQ, 0);
|
||||
tt_int_op(0,OP_EQ, smartlist_bsearch_idx(tmp, "aaa",
|
||||
compare_strs_for_bsearch_, &f));
|
||||
tt_int_op(f,==, 0);
|
||||
tt_int_op(0,==, smartlist_bsearch_idx(tmp, "bar",
|
||||
tt_int_op(f,OP_EQ, 0);
|
||||
tt_int_op(0,OP_EQ, smartlist_bsearch_idx(tmp, "bar",
|
||||
compare_strs_for_bsearch_, &f));
|
||||
tt_int_op(f,==, 1);
|
||||
tt_int_op(f,OP_EQ, 1);
|
||||
/* ... and one for length 2 */
|
||||
smartlist_insert(tmp, 1, (void *)("foo"));
|
||||
tt_int_op(1,==, smartlist_bsearch_idx(tmp, "foo",
|
||||
tt_int_op(1,OP_EQ, smartlist_bsearch_idx(tmp, "foo",
|
||||
compare_strs_for_bsearch_, &f));
|
||||
tt_int_op(f,==, 1);
|
||||
tt_int_op(2,==, smartlist_bsearch_idx(tmp, "goo",
|
||||
tt_int_op(f,OP_EQ, 1);
|
||||
tt_int_op(2,OP_EQ, smartlist_bsearch_idx(tmp, "goo",
|
||||
compare_strs_for_bsearch_, &f));
|
||||
tt_int_op(f,==, 0);
|
||||
tt_int_op(f,OP_EQ, 0);
|
||||
smartlist_free(tmp);
|
||||
}
|
||||
|
||||
/* Test reverse() and pop_last() */
|
||||
smartlist_reverse(sl);
|
||||
cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
|
||||
tt_str_op(cp_alloc,==, "the,router,onion,nickm,by,arma,and");
|
||||
tt_str_op(cp_alloc,OP_EQ, "the,router,onion,nickm,by,arma,and");
|
||||
tor_free(cp_alloc);
|
||||
cp_alloc = smartlist_pop_last(sl);
|
||||
tt_str_op(cp_alloc,==, "and");
|
||||
tt_str_op(cp_alloc,OP_EQ, "and");
|
||||
tor_free(cp_alloc);
|
||||
tt_int_op(smartlist_len(sl),==, 6);
|
||||
tt_int_op(smartlist_len(sl),OP_EQ, 6);
|
||||
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
|
||||
smartlist_clear(sl);
|
||||
cp_alloc = smartlist_pop_last(sl);
|
||||
tt_ptr_op(cp_alloc,==, NULL);
|
||||
tt_ptr_op(cp_alloc,OP_EQ, NULL);
|
||||
|
||||
/* Test uniq() */
|
||||
smartlist_split_string(sl,
|
||||
@@ -295,7 +298,7 @@ test_container_smartlist_strings(void *arg)
|
||||
smartlist_sort(sl, compare_strs_);
|
||||
smartlist_uniq(sl, compare_strs_, tor_free_);
|
||||
cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
|
||||
tt_str_op(cp_alloc,==, "50,a,canal,man,noon,panama,plan,radar");
|
||||
tt_str_op(cp_alloc,OP_EQ, "50,a,canal,man,noon,panama,plan,radar");
|
||||
tor_free(cp_alloc);
|
||||
|
||||
/* Test contains_string, contains_string_case and contains_int_as_string */
|
||||
@@ -331,17 +334,17 @@ test_container_smartlist_strings(void *arg)
|
||||
"Some say the Earth will end in ice and some in fire",
|
||||
" ", 0, 0);
|
||||
cp = smartlist_get(sl, 4);
|
||||
tt_str_op(cp,==, "will");
|
||||
tt_str_op(cp,OP_EQ, "will");
|
||||
smartlist_add(sl, cp);
|
||||
smartlist_remove(sl, cp);
|
||||
tor_free(cp);
|
||||
cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
|
||||
tt_str_op(cp_alloc,==, "Some,say,the,Earth,fire,end,in,ice,and,some,in");
|
||||
tt_str_op(cp_alloc,OP_EQ, "Some,say,the,Earth,fire,end,in,ice,and,some,in");
|
||||
tor_free(cp_alloc);
|
||||
smartlist_string_remove(sl, "in");
|
||||
cp_alloc = smartlist_join_strings2(sl, "+XX", 1, 0, &sz);
|
||||
tt_str_op(cp_alloc,==, "Some+say+the+Earth+fire+end+some+ice+and");
|
||||
tt_int_op((int)sz,==, 40);
|
||||
tt_str_op(cp_alloc,OP_EQ, "Some+say+the+Earth+fire+end+some+ice+and");
|
||||
tt_int_op((int)sz,OP_EQ, 40);
|
||||
|
||||
done:
|
||||
|
||||
@@ -369,7 +372,7 @@ test_container_smartlist_overlap(void *arg)
|
||||
/* add_all */
|
||||
smartlist_add_all(ints, odds);
|
||||
smartlist_add_all(ints, evens);
|
||||
tt_int_op(smartlist_len(ints),==, 10);
|
||||
tt_int_op(smartlist_len(ints),OP_EQ, 10);
|
||||
|
||||
smartlist_add(primes, (void*)2);
|
||||
smartlist_add(primes, (void*)3);
|
||||
@@ -385,7 +388,7 @@ test_container_smartlist_overlap(void *arg)
|
||||
/* intersect */
|
||||
smartlist_add_all(sl, odds);
|
||||
smartlist_intersect(sl, primes);
|
||||
tt_int_op(smartlist_len(sl),==, 3);
|
||||
tt_int_op(smartlist_len(sl),OP_EQ, 3);
|
||||
tt_assert(smartlist_contains(sl, (void*)3));
|
||||
tt_assert(smartlist_contains(sl, (void*)5));
|
||||
tt_assert(smartlist_contains(sl, (void*)7));
|
||||
@@ -393,7 +396,7 @@ test_container_smartlist_overlap(void *arg)
|
||||
/* subtract */
|
||||
smartlist_add_all(sl, primes);
|
||||
smartlist_subtract(sl, odds);
|
||||
tt_int_op(smartlist_len(sl),==, 1);
|
||||
tt_int_op(smartlist_len(sl),OP_EQ, 1);
|
||||
tt_assert(smartlist_contains(sl, (void*)2));
|
||||
|
||||
done:
|
||||
@@ -415,23 +418,23 @@ test_container_smartlist_digests(void *arg)
|
||||
smartlist_add(sl, tor_memdup("AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN));
|
||||
smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN));
|
||||
smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN));
|
||||
tt_int_op(0,==, smartlist_contains_digest(NULL, "AAAAAAAAAAAAAAAAAAAA"));
|
||||
tt_int_op(0,OP_EQ, smartlist_contains_digest(NULL, "AAAAAAAAAAAAAAAAAAAA"));
|
||||
tt_assert(smartlist_contains_digest(sl, "AAAAAAAAAAAAAAAAAAAA"));
|
||||
tt_assert(smartlist_contains_digest(sl, "\00090AAB2AAAAaasdAAAAA"));
|
||||
tt_int_op(0,==, smartlist_contains_digest(sl, "\00090AAB2AAABaasdAAAAA"));
|
||||
tt_int_op(0,OP_EQ, smartlist_contains_digest(sl, "\00090AAB2AAABaasdAAAAA"));
|
||||
|
||||
/* sort digests */
|
||||
smartlist_sort_digests(sl);
|
||||
tt_mem_op(smartlist_get(sl, 0),==, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
|
||||
tt_mem_op(smartlist_get(sl, 1),==, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
|
||||
tt_mem_op(smartlist_get(sl, 2),==, "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN);
|
||||
tt_int_op(3,==, smartlist_len(sl));
|
||||
tt_mem_op(smartlist_get(sl, 0),OP_EQ, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
|
||||
tt_mem_op(smartlist_get(sl, 1),OP_EQ, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
|
||||
tt_mem_op(smartlist_get(sl, 2),OP_EQ, "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN);
|
||||
tt_int_op(3,OP_EQ, smartlist_len(sl));
|
||||
|
||||
/* uniq_digests */
|
||||
smartlist_uniq_digests(sl);
|
||||
tt_int_op(2,==, smartlist_len(sl));
|
||||
tt_mem_op(smartlist_get(sl, 0),==, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
|
||||
tt_mem_op(smartlist_get(sl, 1),==, "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN);
|
||||
tt_int_op(2,OP_EQ, smartlist_len(sl));
|
||||
tt_mem_op(smartlist_get(sl, 0),OP_EQ, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN);
|
||||
tt_mem_op(smartlist_get(sl, 1),OP_EQ, "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN);
|
||||
|
||||
done:
|
||||
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
|
||||
@@ -463,7 +466,7 @@ test_container_smartlist_join(void *arg)
|
||||
sl2, char *, cp2,
|
||||
strcmp(cp1,cp2),
|
||||
smartlist_add(sl3, cp2)) {
|
||||
tt_str_op(cp1,==, cp2);
|
||||
tt_str_op(cp1,OP_EQ, cp2);
|
||||
smartlist_add(sl4, cp1);
|
||||
} SMARTLIST_FOREACH_JOIN_END(cp1, cp2);
|
||||
|
||||
@@ -474,10 +477,11 @@ test_container_smartlist_join(void *arg)
|
||||
tt_assert(smartlist_contains(sl, cp) &&
|
||||
smartlist_contains_string(sl2, cp)));
|
||||
joined = smartlist_join_strings(sl3, ",", 0, NULL);
|
||||
tt_str_op(joined,==, "Anemias,Anemias,Crossbowmen,Work");
|
||||
tt_str_op(joined,OP_EQ, "Anemias,Anemias,Crossbowmen,Work");
|
||||
tor_free(joined);
|
||||
joined = smartlist_join_strings(sl4, ",", 0, NULL);
|
||||
tt_str_op(joined,==, "Ambush,Anchorman,Anchorman,Bacon,Inhumane,Insurance,"
|
||||
tt_str_op(joined,OP_EQ,
|
||||
"Ambush,Anchorman,Anchorman,Bacon,Inhumane,Insurance,"
|
||||
"Knish,Know,Manners,Manners,Maraschinos,Wombats,Wombats");
|
||||
tor_free(joined);
|
||||
|
||||
@@ -612,7 +616,7 @@ test_container_digestset(void *arg)
|
||||
if (digestset_contains(set, d))
|
||||
++false_positives;
|
||||
}
|
||||
tt_int_op(50, >, false_positives); /* Should be far lower. */
|
||||
tt_int_op(50, OP_GT, false_positives); /* Should be far lower. */
|
||||
|
||||
done:
|
||||
if (set)
|
||||
@@ -675,31 +679,31 @@ test_container_pqueue(void *arg)
|
||||
|
||||
OK();
|
||||
|
||||
tt_int_op(smartlist_len(sl),==, 11);
|
||||
tt_ptr_op(smartlist_get(sl, 0),==, &apples);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &apples);
|
||||
tt_int_op(smartlist_len(sl),==, 10);
|
||||
tt_int_op(smartlist_len(sl),OP_EQ, 11);
|
||||
tt_ptr_op(smartlist_get(sl, 0),OP_EQ, &apples);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &apples);
|
||||
tt_int_op(smartlist_len(sl),OP_EQ, 10);
|
||||
OK();
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &cows);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &daschunds);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &cows);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &daschunds);
|
||||
smartlist_pqueue_add(sl, cmp, offset, &chinchillas);
|
||||
OK();
|
||||
smartlist_pqueue_add(sl, cmp, offset, &fireflies);
|
||||
OK();
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &chinchillas);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &eggplants);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &fireflies);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &chinchillas);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &eggplants);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &fireflies);
|
||||
OK();
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &fish);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &frogs);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &lobsters);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &roquefort);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &fish);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &frogs);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &lobsters);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &roquefort);
|
||||
OK();
|
||||
tt_int_op(smartlist_len(sl),==, 3);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &squid);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &weissbier);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &zebras);
|
||||
tt_int_op(smartlist_len(sl),==, 0);
|
||||
tt_int_op(smartlist_len(sl),OP_EQ, 3);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &squid);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &weissbier);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &zebras);
|
||||
tt_int_op(smartlist_len(sl),OP_EQ, 0);
|
||||
OK();
|
||||
|
||||
/* Now test remove. */
|
||||
@@ -709,21 +713,21 @@ test_container_pqueue(void *arg)
|
||||
smartlist_pqueue_add(sl, cmp, offset, &apples);
|
||||
smartlist_pqueue_add(sl, cmp, offset, &squid);
|
||||
smartlist_pqueue_add(sl, cmp, offset, &zebras);
|
||||
tt_int_op(smartlist_len(sl),==, 6);
|
||||
tt_int_op(smartlist_len(sl),OP_EQ, 6);
|
||||
OK();
|
||||
smartlist_pqueue_remove(sl, cmp, offset, &zebras);
|
||||
tt_int_op(smartlist_len(sl),==, 5);
|
||||
tt_int_op(smartlist_len(sl),OP_EQ, 5);
|
||||
OK();
|
||||
smartlist_pqueue_remove(sl, cmp, offset, &cows);
|
||||
tt_int_op(smartlist_len(sl),==, 4);
|
||||
tt_int_op(smartlist_len(sl),OP_EQ, 4);
|
||||
OK();
|
||||
smartlist_pqueue_remove(sl, cmp, offset, &apples);
|
||||
tt_int_op(smartlist_len(sl),==, 3);
|
||||
tt_int_op(smartlist_len(sl),OP_EQ, 3);
|
||||
OK();
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &fish);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &frogs);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &squid);
|
||||
tt_int_op(smartlist_len(sl),==, 0);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &fish);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &frogs);
|
||||
tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),OP_EQ, &squid);
|
||||
tt_int_op(smartlist_len(sl),OP_EQ, 0);
|
||||
OK();
|
||||
|
||||
#undef OK
|
||||
@@ -755,30 +759,30 @@ test_container_strmap(void *arg)
|
||||
(void)arg;
|
||||
map = strmap_new();
|
||||
tt_assert(map);
|
||||
tt_int_op(strmap_size(map),==, 0);
|
||||
tt_int_op(strmap_size(map),OP_EQ, 0);
|
||||
tt_assert(strmap_isempty(map));
|
||||
v = strmap_set(map, "K1", v99);
|
||||
tt_ptr_op(v,==, NULL);
|
||||
tt_ptr_op(v,OP_EQ, NULL);
|
||||
tt_assert(!strmap_isempty(map));
|
||||
v = strmap_set(map, "K2", v101);
|
||||
tt_ptr_op(v,==, NULL);
|
||||
tt_ptr_op(v,OP_EQ, NULL);
|
||||
v = strmap_set(map, "K1", v100);
|
||||
tt_ptr_op(v,==, v99);
|
||||
tt_ptr_op(strmap_get(map,"K1"),==, v100);
|
||||
tt_ptr_op(strmap_get(map,"K2"),==, v101);
|
||||
tt_ptr_op(strmap_get(map,"K-not-there"),==, NULL);
|
||||
tt_ptr_op(v,OP_EQ, v99);
|
||||
tt_ptr_op(strmap_get(map,"K1"),OP_EQ, v100);
|
||||
tt_ptr_op(strmap_get(map,"K2"),OP_EQ, v101);
|
||||
tt_ptr_op(strmap_get(map,"K-not-there"),OP_EQ, NULL);
|
||||
strmap_assert_ok(map);
|
||||
|
||||
v = strmap_remove(map,"K2");
|
||||
strmap_assert_ok(map);
|
||||
tt_ptr_op(v,==, v101);
|
||||
tt_ptr_op(strmap_get(map,"K2"),==, NULL);
|
||||
tt_ptr_op(strmap_remove(map,"K2"),==, NULL);
|
||||
tt_ptr_op(v,OP_EQ, v101);
|
||||
tt_ptr_op(strmap_get(map,"K2"),OP_EQ, NULL);
|
||||
tt_ptr_op(strmap_remove(map,"K2"),OP_EQ, NULL);
|
||||
|
||||
strmap_set(map, "K2", v101);
|
||||
strmap_set(map, "K3", v102);
|
||||
strmap_set(map, "K4", v103);
|
||||
tt_int_op(strmap_size(map),==, 4);
|
||||
tt_int_op(strmap_size(map),OP_EQ, 4);
|
||||
strmap_assert_ok(map);
|
||||
strmap_set(map, "K5", v104);
|
||||
strmap_set(map, "K6", v105);
|
||||
@@ -790,7 +794,7 @@ test_container_strmap(void *arg)
|
||||
while (!strmap_iter_done(iter)) {
|
||||
strmap_iter_get(iter,&k,&v);
|
||||
smartlist_add(found_keys, tor_strdup(k));
|
||||
tt_ptr_op(v,==, strmap_get(map, k));
|
||||
tt_ptr_op(v,OP_EQ, strmap_get(map, k));
|
||||
|
||||
if (!strcmp(k, "K2")) {
|
||||
iter = strmap_iter_next_rmv(map,iter);
|
||||
@@ -800,12 +804,12 @@ test_container_strmap(void *arg)
|
||||
}
|
||||
|
||||
/* Make sure we removed K2, but not the others. */
|
||||
tt_ptr_op(strmap_get(map, "K2"),==, NULL);
|
||||
tt_ptr_op(strmap_get(map, "K5"),==, v104);
|
||||
tt_ptr_op(strmap_get(map, "K2"),OP_EQ, NULL);
|
||||
tt_ptr_op(strmap_get(map, "K5"),OP_EQ, v104);
|
||||
/* Make sure we visited everyone once */
|
||||
smartlist_sort_strings(found_keys);
|
||||
visited = smartlist_join_strings(found_keys, ":", 0, NULL);
|
||||
tt_str_op(visited,==, "K1:K2:K3:K4:K5:K6");
|
||||
tt_str_op(visited,OP_EQ, "K1:K2:K3:K4:K5:K6");
|
||||
|
||||
strmap_assert_ok(map);
|
||||
/* Clean up after ourselves. */
|
||||
@@ -815,13 +819,13 @@ test_container_strmap(void *arg)
|
||||
/* Now try some lc functions. */
|
||||
map = strmap_new();
|
||||
strmap_set_lc(map,"Ab.C", v1);
|
||||
tt_ptr_op(strmap_get(map,"ab.c"),==, v1);
|
||||
tt_ptr_op(strmap_get(map,"ab.c"),OP_EQ, v1);
|
||||
strmap_assert_ok(map);
|
||||
tt_ptr_op(strmap_get_lc(map,"AB.C"),==, v1);
|
||||
tt_ptr_op(strmap_get(map,"AB.C"),==, NULL);
|
||||
tt_ptr_op(strmap_remove_lc(map,"aB.C"),==, v1);
|
||||
tt_ptr_op(strmap_get_lc(map,"AB.C"),OP_EQ, v1);
|
||||
tt_ptr_op(strmap_get(map,"AB.C"),OP_EQ, NULL);
|
||||
tt_ptr_op(strmap_remove_lc(map,"aB.C"),OP_EQ, v1);
|
||||
strmap_assert_ok(map);
|
||||
tt_ptr_op(strmap_get_lc(map,"AB.C"),==, NULL);
|
||||
tt_ptr_op(strmap_get_lc(map,"AB.C"),OP_EQ, NULL);
|
||||
|
||||
done:
|
||||
if (map)
|
||||
@@ -853,41 +857,42 @@ test_container_order_functions(void *arg)
|
||||
|
||||
(void)arg;
|
||||
lst[n++] = 12;
|
||||
tt_int_op(12,==, median()); /* 12 */
|
||||
tt_int_op(12,OP_EQ, median()); /* 12 */
|
||||
lst[n++] = 77;
|
||||
//smartlist_shuffle(sl);
|
||||
tt_int_op(12,==, median()); /* 12, 77 */
|
||||
tt_int_op(12,OP_EQ, median()); /* 12, 77 */
|
||||
lst[n++] = 77;
|
||||
//smartlist_shuffle(sl);
|
||||
tt_int_op(77,==, median()); /* 12, 77, 77 */
|
||||
tt_int_op(77,OP_EQ, median()); /* 12, 77, 77 */
|
||||
lst[n++] = 24;
|
||||
tt_int_op(24,==, median()); /* 12,24,77,77 */
|
||||
tt_int_op(24,OP_EQ, median()); /* 12,24,77,77 */
|
||||
lst[n++] = 60;
|
||||
lst[n++] = 12;
|
||||
lst[n++] = 25;
|
||||
//smartlist_shuffle(sl);
|
||||
tt_int_op(25,==, median()); /* 12,12,24,25,60,77,77 */
|
||||
tt_int_op(25,OP_EQ, median()); /* 12,12,24,25,60,77,77 */
|
||||
#undef median
|
||||
|
||||
#define third_quartile() third_quartile_uint32(lst2, n)
|
||||
|
||||
n = 0;
|
||||
lst2[n++] = 1;
|
||||
tt_int_op(1,==, third_quartile()); /* ~1~ */
|
||||
tt_int_op(1,OP_EQ, third_quartile()); /* ~1~ */
|
||||
lst2[n++] = 2;
|
||||
tt_int_op(2,==, third_quartile()); /* 1, ~2~ */
|
||||
tt_int_op(2,OP_EQ, third_quartile()); /* 1, ~2~ */
|
||||
lst2[n++] = 3;
|
||||
lst2[n++] = 4;
|
||||
lst2[n++] = 5;
|
||||
tt_int_op(4,==, third_quartile()); /* 1, 2, 3, ~4~, 5 */
|
||||
tt_int_op(4,OP_EQ, third_quartile()); /* 1, 2, 3, ~4~, 5 */
|
||||
lst2[n++] = 6;
|
||||
lst2[n++] = 7;
|
||||
lst2[n++] = 8;
|
||||
lst2[n++] = 9;
|
||||
tt_int_op(7,==, third_quartile()); /* 1, 2, 3, 4, 5, 6, ~7~, 8, 9 */
|
||||
tt_int_op(7,OP_EQ, third_quartile()); /* 1, 2, 3, 4, 5, 6, ~7~, 8, 9 */
|
||||
lst2[n++] = 10;
|
||||
lst2[n++] = 11;
|
||||
tt_int_op(9,==, third_quartile()); /* 1, 2, 3, 4, 5, 6, 7, 8, ~9~, 10, 11 */
|
||||
/* 1, 2, 3, 4, 5, 6, 7, 8, ~9~, 10, 11 */
|
||||
tt_int_op(9,OP_EQ, third_quartile());
|
||||
|
||||
#undef third_quartile
|
||||
|
||||
@@ -911,26 +916,26 @@ test_container_di_map(void *arg)
|
||||
(void)arg;
|
||||
|
||||
/* Try searching on an empty map. */
|
||||
tt_ptr_op(NULL, ==, dimap_search(map, key1, NULL));
|
||||
tt_ptr_op(NULL, ==, dimap_search(map, key2, NULL));
|
||||
tt_ptr_op(v3, ==, dimap_search(map, key2, v3));
|
||||
tt_ptr_op(NULL, OP_EQ, dimap_search(map, key1, NULL));
|
||||
tt_ptr_op(NULL, OP_EQ, dimap_search(map, key2, NULL));
|
||||
tt_ptr_op(v3, OP_EQ, dimap_search(map, key2, v3));
|
||||
dimap_free(map, NULL);
|
||||
map = NULL;
|
||||
|
||||
/* Add a single entry. */
|
||||
dimap_add_entry(&map, key1, v1);
|
||||
tt_ptr_op(NULL, ==, dimap_search(map, key2, NULL));
|
||||
tt_ptr_op(v3, ==, dimap_search(map, key2, v3));
|
||||
tt_ptr_op(v1, ==, dimap_search(map, key1, NULL));
|
||||
tt_ptr_op(NULL, OP_EQ, dimap_search(map, key2, NULL));
|
||||
tt_ptr_op(v3, OP_EQ, dimap_search(map, key2, v3));
|
||||
tt_ptr_op(v1, OP_EQ, dimap_search(map, key1, NULL));
|
||||
|
||||
/* Now try it with three entries in the map. */
|
||||
dimap_add_entry(&map, key2, v2);
|
||||
dimap_add_entry(&map, key3, v3);
|
||||
tt_ptr_op(v1, ==, dimap_search(map, key1, NULL));
|
||||
tt_ptr_op(v2, ==, dimap_search(map, key2, NULL));
|
||||
tt_ptr_op(v3, ==, dimap_search(map, key3, NULL));
|
||||
tt_ptr_op(NULL, ==, dimap_search(map, key4, NULL));
|
||||
tt_ptr_op(v1, ==, dimap_search(map, key4, v1));
|
||||
tt_ptr_op(v1, OP_EQ, dimap_search(map, key1, NULL));
|
||||
tt_ptr_op(v2, OP_EQ, dimap_search(map, key2, NULL));
|
||||
tt_ptr_op(v3, OP_EQ, dimap_search(map, key3, NULL));
|
||||
tt_ptr_op(NULL, OP_EQ, dimap_search(map, key4, NULL));
|
||||
tt_ptr_op(v1, OP_EQ, dimap_search(map, key4, v1));
|
||||
|
||||
done:
|
||||
tor_free(v1);
|
||||
@@ -959,7 +964,7 @@ test_container_fp_pair_map(void *arg)
|
||||
(void)arg;
|
||||
map = fp_pair_map_new();
|
||||
tt_assert(map);
|
||||
tt_int_op(fp_pair_map_size(map),==, 0);
|
||||
tt_int_op(fp_pair_map_size(map),OP_EQ, 0);
|
||||
tt_assert(fp_pair_map_isempty(map));
|
||||
|
||||
memset(fp1.first, 0x11, DIGEST_LEN);
|
||||
@@ -976,27 +981,27 @@ test_container_fp_pair_map(void *arg)
|
||||
memset(fp6.second, 0x62, DIGEST_LEN);
|
||||
|
||||
v = fp_pair_map_set(map, &fp1, v99);
|
||||
tt_ptr_op(v, ==, NULL);
|
||||
tt_ptr_op(v, OP_EQ, NULL);
|
||||
tt_assert(!fp_pair_map_isempty(map));
|
||||
v = fp_pair_map_set(map, &fp2, v101);
|
||||
tt_ptr_op(v, ==, NULL);
|
||||
tt_ptr_op(v, OP_EQ, NULL);
|
||||
v = fp_pair_map_set(map, &fp1, v100);
|
||||
tt_ptr_op(v, ==, v99);
|
||||
tt_ptr_op(fp_pair_map_get(map, &fp1),==, v100);
|
||||
tt_ptr_op(fp_pair_map_get(map, &fp2),==, v101);
|
||||
tt_ptr_op(fp_pair_map_get(map, &fp3),==, NULL);
|
||||
tt_ptr_op(v, OP_EQ, v99);
|
||||
tt_ptr_op(fp_pair_map_get(map, &fp1),OP_EQ, v100);
|
||||
tt_ptr_op(fp_pair_map_get(map, &fp2),OP_EQ, v101);
|
||||
tt_ptr_op(fp_pair_map_get(map, &fp3),OP_EQ, NULL);
|
||||
fp_pair_map_assert_ok(map);
|
||||
|
||||
v = fp_pair_map_remove(map, &fp2);
|
||||
fp_pair_map_assert_ok(map);
|
||||
tt_ptr_op(v,==, v101);
|
||||
tt_ptr_op(fp_pair_map_get(map, &fp2),==, NULL);
|
||||
tt_ptr_op(fp_pair_map_remove(map, &fp2),==, NULL);
|
||||
tt_ptr_op(v,OP_EQ, v101);
|
||||
tt_ptr_op(fp_pair_map_get(map, &fp2),OP_EQ, NULL);
|
||||
tt_ptr_op(fp_pair_map_remove(map, &fp2),OP_EQ, NULL);
|
||||
|
||||
fp_pair_map_set(map, &fp2, v101);
|
||||
fp_pair_map_set(map, &fp3, v102);
|
||||
fp_pair_map_set(map, &fp4, v103);
|
||||
tt_int_op(fp_pair_map_size(map),==, 4);
|
||||
tt_int_op(fp_pair_map_size(map),OP_EQ, 4);
|
||||
fp_pair_map_assert_ok(map);
|
||||
fp_pair_map_set(map, &fp5, v104);
|
||||
fp_pair_map_set(map, &fp6, v105);
|
||||
@@ -1006,7 +1011,7 @@ test_container_fp_pair_map(void *arg)
|
||||
iter = fp_pair_map_iter_init(map);
|
||||
while (!fp_pair_map_iter_done(iter)) {
|
||||
fp_pair_map_iter_get(iter, &k, &v);
|
||||
tt_ptr_op(v,==, fp_pair_map_get(map, &k));
|
||||
tt_ptr_op(v,OP_EQ, fp_pair_map_get(map, &k));
|
||||
|
||||
if (tor_memeq(&fp2, &k, sizeof(fp2))) {
|
||||
iter = fp_pair_map_iter_next_rmv(map, iter);
|
||||
@@ -1016,8 +1021,8 @@ test_container_fp_pair_map(void *arg)
|
||||
}
|
||||
|
||||
/* Make sure we removed fp2, but not the others. */
|
||||
tt_ptr_op(fp_pair_map_get(map, &fp2),==, NULL);
|
||||
tt_ptr_op(fp_pair_map_get(map, &fp5),==, v104);
|
||||
tt_ptr_op(fp_pair_map_get(map, &fp2),OP_EQ, NULL);
|
||||
tt_ptr_op(fp_pair_map_get(map, &fp5),OP_EQ, v104);
|
||||
|
||||
fp_pair_map_assert_ok(map);
|
||||
/* Clean up after ourselves. */
|
||||
|
||||
@@ -22,7 +22,7 @@ help_test_bucket_note_empty(uint32_t expected_msec_since_midnight,
|
||||
tvnow.tv_usec = (msec_since_epoch % 1000) * 1000;
|
||||
connection_buckets_note_empty_ts(×tamp_var, tokens_before,
|
||||
tokens_removed, &tvnow);
|
||||
tt_int_op(expected_msec_since_midnight, ==, timestamp_var);
|
||||
tt_int_op(expected_msec_since_midnight, OP_EQ, timestamp_var);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -57,20 +57,20 @@ test_cntev_bucket_millis_empty(void *arg)
|
||||
tvnow.tv_usec = 200000;
|
||||
|
||||
/* Bucket has not been refilled. */
|
||||
tt_int_op(0, ==, bucket_millis_empty(0, 42120, 0, 100, &tvnow));
|
||||
tt_int_op(0, ==, bucket_millis_empty(-10, 42120, -10, 100, &tvnow));
|
||||
tt_int_op(0, OP_EQ, bucket_millis_empty(0, 42120, 0, 100, &tvnow));
|
||||
tt_int_op(0, OP_EQ, bucket_millis_empty(-10, 42120, -10, 100, &tvnow));
|
||||
|
||||
/* Bucket was not empty. */
|
||||
tt_int_op(0, ==, bucket_millis_empty(10, 42120, 20, 100, &tvnow));
|
||||
tt_int_op(0, OP_EQ, bucket_millis_empty(10, 42120, 20, 100, &tvnow));
|
||||
|
||||
/* Bucket has been emptied 80 msec ago and has just been refilled. */
|
||||
tt_int_op(80, ==, bucket_millis_empty(-20, 42120, -10, 100, &tvnow));
|
||||
tt_int_op(80, ==, bucket_millis_empty(-10, 42120, 0, 100, &tvnow));
|
||||
tt_int_op(80, ==, bucket_millis_empty(0, 42120, 10, 100, &tvnow));
|
||||
tt_int_op(80, OP_EQ, bucket_millis_empty(-20, 42120, -10, 100, &tvnow));
|
||||
tt_int_op(80, OP_EQ, bucket_millis_empty(-10, 42120, 0, 100, &tvnow));
|
||||
tt_int_op(80, OP_EQ, bucket_millis_empty(0, 42120, 10, 100, &tvnow));
|
||||
|
||||
/* Bucket has been emptied 180 msec ago, last refill was 100 msec ago
|
||||
* which was insufficient to make it positive, so cap msec at 100. */
|
||||
tt_int_op(100, ==, bucket_millis_empty(0, 42020, 1, 100, &tvnow));
|
||||
tt_int_op(100, OP_EQ, bucket_millis_empty(0, 42020, 1, 100, &tvnow));
|
||||
|
||||
/* 1970-01-02 00:00:00:050000 */
|
||||
tvnow.tv_sec = 86400;
|
||||
@@ -78,7 +78,7 @@ test_cntev_bucket_millis_empty(void *arg)
|
||||
|
||||
/* Last emptied 30 msec before midnight, tvnow is 50 msec after
|
||||
* midnight, that's 80 msec in total. */
|
||||
tt_int_op(80, ==, bucket_millis_empty(0, 86400000 - 30, 1, 100, &tvnow));
|
||||
tt_int_op(80, OP_EQ, bucket_millis_empty(0, 86400000 - 30, 1, 100, &tvnow));
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -118,26 +118,26 @@ test_cntev_sum_up_cell_stats(void *arg)
|
||||
cell_stats = tor_malloc_zero(sizeof(cell_stats_t));
|
||||
add_testing_cell_stats_entry(circ, CELL_RELAY, 0, 0, 0);
|
||||
sum_up_cell_stats_by_command(circ, cell_stats);
|
||||
tt_u64_op(1, ==, cell_stats->added_cells_appward[CELL_RELAY]);
|
||||
tt_u64_op(1, OP_EQ, cell_stats->added_cells_appward[CELL_RELAY]);
|
||||
|
||||
/* A single RELAY cell was added to the exitward queue. */
|
||||
add_testing_cell_stats_entry(circ, CELL_RELAY, 0, 0, 1);
|
||||
sum_up_cell_stats_by_command(circ, cell_stats);
|
||||
tt_u64_op(1, ==, cell_stats->added_cells_exitward[CELL_RELAY]);
|
||||
tt_u64_op(1, OP_EQ, cell_stats->added_cells_exitward[CELL_RELAY]);
|
||||
|
||||
/* A single RELAY cell was removed from the appward queue where it spent
|
||||
* 20 msec. */
|
||||
add_testing_cell_stats_entry(circ, CELL_RELAY, 2, 1, 0);
|
||||
sum_up_cell_stats_by_command(circ, cell_stats);
|
||||
tt_u64_op(20, ==, cell_stats->total_time_appward[CELL_RELAY]);
|
||||
tt_u64_op(1, ==, cell_stats->removed_cells_appward[CELL_RELAY]);
|
||||
tt_u64_op(20, OP_EQ, cell_stats->total_time_appward[CELL_RELAY]);
|
||||
tt_u64_op(1, OP_EQ, cell_stats->removed_cells_appward[CELL_RELAY]);
|
||||
|
||||
/* A single RELAY cell was removed from the exitward queue where it
|
||||
* spent 30 msec. */
|
||||
add_testing_cell_stats_entry(circ, CELL_RELAY, 3, 1, 1);
|
||||
sum_up_cell_stats_by_command(circ, cell_stats);
|
||||
tt_u64_op(30, ==, cell_stats->total_time_exitward[CELL_RELAY]);
|
||||
tt_u64_op(1, ==, cell_stats->removed_cells_exitward[CELL_RELAY]);
|
||||
tt_u64_op(30, OP_EQ, cell_stats->total_time_exitward[CELL_RELAY]);
|
||||
tt_u64_op(1, OP_EQ, cell_stats->removed_cells_exitward[CELL_RELAY]);
|
||||
|
||||
done:
|
||||
tor_free(cell_stats);
|
||||
@@ -164,7 +164,7 @@ test_cntev_append_cell_stats(void *arg)
|
||||
append_cell_stats_by_command(event_parts, key,
|
||||
include_if_non_zero,
|
||||
number_to_include);
|
||||
tt_int_op(0, ==, smartlist_len(event_parts));
|
||||
tt_int_op(0, OP_EQ, smartlist_len(event_parts));
|
||||
|
||||
/* There's a RELAY cell to include, but the corresponding field in
|
||||
* include_if_non_zero is still zero. */
|
||||
@@ -172,7 +172,7 @@ test_cntev_append_cell_stats(void *arg)
|
||||
append_cell_stats_by_command(event_parts, key,
|
||||
include_if_non_zero,
|
||||
number_to_include);
|
||||
tt_int_op(0, ==, smartlist_len(event_parts));
|
||||
tt_int_op(0, OP_EQ, smartlist_len(event_parts));
|
||||
|
||||
/* Now include single RELAY cell. */
|
||||
include_if_non_zero[CELL_RELAY] = 2;
|
||||
@@ -180,7 +180,7 @@ test_cntev_append_cell_stats(void *arg)
|
||||
include_if_non_zero,
|
||||
number_to_include);
|
||||
cp = smartlist_pop_last(event_parts);
|
||||
tt_str_op("Z=relay:1", ==, cp);
|
||||
tt_str_op("Z=relay:1", OP_EQ, cp);
|
||||
tor_free(cp);
|
||||
|
||||
/* Add four CREATE cells. */
|
||||
@@ -190,7 +190,7 @@ test_cntev_append_cell_stats(void *arg)
|
||||
include_if_non_zero,
|
||||
number_to_include);
|
||||
cp = smartlist_pop_last(event_parts);
|
||||
tt_str_op("Z=create:4,relay:1", ==, cp);
|
||||
tt_str_op("Z=create:4,relay:1", OP_EQ, cp);
|
||||
|
||||
done:
|
||||
tor_free(cp);
|
||||
@@ -220,14 +220,14 @@ test_cntev_format_cell_stats(void *arg)
|
||||
/* Origin circuit was completely idle. */
|
||||
cell_stats = tor_malloc_zero(sizeof(cell_stats_t));
|
||||
format_cell_stats(&event_string, TO_CIRCUIT(ocirc), cell_stats);
|
||||
tt_str_op("ID=2 OutboundQueue=3 OutboundConn=1", ==, event_string);
|
||||
tt_str_op("ID=2 OutboundQueue=3 OutboundConn=1", OP_EQ, event_string);
|
||||
tor_free(event_string);
|
||||
|
||||
/* Origin circuit had 4 RELAY cells added to its exitward queue. */
|
||||
cell_stats->added_cells_exitward[CELL_RELAY] = 4;
|
||||
format_cell_stats(&event_string, TO_CIRCUIT(ocirc), cell_stats);
|
||||
tt_str_op("ID=2 OutboundQueue=3 OutboundConn=1 OutboundAdded=relay:4",
|
||||
==, event_string);
|
||||
OP_EQ, event_string);
|
||||
tor_free(event_string);
|
||||
|
||||
/* Origin circuit also had 5 CREATE2 cells added to its exitward
|
||||
@@ -235,7 +235,7 @@ test_cntev_format_cell_stats(void *arg)
|
||||
cell_stats->added_cells_exitward[CELL_CREATE2] = 5;
|
||||
format_cell_stats(&event_string, TO_CIRCUIT(ocirc), cell_stats);
|
||||
tt_str_op("ID=2 OutboundQueue=3 OutboundConn=1 OutboundAdded=relay:4,"
|
||||
"create2:5", ==, event_string);
|
||||
"create2:5", OP_EQ, event_string);
|
||||
tor_free(event_string);
|
||||
|
||||
/* Origin circuit also had 7 RELAY cells removed from its exitward queue
|
||||
@@ -245,7 +245,7 @@ test_cntev_format_cell_stats(void *arg)
|
||||
format_cell_stats(&event_string, TO_CIRCUIT(ocirc), cell_stats);
|
||||
tt_str_op("ID=2 OutboundQueue=3 OutboundConn=1 OutboundAdded=relay:4,"
|
||||
"create2:5 OutboundRemoved=relay:7 OutboundTime=relay:6",
|
||||
==, event_string);
|
||||
OP_EQ, event_string);
|
||||
tor_free(event_string);
|
||||
|
||||
p_chan = tor_malloc_zero(sizeof(channel_tls_t));
|
||||
@@ -265,14 +265,14 @@ test_cntev_format_cell_stats(void *arg)
|
||||
cell_stats = tor_malloc_zero(sizeof(cell_stats_t));
|
||||
format_cell_stats(&event_string, TO_CIRCUIT(or_circ), cell_stats);
|
||||
tt_str_op("InboundQueue=8 InboundConn=2 OutboundQueue=9 OutboundConn=1",
|
||||
==, event_string);
|
||||
OP_EQ, event_string);
|
||||
tor_free(event_string);
|
||||
|
||||
/* OR circuit had 3 RELAY cells added to its appward queue. */
|
||||
cell_stats->added_cells_appward[CELL_RELAY] = 3;
|
||||
format_cell_stats(&event_string, TO_CIRCUIT(or_circ), cell_stats);
|
||||
tt_str_op("InboundQueue=8 InboundConn=2 InboundAdded=relay:3 "
|
||||
"OutboundQueue=9 OutboundConn=1", ==, event_string);
|
||||
"OutboundQueue=9 OutboundConn=1", OP_EQ, event_string);
|
||||
tor_free(event_string);
|
||||
|
||||
/* OR circuit had 7 RELAY cells removed from its appward queue which
|
||||
@@ -282,7 +282,7 @@ test_cntev_format_cell_stats(void *arg)
|
||||
format_cell_stats(&event_string, TO_CIRCUIT(or_circ), cell_stats);
|
||||
tt_str_op("InboundQueue=8 InboundConn=2 InboundAdded=relay:3 "
|
||||
"InboundRemoved=relay:7 InboundTime=relay:6 "
|
||||
"OutboundQueue=9 OutboundConn=1", ==, event_string);
|
||||
"OutboundQueue=9 OutboundConn=1", OP_EQ, event_string);
|
||||
|
||||
done:
|
||||
tor_free(cell_stats);
|
||||
|
||||
+273
-268
File diff suppressed because it is too large
Load Diff
+357
-353
File diff suppressed because it is too large
Load Diff
+55
-53
@@ -71,15 +71,16 @@ setup_fake_routerlist(void)
|
||||
retval = router_load_routers_from_string(TEST_DESCRIPTORS,
|
||||
NULL, SAVED_IN_JOURNAL,
|
||||
NULL, 0, NULL);
|
||||
tt_int_op(retval, ==, NUMBER_OF_DESCRIPTORS);
|
||||
tt_int_op(retval, OP_EQ, NUMBER_OF_DESCRIPTORS);
|
||||
|
||||
/* Sanity checking of routerlist and nodelist. */
|
||||
our_routerlist = router_get_routerlist();
|
||||
tt_int_op(smartlist_len(our_routerlist->routers), ==, NUMBER_OF_DESCRIPTORS);
|
||||
tt_int_op(smartlist_len(our_routerlist->routers), OP_EQ,
|
||||
NUMBER_OF_DESCRIPTORS);
|
||||
routerlist_assert_ok(our_routerlist);
|
||||
|
||||
our_nodelist = nodelist_get_list();
|
||||
tt_int_op(smartlist_len(our_nodelist), ==, NUMBER_OF_DESCRIPTORS);
|
||||
tt_int_op(smartlist_len(our_nodelist), OP_EQ, NUMBER_OF_DESCRIPTORS);
|
||||
|
||||
/* Mark all routers as non-guards but up and running! */
|
||||
SMARTLIST_FOREACH_BEGIN(our_nodelist, node_t *, node) {
|
||||
@@ -163,7 +164,7 @@ test_choose_random_entry_one_possible_guard(void *arg)
|
||||
|
||||
/* Pick an entry. Make sure we pick the node we marked as guard. */
|
||||
chosen_entry = choose_random_entry(NULL);
|
||||
tt_ptr_op(chosen_entry, ==, the_guard);
|
||||
tt_ptr_op(chosen_entry, OP_EQ, the_guard);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -189,14 +190,14 @@ populate_live_entry_guards_test_helper(int num_needed)
|
||||
|
||||
/* Set NumEntryGuards to the provided number. */
|
||||
options->NumEntryGuards = num_needed;
|
||||
tt_int_op(num_needed, ==, decide_num_guards(options, 0));
|
||||
tt_int_op(num_needed, OP_EQ, decide_num_guards(options, 0));
|
||||
|
||||
/* The global entry guards smartlist should be empty now. */
|
||||
tt_int_op(smartlist_len(all_entry_guards), ==, 0);
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_EQ, 0);
|
||||
|
||||
/* Walk the nodelist and add all nodes as entry guards. */
|
||||
our_nodelist = nodelist_get_list();
|
||||
tt_int_op(smartlist_len(our_nodelist), ==, NUMBER_OF_DESCRIPTORS);
|
||||
tt_int_op(smartlist_len(our_nodelist), OP_EQ, NUMBER_OF_DESCRIPTORS);
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(our_nodelist, const node_t *, node) {
|
||||
const node_t *node_tmp;
|
||||
@@ -205,20 +206,20 @@ populate_live_entry_guards_test_helper(int num_needed)
|
||||
} SMARTLIST_FOREACH_END(node);
|
||||
|
||||
/* Make sure the nodes were added as entry guards. */
|
||||
tt_int_op(smartlist_len(all_entry_guards), ==, NUMBER_OF_DESCRIPTORS);
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_EQ, NUMBER_OF_DESCRIPTORS);
|
||||
|
||||
/* Ensure that all the possible entry guards are enough to satisfy us. */
|
||||
tt_int_op(smartlist_len(all_entry_guards), >=, num_needed);
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_GE, num_needed);
|
||||
|
||||
/* Walk the entry guard list for some sanity checking */
|
||||
SMARTLIST_FOREACH_BEGIN(all_entry_guards, const entry_guard_t *, entry) {
|
||||
/* Since we called add_an_entry_guard() with 'for_discovery' being
|
||||
False, all guards should have made_contact enabled. */
|
||||
tt_int_op(entry->made_contact, ==, 1);
|
||||
tt_int_op(entry->made_contact, OP_EQ, 1);
|
||||
|
||||
/* Since we don't have a routerstatus, all of the entry guards are
|
||||
not directory servers. */
|
||||
tt_int_op(entry->is_dir_cache, ==, 0);
|
||||
tt_int_op(entry->is_dir_cache, OP_EQ, 0);
|
||||
} SMARTLIST_FOREACH_END(entry);
|
||||
|
||||
/* First, try to get some fast guards. This should fail. */
|
||||
@@ -228,8 +229,8 @@ populate_live_entry_guards_test_helper(int num_needed)
|
||||
NO_DIRINFO, /* Don't care about DIRINFO*/
|
||||
0, 0,
|
||||
1); /* We want fast guard! */
|
||||
tt_int_op(retval, ==, 0);
|
||||
tt_int_op(smartlist_len(live_entry_guards), ==, 0);
|
||||
tt_int_op(retval, OP_EQ, 0);
|
||||
tt_int_op(smartlist_len(live_entry_guards), OP_EQ, 0);
|
||||
|
||||
/* Now try to get some stable guards. This should fail too. */
|
||||
retval = populate_live_entry_guards(live_entry_guards,
|
||||
@@ -239,8 +240,8 @@ populate_live_entry_guards_test_helper(int num_needed)
|
||||
0,
|
||||
1, /* We want stable guard! */
|
||||
0);
|
||||
tt_int_op(retval, ==, 0);
|
||||
tt_int_op(smartlist_len(live_entry_guards), ==, 0);
|
||||
tt_int_op(retval, OP_EQ, 0);
|
||||
tt_int_op(smartlist_len(live_entry_guards), OP_EQ, 0);
|
||||
|
||||
/* Now try to get any guard we can find. This should succeed. */
|
||||
retval = populate_live_entry_guards(live_entry_guards,
|
||||
@@ -253,8 +254,8 @@ populate_live_entry_guards_test_helper(int num_needed)
|
||||
should have added 'num_needed' of them to live_entry_guards.
|
||||
'retval' should be 1 since we now have enough live entry guards
|
||||
to pick one. */
|
||||
tt_int_op(retval, ==, 1);
|
||||
tt_int_op(smartlist_len(live_entry_guards), ==, num_needed);
|
||||
tt_int_op(retval, OP_EQ, 1);
|
||||
tt_int_op(smartlist_len(live_entry_guards), OP_EQ, num_needed);
|
||||
|
||||
done:
|
||||
smartlist_free(live_entry_guards);
|
||||
@@ -361,7 +362,7 @@ test_entry_guards_parse_state_simple(void *arg)
|
||||
(void) arg;
|
||||
|
||||
/* The global entry guards smartlist should be empty now. */
|
||||
tt_int_op(smartlist_len(all_entry_guards), ==, 0);
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_EQ, 0);
|
||||
|
||||
{ /* Prepare the state entry */
|
||||
|
||||
@@ -387,34 +388,34 @@ test_entry_guards_parse_state_simple(void *arg)
|
||||
|
||||
/* Parse state */
|
||||
retval = entry_guards_parse_state(state, 1, &msg);
|
||||
tt_int_op(retval, >=, 0);
|
||||
tt_int_op(retval, OP_GE, 0);
|
||||
|
||||
/* Test that the guard was registered.
|
||||
We need to re-get the entry guard list since its pointer was
|
||||
overwritten in entry_guards_parse_state(). */
|
||||
all_entry_guards = get_entry_guards();
|
||||
tt_int_op(smartlist_len(all_entry_guards), ==, 1);
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_EQ, 1);
|
||||
|
||||
{ /* Test the entry guard structure */
|
||||
char hex_digest[1024];
|
||||
char str_time[1024];
|
||||
|
||||
const entry_guard_t *e = smartlist_get(all_entry_guards, 0);
|
||||
tt_str_op(e->nickname, ==, nickname); /* Verify nickname */
|
||||
tt_str_op(e->nickname, OP_EQ, nickname); /* Verify nickname */
|
||||
|
||||
base16_encode(hex_digest, sizeof(hex_digest),
|
||||
e->identity, DIGEST_LEN);
|
||||
tt_str_op(hex_digest, ==, fpr); /* Verify fingerprint */
|
||||
tt_str_op(hex_digest, OP_EQ, fpr); /* Verify fingerprint */
|
||||
|
||||
tt_assert(e->is_dir_cache); /* Verify dirness */
|
||||
|
||||
tt_str_op(e->chosen_by_version, ==, tor_version); /* Verify tor version */
|
||||
tt_str_op(e->chosen_by_version, OP_EQ, tor_version); /* Verify version */
|
||||
|
||||
tt_assert(e->made_contact); /* All saved guards have been contacted */
|
||||
|
||||
tt_assert(e->bad_since); /* Verify bad_since timestamp */
|
||||
format_iso_time(str_time, e->bad_since);
|
||||
tt_str_op(str_time, ==, unlisted_since);
|
||||
tt_str_op(str_time, OP_EQ, unlisted_since);
|
||||
|
||||
/* The rest should be unset */
|
||||
tt_assert(!e->unreachable_since);
|
||||
@@ -456,7 +457,7 @@ test_entry_guards_parse_state_pathbias(void *arg)
|
||||
(void) arg;
|
||||
|
||||
/* The global entry guards smartlist should be empty now. */
|
||||
tt_int_op(smartlist_len(all_entry_guards), ==, 0);
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_EQ, 0);
|
||||
|
||||
{ /* Prepare the state entry */
|
||||
|
||||
@@ -492,11 +493,11 @@ test_entry_guards_parse_state_pathbias(void *arg)
|
||||
|
||||
/* Parse state */
|
||||
retval = entry_guards_parse_state(state, 1, &msg);
|
||||
tt_int_op(retval, >=, 0);
|
||||
tt_int_op(retval, OP_GE, 0);
|
||||
|
||||
/* Test that the guard was registered */
|
||||
all_entry_guards = get_entry_guards();
|
||||
tt_int_op(smartlist_len(all_entry_guards), ==, 1);
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_EQ, 1);
|
||||
|
||||
{ /* Test the path bias of this guard */
|
||||
const entry_guard_t *e = smartlist_get(all_entry_guards, 0);
|
||||
@@ -505,12 +506,13 @@ test_entry_guards_parse_state_pathbias(void *arg)
|
||||
tt_assert(!e->can_retry);
|
||||
|
||||
/* XXX tt_double_op doesn't support equality. Cast to int for now. */
|
||||
tt_int_op((int)e->circ_attempts, ==, (int)circ_attempts);
|
||||
tt_int_op((int)e->circ_successes, ==, (int)circ_successes);
|
||||
tt_int_op((int)e->successful_circuits_closed, ==, (int)successful_closed);
|
||||
tt_int_op((int)e->timeouts, ==, (int)timeouts);
|
||||
tt_int_op((int)e->collapsed_circuits, ==, (int)collapsed);
|
||||
tt_int_op((int)e->unusable_circuits, ==, (int)unusable);
|
||||
tt_int_op((int)e->circ_attempts, OP_EQ, (int)circ_attempts);
|
||||
tt_int_op((int)e->circ_successes, OP_EQ, (int)circ_successes);
|
||||
tt_int_op((int)e->successful_circuits_closed, OP_EQ,
|
||||
(int)successful_closed);
|
||||
tt_int_op((int)e->timeouts, OP_EQ, (int)timeouts);
|
||||
tt_int_op((int)e->collapsed_circuits, OP_EQ, (int)collapsed);
|
||||
tt_int_op((int)e->unusable_circuits, OP_EQ, (int)unusable);
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -537,17 +539,17 @@ test_entry_guards_set_from_config(void *arg)
|
||||
retval = routerset_parse(options->EntryNodes,
|
||||
entrynodes_str,
|
||||
"test_entrynodes");
|
||||
tt_int_op(retval, >=, 0);
|
||||
tt_int_op(retval, OP_GE, 0);
|
||||
|
||||
/* Read nodes from EntryNodes */
|
||||
entry_guards_set_from_config(options);
|
||||
|
||||
/* Test that only one guard was added. */
|
||||
tt_int_op(smartlist_len(all_entry_guards), ==, 1);
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_EQ, 1);
|
||||
|
||||
/* Make sure it was the guard we specified. */
|
||||
chosen_entry = choose_random_entry(NULL);
|
||||
tt_str_op(chosen_entry->ri->nickname, ==, entrynodes_str);
|
||||
tt_str_op(chosen_entry->ri->nickname, OP_EQ, entrynodes_str);
|
||||
|
||||
done:
|
||||
routerset_free(options->EntryNodes);
|
||||
@@ -569,59 +571,59 @@ test_entry_is_time_to_retry(void *arg)
|
||||
test_guard->unreachable_since = now - 1;
|
||||
|
||||
retval = entry_is_time_to_retry(test_guard,now);
|
||||
tt_int_op(retval,==,1);
|
||||
tt_int_op(retval,OP_EQ,1);
|
||||
|
||||
test_guard->unreachable_since = now - (6*60*60 - 1);
|
||||
test_guard->last_attempted = now - (60*60 + 1);
|
||||
|
||||
retval = entry_is_time_to_retry(test_guard,now);
|
||||
tt_int_op(retval,==,1);
|
||||
tt_int_op(retval,OP_EQ,1);
|
||||
|
||||
test_guard->last_attempted = now - (60*60 - 1);
|
||||
|
||||
retval = entry_is_time_to_retry(test_guard,now);
|
||||
tt_int_op(retval,==,0);
|
||||
tt_int_op(retval,OP_EQ,0);
|
||||
|
||||
test_guard->unreachable_since = now - (6*60*60 + 1);
|
||||
test_guard->last_attempted = now - (4*60*60 + 1);
|
||||
|
||||
retval = entry_is_time_to_retry(test_guard,now);
|
||||
tt_int_op(retval,==,1);
|
||||
tt_int_op(retval,OP_EQ,1);
|
||||
|
||||
test_guard->unreachable_since = now - (3*24*60*60 - 1);
|
||||
test_guard->last_attempted = now - (4*60*60 + 1);
|
||||
|
||||
retval = entry_is_time_to_retry(test_guard,now);
|
||||
tt_int_op(retval,==,1);
|
||||
tt_int_op(retval,OP_EQ,1);
|
||||
|
||||
test_guard->unreachable_since = now - (3*24*60*60 + 1);
|
||||
test_guard->last_attempted = now - (18*60*60 + 1);
|
||||
|
||||
retval = entry_is_time_to_retry(test_guard,now);
|
||||
tt_int_op(retval,==,1);
|
||||
tt_int_op(retval,OP_EQ,1);
|
||||
|
||||
test_guard->unreachable_since = now - (7*24*60*60 - 1);
|
||||
test_guard->last_attempted = now - (18*60*60 + 1);
|
||||
|
||||
retval = entry_is_time_to_retry(test_guard,now);
|
||||
tt_int_op(retval,==,1);
|
||||
tt_int_op(retval,OP_EQ,1);
|
||||
|
||||
test_guard->last_attempted = now - (18*60*60 - 1);
|
||||
|
||||
retval = entry_is_time_to_retry(test_guard,now);
|
||||
tt_int_op(retval,==,0);
|
||||
tt_int_op(retval,OP_EQ,0);
|
||||
|
||||
test_guard->unreachable_since = now - (7*24*60*60 + 1);
|
||||
test_guard->last_attempted = now - (36*60*60 + 1);
|
||||
|
||||
retval = entry_is_time_to_retry(test_guard,now);
|
||||
tt_int_op(retval,==,1);
|
||||
tt_int_op(retval,OP_EQ,1);
|
||||
|
||||
test_guard->unreachable_since = now - (7*24*60*60 + 1);
|
||||
test_guard->last_attempted = now - (36*60*60 + 1);
|
||||
|
||||
retval = entry_is_time_to_retry(test_guard,now);
|
||||
tt_int_op(retval,==,1);
|
||||
tt_int_op(retval,OP_EQ,1);
|
||||
|
||||
done:
|
||||
tor_free(test_guard);
|
||||
@@ -641,23 +643,23 @@ test_entry_is_live(void *arg)
|
||||
(void) arg;
|
||||
|
||||
/* The global entry guards smartlist should be empty now. */
|
||||
tt_int_op(smartlist_len(all_entry_guards), ==, 0);
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_EQ, 0);
|
||||
|
||||
/* Walk the nodelist and add all nodes as entry guards. */
|
||||
our_nodelist = nodelist_get_list();
|
||||
tt_int_op(smartlist_len(our_nodelist), ==, NUMBER_OF_DESCRIPTORS);
|
||||
tt_int_op(smartlist_len(our_nodelist), OP_EQ, NUMBER_OF_DESCRIPTORS);
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(our_nodelist, const node_t *, node) {
|
||||
const node_t *node_tmp;
|
||||
node_tmp = add_an_entry_guard(node, 0, 1, 0, 0);
|
||||
tt_assert(node_tmp);
|
||||
|
||||
tt_int_op(node->is_stable, ==, 0);
|
||||
tt_int_op(node->is_fast, ==, 0);
|
||||
tt_int_op(node->is_stable, OP_EQ, 0);
|
||||
tt_int_op(node->is_fast, OP_EQ, 0);
|
||||
} SMARTLIST_FOREACH_END(node);
|
||||
|
||||
/* Make sure the nodes were added as entry guards. */
|
||||
tt_int_op(smartlist_len(all_entry_guards), ==, NUMBER_OF_DESCRIPTORS);
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_EQ, NUMBER_OF_DESCRIPTORS);
|
||||
|
||||
/* Now get a random test entry that we will use for this unit test. */
|
||||
which_node = 3; /* (chosen by fair dice roll) */
|
||||
@@ -681,12 +683,12 @@ test_entry_is_live(void *arg)
|
||||
/* Don't impose any restrictions on the node. Should succeed. */
|
||||
test_node = entry_is_live(test_entry, 0, &msg);
|
||||
tt_assert(test_node);
|
||||
tt_ptr_op(test_node, ==, node_get_by_id(test_entry->identity));
|
||||
tt_ptr_op(test_node, OP_EQ, node_get_by_id(test_entry->identity));
|
||||
|
||||
/* Require descriptor for this node. It has one so it should succeed. */
|
||||
test_node = entry_is_live(test_entry, ENTRY_NEED_DESCRIPTOR, &msg);
|
||||
tt_assert(test_node);
|
||||
tt_ptr_op(test_node, ==, node_get_by_id(test_entry->identity));
|
||||
tt_ptr_op(test_node, OP_EQ, node_get_by_id(test_entry->identity));
|
||||
|
||||
done:
|
||||
; /* XXX */
|
||||
|
||||
+95
-92
@@ -24,35 +24,37 @@ test_ext_or_id_map(void *arg)
|
||||
(void)arg;
|
||||
|
||||
/* pre-initialization */
|
||||
tt_ptr_op(NULL, ==, connection_or_get_by_ext_or_id("xxxxxxxxxxxxxxxxxxxx"));
|
||||
tt_ptr_op(NULL, OP_EQ,
|
||||
connection_or_get_by_ext_or_id("xxxxxxxxxxxxxxxxxxxx"));
|
||||
|
||||
c1 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
|
||||
c2 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
|
||||
c3 = or_connection_new(CONN_TYPE_OR, AF_INET);
|
||||
|
||||
tt_ptr_op(c1->ext_or_conn_id, !=, NULL);
|
||||
tt_ptr_op(c2->ext_or_conn_id, !=, NULL);
|
||||
tt_ptr_op(c3->ext_or_conn_id, ==, NULL);
|
||||
tt_ptr_op(c1->ext_or_conn_id, OP_NE, NULL);
|
||||
tt_ptr_op(c2->ext_or_conn_id, OP_NE, NULL);
|
||||
tt_ptr_op(c3->ext_or_conn_id, OP_EQ, NULL);
|
||||
|
||||
tt_ptr_op(c1, ==, connection_or_get_by_ext_or_id(c1->ext_or_conn_id));
|
||||
tt_ptr_op(c2, ==, connection_or_get_by_ext_or_id(c2->ext_or_conn_id));
|
||||
tt_ptr_op(NULL, ==, connection_or_get_by_ext_or_id("xxxxxxxxxxxxxxxxxxxx"));
|
||||
tt_ptr_op(c1, OP_EQ, connection_or_get_by_ext_or_id(c1->ext_or_conn_id));
|
||||
tt_ptr_op(c2, OP_EQ, connection_or_get_by_ext_or_id(c2->ext_or_conn_id));
|
||||
tt_ptr_op(NULL, OP_EQ,
|
||||
connection_or_get_by_ext_or_id("xxxxxxxxxxxxxxxxxxxx"));
|
||||
|
||||
idp = tor_memdup(c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
|
||||
|
||||
/* Give c2 a new ID. */
|
||||
connection_or_set_ext_or_identifier(c2);
|
||||
tt_mem_op(idp, !=, c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
|
||||
tt_mem_op(idp, OP_NE, c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
|
||||
idp2 = tor_memdup(c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
|
||||
tt_assert(!tor_digest_is_zero(idp2));
|
||||
|
||||
tt_ptr_op(NULL, ==, connection_or_get_by_ext_or_id(idp));
|
||||
tt_ptr_op(c2, ==, connection_or_get_by_ext_or_id(idp2));
|
||||
tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp));
|
||||
tt_ptr_op(c2, OP_EQ, connection_or_get_by_ext_or_id(idp2));
|
||||
|
||||
/* Now remove it. */
|
||||
connection_or_remove_from_ext_or_id_map(c2);
|
||||
tt_ptr_op(NULL, ==, connection_or_get_by_ext_or_id(idp));
|
||||
tt_ptr_op(NULL, ==, connection_or_get_by_ext_or_id(idp2));
|
||||
tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp));
|
||||
tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp2));
|
||||
|
||||
done:
|
||||
if (c1)
|
||||
@@ -112,33 +114,33 @@ test_ext_or_write_command(void *arg)
|
||||
|
||||
/* Length too long */
|
||||
tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 100, "X", 100000),
|
||||
<, 0);
|
||||
OP_LT, 0);
|
||||
|
||||
/* Empty command */
|
||||
tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0x99, NULL, 0),
|
||||
==, 0);
|
||||
OP_EQ, 0);
|
||||
cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
|
||||
tt_int_op(sz, ==, 4);
|
||||
tt_mem_op(cp, ==, "\x00\x99\x00\x00", 4);
|
||||
tt_int_op(sz, OP_EQ, 4);
|
||||
tt_mem_op(cp, OP_EQ, "\x00\x99\x00\x00", 4);
|
||||
tor_free(cp);
|
||||
|
||||
/* Medium command. */
|
||||
tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0x99,
|
||||
"Wai\0Hello", 9), ==, 0);
|
||||
"Wai\0Hello", 9), OP_EQ, 0);
|
||||
cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
|
||||
tt_int_op(sz, ==, 13);
|
||||
tt_mem_op(cp, ==, "\x00\x99\x00\x09Wai\x00Hello", 13);
|
||||
tt_int_op(sz, OP_EQ, 13);
|
||||
tt_mem_op(cp, OP_EQ, "\x00\x99\x00\x09Wai\x00Hello", 13);
|
||||
tor_free(cp);
|
||||
|
||||
/* Long command */
|
||||
buf = tor_malloc(65535);
|
||||
memset(buf, 'x', 65535);
|
||||
tt_int_op(connection_write_ext_or_command(TO_CONN(c1), 0xf00d,
|
||||
buf, 65535), ==, 0);
|
||||
buf, 65535), OP_EQ, 0);
|
||||
cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz);
|
||||
tt_int_op(sz, ==, 65539);
|
||||
tt_mem_op(cp, ==, "\xf0\x0d\xff\xff", 4);
|
||||
tt_mem_op(cp+4, ==, buf, 65535);
|
||||
tt_int_op(sz, OP_EQ, 65539);
|
||||
tt_mem_op(cp, OP_EQ, "\xf0\x0d\xff\xff", 4);
|
||||
tt_mem_op(cp+4, OP_EQ, buf, 65535);
|
||||
tor_free(cp);
|
||||
|
||||
done:
|
||||
@@ -175,7 +177,7 @@ test_ext_or_init_auth(void *arg)
|
||||
tor_free(options->DataDirectory);
|
||||
options->DataDirectory = tor_strdup("foo");
|
||||
cp = get_ext_or_auth_cookie_file_name();
|
||||
tt_str_op(cp, ==, "foo"PATH_SEPARATOR"extended_orport_auth_cookie");
|
||||
tt_str_op(cp, OP_EQ, "foo"PATH_SEPARATOR"extended_orport_auth_cookie");
|
||||
tor_free(cp);
|
||||
|
||||
/* Shouldn't be initialized already, or our tests will be a bit
|
||||
@@ -187,30 +189,30 @@ test_ext_or_init_auth(void *arg)
|
||||
fn = get_fname("ext_cookie_file");
|
||||
options->ExtORPortCookieAuthFile = tor_strdup(fn);
|
||||
cp = get_ext_or_auth_cookie_file_name();
|
||||
tt_str_op(cp, ==, fn);
|
||||
tt_str_op(cp, OP_EQ, fn);
|
||||
tor_free(cp);
|
||||
|
||||
/* Test the initialization function with a broken
|
||||
write_bytes_to_file(). See if the problem is handled properly. */
|
||||
MOCK(write_bytes_to_file, write_bytes_to_file_fail);
|
||||
tt_int_op(-1, ==, init_ext_or_cookie_authentication(1));
|
||||
tt_int_op(ext_or_auth_cookie_is_set, ==, 0);
|
||||
tt_int_op(-1, OP_EQ, init_ext_or_cookie_authentication(1));
|
||||
tt_int_op(ext_or_auth_cookie_is_set, OP_EQ, 0);
|
||||
UNMOCK(write_bytes_to_file);
|
||||
|
||||
/* Now do the actual initialization. */
|
||||
tt_int_op(0, ==, init_ext_or_cookie_authentication(1));
|
||||
tt_int_op(ext_or_auth_cookie_is_set, ==, 1);
|
||||
tt_int_op(0, OP_EQ, init_ext_or_cookie_authentication(1));
|
||||
tt_int_op(ext_or_auth_cookie_is_set, OP_EQ, 1);
|
||||
cp = read_file_to_str(fn, RFTS_BIN, &st);
|
||||
tt_ptr_op(cp, !=, NULL);
|
||||
tt_u64_op((uint64_t)st.st_size, ==, 64);
|
||||
tt_mem_op(cp,==, "! Extended ORPort Auth Cookie !\x0a", 32);
|
||||
tt_mem_op(cp+32,==, ext_or_auth_cookie, 32);
|
||||
tt_ptr_op(cp, OP_NE, NULL);
|
||||
tt_u64_op((uint64_t)st.st_size, OP_EQ, 64);
|
||||
tt_mem_op(cp,OP_EQ, "! Extended ORPort Auth Cookie !\x0a", 32);
|
||||
tt_mem_op(cp+32,OP_EQ, ext_or_auth_cookie, 32);
|
||||
memcpy(cookie0, ext_or_auth_cookie, 32);
|
||||
tt_assert(!tor_mem_is_zero((char*)ext_or_auth_cookie, 32));
|
||||
|
||||
/* Operation should be idempotent. */
|
||||
tt_int_op(0, ==, init_ext_or_cookie_authentication(1));
|
||||
tt_mem_op(cookie0,==, ext_or_auth_cookie, 32);
|
||||
tt_int_op(0, OP_EQ, init_ext_or_cookie_authentication(1));
|
||||
tt_mem_op(cookie0,OP_EQ, ext_or_auth_cookie, 32);
|
||||
|
||||
done:
|
||||
tor_free(cp);
|
||||
@@ -237,8 +239,8 @@ test_ext_or_cookie_auth(void *arg)
|
||||
|
||||
(void)arg;
|
||||
|
||||
tt_int_op(strlen(client_hash_input), ==, 46+32+32);
|
||||
tt_int_op(strlen(server_hash_input), ==, 46+32+32);
|
||||
tt_int_op(strlen(client_hash_input), OP_EQ, 46+32+32);
|
||||
tt_int_op(strlen(server_hash_input), OP_EQ, 46+32+32);
|
||||
|
||||
ext_or_auth_cookie = tor_malloc_zero(32);
|
||||
memcpy(ext_or_auth_cookie, "s beside you? When I count, ther", 32);
|
||||
@@ -258,20 +260,20 @@ test_ext_or_cookie_auth(void *arg)
|
||||
*/
|
||||
|
||||
/* Wrong length */
|
||||
tt_int_op(-1, ==,
|
||||
tt_int_op(-1, OP_EQ,
|
||||
handle_client_auth_nonce(client_nonce, 33, &client_hash, &reply,
|
||||
&reply_len));
|
||||
tt_int_op(-1, ==,
|
||||
tt_int_op(-1, OP_EQ,
|
||||
handle_client_auth_nonce(client_nonce, 31, &client_hash, &reply,
|
||||
&reply_len));
|
||||
|
||||
/* Now let's try this for real! */
|
||||
tt_int_op(0, ==,
|
||||
tt_int_op(0, OP_EQ,
|
||||
handle_client_auth_nonce(client_nonce, 32, &client_hash, &reply,
|
||||
&reply_len));
|
||||
tt_int_op(reply_len, ==, 64);
|
||||
tt_ptr_op(reply, !=, NULL);
|
||||
tt_ptr_op(client_hash, !=, NULL);
|
||||
tt_int_op(reply_len, OP_EQ, 64);
|
||||
tt_ptr_op(reply, OP_NE, NULL);
|
||||
tt_ptr_op(client_hash, OP_NE, NULL);
|
||||
/* Fill in the server nonce into the hash inputs... */
|
||||
memcpy(server_hash_input+46+32, reply+32, 32);
|
||||
memcpy(client_hash_input+46+32, reply+32, 32);
|
||||
@@ -280,15 +282,15 @@ test_ext_or_cookie_auth(void *arg)
|
||||
46+32+32);
|
||||
crypto_hmac_sha256(hmac2, (char*)ext_or_auth_cookie, 32, client_hash_input,
|
||||
46+32+32);
|
||||
tt_mem_op(hmac1,==, reply, 32);
|
||||
tt_mem_op(hmac2,==, client_hash, 32);
|
||||
tt_mem_op(hmac1,OP_EQ, reply, 32);
|
||||
tt_mem_op(hmac2,OP_EQ, client_hash, 32);
|
||||
|
||||
/* Now do it again and make sure that the results are *different* */
|
||||
tt_int_op(0, ==,
|
||||
tt_int_op(0, OP_EQ,
|
||||
handle_client_auth_nonce(client_nonce, 32, &client_hash2, &reply2,
|
||||
&reply_len));
|
||||
tt_mem_op(reply2,!=, reply, reply_len);
|
||||
tt_mem_op(client_hash2,!=, client_hash, 32);
|
||||
tt_mem_op(reply2,OP_NE, reply, reply_len);
|
||||
tt_mem_op(client_hash2,OP_NE, client_hash, 32);
|
||||
/* But that this one checks out too. */
|
||||
memcpy(server_hash_input+46+32, reply2+32, 32);
|
||||
memcpy(client_hash_input+46+32, reply2+32, 32);
|
||||
@@ -297,8 +299,8 @@ test_ext_or_cookie_auth(void *arg)
|
||||
46+32+32);
|
||||
crypto_hmac_sha256(hmac2, (char*)ext_or_auth_cookie, 32, client_hash_input,
|
||||
46+32+32);
|
||||
tt_mem_op(hmac1,==, reply2, 32);
|
||||
tt_mem_op(hmac2,==, client_hash2, 32);
|
||||
tt_mem_op(hmac1,OP_EQ, reply2, 32);
|
||||
tt_mem_op(hmac2,OP_EQ, client_hash2, 32);
|
||||
|
||||
done:
|
||||
tor_free(reply);
|
||||
@@ -334,12 +336,12 @@ test_ext_or_cookie_auth_testvec(void *arg)
|
||||
|
||||
MOCK(crypto_rand, crypto_rand_return_tse_str);
|
||||
|
||||
tt_int_op(0, ==,
|
||||
tt_int_op(0, OP_EQ,
|
||||
handle_client_auth_nonce(client_nonce, 32, &client_hash, &reply,
|
||||
&reply_len));
|
||||
tt_ptr_op(reply, !=, NULL );
|
||||
tt_uint_op(reply_len, ==, 64);
|
||||
tt_mem_op(reply+32,==, "te road There is always another ", 32);
|
||||
tt_ptr_op(reply, OP_NE, NULL );
|
||||
tt_uint_op(reply_len, OP_EQ, 64);
|
||||
tt_mem_op(reply+32,OP_EQ, "te road There is always another ", 32);
|
||||
/* HMACSHA256("Gliding wrapt in a brown mantle,"
|
||||
* "ExtORPort authentication server-to-client hash"
|
||||
* "But when I look ahead up the write road There is always another ");
|
||||
@@ -402,11 +404,11 @@ handshake_start(or_connection_t *conn, int receiving)
|
||||
} while (0)
|
||||
#define CONTAINS(s,n) \
|
||||
do { \
|
||||
tt_int_op((n), <=, sizeof(b)); \
|
||||
tt_int_op(buf_datalen(TO_CONN(conn)->outbuf), ==, (n)); \
|
||||
tt_int_op((n), OP_LE, sizeof(b)); \
|
||||
tt_int_op(buf_datalen(TO_CONN(conn)->outbuf), OP_EQ, (n)); \
|
||||
if ((n)) { \
|
||||
fetch_from_buf(b, (n), TO_CONN(conn)->outbuf); \
|
||||
tt_mem_op(b, ==, (s), (n)); \
|
||||
tt_mem_op(b, OP_EQ, (s), (n)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@@ -416,14 +418,15 @@ do_ext_or_handshake(or_connection_t *conn)
|
||||
{
|
||||
char b[256];
|
||||
|
||||
tt_int_op(0, ==, connection_ext_or_start_auth(conn));
|
||||
tt_int_op(0, OP_EQ, connection_ext_or_start_auth(conn));
|
||||
CONTAINS("\x01\x00", 2);
|
||||
WRITE("\x01", 1);
|
||||
WRITE("But when I look ahead up the whi", 32);
|
||||
MOCK(crypto_rand, crypto_rand_return_tse_str);
|
||||
tt_int_op(0, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
UNMOCK(crypto_rand);
|
||||
tt_int_op(TO_CONN(conn)->state, ==, EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH);
|
||||
tt_int_op(TO_CONN(conn)->state, OP_EQ,
|
||||
EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH);
|
||||
CONTAINS("\xec\x80\xed\x6e\x54\x6d\x3b\x36\xfd\xfc\x22\xfe\x13\x15\x41\x6b"
|
||||
"\x02\x9f\x1a\xde\x76\x10\xd9\x10\x87\x8b\x62\xee\xb7\x40\x38\x21"
|
||||
"te road There is always another ", 64);
|
||||
@@ -431,10 +434,10 @@ do_ext_or_handshake(or_connection_t *conn)
|
||||
WRITE("\xab\x39\x17\x32\xdd\x2e\xd9\x68\xcd\x40\xc0\x87\xd1\xb1\xf2\x5b"
|
||||
"\x33\xb3\xcd\x77\xff\x79\xbd\x80\xc2\x07\x4b\xbf\x43\x81\x19\xa2",
|
||||
32);
|
||||
tt_int_op(0, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
CONTAINS("\x01", 1);
|
||||
tt_assert(! TO_CONN(conn)->marked_for_close);
|
||||
tt_int_op(TO_CONN(conn)->state, ==, EXT_OR_CONN_STATE_OPEN);
|
||||
tt_int_op(TO_CONN(conn)->state, OP_EQ, EXT_OR_CONN_STATE_OPEN);
|
||||
|
||||
done: ;
|
||||
}
|
||||
@@ -456,14 +459,14 @@ test_ext_or_handshake(void *arg)
|
||||
init_connection_lists();
|
||||
|
||||
conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
|
||||
tt_int_op(0, ==, connection_ext_or_start_auth(conn));
|
||||
tt_int_op(0, OP_EQ, connection_ext_or_start_auth(conn));
|
||||
/* The server starts by telling us about the one supported authtype. */
|
||||
CONTAINS("\x01\x00", 2);
|
||||
/* Say the client hasn't responded yet. */
|
||||
tt_int_op(0, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
/* Let's say the client replies badly. */
|
||||
WRITE("\x99", 1);
|
||||
tt_int_op(-1, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
CONTAINS("", 0);
|
||||
tt_assert(TO_CONN(conn)->marked_for_close);
|
||||
close_closeable_connections();
|
||||
@@ -471,23 +474,23 @@ test_ext_or_handshake(void *arg)
|
||||
|
||||
/* Okay, try again. */
|
||||
conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
|
||||
tt_int_op(0, ==, connection_ext_or_start_auth(conn));
|
||||
tt_int_op(0, OP_EQ, connection_ext_or_start_auth(conn));
|
||||
CONTAINS("\x01\x00", 2);
|
||||
/* Let's say the client replies sensibly this time. "Yes, AUTHTYPE_COOKIE
|
||||
* sounds delicious. Let's have some of that!" */
|
||||
WRITE("\x01", 1);
|
||||
/* Let's say that the client also sends part of a nonce. */
|
||||
WRITE("But when I look ", 16);
|
||||
tt_int_op(0, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
CONTAINS("", 0);
|
||||
tt_int_op(TO_CONN(conn)->state, ==,
|
||||
tt_int_op(TO_CONN(conn)->state, OP_EQ,
|
||||
EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE);
|
||||
/* Pump it again. Nothing should happen. */
|
||||
tt_int_op(0, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
/* send the rest of the nonce. */
|
||||
WRITE("ahead up the whi", 16);
|
||||
MOCK(crypto_rand, crypto_rand_return_tse_str);
|
||||
tt_int_op(0, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
UNMOCK(crypto_rand);
|
||||
/* We should get the right reply from the server. */
|
||||
CONTAINS("\xec\x80\xed\x6e\x54\x6d\x3b\x36\xfd\xfc\x22\xfe\x13\x15\x41\x6b"
|
||||
@@ -496,7 +499,7 @@ test_ext_or_handshake(void *arg)
|
||||
/* Send the wrong response. */
|
||||
WRITE("not with a bang but a whimper...", 32);
|
||||
MOCK(control_event_bootstrap_problem, ignore_bootstrap_problem);
|
||||
tt_int_op(-1, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
CONTAINS("\x00", 1);
|
||||
tt_assert(TO_CONN(conn)->marked_for_close);
|
||||
/* XXXX Hold-open-until-flushed. */
|
||||
@@ -515,32 +518,32 @@ test_ext_or_handshake(void *arg)
|
||||
/* Now let's run through some messages. */
|
||||
/* First let's send some junk and make sure it's ignored. */
|
||||
WRITE("\xff\xf0\x00\x03""ABC", 7);
|
||||
tt_int_op(0, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
CONTAINS("", 0);
|
||||
/* Now let's send a USERADDR command. */
|
||||
WRITE("\x00\x01\x00\x0c""1.2.3.4:5678", 16);
|
||||
tt_int_op(0, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(TO_CONN(conn)->port, ==, 5678);
|
||||
tt_int_op(tor_addr_to_ipv4h(&TO_CONN(conn)->addr), ==, 0x01020304);
|
||||
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(TO_CONN(conn)->port, OP_EQ, 5678);
|
||||
tt_int_op(tor_addr_to_ipv4h(&TO_CONN(conn)->addr), OP_EQ, 0x01020304);
|
||||
/* Now let's send a TRANSPORT command. */
|
||||
WRITE("\x00\x02\x00\x07""rfc1149", 11);
|
||||
tt_int_op(0, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_ptr_op(NULL, !=, conn->ext_or_transport);
|
||||
tt_str_op("rfc1149", ==, conn->ext_or_transport);
|
||||
tt_int_op(is_reading,==,1);
|
||||
tt_int_op(TO_CONN(conn)->state, ==, EXT_OR_CONN_STATE_OPEN);
|
||||
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
tt_ptr_op(NULL, OP_NE, conn->ext_or_transport);
|
||||
tt_str_op("rfc1149", OP_EQ, conn->ext_or_transport);
|
||||
tt_int_op(is_reading,OP_EQ,1);
|
||||
tt_int_op(TO_CONN(conn)->state, OP_EQ, EXT_OR_CONN_STATE_OPEN);
|
||||
/* DONE */
|
||||
WRITE("\x00\x00\x00\x00", 4);
|
||||
tt_int_op(0, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(TO_CONN(conn)->state, ==, EXT_OR_CONN_STATE_FLUSHING);
|
||||
tt_int_op(is_reading,==,0);
|
||||
tt_int_op(0, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(TO_CONN(conn)->state, OP_EQ, EXT_OR_CONN_STATE_FLUSHING);
|
||||
tt_int_op(is_reading,OP_EQ,0);
|
||||
CONTAINS("\x10\x00\x00\x00", 4);
|
||||
tt_int_op(handshake_start_called,==,0);
|
||||
tt_int_op(0, ==, connection_ext_or_finished_flushing(conn));
|
||||
tt_int_op(is_reading,==,1);
|
||||
tt_int_op(handshake_start_called,==,1);
|
||||
tt_int_op(TO_CONN(conn)->type, ==, CONN_TYPE_OR);
|
||||
tt_int_op(TO_CONN(conn)->state, ==, 0);
|
||||
tt_int_op(handshake_start_called,OP_EQ,0);
|
||||
tt_int_op(0, OP_EQ, connection_ext_or_finished_flushing(conn));
|
||||
tt_int_op(is_reading,OP_EQ,1);
|
||||
tt_int_op(handshake_start_called,OP_EQ,1);
|
||||
tt_int_op(TO_CONN(conn)->type, OP_EQ, CONN_TYPE_OR);
|
||||
tt_int_op(TO_CONN(conn)->state, OP_EQ, 0);
|
||||
close_closeable_connections();
|
||||
conn = NULL;
|
||||
|
||||
@@ -551,7 +554,7 @@ test_ext_or_handshake(void *arg)
|
||||
/* USERADDR command with an extra NUL byte */
|
||||
WRITE("\x00\x01\x00\x0d""1.2.3.4:5678\x00", 17);
|
||||
MOCK(control_event_bootstrap_problem, ignore_bootstrap_problem);
|
||||
tt_int_op(-1, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
CONTAINS("", 0);
|
||||
tt_assert(TO_CONN(conn)->marked_for_close);
|
||||
close_closeable_connections();
|
||||
@@ -564,7 +567,7 @@ test_ext_or_handshake(void *arg)
|
||||
/* TRANSPORT command with an extra NUL byte */
|
||||
WRITE("\x00\x02\x00\x08""rfc1149\x00", 12);
|
||||
MOCK(control_event_bootstrap_problem, ignore_bootstrap_problem);
|
||||
tt_int_op(-1, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
CONTAINS("", 0);
|
||||
tt_assert(TO_CONN(conn)->marked_for_close);
|
||||
close_closeable_connections();
|
||||
@@ -578,7 +581,7 @@ test_ext_or_handshake(void *arg)
|
||||
C-identifier) */
|
||||
WRITE("\x00\x02\x00\x07""rf*1149", 11);
|
||||
MOCK(control_event_bootstrap_problem, ignore_bootstrap_problem);
|
||||
tt_int_op(-1, ==, connection_ext_or_process_inbuf(conn));
|
||||
tt_int_op(-1, OP_EQ, connection_ext_or_process_inbuf(conn));
|
||||
CONTAINS("", 0);
|
||||
tt_assert(TO_CONN(conn)->marked_for_close);
|
||||
close_closeable_connections();
|
||||
|
||||
+10
-8
@@ -85,7 +85,7 @@ test_hs_desc_event(void *arg)
|
||||
expected_msg = "650 HS_DESC REQUESTED "STR_HS_ADDR" NO_AUTH "\
|
||||
STR_HSDIR_EXIST_LONGNAME" "STR_HS_ID"\r\n";
|
||||
tt_assert(received_msg);
|
||||
tt_str_op(received_msg,==, expected_msg);
|
||||
tt_str_op(received_msg,OP_EQ, expected_msg);
|
||||
tor_free(received_msg);
|
||||
|
||||
/* test received event */
|
||||
@@ -94,25 +94,27 @@ test_hs_desc_event(void *arg)
|
||||
expected_msg = "650 HS_DESC RECEIVED "STR_HS_ADDR" BASIC_AUTH "\
|
||||
STR_HSDIR_EXIST_LONGNAME"\r\n";
|
||||
tt_assert(received_msg);
|
||||
tt_str_op(received_msg,==, expected_msg);
|
||||
tt_str_op(received_msg,OP_EQ, expected_msg);
|
||||
tor_free(received_msg);
|
||||
|
||||
/* test failed event */
|
||||
rend_query.auth_type = 2;
|
||||
control_event_hs_descriptor_failed(&rend_query, HSDIR_NONE_EXIST_ID);
|
||||
control_event_hs_descriptor_failed(&rend_query, HSDIR_NONE_EXIST_ID,
|
||||
"QUERY_REJECTED");
|
||||
expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" STEALTH_AUTH "\
|
||||
STR_HSDIR_NONE_EXIST_LONGNAME"\r\n";
|
||||
STR_HSDIR_NONE_EXIST_LONGNAME" REASON=QUERY_REJECTED\r\n";
|
||||
tt_assert(received_msg);
|
||||
tt_str_op(received_msg,==, expected_msg);
|
||||
tt_str_op(received_msg,OP_EQ, expected_msg);
|
||||
tor_free(received_msg);
|
||||
|
||||
/* test invalid auth type */
|
||||
rend_query.auth_type = 999;
|
||||
control_event_hs_descriptor_failed(&rend_query, HSDIR_EXIST_ID);
|
||||
control_event_hs_descriptor_failed(&rend_query, HSDIR_EXIST_ID,
|
||||
"QUERY_REJECTED");
|
||||
expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" UNKNOWN "\
|
||||
STR_HSDIR_EXIST_LONGNAME"\r\n";
|
||||
STR_HSDIR_EXIST_LONGNAME" REASON=QUERY_REJECTED\r\n";
|
||||
tt_assert(received_msg);
|
||||
tt_str_op(received_msg,==, expected_msg);
|
||||
tt_str_op(received_msg,OP_EQ, expected_msg);
|
||||
tor_free(received_msg);
|
||||
|
||||
done:
|
||||
|
||||
@@ -310,7 +310,7 @@ do_parse_test(uint8_t *plaintext, size_t plaintext_len, int phase)
|
||||
parsed_req = rend_service_begin_parse_intro(cell, cell_len, 2, &err_msg);
|
||||
tt_assert(parsed_req);
|
||||
tt_assert(!err_msg);
|
||||
tt_mem_op(parsed_req->pk,==, digest, DIGEST_LEN);
|
||||
tt_mem_op(parsed_req->pk,OP_EQ, digest, DIGEST_LEN);
|
||||
tt_assert(parsed_req->ciphertext);
|
||||
tt_assert(parsed_req->ciphertext_len > 0);
|
||||
|
||||
|
||||
+15
-15
@@ -22,8 +22,8 @@ test_get_sigsafe_err_fds(void *arg)
|
||||
init_logging(1);
|
||||
|
||||
n = tor_log_get_sigsafe_err_fds(&fds);
|
||||
tt_int_op(n, ==, 1);
|
||||
tt_int_op(fds[0], ==, STDERR_FILENO);
|
||||
tt_int_op(n, OP_EQ, 1);
|
||||
tt_int_op(fds[0], OP_EQ, STDERR_FILENO);
|
||||
|
||||
set_log_severity_config(LOG_WARN, LOG_ERR, &include_bug);
|
||||
set_log_severity_config(LOG_WARN, LOG_ERR, &no_bug);
|
||||
@@ -40,26 +40,26 @@ test_get_sigsafe_err_fds(void *arg)
|
||||
tor_log_update_sigsafe_err_fds();
|
||||
|
||||
n = tor_log_get_sigsafe_err_fds(&fds);
|
||||
tt_int_op(n, ==, 2);
|
||||
tt_int_op(fds[0], ==, STDERR_FILENO);
|
||||
tt_int_op(fds[1], ==, 3);
|
||||
tt_int_op(n, OP_EQ, 2);
|
||||
tt_int_op(fds[0], OP_EQ, STDERR_FILENO);
|
||||
tt_int_op(fds[1], OP_EQ, 3);
|
||||
|
||||
/* Allow STDOUT to replace STDERR. */
|
||||
add_stream_log(&include_bug, "dummy-4", STDOUT_FILENO);
|
||||
tor_log_update_sigsafe_err_fds();
|
||||
n = tor_log_get_sigsafe_err_fds(&fds);
|
||||
tt_int_op(n, ==, 2);
|
||||
tt_int_op(fds[0], ==, 3);
|
||||
tt_int_op(fds[1], ==, STDOUT_FILENO);
|
||||
tt_int_op(n, OP_EQ, 2);
|
||||
tt_int_op(fds[0], OP_EQ, 3);
|
||||
tt_int_op(fds[1], OP_EQ, STDOUT_FILENO);
|
||||
|
||||
/* But don't allow it to replace explicit STDERR. */
|
||||
add_stream_log(&include_bug, "dummy-5", STDERR_FILENO);
|
||||
tor_log_update_sigsafe_err_fds();
|
||||
n = tor_log_get_sigsafe_err_fds(&fds);
|
||||
tt_int_op(n, ==, 3);
|
||||
tt_int_op(fds[0], ==, STDERR_FILENO);
|
||||
tt_int_op(fds[1], ==, STDOUT_FILENO);
|
||||
tt_int_op(fds[2], ==, 3);
|
||||
tt_int_op(n, OP_EQ, 3);
|
||||
tt_int_op(fds[0], OP_EQ, STDERR_FILENO);
|
||||
tt_int_op(fds[1], OP_EQ, STDOUT_FILENO);
|
||||
tt_int_op(fds[2], OP_EQ, 3);
|
||||
|
||||
/* Don't overflow the array. */
|
||||
{
|
||||
@@ -70,7 +70,7 @@ test_get_sigsafe_err_fds(void *arg)
|
||||
}
|
||||
tor_log_update_sigsafe_err_fds();
|
||||
n = tor_log_get_sigsafe_err_fds(&fds);
|
||||
tt_int_op(n, ==, 8);
|
||||
tt_int_op(n, OP_EQ, 8);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -109,7 +109,7 @@ test_sigsafe_err(void *arg)
|
||||
|
||||
tt_assert(content != NULL);
|
||||
tor_split_lines(lines, content, (int)strlen(content));
|
||||
tt_int_op(smartlist_len(lines), >=, 5);
|
||||
tt_int_op(smartlist_len(lines), OP_GE, 5);
|
||||
|
||||
if (strstr(smartlist_get(lines, 0), "opening new log file"))
|
||||
smartlist_del_keeporder(lines, 0);
|
||||
@@ -119,7 +119,7 @@ test_sigsafe_err(void *arg)
|
||||
tt_assert(!strcmpstart(smartlist_get(lines, 2), "Minimal."));
|
||||
/* Next line is blank. */
|
||||
tt_assert(!strcmpstart(smartlist_get(lines, 3), "=============="));
|
||||
tt_str_op(smartlist_get(lines, 4), ==,
|
||||
tt_str_op(smartlist_get(lines, 4), OP_EQ,
|
||||
"Testing any attempt to manually log from a signal.");
|
||||
|
||||
done:
|
||||
|
||||
+78
-78
@@ -75,9 +75,9 @@ test_md_cache(void *data)
|
||||
tor_free(options->DataDirectory);
|
||||
options->DataDirectory = tor_strdup(get_fname("md_datadir_test"));
|
||||
#ifdef _WIN32
|
||||
tt_int_op(0, ==, mkdir(options->DataDirectory));
|
||||
tt_int_op(0, OP_EQ, mkdir(options->DataDirectory));
|
||||
#else
|
||||
tt_int_op(0, ==, mkdir(options->DataDirectory, 0700));
|
||||
tt_int_op(0, OP_EQ, mkdir(options->DataDirectory, 0700));
|
||||
#endif
|
||||
|
||||
tt_assert(!strcmpstart(test_md3_noannotation, "onion-key"));
|
||||
@@ -91,7 +91,7 @@ test_md_cache(void *data)
|
||||
|
||||
added = microdescs_add_to_cache(mc, test_md1, NULL, SAVED_NOWHERE, 0,
|
||||
time1, NULL);
|
||||
tt_int_op(1, ==, smartlist_len(added));
|
||||
tt_int_op(1, OP_EQ, smartlist_len(added));
|
||||
md1 = smartlist_get(added, 0);
|
||||
smartlist_free(added);
|
||||
added = NULL;
|
||||
@@ -100,7 +100,7 @@ test_md_cache(void *data)
|
||||
added = microdescs_add_to_cache(mc, test_md2, NULL, SAVED_NOWHERE, 0,
|
||||
time2, wanted);
|
||||
/* Should fail, since we didn't list test_md2's digest in wanted */
|
||||
tt_int_op(0, ==, smartlist_len(added));
|
||||
tt_int_op(0, OP_EQ, smartlist_len(added));
|
||||
smartlist_free(added);
|
||||
added = NULL;
|
||||
|
||||
@@ -109,75 +109,75 @@ test_md_cache(void *data)
|
||||
added = microdescs_add_to_cache(mc, test_md2, NULL, SAVED_NOWHERE, 0,
|
||||
time2, wanted);
|
||||
/* Now it can work. md2 should have been added */
|
||||
tt_int_op(1, ==, smartlist_len(added));
|
||||
tt_int_op(1, OP_EQ, smartlist_len(added));
|
||||
md2 = smartlist_get(added, 0);
|
||||
/* And it should have gotten removed from 'wanted' */
|
||||
tt_int_op(smartlist_len(wanted), ==, 1);
|
||||
tt_mem_op(smartlist_get(wanted, 0), ==, d3, DIGEST256_LEN);
|
||||
tt_int_op(smartlist_len(wanted), OP_EQ, 1);
|
||||
tt_mem_op(smartlist_get(wanted, 0), OP_EQ, d3, DIGEST256_LEN);
|
||||
smartlist_free(added);
|
||||
added = NULL;
|
||||
|
||||
added = microdescs_add_to_cache(mc, test_md3, NULL,
|
||||
SAVED_NOWHERE, 0, -1, NULL);
|
||||
/* Must fail, since SAVED_NOWHERE precludes annotations */
|
||||
tt_int_op(0, ==, smartlist_len(added));
|
||||
tt_int_op(0, OP_EQ, smartlist_len(added));
|
||||
smartlist_free(added);
|
||||
added = NULL;
|
||||
|
||||
added = microdescs_add_to_cache(mc, test_md3_noannotation, NULL,
|
||||
SAVED_NOWHERE, 0, time3, NULL);
|
||||
/* Now it can work */
|
||||
tt_int_op(1, ==, smartlist_len(added));
|
||||
tt_int_op(1, OP_EQ, smartlist_len(added));
|
||||
md3 = smartlist_get(added, 0);
|
||||
smartlist_free(added);
|
||||
added = NULL;
|
||||
|
||||
/* Okay. We added 1...3. Let's poke them to see how they look, and make
|
||||
* sure they're really in the journal. */
|
||||
tt_ptr_op(md1, ==, microdesc_cache_lookup_by_digest256(mc, d1));
|
||||
tt_ptr_op(md2, ==, microdesc_cache_lookup_by_digest256(mc, d2));
|
||||
tt_ptr_op(md3, ==, microdesc_cache_lookup_by_digest256(mc, d3));
|
||||
tt_ptr_op(md1, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d1));
|
||||
tt_ptr_op(md2, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d2));
|
||||
tt_ptr_op(md3, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d3));
|
||||
|
||||
tt_int_op(md1->last_listed, ==, time1);
|
||||
tt_int_op(md2->last_listed, ==, time2);
|
||||
tt_int_op(md3->last_listed, ==, time3);
|
||||
tt_int_op(md1->last_listed, OP_EQ, time1);
|
||||
tt_int_op(md2->last_listed, OP_EQ, time2);
|
||||
tt_int_op(md3->last_listed, OP_EQ, time3);
|
||||
|
||||
tt_int_op(md1->saved_location, ==, SAVED_IN_JOURNAL);
|
||||
tt_int_op(md2->saved_location, ==, SAVED_IN_JOURNAL);
|
||||
tt_int_op(md3->saved_location, ==, SAVED_IN_JOURNAL);
|
||||
tt_int_op(md1->saved_location, OP_EQ, SAVED_IN_JOURNAL);
|
||||
tt_int_op(md2->saved_location, OP_EQ, SAVED_IN_JOURNAL);
|
||||
tt_int_op(md3->saved_location, OP_EQ, SAVED_IN_JOURNAL);
|
||||
|
||||
tt_int_op(md1->bodylen, ==, strlen(test_md1));
|
||||
tt_int_op(md2->bodylen, ==, strlen(test_md2));
|
||||
tt_int_op(md3->bodylen, ==, strlen(test_md3_noannotation));
|
||||
tt_mem_op(md1->body, ==, test_md1, strlen(test_md1));
|
||||
tt_mem_op(md2->body, ==, test_md2, strlen(test_md2));
|
||||
tt_mem_op(md3->body, ==, test_md3_noannotation,
|
||||
tt_int_op(md1->bodylen, OP_EQ, strlen(test_md1));
|
||||
tt_int_op(md2->bodylen, OP_EQ, strlen(test_md2));
|
||||
tt_int_op(md3->bodylen, OP_EQ, strlen(test_md3_noannotation));
|
||||
tt_mem_op(md1->body, OP_EQ, test_md1, strlen(test_md1));
|
||||
tt_mem_op(md2->body, OP_EQ, test_md2, strlen(test_md2));
|
||||
tt_mem_op(md3->body, OP_EQ, test_md3_noannotation,
|
||||
strlen(test_md3_noannotation));
|
||||
|
||||
tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs.new",
|
||||
options->DataDirectory);
|
||||
s = read_file_to_str(fn, RFTS_BIN, NULL);
|
||||
tt_assert(s);
|
||||
tt_mem_op(md1->body, ==, s + md1->off, md1->bodylen);
|
||||
tt_mem_op(md2->body, ==, s + md2->off, md2->bodylen);
|
||||
tt_mem_op(md3->body, ==, s + md3->off, md3->bodylen);
|
||||
tt_mem_op(md1->body, OP_EQ, s + md1->off, md1->bodylen);
|
||||
tt_mem_op(md2->body, OP_EQ, s + md2->off, md2->bodylen);
|
||||
tt_mem_op(md3->body, OP_EQ, s + md3->off, md3->bodylen);
|
||||
|
||||
tt_ptr_op(md1->family, ==, NULL);
|
||||
tt_ptr_op(md3->family, !=, NULL);
|
||||
tt_int_op(smartlist_len(md3->family), ==, 3);
|
||||
tt_str_op(smartlist_get(md3->family, 0), ==, "nodeX");
|
||||
tt_ptr_op(md1->family, OP_EQ, NULL);
|
||||
tt_ptr_op(md3->family, OP_NE, NULL);
|
||||
tt_int_op(smartlist_len(md3->family), OP_EQ, 3);
|
||||
tt_str_op(smartlist_get(md3->family, 0), OP_EQ, "nodeX");
|
||||
|
||||
/* Now rebuild the cache! */
|
||||
tt_int_op(microdesc_cache_rebuild(mc, 1), ==, 0);
|
||||
tt_int_op(microdesc_cache_rebuild(mc, 1), OP_EQ, 0);
|
||||
|
||||
tt_int_op(md1->saved_location, ==, SAVED_IN_CACHE);
|
||||
tt_int_op(md2->saved_location, ==, SAVED_IN_CACHE);
|
||||
tt_int_op(md3->saved_location, ==, SAVED_IN_CACHE);
|
||||
tt_int_op(md1->saved_location, OP_EQ, SAVED_IN_CACHE);
|
||||
tt_int_op(md2->saved_location, OP_EQ, SAVED_IN_CACHE);
|
||||
tt_int_op(md3->saved_location, OP_EQ, SAVED_IN_CACHE);
|
||||
|
||||
/* The journal should be empty now */
|
||||
tor_free(s);
|
||||
s = read_file_to_str(fn, RFTS_BIN, NULL);
|
||||
tt_str_op(s, ==, "");
|
||||
tt_str_op(s, OP_EQ, "");
|
||||
tor_free(s);
|
||||
tor_free(fn);
|
||||
|
||||
@@ -185,9 +185,9 @@ test_md_cache(void *data)
|
||||
tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs",
|
||||
options->DataDirectory);
|
||||
s = read_file_to_str(fn, RFTS_BIN, NULL);
|
||||
tt_mem_op(md1->body, ==, s + md1->off, strlen(test_md1));
|
||||
tt_mem_op(md2->body, ==, s + md2->off, strlen(test_md2));
|
||||
tt_mem_op(md3->body, ==, s + md3->off, strlen(test_md3_noannotation));
|
||||
tt_mem_op(md1->body, OP_EQ, s + md1->off, strlen(test_md1));
|
||||
tt_mem_op(md2->body, OP_EQ, s + md2->off, strlen(test_md2));
|
||||
tt_mem_op(md3->body, OP_EQ, s + md3->off, strlen(test_md3_noannotation));
|
||||
|
||||
/* Okay, now we are going to forget about the cache entirely, and reload it
|
||||
* from the disk. */
|
||||
@@ -199,41 +199,41 @@ test_md_cache(void *data)
|
||||
tt_assert(md1);
|
||||
tt_assert(md2);
|
||||
tt_assert(md3);
|
||||
tt_mem_op(md1->body, ==, s + md1->off, strlen(test_md1));
|
||||
tt_mem_op(md2->body, ==, s + md2->off, strlen(test_md2));
|
||||
tt_mem_op(md3->body, ==, s + md3->off, strlen(test_md3_noannotation));
|
||||
tt_mem_op(md1->body, OP_EQ, s + md1->off, strlen(test_md1));
|
||||
tt_mem_op(md2->body, OP_EQ, s + md2->off, strlen(test_md2));
|
||||
tt_mem_op(md3->body, OP_EQ, s + md3->off, strlen(test_md3_noannotation));
|
||||
|
||||
tt_int_op(md1->last_listed, ==, time1);
|
||||
tt_int_op(md2->last_listed, ==, time2);
|
||||
tt_int_op(md3->last_listed, ==, time3);
|
||||
tt_int_op(md1->last_listed, OP_EQ, time1);
|
||||
tt_int_op(md2->last_listed, OP_EQ, time2);
|
||||
tt_int_op(md3->last_listed, OP_EQ, time3);
|
||||
|
||||
/* Okay, now we are going to clear out everything older than a week old.
|
||||
* In practice, that means md3 */
|
||||
microdesc_cache_clean(mc, time(NULL)-7*24*60*60, 1/*force*/);
|
||||
tt_ptr_op(md1, ==, microdesc_cache_lookup_by_digest256(mc, d1));
|
||||
tt_ptr_op(md2, ==, microdesc_cache_lookup_by_digest256(mc, d2));
|
||||
tt_ptr_op(NULL, ==, microdesc_cache_lookup_by_digest256(mc, d3));
|
||||
tt_ptr_op(md1, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d1));
|
||||
tt_ptr_op(md2, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d2));
|
||||
tt_ptr_op(NULL, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d3));
|
||||
md3 = NULL; /* it's history now! */
|
||||
|
||||
/* rebuild again, make sure it stays gone. */
|
||||
tt_int_op(microdesc_cache_rebuild(mc, 1), ==, 0);
|
||||
tt_ptr_op(md1, ==, microdesc_cache_lookup_by_digest256(mc, d1));
|
||||
tt_ptr_op(md2, ==, microdesc_cache_lookup_by_digest256(mc, d2));
|
||||
tt_ptr_op(NULL, ==, microdesc_cache_lookup_by_digest256(mc, d3));
|
||||
tt_int_op(microdesc_cache_rebuild(mc, 1), OP_EQ, 0);
|
||||
tt_ptr_op(md1, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d1));
|
||||
tt_ptr_op(md2, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d2));
|
||||
tt_ptr_op(NULL, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d3));
|
||||
|
||||
/* Re-add md3, and make sure we can rebuild the cache. */
|
||||
added = microdescs_add_to_cache(mc, test_md3_noannotation, NULL,
|
||||
SAVED_NOWHERE, 0, time3, NULL);
|
||||
tt_int_op(1, ==, smartlist_len(added));
|
||||
tt_int_op(1, OP_EQ, smartlist_len(added));
|
||||
md3 = smartlist_get(added, 0);
|
||||
smartlist_free(added);
|
||||
added = NULL;
|
||||
tt_int_op(md1->saved_location, ==, SAVED_IN_CACHE);
|
||||
tt_int_op(md2->saved_location, ==, SAVED_IN_CACHE);
|
||||
tt_int_op(md3->saved_location, ==, SAVED_IN_JOURNAL);
|
||||
tt_int_op(md1->saved_location, OP_EQ, SAVED_IN_CACHE);
|
||||
tt_int_op(md2->saved_location, OP_EQ, SAVED_IN_CACHE);
|
||||
tt_int_op(md3->saved_location, OP_EQ, SAVED_IN_JOURNAL);
|
||||
|
||||
tt_int_op(microdesc_cache_rebuild(mc, 1), ==, 0);
|
||||
tt_int_op(md3->saved_location, ==, SAVED_IN_CACHE);
|
||||
tt_int_op(microdesc_cache_rebuild(mc, 1), OP_EQ, 0);
|
||||
tt_int_op(md3->saved_location, OP_EQ, SAVED_IN_CACHE);
|
||||
|
||||
done:
|
||||
if (options)
|
||||
@@ -273,9 +273,9 @@ test_md_cache_broken(void *data)
|
||||
options->DataDirectory = tor_strdup(get_fname("md_datadir_test2"));
|
||||
|
||||
#ifdef _WIN32
|
||||
tt_int_op(0, ==, mkdir(options->DataDirectory));
|
||||
tt_int_op(0, OP_EQ, mkdir(options->DataDirectory));
|
||||
#else
|
||||
tt_int_op(0, ==, mkdir(options->DataDirectory, 0700));
|
||||
tt_int_op(0, OP_EQ, mkdir(options->DataDirectory, 0700));
|
||||
#endif
|
||||
|
||||
tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs",
|
||||
@@ -375,7 +375,7 @@ test_md_generate(void *arg)
|
||||
ri = router_parse_entry_from_string(test_ri, NULL, 0, 0, NULL, NULL);
|
||||
tt_assert(ri);
|
||||
md = dirvote_create_microdescriptor(ri, 8);
|
||||
tt_str_op(md->body, ==, test_md_8);
|
||||
tt_str_op(md->body, OP_EQ, test_md_8);
|
||||
|
||||
/* XXXX test family lines. */
|
||||
/* XXXX test method 14 for A lines. */
|
||||
@@ -384,12 +384,12 @@ test_md_generate(void *arg)
|
||||
microdesc_free(md);
|
||||
md = NULL;
|
||||
md = dirvote_create_microdescriptor(ri, 16);
|
||||
tt_str_op(md->body, ==, test_md_16);
|
||||
tt_str_op(md->body, OP_EQ, test_md_16);
|
||||
|
||||
microdesc_free(md);
|
||||
md = NULL;
|
||||
md = dirvote_create_microdescriptor(ri, 18);
|
||||
tt_str_op(md->body, ==, test_md_18);
|
||||
tt_str_op(md->body, OP_EQ, test_md_18);
|
||||
|
||||
done:
|
||||
microdesc_free(md);
|
||||
@@ -564,8 +564,8 @@ test_md_parse(void *arg)
|
||||
smartlist_t *mds = microdescs_parse_from_string(MD_PARSE_TEST_DATA,
|
||||
NULL, 1, SAVED_NOWHERE,
|
||||
invalid);
|
||||
tt_int_op(smartlist_len(mds), ==, 11);
|
||||
tt_int_op(smartlist_len(invalid), ==, 4);
|
||||
tt_int_op(smartlist_len(mds), OP_EQ, 11);
|
||||
tt_int_op(smartlist_len(invalid), OP_EQ, 4);
|
||||
|
||||
test_memeq_hex(smartlist_get(invalid,0),
|
||||
"5d76bf1c6614e885614a1e0ad074e1ab"
|
||||
@@ -585,11 +585,11 @@ test_md_parse(void *arg)
|
||||
test_memeq_hex(md->digest,
|
||||
"54bb6d733ddeb375d2456c79ae103961"
|
||||
"da0cae29620375ac4cf13d54da4d92b3");
|
||||
tt_int_op(md->last_listed, ==, 0);
|
||||
tt_int_op(md->saved_location, ==, SAVED_NOWHERE);
|
||||
tt_int_op(md->no_save, ==, 0);
|
||||
tt_uint_op(md->held_in_map, ==, 0);
|
||||
tt_uint_op(md->held_by_nodes, ==, 0);
|
||||
tt_int_op(md->last_listed, OP_EQ, 0);
|
||||
tt_int_op(md->saved_location, OP_EQ, SAVED_NOWHERE);
|
||||
tt_int_op(md->no_save, OP_EQ, 0);
|
||||
tt_uint_op(md->held_in_map, OP_EQ, 0);
|
||||
tt_uint_op(md->held_by_nodes, OP_EQ, 0);
|
||||
tt_assert(md->onion_curve25519_pkey);
|
||||
|
||||
md = smartlist_get(mds, 6);
|
||||
@@ -609,7 +609,7 @@ test_md_parse(void *arg)
|
||||
"409ebd87d23925a2732bd467a92813c9"
|
||||
"21ca378fcb9ca193d354c51550b6d5e9");
|
||||
tt_assert(tor_addr_family(&md->ipv6_addr) == AF_INET6);
|
||||
tt_int_op(md->ipv6_orport, ==, 9090);
|
||||
tt_int_op(md->ipv6_orport, OP_EQ, 9090);
|
||||
|
||||
done:
|
||||
SMARTLIST_FOREACH(mds, microdesc_t *, md, microdesc_free(md));
|
||||
@@ -667,9 +667,9 @@ test_md_reject_cache(void *arg)
|
||||
mock_ns_val->flavor = FLAV_MICRODESC;
|
||||
|
||||
#ifdef _WIN32
|
||||
tt_int_op(0, ==, mkdir(options->DataDirectory));
|
||||
tt_int_op(0, OP_EQ, mkdir(options->DataDirectory));
|
||||
#else
|
||||
tt_int_op(0, ==, mkdir(options->DataDirectory, 0700));
|
||||
tt_int_op(0, OP_EQ, mkdir(options->DataDirectory, 0700));
|
||||
#endif
|
||||
|
||||
MOCK(router_get_mutable_consensus_status_by_descriptor_digest,
|
||||
@@ -679,7 +679,7 @@ test_md_reject_cache(void *arg)
|
||||
mc = get_microdesc_cache();
|
||||
#define ADD(hex) \
|
||||
do { \
|
||||
tt_int_op(0,==,base16_decode(buf,sizeof(buf),hex,strlen(hex))); \
|
||||
tt_int_op(0,OP_EQ,base16_decode(buf,sizeof(buf),hex,strlen(hex))); \
|
||||
smartlist_add(wanted, tor_memdup(buf, DIGEST256_LEN)); \
|
||||
} while (0)
|
||||
|
||||
@@ -695,10 +695,10 @@ test_md_reject_cache(void *arg)
|
||||
added = microdescs_add_to_cache(mc, MD_PARSE_TEST_DATA, NULL,
|
||||
SAVED_NOWHERE, 0, time(NULL), wanted);
|
||||
|
||||
tt_int_op(smartlist_len(added), ==, 2);
|
||||
tt_int_op(mock_rgsbd_called, ==, 2);
|
||||
tt_int_op(mock_rgsbd_val_a->dl_status.n_download_failures, ==, 255);
|
||||
tt_int_op(mock_rgsbd_val_b->dl_status.n_download_failures, ==, 255);
|
||||
tt_int_op(smartlist_len(added), OP_EQ, 2);
|
||||
tt_int_op(mock_rgsbd_called, OP_EQ, 2);
|
||||
tt_int_op(mock_rgsbd_val_a->dl_status.n_download_failures, OP_EQ, 255);
|
||||
tt_int_op(mock_rgsbd_val_b->dl_status.n_download_failures, OP_EQ, 255);
|
||||
|
||||
done:
|
||||
UNMOCK(networkstatus_get_latest_consensus_by_flavor);
|
||||
|
||||
@@ -25,7 +25,7 @@ test_nodelist_node_get_verbose_nickname_by_id_null_node(void *arg)
|
||||
/* make sure node_get_by_id returns NULL */
|
||||
tt_assert(!node_get_by_id(ID));
|
||||
node_get_verbose_nickname_by_id(ID, vname);
|
||||
tt_str_op(vname,==, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
|
||||
tt_str_op(vname,OP_EQ, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
|
||||
done:
|
||||
return;
|
||||
}
|
||||
@@ -54,7 +54,7 @@ test_nodelist_node_get_verbose_nickname_not_named(void *arg)
|
||||
"\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
|
||||
DIGEST_LEN);
|
||||
node_get_verbose_nickname(&mock_node, vname);
|
||||
tt_str_op(vname,==, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR");
|
||||
tt_str_op(vname,OP_EQ, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR");
|
||||
|
||||
done:
|
||||
return;
|
||||
|
||||
+40
-40
@@ -151,9 +151,9 @@ test_oom_circbuf(void *arg)
|
||||
options->MaxMemInQueues = 256*packed_cell_mem_cost();
|
||||
options->CellStatistics = 0;
|
||||
|
||||
tt_int_op(cell_queues_check_size(), ==, 0); /* We don't start out OOM. */
|
||||
tt_int_op(cell_queues_get_total_allocation(), ==, 0);
|
||||
tt_int_op(buf_get_total_allocation(), ==, 0);
|
||||
tt_int_op(cell_queues_check_size(), OP_EQ, 0); /* We don't start out OOM. */
|
||||
tt_int_op(cell_queues_get_total_allocation(), OP_EQ, 0);
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
|
||||
|
||||
/* Now we're going to fake up some circuits and get them added to the global
|
||||
circuit list. */
|
||||
@@ -165,21 +165,21 @@ test_oom_circbuf(void *arg)
|
||||
c2 = dummy_or_circuit_new(20, 20);
|
||||
|
||||
#ifdef ENABLE_MEMPOOLS
|
||||
tt_int_op(packed_cell_mem_cost(), ==,
|
||||
tt_int_op(packed_cell_mem_cost(), OP_EQ,
|
||||
sizeof(packed_cell_t) + MP_POOL_ITEM_OVERHEAD);
|
||||
#else
|
||||
tt_int_op(packed_cell_mem_cost(), ==,
|
||||
tt_int_op(packed_cell_mem_cost(), OP_EQ,
|
||||
sizeof(packed_cell_t));
|
||||
#endif /* ENABLE_MEMPOOLS */
|
||||
tt_int_op(cell_queues_get_total_allocation(), ==,
|
||||
tt_int_op(cell_queues_get_total_allocation(), OP_EQ,
|
||||
packed_cell_mem_cost() * 70);
|
||||
tt_int_op(cell_queues_check_size(), ==, 0); /* We are still not OOM */
|
||||
tt_int_op(cell_queues_check_size(), OP_EQ, 0); /* We are still not OOM */
|
||||
|
||||
tv.tv_usec = 20*1000;
|
||||
tor_gettimeofday_cache_set(&tv);
|
||||
c3 = dummy_or_circuit_new(100, 85);
|
||||
tt_int_op(cell_queues_check_size(), ==, 0); /* We are still not OOM */
|
||||
tt_int_op(cell_queues_get_total_allocation(), ==,
|
||||
tt_int_op(cell_queues_check_size(), OP_EQ, 0); /* We are still not OOM */
|
||||
tt_int_op(cell_queues_get_total_allocation(), OP_EQ,
|
||||
packed_cell_mem_cost() * 255);
|
||||
|
||||
tv.tv_usec = 30*1000;
|
||||
@@ -187,17 +187,17 @@ test_oom_circbuf(void *arg)
|
||||
/* Adding this cell will trigger our OOM handler. */
|
||||
c4 = dummy_or_circuit_new(2, 0);
|
||||
|
||||
tt_int_op(cell_queues_get_total_allocation(), ==,
|
||||
tt_int_op(cell_queues_get_total_allocation(), OP_EQ,
|
||||
packed_cell_mem_cost() * 257);
|
||||
|
||||
tt_int_op(cell_queues_check_size(), ==, 1); /* We are now OOM */
|
||||
tt_int_op(cell_queues_check_size(), OP_EQ, 1); /* We are now OOM */
|
||||
|
||||
tt_assert(c1->marked_for_close);
|
||||
tt_assert(! c2->marked_for_close);
|
||||
tt_assert(! c3->marked_for_close);
|
||||
tt_assert(! c4->marked_for_close);
|
||||
|
||||
tt_int_op(cell_queues_get_total_allocation(), ==,
|
||||
tt_int_op(cell_queues_get_total_allocation(), OP_EQ,
|
||||
packed_cell_mem_cost() * (257 - 30));
|
||||
|
||||
circuit_free(c1);
|
||||
@@ -208,14 +208,14 @@ test_oom_circbuf(void *arg)
|
||||
tv.tv_usec = 40*1000; /* go back to the future */
|
||||
tor_gettimeofday_cache_set(&tv);
|
||||
|
||||
tt_int_op(cell_queues_check_size(), ==, 1); /* We are now OOM */
|
||||
tt_int_op(cell_queues_check_size(), OP_EQ, 1); /* We are now OOM */
|
||||
|
||||
tt_assert(c1->marked_for_close);
|
||||
tt_assert(! c2->marked_for_close);
|
||||
tt_assert(! c3->marked_for_close);
|
||||
tt_assert(! c4->marked_for_close);
|
||||
|
||||
tt_int_op(cell_queues_get_total_allocation(), ==,
|
||||
tt_int_op(cell_queues_get_total_allocation(), OP_EQ,
|
||||
packed_cell_mem_cost() * (257 - 30));
|
||||
|
||||
done:
|
||||
@@ -250,9 +250,9 @@ test_oom_streambuf(void *arg)
|
||||
options->MaxMemInQueues = 81*packed_cell_mem_cost() + 4096 * 34;
|
||||
options->CellStatistics = 0;
|
||||
|
||||
tt_int_op(cell_queues_check_size(), ==, 0); /* We don't start out OOM. */
|
||||
tt_int_op(cell_queues_get_total_allocation(), ==, 0);
|
||||
tt_int_op(buf_get_total_allocation(), ==, 0);
|
||||
tt_int_op(cell_queues_check_size(), OP_EQ, 0); /* We don't start out OOM. */
|
||||
tt_int_op(cell_queues_get_total_allocation(), OP_EQ, 0);
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
|
||||
|
||||
/* Start all circuits with a bit of data queued in cells */
|
||||
tv.tv_usec = 500*1000; /* go halfway into the second. */
|
||||
@@ -267,7 +267,7 @@ test_oom_streambuf(void *arg)
|
||||
tv.tv_usec = 530*1000;
|
||||
tor_gettimeofday_cache_set(&tv);
|
||||
c4 = dummy_or_circuit_new(0,0);
|
||||
tt_int_op(cell_queues_get_total_allocation(), ==,
|
||||
tt_int_op(cell_queues_get_total_allocation(), OP_EQ,
|
||||
packed_cell_mem_cost() * 80);
|
||||
|
||||
tv.tv_usec = 600*1000;
|
||||
@@ -303,24 +303,24 @@ test_oom_streambuf(void *arg)
|
||||
tv.tv_usec = 0;
|
||||
tvms = (uint32_t) tv_to_msec(&tv);
|
||||
|
||||
tt_int_op(circuit_max_queued_cell_age(c1, tvms), ==, 500);
|
||||
tt_int_op(circuit_max_queued_cell_age(c2, tvms), ==, 490);
|
||||
tt_int_op(circuit_max_queued_cell_age(c3, tvms), ==, 480);
|
||||
tt_int_op(circuit_max_queued_cell_age(c4, tvms), ==, 0);
|
||||
tt_int_op(circuit_max_queued_cell_age(c1, tvms), OP_EQ, 500);
|
||||
tt_int_op(circuit_max_queued_cell_age(c2, tvms), OP_EQ, 490);
|
||||
tt_int_op(circuit_max_queued_cell_age(c3, tvms), OP_EQ, 480);
|
||||
tt_int_op(circuit_max_queued_cell_age(c4, tvms), OP_EQ, 0);
|
||||
|
||||
tt_int_op(circuit_max_queued_data_age(c1, tvms), ==, 390);
|
||||
tt_int_op(circuit_max_queued_data_age(c2, tvms), ==, 380);
|
||||
tt_int_op(circuit_max_queued_data_age(c3, tvms), ==, 0);
|
||||
tt_int_op(circuit_max_queued_data_age(c4, tvms), ==, 370);
|
||||
tt_int_op(circuit_max_queued_data_age(c1, tvms), OP_EQ, 390);
|
||||
tt_int_op(circuit_max_queued_data_age(c2, tvms), OP_EQ, 380);
|
||||
tt_int_op(circuit_max_queued_data_age(c3, tvms), OP_EQ, 0);
|
||||
tt_int_op(circuit_max_queued_data_age(c4, tvms), OP_EQ, 370);
|
||||
|
||||
tt_int_op(circuit_max_queued_item_age(c1, tvms), ==, 500);
|
||||
tt_int_op(circuit_max_queued_item_age(c2, tvms), ==, 490);
|
||||
tt_int_op(circuit_max_queued_item_age(c3, tvms), ==, 480);
|
||||
tt_int_op(circuit_max_queued_item_age(c4, tvms), ==, 370);
|
||||
tt_int_op(circuit_max_queued_item_age(c1, tvms), OP_EQ, 500);
|
||||
tt_int_op(circuit_max_queued_item_age(c2, tvms), OP_EQ, 490);
|
||||
tt_int_op(circuit_max_queued_item_age(c3, tvms), OP_EQ, 480);
|
||||
tt_int_op(circuit_max_queued_item_age(c4, tvms), OP_EQ, 370);
|
||||
|
||||
tt_int_op(cell_queues_get_total_allocation(), ==,
|
||||
tt_int_op(cell_queues_get_total_allocation(), OP_EQ,
|
||||
packed_cell_mem_cost() * 80);
|
||||
tt_int_op(buf_get_total_allocation(), ==, 4096*16*2);
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 4096*16*2);
|
||||
|
||||
/* Now give c4 a very old buffer of modest size */
|
||||
{
|
||||
@@ -332,21 +332,21 @@ test_oom_streambuf(void *arg)
|
||||
tt_assert(ec);
|
||||
smartlist_add(edgeconns, ec);
|
||||
}
|
||||
tt_int_op(buf_get_total_allocation(), ==, 4096*17*2);
|
||||
tt_int_op(circuit_max_queued_item_age(c4, tvms), ==, 1000);
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 4096*17*2);
|
||||
tt_int_op(circuit_max_queued_item_age(c4, tvms), OP_EQ, 1000);
|
||||
|
||||
tt_int_op(cell_queues_check_size(), ==, 0);
|
||||
tt_int_op(cell_queues_check_size(), OP_EQ, 0);
|
||||
|
||||
/* And run over the limit. */
|
||||
tv.tv_usec = 800*1000;
|
||||
tor_gettimeofday_cache_set(&tv);
|
||||
c5 = dummy_or_circuit_new(0,5);
|
||||
|
||||
tt_int_op(cell_queues_get_total_allocation(), ==,
|
||||
tt_int_op(cell_queues_get_total_allocation(), OP_EQ,
|
||||
packed_cell_mem_cost() * 85);
|
||||
tt_int_op(buf_get_total_allocation(), ==, 4096*17*2);
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 4096*17*2);
|
||||
|
||||
tt_int_op(cell_queues_check_size(), ==, 1); /* We are now OOM */
|
||||
tt_int_op(cell_queues_check_size(), OP_EQ, 1); /* We are now OOM */
|
||||
|
||||
/* C4 should have died. */
|
||||
tt_assert(! c1->marked_for_close);
|
||||
@@ -355,9 +355,9 @@ test_oom_streambuf(void *arg)
|
||||
tt_assert(c4->marked_for_close);
|
||||
tt_assert(! c5->marked_for_close);
|
||||
|
||||
tt_int_op(cell_queues_get_total_allocation(), ==,
|
||||
tt_int_op(cell_queues_get_total_allocation(), OP_EQ,
|
||||
packed_cell_mem_cost() * 85);
|
||||
tt_int_op(buf_get_total_allocation(), ==, 4096*8*2);
|
||||
tt_int_op(buf_get_total_allocation(), OP_EQ, 4096*8*2);
|
||||
|
||||
done:
|
||||
circuit_free(c1);
|
||||
|
||||
@@ -87,10 +87,10 @@ test_options_validate_impl(const char *configuration,
|
||||
clear_log_messages();
|
||||
|
||||
r = config_get_lines(configuration, &cl, 1);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
|
||||
r = config_assign(&options_format, opt, cl, 0, 0, &msg);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
|
||||
r = options_validate(NULL, opt, dflt, 0, &msg);
|
||||
if (expect_errmsg && !msg) {
|
||||
@@ -103,7 +103,7 @@ test_options_validate_impl(const char *configuration,
|
||||
TT_DIE(("Expected no error message from <%s> but got <%s>.",
|
||||
configuration, msg));
|
||||
}
|
||||
tt_int_op((r == 0), ==, (msg == NULL));
|
||||
tt_int_op((r == 0), OP_EQ, (msg == NULL));
|
||||
|
||||
if (expect_log) {
|
||||
int found = 0;
|
||||
|
||||
+20
-20
@@ -22,7 +22,7 @@ test_short_policy_parse(const char *input,
|
||||
short_policy = parse_short_policy(input);
|
||||
tt_assert(short_policy);
|
||||
out = write_short_policy(short_policy);
|
||||
tt_str_op(out, ==, expected);
|
||||
tt_str_op(out, OP_EQ, expected);
|
||||
|
||||
done:
|
||||
tor_free(out);
|
||||
@@ -50,17 +50,17 @@ test_policy_summary_helper(const char *policy_str,
|
||||
r = policies_parse_exit_policy(&line, &policy,
|
||||
EXIT_POLICY_IPV6_ENABLED |
|
||||
EXIT_POLICY_ADD_DEFAULT ,0);
|
||||
tt_int_op(r,==, 0);
|
||||
tt_int_op(r,OP_EQ, 0);
|
||||
|
||||
summary = policy_summarize(policy, AF_INET);
|
||||
|
||||
tt_assert(summary != NULL);
|
||||
tt_str_op(summary,==, expected_summary);
|
||||
tt_str_op(summary,OP_EQ, expected_summary);
|
||||
|
||||
short_policy = parse_short_policy(summary);
|
||||
tt_assert(short_policy);
|
||||
summary_after = write_short_policy(short_policy);
|
||||
tt_str_op(summary,==, summary_after);
|
||||
tt_str_op(summary,OP_EQ, summary_after);
|
||||
|
||||
done:
|
||||
tor_free(summary_after);
|
||||
@@ -90,12 +90,12 @@ test_policies_general(void *arg)
|
||||
|
||||
p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1);
|
||||
tt_assert(p != NULL);
|
||||
tt_int_op(ADDR_POLICY_REJECT,==, p->policy_type);
|
||||
tt_int_op(ADDR_POLICY_REJECT,OP_EQ, p->policy_type);
|
||||
tor_addr_from_ipv4h(&tar, 0xc0a80000u);
|
||||
tt_int_op(0,==, tor_addr_compare(&p->addr, &tar, CMP_EXACT));
|
||||
tt_int_op(16,==, p->maskbits);
|
||||
tt_int_op(1,==, p->prt_min);
|
||||
tt_int_op(65535,==, p->prt_max);
|
||||
tt_int_op(0,OP_EQ, tor_addr_compare(&p->addr, &tar, CMP_EXACT));
|
||||
tt_int_op(16,OP_EQ, p->maskbits);
|
||||
tt_int_op(1,OP_EQ, p->prt_min);
|
||||
tt_int_op(65535,OP_EQ, p->prt_max);
|
||||
|
||||
smartlist_add(policy, p);
|
||||
|
||||
@@ -109,7 +109,7 @@ test_policies_general(void *arg)
|
||||
tt_assert(ADDR_POLICY_REJECTED ==
|
||||
compare_tor_addr_to_addr_policy(&tar, 2, policy));
|
||||
|
||||
tt_int_op(0, ==, policies_parse_exit_policy(NULL, &policy2,
|
||||
tt_int_op(0, OP_EQ, policies_parse_exit_policy(NULL, &policy2,
|
||||
EXIT_POLICY_IPV6_ENABLED |
|
||||
EXIT_POLICY_REJECT_PRIVATE |
|
||||
EXIT_POLICY_ADD_DEFAULT, 0));
|
||||
@@ -200,14 +200,14 @@ test_policies_general(void *arg)
|
||||
line.key = (char*)"foo";
|
||||
line.value = (char*)"accept *:80,reject private:*,reject *:*";
|
||||
line.next = NULL;
|
||||
tt_int_op(0, ==, policies_parse_exit_policy(&line,&policy,
|
||||
tt_int_op(0, OP_EQ, policies_parse_exit_policy(&line,&policy,
|
||||
EXIT_POLICY_IPV6_ENABLED |
|
||||
EXIT_POLICY_ADD_DEFAULT,0));
|
||||
tt_assert(policy);
|
||||
|
||||
//test_streq(policy->string, "accept *:80");
|
||||
//test_streq(policy->next->string, "reject *:*");
|
||||
tt_int_op(smartlist_len(policy),==, 4);
|
||||
tt_int_op(smartlist_len(policy),OP_EQ, 4);
|
||||
|
||||
/* test policy summaries */
|
||||
/* check if we properly ignore private IP addresses */
|
||||
@@ -281,7 +281,7 @@ test_policies_general(void *arg)
|
||||
/* Try parsing various broken short policies */
|
||||
#define TT_BAD_SHORT_POLICY(s) \
|
||||
do { \
|
||||
tt_ptr_op(NULL, ==, (short_parsed = parse_short_policy((s)))); \
|
||||
tt_ptr_op(NULL, OP_EQ, (short_parsed = parse_short_policy((s)))); \
|
||||
} while (0)
|
||||
TT_BAD_SHORT_POLICY("accept 200-199");
|
||||
TT_BAD_SHORT_POLICY("");
|
||||
@@ -311,7 +311,7 @@ test_policies_general(void *arg)
|
||||
smartlist_free(chunks);
|
||||
short_parsed = parse_short_policy(policy);/* shouldn't be accepted */
|
||||
tor_free(policy);
|
||||
tt_ptr_op(NULL, ==, short_parsed);
|
||||
tt_ptr_op(NULL, OP_EQ, short_parsed);
|
||||
}
|
||||
|
||||
/* truncation ports */
|
||||
@@ -369,7 +369,7 @@ test_dump_exit_policy_to_string(void *arg)
|
||||
ri->exit_policy = NULL; // expecting "reject *:*"
|
||||
ep = router_dump_exit_policy_to_string(ri,1,1);
|
||||
|
||||
tt_str_op("reject *:*",==, ep);
|
||||
tt_str_op("reject *:*",OP_EQ, ep);
|
||||
|
||||
tor_free(ep);
|
||||
|
||||
@@ -382,7 +382,7 @@ test_dump_exit_policy_to_string(void *arg)
|
||||
|
||||
ep = router_dump_exit_policy_to_string(ri,1,1);
|
||||
|
||||
tt_str_op("accept *:*",==, ep);
|
||||
tt_str_op("accept *:*",OP_EQ, ep);
|
||||
|
||||
tor_free(ep);
|
||||
|
||||
@@ -392,7 +392,7 @@ test_dump_exit_policy_to_string(void *arg)
|
||||
|
||||
ep = router_dump_exit_policy_to_string(ri,1,1);
|
||||
|
||||
tt_str_op("accept *:*\nreject *:25",==, ep);
|
||||
tt_str_op("accept *:*\nreject *:25",OP_EQ, ep);
|
||||
|
||||
tor_free(ep);
|
||||
|
||||
@@ -403,7 +403,7 @@ test_dump_exit_policy_to_string(void *arg)
|
||||
|
||||
ep = router_dump_exit_policy_to_string(ri,1,1);
|
||||
|
||||
tt_str_op("accept *:*\nreject *:25\nreject 8.8.8.8:*",==, ep);
|
||||
tt_str_op("accept *:*\nreject *:25\nreject 8.8.8.8:*",OP_EQ, ep);
|
||||
tor_free(ep);
|
||||
|
||||
policy_entry =
|
||||
@@ -414,7 +414,7 @@ test_dump_exit_policy_to_string(void *arg)
|
||||
ep = router_dump_exit_policy_to_string(ri,1,1);
|
||||
|
||||
tt_str_op("accept *:*\nreject *:25\nreject 8.8.8.8:*\n"
|
||||
"reject6 [fc00::]/7:*",==, ep);
|
||||
"reject6 [fc00::]/7:*",OP_EQ, ep);
|
||||
tor_free(ep);
|
||||
|
||||
policy_entry =
|
||||
@@ -425,7 +425,7 @@ test_dump_exit_policy_to_string(void *arg)
|
||||
ep = router_dump_exit_policy_to_string(ri,1,1);
|
||||
|
||||
tt_str_op("accept *:*\nreject *:25\nreject 8.8.8.8:*\n"
|
||||
"reject6 [fc00::]/7:*\naccept6 [c000::]/3:*",==, ep);
|
||||
"reject6 [fc00::]/7:*\naccept6 [c000::]/3:*",OP_EQ, ep);
|
||||
|
||||
done:
|
||||
|
||||
|
||||
+36
-36
@@ -69,7 +69,7 @@ test_pt_parsing(void *arg)
|
||||
/* test registered SOCKS version of transport */
|
||||
tt_assert(transport->socks_version == PROXY_SOCKS5);
|
||||
/* test registered name of transport */
|
||||
tt_str_op(transport->name,==, "trebuchet");
|
||||
tt_str_op(transport->name,OP_EQ, "trebuchet");
|
||||
|
||||
reset_mp(mp);
|
||||
|
||||
@@ -96,7 +96,7 @@ test_pt_parsing(void *arg)
|
||||
/* test registered port of transport */
|
||||
tt_assert(transport->port == 2999);
|
||||
/* test registered name of transport */
|
||||
tt_str_op(transport->name,==, "trebuchy");
|
||||
tt_str_op(transport->name,OP_EQ, "trebuchy");
|
||||
|
||||
reset_mp(mp);
|
||||
|
||||
@@ -105,14 +105,14 @@ test_pt_parsing(void *arg)
|
||||
"ARGS:counterweight=3,sling=snappy",
|
||||
sizeof(line));
|
||||
tt_assert(parse_smethod_line(line, mp) == 0);
|
||||
tt_int_op(1, ==, smartlist_len(mp->transports));
|
||||
tt_int_op(1, OP_EQ, smartlist_len(mp->transports));
|
||||
{
|
||||
const transport_t *transport = smartlist_get(mp->transports, 0);
|
||||
tt_assert(transport);
|
||||
tt_str_op(transport->name, ==, "trebuchet");
|
||||
tt_int_op(transport->port, ==, 9999);
|
||||
tt_str_op(fmt_addr(&transport->addr), ==, "127.0.0.1");
|
||||
tt_str_op(transport->extra_info_args, ==,
|
||||
tt_str_op(transport->name, OP_EQ, "trebuchet");
|
||||
tt_int_op(transport->port, OP_EQ, 9999);
|
||||
tt_str_op(fmt_addr(&transport->addr), OP_EQ, "127.0.0.1");
|
||||
tt_str_op(transport->extra_info_args, OP_EQ,
|
||||
"counterweight=3,sling=snappy");
|
||||
}
|
||||
reset_mp(mp);
|
||||
@@ -151,9 +151,9 @@ test_pt_get_transport_options(void *arg)
|
||||
execve_args[1] = NULL;
|
||||
|
||||
mp = managed_proxy_create(transport_list, execve_args, 1);
|
||||
tt_ptr_op(mp, !=, NULL);
|
||||
tt_ptr_op(mp, OP_NE, NULL);
|
||||
opt_str = get_transport_options_for_server_proxy(mp);
|
||||
tt_ptr_op(opt_str, ==, NULL);
|
||||
tt_ptr_op(opt_str, OP_EQ, NULL);
|
||||
|
||||
smartlist_add(mp->transports_to_launch, tor_strdup("gruyere"));
|
||||
smartlist_add(mp->transports_to_launch, tor_strdup("roquefort"));
|
||||
@@ -176,7 +176,7 @@ test_pt_get_transport_options(void *arg)
|
||||
options->ServerTransportOptions = cl;
|
||||
|
||||
opt_str = get_transport_options_for_server_proxy(mp);
|
||||
tt_str_op(opt_str, ==,
|
||||
tt_str_op(opt_str, OP_EQ,
|
||||
"gruyere:melty=10;gruyere:hardness=se\\;ven;"
|
||||
"stnectaire:melty=4;stnectaire:hardness=three");
|
||||
|
||||
@@ -196,7 +196,7 @@ test_pt_protocol(void *arg)
|
||||
(void)arg;
|
||||
mp->conf_state = PT_PROTO_LAUNCHED;
|
||||
mp->transports = smartlist_new();
|
||||
mp->argv = tor_calloc(sizeof(char *), 2);
|
||||
mp->argv = tor_calloc(2, sizeof(char *));
|
||||
mp->argv[0] = tor_strdup("<testcase>");
|
||||
|
||||
/* various wrong protocol runs: */
|
||||
@@ -262,17 +262,17 @@ test_pt_get_extrainfo_string(void *arg)
|
||||
mp2 = managed_proxy_create(t2, argv2, 1);
|
||||
|
||||
r = parse_smethod_line("SMETHOD hagbard 127.0.0.1:5555", mp1);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
r = parse_smethod_line("SMETHOD celine 127.0.0.1:1723 ARGS:card=no-enemy",
|
||||
mp2);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
|
||||
/* Force these proxies to look "completed" or they won't generate output. */
|
||||
mp1->conf_state = mp2->conf_state = PT_PROTO_COMPLETED;
|
||||
|
||||
s = pt_get_extra_info_descriptor_string();
|
||||
tt_assert(s);
|
||||
tt_str_op(s, ==,
|
||||
tt_str_op(s, OP_EQ,
|
||||
"transport hagbard 127.0.0.1:5555\n"
|
||||
"transport celine 127.0.0.1:1723 card=no-enemy\n");
|
||||
|
||||
@@ -380,7 +380,7 @@ test_pt_configure_proxy(void *arg)
|
||||
for (i = 0 ; i < 5 ; i++) {
|
||||
retval = configure_proxy(mp);
|
||||
/* retval should be zero because proxy hasn't finished configuring yet */
|
||||
tt_int_op(retval, ==, 0);
|
||||
tt_int_op(retval, OP_EQ, 0);
|
||||
/* check the number of registered transports */
|
||||
tt_assert(smartlist_len(mp->transports) == i+1);
|
||||
/* check that the mp is still waiting for transports */
|
||||
@@ -390,23 +390,23 @@ test_pt_configure_proxy(void *arg)
|
||||
/* this last configure_proxy() should finalize the proxy configuration. */
|
||||
retval = configure_proxy(mp);
|
||||
/* retval should be 1 since the proxy finished configuring */
|
||||
tt_int_op(retval, ==, 1);
|
||||
tt_int_op(retval, OP_EQ, 1);
|
||||
/* check the mp state */
|
||||
tt_assert(mp->conf_state == PT_PROTO_COMPLETED);
|
||||
|
||||
tt_int_op(controlevent_n, ==, 5);
|
||||
tt_int_op(controlevent_event, ==, EVENT_TRANSPORT_LAUNCHED);
|
||||
tt_int_op(smartlist_len(controlevent_msgs), ==, 5);
|
||||
tt_int_op(controlevent_n, OP_EQ, 5);
|
||||
tt_int_op(controlevent_event, OP_EQ, EVENT_TRANSPORT_LAUNCHED);
|
||||
tt_int_op(smartlist_len(controlevent_msgs), OP_EQ, 5);
|
||||
smartlist_sort_strings(controlevent_msgs);
|
||||
tt_str_op(smartlist_get(controlevent_msgs, 0), ==,
|
||||
tt_str_op(smartlist_get(controlevent_msgs, 0), OP_EQ,
|
||||
"650 TRANSPORT_LAUNCHED server mock1 127.0.0.1 5551\r\n");
|
||||
tt_str_op(smartlist_get(controlevent_msgs, 1), ==,
|
||||
tt_str_op(smartlist_get(controlevent_msgs, 1), OP_EQ,
|
||||
"650 TRANSPORT_LAUNCHED server mock2 127.0.0.1 5552\r\n");
|
||||
tt_str_op(smartlist_get(controlevent_msgs, 2), ==,
|
||||
tt_str_op(smartlist_get(controlevent_msgs, 2), OP_EQ,
|
||||
"650 TRANSPORT_LAUNCHED server mock3 127.0.0.1 5553\r\n");
|
||||
tt_str_op(smartlist_get(controlevent_msgs, 3), ==,
|
||||
tt_str_op(smartlist_get(controlevent_msgs, 3), OP_EQ,
|
||||
"650 TRANSPORT_LAUNCHED server mock4 127.0.0.1 5554\r\n");
|
||||
tt_str_op(smartlist_get(controlevent_msgs, 4), ==,
|
||||
tt_str_op(smartlist_get(controlevent_msgs, 4), OP_EQ,
|
||||
"650 TRANSPORT_LAUNCHED server mock5 127.0.0.1 5555\r\n");
|
||||
|
||||
{ /* check that the transport info were saved properly in the tor state */
|
||||
@@ -423,8 +423,8 @@ test_pt_configure_proxy(void *arg)
|
||||
NULL, 0, 0);
|
||||
name_of_transport = smartlist_get(transport_info_sl, 0);
|
||||
bindaddr = smartlist_get(transport_info_sl, 1);
|
||||
tt_str_op(name_of_transport, ==, "mock1");
|
||||
tt_str_op(bindaddr, ==, "127.0.0.1:5551");
|
||||
tt_str_op(name_of_transport, OP_EQ, "mock1");
|
||||
tt_str_op(bindaddr, OP_EQ, "127.0.0.1:5551");
|
||||
|
||||
SMARTLIST_FOREACH(transport_info_sl, char *, cp, tor_free(cp));
|
||||
smartlist_free(transport_info_sl);
|
||||
@@ -470,9 +470,9 @@ test_get_pt_proxy_uri(void *arg)
|
||||
ret = tor_addr_port_lookup(options->Socks4Proxy,
|
||||
&options->Socks4ProxyAddr,
|
||||
&options->Socks4ProxyPort);
|
||||
tt_int_op(ret, ==, 0);
|
||||
tt_int_op(ret, OP_EQ, 0);
|
||||
uri = get_pt_proxy_uri();
|
||||
tt_str_op(uri, ==, "socks4a://192.0.2.1:1080");
|
||||
tt_str_op(uri, OP_EQ, "socks4a://192.0.2.1:1080");
|
||||
tor_free(uri);
|
||||
tor_free(options->Socks4Proxy);
|
||||
|
||||
@@ -481,16 +481,16 @@ test_get_pt_proxy_uri(void *arg)
|
||||
ret = tor_addr_port_lookup(options->Socks5Proxy,
|
||||
&options->Socks5ProxyAddr,
|
||||
&options->Socks5ProxyPort);
|
||||
tt_int_op(ret, ==, 0);
|
||||
tt_int_op(ret, OP_EQ, 0);
|
||||
uri = get_pt_proxy_uri();
|
||||
tt_str_op(uri, ==, "socks5://192.0.2.1:1080");
|
||||
tt_str_op(uri, OP_EQ, "socks5://192.0.2.1:1080");
|
||||
tor_free(uri);
|
||||
|
||||
/* Test with a SOCKS5 proxy, with username/password. */
|
||||
options->Socks5ProxyUsername = tor_strdup("hwest");
|
||||
options->Socks5ProxyPassword = tor_strdup("r34n1m470r");
|
||||
uri = get_pt_proxy_uri();
|
||||
tt_str_op(uri, ==, "socks5://hwest:r34n1m470r@192.0.2.1:1080");
|
||||
tt_str_op(uri, OP_EQ, "socks5://hwest:r34n1m470r@192.0.2.1:1080");
|
||||
tor_free(uri);
|
||||
tor_free(options->Socks5Proxy);
|
||||
tor_free(options->Socks5ProxyUsername);
|
||||
@@ -501,15 +501,15 @@ test_get_pt_proxy_uri(void *arg)
|
||||
ret = tor_addr_port_lookup(options->HTTPSProxy,
|
||||
&options->HTTPSProxyAddr,
|
||||
&options->HTTPSProxyPort);
|
||||
tt_int_op(ret, ==, 0);
|
||||
tt_int_op(ret, OP_EQ, 0);
|
||||
uri = get_pt_proxy_uri();
|
||||
tt_str_op(uri, ==, "http://192.0.2.1:80");
|
||||
tt_str_op(uri, OP_EQ, "http://192.0.2.1:80");
|
||||
tor_free(uri);
|
||||
|
||||
/* Test with a HTTPS proxy, with authenticator. */
|
||||
options->HTTPSProxyAuthenticator = tor_strdup("hwest:r34n1m470r");
|
||||
uri = get_pt_proxy_uri();
|
||||
tt_str_op(uri, ==, "http://hwest:r34n1m470r@192.0.2.1:80");
|
||||
tt_str_op(uri, OP_EQ, "http://hwest:r34n1m470r@192.0.2.1:80");
|
||||
tor_free(uri);
|
||||
tor_free(options->HTTPSProxy);
|
||||
tor_free(options->HTTPSProxyAuthenticator);
|
||||
@@ -519,9 +519,9 @@ test_get_pt_proxy_uri(void *arg)
|
||||
ret = tor_addr_port_lookup(options->Socks4Proxy,
|
||||
&options->Socks4ProxyAddr,
|
||||
&options->Socks4ProxyPort);
|
||||
tt_int_op(ret, ==, 0);
|
||||
tt_int_op(ret, OP_EQ, 0);
|
||||
uri = get_pt_proxy_uri();
|
||||
tt_str_op(uri, ==, "socks4a://[2001:db8::1]:1080");
|
||||
tt_str_op(uri, OP_EQ, "socks4a://[2001:db8::1]:1080");
|
||||
tor_free(uri);
|
||||
tor_free(options->Socks4Proxy);
|
||||
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/* Copyright (c) 2014, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
#include "or.h"
|
||||
#define CIRCUITBUILD_PRIVATE
|
||||
#include "circuitbuild.h"
|
||||
#define RELAY_PRIVATE
|
||||
#include "relay.h"
|
||||
/* For init/free stuff */
|
||||
#include "scheduler.h"
|
||||
|
||||
/* Test suite stuff */
|
||||
#include "test.h"
|
||||
#include "fakechans.h"
|
||||
|
||||
static or_circuit_t * new_fake_orcirc(channel_t *nchan, channel_t *pchan);
|
||||
|
||||
static void test_relay_append_cell_to_circuit_queue(void *arg);
|
||||
|
||||
static or_circuit_t *
|
||||
new_fake_orcirc(channel_t *nchan, channel_t *pchan)
|
||||
{
|
||||
or_circuit_t *orcirc = NULL;
|
||||
circuit_t *circ = NULL;
|
||||
|
||||
orcirc = tor_malloc_zero(sizeof(*orcirc));
|
||||
circ = &(orcirc->base_);
|
||||
circ->magic = OR_CIRCUIT_MAGIC;
|
||||
|
||||
circ->n_chan = nchan;
|
||||
circ->n_circ_id = get_unique_circ_id_by_chan(nchan);
|
||||
circ->n_mux = NULL; /* ?? */
|
||||
cell_queue_init(&(circ->n_chan_cells));
|
||||
circ->n_hop = NULL;
|
||||
circ->streams_blocked_on_n_chan = 0;
|
||||
circ->streams_blocked_on_p_chan = 0;
|
||||
circ->n_delete_pending = 0;
|
||||
circ->p_delete_pending = 0;
|
||||
circ->received_destroy = 0;
|
||||
circ->state = CIRCUIT_STATE_OPEN;
|
||||
circ->purpose = CIRCUIT_PURPOSE_OR;
|
||||
circ->package_window = CIRCWINDOW_START_MAX;
|
||||
circ->deliver_window = CIRCWINDOW_START_MAX;
|
||||
circ->n_chan_create_cell = NULL;
|
||||
|
||||
orcirc->p_chan = pchan;
|
||||
orcirc->p_circ_id = get_unique_circ_id_by_chan(pchan);
|
||||
cell_queue_init(&(orcirc->p_chan_cells));
|
||||
|
||||
return orcirc;
|
||||
}
|
||||
|
||||
static void
|
||||
test_relay_append_cell_to_circuit_queue(void *arg)
|
||||
{
|
||||
channel_t *nchan = NULL, *pchan = NULL;
|
||||
or_circuit_t *orcirc = NULL;
|
||||
cell_t *cell = NULL;
|
||||
int old_count, new_count;
|
||||
|
||||
(void)arg;
|
||||
|
||||
/* We'll need the cell pool for append_cell_to_circuit_queue() to work */
|
||||
#ifdef ENABLE_MEMPOOLS
|
||||
init_cell_pool();
|
||||
#endif /* ENABLE_MEMPOOLS */
|
||||
|
||||
/* Make fake channels to be nchan and pchan for the circuit */
|
||||
nchan = new_fake_channel();
|
||||
tt_assert(nchan);
|
||||
|
||||
pchan = new_fake_channel();
|
||||
tt_assert(pchan);
|
||||
|
||||
/* We'll need chans with working cmuxes */
|
||||
nchan->cmux = circuitmux_alloc();
|
||||
pchan->cmux = circuitmux_alloc();
|
||||
|
||||
/* Make a fake orcirc */
|
||||
orcirc = new_fake_orcirc(nchan, pchan);
|
||||
tt_assert(orcirc);
|
||||
|
||||
/* Make a cell */
|
||||
cell = tor_malloc_zero(sizeof(cell_t));
|
||||
make_fake_cell(cell);
|
||||
|
||||
MOCK(scheduler_channel_has_waiting_cells,
|
||||
scheduler_channel_has_waiting_cells_mock);
|
||||
|
||||
/* Append it */
|
||||
old_count = get_mock_scheduler_has_waiting_cells_count();
|
||||
append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), nchan, cell,
|
||||
CELL_DIRECTION_OUT, 0);
|
||||
new_count = get_mock_scheduler_has_waiting_cells_count();
|
||||
tt_int_op(new_count, ==, old_count + 1);
|
||||
|
||||
/* Now try the reverse direction */
|
||||
old_count = get_mock_scheduler_has_waiting_cells_count();
|
||||
append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), pchan, cell,
|
||||
CELL_DIRECTION_IN, 0);
|
||||
new_count = get_mock_scheduler_has_waiting_cells_count();
|
||||
tt_int_op(new_count, ==, old_count + 1);
|
||||
|
||||
UNMOCK(scheduler_channel_has_waiting_cells);
|
||||
|
||||
/* Get rid of the fake channels */
|
||||
MOCK(scheduler_release_channel, scheduler_release_channel_mock);
|
||||
channel_mark_for_close(nchan);
|
||||
channel_mark_for_close(pchan);
|
||||
UNMOCK(scheduler_release_channel);
|
||||
|
||||
/* Shut down channels */
|
||||
channel_free_all();
|
||||
nchan = pchan = NULL;
|
||||
|
||||
done:
|
||||
tor_free(orcirc);
|
||||
if (nchan && nchan->cmux) circuitmux_free(nchan->cmux);
|
||||
tor_free(nchan);
|
||||
if (pchan && pchan->cmux) circuitmux_free(pchan->cmux);
|
||||
tor_free(pchan);
|
||||
#ifdef ENABLE_MEMPOOLS
|
||||
free_cell_pool();
|
||||
#endif /* ENABLE_MEMPOOLS */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
struct testcase_t relay_tests[] = {
|
||||
{ "append_cell_to_circuit_queue", test_relay_append_cell_to_circuit_queue,
|
||||
TT_FORK, NULL, NULL },
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
||||
+27
-27
@@ -87,24 +87,24 @@ test_relaycell_resolved(void *arg)
|
||||
srm_ncalls = mum_ncalls = 0; \
|
||||
} while (0)
|
||||
#define ASSERT_MARK_CALLED(reason) do { \
|
||||
tt_int_op(mum_ncalls, ==, 1); \
|
||||
tt_ptr_op(mum_conn, ==, entryconn); \
|
||||
tt_int_op(mum_endreason, ==, (reason)); \
|
||||
tt_int_op(mum_ncalls, OP_EQ, 1); \
|
||||
tt_ptr_op(mum_conn, OP_EQ, entryconn); \
|
||||
tt_int_op(mum_endreason, OP_EQ, (reason)); \
|
||||
} while (0)
|
||||
#define ASSERT_RESOLVED_CALLED(atype, answer, ttl, expires) do { \
|
||||
tt_int_op(srm_ncalls, ==, 1); \
|
||||
tt_ptr_op(srm_conn, ==, entryconn); \
|
||||
tt_int_op(srm_atype, ==, (atype)); \
|
||||
tt_int_op(srm_ncalls, OP_EQ, 1); \
|
||||
tt_ptr_op(srm_conn, OP_EQ, entryconn); \
|
||||
tt_int_op(srm_atype, OP_EQ, (atype)); \
|
||||
if (answer) { \
|
||||
tt_int_op(srm_alen, ==, sizeof(answer)-1); \
|
||||
tt_int_op(srm_alen, <, 512); \
|
||||
tt_int_op(srm_answer_is_set, ==, 1); \
|
||||
tt_mem_op(srm_answer, ==, answer, sizeof(answer)-1); \
|
||||
tt_int_op(srm_alen, OP_EQ, sizeof(answer)-1); \
|
||||
tt_int_op(srm_alen, OP_LT, 512); \
|
||||
tt_int_op(srm_answer_is_set, OP_EQ, 1); \
|
||||
tt_mem_op(srm_answer, OP_EQ, answer, sizeof(answer)-1); \
|
||||
} else { \
|
||||
tt_int_op(srm_answer_is_set, ==, 0); \
|
||||
tt_int_op(srm_answer_is_set, OP_EQ, 0); \
|
||||
} \
|
||||
tt_int_op(srm_ttl, ==, ttl); \
|
||||
tt_int_op(srm_expires, ==, expires); \
|
||||
tt_int_op(srm_ttl, OP_EQ, ttl); \
|
||||
tt_int_op(srm_expires, OP_EQ, expires); \
|
||||
} while (0)
|
||||
|
||||
(void)arg;
|
||||
@@ -130,9 +130,9 @@ test_relaycell_resolved(void *arg)
|
||||
/* Try with connection in non-RESOLVE_WAIT state: cell gets ignored */
|
||||
MOCK_RESET();
|
||||
r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(srm_ncalls, ==, 0);
|
||||
tt_int_op(mum_ncalls, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
tt_int_op(srm_ncalls, OP_EQ, 0);
|
||||
tt_int_op(mum_ncalls, OP_EQ, 0);
|
||||
|
||||
/* Now put it in the right state. */
|
||||
ENTRY_TO_CONN(entryconn)->state = AP_CONN_STATE_RESOLVE_WAIT;
|
||||
@@ -144,7 +144,7 @@ test_relaycell_resolved(void *arg)
|
||||
/* We prefer ipv4, so we should get the first ipv4 answer */
|
||||
MOCK_RESET();
|
||||
r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
|
||||
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
|
||||
ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_IPV4, "\x7f\x00\x01\x02", 256, -1);
|
||||
@@ -153,7 +153,7 @@ test_relaycell_resolved(void *arg)
|
||||
MOCK_RESET();
|
||||
options->ClientDNSRejectInternalAddresses = 1;
|
||||
r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
|
||||
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
|
||||
ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_IPV4, "\x12\x00\x00\x01", 512, -1);
|
||||
@@ -162,7 +162,7 @@ test_relaycell_resolved(void *arg)
|
||||
entryconn->prefer_ipv6_traffic = 1;
|
||||
MOCK_RESET();
|
||||
r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
|
||||
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
|
||||
ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_IPV6,
|
||||
@@ -174,7 +174,7 @@ test_relaycell_resolved(void *arg)
|
||||
MOCK_RESET();
|
||||
SET_CELL("\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
|
||||
r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
|
||||
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
|
||||
ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_IPV4, "\x12\x00\x00\x01", 512, -1);
|
||||
@@ -184,7 +184,7 @@ test_relaycell_resolved(void *arg)
|
||||
MOCK_RESET();
|
||||
entryconn->ipv4_traffic_ok = 0;
|
||||
r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
|
||||
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
|
||||
ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_ERROR, NULL, -1, -1);
|
||||
@@ -194,7 +194,7 @@ test_relaycell_resolved(void *arg)
|
||||
entryconn->ipv4_traffic_ok = 1;
|
||||
entryconn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR;
|
||||
r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
|
||||
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
|
||||
ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_ERROR, NULL, -1, -1);
|
||||
@@ -203,7 +203,7 @@ test_relaycell_resolved(void *arg)
|
||||
MOCK_RESET();
|
||||
SET_CELL("\x00\x0fwww.example.com\x00\x01\x00\x00");
|
||||
r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
|
||||
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
|
||||
ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_HOSTNAME, "www.example.com", 65536, -1);
|
||||
@@ -213,9 +213,9 @@ test_relaycell_resolved(void *arg)
|
||||
entryconn->socks_request->command = SOCKS_COMMAND_RESOLVE;
|
||||
SET_CELL("\x04\x04\x01\x02\x03\x04"); /* no ttl */
|
||||
r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
ASSERT_MARK_CALLED(END_STREAM_REASON_TORPROTOCOL);
|
||||
tt_int_op(srm_ncalls, ==, 0);
|
||||
tt_int_op(srm_ncalls, OP_EQ, 0);
|
||||
|
||||
/* error on all addresses private */
|
||||
MOCK_RESET();
|
||||
@@ -224,7 +224,7 @@ test_relaycell_resolved(void *arg)
|
||||
/* IPv4: 192.168.1.1, ttl 256 */
|
||||
"\x04\x04\xc0\xa8\x01\x01\x00\x00\x01\x00");
|
||||
r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
ASSERT_MARK_CALLED(END_STREAM_REASON_TORPROTOCOL);
|
||||
ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_ERROR_TRANSIENT, NULL, 0, TIME_MAX);
|
||||
|
||||
@@ -232,7 +232,7 @@ test_relaycell_resolved(void *arg)
|
||||
MOCK_RESET();
|
||||
SET_CELL("\xf0\x15" "quiet and meaningless" "\x00\x00\x0f\xff");
|
||||
r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
|
||||
END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
|
||||
ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_ERROR_TRANSIENT, NULL, -1, -1);
|
||||
|
||||
+26
-26
@@ -44,7 +44,7 @@ test_replaycache_badalloc(void *arg)
|
||||
/* Negative interval should get adjusted to zero */
|
||||
r = replaycache_new(600, -300);
|
||||
tt_assert(r != NULL);
|
||||
tt_int_op(r->scrub_interval,==, 0);
|
||||
tt_int_op(r->scrub_interval,OP_EQ, 0);
|
||||
replaycache_free(r);
|
||||
/* Negative horizon and negative interval should still fail */
|
||||
r = replaycache_new(-600, -300);
|
||||
@@ -81,13 +81,13 @@ test_replaycache_miss(void *arg)
|
||||
result =
|
||||
replaycache_add_and_test_internal(1200, r, test_buffer,
|
||||
strlen(test_buffer), NULL);
|
||||
tt_int_op(result,==, 0);
|
||||
tt_int_op(result,OP_EQ, 0);
|
||||
|
||||
/* poke the bad-parameter error case too */
|
||||
result =
|
||||
replaycache_add_and_test_internal(1200, NULL, test_buffer,
|
||||
strlen(test_buffer), NULL);
|
||||
tt_int_op(result,==, 0);
|
||||
tt_int_op(result,OP_EQ, 0);
|
||||
|
||||
done:
|
||||
if (r) replaycache_free(r);
|
||||
@@ -108,12 +108,12 @@ test_replaycache_hit(void *arg)
|
||||
result =
|
||||
replaycache_add_and_test_internal(1200, r, test_buffer,
|
||||
strlen(test_buffer), NULL);
|
||||
tt_int_op(result,==, 0);
|
||||
tt_int_op(result,OP_EQ, 0);
|
||||
|
||||
result =
|
||||
replaycache_add_and_test_internal(1300, r, test_buffer,
|
||||
strlen(test_buffer), NULL);
|
||||
tt_int_op(result,==, 1);
|
||||
tt_int_op(result,OP_EQ, 1);
|
||||
|
||||
done:
|
||||
if (r) replaycache_free(r);
|
||||
@@ -134,17 +134,17 @@ test_replaycache_age(void *arg)
|
||||
result =
|
||||
replaycache_add_and_test_internal(1200, r, test_buffer,
|
||||
strlen(test_buffer), NULL);
|
||||
tt_int_op(result,==, 0);
|
||||
tt_int_op(result,OP_EQ, 0);
|
||||
|
||||
result =
|
||||
replaycache_add_and_test_internal(1300, r, test_buffer,
|
||||
strlen(test_buffer), NULL);
|
||||
tt_int_op(result,==, 1);
|
||||
tt_int_op(result,OP_EQ, 1);
|
||||
|
||||
result =
|
||||
replaycache_add_and_test_internal(3000, r, test_buffer,
|
||||
strlen(test_buffer), NULL);
|
||||
tt_int_op(result,==, 0);
|
||||
tt_int_op(result,OP_EQ, 0);
|
||||
|
||||
done:
|
||||
if (r) replaycache_free(r);
|
||||
@@ -166,13 +166,13 @@ test_replaycache_elapsed(void *arg)
|
||||
result =
|
||||
replaycache_add_and_test_internal(1200, r, test_buffer,
|
||||
strlen(test_buffer), NULL);
|
||||
tt_int_op(result,==, 0);
|
||||
tt_int_op(result,OP_EQ, 0);
|
||||
|
||||
result =
|
||||
replaycache_add_and_test_internal(1300, r, test_buffer,
|
||||
strlen(test_buffer), &elapsed);
|
||||
tt_int_op(result,==, 1);
|
||||
tt_int_op(elapsed,==, 100);
|
||||
tt_int_op(result,OP_EQ, 1);
|
||||
tt_int_op(elapsed,OP_EQ, 100);
|
||||
|
||||
done:
|
||||
if (r) replaycache_free(r);
|
||||
@@ -193,17 +193,17 @@ test_replaycache_noexpire(void *arg)
|
||||
result =
|
||||
replaycache_add_and_test_internal(1200, r, test_buffer,
|
||||
strlen(test_buffer), NULL);
|
||||
tt_int_op(result,==, 0);
|
||||
tt_int_op(result,OP_EQ, 0);
|
||||
|
||||
result =
|
||||
replaycache_add_and_test_internal(1300, r, test_buffer,
|
||||
strlen(test_buffer), NULL);
|
||||
tt_int_op(result,==, 1);
|
||||
tt_int_op(result,OP_EQ, 1);
|
||||
|
||||
result =
|
||||
replaycache_add_and_test_internal(3000, r, test_buffer,
|
||||
strlen(test_buffer), NULL);
|
||||
tt_int_op(result,==, 1);
|
||||
tt_int_op(result,OP_EQ, 1);
|
||||
|
||||
done:
|
||||
if (r) replaycache_free(r);
|
||||
@@ -225,12 +225,12 @@ test_replaycache_scrub(void *arg)
|
||||
result =
|
||||
replaycache_add_and_test_internal(100, r, test_buffer,
|
||||
strlen(test_buffer), NULL);
|
||||
tt_int_op(result,==, 0);
|
||||
tt_int_op(result,OP_EQ, 0);
|
||||
|
||||
result =
|
||||
replaycache_add_and_test_internal(200, r, test_buffer,
|
||||
strlen(test_buffer), NULL);
|
||||
tt_int_op(result,==, 1);
|
||||
tt_int_op(result,OP_EQ, 1);
|
||||
|
||||
/*
|
||||
* Poke a few replaycache_scrub_if_needed_internal() error cases that
|
||||
@@ -245,7 +245,7 @@ test_replaycache_scrub(void *arg)
|
||||
/* Make sure we hit the aging-out case too */
|
||||
replaycache_scrub_if_needed_internal(1500, r);
|
||||
/* Assert that we aged it */
|
||||
tt_int_op(digestmap_size(r->digests_seen),==, 0);
|
||||
tt_int_op(digestmap_size(r->digests_seen),OP_EQ, 0);
|
||||
|
||||
done:
|
||||
if (r) replaycache_free(r);
|
||||
@@ -268,16 +268,16 @@ test_replaycache_future(void *arg)
|
||||
result =
|
||||
replaycache_add_and_test_internal(100, r, test_buffer,
|
||||
strlen(test_buffer), &elapsed);
|
||||
tt_int_op(result,==, 0);
|
||||
tt_int_op(result,OP_EQ, 0);
|
||||
/* elapsed should still be 0, since it wasn't written */
|
||||
tt_int_op(elapsed,==, 0);
|
||||
tt_int_op(elapsed,OP_EQ, 0);
|
||||
|
||||
result =
|
||||
replaycache_add_and_test_internal(200, r, test_buffer,
|
||||
strlen(test_buffer), &elapsed);
|
||||
tt_int_op(result,==, 1);
|
||||
tt_int_op(result,OP_EQ, 1);
|
||||
/* elapsed should be the time since the last hit */
|
||||
tt_int_op(elapsed,==, 100);
|
||||
tt_int_op(elapsed,OP_EQ, 100);
|
||||
|
||||
/*
|
||||
* Now let's turn the clock back to get coverage on the cache entry from the
|
||||
@@ -287,9 +287,9 @@ test_replaycache_future(void *arg)
|
||||
replaycache_add_and_test_internal(150, r, test_buffer,
|
||||
strlen(test_buffer), &elapsed);
|
||||
/* We should still get a hit */
|
||||
tt_int_op(result,==, 1);
|
||||
tt_int_op(result,OP_EQ, 1);
|
||||
/* ...but it shouldn't let us see a negative elapsed time */
|
||||
tt_int_op(elapsed,==, 0);
|
||||
tt_int_op(elapsed,OP_EQ, 0);
|
||||
|
||||
done:
|
||||
if (r) replaycache_free(r);
|
||||
@@ -316,18 +316,18 @@ test_replaycache_realtime(void *arg)
|
||||
/* This should miss */
|
||||
result =
|
||||
replaycache_add_and_test(r, test_buffer, strlen(test_buffer));
|
||||
tt_int_op(result,==, 0);
|
||||
tt_int_op(result,OP_EQ, 0);
|
||||
|
||||
/* This should hit */
|
||||
result =
|
||||
replaycache_add_and_test(r, test_buffer, strlen(test_buffer));
|
||||
tt_int_op(result,==, 1);
|
||||
tt_int_op(result,OP_EQ, 1);
|
||||
|
||||
/* This should hit and return a small elapsed time */
|
||||
result =
|
||||
replaycache_add_test_and_elapsed(r, test_buffer,
|
||||
strlen(test_buffer), &elapsed);
|
||||
tt_int_op(result,==, 1);
|
||||
tt_int_op(result,OP_EQ, 1);
|
||||
tt_assert(elapsed >= 0);
|
||||
tt_assert(elapsed <= 5);
|
||||
|
||||
|
||||
@@ -33,38 +33,38 @@ test_routerkeys_write_fingerprint(void *arg)
|
||||
set_server_identity_key(key);
|
||||
set_client_identity_key(crypto_pk_dup_key(key));
|
||||
|
||||
tt_int_op(0, ==, check_private_dir(ddir, CPD_CREATE, NULL));
|
||||
tt_int_op(crypto_pk_cmp_keys(get_server_identity_key(),key),==,0);
|
||||
tt_int_op(0, OP_EQ, check_private_dir(ddir, CPD_CREATE, NULL));
|
||||
tt_int_op(crypto_pk_cmp_keys(get_server_identity_key(),key),OP_EQ,0);
|
||||
|
||||
/* Write fingerprint file */
|
||||
tt_int_op(0, ==, router_write_fingerprint(0));
|
||||
tt_int_op(0, OP_EQ, router_write_fingerprint(0));
|
||||
cp = read_file_to_str(get_fname("write_fingerprint/fingerprint"),
|
||||
0, NULL);
|
||||
crypto_pk_get_fingerprint(key, fp, 0);
|
||||
tor_asprintf(&cp2, "haflinger %s\n", fp);
|
||||
tt_str_op(cp, ==, cp2);
|
||||
tt_str_op(cp, OP_EQ, cp2);
|
||||
tor_free(cp);
|
||||
tor_free(cp2);
|
||||
|
||||
/* Write hashed-fingerprint file */
|
||||
tt_int_op(0, ==, router_write_fingerprint(1));
|
||||
tt_int_op(0, OP_EQ, router_write_fingerprint(1));
|
||||
cp = read_file_to_str(get_fname("write_fingerprint/hashed-fingerprint"),
|
||||
0, NULL);
|
||||
crypto_pk_get_hashed_fingerprint(key, fp);
|
||||
tor_asprintf(&cp2, "haflinger %s\n", fp);
|
||||
tt_str_op(cp, ==, cp2);
|
||||
tt_str_op(cp, OP_EQ, cp2);
|
||||
tor_free(cp);
|
||||
tor_free(cp2);
|
||||
|
||||
/* Replace outdated file */
|
||||
write_str_to_file(get_fname("write_fingerprint/hashed-fingerprint"),
|
||||
"junk goes here", 0);
|
||||
tt_int_op(0, ==, router_write_fingerprint(1));
|
||||
tt_int_op(0, OP_EQ, router_write_fingerprint(1));
|
||||
cp = read_file_to_str(get_fname("write_fingerprint/hashed-fingerprint"),
|
||||
0, NULL);
|
||||
crypto_pk_get_hashed_fingerprint(key, fp);
|
||||
tor_asprintf(&cp2, "haflinger %s\n", fp);
|
||||
tt_str_op(cp, ==, cp2);
|
||||
tt_str_op(cp, OP_EQ, cp2);
|
||||
tor_free(cp);
|
||||
tor_free(cp2);
|
||||
|
||||
|
||||
+138
-138
@@ -25,12 +25,12 @@ NS(test_main)(void *arg)
|
||||
|
||||
rs = routerset_new();
|
||||
|
||||
tt_ptr_op(rs, !=, NULL);
|
||||
tt_ptr_op(rs->list, !=, NULL);
|
||||
tt_ptr_op(rs->names, !=, NULL);
|
||||
tt_ptr_op(rs->digests, !=, NULL);
|
||||
tt_ptr_op(rs->policies, !=, NULL);
|
||||
tt_ptr_op(rs->country_names, !=, NULL);
|
||||
tt_ptr_op(rs, OP_NE, NULL);
|
||||
tt_ptr_op(rs->list, OP_NE, NULL);
|
||||
tt_ptr_op(rs->names, OP_NE, NULL);
|
||||
tt_ptr_op(rs->digests, OP_NE, NULL);
|
||||
tt_ptr_op(rs->policies, OP_NE, NULL);
|
||||
tt_ptr_op(rs->country_names, OP_NE, NULL);
|
||||
|
||||
done:
|
||||
routerset_free(rs);
|
||||
@@ -53,30 +53,30 @@ NS(test_main)(void *arg)
|
||||
/* strlen(c) < 4 */
|
||||
input = "xxx";
|
||||
name = routerset_get_countryname(input);
|
||||
tt_ptr_op(name, ==, NULL);
|
||||
tt_ptr_op(name, OP_EQ, NULL);
|
||||
tor_free(name);
|
||||
|
||||
/* c[0] != '{' */
|
||||
input = "xxx}";
|
||||
name = routerset_get_countryname(input);
|
||||
tt_ptr_op(name, ==, NULL);
|
||||
tt_ptr_op(name, OP_EQ, NULL);
|
||||
tor_free(name);
|
||||
|
||||
/* c[3] != '}' */
|
||||
input = "{xxx";
|
||||
name = routerset_get_countryname(input);
|
||||
tt_ptr_op(name, ==, NULL);
|
||||
tt_ptr_op(name, OP_EQ, NULL);
|
||||
tor_free(name);
|
||||
|
||||
/* tor_strlower */
|
||||
input = "{XX}";
|
||||
name = routerset_get_countryname(input);
|
||||
tt_str_op(name, ==, "xx");
|
||||
tt_str_op(name, OP_EQ, "xx");
|
||||
tor_free(name);
|
||||
|
||||
input = "{xx}";
|
||||
name = routerset_get_countryname(input);
|
||||
tt_str_op(name, ==, "xx");
|
||||
tt_str_op(name, OP_EQ, "xx");
|
||||
done:
|
||||
tor_free(name);
|
||||
}
|
||||
@@ -103,10 +103,10 @@ NS(test_main)(void *arg)
|
||||
|
||||
routerset_refresh_countries(set);
|
||||
|
||||
tt_ptr_op(set->countries, ==, NULL);
|
||||
tt_int_op(set->n_countries, ==, 0);
|
||||
tt_int_op(CALLED(geoip_is_loaded), ==, 1);
|
||||
tt_int_op(CALLED(geoip_get_n_countries), ==, 0);
|
||||
tt_ptr_op(set->countries, OP_EQ, NULL);
|
||||
tt_int_op(set->n_countries, OP_EQ, 0);
|
||||
tt_int_op(CALLED(geoip_is_loaded), OP_EQ, 1);
|
||||
tt_int_op(CALLED(geoip_get_n_countries), OP_EQ, 0);
|
||||
|
||||
done:
|
||||
NS_UNMOCK(geoip_is_loaded);
|
||||
@@ -154,12 +154,12 @@ NS(test_main)(void *arg)
|
||||
|
||||
routerset_refresh_countries(set);
|
||||
|
||||
tt_ptr_op(set->countries, !=, NULL);
|
||||
tt_int_op(set->n_countries, ==, 1);
|
||||
tt_int_op((unsigned int)(*set->countries), ==, 0);
|
||||
tt_int_op(CALLED(geoip_is_loaded), ==, 1);
|
||||
tt_int_op(CALLED(geoip_get_n_countries), ==, 1);
|
||||
tt_int_op(CALLED(geoip_get_country), ==, 0);
|
||||
tt_ptr_op(set->countries, OP_NE, NULL);
|
||||
tt_int_op(set->n_countries, OP_EQ, 1);
|
||||
tt_int_op((unsigned int)(*set->countries), OP_EQ, 0);
|
||||
tt_int_op(CALLED(geoip_is_loaded), OP_EQ, 1);
|
||||
tt_int_op(CALLED(geoip_get_n_countries), OP_EQ, 1);
|
||||
tt_int_op(CALLED(geoip_get_country), OP_EQ, 0);
|
||||
|
||||
done:
|
||||
NS_UNMOCK(geoip_is_loaded);
|
||||
@@ -218,12 +218,12 @@ NS(test_main)(void *arg)
|
||||
|
||||
routerset_refresh_countries(set);
|
||||
|
||||
tt_ptr_op(set->countries, !=, NULL);
|
||||
tt_int_op(set->n_countries, ==, 2);
|
||||
tt_int_op(CALLED(geoip_is_loaded), ==, 1);
|
||||
tt_int_op(CALLED(geoip_get_n_countries), ==, 1);
|
||||
tt_int_op(CALLED(geoip_get_country), ==, 1);
|
||||
tt_int_op((unsigned int)(*set->countries), !=, 0);
|
||||
tt_ptr_op(set->countries, OP_NE, NULL);
|
||||
tt_int_op(set->n_countries, OP_EQ, 2);
|
||||
tt_int_op(CALLED(geoip_is_loaded), OP_EQ, 1);
|
||||
tt_int_op(CALLED(geoip_get_n_countries), OP_EQ, 1);
|
||||
tt_int_op(CALLED(geoip_get_country), OP_EQ, 1);
|
||||
tt_int_op((unsigned int)(*set->countries), OP_NE, 0);
|
||||
|
||||
done:
|
||||
NS_UNMOCK(geoip_is_loaded);
|
||||
@@ -283,12 +283,12 @@ NS(test_main)(void *arg)
|
||||
|
||||
routerset_refresh_countries(set);
|
||||
|
||||
tt_ptr_op(set->countries, !=, NULL);
|
||||
tt_int_op(set->n_countries, ==, 2);
|
||||
tt_int_op(CALLED(geoip_is_loaded), ==, 1);
|
||||
tt_int_op(CALLED(geoip_get_n_countries), ==, 1);
|
||||
tt_int_op(CALLED(geoip_get_country), ==, 1);
|
||||
tt_int_op((unsigned int)(*set->countries), ==, 0);
|
||||
tt_ptr_op(set->countries, OP_NE, NULL);
|
||||
tt_int_op(set->n_countries, OP_EQ, 2);
|
||||
tt_int_op(CALLED(geoip_is_loaded), OP_EQ, 1);
|
||||
tt_int_op(CALLED(geoip_get_n_countries), OP_EQ, 1);
|
||||
tt_int_op(CALLED(geoip_get_country), OP_EQ, 1);
|
||||
tt_int_op((unsigned int)(*set->countries), OP_EQ, 0);
|
||||
|
||||
done:
|
||||
NS_UNMOCK(geoip_is_loaded);
|
||||
@@ -340,7 +340,7 @@ NS(test_main)(void *arg)
|
||||
|
||||
r = routerset_parse(set, s, "");
|
||||
|
||||
tt_int_op(r, ==, -1);
|
||||
tt_int_op(r, OP_EQ, -1);
|
||||
|
||||
done:
|
||||
routerset_free(set);
|
||||
@@ -365,8 +365,8 @@ NS(test_main)(void *arg)
|
||||
set = routerset_new();
|
||||
s = "$0000000000000000000000000000000000000000";
|
||||
r = routerset_parse(set, s, "");
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(digestmap_isempty(set->digests), !=, 1);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
tt_int_op(digestmap_isempty(set->digests), OP_NE, 1);
|
||||
|
||||
done:
|
||||
routerset_free(set);
|
||||
@@ -390,8 +390,8 @@ NS(test_main)(void *arg)
|
||||
set = routerset_new();
|
||||
s = "fred";
|
||||
r = routerset_parse(set, s, "");
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(strmap_isempty(set->names), !=, 1);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
tt_int_op(strmap_isempty(set->names), OP_NE, 1);
|
||||
|
||||
done:
|
||||
routerset_free(set);
|
||||
@@ -415,8 +415,8 @@ NS(test_main)(void *arg)
|
||||
set = routerset_new();
|
||||
s = "{cc}";
|
||||
r = routerset_parse(set, s, "");
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(smartlist_len(set->country_names), !=, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
tt_int_op(smartlist_len(set->country_names), OP_NE, 0);
|
||||
|
||||
done:
|
||||
routerset_free(set);
|
||||
@@ -448,9 +448,9 @@ NS(test_main)(void *arg)
|
||||
set = routerset_new();
|
||||
s = "*";
|
||||
r = routerset_parse(set, s, "");
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(smartlist_len(set->policies), !=, 0);
|
||||
tt_int_op(CALLED(router_parse_addr_policy_item_from_string), ==, 1);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
tt_int_op(smartlist_len(set->policies), OP_NE, 0);
|
||||
tt_int_op(CALLED(router_parse_addr_policy_item_from_string), OP_EQ, 1);
|
||||
|
||||
done:
|
||||
routerset_free(set);
|
||||
@@ -489,10 +489,10 @@ NS(test_main)(void *arg)
|
||||
NS_MOCK(smartlist_new);
|
||||
|
||||
routerset_union(set, NULL);
|
||||
tt_int_op(CALLED(smartlist_new), ==, 0);
|
||||
tt_int_op(CALLED(smartlist_new), OP_EQ, 0);
|
||||
|
||||
routerset_union(set, bad_set);
|
||||
tt_int_op(CALLED(smartlist_new), ==, 0);
|
||||
tt_int_op(CALLED(smartlist_new), OP_EQ, 0);
|
||||
|
||||
done:
|
||||
NS_UNMOCK(smartlist_new);
|
||||
@@ -529,7 +529,7 @@ NS(test_main)(void *arg)
|
||||
smartlist_add(src->list, tor_strdup("{xx}"));
|
||||
routerset_union(tgt, src);
|
||||
|
||||
tt_int_op(smartlist_len(tgt->list), !=, 0);
|
||||
tt_int_op(smartlist_len(tgt->list), OP_NE, 0);
|
||||
|
||||
done:
|
||||
routerset_free(src);
|
||||
@@ -556,7 +556,7 @@ NS(test_main)(void *arg)
|
||||
is_list = routerset_is_list(set);
|
||||
routerset_free(set);
|
||||
set = NULL;
|
||||
tt_int_op(is_list, !=, 0);
|
||||
tt_int_op(is_list, OP_NE, 0);
|
||||
|
||||
/* len(set->country_names) != 0, len(set->policies) == 0 */
|
||||
set = routerset_new();
|
||||
@@ -564,7 +564,7 @@ NS(test_main)(void *arg)
|
||||
is_list = routerset_is_list(set);
|
||||
routerset_free(set);
|
||||
set = NULL;
|
||||
tt_int_op(is_list, ==, 0);
|
||||
tt_int_op(is_list, OP_EQ, 0);
|
||||
|
||||
/* len(set->country_names) == 0, len(set->policies) != 0 */
|
||||
set = routerset_new();
|
||||
@@ -573,7 +573,7 @@ NS(test_main)(void *arg)
|
||||
is_list = routerset_is_list(set);
|
||||
routerset_free(set);
|
||||
set = NULL;
|
||||
tt_int_op(is_list, ==, 0);
|
||||
tt_int_op(is_list, OP_EQ, 0);
|
||||
|
||||
/* len(set->country_names) != 0, len(set->policies) != 0 */
|
||||
set = routerset_new();
|
||||
@@ -583,7 +583,7 @@ NS(test_main)(void *arg)
|
||||
is_list = routerset_is_list(set);
|
||||
routerset_free(set);
|
||||
set = NULL;
|
||||
tt_int_op(is_list, ==, 0);
|
||||
tt_int_op(is_list, OP_EQ, 0);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -605,12 +605,12 @@ NS(test_main)(void *arg)
|
||||
|
||||
set = NULL;
|
||||
needs_geoip = routerset_needs_geoip(set);
|
||||
tt_int_op(needs_geoip, ==, 0);
|
||||
tt_int_op(needs_geoip, OP_EQ, 0);
|
||||
|
||||
set = routerset_new();
|
||||
needs_geoip = routerset_needs_geoip(set);
|
||||
routerset_free((routerset_t *)set);
|
||||
tt_int_op(needs_geoip, ==, 0);
|
||||
tt_int_op(needs_geoip, OP_EQ, 0);
|
||||
set = NULL;
|
||||
|
||||
set = routerset_new();
|
||||
@@ -618,7 +618,7 @@ NS(test_main)(void *arg)
|
||||
needs_geoip = routerset_needs_geoip(set);
|
||||
routerset_free((routerset_t *)set);
|
||||
set = NULL;
|
||||
tt_int_op(needs_geoip, !=, 0);
|
||||
tt_int_op(needs_geoip, OP_NE, 0);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -639,20 +639,20 @@ NS(test_main)(void *arg)
|
||||
(void)arg;
|
||||
|
||||
is_empty = routerset_is_empty(set);
|
||||
tt_int_op(is_empty, !=, 0);
|
||||
tt_int_op(is_empty, OP_NE, 0);
|
||||
|
||||
set = routerset_new();
|
||||
is_empty = routerset_is_empty(set);
|
||||
routerset_free(set);
|
||||
set = NULL;
|
||||
tt_int_op(is_empty, !=, 0);
|
||||
tt_int_op(is_empty, OP_NE, 0);
|
||||
|
||||
set = routerset_new();
|
||||
smartlist_add(set->list, tor_strdup("{xx}"));
|
||||
is_empty = routerset_is_empty(set);
|
||||
routerset_free(set);
|
||||
set = NULL;
|
||||
tt_int_op(is_empty, ==, 0);
|
||||
tt_int_op(is_empty, OP_EQ, 0);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -675,13 +675,13 @@ NS(test_main)(void *arg)
|
||||
|
||||
contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
|
||||
|
||||
tt_int_op(contains, ==, 0);
|
||||
tt_int_op(contains, OP_EQ, 0);
|
||||
|
||||
set = tor_malloc_zero(sizeof(routerset_t));
|
||||
set->list = NULL;
|
||||
contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
|
||||
tor_free(set);
|
||||
tt_int_op(contains, ==, 0);
|
||||
tt_int_op(contains, OP_EQ, 0);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -706,7 +706,7 @@ NS(test_main)(void *arg)
|
||||
contains = routerset_contains(set, NULL, 0, nickname, NULL, 0);
|
||||
routerset_free(set);
|
||||
|
||||
tt_int_op(contains, ==, 0);
|
||||
tt_int_op(contains, OP_EQ, 0);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -733,7 +733,7 @@ NS(test_main)(void *arg)
|
||||
contains = routerset_contains(set, NULL, 0, nickname, NULL, 0);
|
||||
routerset_free(set);
|
||||
|
||||
tt_int_op(contains, ==, 4);
|
||||
tt_int_op(contains, OP_EQ, 4);
|
||||
done:
|
||||
;
|
||||
}
|
||||
@@ -757,7 +757,7 @@ NS(test_main)(void *arg)
|
||||
contains = routerset_contains(set, NULL, 0, "foo", NULL, 0);
|
||||
routerset_free(set);
|
||||
|
||||
tt_int_op(contains, ==, 0);
|
||||
tt_int_op(contains, OP_EQ, 0);
|
||||
done:
|
||||
;
|
||||
}
|
||||
@@ -782,7 +782,7 @@ NS(test_main)(void *arg)
|
||||
contains = routerset_contains(set, NULL, 0, NULL, (const char*)foo, 0);
|
||||
routerset_free(set);
|
||||
|
||||
tt_int_op(contains, ==, 4);
|
||||
tt_int_op(contains, OP_EQ, 4);
|
||||
done:
|
||||
;
|
||||
}
|
||||
@@ -808,7 +808,7 @@ NS(test_main)(void *arg)
|
||||
contains = routerset_contains(set, NULL, 0, NULL, (const char*)foo, 0);
|
||||
routerset_free(set);
|
||||
|
||||
tt_int_op(contains, ==, 0);
|
||||
tt_int_op(contains, OP_EQ, 0);
|
||||
done:
|
||||
;
|
||||
}
|
||||
@@ -833,7 +833,7 @@ NS(test_main)(void *arg)
|
||||
contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
|
||||
routerset_free(set);
|
||||
|
||||
tt_int_op(contains, ==, 0);
|
||||
tt_int_op(contains, OP_EQ, 0);
|
||||
done:
|
||||
;
|
||||
}
|
||||
@@ -865,8 +865,8 @@ NS(test_main)(void *arg)
|
||||
contains = routerset_contains(set, addr, 0, NULL, NULL, 0);
|
||||
routerset_free(set);
|
||||
|
||||
tt_int_op(CALLED(compare_tor_addr_to_addr_policy), ==, 1);
|
||||
tt_int_op(contains, ==, 3);
|
||||
tt_int_op(CALLED(compare_tor_addr_to_addr_policy), OP_EQ, 1);
|
||||
tt_int_op(contains, OP_EQ, 3);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -879,7 +879,7 @@ NS(compare_tor_addr_to_addr_policy)(const tor_addr_t *addr, uint16_t port,
|
||||
(void)port;
|
||||
(void)policy;
|
||||
CALLED(compare_tor_addr_to_addr_policy)++;
|
||||
tt_ptr_op(addr, ==, MOCK_TOR_ADDR_PTR);
|
||||
tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
|
||||
return ADDR_POLICY_REJECTED;
|
||||
|
||||
done:
|
||||
@@ -910,8 +910,8 @@ NS(test_main)(void *arg)
|
||||
contains = routerset_contains(set, addr, 0, NULL, NULL, 0);
|
||||
routerset_free(set);
|
||||
|
||||
tt_int_op(CALLED(compare_tor_addr_to_addr_policy), ==, 1);
|
||||
tt_int_op(contains, ==, 0);
|
||||
tt_int_op(CALLED(compare_tor_addr_to_addr_policy), OP_EQ, 1);
|
||||
tt_int_op(contains, OP_EQ, 0);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -924,7 +924,7 @@ NS(compare_tor_addr_to_addr_policy)(const tor_addr_t *addr, uint16_t port,
|
||||
(void)port;
|
||||
(void)policy;
|
||||
CALLED(compare_tor_addr_to_addr_policy)++;
|
||||
tt_ptr_op(addr, ==, MOCK_TOR_ADDR_PTR);
|
||||
tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
|
||||
|
||||
return ADDR_POLICY_ACCEPTED;
|
||||
|
||||
@@ -955,7 +955,7 @@ NS(test_main)(void *arg)
|
||||
contains = routerset_contains(set, NULL, 0, NULL, NULL, 0);
|
||||
routerset_free(set);
|
||||
|
||||
tt_int_op(contains, ==, 0);
|
||||
tt_int_op(contains, OP_EQ, 0);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -968,7 +968,7 @@ NS(compare_tor_addr_to_addr_policy)(const tor_addr_t *addr, uint16_t port,
|
||||
(void)port;
|
||||
(void)policy;
|
||||
CALLED(compare_tor_addr_to_addr_policy)++;
|
||||
tt_ptr_op(addr, ==, MOCK_TOR_ADDR_PTR);
|
||||
tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
|
||||
|
||||
return ADDR_POLICY_ACCEPTED;
|
||||
|
||||
@@ -1003,9 +1003,9 @@ NS(test_main)(void *arg)
|
||||
contains = routerset_contains(set, MOCK_TOR_ADDR_PTR, 0, NULL, NULL, -1);
|
||||
routerset_free(set);
|
||||
|
||||
tt_int_op(contains, ==, 0);
|
||||
tt_int_op(CALLED(compare_tor_addr_to_addr_policy), ==, 1);
|
||||
tt_int_op(CALLED(geoip_get_country_by_addr), ==, 1);
|
||||
tt_int_op(contains, OP_EQ, 0);
|
||||
tt_int_op(CALLED(compare_tor_addr_to_addr_policy), OP_EQ, 1);
|
||||
tt_int_op(CALLED(geoip_get_country_by_addr), OP_EQ, 1);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -1018,7 +1018,7 @@ NS(compare_tor_addr_to_addr_policy)(const tor_addr_t *addr, uint16_t port,
|
||||
(void)port;
|
||||
(void)policy;
|
||||
CALLED(compare_tor_addr_to_addr_policy)++;
|
||||
tt_ptr_op(addr, ==, MOCK_TOR_ADDR_PTR);
|
||||
tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
|
||||
|
||||
done:
|
||||
return ADDR_POLICY_ACCEPTED;
|
||||
@@ -1028,7 +1028,7 @@ int
|
||||
NS(geoip_get_country_by_addr)(const tor_addr_t *addr)
|
||||
{
|
||||
CALLED(geoip_get_country_by_addr)++;
|
||||
tt_ptr_op(addr, ==, MOCK_TOR_ADDR_PTR);
|
||||
tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
|
||||
|
||||
done:
|
||||
return -1;
|
||||
@@ -1062,9 +1062,9 @@ NS(test_main)(void *arg)
|
||||
contains = routerset_contains(set, MOCK_TOR_ADDR_PTR, 0, NULL, NULL, -1);
|
||||
routerset_free(set);
|
||||
|
||||
tt_int_op(contains, ==, 2);
|
||||
tt_int_op(CALLED(compare_tor_addr_to_addr_policy), ==, 1);
|
||||
tt_int_op(CALLED(geoip_get_country_by_addr), ==, 1);
|
||||
tt_int_op(contains, OP_EQ, 2);
|
||||
tt_int_op(CALLED(compare_tor_addr_to_addr_policy), OP_EQ, 1);
|
||||
tt_int_op(CALLED(geoip_get_country_by_addr), OP_EQ, 1);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -1077,7 +1077,7 @@ NS(compare_tor_addr_to_addr_policy)(const tor_addr_t *addr, uint16_t port,
|
||||
(void)port;
|
||||
(void)policy;
|
||||
CALLED(compare_tor_addr_to_addr_policy)++;
|
||||
tt_ptr_op(addr, ==, MOCK_TOR_ADDR_PTR);
|
||||
tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
|
||||
|
||||
done:
|
||||
return ADDR_POLICY_ACCEPTED;
|
||||
@@ -1087,7 +1087,7 @@ int
|
||||
NS(geoip_get_country_by_addr)(const tor_addr_t *addr)
|
||||
{
|
||||
CALLED(geoip_get_country_by_addr)++;
|
||||
tt_ptr_op(addr, ==, MOCK_TOR_ADDR_PTR);
|
||||
tt_ptr_op(addr, OP_EQ, MOCK_TOR_ADDR_PTR);
|
||||
|
||||
done:
|
||||
return 1;
|
||||
@@ -1111,7 +1111,7 @@ NS(test_main)(void *arg)
|
||||
|
||||
r = routerset_add_unknown_ccs(setp, 1);
|
||||
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
|
||||
done:
|
||||
routerset_free(set);
|
||||
@@ -1140,8 +1140,8 @@ NS(test_main)(void *arg)
|
||||
|
||||
r = routerset_add_unknown_ccs(setp, 0);
|
||||
|
||||
tt_ptr_op(*setp, !=, NULL);
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_ptr_op(*setp, OP_NE, NULL);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
|
||||
done:
|
||||
if (set != NULL)
|
||||
@@ -1181,9 +1181,9 @@ NS(test_main)(void *arg)
|
||||
|
||||
r = routerset_add_unknown_ccs(setp, 0);
|
||||
|
||||
tt_int_op(r, ==, 1);
|
||||
tt_int_op(smartlist_contains_string(set->country_names, "??"), ==, 1);
|
||||
tt_int_op(smartlist_contains_string(set->list, "{??}"), ==, 1);
|
||||
tt_int_op(r, OP_EQ, 1);
|
||||
tt_int_op(smartlist_contains_string(set->country_names, "??"), OP_EQ, 1);
|
||||
tt_int_op(smartlist_contains_string(set->list, "{??}"), OP_EQ, 1);
|
||||
|
||||
done:
|
||||
if (set != NULL)
|
||||
@@ -1200,7 +1200,7 @@ NS(geoip_get_country)(const char *country)
|
||||
arg_is_qq = !strcmp(country, "??");
|
||||
arg_is_a1 = !strcmp(country, "A1");
|
||||
|
||||
tt_int_op(arg_is_qq || arg_is_a1, ==, 1);
|
||||
tt_int_op(arg_is_qq || arg_is_a1, OP_EQ, 1);
|
||||
|
||||
if (arg_is_qq)
|
||||
return 1;
|
||||
@@ -1214,7 +1214,7 @@ NS(geoip_is_loaded)(sa_family_t family)
|
||||
{
|
||||
CALLED(geoip_is_loaded)++;
|
||||
|
||||
tt_int_op(family, ==, AF_INET);
|
||||
tt_int_op(family, OP_EQ, AF_INET);
|
||||
|
||||
done:
|
||||
return 0;
|
||||
@@ -1244,9 +1244,9 @@ NS(test_main)(void *arg)
|
||||
|
||||
r = routerset_add_unknown_ccs(setp, 0);
|
||||
|
||||
tt_int_op(r, ==, 1);
|
||||
tt_int_op(smartlist_contains_string(set->country_names, "a1"), ==, 1);
|
||||
tt_int_op(smartlist_contains_string(set->list, "{a1}"), ==, 1);
|
||||
tt_int_op(r, OP_EQ, 1);
|
||||
tt_int_op(smartlist_contains_string(set->country_names, "a1"), OP_EQ, 1);
|
||||
tt_int_op(smartlist_contains_string(set->list, "{a1}"), OP_EQ, 1);
|
||||
|
||||
done:
|
||||
if (set != NULL)
|
||||
@@ -1263,7 +1263,7 @@ NS(geoip_get_country)(const char *country)
|
||||
arg_is_qq = !strcmp(country, "??");
|
||||
arg_is_a1 = !strcmp(country, "A1");
|
||||
|
||||
tt_int_op(arg_is_qq || arg_is_a1, ==, 1);
|
||||
tt_int_op(arg_is_qq || arg_is_a1, OP_EQ, 1);
|
||||
|
||||
if (arg_is_a1)
|
||||
return 1;
|
||||
@@ -1277,7 +1277,7 @@ NS(geoip_is_loaded)(sa_family_t family)
|
||||
{
|
||||
CALLED(geoip_is_loaded)++;
|
||||
|
||||
tt_int_op(family, ==, AF_INET);
|
||||
tt_int_op(family, OP_EQ, AF_INET);
|
||||
|
||||
done:
|
||||
return 0;
|
||||
@@ -1306,7 +1306,7 @@ NS(test_main)(void *arg)
|
||||
|
||||
r = routerset_contains_extendinfo(set, &ei);
|
||||
|
||||
tt_int_op(r, ==, 4);
|
||||
tt_int_op(r, OP_EQ, 4);
|
||||
done:
|
||||
routerset_free(set);
|
||||
}
|
||||
@@ -1334,7 +1334,7 @@ NS(test_main)(void *arg)
|
||||
|
||||
r = routerset_contains_router(set, &ri, country);
|
||||
|
||||
tt_int_op(r, ==, 4);
|
||||
tt_int_op(r, OP_EQ, 4);
|
||||
done:
|
||||
routerset_free(set);
|
||||
}
|
||||
@@ -1367,7 +1367,7 @@ NS(test_main)(void *arg)
|
||||
|
||||
r = routerset_contains_routerstatus(set, &rs, country);
|
||||
|
||||
tt_int_op(r, ==, 4);
|
||||
tt_int_op(r, OP_EQ, 4);
|
||||
done:
|
||||
routerset_free(set);
|
||||
}
|
||||
@@ -1393,7 +1393,7 @@ NS(test_main)(void *arg)
|
||||
NS(mock_node).rs = NULL;
|
||||
|
||||
r = routerset_contains_node(set, &NS(mock_node));
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
|
||||
done:
|
||||
routerset_free(set);
|
||||
@@ -1427,7 +1427,7 @@ NS(test_main)(void *arg)
|
||||
|
||||
r = routerset_contains_node(set, &NS(mock_node));
|
||||
|
||||
tt_int_op(r, ==, 4);
|
||||
tt_int_op(r, OP_EQ, 4);
|
||||
done:
|
||||
routerset_free(set);
|
||||
}
|
||||
@@ -1458,7 +1458,7 @@ NS(test_main)(void *arg)
|
||||
|
||||
r = routerset_contains_node(set, &mock_node);
|
||||
|
||||
tt_int_op(r, ==, 4);
|
||||
tt_int_op(r, OP_EQ, 4);
|
||||
done:
|
||||
routerset_free(set);
|
||||
}
|
||||
@@ -1478,15 +1478,15 @@ NS(test_main)(void *arg)
|
||||
routerset_t *set = NULL;
|
||||
(void)arg;
|
||||
|
||||
tt_int_op(smartlist_len(out), ==, 0);
|
||||
tt_int_op(smartlist_len(out), OP_EQ, 0);
|
||||
routerset_get_all_nodes(out, NULL, NULL, 0);
|
||||
|
||||
tt_int_op(smartlist_len(out), ==, 0);
|
||||
tt_int_op(smartlist_len(out), OP_EQ, 0);
|
||||
|
||||
set = routerset_new();
|
||||
smartlist_free(set->list);
|
||||
routerset_get_all_nodes(out, NULL, NULL, 0);
|
||||
tt_int_op(smartlist_len(out), ==, 0);
|
||||
tt_int_op(smartlist_len(out), OP_EQ, 0);
|
||||
|
||||
/* Just recreate list, so we can simply use routerset_free. */
|
||||
set->list = smartlist_new();
|
||||
@@ -1527,8 +1527,8 @@ NS(test_main)(void *arg)
|
||||
smartlist_free(out);
|
||||
routerset_free(set);
|
||||
|
||||
tt_int_op(out_len, ==, 0);
|
||||
tt_int_op(CALLED(node_get_by_nickname), ==, 1);
|
||||
tt_int_op(out_len, OP_EQ, 0);
|
||||
tt_int_op(CALLED(node_get_by_nickname), OP_EQ, 1);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -1538,8 +1538,8 @@ const node_t *
|
||||
NS(node_get_by_nickname)(const char *nickname, int warn_if_unused)
|
||||
{
|
||||
CALLED(node_get_by_nickname)++;
|
||||
tt_str_op(nickname, ==, NS(mock_nickname));
|
||||
tt_int_op(warn_if_unused, ==, 1);
|
||||
tt_str_op(nickname, OP_EQ, NS(mock_nickname));
|
||||
tt_int_op(warn_if_unused, OP_EQ, 1);
|
||||
|
||||
done:
|
||||
return NULL;
|
||||
@@ -1578,8 +1578,8 @@ NS(test_main)(void *arg)
|
||||
smartlist_free(out);
|
||||
routerset_free(set);
|
||||
|
||||
tt_int_op(out_len, ==, 0);
|
||||
tt_int_op(CALLED(node_get_by_nickname), ==, 1);
|
||||
tt_int_op(out_len, OP_EQ, 0);
|
||||
tt_int_op(CALLED(node_get_by_nickname), OP_EQ, 1);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -1589,8 +1589,8 @@ const node_t *
|
||||
NS(node_get_by_nickname)(const char *nickname, int warn_if_unused)
|
||||
{
|
||||
CALLED(node_get_by_nickname)++;
|
||||
tt_str_op(nickname, ==, NS(mock_nickname));
|
||||
tt_int_op(warn_if_unused, ==, 1);
|
||||
tt_str_op(nickname, OP_EQ, NS(mock_nickname));
|
||||
tt_int_op(warn_if_unused, OP_EQ, 1);
|
||||
|
||||
done:
|
||||
return &NS(mock_node);
|
||||
@@ -1629,9 +1629,9 @@ NS(test_main)(void *arg)
|
||||
smartlist_free(out);
|
||||
routerset_free(set);
|
||||
|
||||
tt_int_op(out_len, ==, 1);
|
||||
tt_ptr_op(ent, ==, &NS(mock_node));
|
||||
tt_int_op(CALLED(node_get_by_nickname), ==, 1);
|
||||
tt_int_op(out_len, OP_EQ, 1);
|
||||
tt_ptr_op(ent, OP_EQ, &NS(mock_node));
|
||||
tt_int_op(CALLED(node_get_by_nickname), OP_EQ, 1);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -1641,8 +1641,8 @@ const node_t *
|
||||
NS(node_get_by_nickname)(const char *nickname, int warn_if_unused)
|
||||
{
|
||||
CALLED(node_get_by_nickname)++;
|
||||
tt_str_op(nickname, ==, NS(mock_nickname));
|
||||
tt_int_op(warn_if_unused, ==, 1);
|
||||
tt_str_op(nickname, OP_EQ, NS(mock_nickname));
|
||||
tt_int_op(warn_if_unused, OP_EQ, 1);
|
||||
|
||||
done:
|
||||
return &NS(mock_node);
|
||||
@@ -1678,8 +1678,8 @@ NS(test_main)(void *arg)
|
||||
smartlist_free(out);
|
||||
smartlist_free(NS(mock_smartlist));
|
||||
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(CALLED(nodelist_get_list), ==, 1);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
tt_int_op(CALLED(nodelist_get_list), OP_EQ, 1);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -1727,8 +1727,8 @@ NS(test_main)(void *arg)
|
||||
smartlist_free(out);
|
||||
smartlist_free(NS(mock_smartlist));
|
||||
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(CALLED(nodelist_get_list), ==, 1);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
tt_int_op(CALLED(nodelist_get_list), OP_EQ, 1);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -1766,10 +1766,10 @@ NS(test_main)(void *arg)
|
||||
mock_node.ri = &ri;
|
||||
smartlist_add(list, (void *)&mock_node);
|
||||
|
||||
tt_int_op(smartlist_len(list), !=, 0);
|
||||
tt_int_op(smartlist_len(list), OP_NE, 0);
|
||||
routerset_subtract_nodes(list, set);
|
||||
|
||||
tt_int_op(smartlist_len(list), ==, 0);
|
||||
tt_int_op(smartlist_len(list), OP_EQ, 0);
|
||||
done:
|
||||
routerset_free(set);
|
||||
smartlist_free(list);
|
||||
@@ -1796,10 +1796,10 @@ NS(test_main)(void *arg)
|
||||
mock_node.ri = &ri;
|
||||
smartlist_add(list, (void *)&mock_node);
|
||||
|
||||
tt_int_op(smartlist_len(list), !=, 0);
|
||||
tt_int_op(smartlist_len(list), OP_NE, 0);
|
||||
routerset_subtract_nodes(list, set);
|
||||
|
||||
tt_int_op(smartlist_len(list), !=, 0);
|
||||
tt_int_op(smartlist_len(list), OP_NE, 0);
|
||||
done:
|
||||
routerset_free(set);
|
||||
smartlist_free(list);
|
||||
@@ -1821,19 +1821,19 @@ NS(test_main)(void *arg)
|
||||
|
||||
set = NULL;
|
||||
s = routerset_to_string(set);
|
||||
tt_str_op(s, ==, "");
|
||||
tt_str_op(s, OP_EQ, "");
|
||||
tor_free(s);
|
||||
|
||||
set = routerset_new();
|
||||
s = routerset_to_string(set);
|
||||
tt_str_op(s, ==, "");
|
||||
tt_str_op(s, OP_EQ, "");
|
||||
tor_free(s);
|
||||
routerset_free(set); set = NULL;
|
||||
|
||||
set = routerset_new();
|
||||
smartlist_add(set->list, tor_strndup("a", 1));
|
||||
s = routerset_to_string(set);
|
||||
tt_str_op(s, ==, "a");
|
||||
tt_str_op(s, OP_EQ, "a");
|
||||
tor_free(s);
|
||||
routerset_free(set); set = NULL;
|
||||
|
||||
@@ -1841,7 +1841,7 @@ NS(test_main)(void *arg)
|
||||
smartlist_add(set->list, tor_strndup("a", 1));
|
||||
smartlist_add(set->list, tor_strndup("b", 1));
|
||||
s = routerset_to_string(set);
|
||||
tt_str_op(s, ==, "a,b");
|
||||
tt_str_op(s, OP_EQ, "a,b");
|
||||
tor_free(s);
|
||||
routerset_free(set); set = NULL;
|
||||
|
||||
@@ -1868,7 +1868,7 @@ NS(test_main)(void *arg)
|
||||
routerset_free(a);
|
||||
routerset_free(b);
|
||||
|
||||
tt_int_op(r, ==, 1);
|
||||
tt_int_op(r, OP_EQ, 1);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -1893,7 +1893,7 @@ NS(test_main)(void *arg)
|
||||
routerset_free(a);
|
||||
routerset_free(b);
|
||||
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
done:
|
||||
;
|
||||
}
|
||||
@@ -1920,7 +1920,7 @@ NS(test_main)(void *arg)
|
||||
routerset_free(a);
|
||||
routerset_free(b);
|
||||
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
done:
|
||||
;
|
||||
}
|
||||
@@ -1946,7 +1946,7 @@ NS(test_main)(void *arg)
|
||||
routerset_free(a);
|
||||
routerset_free(b);
|
||||
|
||||
tt_int_op(r, ==, 0);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
done:
|
||||
;
|
||||
}
|
||||
@@ -1972,7 +1972,7 @@ NS(test_main)(void *arg)
|
||||
routerset_free(a);
|
||||
routerset_free(b);
|
||||
|
||||
tt_int_op(r, ==, 1);
|
||||
tt_int_op(r, OP_EQ, 1);
|
||||
done:
|
||||
;
|
||||
}
|
||||
@@ -1995,7 +1995,7 @@ NS(test_main)(void *arg)
|
||||
|
||||
routerset_free(NULL);
|
||||
|
||||
tt_int_op(CALLED(smartlist_free), ==, 0);
|
||||
tt_int_op(CALLED(smartlist_free), OP_EQ, 0);
|
||||
|
||||
done:
|
||||
;
|
||||
@@ -2031,9 +2031,9 @@ NS(test_main)(void *arg)
|
||||
|
||||
routerset_free(routerset);
|
||||
|
||||
tt_int_op(CALLED(smartlist_free), !=, 0);
|
||||
tt_int_op(CALLED(strmap_free), !=, 0);
|
||||
tt_int_op(CALLED(digestmap_free), !=, 0);
|
||||
tt_int_op(CALLED(smartlist_free), OP_NE, 0);
|
||||
tt_int_op(CALLED(strmap_free), OP_NE, 0);
|
||||
tt_int_op(CALLED(digestmap_free), OP_NE, 0);
|
||||
|
||||
done:
|
||||
;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user