diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/backtrace.c | 7 | ||||
-rw-r--r-- | src/common/compat.c | 3 | ||||
-rw-r--r-- | src/common/tortls.c | 9 | ||||
-rw-r--r-- | src/or/connection.c | 19 | ||||
-rw-r--r-- | src/or/connection_edge.c | 77 | ||||
-rw-r--r-- | src/or/connection_edge.h | 4 | ||||
-rw-r--r-- | src/or/geoip.c | 2 | ||||
-rw-r--r-- | src/or/main.c | 9 | ||||
-rw-r--r-- | src/or/networkstatus.c | 14 | ||||
-rw-r--r-- | src/or/router.c | 8 | ||||
-rw-r--r-- | src/or/router.h | 5 | ||||
-rwxr-xr-x | src/test/bt_test.py | 9 | ||||
-rw-r--r-- | src/test/include.am | 1 | ||||
-rw-r--r-- | src/test/test_bt_cl.c | 1 | ||||
-rw-r--r-- | src/test/test_config.c | 169 | ||||
-rw-r--r-- | src/test/test_connection.c | 10 | ||||
-rw-r--r-- | src/test/test_dns.c | 3 | ||||
-rw-r--r-- | src/test/test_policy.c | 2 | ||||
-rw-r--r-- | src/test/test_switch_id.c | 16 | ||||
-rw-r--r-- | src/test/test_tortls.c | 13 |
20 files changed, 303 insertions, 78 deletions
diff --git a/src/common/backtrace.c b/src/common/backtrace.c index bed0442471..94de1eb5ee 100644 --- a/src/common/backtrace.c +++ b/src/common/backtrace.c @@ -215,9 +215,10 @@ int configure_backtrace_handler(const char *tor_version) { tor_free(bt_version); - if (!tor_version) - tor_version = ""; - tor_asprintf(&bt_version, "Tor %s", tor_version); + if (tor_version) + tor_asprintf(&bt_version, "Tor %s", tor_version); + else + tor_asprintf(&bt_version, "Tor"); return install_bt_handler(); } diff --git a/src/common/compat.c b/src/common/compat.c index 7e8eec189a..0b8fcb7e64 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -2207,8 +2207,7 @@ switch_id(const char *user, const unsigned flags) (void)user; (void)flags; - log_warn(LD_CONFIG, - "User specified but switching users is unsupported on your OS."); + log_warn(LD_CONFIG, "Switching users is unsupported on your OS."); return -1; #endif } diff --git a/src/common/tortls.c b/src/common/tortls.c index b1d3f6f9e8..78f731bbcc 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -884,7 +884,7 @@ tor_tls_cert_is_valid(int severity, EVP_PKEY *cert_key; int r, key_ok = 0; - if (!signing_cert) + if (!signing_cert || !cert) goto bad; EVP_PKEY *signing_key = X509_get_pubkey(signing_cert->cert); @@ -1310,6 +1310,7 @@ find_cipher_by_id(const SSL *ssl, const SSL_METHOD *m, uint16_t cipher) { const SSL_CIPHER *c; #ifdef HAVE_SSL_CIPHER_FIND + (void) m; { unsigned char cipherid[3]; tor_assert(ssl); @@ -1322,7 +1323,8 @@ find_cipher_by_id(const SSL *ssl, const SSL_METHOD *m, uint16_t cipher) tor_assert((SSL_CIPHER_get_id(c) & 0xffff) == cipher); return c != NULL; } -#elif defined(HAVE_STRUCT_SSL_METHOD_ST_GET_CIPHER_BY_CHAR) +#else +#if defined(HAVE_STRUCT_SSL_METHOD_ST_GET_CIPHER_BY_CHAR) if (m && m->get_cipher_by_char) { unsigned char cipherid[3]; set_uint16(cipherid, htons(cipher)); @@ -1333,7 +1335,7 @@ find_cipher_by_id(const SSL *ssl, const SSL_METHOD *m, uint16_t cipher) if (c) tor_assert((c->id & 0xffff) == cipher); return c != NULL; - } else + } #endif #if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,1,0) if (m && m->get_cipher && m->num_ciphers) { @@ -1355,6 +1357,7 @@ find_cipher_by_id(const SSL *ssl, const SSL_METHOD *m, uint16_t cipher) (void) m; (void) cipher; return 1; /* No way to search */ +#endif } /** Remove from v2_cipher_list every cipher that we don't support, so that diff --git a/src/or/connection.c b/src/or/connection.c index d6e5fcb277..c0031047e7 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -678,6 +678,13 @@ connection_free,(connection_t *conn)) if (conn->type == CONN_TYPE_CONTROL) { connection_control_closed(TO_CONTROL_CONN(conn)); } +#if 1 + /* DEBUGGING */ + if (conn->type == CONN_TYPE_AP) { + connection_ap_warn_and_unmark_if_pending_circ(TO_ENTRY_CONN(conn), + "connection_free"); + } +#endif connection_unregister_events(conn); connection_free_(conn); } @@ -1128,11 +1135,12 @@ connection_listener_new(const struct sockaddr *listensockaddr, tor_socket_strerror(errno)); } -#if defined USE_TRANSPARENT && defined(IP_TRANSPARENT) +#if defined(USE_TRANSPARENT) && defined(IP_TRANSPARENT) if (options->TransProxyType_parsed == TPT_TPROXY && type == CONN_TYPE_AP_TRANS_LISTENER) { int one = 1; - if (setsockopt(s, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) < 0) { + if (setsockopt(s, SOL_IP, IP_TRANSPARENT, (void*)&one, + (socklen_t)sizeof(one)) < 0) { const char *extra = ""; int e = tor_socket_errno(s); if (e == EPERM) @@ -1146,16 +1154,11 @@ connection_listener_new(const struct sockaddr *listensockaddr, #ifdef IPV6_V6ONLY if (listensockaddr->sa_family == AF_INET6) { -#ifdef _WIN32 - /* In Redmond, this kind of thing passes for standards-conformance. */ - DWORD one = 1; -#else int one = 1; -#endif /* We need to set IPV6_V6ONLY so that this socket can't get used for * IPv4 connections. */ if (setsockopt(s,IPPROTO_IPV6, IPV6_V6ONLY, - (void*)&one, sizeof(one)) < 0) { + (void*)&one, (socklen_t)sizeof(one)) < 0) { int e = tor_socket_errno(s); log_warn(LD_NET, "Error setting IPV6_V6ONLY flag: %s", tor_socket_strerror(e)); diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 961e49abd9..758d583c39 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -527,27 +527,6 @@ connection_edge_about_to_close(edge_connection_t *edge_conn) conn->marked_for_close_file, conn->marked_for_close); tor_fragile_assert(); } - - if (TO_CONN(edge_conn)->type != CONN_TYPE_AP || - PREDICT_UNLIKELY(NULL == pending_entry_connections)) - return; - - entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(edge_conn); - - if (TO_CONN(edge_conn)->state == AP_CONN_STATE_CIRCUIT_WAIT) { - smartlist_remove(pending_entry_connections, entry_conn); - } - -#if 1 - /* Check to make sure that this isn't in pending_entry_connections if it - * didn't actually belong there. */ - if (TO_CONN(edge_conn)->type == CONN_TYPE_AP && - smartlist_contains(pending_entry_connections, entry_conn)) { - log_warn(LD_BUG, "What was %p doing in pending_entry_connections???", - entry_conn); - smartlist_remove(pending_entry_connections, entry_conn); - } -#endif } /** Called when we're about to finally unlink and free an AP (client) @@ -559,6 +538,8 @@ connection_ap_about_to_close(entry_connection_t *entry_conn) edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(entry_conn); connection_t *conn = ENTRY_TO_CONN(entry_conn); + connection_edge_about_to_close(edge_conn); + if (entry_conn->socks_request->has_finished == 0) { /* since conn gets removed right after this function finishes, * there's no point trying to send back a reply at this point. */ @@ -577,6 +558,20 @@ connection_ap_about_to_close(entry_connection_t *entry_conn) conn->marked_for_close_file, conn->marked_for_close); dnsserv_reject_request(entry_conn); } + + if (TO_CONN(edge_conn)->state == AP_CONN_STATE_CIRCUIT_WAIT) { + smartlist_remove(pending_entry_connections, entry_conn); + } + +#if 1 + /* Check to make sure that this isn't in pending_entry_connections if it + * didn't actually belong there. */ + if (TO_CONN(edge_conn)->type == CONN_TYPE_AP) { + connection_ap_warn_and_unmark_if_pending_circ(entry_conn, + "about_to_close"); + } +#endif + control_event_stream_bandwidth(edge_conn); control_event_stream_status(entry_conn, STREAM_EVENT_CLOSED, edge_conn->end_reason); @@ -805,20 +800,23 @@ connection_ap_attach_pending(int retry) if (untried_pending_connections == 0 && !retry) return; - SMARTLIST_FOREACH_BEGIN(pending_entry_connections, + /* Don't allow modifications to pending_entry_connections while we are + * iterating over it. */ + smartlist_t *pending = pending_entry_connections; + pending_entry_connections = smartlist_new(); + + SMARTLIST_FOREACH_BEGIN(pending, entry_connection_t *, entry_conn) { connection_t *conn = ENTRY_TO_CONN(entry_conn); tor_assert(conn && entry_conn); if (conn->marked_for_close) { UNMARK(); - SMARTLIST_DEL_CURRENT(pending_entry_connections, entry_conn); continue; } if (conn->magic != ENTRY_CONNECTION_MAGIC) { log_warn(LD_BUG, "%p has impossible magic value %u.", entry_conn, (unsigned)conn->magic); UNMARK(); - SMARTLIST_DEL_CURRENT(pending_entry_connections, entry_conn); continue; } if (conn->state != AP_CONN_STATE_CIRCUIT_WAIT) { @@ -827,7 +825,6 @@ connection_ap_attach_pending(int retry) entry_conn, conn_state_to_string(conn->type, conn->state)); UNMARK(); - SMARTLIST_DEL_CURRENT(pending_entry_connections, entry_conn); continue; } @@ -837,18 +834,19 @@ connection_ap_attach_pending(int retry) END_STREAM_REASON_CANT_ATTACH); } - if (conn->marked_for_close || - conn->type != CONN_TYPE_AP || - conn->state != AP_CONN_STATE_CIRCUIT_WAIT) { - UNMARK(); - SMARTLIST_DEL_CURRENT(pending_entry_connections, entry_conn); - continue; + if (! conn->marked_for_close && + conn->type == CONN_TYPE_AP && + conn->state == AP_CONN_STATE_CIRCUIT_WAIT) { + if (!smartlist_contains(pending_entry_connections, entry_conn)) { + smartlist_add(pending_entry_connections, entry_conn); + continue; + } } - tor_assert(conn->magic == ENTRY_CONNECTION_MAGIC); - + UNMARK(); } SMARTLIST_FOREACH_END(entry_conn); + smartlist_free(pending); untried_pending_connections = 0; } @@ -906,6 +904,19 @@ connection_ap_mark_as_non_pending_circuit(entry_connection_t *entry_conn) smartlist_remove(pending_entry_connections, entry_conn); } +/** DOCDOC */ +void +connection_ap_warn_and_unmark_if_pending_circ(entry_connection_t *entry_conn, + const char *where) +{ + if (pending_entry_connections && + smartlist_contains(pending_entry_connections, entry_conn)) { + log_warn(LD_BUG, "What was %p doing in pending_entry_connections in %s?", + entry_conn, where); + connection_ap_mark_as_non_pending_circuit(entry_conn); + } +} + /** Tell any AP streams that are waiting for a one-hop tunnel to * <b>failed_digest</b> that they are going to fail. */ /* XXX024 We should get rid of this function, and instead attach diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h index 6da51eb0c6..2aba801461 100644 --- a/src/or/connection_edge.h +++ b/src/or/connection_edge.h @@ -115,6 +115,10 @@ streamid_t get_unique_stream_id_by_circ(origin_circuit_t *circ); void connection_edge_free_all(void); +void connection_ap_warn_and_unmark_if_pending_circ( + entry_connection_t *entry_conn, + const char *where); + /** @name Begin-cell flags * * These flags are used in RELAY_BEGIN cells to change the default behavior diff --git a/src/or/geoip.c b/src/or/geoip.c index 3ef1672f52..26030ae52a 100644 --- a/src/or/geoip.c +++ b/src/or/geoip.c @@ -1279,6 +1279,8 @@ geoip_dirreq_stats_write(time_t now) /* Generate history string .*/ str = geoip_format_dirreq_stats(now); + if (! str) + goto done; /* Write dirreq-stats string to disk. */ if (!check_or_create_data_subdir("stats")) { diff --git a/src/or/main.c b/src/or/main.c index 455cba4513..c8b1283974 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -225,11 +225,13 @@ set_buffer_lengths_to_zero(tor_socket_t s) { int zero = 0; int r = 0; - if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (void*)&zero, sizeof(zero))) { + if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (void*)&zero, + (socklen_t)sizeof(zero))) { log_warn(LD_NET, "Unable to clear SO_SNDBUF"); r = -1; } - if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (void*)&zero, sizeof(zero))) { + if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (void*)&zero, + (socklen_t)sizeof(zero))) { log_warn(LD_NET, "Unable to clear SO_RCVBUF"); r = -1; } @@ -3460,6 +3462,9 @@ sandbox_init_filter(void) ".tmp"); OPEN_DATADIR2_SUFFIX("keys", "ed25519_master_id_public_key", ".tmp"); OPEN_DATADIR2_SUFFIX("keys", "ed25519_signing_secret_key", ".tmp"); + OPEN_DATADIR2_SUFFIX("keys", "ed25519_signing_secret_key_encrypted", + ".tmp"); + OPEN_DATADIR2_SUFFIX("keys", "ed25519_signing_public_key", ".tmp"); OPEN_DATADIR2_SUFFIX("keys", "ed25519_signing_cert", ".tmp"); OPEN_DATADIR2_SUFFIX("stats", "bridge-stats", ".tmp"); diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index 076a2c4116..f3a8276689 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -1286,25 +1286,29 @@ networkstatus_consensus_is_boostrapping(time_t now) } /** Check if we can use multiple directories for a consensus download. - * Only clients (including bridges, but excluding bridge clients) benefit + * Only clients (including bridge relays, which act like clients) benefit * from multiple simultaneous consensus downloads. */ int networkstatus_consensus_can_use_multiple_directories( const or_options_t *options) { /* If we are a client, bridge, bridge client, or hidden service */ - return (!directory_fetches_from_authorities(options)); + return !public_server_mode(options); } /** Check if we can use fallback directory mirrors for a consensus download. - * Only clients that have a list of additional fallbacks can use fallbacks. */ + * If we have fallbacks and don't want to fetch from the authorities, + * we can use them. */ int networkstatus_consensus_can_use_extra_fallbacks(const or_options_t *options) { - /* If we are a client, and we have additional mirrors, we can use them. - * The list length comparisons are a quick way to check if we have any + /* The list length comparisons are a quick way to check if we have any * non-authority fallback directories. If we ever have any authorities that * aren't fallback directories, we will need to change this code. */ + tor_assert(smartlist_len(router_get_fallback_dir_servers()) + >= smartlist_len(router_get_trusted_dir_servers())); + /* If we don't fetch from the authorities, and we have additional mirrors, + * we can use them. */ return (!directory_fetches_from_authorities(options) && (smartlist_len(router_get_fallback_dir_servers()) > smartlist_len(router_get_trusted_dir_servers()))); diff --git a/src/or/router.c b/src/or/router.c index c1d970dbe1..2081bdb06a 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1503,8 +1503,8 @@ static int server_is_advertised=0; /** Return true iff we have published our descriptor lately. */ -int -advertised_server_mode(void) +MOCK_IMPL(int, +advertised_server_mode,(void)) { return server_is_advertised; } @@ -1866,8 +1866,8 @@ static int router_guess_address_from_dir_headers(uint32_t *guess); * it's configured in torrc, or because we've learned it from * dirserver headers. Place the answer in *<b>addr</b> and return * 0 on success, else return -1 if we have no guess. */ -int -router_pick_published_address(const or_options_t *options, uint32_t *addr) +MOCK_IMPL(int, +router_pick_published_address,(const or_options_t *options, uint32_t *addr)) { *addr = get_last_resolved_addr(); if (!*addr && diff --git a/src/or/router.h b/src/or/router.h index f176477d77..ca590e3217 100644 --- a/src/or/router.h +++ b/src/or/router.h @@ -68,7 +68,7 @@ uint16_t router_get_advertised_dir_port(const or_options_t *options, MOCK_DECL(int, server_mode, (const or_options_t *options)); MOCK_DECL(int, public_server_mode, (const or_options_t *options)); -int advertised_server_mode(void); +MOCK_DECL(int, advertised_server_mode, (void)); int proxy_mode(const or_options_t *options); void consider_publishable_server(int force); int should_refuse_unknown_exits(const or_options_t *options); @@ -90,7 +90,8 @@ int router_digest_is_me(const char *digest); const uint8_t *router_get_my_id_digest(void); int router_extrainfo_digest_is_me(const char *digest); int router_is_me(const routerinfo_t *router); -int router_pick_published_address(const or_options_t *options, uint32_t *addr); +MOCK_DECL(int,router_pick_published_address,(const or_options_t *options, + uint32_t *addr)); int router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e); int router_rebuild_descriptor(int force); char *router_dump_router_to_string(routerinfo_t *router, diff --git a/src/test/bt_test.py b/src/test/bt_test.py index e694361703..dab02d7699 100755 --- a/src/test/bt_test.py +++ b/src/test/bt_test.py @@ -15,6 +15,7 @@ OK """ +from __future__ import print_function import sys @@ -37,6 +38,8 @@ for I in range(len(LINES)): if matches(LINES[I:], FUNCNAMES): print("OK") sys.exit(0) -else: - print("BAD") - sys.exit(1) + +for l in LINES: + print("{}".format(l), end="") + +sys.exit(1) diff --git a/src/test/include.am b/src/test/include.am index c6600c8650..85c3be8081 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -144,6 +144,7 @@ src_test_test_switch_id_SOURCES = \ src/test/test_switch_id.c src_test_test_switch_id_CPPFLAGS= $(src_test_AM_CPPFLAGS) src_test_test_switch_id_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) +src_test_test_switch_id_LDFLAGS = @TOR_LDFLAGS_zlib@ src_test_test_switch_id_LDADD = \ src/common/libor-testing.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ diff --git a/src/test/test_bt_cl.c b/src/test/test_bt_cl.c index dabaee6e0a..c43143ffe9 100644 --- a/src/test/test_bt_cl.c +++ b/src/test/test_bt_cl.c @@ -119,6 +119,7 @@ main(int argc, char **argv) printf("%d\n", we_weave(2)); clean_up_backtrace_handler(); + logs_free_all(); return 0; } diff --git a/src/test/test_config.c b/src/test/test_config.c index 53fc693a33..098b0a8cf8 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -19,6 +19,8 @@ #include "transports.h" #include "routerlist.h" #include "networkstatus.h" +#include "router.h" +#include "dirserv.h" static void test_config_addressmap(void *arg) @@ -3450,22 +3452,74 @@ test_config_default_dir_servers(void *arg) or_options_free(opts); } +static int mock_router_pick_published_address_result = 0; + +static int +mock_router_pick_published_address(const or_options_t *options, uint32_t *addr) +{ + (void)options; + (void)addr; + return mock_router_pick_published_address_result; +} + +static int mock_router_my_exit_policy_is_reject_star_result = 0; + +static int +mock_router_my_exit_policy_is_reject_star(void) +{ + return mock_router_my_exit_policy_is_reject_star_result; +} + +static int mock_advertised_server_mode_result = 0; + +static int +mock_advertised_server_mode(void) +{ + return mock_advertised_server_mode_result; +} + +static routerinfo_t *mock_router_get_my_routerinfo_result = NULL; + +static const routerinfo_t * +mock_router_get_my_routerinfo(void) +{ + return mock_router_get_my_routerinfo_result; +} + static void -test_config_use_multiple_directories(void *arg) +test_config_directory_fetch(void *arg) { (void)arg; + /* Test Setup */ or_options_t *options = tor_malloc_zero(sizeof(or_options_t)); + routerinfo_t routerinfo; + memset(&routerinfo, 0, sizeof(routerinfo)); + mock_router_pick_published_address_result = -1; + mock_router_my_exit_policy_is_reject_star_result = 1; + mock_advertised_server_mode_result = 0; + mock_router_get_my_routerinfo_result = NULL; + MOCK(router_pick_published_address, mock_router_pick_published_address); + MOCK(router_my_exit_policy_is_reject_star, + mock_router_my_exit_policy_is_reject_star); + MOCK(advertised_server_mode, mock_advertised_server_mode); + MOCK(router_get_my_routerinfo, mock_router_get_my_routerinfo); /* Clients can use multiple directory mirrors for bootstrap */ memset(options, 0, sizeof(or_options_t)); options->ClientOnly = 1; + tt_assert(server_mode(options) == 0); + tt_assert(public_server_mode(options) == 0); + tt_assert(directory_fetches_from_authorities(options) == 0); tt_assert(networkstatus_consensus_can_use_multiple_directories(options) == 1); /* Bridge Clients can use multiple directory mirrors for bootstrap */ memset(options, 0, sizeof(or_options_t)); options->UseBridges = 1; + tt_assert(server_mode(options) == 0); + tt_assert(public_server_mode(options) == 0); + tt_assert(directory_fetches_from_authorities(options) == 0); tt_assert(networkstatus_consensus_can_use_multiple_directories(options) == 1); @@ -3473,23 +3527,130 @@ test_config_use_multiple_directories(void *arg) * directory mirrors for bootstrap */ memset(options, 0, sizeof(or_options_t)); options->BridgeRelay = 1; + options->ORPort_set = 1; + tt_assert(server_mode(options) == 1); + tt_assert(public_server_mode(options) == 0); + tt_assert(directory_fetches_from_authorities(options) == 0); tt_assert(networkstatus_consensus_can_use_multiple_directories(options) == 1); - /* Clients set to FetchDirInfoEarly must fetch it from the authorities */ + /* Clients set to FetchDirInfoEarly must fetch it from the authorities, + * but can use multiple authorities for bootstrap */ memset(options, 0, sizeof(or_options_t)); options->FetchDirInfoEarly = 1; + tt_assert(server_mode(options) == 0); + tt_assert(public_server_mode(options) == 0); + tt_assert(directory_fetches_from_authorities(options) == 1); + tt_assert(networkstatus_consensus_can_use_multiple_directories(options) + == 1); + + /* OR servers only fetch the consensus from the authorities when they don't + * know their own address, but never use multiple directories for bootstrap + */ + memset(options, 0, sizeof(or_options_t)); + options->ORPort_set = 1; + + mock_router_pick_published_address_result = -1; + tt_assert(server_mode(options) == 1); + tt_assert(public_server_mode(options) == 1); + tt_assert(directory_fetches_from_authorities(options) == 1); + tt_assert(networkstatus_consensus_can_use_multiple_directories(options) + == 0); + + mock_router_pick_published_address_result = 0; + tt_assert(server_mode(options) == 1); + tt_assert(public_server_mode(options) == 1); + tt_assert(directory_fetches_from_authorities(options) == 0); + tt_assert(networkstatus_consensus_can_use_multiple_directories(options) + == 0); + + /* Exit OR servers only fetch the consensus from the authorities when they + * refuse unknown exits, but never use multiple directories for bootstrap + */ + memset(options, 0, sizeof(or_options_t)); + options->ORPort_set = 1; + options->ExitRelay = 1; + mock_router_pick_published_address_result = 0; + mock_router_my_exit_policy_is_reject_star_result = 0; + mock_advertised_server_mode_result = 1; + mock_router_get_my_routerinfo_result = &routerinfo; + + options->RefuseUnknownExits = 1; + tt_assert(server_mode(options) == 1); + tt_assert(public_server_mode(options) == 1); + tt_assert(directory_fetches_from_authorities(options) == 1); + tt_assert(networkstatus_consensus_can_use_multiple_directories(options) + == 0); + + options->RefuseUnknownExits = 0; + mock_router_pick_published_address_result = 0; + tt_assert(server_mode(options) == 1); + tt_assert(public_server_mode(options) == 1); + tt_assert(directory_fetches_from_authorities(options) == 0); tt_assert(networkstatus_consensus_can_use_multiple_directories(options) == 0); - /* OR servers must fetch the consensus from the authorities */ + /* Dir servers fetch the consensus from the authorities, unless they are not + * advertising themselves (hibernating) or have no routerinfo or are not + * advertising their dirport, and never use multiple directories for + * bootstrap. This only applies if they are also OR servers. + * (We don't care much about the behaviour of non-OR directory servers.) */ memset(options, 0, sizeof(or_options_t)); + options->DirPort_set = 1; options->ORPort_set = 1; + mock_router_pick_published_address_result = 0; + mock_router_my_exit_policy_is_reject_star_result = 1; + + mock_advertised_server_mode_result = 1; + routerinfo.dir_port = 1; + mock_router_get_my_routerinfo_result = &routerinfo; + tt_assert(server_mode(options) == 1); + tt_assert(public_server_mode(options) == 1); + tt_assert(directory_fetches_from_authorities(options) == 1); + tt_assert(networkstatus_consensus_can_use_multiple_directories(options) + == 0); + + mock_advertised_server_mode_result = 0; + routerinfo.dir_port = 1; + mock_router_get_my_routerinfo_result = &routerinfo; + tt_assert(server_mode(options) == 1); + tt_assert(public_server_mode(options) == 1); + tt_assert(directory_fetches_from_authorities(options) == 0); + tt_assert(networkstatus_consensus_can_use_multiple_directories(options) + == 0); + + mock_advertised_server_mode_result = 1; + mock_router_get_my_routerinfo_result = NULL; + tt_assert(server_mode(options) == 1); + tt_assert(public_server_mode(options) == 1); + tt_assert(directory_fetches_from_authorities(options) == 0); + tt_assert(networkstatus_consensus_can_use_multiple_directories(options) + == 0); + + mock_advertised_server_mode_result = 1; + routerinfo.dir_port = 0; + mock_router_get_my_routerinfo_result = &routerinfo; + tt_assert(server_mode(options) == 1); + tt_assert(public_server_mode(options) == 1); + tt_assert(directory_fetches_from_authorities(options) == 0); + tt_assert(networkstatus_consensus_can_use_multiple_directories(options) + == 0); + + mock_advertised_server_mode_result = 1; + routerinfo.dir_port = 1; + mock_router_get_my_routerinfo_result = &routerinfo; + tt_assert(server_mode(options) == 1); + tt_assert(public_server_mode(options) == 1); + tt_assert(directory_fetches_from_authorities(options) == 1); tt_assert(networkstatus_consensus_can_use_multiple_directories(options) == 0); done: tor_free(options); + UNMOCK(router_pick_published_address); + UNMOCK(router_get_my_routerinfo); + UNMOCK(advertised_server_mode); + UNMOCK(router_my_exit_policy_is_reject_star); } static void @@ -3539,7 +3700,7 @@ struct testcase_t config_tests[] = { CONFIG_TEST(check_or_create_data_subdir, TT_FORK), CONFIG_TEST(write_to_data_subdir, TT_FORK), CONFIG_TEST(fix_my_family, 0), - CONFIG_TEST(use_multiple_directories, 0), + CONFIG_TEST(directory_fetch, 0), END_OF_TESTCASES }; diff --git a/src/test/test_connection.c b/src/test/test_connection.c index f6e08fdf1f..c5ef92931d 100644 --- a/src/test/test_connection.c +++ b/src/test/test_connection.c @@ -182,14 +182,13 @@ test_conn_get_basic_teardown(const struct testcase_t *tc, void *arg) conn->linked_conn->write_event = NULL; } - connection_free(conn->linked_conn); - conn->linked_conn = NULL; - - conn->linked_conn->linked_conn = NULL; if (!conn->linked_conn->marked_for_close) { connection_close_immediate(conn->linked_conn); connection_mark_for_close(conn->linked_conn); } + conn->linked_conn->linked_conn = NULL; + connection_free(conn->linked_conn); + conn->linked_conn = NULL; } /* We didn't set the events up properly, so we can't use event_del() in @@ -231,9 +230,10 @@ test_conn_get_rend_setup(const struct testcase_t *tc) /* TODO: use directory_initiate_command_rend() to do this - maybe? */ conn->rend_data = tor_malloc_zero(sizeof(rend_data_t)); + tor_assert(strlen(TEST_CONN_REND_ADDR) == REND_SERVICE_ID_LEN_BASE32); memcpy(conn->rend_data->onion_address, TEST_CONN_REND_ADDR, - REND_SERVICE_ADDRESS_LEN+1); + REND_SERVICE_ID_LEN_BASE32+1); conn->rend_data->hsdirs_fp = smartlist_new(); conn->base_.purpose = TEST_CONN_REND_PURPOSE; diff --git a/src/test/test_dns.c b/src/test/test_dns.c index b781d6da53..6fdbe905e0 100644 --- a/src/test/test_dns.c +++ b/src/test/test_dns.c @@ -738,7 +738,8 @@ NS(test_main)(void *arg) NS_UNMOCK(launch_resolve); tor_free(on_circ); tor_free(TO_CONN(exitconn)->address); - tor_free(cache_entry->pending_connections); + if (cache_entry) + tor_free(cache_entry->pending_connections); tor_free(cache_entry); tor_free(exitconn); return; diff --git a/src/test/test_policy.c b/src/test/test_policy.c index 4f5565e575..794978fc42 100644 --- a/src/test/test_policy.c +++ b/src/test/test_policy.c @@ -1021,6 +1021,8 @@ test_policies_getinfo_helper_policies(void *arg) const char *errmsg = NULL; routerinfo_t mock_my_routerinfo; + memset(&mock_my_routerinfo, 0, sizeof(mock_my_routerinfo)); + rv = getinfo_helper_policies(NULL, "exit-policy/default", &answer, &errmsg); tt_assert(rv == 0); tt_assert(answer != NULL); diff --git a/src/test/test_switch_id.c b/src/test/test_switch_id.c index e85025c3b5..3d9c1c8bba 100644 --- a/src/test/test_switch_id.c +++ b/src/test/test_switch_id.c @@ -14,8 +14,6 @@ #define TEST_SETUID_KEEPCAPS 4 #define TEST_SETUID_STRICT 5 -static const char *username; - static const struct { const char *name; int test_id; @@ -29,6 +27,7 @@ static const struct { { NULL, 0 } }; +#if !defined(_WIN32) /* 0 on no, 1 on yes, -1 on failure. */ static int check_can_bind_low_ports(void) @@ -47,7 +46,8 @@ check_can_bind_low_ports(void) } int one = 1; - if (setsockopt(fd, SOL_SOCKET,SO_REUSEADDR, &one, sizeof(one))) { + if (setsockopt(fd, SOL_SOCKET,SO_REUSEADDR, (void*)&one, + (socklen_t)sizeof(one))) { perror("setsockopt"); tor_close_socket_simple(fd); return -1; @@ -71,10 +71,19 @@ check_can_bind_low_ports(void) return -1; } +#endif int main(int argc, char **argv) { +#if defined(_WIN32) + (void) argc; + (void) argv; + + fprintf(stderr, "This test is not supported on your OS.\n"); + return 77; +#else + const char *username; const char *testname; if (argc != 3) { fprintf(stderr, "I want 2 arguments: a username and a command.\n"); @@ -177,5 +186,6 @@ main(int argc, char **argv) } return (okay ? 0 : 1); +#endif } diff --git a/src/test/test_tortls.c b/src/test/test_tortls.c index 8602d9ef15..add020e9f4 100644 --- a/src/test/test_tortls.c +++ b/src/test/test_tortls.c @@ -1128,7 +1128,9 @@ test_tortls_check_lifetime(void *ignored) ret = tor_tls_check_lifetime(LOG_WARN, tls, 0, 0); tt_int_op(ret, OP_EQ, 0); + ASN1_STRING_free(validCert->cert_info->validity->notBefore); validCert->cert_info->validity->notBefore = ASN1_TIME_set(NULL, now-10); + ASN1_STRING_free(validCert->cert_info->validity->notAfter); validCert->cert_info->validity->notAfter = ASN1_TIME_set(NULL, now+60); ret = tor_tls_check_lifetime(LOG_WARN, tls, 0, -1000); @@ -1454,17 +1456,21 @@ test_tortls_try_to_extract_certs_from_tls(void *ignored) try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert); tt_assert(cert == c1); tt_assert(!id_cert); + X509_free(cert); /* decrease refcnt */ sess->cert_chain = sk_X509_new_null(); try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert); tt_assert(cert == c1); tt_assert(!id_cert); + X509_free(cert); /* decrease refcnt */ sk_X509_push(sess->cert_chain, c1); sk_X509_push(sess->cert_chain, c2); + try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert); tt_assert(cert == c1); tt_assert(id_cert); + X509_free(cert); /* decrease refcnt */ done: sk_X509_free(sess->cert_chain); @@ -1472,6 +1478,8 @@ test_tortls_try_to_extract_certs_from_tls(void *ignored) tor_free(tls->ssl->session); tor_free(tls->ssl); tor_free(tls); + X509_free(c1); + X509_free(c2); } #endif @@ -2672,7 +2680,12 @@ test_tortls_cert_is_valid(void *ignored) scert = tor_malloc_zero(sizeof(tor_x509_cert_t)); ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, 0); tt_int_op(ret, OP_EQ, 0); + + cert = tor_malloc_zero(sizeof(tor_x509_cert_t)); + ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, 0); + tt_int_op(ret, OP_EQ, 0); tor_free(scert); + tor_free(cert); cert = tor_x509_cert_new(read_cert_from(validCertString)); scert = tor_x509_cert_new(read_cert_from(caCertString)); |