summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/test_microdesc.c35
-rw-r--r--src/test/test_nodelist.c49
-rw-r--r--src/test/test_router.c154
3 files changed, 228 insertions, 10 deletions
diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c
index 3318408d53..fd79aee6be 100644
--- a/src/test/test_microdesc.c
+++ b/src/test/test_microdesc.c
@@ -176,7 +176,7 @@ test_md_cache(void *data)
tt_ptr_op(md3->family, OP_NE, NULL);
encoded_family = nodefamily_format(md3->family);
- tt_str_op(encoded_family, OP_EQ, "nodeX nodeY nodeZ");
+ tt_str_op(encoded_family, OP_EQ, "nodex nodey nodez");
/* Now rebuild the cache! */
tt_int_op(microdesc_cache_rebuild(mc, 1), OP_EQ, 0);
@@ -421,6 +421,28 @@ static const char test_md2_21[] =
"ntor-onion-key hbxdRnfVUJJY7+KcT4E3Rs7/zuClbN3hJrjSBiEGMgI=\n"
"id ed25519 wqfLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx/Q\n";
+static const char test_md2_withfamily_28[] =
+ "onion-key\n"
+ "-----BEGIN RSA PUBLIC KEY-----\n"
+ "MIGJAoGBAL2R8EfubUcahxha4u02P4VAR0llQIMwFAmrHPjzcK7apcQgDOf2ovOA\n"
+ "+YQnJFxlpBmCoCZC6ssCi+9G0mqo650lFuTMP5I90BdtjotfzESfTykHLiChyvhd\n"
+ "l0dlqclb2SU/GKem/fLRXH16aNi72CdSUu/1slKs/70ILi34QixRAgMBAAE=\n"
+ "-----END RSA PUBLIC KEY-----\n"
+ "ntor-onion-key hbxdRnfVUJJY7+KcT4E3Rs7/zuClbN3hJrjSBiEGMgI=\n"
+ "family OtherNode !Strange\n"
+ "id ed25519 wqfLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx/Q\n";
+
+static const char test_md2_withfamily_29[] =
+ "onion-key\n"
+ "-----BEGIN RSA PUBLIC KEY-----\n"
+ "MIGJAoGBAL2R8EfubUcahxha4u02P4VAR0llQIMwFAmrHPjzcK7apcQgDOf2ovOA\n"
+ "+YQnJFxlpBmCoCZC6ssCi+9G0mqo650lFuTMP5I90BdtjotfzESfTykHLiChyvhd\n"
+ "l0dlqclb2SU/GKem/fLRXH16aNi72CdSUu/1slKs/70ILi34QixRAgMBAAE=\n"
+ "-----END RSA PUBLIC KEY-----\n"
+ "ntor-onion-key hbxdRnfVUJJY7+KcT4E3Rs7/zuClbN3hJrjSBiEGMgI=\n"
+ "family !Strange $B7E27F104213C36F13E7E9829182845E495997A0 othernode\n"
+ "id ed25519 wqfLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx/Q\n";
+
static void
test_md_generate(void *arg)
{
@@ -451,6 +473,17 @@ test_md_generate(void *arg)
tt_assert(ed25519_pubkey_eq(md->ed25519_identity_pkey,
&ri->cache_info.signing_key_cert->signing_key));
+ // Try family encoding.
+ microdesc_free(md);
+ ri->declared_family = smartlist_new();
+ smartlist_add_strdup(ri->declared_family, "OtherNode !Strange");
+ md = dirvote_create_microdescriptor(ri, 28);
+ tt_str_op(md->body, OP_EQ, test_md2_withfamily_28);
+
+ microdesc_free(md);
+ md = dirvote_create_microdescriptor(ri, 29);
+ tt_str_op(md->body, OP_EQ, test_md2_withfamily_29);
+
done:
microdesc_free(md);
routerinfo_free(ri);
diff --git a/src/test/test_nodelist.c b/src/test/test_nodelist.c
index 0287be3305..ed919f4edf 100644
--- a/src/test/test_nodelist.c
+++ b/src/test/test_nodelist.c
@@ -299,7 +299,7 @@ test_nodelist_nodefamily(void *arg)
tt_ptr_op(nf1, OP_EQ, nf3);
/* Do we get the expected result when we re-encode? */
- tor_asprintf(&enc, "hello $%s", h1);
+ tor_asprintf(&enc, "$%s hello", h1);
enc2 = nodefamily_format(nf1);
tt_str_op(enc2, OP_EQ, enc);
tor_free(enc2);
@@ -399,8 +399,8 @@ test_nodelist_nodefamily_parse_err(void *arg)
tt_assert(nf1);
enc = nodefamily_format(nf1);
tt_str_op(enc, OP_EQ,
- "reticulatogranulate "
- "$7468696E67732D696E2D7468656D73656C766573");
+ "$7468696E67732D696E2D7468656D73656C766573 "
+ "reticulatogranulate");
tor_free(enc);
}
@@ -470,11 +470,11 @@ test_nodelist_nodefamily_lookup(void *arg)
tt_int_op(smartlist_len(sl), OP_EQ, 3);
const node_t *n = smartlist_get(sl, 0);
- tt_str_op(n->identity, OP_EQ, "erewhon");
- n = smartlist_get(sl, 1);
test_memeq_hex(n->identity, "3333333333333333333333333333333333333333");
- n = smartlist_get(sl, 2);
+ n = smartlist_get(sl, 1);
test_memeq_hex(n->identity, "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE");
+ n = smartlist_get(sl, 2);
+ tt_str_op(n->identity, OP_EQ, "erewhon");
done:
UNMOCK(node_get_by_nickname);
@@ -583,9 +583,9 @@ test_nodelist_node_nodefamily(void *arg)
node_lookup_declared_family(nodes, &mock_node1);
tt_int_op(smartlist_len(nodes), OP_EQ, 2);
const node_t *n = smartlist_get(nodes, 0);
- tt_str_op(n->identity, OP_EQ, "NodeFour");
- n = smartlist_get(nodes, 1);
tt_mem_op(n->identity, OP_EQ, "SecondNodeWe'reTestn", DIGEST_LEN);
+ n = smartlist_get(nodes, 1);
+ tt_str_op(n->identity, OP_EQ, "nodefour");
// free, try the other one.
SMARTLIST_FOREACH(nodes, node_t *, x, tor_free(x));
@@ -594,9 +594,9 @@ test_nodelist_node_nodefamily(void *arg)
node_lookup_declared_family(nodes, &mock_node2);
tt_int_op(smartlist_len(nodes), OP_EQ, 2);
n = smartlist_get(nodes, 0);
+ // This gets a truncated hex hex ID since it was looked up by name
tt_str_op(n->identity, OP_EQ, "NodeThree");
n = smartlist_get(nodes, 1);
- // This gets a truncated hex hex ID since it was looked up by name
tt_str_op(n->identity, OP_EQ, "4e6f64654f6e654e6f6");
done:
@@ -610,6 +610,36 @@ test_nodelist_node_nodefamily(void *arg)
smartlist_free(nodes);
}
+static void
+test_nodelist_nodefamily_canonicalize(void *arg)
+{
+ (void)arg;
+ char *c = NULL;
+
+ c = nodefamily_canonicalize("", NULL, 0);
+ tt_str_op(c, OP_EQ, "");
+ tor_free(c);
+
+ uint8_t own_id[20];
+ memset(own_id, 0, sizeof(own_id));
+ c = nodefamily_canonicalize(
+ "alice BOB caroL %potrzebie !!!@#@# "
+ "$bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb=fred "
+ "ffffffffffffffffffffffffffffffffffffffff "
+ "$cccccccccccccccccccccccccccccccccccccccc ", own_id, 0);
+ tt_str_op(c, OP_EQ,
+ "!!!@#@# "
+ "$0000000000000000000000000000000000000000 "
+ "$BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB "
+ "$CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC "
+ "$FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF "
+ "%potrzebie "
+ "alice bob carol");
+
+ done:
+ tor_free(c);
+}
+
#define NODE(name, flags) \
{ #name, test_nodelist_##name, (flags), NULL, NULL }
@@ -623,5 +653,6 @@ struct testcase_t nodelist_tests[] = {
NODE(nodefamily_lookup, TT_FORK),
NODE(nickname_matches, 0),
NODE(node_nodefamily, TT_FORK),
+ NODE(nodefamily_canonicalize, 0),
END_OF_TESTCASES
};
diff --git a/src/test/test_router.c b/src/test/test_router.c
index 18740dcb84..91cdd2c064 100644
--- a/src/test/test_router.c
+++ b/src/test/test_router.c
@@ -7,6 +7,7 @@
* \brief Unittests for code in router.c
**/
+#define CONFIG_PRIVATE
#define ROUTER_PRIVATE
#include "core/or/or.h"
@@ -15,6 +16,8 @@
#include "feature/hibernate/hibernate.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/networkstatus_st.h"
+#include "feature/nodelist/node_st.h"
+#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerinfo_st.h"
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerstatus_st.h"
@@ -22,6 +25,7 @@
#include "feature/stats/rephist.h"
#include "lib/crypt_ops/crypto_curve25519.h"
#include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/encoding/confline.h"
/* Test suite stuff */
#include "test/test.h"
@@ -328,6 +332,155 @@ test_router_mark_if_too_old(void *arg)
UNMOCK(networkstatus_vote_find_entry);
}
+static node_t fake_node;
+static const node_t *
+mock_node_get_by_nickname(const char *name, unsigned flags)
+{
+ (void)flags;
+ if (!strcasecmp(name, "crumpet"))
+ return &fake_node;
+ else
+ return NULL;
+}
+
+static void
+test_router_get_my_family(void *arg)
+{
+ (void)arg;
+ or_options_t *options = options_new();
+ smartlist_t *sl = NULL;
+ char *join = NULL;
+ // Overwrite the result of router_get_my_identity_digest(). This
+ // happens to be okay, but only for testing.
+ set_server_identity_key_digest_testing(
+ (const uint8_t*)"holeinthebottomofthe");
+
+ setup_capture_of_logs(LOG_WARN);
+
+ // No family listed -- so there's no list.
+ sl = get_my_declared_family(options);
+ tt_ptr_op(sl, OP_EQ, NULL);
+ expect_no_log_entry();
+
+#define CLEAR() do { \
+ if (sl) { \
+ SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); \
+ smartlist_free(sl); \
+ } \
+ tor_free(join); \
+ mock_clean_saved_logs(); \
+ } while (0)
+
+ // Add a single nice friendly hex member. This should be enough
+ // to have our own ID added.
+ tt_ptr_op(options->MyFamily, OP_EQ, NULL);
+ config_line_append(&options->MyFamily, "MyFamily",
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
+
+ sl = get_my_declared_family(options);
+ tt_ptr_op(sl, OP_NE, NULL);
+ tt_int_op(smartlist_len(sl), OP_EQ, 2);
+ join = smartlist_join_strings(sl, " ", 0, NULL);
+ tt_str_op(join, OP_EQ,
+ "$686F6C65696E746865626F74746F6D6F66746865 "
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
+ expect_no_log_entry();
+ CLEAR();
+
+ // Add a hex member with a ~. The ~ part should get removed.
+ config_line_append(&options->MyFamily, "MyFamily",
+ "$0123456789abcdef0123456789abcdef01234567~Muffin");
+ sl = get_my_declared_family(options);
+ tt_ptr_op(sl, OP_NE, NULL);
+ tt_int_op(smartlist_len(sl), OP_EQ, 3);
+ join = smartlist_join_strings(sl, " ", 0, NULL);
+ tt_str_op(join, OP_EQ,
+ "$0123456789ABCDEF0123456789ABCDEF01234567 "
+ "$686F6C65696E746865626F74746F6D6F66746865 "
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
+ expect_no_log_entry();
+ CLEAR();
+
+ // Nickname lookup will fail, so a nickname will appear verbatim.
+ config_line_append(&options->MyFamily, "MyFamily",
+ "BAGEL");
+ sl = get_my_declared_family(options);
+ tt_ptr_op(sl, OP_NE, NULL);
+ tt_int_op(smartlist_len(sl), OP_EQ, 4);
+ join = smartlist_join_strings(sl, " ", 0, NULL);
+ tt_str_op(join, OP_EQ,
+ "$0123456789ABCDEF0123456789ABCDEF01234567 "
+ "$686F6C65696E746865626F74746F6D6F66746865 "
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
+ "bagel");
+ expect_single_log_msg_containing(
+ "There is a router named \"BAGEL\" in my declared family, but "
+ "I have no descriptor for it.");
+ CLEAR();
+
+ // A bogus digest should fail entirely.
+ config_line_append(&options->MyFamily, "MyFamily",
+ "$painauchocolat");
+ sl = get_my_declared_family(options);
+ tt_ptr_op(sl, OP_NE, NULL);
+ tt_int_op(smartlist_len(sl), OP_EQ, 4);
+ join = smartlist_join_strings(sl, " ", 0, NULL);
+ tt_str_op(join, OP_EQ,
+ "$0123456789ABCDEF0123456789ABCDEF01234567 "
+ "$686F6C65696E746865626F74746F6D6F66746865 "
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
+ "bagel");
+ // "BAGEL" is still there, but it won't make a warning, because we already
+ // warned about it.
+ expect_single_log_msg_containing(
+ "There is a router named \"$painauchocolat\" in my declared "
+ "family, but that isn't a legal digest or nickname. Skipping it.");
+ CLEAR();
+
+ // Let's introduce a node we can look up by nickname
+ memset(&fake_node, 0, sizeof(fake_node));
+ memcpy(fake_node.identity, "whydoyouasknonononon", DIGEST_LEN);
+ MOCK(node_get_by_nickname, mock_node_get_by_nickname);
+
+ config_line_append(&options->MyFamily, "MyFamily",
+ "CRUmpeT");
+ sl = get_my_declared_family(options);
+ tt_ptr_op(sl, OP_NE, NULL);
+ tt_int_op(smartlist_len(sl), OP_EQ, 5);
+ join = smartlist_join_strings(sl, " ", 0, NULL);
+ tt_str_op(join, OP_EQ,
+ "$0123456789ABCDEF0123456789ABCDEF01234567 "
+ "$686F6C65696E746865626F74746F6D6F66746865 "
+ "$776879646F796F7561736B6E6F6E6F6E6F6E6F6E "
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
+ "bagel");
+ // "BAGEL" is still there, but it won't make a warning, because we already
+ // warned about it. Some with "$painauchocolat".
+ expect_single_log_msg_containing(
+ "There is a router named \"CRUmpeT\" in my declared "
+ "family, but it wasn't listed by digest. Please consider saying "
+ "$776879646F796F7561736B6E6F6E6F6E6F6E6F6E instead, if that's "
+ "what you meant.");
+ CLEAR();
+ UNMOCK(node_get_by_nickname);
+
+ // Try a singleton list containing only us: It should give us NULL.
+ config_free_lines(options->MyFamily);
+ config_line_append(&options->MyFamily, "MyFamily",
+ "$686F6C65696E746865626F74746F6D6F66746865");
+ sl = get_my_declared_family(options);
+ tt_ptr_op(sl, OP_EQ, NULL);
+ expect_no_log_entry();
+
+ done:
+ or_options_free(options);
+ teardown_capture_of_logs();
+ CLEAR();
+ UNMOCK(node_get_by_nickname);
+
+#undef CLEAR
+}
+
#define ROUTER_TEST(name, flags) \
{ #name, test_router_ ## name, flags, NULL, NULL }
@@ -335,5 +488,6 @@ struct testcase_t router_tests[] = {
ROUTER_TEST(check_descriptor_bandwidth_changed, TT_FORK),
ROUTER_TEST(dump_router_to_string_no_bridge_distribution_method, TT_FORK),
ROUTER_TEST(mark_if_too_old, TT_FORK),
+ ROUTER_TEST(get_my_family, TT_FORK),
END_OF_TESTCASES
};