diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-04-10 15:32:26 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-04-10 15:32:26 -0400 |
commit | 6bdfaa8b244ca3e10e57f6d99616af1d5f68fa67 (patch) | |
tree | a729843d38786f76d0314e14141a359c269cbc97 | |
parent | 6e467a7a340cdc0267206ebaf8dca54c1a4a7b0a (diff) | |
parent | 4178642bf83736d154176623ba8dce845a5b412c (diff) | |
download | tor-6bdfaa8b244ca3e10e57f6d99616af1d5f68fa67.tar.gz tor-6bdfaa8b244ca3e10e57f6d99616af1d5f68fa67.zip |
Merge remote-tracking branch 'isis-github/bug25425_squashed2'
-rw-r--r-- | changes/bug25425 | 4 | ||||
-rw-r--r-- | src/or/bridges.c | 10 | ||||
-rw-r--r-- | src/or/bridges.h | 13 | ||||
-rw-r--r-- | src/or/transports.c | 6 | ||||
-rw-r--r-- | src/or/transports.h | 5 | ||||
-rw-r--r-- | src/test/include.am | 1 | ||||
-rw-r--r-- | src/test/test.c | 1 | ||||
-rw-r--r-- | src/test/test.h | 9 | ||||
-rw-r--r-- | src/test/test_bridges.c | 618 |
9 files changed, 658 insertions, 9 deletions
diff --git a/changes/bug25425 b/changes/bug25425 new file mode 100644 index 0000000000..41f1a47b15 --- /dev/null +++ b/changes/bug25425 @@ -0,0 +1,4 @@ + o Minor features (testing): + - A new unittests module specifically for testing the functions in the + (new-ish) bridges.c module has been created with new unittests, raising + the code coverage percentages. Closes 25425. diff --git a/src/or/bridges.c b/src/or/bridges.c index 29d00f37ba..699e030e6c 100644 --- a/src/or/bridges.c +++ b/src/or/bridges.c @@ -11,6 +11,8 @@ * Bridges are fixed entry nodes, used for censorship circumvention. **/ +#define TOR_BRIDGES_PRIVATE + #include "or.h" #include "bridges.h" #include "circuitbuild.h" @@ -93,7 +95,7 @@ sweep_bridge_list(void) } /** Initialize the bridge list to empty, creating it if needed. */ -static void +STATIC void clear_bridge_list(void) { if (!bridge_list) @@ -156,7 +158,7 @@ bridge_get_addr_port(const bridge_info_t *bridge) * bridge with no known digest whose address matches any of the * tor_addr_port_t's in <b>orports</b>, return that bridge. Else return * NULL. */ -static bridge_info_t * +STATIC bridge_info_t * get_configured_bridge_by_orports_digest(const char *digest, const smartlist_t *orports) { @@ -350,7 +352,7 @@ bridge_has_digest(const bridge_info_t *bridge, const char *digest) * existing bridge with the same address and port, and warn the user as * appropriate. */ -static void +STATIC void bridge_resolve_conflicts(const tor_addr_t *addr, uint16_t port, const char *digest, const char *transport_name) { @@ -471,7 +473,7 @@ bridge_add_from_config(bridge_line_t *bridge_line) } /** If <b>digest</b> is one of our known bridges, return it. */ -bridge_info_t * +STATIC bridge_info_t * find_bridge_by_digest(const char *digest) { if (! bridge_list) diff --git a/src/or/bridges.h b/src/or/bridges.h index 54a6250259..3108eb555d 100644 --- a/src/or/bridges.h +++ b/src/or/bridges.h @@ -20,7 +20,6 @@ typedef struct bridge_info_t bridge_info_t; void mark_bridge_list(void); void sweep_bridge_list(void); const smartlist_t *bridge_list_get(void); -bridge_info_t *find_bridge_by_digest(const char *digest); const uint8_t *bridge_get_rsa_id_digest(const bridge_info_t *bridge); const tor_addr_port_t * bridge_get_addr_port(const bridge_info_t *bridge); bridge_info_t *get_configured_bridge_by_addr_port_digest( @@ -65,5 +64,17 @@ MOCK_DECL(download_status_t *, get_bridge_dl_status_by_id, void bridges_free_all(void); +#ifdef TOR_BRIDGES_PRIVATE +STATIC void clear_bridge_list(void); +STATIC bridge_info_t *find_bridge_by_digest(const char *digest); +STATIC bridge_info_t *get_configured_bridge_by_orports_digest( + const char *digest, + const smartlist_t *orports); +STATIC void bridge_resolve_conflicts(const tor_addr_t *addr, + uint16_t port, + const char *digest, + const char *transport_name); +#endif /* defined(TOR_BRIDGES_PRIVATE) */ + #endif /* !defined(TOR_BRIDGES_H) */ diff --git a/src/or/transports.c b/src/or/transports.c index 5cbf1ddbc1..614fc81da8 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -135,7 +135,7 @@ static smartlist_t *transport_list = NULL; /** Returns a transport_t struct for a transport proxy supporting the protocol <b>name</b> listening at <b>addr</b>:<b>port</b> using SOCKS version <b>socks_ver</b>. */ -static transport_t * +STATIC transport_t * transport_new(const tor_addr_t *addr, uint16_t port, const char *name, int socks_ver, const char *extra_info_args) @@ -222,8 +222,8 @@ transport_copy(const transport_t *transport) /** Returns the transport in our transport list that has the name <b>name</b>. * Else returns NULL. */ -transport_t * -transport_get_by_name(const char *name) +MOCK_IMPL(transport_t *, +transport_get_by_name,(const char *name)) { tor_assert(name); diff --git a/src/or/transports.h b/src/or/transports.h index 1b2786472c..022b926a03 100644 --- a/src/or/transports.h +++ b/src/or/transports.h @@ -38,7 +38,7 @@ MOCK_DECL(int, transport_add_from_config, void transport_free_(transport_t *transport); #define transport_free(tr) FREE_AND_NULL(transport_t, transport_free_, (tr)) -transport_t *transport_get_by_name(const char *name); +MOCK_DECL(transport_t*, transport_get_by_name, (const char *name)); MOCK_DECL(void, pt_kickstart_proxy, (const smartlist_t *transport_list, char **proxy_argv, @@ -113,6 +113,9 @@ typedef struct { smartlist_t *transports; } managed_proxy_t; +STATIC transport_t *transport_new(const tor_addr_t *addr, uint16_t port, + const char *name, int socks_ver, + const char *extra_info_args); STATIC int parse_cmethod_line(const char *line, managed_proxy_t *mp); STATIC int parse_smethod_line(const char *line, managed_proxy_t *mp); diff --git a/src/test/include.am b/src/test/include.am index e98b056a44..a663fa5524 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -88,6 +88,7 @@ src_test_test_SOURCES = \ src/test/test_addr.c \ src/test/test_address.c \ src/test/test_address_set.c \ + src/test/test_bridges.c \ src/test/test_buffers.c \ src/test/test_cell_formats.c \ src/test/test_cell_queue.c \ diff --git a/src/test/test.c b/src/test/test.c index 4f2fbc693a..f90669b5dd 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -811,6 +811,7 @@ struct testgroup_t testgroups[] = { { "addr/", addr_tests }, { "address/", address_tests }, { "address_set/", address_set_tests }, + { "bridges/", bridges_tests }, { "buffer/", buffer_tests }, { "cellfmt/", cell_format_tests }, { "cellqueue/", cell_queue_tests }, diff --git a/src/test/test.h b/src/test/test.h index 02ec9bda89..34c6e46427 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -72,6 +72,14 @@ I64_PRINTF_TYPE, I64_FORMAT, \ {print_ = (I64_PRINTF_TYPE) value_;}, {}, TT_EXIT_TEST_FUNCTION) +/** + * Declare that the test is done, even though no tt___op() calls were made. + * + * For use when you only want to test calling something, but not check + * any values/pointers/etc afterwards. + */ +#define tt_finished() TT_EXIT_TEST_FUNCTION + const char *get_fname(const char *name); const char *get_fname_rnd(const char *name); struct crypto_pk_t *pk_generate(int idx); @@ -178,6 +186,7 @@ extern struct testcase_t accounting_tests[]; extern struct testcase_t addr_tests[]; extern struct testcase_t address_tests[]; extern struct testcase_t address_set_tests[]; +extern struct testcase_t bridges_tests[]; extern struct testcase_t buffer_tests[]; extern struct testcase_t cell_format_tests[]; extern struct testcase_t cell_queue_tests[]; diff --git a/src/test/test_bridges.c b/src/test/test_bridges.c new file mode 100644 index 0000000000..b5bd27e098 --- /dev/null +++ b/src/test/test_bridges.c @@ -0,0 +1,618 @@ +/* Copyright (c) 2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file test_bridges.c + * \brief Unittests for code in src/or/bridges.c + **/ + +#define TOR_BRIDGES_PRIVATE +#define PT_PRIVATE /* Only needed for the mock_* items below */ + +#include <stdbool.h> + +#include "or.h" +#include "address.h" +#include "bridges.h" +#include "config.h" +#include "container.h" +#include "transports.h" +#include "util.h" + +/* Test suite stuff */ +#include "test.h" + +/** + * A mocked transport_t, constructed via mock_transport_get_by_name(). + */ +static transport_t *mock_transport = NULL; + +/** + * Mock transport_get_by_name() to simply return a transport_t for the + * transport name that was input to it. + */ +static transport_t * +mock_transport_get_by_name(const char *name) +{ + tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); + uint16_t port = 9999; + int socksv = 9; + char *args = tor_strdup("foo=bar"); + + if (!mock_transport) { + tor_addr_parse(addr, "99.99.99.99"); + mock_transport = transport_new(addr, port, name, socksv, args); + } + + tor_free(addr); + tor_free(args); + + return mock_transport; +} + +#undef PT_PRIVATE /* defined(PT_PRIVATE) */ + +/** + * Test helper: Add a variety of bridges to our global bridgelist. + */ +static void +helper_add_bridges_to_bridgelist(void *arg) +{ + /* Note: the two bridges which do not have specified fingerprints will be + * internally stored as both having the same fingerprint of all-zero bytes. + */ + + (void)arg; + char *bridge0 = tor_strdup("6.6.6.6:6666"); + char *bridge1 = tor_strdup("6.6.6.7:6667 " + "A10C4F666D27364036B562823E5830BC448E046A"); + char *bridge2 = tor_strdup("obfs4 198.245.60.51:443 " + "752CF7825B3B9EA6A98C83AC41F7099D67007EA5 " + "cert=xpmQtKUqQ/6v5X7ijgYE/f03+l2/EuQ1dexjyUhh16wQlu/" + "cpXUGalmhDIlhuiQPNEKmKw iat-mode=0"); + char *bridge3 = tor_strdup("banana 5.5.5.5:5555 " + "9D6AE1BD4FDF39721CE908966E79E16F9BFCCF2F"); + char *bridge4 = tor_strdup("obfs4 1.2.3.4:1234 " + "foo=abcdefghijklmnopqrstuvwxyz"); + char *bridge5 = tor_strdup("apple 4.4.4.4:4444 " + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA " + "foo=abcdefghijklmnopqrstuvwxyz"); + + mark_bridge_list(); + +#define ADD_BRIDGE(bridge) \ + bridge_line_t *bridge_line_ ##bridge = parse_bridge_line(bridge); \ + if (!bridge_line_ ##bridge) { \ + printf("Unparseable bridge line: '%s'", #bridge); \ + } else { \ + bridge_add_from_config(bridge_line_ ##bridge); \ + } \ + tor_free(bridge); + + ADD_BRIDGE(bridge0); + ADD_BRIDGE(bridge1); + ADD_BRIDGE(bridge2); + ADD_BRIDGE(bridge3); + ADD_BRIDGE(bridge4); + ADD_BRIDGE(bridge5); +#undef ADD_BRIDGES + + sweep_bridge_list(); +} + +/** + * Make sure our test helper works too. + */ +static void +test_bridges_helper_func_add_bridges_to_bridgelist(void *arg) +{ + helper_add_bridges_to_bridgelist(arg); + tt_finished(); + + done: + mark_bridge_list(); + sweep_bridge_list(); +} + +/** + * Calling bridge_list_get() should create a new bridgelist if we + * didn't have one before. + */ +static void +test_bridges_bridge_list_get_creates_new_bridgelist(void *arg) +{ + const smartlist_t *bridgelist = bridge_list_get(); + + (void)arg; + + tt_ptr_op(bridgelist, OP_NE, NULL); + + done: + return; +} + +/** + * Calling clear_bridge_list() should remove all bridges from the bridgelist. + */ +static void +test_bridges_clear_bridge_list(void *arg) +{ + const smartlist_t *bridgelist; + const smartlist_t *bridgelist_after; + const bridge_info_t *bridge; + const bridge_info_t *bridge_after; + + helper_add_bridges_to_bridgelist(arg); + bridgelist = bridge_list_get(); + tt_ptr_op(bridgelist, OP_NE, NULL); + + bridge = smartlist_get(bridgelist, 0); + tt_ptr_op(bridge, OP_NE, NULL); + + clear_bridge_list(); + bridgelist_after = bridge_list_get(); + tt_ptr_op(bridgelist_after, OP_NE, NULL); + + bridge_after = smartlist_get(bridgelist, 0); + // There now shouldn't be a first bridge + tt_ptr_op(bridge_after, OP_EQ, NULL); + + done: + return; +} + +/** + * Calling bridge_get_addrport() should give me the address and port + * of the bridge. In this case, we sort the smartlist of bridges on + * fingerprints and choose the first one. + */ +static void +test_bridges_bridge_get_addrport(void *arg) +{ + smartlist_t *bridgelist; + const bridge_info_t *bridge; + const tor_addr_port_t *addrport; + + helper_add_bridges_to_bridgelist(arg); + bridgelist = (smartlist_t*)bridge_list_get(); + tt_ptr_op(bridgelist, OP_NE, NULL); + + // This should be the bridge at 6.6.6.6:6666 with fingerprint + // 0000000000000000000000000000000000000000 + bridge = smartlist_get(bridgelist, 0); + tt_ptr_op(bridge, OP_NE, NULL); + + addrport = bridge_get_addr_port(bridge); + tt_int_op(addrport->port, OP_EQ, 6666); + + done: + mark_bridge_list(); + sweep_bridge_list(); +} + +/** + * Calling get_configured_bridge_by_orports_digest() with two + * configured bridge orports and an invalid digest should return the + * bridge of the first addrport in the list. + */ +static void +test_bridges_get_configured_bridge_by_orports_digest(void *arg) +{ + smartlist_t *orports = NULL; + const smartlist_t *bridgelist; + const bridge_info_t *bridge1; + const bridge_info_t *bridge2; + const bridge_info_t *ret; + tor_addr_port_t *addrport1; + tor_addr_port_t *addrport2; + const char *digest; + + helper_add_bridges_to_bridgelist(arg); + bridgelist = bridge_list_get(); + tt_ptr_op(bridgelist, OP_NE, NULL); + + // This should be the bridge at 6.6.6.6:6666 with fingerprint + // 0000000000000000000000000000000000000000 + bridge1 = smartlist_get(bridgelist, 0); + tt_ptr_op(bridge1, OP_NE, NULL); + // This should be the bridge at 6.6.6.7:6667 with fingerprint + // A10C4F666D27364036B562823E5830BC448E046A + bridge2 = smartlist_get(bridgelist, 1); + tt_ptr_op(bridge2, OP_NE, NULL); + + addrport1 = (tor_addr_port_t*)bridge_get_addr_port(bridge1); + tt_int_op(addrport1->port, OP_EQ, 6666); + addrport2 = (tor_addr_port_t*)bridge_get_addr_port(bridge2); + tt_int_op(addrport2->port, OP_EQ, 6667); + + orports = smartlist_new(); + smartlist_add(orports, addrport1); + smartlist_add(orports, addrport2); + + digest = "zzzzzzzzzzzzzzzz"; + + ret = get_configured_bridge_by_orports_digest(digest, orports); + tt_ptr_op(ret, OP_NE, NULL); + + tt_mem_op(addrport1, OP_EQ, bridge_get_addr_port(ret), sizeof(ret)); + + done: + smartlist_free(orports); + + mark_bridge_list(); + sweep_bridge_list(); +} + +/** + * Calling get_configured_bridge_by_addr_port_digest() with a digest that we do + * have and an addr:port pair we don't should return the bridge for that + * digest. + */ +static void +test_bridges_get_configured_bridge_by_addr_port_digest_digest_only(void *arg) +{ + char digest[DIGEST_LEN]; + bridge_info_t *bridge; + const char fingerprint[HEX_DIGEST_LEN] = + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); + char ret_addr[16]; + uint16_t port = 11111; + int ret; + + helper_add_bridges_to_bridgelist(arg); + + // We don't actually have a bridge with this addr:port pair + base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN); + ret = tor_addr_parse(addr, "111.111.111.111"); + tt_int_op(ret, OP_EQ, 2); // it returns the address family on success + + bridge = get_configured_bridge_by_addr_port_digest(addr, port, digest); + tt_ptr_op(bridge, OP_NE, NULL); + + tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0); + tt_str_op("4.4.4.4", OP_EQ, ret_addr); + + done: + tor_free(addr); + + mark_bridge_list(); + sweep_bridge_list(); +} + +/** + * Calling get_configured_bridge_by_addr_port_digest() with only an + * addr:port (i.e. digest set to NULL) should return the bridge for + * that digest when there is such a bridge. + */ +static void +test_bridges_get_configured_bridge_by_addr_port_digest_address_only(void *arg) +{ + bridge_info_t *bridge; + tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); + char ret_addr[16]; + uint16_t port = 6666; + int ret; + + helper_add_bridges_to_bridgelist(arg); + + ret = tor_addr_parse(addr, "6.6.6.6"); + tt_int_op(ret, OP_EQ, 2); // it returns the address family on success + + bridge = get_configured_bridge_by_addr_port_digest(addr, port, NULL); + tt_ptr_op(bridge, OP_NE, NULL); + + tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0); + tt_str_op("6.6.6.6", OP_EQ, ret_addr); + + done: + tor_free(addr); + + mark_bridge_list(); + sweep_bridge_list(); +} + +/** + * Calling get_configured_bridge_by_exact_addr_port_digest() with a digest that + * we do have, and an addr:port pair we don't have, should return NULL. + */ +static void +test_bridges_get_configured_bridge_by_exact_addr_port_digest_donly(void *arg) +{ + char digest[DIGEST_LEN]; + bridge_info_t *bridge; + const char fingerprint[HEX_DIGEST_LEN] = + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); + uint16_t port = 11111; + int ret; + + helper_add_bridges_to_bridgelist(arg); + + // We don't actually have a bridge with this addr:port pair + base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN); + ret = tor_addr_parse(addr, "111.111.111.111"); + tt_int_op(ret, OP_EQ, 2); // it returns the address family on success + + bridge = get_configured_bridge_by_exact_addr_port_digest(addr, port, digest); + tt_ptr_op(bridge, OP_EQ, NULL); + + done: + tor_free(addr); + + mark_bridge_list(); + sweep_bridge_list(); +} + +/** + * Calling get_configured_bridge_by_exact_addr_port_digest() with a digest that + * we do have, and an addr:port pair we do have, should return the bridge. + */ +static void +test_bridges_get_configured_bridge_by_exact_addr_port_digest_both(void *arg) +{ + char digest[DIGEST_LEN]; + bridge_info_t *bridge; + const char fingerprint[HEX_DIGEST_LEN] = + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); + uint16_t port = 4444; + char ret_addr[16]; + int ret; + + helper_add_bridges_to_bridgelist(arg); + + base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN); + ret = tor_addr_parse(addr, "4.4.4.4"); + tt_int_op(ret, OP_EQ, 2); // it returns the address family on success + + bridge = get_configured_bridge_by_exact_addr_port_digest(addr, port, digest); + tt_ptr_op(bridge, OP_NE, NULL); + + tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0); + tt_str_op("4.4.4.4", OP_EQ, ret_addr); + + done: + tor_free(addr); + + mark_bridge_list(); + sweep_bridge_list(); +} + +/** + * Calling get_configured_bridge_by_exact_addr_port_digest() with no digest, + * and an addr:port pair we do have, should return the bridge. + */ +static void +test_bridges_get_configured_bridge_by_exact_addr_port_digest_aonly(void *arg) +{ + bridge_info_t *bridge; + tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); + uint16_t port = 4444; + char ret_addr[16]; + int ret; + + helper_add_bridges_to_bridgelist(arg); + + ret = tor_addr_parse(addr, "4.4.4.4"); + tt_int_op(ret, OP_EQ, 2); // it returns the address family on success + + bridge = get_configured_bridge_by_exact_addr_port_digest(addr, port, NULL); + tt_ptr_op(bridge, OP_NE, NULL); + + tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0); + tt_str_op("4.4.4.4", OP_EQ, ret_addr); + + done: + tor_free(addr); + + mark_bridge_list(); + sweep_bridge_list(); +} + +/** + * Calling find_bridge_by_digest() when we have a bridge with a known + * identity digest should return the bridge's information. + */ +static void +test_bridges_find_bridge_by_digest_known(void *arg) +{ + char digest1[DIGEST_LEN]; + bridge_info_t *bridge; + const char fingerprint[HEX_DIGEST_LEN] = + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + + helper_add_bridges_to_bridgelist(arg); + + base16_decode(digest1, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN); + bridge = find_bridge_by_digest(digest1); + + tt_ptr_op(bridge, OP_NE, NULL); + + /* We have to call bridge_get_rsa_id_digest() here because the bridge_info_t + * struct is opaquely defined in bridges.h. */ + const uint8_t *digest2 = bridge_get_rsa_id_digest(bridge); + + tt_mem_op((char*)digest2, OP_EQ, digest1, DIGEST_LEN); + + done: + mark_bridge_list(); + sweep_bridge_list(); +} + +/** + * Calling find_bridge_by_digest() when we do NOT have a bridge with that + * identity digest should return NULL. + */ +static void +test_bridges_find_bridge_by_digest_unknown(void *arg) +{ + const char *fingerprint = "cccccccccccccccccccccccccccccccccccccccc"; + bridge_info_t *bridge; + + helper_add_bridges_to_bridgelist(arg); + + bridge = find_bridge_by_digest(fingerprint); + + tt_ptr_op(bridge, OP_EQ, NULL); + + done: + mark_bridge_list(); + sweep_bridge_list(); +} + +/** + * Calling bridge_resolve_conflicts() with an identical bridge to one we've + * already configure should mark the pre-configured bridge for removal. + */ +static void +test_bridges_bridge_resolve_conflicts(void *arg) +{ + tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); + uint16_t port = 4444; + const char *digest = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + const char *transport = "apple"; + int ret; + + helper_add_bridges_to_bridgelist(arg); + + ret = tor_addr_parse(addr, "4.4.4.4"); + tt_int_op(ret, OP_EQ, 2); // it returns the address family on success + + bridge_resolve_conflicts((const tor_addr_t*)addr, port, digest, transport); + + /* The bridge should now be marked for removal, and removed when we sweep the + * bridge_list */ + sweep_bridge_list(); + ret = addr_is_a_configured_bridge((const tor_addr_t*)addr, port, digest); + tt_int_op(ret, OP_EQ, 0); + + done: + tor_free(addr); + + mark_bridge_list(); + sweep_bridge_list(); +} + +/** + * Calling transport_is_needed() with a transport we do need ("obfs4") and a + * bogus transport that we don't need should return 1 and 0, respectively. + */ +static void +test_bridges_transport_is_needed(void *arg) +{ + int ret; + + helper_add_bridges_to_bridgelist(arg); + + ret = transport_is_needed("obfs4"); + tt_int_op(ret, OP_EQ, 1); + + ret = transport_is_needed("apowefjaoewpaief"); + tt_int_op(ret, OP_EQ, 0); + + done: + mark_bridge_list(); + sweep_bridge_list(); +} + +/** + * Calling get_transport_by_bridge_addrport() with the address and port of a + * configured bridge which uses a pluggable transport when there is no global + * transport_list should return -1 and the transport_t should be NULL. + */ +static void +test_bridges_get_transport_by_bridge_addrport_no_ptlist(void *arg) +{ + transport_t *transport = NULL; + tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); + uint16_t port = 1234; + int ret; + + helper_add_bridges_to_bridgelist(arg); + + ret = tor_addr_parse(addr, "1.2.3.4"); + tt_int_op(ret, OP_EQ, 2); // it returns the address family on success? + + /* This will fail because the global transport_list has nothing in it, and so + * transport_get_by_name() has nothing to return, even the the bridge *did* + * say it had an obfs4 transport. + */ + ret = get_transport_by_bridge_addrport((const tor_addr_t*)addr, port, + (const transport_t**)&transport); + tt_int_op(ret, OP_EQ, -1); // returns -1 on failure + tt_ptr_op(transport, OP_EQ, NULL); + + done: + tor_free(addr); + + mark_bridge_list(); + sweep_bridge_list(); +} + +#define PT_PRIVATE + +/** + * Calling get_transport_by_bridge_addrport() with the address and port of a + * configured bridge which uses a pluggable transport should return 0 and set + * appropriate transport_t. + */ +static void +test_bridges_get_transport_by_bridge_addrport(void *arg) +{ + transport_t *transport = NULL; + tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t)); + uint16_t port = 1234; + int ret; + + helper_add_bridges_to_bridgelist(arg); + mark_transport_list(); // Also initialise our transport_list + + ret = tor_addr_parse(addr, "1.2.3.4"); + tt_int_op(ret, OP_EQ, 2); // it returns the address family on success? + + /* After we mock transport_get_by_name() to return a bogus transport_t with + * the name it was asked for, the call should succeed. + */ + MOCK(transport_get_by_name, mock_transport_get_by_name); + ret = get_transport_by_bridge_addrport((const tor_addr_t*)addr, port, + (const transport_t**)&transport); + tt_int_op(ret, OP_EQ, 0); // returns 0 on success + tt_ptr_op(transport, OP_NE, NULL); + tt_str_op(transport->name, OP_EQ, "obfs4"); + + done: + UNMOCK(transport_get_by_name); + + tor_free(addr); + transport_free(transport); + + mark_bridge_list(); + sweep_bridge_list(); +} + +#undef PT_PRIVATE /* defined(PT_PRIVATE) */ + +#define B_TEST(name, flags) \ + { #name, test_bridges_ ##name, (flags), NULL, NULL } + +struct testcase_t bridges_tests[] = { + B_TEST(helper_func_add_bridges_to_bridgelist, 0), + B_TEST(bridge_list_get_creates_new_bridgelist, 0), + B_TEST(clear_bridge_list, 0), + B_TEST(bridge_get_addrport, 0), + B_TEST(get_configured_bridge_by_orports_digest, 0), + B_TEST(get_configured_bridge_by_addr_port_digest_digest_only, 0), + B_TEST(get_configured_bridge_by_addr_port_digest_address_only, 0), + B_TEST(get_configured_bridge_by_exact_addr_port_digest_donly, 0), + B_TEST(get_configured_bridge_by_exact_addr_port_digest_both, 0), + B_TEST(get_configured_bridge_by_exact_addr_port_digest_aonly, 0), + B_TEST(find_bridge_by_digest_known, 0), + B_TEST(find_bridge_by_digest_unknown, 0), + B_TEST(bridge_resolve_conflicts, 0), + B_TEST(get_transport_by_bridge_addrport_no_ptlist, 0), + B_TEST(get_transport_by_bridge_addrport, 0), + B_TEST(transport_is_needed, 0), + END_OF_TESTCASES +}; + |