diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/include.am | 1 | ||||
-rw-r--r-- | src/test/test.c | 134 | ||||
-rw-r--r-- | src/test/test_addr.c | 179 | ||||
-rw-r--r-- | src/test/test_cell_formats.c | 386 | ||||
-rw-r--r-- | src/test/test_config.c | 1 | ||||
-rw-r--r-- | src/test/test_dir.c | 18 | ||||
-rw-r--r-- | src/test/test_util.c | 2 |
7 files changed, 648 insertions, 73 deletions
diff --git a/src/test/include.am b/src/test/include.am index bdfe498d66..075df36460 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -14,6 +14,7 @@ src_test_AM_CPPFLAGS = -DSHARE_DATADIR="\"$(datadir)\"" \ src_test_test_SOURCES = \ src/test/test.c \ src/test/test_addr.c \ + src/test/test_cell_formats.c \ src/test/test_containers.c \ src/test/test_crypto.c \ src/test/test_data.c \ diff --git a/src/test/test.c b/src/test/test.c index 210b9a4f8d..c96aeb7053 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -1044,9 +1044,9 @@ test_policy_summary_helper(const char *policy_str, line.value = (char *)policy_str; line.next = NULL; - r = policies_parse_exit_policy(&line, &policy, 0, NULL, 1); + r = policies_parse_exit_policy(&line, &policy, 1, 0, NULL, 1); test_eq(r, 0); - summary = policy_summarize(policy); + summary = policy_summarize(policy, AF_INET); test_assert(summary != NULL); test_streq(summary, expected_summary); @@ -1101,7 +1101,7 @@ test_policies(void) test_assert(ADDR_POLICY_REJECTED == compare_tor_addr_to_addr_policy(&tar, 2, policy)); - test_assert(0 == policies_parse_exit_policy(NULL, &policy2, 1, NULL, 1)); + test_assert(0 == policies_parse_exit_policy(NULL, &policy2, 1, 1, NULL, 1)); test_assert(policy2); policy3 = smartlist_new(); @@ -1176,9 +1176,9 @@ test_policies(void) test_assert(!cmp_addr_policies(policy2, policy2)); test_assert(!cmp_addr_policies(NULL, NULL)); - test_assert(!policy_is_reject_star(policy2)); - test_assert(policy_is_reject_star(policy)); - test_assert(policy_is_reject_star(NULL)); + test_assert(!policy_is_reject_star(policy2, AF_INET)); + test_assert(policy_is_reject_star(policy, AF_INET)); + test_assert(policy_is_reject_star(NULL, AF_INET)); addr_policy_list_free(policy); policy = NULL; @@ -1188,11 +1188,11 @@ test_policies(void) line.key = (char*)"foo"; line.value = (char*)"accept *:80,reject private:*,reject *:*"; line.next = NULL; - test_assert(0 == policies_parse_exit_policy(&line, &policy, 0, NULL, 1)); + test_assert(0 == policies_parse_exit_policy(&line, &policy, 1, 0, NULL, 1)); test_assert(policy); //test_streq(policy->string, "accept *:80"); //test_streq(policy->next->string, "reject *:*"); - test_eq(smartlist_len(policy), 2); + test_eq(smartlist_len(policy), 4); /* test policy summaries */ /* check if we properly ignore private IP addresses */ @@ -1454,10 +1454,11 @@ test_geoip(void) { int i, j; time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */ - char *s = NULL; + char *s = NULL, *v = NULL; const char *bridge_stats_1 = "bridge-stats-end 2010-08-12 13:27:30 (86400 s)\n" - "bridge-ips zz=24,xy=8\n", + "bridge-ips zz=24,xy=8\n" + "bridge-ip-versions v4=16,v6=16\n", *dirreq_stats_1 = "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n" "dirreq-v3-ips ab=8\n" @@ -1521,61 +1522,109 @@ test_geoip(void) "entry-stats-end 2010-08-12 13:27:30 (86400 s)\n" "entry-ips \n"; tor_addr_t addr; + struct in6_addr in6; /* Populate the DB a bit. Add these in order, since we can't do the final * 'sort' step. These aren't very good IP addresses, but they're perfectly * fine uint32_t values. */ - test_eq(0, geoip_parse_entry("10,50,AB")); - test_eq(0, geoip_parse_entry("52,90,XY")); - test_eq(0, geoip_parse_entry("95,100,AB")); - test_eq(0, geoip_parse_entry("\"105\",\"140\",\"ZZ\"")); - test_eq(0, geoip_parse_entry("\"150\",\"190\",\"XY\"")); - test_eq(0, geoip_parse_entry("\"200\",\"250\",\"AB\"")); + test_eq(0, geoip_parse_entry("10,50,AB", AF_INET)); + test_eq(0, geoip_parse_entry("52,90,XY", AF_INET)); + test_eq(0, geoip_parse_entry("95,100,AB", AF_INET)); + test_eq(0, geoip_parse_entry("\"105\",\"140\",\"ZZ\"", AF_INET)); + test_eq(0, geoip_parse_entry("\"150\",\"190\",\"XY\"", AF_INET)); + test_eq(0, geoip_parse_entry("\"200\",\"250\",\"AB\"", AF_INET)); + + /* Populate the IPv6 DB equivalently with fake IPs in the same range */ + test_eq(0, geoip_parse_entry("::a,::32,AB", AF_INET6)); + test_eq(0, geoip_parse_entry("::34,::5a,XY", AF_INET6)); + test_eq(0, geoip_parse_entry("::5f,::64,AB", AF_INET6)); + test_eq(0, geoip_parse_entry("::69,::8c,ZZ", AF_INET6)); + test_eq(0, geoip_parse_entry("::96,::be,XY", AF_INET6)); + test_eq(0, geoip_parse_entry("::c8,::fa,AB", AF_INET6)); /* We should have 4 countries: ??, ab, xy, zz. */ test_eq(4, geoip_get_n_countries()); + memset(&in6, 0, sizeof(in6)); + /* Make sure that country ID actually works. */ -#define NAMEFOR(x) geoip_get_country_name(geoip_get_country_by_ip(x)) - test_streq("??", NAMEFOR(3)); - test_eq(0, geoip_get_country_by_ip(3)); - test_streq("ab", NAMEFOR(32)); - test_streq("??", NAMEFOR(5)); - test_streq("??", NAMEFOR(51)); - test_streq("xy", NAMEFOR(150)); - test_streq("xy", NAMEFOR(190)); - test_streq("??", NAMEFOR(2000)); -#undef NAMEFOR +#define SET_TEST_IPV6(i) \ + do { \ + set_uint32(in6.s6_addr + 12, htonl((uint32_t) (i))); \ + } while (0) +#define CHECK_COUNTRY(country, val) do { \ + /* test ipv4 country lookup */ \ + test_streq(country, \ + geoip_get_country_name(geoip_get_country_by_ipv4(val))); \ + /* test ipv6 country lookup */ \ + SET_TEST_IPV6(val); \ + test_streq(country, \ + geoip_get_country_name(geoip_get_country_by_ipv6(&in6))); \ + } while (0) + + CHECK_COUNTRY("??", 3); + CHECK_COUNTRY("ab", 32); + CHECK_COUNTRY("??", 5); + CHECK_COUNTRY("??", 51); + CHECK_COUNTRY("xy", 150); + CHECK_COUNTRY("xy", 190); + CHECK_COUNTRY("??", 2000); + + test_eq(0, geoip_get_country_by_ipv4(3)); + SET_TEST_IPV6(3); + test_eq(0, geoip_get_country_by_ipv6(&in6)); + +#undef CHECK_COUNTRY + + /* Record odd numbered fake-IPs using ipv6, even numbered fake-IPs + * using ipv4. Since our fake geoip database is the same between + * ipv4 and ipv6, we should get the same result no matter which + * address family we pick for each IP. */ +#define SET_TEST_ADDRESS(i) do { \ + if ((i) & 1) { \ + SET_TEST_IPV6(i); \ + tor_addr_from_in6(&addr, &in6); \ + } else { \ + tor_addr_from_ipv4h(&addr, (uint32_t) i); \ + } \ + } while (0) get_options_mutable()->BridgeRelay = 1; get_options_mutable()->BridgeRecordUsageByCountry = 1; /* Put 9 observations in AB... */ for (i=32; i < 40; ++i) { - tor_addr_from_ipv4h(&addr, (uint32_t) i); + SET_TEST_ADDRESS(i); geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now-7200); } - tor_addr_from_ipv4h(&addr, (uint32_t) 225); + SET_TEST_ADDRESS(225); geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now-7200); /* and 3 observations in XY, several times. */ for (j=0; j < 10; ++j) for (i=52; i < 55; ++i) { - tor_addr_from_ipv4h(&addr, (uint32_t) i); + SET_TEST_ADDRESS(i); geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now-3600); } /* and 17 observations in ZZ... */ for (i=110; i < 127; ++i) { - tor_addr_from_ipv4h(&addr, (uint32_t) i); + SET_TEST_ADDRESS(i); geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now); } - s = geoip_get_client_history(GEOIP_CLIENT_CONNECT); + geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v); test_assert(s); + test_assert(v); test_streq("zz=24,ab=16,xy=8", s); + test_streq("v4=16,v6=16", v); tor_free(s); + tor_free(v); /* Now clear out all the AB observations. */ geoip_remove_old_clients(now-6000); - s = geoip_get_client_history(GEOIP_CLIENT_CONNECT); + geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v); test_assert(s); + test_assert(v); test_streq("zz=24,xy=8", s); + test_streq("v4=16,v6=16", v); + tor_free(s); + tor_free(v); /* Start testing bridge statistics by making sure that we don't output * bridge stats without initializing them. */ @@ -1604,7 +1653,7 @@ test_geoip(void) /* Start testing dirreq statistics by making sure that we don't collect * dirreq stats without initializing them. */ - tor_addr_from_ipv4h(&addr, (uint32_t) 100); + SET_TEST_ADDRESS(100); geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, now); s = geoip_format_dirreq_stats(now + 86400); test_assert(!s); @@ -1612,7 +1661,7 @@ test_geoip(void) /* Initialize stats, note one connecting client, and generate the * dirreq-stats history string. */ geoip_dirreq_stats_init(now); - tor_addr_from_ipv4h(&addr, (uint32_t) 100); + SET_TEST_ADDRESS(100); geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, now); s = geoip_format_dirreq_stats(now + 86400); test_streq(dirreq_stats_1, s); @@ -1621,7 +1670,7 @@ test_geoip(void) /* Stop collecting stats, add another connecting client, and ensure we * don't generate a history string. */ geoip_dirreq_stats_term(); - tor_addr_from_ipv4h(&addr, (uint32_t) 101); + SET_TEST_ADDRESS(101); geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, now); s = geoip_format_dirreq_stats(now + 86400); test_assert(!s); @@ -1629,7 +1678,7 @@ test_geoip(void) /* Re-start stats, add a connecting client, reset stats, and make sure * that we get an all empty history string. */ geoip_dirreq_stats_init(now); - tor_addr_from_ipv4h(&addr, (uint32_t) 100); + SET_TEST_ADDRESS(100); geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, now); geoip_reset_dirreq_stats(now); s = geoip_format_dirreq_stats(now + 86400); @@ -1657,7 +1706,7 @@ test_geoip(void) /* Start testing entry statistics by making sure that we don't collect * anything without initializing entry stats. */ - tor_addr_from_ipv4h(&addr, (uint32_t) 100); + SET_TEST_ADDRESS(100); geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now); s = geoip_format_entry_stats(now + 86400); test_assert(!s); @@ -1665,7 +1714,7 @@ test_geoip(void) /* Initialize stats, note one connecting client, and generate the * entry-stats history string. */ geoip_entry_stats_init(now); - tor_addr_from_ipv4h(&addr, (uint32_t) 100); + SET_TEST_ADDRESS(100); geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now); s = geoip_format_entry_stats(now + 86400); test_streq(entry_stats_1, s); @@ -1674,7 +1723,7 @@ test_geoip(void) /* Stop collecting stats, add another connecting client, and ensure we * don't generate a history string. */ geoip_entry_stats_term(); - tor_addr_from_ipv4h(&addr, (uint32_t) 101); + SET_TEST_ADDRESS(101); geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now); s = geoip_format_entry_stats(now + 86400); test_assert(!s); @@ -1682,13 +1731,16 @@ test_geoip(void) /* Re-start stats, add a connecting client, reset stats, and make sure * that we get an all empty history string. */ geoip_entry_stats_init(now); - tor_addr_from_ipv4h(&addr, (uint32_t) 100); + SET_TEST_ADDRESS(100); geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, now); geoip_reset_entry_stats(now); s = geoip_format_entry_stats(now + 86400); test_streq(entry_stats_2, s); tor_free(s); +#undef SET_TEST_ADDRESS +#undef SET_TEST_IPV6 + /* Stop collecting entry statistics. */ geoip_entry_stats_term(); get_options_mutable()->EntryStatistics = 0; @@ -1931,6 +1983,7 @@ extern struct testcase_t pt_tests[]; extern struct testcase_t config_tests[]; extern struct testcase_t introduce_tests[]; extern struct testcase_t replaycache_tests[]; +extern struct testcase_t cell_format_tests[]; static struct testgroup_t testgroups[] = { { "", test_array }, @@ -1939,6 +1992,7 @@ static struct testgroup_t testgroups[] = { { "crypto/", crypto_tests }, { "container/", container_tests }, { "util/", util_tests }, + { "cellfmt/", cell_format_tests }, { "dir/", dir_tests }, { "dir/md/", microdesc_tests }, { "pt/", pt_tests }, diff --git a/src/test/test_addr.c b/src/test/test_addr.c index 343ec6d3c2..d2b25e5e6c 100644 --- a/src/test/test_addr.c +++ b/src/test/test_addr.c @@ -159,7 +159,8 @@ test_addr_basic(void) * as <b>pt1..pt2</b>. */ #define test_addr_mask_ports_parse(xx, f, ip1, ip2, ip3, ip4, mm, pt1, pt2) \ STMT_BEGIN \ - test_eq(tor_addr_parse_mask_ports(xx, &t1, &mask, &port1, &port2), f); \ + test_eq(tor_addr_parse_mask_ports(xx, 0, &t1, &mask, &port1, &port2), \ + f); \ p1=tor_inet_ntop(AF_INET6, &t1.addr.in6_addr, bug, sizeof(bug)); \ test_eq(htonl(ip1), tor_addr_to_in6_addr32(&t1)[0]); \ test_eq(htonl(ip2), tor_addr_to_in6_addr32(&t1)[1]); \ @@ -401,11 +402,11 @@ test_addr_ip6_helpers(void) 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. */ - tor_addr_parse_mask_ports("[::ffff:2.3.4.5]", &t1, NULL, NULL, NULL); - tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL); + 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); test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) == 0); - tor_addr_parse_mask_ports("[::ffff:2.3.4.4]", &t1, NULL, NULL, NULL); - tor_addr_parse_mask_ports("2.3.4.5", &t2, NULL, NULL, NULL); + tor_addr_parse_mask_ports("[::ffff:2.3.4.4]", 0, &t1, NULL, NULL, NULL); + tor_addr_parse_mask_ports("2.3.4.5", 0, &t2, NULL, NULL, NULL); test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) < 0); /* test compare_masked */ @@ -568,6 +569,7 @@ test_addr_ip6_helpers(void) test_streq(rbuf, 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); @@ -581,27 +583,123 @@ test_addr_ip6_helpers(void) 0xabcd0002, 0, 0, 0x044a0000, 128, 2, 65000); test_streq(p1, "abcd:2::44a:0"); - r=tor_addr_parse_mask_ports("[fefef::]/112", &t1, NULL, NULL, NULL); + /* Try some long addresses. */ + r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:1111]", + 0, &t1, NULL, NULL, NULL); + test_assert(r == AF_INET6); + r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:11111]", + 0, &t1, NULL, NULL, NULL); + test_assert(r == -1); + r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:1111:1]", + 0, &t1, NULL, NULL, NULL); + test_assert(r == -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); + test_assert(r == -1); + /* Try some failing cases. */ + r=tor_addr_parse_mask_ports("[fefef::]/112", 0, &t1, NULL, NULL, NULL); + test_assert(r == -1); + r=tor_addr_parse_mask_ports("[fefe::/112", 0, &t1, NULL, NULL, NULL); + test_assert(r == -1); + r=tor_addr_parse_mask_ports("[fefe::", 0, &t1, NULL, NULL, NULL); + test_assert(r == -1); + r=tor_addr_parse_mask_ports("[fefe::X]", 0, &t1, NULL, NULL, NULL); + test_assert(r == -1); + r=tor_addr_parse_mask_ports("efef::/112", 0, &t1, NULL, NULL, NULL); + test_assert(r == -1); + r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f::]",0,&t1, NULL, NULL, NULL); test_assert(r == -1); - r=tor_addr_parse_mask_ports("efef::/112", &t1, NULL, NULL, NULL); + r=tor_addr_parse_mask_ports("[::f:f:f:f:f:f:f:f]",0,&t1, NULL, NULL, NULL); test_assert(r == -1); - r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f::]", &t1, NULL, NULL, NULL); + r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f:f]",0,&t1, NULL, NULL, NULL); test_assert(r == -1); - r=tor_addr_parse_mask_ports("[::f:f:f:f:f:f:f:f]", &t1, NULL, NULL, NULL); + r=tor_addr_parse_mask_ports("[f:f:f:f:f::]/fred",0,&t1,&mask, NULL, NULL); test_assert(r == -1); - r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f:f]", &t1, NULL, NULL, NULL); + r=tor_addr_parse_mask_ports("[f:f:f:f:f::]/255.255.0.0", + 0,&t1, NULL, NULL, NULL); + test_assert(r == -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); test_assert(r == -1); /* Test for V4-mapped address with mask < 96. (arguably not valid) */ - r=tor_addr_parse_mask_ports("[::ffff:1.1.2.2/33]", &t1, &mask, NULL, NULL); + r=tor_addr_parse_mask_ports("[::ffff:1.1.2.2/33]",0,&t1, &mask, NULL, NULL); + test_assert(r == -1); + r=tor_addr_parse_mask_ports("1.1.2.2/33",0,&t1, &mask, NULL, NULL); + test_assert(r == -1); + /* Try extended wildcard addresses with out TAPMP_EXTENDED_STAR*/ + r=tor_addr_parse_mask_ports("*4",0,&t1, &mask, NULL, NULL); + test_assert(r == -1); + r=tor_addr_parse_mask_ports("*6",0,&t1, &mask, NULL, NULL); test_assert(r == -1); - r=tor_addr_parse_mask_ports("1.1.2.2/33", &t1, &mask, NULL, NULL); +#if 0 + /* Try a mask with a wildcard. */ + r=tor_addr_parse_mask_ports("*/16",0,&t1, &mask, NULL, NULL); test_assert(r == -1); - r=tor_addr_parse_mask_ports("1.1.2.2/31", &t1, &mask, NULL, NULL); + r=tor_addr_parse_mask_ports("*4/16",TAPMP_EXTENDED_STAR, + &t1, &mask, NULL, NULL); + test_assert(r == -1); + r=tor_addr_parse_mask_ports("*6/30",TAPMP_EXTENDED_STAR, + &t1, &mask, NULL, NULL); + test_assert(r == -1); +#endif + /* Basic mask tests*/ + r=tor_addr_parse_mask_ports("1.1.2.2/31",0,&t1, &mask, NULL, NULL); + test_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); + r=tor_addr_parse_mask_ports("3.4.16.032:1-2",0,&t1, &mask, &port1, &port2); + test_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); + test_assert(port1 == 1); + test_assert(port2 == 2); + r=tor_addr_parse_mask_ports("1.1.2.3/255.255.128.0",0,&t1, &mask,NULL,NULL); test_assert(r == AF_INET); - r=tor_addr_parse_mask_ports("[efef::]/112", &t1, &mask, &port1, &port2); + tt_int_op(mask,==,17); + tt_int_op(tor_addr_family(&t1),==,AF_INET); + tt_int_op(tor_addr_to_ipv4h(&t1),==,0x01010203); + r=tor_addr_parse_mask_ports("[efef::]/112",0,&t1, &mask, &port1, &port2); test_assert(r == AF_INET6); test_assert(port1 == 1); test_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); + /* 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); + 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); + 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_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); /* make sure inet address lengths >= max */ test_assert(INET_NTOA_BUF_LEN >= sizeof("255.255.255.255")); @@ -623,12 +721,65 @@ test_addr_ip6_helpers(void) ; } +/** Test tor_addr_port_parse(). */ +static void +test_addr_parse(void) +{ + int r; + tor_addr_t addr; + char buf[TOR_ADDR_BUF_LEN]; + uint16_t port = 0; + + /* Correct call. */ + r= tor_addr_port_parse(LOG_DEBUG, + "192.0.2.1:1234", + &addr, &port); + test_assert(r == 0); + tor_addr_to_str(buf, &addr, sizeof(buf), 0); + test_streq(buf, "192.0.2.1"); + test_eq(port, 1234); + + /* Domain name. */ + r= tor_addr_port_parse(LOG_DEBUG, + "torproject.org:1234", + &addr, &port); + test_assert(r == -1); + + /* Only IP. */ + r= tor_addr_port_parse(LOG_DEBUG, + "192.0.2.2", + &addr, &port); + test_assert(r == -1); + + /* Bad port. */ + r= tor_addr_port_parse(LOG_DEBUG, + "192.0.2.2:66666", + &addr, &port); + test_assert(r == -1); + + /* Only domain name */ + r= tor_addr_port_parse(LOG_DEBUG, + "torproject.org", + &addr, &port); + test_assert(r == -1); + + /* Bad IP address */ + r= tor_addr_port_parse(LOG_DEBUG, + "192.0.2:1234", + &addr, &port); + test_assert(r == -1); + + done: + ; +} + #define ADDR_LEGACY(name) \ { #name, legacy_test_helper, 0, &legacy_setup, test_addr_ ## name } struct testcase_t addr_tests[] = { ADDR_LEGACY(basic), ADDR_LEGACY(ip6_helpers), + ADDR_LEGACY(parse), END_OF_TESTCASES }; diff --git a/src/test/test_cell_formats.c b/src/test/test_cell_formats.c new file mode 100644 index 0000000000..4222c79d92 --- /dev/null +++ b/src/test/test_cell_formats.c @@ -0,0 +1,386 @@ +/* Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2012, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "orconfig.h" + +#define CONNECTION_EDGE_PRIVATE +#define RELAY_PRIVATE +#include "or.h" +#include "connection_edge.h" +#include "relay.h" +#include "test.h" + +#include <stdlib.h> +#include <string.h> + +static void +test_cfmt_relay_header(void *arg) +{ + relay_header_t rh; + const uint8_t hdr_1[RELAY_HEADER_SIZE] = + "\x03" "\x00\x00" "\x21\x22" "ABCD" "\x01\x03"; + uint8_t hdr_out[RELAY_HEADER_SIZE]; + (void)arg; + + tt_int_op(sizeof(hdr_1), ==, RELAY_HEADER_SIZE); + relay_header_unpack(&rh, hdr_1); + tt_int_op(rh.command, ==, 3); + tt_int_op(rh.recognized, ==, 0); + tt_int_op(rh.stream_id, ==, 0x2122); + test_mem_op(rh.integrity, ==, "ABCD", 4); + tt_int_op(rh.length, ==, 0x103); + + relay_header_pack(hdr_out, &rh); + test_mem_op(hdr_out, ==, hdr_1, RELAY_HEADER_SIZE); + + done: + ; +} + +static void +make_relay_cell(cell_t *out, uint8_t command, + const void *body, size_t bodylen) +{ + relay_header_t rh; + + memset(&rh, 0, sizeof(rh)); + rh.stream_id = 5; + rh.command = command; + rh.length = bodylen; + + out->command = CELL_RELAY; + out->circ_id = 10; + relay_header_pack(out->payload, &rh); + + memcpy(out->payload + RELAY_HEADER_SIZE, body, bodylen); +} + +static void +test_cfmt_begin_cells(void *arg) +{ + cell_t cell; + begin_cell_t bcell; + uint8_t end_reason; + (void)arg; + + /* Try begindir. */ + memset(&bcell, 0x7f, sizeof(bcell)); + make_relay_cell(&cell, RELAY_COMMAND_BEGIN_DIR, "", 0); + tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + tt_ptr_op(NULL, ==, bcell.address); + tt_int_op(0, ==, bcell.flags); + tt_int_op(0, ==, bcell.port); + tt_int_op(5, ==, bcell.stream_id); + tt_int_op(1, ==, bcell.is_begindir); + + /* A Begindir with extra stuff. */ + memset(&bcell, 0x7f, sizeof(bcell)); + make_relay_cell(&cell, RELAY_COMMAND_BEGIN_DIR, "12345", 5); + tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + tt_ptr_op(NULL, ==, bcell.address); + tt_int_op(0, ==, bcell.flags); + tt_int_op(0, ==, bcell.port); + tt_int_op(5, ==, bcell.stream_id); + tt_int_op(1, ==, bcell.is_begindir); + + /* A short but valid begin cell */ + memset(&bcell, 0x7f, sizeof(bcell)); + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:9", 6); + tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + tt_str_op("a.b", ==, bcell.address); + tt_int_op(0, ==, bcell.flags); + tt_int_op(9, ==, bcell.port); + tt_int_op(5, ==, bcell.stream_id); + tt_int_op(0, ==, bcell.is_begindir); + tor_free(bcell.address); + + /* A significantly loner begin cell */ + memset(&bcell, 0x7f, sizeof(bcell)); + { + const char c[] = "here-is-a-nice-long.hostname.com:65535"; + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, strlen(c)+1); + } + tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + tt_str_op("here-is-a-nice-long.hostname.com", ==, bcell.address); + tt_int_op(0, ==, bcell.flags); + tt_int_op(65535, ==, bcell.port); + tt_int_op(5, ==, bcell.stream_id); + tt_int_op(0, ==, bcell.is_begindir); + tor_free(bcell.address); + + /* An IPv4 begin cell. */ + memset(&bcell, 0x7f, sizeof(bcell)); + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "18.9.22.169:80", 15); + tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + tt_str_op("18.9.22.169", ==, bcell.address); + tt_int_op(0, ==, bcell.flags); + tt_int_op(80, ==, bcell.port); + tt_int_op(5, ==, bcell.stream_id); + tt_int_op(0, ==, bcell.is_begindir); + tor_free(bcell.address); + + /* An IPv6 begin cell. Let's make sure we handle colons*/ + memset(&bcell, 0x7f, sizeof(bcell)); + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, + "[2620::6b0:b:1a1a:0:26e5:480e]:80", 34); + tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + tt_str_op("[2620::6b0:b:1a1a:0:26e5:480e]", ==, bcell.address); + tt_int_op(0, ==, bcell.flags); + tt_int_op(80, ==, bcell.port); + tt_int_op(5, ==, bcell.stream_id); + tt_int_op(0, ==, bcell.is_begindir); + tor_free(bcell.address); + + /* a begin cell with extra junk but not enough for flags. */ + memset(&bcell, 0x7f, sizeof(bcell)); + { + const char c[] = "another.example.com:80\x00\x01\x02"; + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1); + } + tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + tt_str_op("another.example.com", ==, bcell.address); + tt_int_op(0, ==, bcell.flags); + tt_int_op(80, ==, bcell.port); + tt_int_op(5, ==, bcell.stream_id); + tt_int_op(0, ==, bcell.is_begindir); + tor_free(bcell.address); + + /* a begin cell with flags. */ + memset(&bcell, 0x7f, sizeof(bcell)); + { + const char c[] = "another.example.com:443\x00\x01\x02\x03\x04"; + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1); + } + tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + tt_str_op("another.example.com", ==, bcell.address); + tt_int_op(0x1020304, ==, bcell.flags); + tt_int_op(443, ==, bcell.port); + tt_int_op(5, ==, bcell.stream_id); + tt_int_op(0, ==, bcell.is_begindir); + tor_free(bcell.address); + + /* a begin cell with flags and even more cruft after that. */ + memset(&bcell, 0x7f, sizeof(bcell)); + { + const char c[] = "a-further.example.com:22\x00\xee\xaa\x00\xffHi mom"; + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, c, sizeof(c)-1); + } + tt_int_op(0, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + tt_str_op("a-further.example.com", ==, bcell.address); + tt_int_op(0xeeaa00ff, ==, bcell.flags); + tt_int_op(22, ==, bcell.port); + tt_int_op(5, ==, bcell.stream_id); + tt_int_op(0, ==, bcell.is_begindir); + tor_free(bcell.address); + + /* bad begin cell: impossible length. */ + memset(&bcell, 0x7f, sizeof(bcell)); + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:80", 7); + cell.payload[9] = 0x01; /* Set length to 510 */ + cell.payload[10] = 0xfe; + { + relay_header_t rh; + relay_header_unpack(&rh, cell.payload); + tt_int_op(rh.length, ==, 510); + } + tt_int_op(-2, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + + /* Bad begin cell: no body. */ + memset(&bcell, 0x7f, sizeof(bcell)); + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "", 0); + tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + + /* bad begin cell: no body. */ + memset(&bcell, 0x7f, sizeof(bcell)); + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "", 0); + tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + + /* bad begin cell: no colon */ + memset(&bcell, 0x7f, sizeof(bcell)); + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b", 4); + tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + + /* bad begin cell: no ports */ + memset(&bcell, 0x7f, sizeof(bcell)); + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:", 5); + tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + + /* bad begin cell: bad port */ + memset(&bcell, 0x7f, sizeof(bcell)); + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:xyz", 8); + tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + memset(&bcell, 0x7f, sizeof(bcell)); + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:100000", 11); + tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + + /* bad begin cell: no nul */ + memset(&bcell, 0x7f, sizeof(bcell)); + make_relay_cell(&cell, RELAY_COMMAND_BEGIN, "a.b:80", 6); + tt_int_op(-1, ==, begin_cell_parse(&cell, &bcell, &end_reason)); + + done: + tor_free(bcell.address); +} + +static void +test_cfmt_connected_cells(void *arg) +{ + relay_header_t rh; + cell_t cell; + tor_addr_t addr; + int ttl, r; + char *mem_op_hex_tmp = NULL; + (void)arg; + + /* Let's try an oldschool one with nothing in it. */ + make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "", 0); + relay_header_unpack(&rh, cell.payload); + r = connected_cell_parse(&rh, &cell, &addr, &ttl); + tt_int_op(r, ==, 0); + tt_int_op(tor_addr_family(&addr), ==, AF_UNSPEC); + tt_int_op(ttl, ==, -1); + + /* A slightly less oldschool one: only an IPv4 address */ + make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x20\x30\x40\x50", 4); + relay_header_unpack(&rh, cell.payload); + r = connected_cell_parse(&rh, &cell, &addr, &ttl); + tt_int_op(r, ==, 0); + tt_int_op(tor_addr_family(&addr), ==, AF_INET); + tt_str_op(fmt_addr(&addr), ==, "32.48.64.80"); + tt_int_op(ttl, ==, -1); + + /* Bogus but understandable: truncated TTL */ + make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x11\x12\x13\x14\x15", 5); + relay_header_unpack(&rh, cell.payload); + r = connected_cell_parse(&rh, &cell, &addr, &ttl); + tt_int_op(r, ==, 0); + tt_int_op(tor_addr_family(&addr), ==, AF_INET); + tt_str_op(fmt_addr(&addr), ==, "17.18.19.20"); + tt_int_op(ttl, ==, -1); + + /* Regular IPv4 one: address and TTL */ + make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, + "\x02\x03\x04\x05\x00\x00\x0e\x10", 8); + relay_header_unpack(&rh, cell.payload); + r = connected_cell_parse(&rh, &cell, &addr, &ttl); + tt_int_op(r, ==, 0); + tt_int_op(tor_addr_family(&addr), ==, AF_INET); + tt_str_op(fmt_addr(&addr), ==, "2.3.4.5"); + tt_int_op(ttl, ==, 3600); + + /* IPv4 with too-big TTL */ + make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, + "\x02\x03\x04\x05\xf0\x00\x00\x00", 8); + relay_header_unpack(&rh, cell.payload); + r = connected_cell_parse(&rh, &cell, &addr, &ttl); + tt_int_op(r, ==, 0); + tt_int_op(tor_addr_family(&addr), ==, AF_INET); + tt_str_op(fmt_addr(&addr), ==, "2.3.4.5"); + tt_int_op(ttl, ==, -1); + + /* IPv6 (ttl is mandatory) */ + make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, + "\x00\x00\x00\x00\x06" + "\x26\x07\xf8\xb0\x40\x0c\x0c\x02" + "\x00\x00\x00\x00\x00\x00\x00\x68" + "\x00\x00\x02\x58", 25); + relay_header_unpack(&rh, cell.payload); + r = connected_cell_parse(&rh, &cell, &addr, &ttl); + tt_int_op(r, ==, 0); + tt_int_op(tor_addr_family(&addr), ==, AF_INET6); + tt_str_op(fmt_addr(&addr), ==, "2607:f8b0:400c:c02::68"); + tt_int_op(ttl, ==, 600); + + /* IPv6 (ttl too big) */ + make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, + "\x00\x00\x00\x00\x06" + "\x26\x07\xf8\xb0\x40\x0c\x0c\x02" + "\x00\x00\x00\x00\x00\x00\x00\x68" + "\x90\x00\x02\x58", 25); + relay_header_unpack(&rh, cell.payload); + r = connected_cell_parse(&rh, &cell, &addr, &ttl); + tt_int_op(r, ==, 0); + tt_int_op(tor_addr_family(&addr), ==, AF_INET6); + tt_str_op(fmt_addr(&addr), ==, "2607:f8b0:400c:c02::68"); + tt_int_op(ttl, ==, -1); + + /* Bogus size: 3. */ + make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, + "\x00\x01\x02", 3); + relay_header_unpack(&rh, cell.payload); + r = connected_cell_parse(&rh, &cell, &addr, &ttl); + tt_int_op(r, ==, -1); + + /* Bogus family: 7. */ + make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, + "\x00\x00\x00\x00\x07" + "\x26\x07\xf8\xb0\x40\x0c\x0c\x02" + "\x00\x00\x00\x00\x00\x00\x00\x68" + "\x90\x00\x02\x58", 25); + relay_header_unpack(&rh, cell.payload); + r = connected_cell_parse(&rh, &cell, &addr, &ttl); + tt_int_op(r, ==, -1); + + /* Truncated IPv6. */ + make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, + "\x00\x00\x00\x00\x06" + "\x26\x07\xf8\xb0\x40\x0c\x0c\x02" + "\x00\x00\x00\x00\x00\x00\x00\x68" + "\x00\x00\x02", 24); + relay_header_unpack(&rh, cell.payload); + r = connected_cell_parse(&rh, &cell, &addr, &ttl); + tt_int_op(r, ==, -1); + + /* Now make sure we can generate connected cells correctly. */ + /* Try an IPv4 address */ + memset(&rh, 0, sizeof(rh)); + memset(&cell, 0, sizeof(cell)); + tor_addr_parse(&addr, "30.40.50.60"); + rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE, + &addr, 128); + tt_int_op(rh.length, ==, 8); + test_memeq_hex(cell.payload+RELAY_HEADER_SIZE, "1e28323c" "00000080"); + + /* Try parsing it. */ + tor_addr_make_unspec(&addr); + r = connected_cell_parse(&rh, &cell, &addr, &ttl); + tt_int_op(r, ==, 0); + tt_int_op(tor_addr_family(&addr), ==, AF_INET); + tt_str_op(fmt_addr(&addr), ==, "30.40.50.60"); + tt_int_op(ttl, ==, 128); + + /* Try an IPv6 address */ + memset(&rh, 0, sizeof(rh)); + memset(&cell, 0, sizeof(cell)); + tor_addr_parse(&addr, "2620::6b0:b:1a1a:0:26e5:480e"); + rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE, + &addr, 3600); + tt_int_op(rh.length, ==, 25); + test_memeq_hex(cell.payload + RELAY_HEADER_SIZE, + "00000000" "06" + "2620000006b0000b1a1a000026e5480e" "00000e10"); + + /* Try parsing it. */ + tor_addr_make_unspec(&addr); + r = connected_cell_parse(&rh, &cell, &addr, &ttl); + tt_int_op(r, ==, 0); + tt_int_op(tor_addr_family(&addr), ==, AF_INET6); + tt_str_op(fmt_addr(&addr), ==, "2620:0:6b0:b:1a1a:0:26e5:480e"); + tt_int_op(ttl, ==, 3600); + + done: + tor_free(mem_op_hex_tmp); +} + +#define TEST(name, flags) \ + { #name, test_cfmt_ ## name, flags, 0, NULL } + +struct testcase_t cell_format_tests[] = { + TEST(relay_header, 0), + TEST(begin_cells, 0), + TEST(connected_cells, 0), + END_OF_TESTCASES +}; + diff --git a/src/test/test_config.c b/src/test/test_config.c index d9fcd8b35b..e04b9dfc2e 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -5,6 +5,7 @@ #include "orconfig.h" #include "or.h" +#include "addressmap.h" #include "config.h" #include "confparse.h" #include "connection_edge.h" diff --git a/src/test/test_dir.c b/src/test/test_dir.c index 9bf44b116b..ff41bf2f3f 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -223,24 +223,6 @@ test_dir_formats(void) add_fingerprint_to_dir("Fred", buf, fingerprint_list); } - { - char d[DIGEST_LEN]; - const char *m; - /* XXXX NM re-enable. */ - /* Make sure routers aren't too far in the past any more. */ - r1->cache_info.published_on = time(NULL); - r2->cache_info.published_on = time(NULL)-3*60*60; - test_assert(router_dump_router_to_string(buf, 2048, r1, pk2)>0); - test_eq(dirserv_add_descriptor(buf,&m,""), ROUTER_ADDED_NOTIFY_GENERATOR); - test_assert(router_dump_router_to_string(buf, 2048, r2, pk1)>0); - test_eq(dirserv_add_descriptor(buf,&m,""), ROUTER_ADDED_NOTIFY_GENERATOR); - get_options()->Nickname = tor_strdup("DirServer"); - test_assert(!dirserv_dump_directory_to_string(&cp,pk3, 0)); - crypto_pk_get_digest(pk3, d); - test_assert(!router_parse_directory(cp)); - test_eq(2, smartlist_len(dir1->routers)); - tor_free(cp); - } #endif dirserv_free_fingerprint_list(); diff --git a/src/test/test_util.c b/src/test/test_util.c index 02a00d0ac8..3ed2cbb54d 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -2290,7 +2290,7 @@ test_util_load_win_lib(void *ptr) tt_assert(h); done: if (h) - CloseHandle(h); + FreeLibrary(h); } #endif |