[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Merge branch 'feature17840-v11-squashed' into feature17840-v11-merged
commit c4cb4706c9bb1087584c9813b0ca97c261e6fd77
Merge: 42dea56 73fc67b
Author: teor (Tim Wilson-Brown) <teor2345@xxxxxxxxx>
Date: Fri Jan 29 07:37:06 2016 +1100
Merge branch 'feature17840-v11-squashed' into feature17840-v11-merged
Conflicts:
src/or/directory.c
src/test/test_routerlist.c
Fix minor conflicts.
changes/feature17840 | 9 +
doc/tor.1.txt | 39 ++-
src/common/address.c | 53 ++++
src/common/address.h | 21 ++
src/or/circuitbuild.c | 48 ++--
src/or/circuituse.c | 7 +-
src/or/config.c | 30 +-
src/or/connection.c | 74 ++++-
src/or/connection.h | 6 +-
src/or/control.c | 18 +-
src/or/directory.c | 251 ++++++++++++----
src/or/directory.h | 4 +-
src/or/entrynodes.c | 26 +-
src/or/nodelist.c | 309 +++++++++++++++-----
src/or/nodelist.h | 12 +-
src/or/or.h | 29 +-
src/or/policies.c | 699 +++++++++++++++++++++++++++++++++++++++++++--
src/or/policies.h | 54 +++-
src/or/rendclient.c | 12 +-
src/or/router.c | 31 +-
src/or/routerlist.c | 332 ++++++++++++++++-----
src/or/routerlist.h | 5 +-
src/test/test_entrynodes.c | 218 +++++++++++++-
src/test/test_policy.c | 531 ++++++++++++++++++++++++++++++++++
src/test/test_routerlist.c | 73 +++++
25 files changed, 2576 insertions(+), 315 deletions(-)
diff --cc src/test/test_routerlist.c
index 090a607,7ec6525..193e3fa
--- a/src/test/test_routerlist.c
+++ b/src/test/test_routerlist.c
@@@ -1,35 -1,12 +1,36 @@@
/* Copyright (c) 2014, The Tor Project, Inc. */
/* See LICENSE for licensing information */
+#include "orconfig.h"
+#include <math.h>
+#include <time.h>
+
+#define DIRVOTE_PRIVATE
+#define NETWORKSTATUS_PRIVATE
#define ROUTERLIST_PRIVATE
+#define TOR_UNIT_TESTING
#include "or.h"
-#include "routerlist.h"
-#include "directory.h"
+#include "config.h"
+ #include "connection.h"
+#include "container.h"
+#include "directory.h"
+#include "dirvote.h"
+#include "networkstatus.h"
+#include "nodelist.h"
+#include "policies.h"
+#include "routerlist.h"
+#include "routerparse.h"
#include "test.h"
+#include "test_dir_common.h"
+
+extern const char AUTHORITY_CERT_1[];
+extern const char AUTHORITY_SIGNKEY_1[];
+extern const char AUTHORITY_CERT_2[];
+extern const char AUTHORITY_SIGNKEY_2[];
+extern const char AUTHORITY_CERT_3[];
+extern const char AUTHORITY_SIGNKEY_3[];
+
+void construct_consensus(const char **consensus_text_md);
/* 4 digests + 3 sep + pre + post + NULL */
static char output[4*BASE64_DIGEST256_LEN+3+2+2+1];
@@@ -118,268 -95,84 +119,340 @@@ test_routerlist_launch_descriptor_downl
smartlist_free(downloadable);
}
+void
+construct_consensus(const char **consensus_text_md)
+{
+ networkstatus_t *vote = NULL;
+ networkstatus_t *v1 = NULL, *v2 = NULL, *v3 = NULL;
+ networkstatus_voter_info_t *voter = NULL;
+ authority_cert_t *cert1=NULL, *cert2=NULL, *cert3=NULL;
+ crypto_pk_t *sign_skey_1=NULL, *sign_skey_2=NULL, *sign_skey_3=NULL;
+ crypto_pk_t *sign_skey_leg=NULL;
+ time_t now = time(NULL);
+ smartlist_t *votes = NULL;
+ addr_policy_t *pol1 = NULL, *pol2 = NULL, *pol3 = NULL;
+ int n_vrs;
+
+ tt_assert(!dir_common_authority_pk_init(&cert1, &cert2, &cert3,
+ &sign_skey_1, &sign_skey_2,
+ &sign_skey_3));
+ sign_skey_leg = pk_generate(4);
+
+ dir_common_construct_vote_1(&vote, cert1, sign_skey_1,
+ &dir_common_gen_routerstatus_for_v3ns,
+ &v1, &n_vrs, now, 1);
+
+ tt_assert(v1);
+ tt_int_op(n_vrs, ==, 4);
+ tt_int_op(smartlist_len(v1->routerstatus_list), ==, 4);
+
+ dir_common_construct_vote_2(&vote, cert2, sign_skey_2,
+ &dir_common_gen_routerstatus_for_v3ns,
+ &v2, &n_vrs, now, 1);
+
+ tt_assert(v2);
+ tt_int_op(n_vrs, ==, 4);
+ tt_int_op(smartlist_len(v2->routerstatus_list), ==, 4);
+
+ dir_common_construct_vote_3(&vote, cert3, sign_skey_3,
+ &dir_common_gen_routerstatus_for_v3ns,
+ &v3, &n_vrs, now, 1);
+
+ tt_assert(v3);
+ tt_int_op(n_vrs, ==, 4);
+ tt_int_op(smartlist_len(v3->routerstatus_list), ==, 4);
+
+ votes = smartlist_new();
+ smartlist_add(votes, v1);
+ smartlist_add(votes, v2);
+ smartlist_add(votes, v3);
+
+ *consensus_text_md = networkstatus_compute_consensus(votes, 3,
+ cert1->identity_key,
+ sign_skey_1,
+ "AAAAAAAAAAAAAAAAAAAA",
+ sign_skey_leg,
+ FLAV_MICRODESC);
+
+ tt_assert(*consensus_text_md);
+
+ done:
+ if (vote)
+ tor_free(vote);
+ if (voter)
+ tor_free(voter);
+ if (pol1)
+ tor_free(pol1);
+ if (pol2)
+ tor_free(pol2);
+ if (pol3)
+ tor_free(pol3);
+}
+
+static void
+test_router_pick_directory_server_impl(void *arg)
+{
+ (void)arg;
+
+ networkstatus_t *con_md = NULL;
+ const char *consensus_text_md = NULL;
+ int flags = PDS_IGNORE_FASCISTFIREWALL|PDS_RETRY_IF_NO_SERVERS;
+ or_options_t *options = get_options_mutable();
+ const routerstatus_t *rs = NULL;
+ options->UseMicrodescriptors = 1;
+ char *router1_id = NULL, *router2_id = NULL, *router3_id = NULL;
+ node_t *node_router1 = NULL, *node_router2 = NULL, *node_router3 = NULL;
+ config_line_t *policy_line = NULL;
+ time_t now = time(NULL);
+ int tmp_dirport1, tmp_dirport3;
+
+ (void)arg;
+
+ /* No consensus available, fail early */
+ rs = router_pick_directory_server_impl(V3_DIRINFO, (const int) 0, NULL);
+ tt_assert(rs == NULL);
+
+ construct_consensus(&consensus_text_md);
+ tt_assert(consensus_text_md);
+ con_md = networkstatus_parse_vote_from_string(consensus_text_md, NULL,
+ NS_TYPE_CONSENSUS);
+ tt_assert(con_md);
+ tt_int_op(con_md->flavor,==, FLAV_MICRODESC);
+ tt_assert(con_md->routerstatus_list);
+ tt_int_op(smartlist_len(con_md->routerstatus_list), ==, 3);
+ tt_assert(!networkstatus_set_current_consensus_from_ns(con_md,
+ "microdesc"));
+ nodelist_set_consensus(con_md);
+ nodelist_assert_ok();
+
+ rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
+ /* We should not fail now we have a consensus and routerstatus_list
+ * and nodelist are populated. */
+ tt_assert(rs != NULL);
+
+ /* Manipulate the nodes so we get the dir server we expect */
+ router1_id = tor_malloc(DIGEST_LEN);
+ memset(router1_id, TEST_DIR_ROUTER_ID_1, DIGEST_LEN);
+ router2_id = tor_malloc(DIGEST_LEN);
+ memset(router2_id, TEST_DIR_ROUTER_ID_2, DIGEST_LEN);
+ router3_id = tor_malloc(DIGEST_LEN);
+ memset(router3_id, TEST_DIR_ROUTER_ID_3, DIGEST_LEN);
+
+ node_router1 = node_get_mutable_by_id(router1_id);
+ node_router2 = node_get_mutable_by_id(router2_id);
+ node_router3 = node_get_mutable_by_id(router3_id);
+
+ node_router1->is_possible_guard = 1;
+
+ node_router1->is_running = 0;
+ node_router3->is_running = 0;
+ rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
+ tt_assert(rs != NULL);
+ tt_assert(tor_memeq(rs->identity_digest, router2_id, DIGEST_LEN));
+ rs = NULL;
+ node_router1->is_running = 1;
+ node_router3->is_running = 1;
+
+ node_router1->rs->is_v2_dir = 0;
+ node_router3->rs->is_v2_dir = 0;
+ tmp_dirport1 = node_router1->rs->dir_port;
+ tmp_dirport3 = node_router3->rs->dir_port;
+ node_router1->rs->dir_port = 0;
+ node_router3->rs->dir_port = 0;
+ rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
+ tt_assert(rs != NULL);
+ tt_assert(tor_memeq(rs->identity_digest, router2_id, DIGEST_LEN));
+ rs = NULL;
+ node_router1->rs->is_v2_dir = 1;
+ node_router3->rs->is_v2_dir = 1;
+ node_router1->rs->dir_port = tmp_dirport1;
+ node_router3->rs->dir_port = tmp_dirport3;
+
+ node_router1->is_valid = 0;
+ node_router3->is_valid = 0;
+ rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
+ tt_assert(rs != NULL);
+ tt_assert(tor_memeq(rs->identity_digest, router2_id, DIGEST_LEN));
+ rs = NULL;
+ node_router1->is_valid = 1;
+ node_router3->is_valid = 1;
+
+ flags |= PDS_FOR_GUARD;
+ node_router1->using_as_guard = 1;
+ node_router2->using_as_guard = 1;
+ node_router3->using_as_guard = 1;
+ rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
+ tt_assert(rs == NULL);
+ node_router1->using_as_guard = 0;
+ rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
+ tt_assert(rs != NULL);
+ tt_assert(tor_memeq(rs->identity_digest, router1_id, DIGEST_LEN));
+ rs = NULL;
+ node_router2->using_as_guard = 0;
+ node_router3->using_as_guard = 0;
+
+ /* One not valid, one guard. This should leave one remaining */
+ node_router1->is_valid = 0;
+ node_router2->using_as_guard = 1;
+ rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
+ tt_assert(rs != NULL);
+ tt_assert(tor_memeq(rs->identity_digest, router3_id, DIGEST_LEN));
+ rs = NULL;
+ node_router1->is_valid = 1;
+ node_router2->using_as_guard = 0;
+
+ /* Manipulate overloaded */
+
+ node_router2->rs->last_dir_503_at = now;
+ node_router3->rs->last_dir_503_at = now;
+ rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
+ tt_assert(rs != NULL);
+ tt_assert(tor_memeq(rs->identity_digest, router1_id, DIGEST_LEN));
+ node_router2->rs->last_dir_503_at = 0;
+ node_router3->rs->last_dir_503_at = 0;
+
+ /* Set a Fascist firewall */
+ flags &= ! PDS_IGNORE_FASCISTFIREWALL;
+ policy_line = tor_malloc_zero(sizeof(config_line_t));
+ policy_line->key = tor_strdup("ReachableORAddresses");
+ policy_line->value = tor_strdup("accept *:442, reject *:*");
+ options->ReachableORAddresses = policy_line;
+ policies_parse_from_options(options);
+
+ node_router1->rs->or_port = 444;
+ node_router2->rs->or_port = 443;
+ node_router3->rs->or_port = 442;
+ rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
+ tt_assert(rs != NULL);
+ tt_assert(tor_memeq(rs->identity_digest, router3_id, DIGEST_LEN));
+ node_router1->rs->or_port = 442;
+ node_router2->rs->or_port = 443;
+ node_router3->rs->or_port = 444;
+ rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
+ tt_assert(rs != NULL);
+ tt_assert(tor_memeq(rs->identity_digest, router1_id, DIGEST_LEN));
+
+ /* Fascist firewall and overloaded */
+ node_router1->rs->or_port = 442;
+ node_router2->rs->or_port = 443;
+ node_router3->rs->or_port = 442;
+ node_router3->rs->last_dir_503_at = now;
+ rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
+ tt_assert(rs != NULL);
+ tt_assert(tor_memeq(rs->identity_digest, router1_id, DIGEST_LEN));
+ node_router3->rs->last_dir_503_at = 0;
+
+ /* Fascists against OR and Dir */
+ policy_line = tor_malloc_zero(sizeof(config_line_t));
+ policy_line->key = tor_strdup("ReachableAddresses");
+ policy_line->value = tor_strdup("accept *:80, reject *:*");
+ options->ReachableDirAddresses = policy_line;
+ policies_parse_from_options(options);
+ node_router1->rs->or_port = 442;
+ node_router2->rs->or_port = 441;
+ node_router3->rs->or_port = 443;
+ node_router1->rs->dir_port = 80;
+ node_router2->rs->dir_port = 80;
+ node_router3->rs->dir_port = 81;
+ node_router1->rs->last_dir_503_at = now;
+ rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
+ tt_assert(rs != NULL);
+ tt_assert(tor_memeq(rs->identity_digest, router1_id, DIGEST_LEN));
+ node_router1->rs->last_dir_503_at = 0;
+
+ done:
+ if (router1_id)
+ tor_free(router1_id);
+ if (router2_id)
+ tor_free(router2_id);
+ if (router3_id)
+ tor_free(router3_id);
+ if (options->ReachableORAddresses ||
+ options->ReachableDirAddresses)
+ policies_free_all();
+}
+
+ connection_t *mocked_connection = NULL;
+
+ /* Mock connection_get_by_type_addr_port_purpose by returning
+ * mocked_connection. */
+ static connection_t *
+ mock_connection_get_by_type_addr_port_purpose(int type,
+ const tor_addr_t *addr,
+ uint16_t port, int purpose)
+ {
+ (void)type;
+ (void)addr;
+ (void)port;
+ (void)purpose;
+
+ return mocked_connection;
+ }
+
+ #define TEST_ADDR_STR "127.0.0.1"
+ #define TEST_DIR_PORT 12345
+
+ static void
+ test_routerlist_router_is_already_dir_fetching(void *arg)
+ {
+ (void)arg;
+ tor_addr_port_t test_ap, null_addr_ap, zero_port_ap;
+
+ /* Setup */
+ tor_addr_parse(&test_ap.addr, TEST_ADDR_STR);
+ test_ap.port = TEST_DIR_PORT;
+ tor_addr_make_null(&null_addr_ap.addr, AF_INET6);
+ null_addr_ap.port = TEST_DIR_PORT;
+ tor_addr_parse(&zero_port_ap.addr, TEST_ADDR_STR);
+ zero_port_ap.port = 0;
+ MOCK(connection_get_by_type_addr_port_purpose,
+ mock_connection_get_by_type_addr_port_purpose);
+
+ /* Test that we never get 1 from a NULL connection */
+ mocked_connection = NULL;
+ tt_assert(router_is_already_dir_fetching(&test_ap, 1, 1) == 0);
+ tt_assert(router_is_already_dir_fetching(&test_ap, 1, 0) == 0);
+ tt_assert(router_is_already_dir_fetching(&test_ap, 0, 1) == 0);
+ /* We always expect 0 in these cases */
+ tt_assert(router_is_already_dir_fetching(&test_ap, 0, 0) == 0);
+ tt_assert(router_is_already_dir_fetching(NULL, 1, 1) == 0);
+ tt_assert(router_is_already_dir_fetching(&null_addr_ap, 1, 1) == 0);
+ tt_assert(router_is_already_dir_fetching(&zero_port_ap, 1, 1) == 0);
+
+ /* Test that we get 1 with a connection in the appropriate circumstances */
+ mocked_connection = connection_new(CONN_TYPE_DIR, AF_INET);
+ tt_assert(router_is_already_dir_fetching(&test_ap, 1, 1) == 1);
+ tt_assert(router_is_already_dir_fetching(&test_ap, 1, 0) == 1);
+ tt_assert(router_is_already_dir_fetching(&test_ap, 0, 1) == 1);
+
+ /* Test that we get 0 even with a connection in the appropriate
+ * circumstances */
+ tt_assert(router_is_already_dir_fetching(&test_ap, 0, 0) == 0);
+ tt_assert(router_is_already_dir_fetching(NULL, 1, 1) == 0);
+ tt_assert(router_is_already_dir_fetching(&null_addr_ap, 1, 1) == 0);
+ tt_assert(router_is_already_dir_fetching(&zero_port_ap, 1, 1) == 0);
+
+ done:
+ /* If a connection is never set up, connection_free chokes on it. */
+ buf_free(mocked_connection->inbuf);
+ buf_free(mocked_connection->outbuf);
+ tor_free(mocked_connection);
+ UNMOCK(connection_get_by_type_addr_port_purpose);
+ }
+
+ #undef TEST_ADDR_STR
+ #undef TEST_DIR_PORT
+
#define NODE(name, flags) \
{ #name, test_routerlist_##name, (flags), NULL, NULL }
+#define ROUTER(name,flags) \
+ { #name, test_router_##name, (flags), NULL, NULL }
struct testcase_t routerlist_tests[] = {
NODE(initiate_descriptor_downloads, 0),
NODE(launch_descriptor_downloads, 0),
+ NODE(router_is_already_dir_fetching, TT_FORK),
+ ROUTER(pick_directory_server_impl, TT_FORK),
END_OF_TESTCASES
};
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits