diff options
author | Nick Mathewson <nickm@torproject.org> | 2017-09-11 09:50:31 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-09-11 09:50:31 -0400 |
commit | 362bc880b1c4bbccba8698b872c16fc6a6da168e (patch) | |
tree | 243c1f3f2d07859811db59180994419adc3784ca | |
parent | 67a5d4cb60a9f27e981b83195cf47183a7e9abcc (diff) | |
download | tor-362bc880b1c4bbccba8698b872c16fc6a6da168e.tar.gz tor-362bc880b1c4bbccba8698b872c16fc6a6da168e.zip |
Add a function to check for support for "protocol X or later"
Also, add unit tests for this new function and for the regular
"does this list include support for protocol X" code.
-rw-r--r-- | src/or/protover.c | 36 | ||||
-rw-r--r-- | src/or/protover.h | 3 | ||||
-rw-r--r-- | src/test/test_protover.c | 30 |
3 files changed, 69 insertions, 0 deletions
diff --git a/src/or/protover.c b/src/or/protover.c index 1a3e69be10..5aaf4f4c34 100644 --- a/src/or/protover.c +++ b/src/or/protover.c @@ -280,6 +280,42 @@ protocol_list_supports_protocol(const char *list, protocol_type_t tp, return contains; } +/** + * Return true iff "list" encodes a protocol list that includes support for + * the indicated protocol and version, or some later version. + */ +int +protocol_list_supports_protocol_or_later(const char *list, + protocol_type_t tp, + uint32_t version) +{ + /* NOTE: This is a pretty inefficient implementation. If it ever shows + * up in profiles, we should memoize it. + */ + smartlist_t *protocols = parse_protocol_list(list); + if (!protocols) { + return 0; + } + const char *pr_name = protocol_type_to_str(tp); + + int contains = 0; + SMARTLIST_FOREACH_BEGIN(protocols, proto_entry_t *, proto) { + if (strcasecmp(proto->name, pr_name)) + continue; + SMARTLIST_FOREACH_BEGIN(proto->ranges, const proto_range_t *, range) { + if (range->high >= version) { + contains = 1; + goto found; + } + } SMARTLIST_FOREACH_END(range); + } SMARTLIST_FOREACH_END(proto); + + found: + SMARTLIST_FOREACH(protocols, proto_entry_t *, ent, proto_entry_free(ent)); + smartlist_free(protocols); + return contains; +} + /** Return the canonical string containing the list of protocols * that we support. */ const char * diff --git a/src/or/protover.h b/src/or/protover.h index ec8da1a0d0..7176459556 100644 --- a/src/or/protover.h +++ b/src/or/protover.h @@ -47,6 +47,9 @@ char *protover_compute_vote(const smartlist_t *list_of_proto_strings, const char *protover_compute_for_old_tor(const char *version); int protocol_list_supports_protocol(const char *list, protocol_type_t tp, uint32_t version); +int protocol_list_supports_protocol_or_later(const char *list, + protocol_type_t tp, + uint32_t version); void protover_free_all(void); diff --git a/src/test/test_protover.c b/src/test/test_protover.c index 6ce54890d6..874b315490 100644 --- a/src/test/test_protover.c +++ b/src/test/test_protover.c @@ -182,6 +182,35 @@ test_protover_all_supported(void *arg) tor_free(msg); } +static void +test_protover_supports_version(void *arg) +{ + (void)arg; + + tt_assert(protocol_list_supports_protocol("Link=3-6", PRT_LINK, 3)); + tt_assert(protocol_list_supports_protocol("Link=3-6", PRT_LINK, 6)); + tt_assert(!protocol_list_supports_protocol("Link=3-6", PRT_LINK, 7)); + tt_assert(!protocol_list_supports_protocol("Link=3-6", PRT_LINKAUTH, 3)); + + tt_assert(!protocol_list_supports_protocol("Link=4-6 LinkAuth=3", + PRT_LINKAUTH, 2)); + tt_assert(protocol_list_supports_protocol("Link=4-6 LinkAuth=3", + PRT_LINKAUTH, 3)); + tt_assert(!protocol_list_supports_protocol("Link=4-6 LinkAuth=3", + PRT_LINKAUTH, 4)); + tt_assert(!protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3", + PRT_LINKAUTH, 4)); + tt_assert(protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3", + PRT_LINKAUTH, 3)); + tt_assert(protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3", + PRT_LINKAUTH, 2)); + + tt_assert(!protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3", + PRT_DESC, 2)); + done: + ; +} + #define PV_TEST(name, flags) \ { #name, test_protover_ ##name, (flags), NULL, NULL } @@ -190,6 +219,7 @@ struct testcase_t protover_tests[] = { PV_TEST(parse_fail, 0), PV_TEST(vote, 0), PV_TEST(all_supported, 0), + PV_TEST(supports_version, 0), END_OF_TESTCASES }; |