|
@@ -5,6 +5,7 @@
|
|
|
|
|
|
#define CONNECTION_PRIVATE
|
|
|
#define MAIN_PRIVATE
|
|
|
+#define CONNECTION_OR_PRIVATE
|
|
|
|
|
|
#include "or.h"
|
|
|
#include "test.h"
|
|
@@ -13,9 +14,11 @@
|
|
|
#include "hs_common.h"
|
|
|
#include "main.h"
|
|
|
#include "microdesc.h"
|
|
|
+#include "nodelist.h"
|
|
|
#include "networkstatus.h"
|
|
|
#include "rendcache.h"
|
|
|
#include "directory.h"
|
|
|
+#include "connection_or.h"
|
|
|
|
|
|
#include "test_connection.h"
|
|
|
#include "test_helpers.h"
|
|
@@ -776,6 +779,99 @@ test_conn_download_status(void *arg)
|
|
|
/* the teardown function removes all the connections in the global list*/;
|
|
|
}
|
|
|
|
|
|
+static node_t test_node;
|
|
|
+
|
|
|
+static node_t *
|
|
|
+mock_node_get_mutable_by_id(const char *digest)
|
|
|
+{
|
|
|
+ (void) digest;
|
|
|
+ static routerinfo_t node_ri;
|
|
|
+ memset(&node_ri, 0, sizeof(node_ri));
|
|
|
+
|
|
|
+ test_node.ri = &node_ri;
|
|
|
+ memset(test_node.identity, 'c', sizeof(test_node.identity));
|
|
|
+
|
|
|
+ tor_addr_t ipv4_addr;
|
|
|
+ tor_addr_parse(&ipv4_addr, "18.0.0.1");
|
|
|
+ node_ri.addr = tor_addr_to_ipv4h(&ipv4_addr);
|
|
|
+ node_ri.or_port = 1;
|
|
|
+
|
|
|
+ return &test_node;
|
|
|
+}
|
|
|
+
|
|
|
+static const node_t *
|
|
|
+mock_node_get_by_id(const char *digest)
|
|
|
+{
|
|
|
+ (void) digest;
|
|
|
+ memset(test_node.identity, 'c', sizeof(test_node.identity));
|
|
|
+ return &test_node;
|
|
|
+}
|
|
|
+
|
|
|
+/* Test whether we correctly track failed connections between relays. */
|
|
|
+static void
|
|
|
+test_failed_orconn_tracker(void *arg)
|
|
|
+{
|
|
|
+ (void) arg;
|
|
|
+
|
|
|
+ int can_connect;
|
|
|
+ time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
|
|
|
+ (void) now;
|
|
|
+
|
|
|
+ update_approx_time(now);
|
|
|
+
|
|
|
+ /* Prepare the OR connection that will be used in this test */
|
|
|
+ or_connection_t or_conn;
|
|
|
+ tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&or_conn.real_addr, "18.0.0.1"));
|
|
|
+ tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&or_conn.base_.addr, "18.0.0.1"));
|
|
|
+ or_conn.base_.port = 1;
|
|
|
+ memset(or_conn.identity_digest, 'c', sizeof(or_conn.identity_digest));
|
|
|
+
|
|
|
+ /* Check whether we can connect with an empty failure cache:
|
|
|
+ * this should succeed */
|
|
|
+ can_connect = should_connect_to_relay(&or_conn);
|
|
|
+ tt_int_op(can_connect, OP_EQ, 1);
|
|
|
+
|
|
|
+ /* Now add the destination to the failure cache */
|
|
|
+ note_or_connect_failed(&or_conn);
|
|
|
+
|
|
|
+ /* Check again: now it shouldn't connect */
|
|
|
+ can_connect = should_connect_to_relay(&or_conn);
|
|
|
+ tt_int_op(can_connect, OP_EQ, 0);
|
|
|
+
|
|
|
+ /* Move time forward and check again: the cache should have been cleared and
|
|
|
+ * now it should connect */
|
|
|
+ now += 3600;
|
|
|
+ update_approx_time(now);
|
|
|
+ can_connect = should_connect_to_relay(&or_conn);
|
|
|
+ tt_int_op(can_connect, OP_EQ, 1);
|
|
|
+
|
|
|
+ /* Now mock the node_get_*by_id() functions to start using the node subsystem
|
|
|
+ * optimization. */
|
|
|
+ MOCK(node_get_by_id, mock_node_get_by_id);
|
|
|
+ MOCK(node_get_mutable_by_id, mock_node_get_mutable_by_id);
|
|
|
+
|
|
|
+ /* Since we just started using the node subsystem it will allow connections
|
|
|
+ * now */
|
|
|
+ can_connect = should_connect_to_relay(&or_conn);
|
|
|
+ tt_int_op(can_connect, OP_EQ, 1);
|
|
|
+
|
|
|
+ /* Mark it as failed */
|
|
|
+ note_or_connect_failed(&or_conn);
|
|
|
+
|
|
|
+ /* Check that it shouldn't connect now */
|
|
|
+ can_connect = should_connect_to_relay(&or_conn);
|
|
|
+ tt_int_op(can_connect, OP_EQ, 0);
|
|
|
+
|
|
|
+ /* Move time forward and check again: now it should connect */
|
|
|
+ now += 3600;
|
|
|
+ update_approx_time(now);
|
|
|
+ can_connect = should_connect_to_relay(&or_conn);
|
|
|
+ tt_int_op(can_connect, OP_EQ, 1);
|
|
|
+
|
|
|
+ done:
|
|
|
+ ;
|
|
|
+}
|
|
|
+
|
|
|
#define CONNECTION_TESTCASE(name, fork, setup) \
|
|
|
{ #name, test_conn_##name, fork, &setup, NULL }
|
|
|
|
|
@@ -792,6 +888,7 @@ struct testcase_t connection_tests[] = {
|
|
|
CONNECTION_TESTCASE_ARG(download_status, TT_FORK,
|
|
|
test_conn_download_status_st, FLAV_NS),
|
|
|
//CONNECTION_TESTCASE(func_suffix, TT_FORK, setup_func_pair),
|
|
|
+ { "failed_orconn_tracker", test_failed_orconn_tracker, TT_FORK, NULL, NULL },
|
|
|
END_OF_TESTCASES
|
|
|
};
|
|
|
|