lists.torproject.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
April
March
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
tor-commits
October 2015
----- 2025 -----
April 2025
March 2025
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
tor-commits@lists.torproject.org
14 participants
1182 discussions
Start a n
N
ew thread
[translation/tor-messenger-prefsdtd] Update translations for tor-messenger-prefsdtd
by translation@torproject.org
07 Oct '15
07 Oct '15
commit de26be9ef7e0e73529e26b3fc107f76be2952a75 Author: Translation commit bot <translation(a)torproject.org> Date: Wed Oct 7 02:16:31 2015 +0000 Update translations for tor-messenger-prefsdtd --- ca/prefs.dtd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ca/prefs.dtd b/ca/prefs.dtd index 1441b0e..1a8396b 100644 --- a/ca/prefs.dtd +++ b/ca/prefs.dtd @@ -1,4 +1,4 @@ -<!ENTITY prefs.otrPreferences "OTR Preferences"> +<!ENTITY prefs.otrPreferences "
…
[View More]
Preferències OTR"> <!ENTITY prefs.otrSettings "OTR Settings"> <!ENTITY prefs.requireEncryption "Require encryption"> <!ENTITY prefs.otrKeys "My Private Keys">
[View Less]
1
0
0
0
[translation/https_everywhere_completed] Update translations for https_everywhere_completed
by translation@torproject.org
06 Oct '15
06 Oct '15
commit 45e2223c6b96539b5caf0afbe5b6870171d929a6 Author: Translation commit bot <translation(a)torproject.org> Date: Tue Oct 6 16:45:20 2015 +0000 Update translations for https_everywhere_completed --- el/https-everywhere.dtd | 1 + 1 file changed, 1 insertion(+) diff --git a/el/https-everywhere.dtd b/el/https-everywhere.dtd index 0837974..b5fa535 100644 --- a/el/https-everywhere.dtd +++ b/el/https-everywhere.dtd @@ -17,6 +17,7 @@ <!ENTITY https-everywhere.menu.
…
[View More]
globalDisable "Απενεργοποίηση του HTTPS Everywhere"> <!ENTITY https-everywhere.menu.blockHttpRequests "Μπλοκάρισμα όλων των αιτημάτων HTTP"> <!ENTITY https-everywhere.menu.showCounter "Εμφάνιση Μετρητή"> +<!ENTITY https-everywhere.menu.viewAllRules "Προβολή όλων των Κανόνων"> <!ENTITY https-everywhere.prefs.title "Προτιμήσεις του HTTPS Everywhere"> <!ENTITY https-everywhere.prefs.enable_all "Ενεργοποίηση όλων">
[View Less]
1
0
0
0
[translation/https_everywhere] Update translations for https_everywhere
by translation@torproject.org
06 Oct '15
06 Oct '15
commit dd675c979511c7fa5a26bc2e7a2ac96b3cb3025d Author: Translation commit bot <translation(a)torproject.org> Date: Tue Oct 6 16:45:14 2015 +0000 Update translations for https_everywhere --- el/https-everywhere.dtd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/el/https-everywhere.dtd b/el/https-everywhere.dtd index 26e2f9a..b5fa535 100644 --- a/el/https-everywhere.dtd +++ b/el/https-everywhere.dtd @@ -17,7 +17,7 @@ <!ENTITY https-everywhere.menu.
…
[View More]
globalDisable "Απενεργοποίηση του HTTPS Everywhere"> <!ENTITY https-everywhere.menu.blockHttpRequests "Μπλοκάρισμα όλων των αιτημάτων HTTP"> <!ENTITY https-everywhere.menu.showCounter "Εμφάνιση Μετρητή"> -<!ENTITY https-everywhere.menu.viewAllRules "View All Rules"> +<!ENTITY https-everywhere.menu.viewAllRules "Προβολή όλων των Κανόνων"> <!ENTITY https-everywhere.prefs.title "Προτιμήσεις του HTTPS Everywhere"> <!ENTITY https-everywhere.prefs.enable_all "Ενεργοποίηση όλων">
[View Less]
1
0
0
0
[tor/master] Add tests for the rend cache
by nickm@torproject.org
06 Oct '15
06 Oct '15
commit ade5005853c17b3ae5923c194680442e0f86db4d Author: Ola Bini <ola(a)olabini.se> Date: Tue Sep 15 16:21:50 2015 +0200 Add tests for the rend cache --- src/or/rendcache.c | 37 +- src/or/rendcache.h | 17 +- src/or/routerlist.c | 5 +- src/or/routerlist.h | 3 +- src/test/include.am | 2 + src/test/rend_test_helpers.c | 65 +++ src/test/rend_test_helpers.h | 12 + src/test/test.c | 3 +- src/test/
…
[View More]
test_rendcache.c | 1178 ++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 1296 insertions(+), 26 deletions(-) diff --git a/src/or/rendcache.c b/src/or/rendcache.c index 542d322..800cc24 100644 --- a/src/or/rendcache.c +++ b/src/or/rendcache.c @@ -3,9 +3,10 @@ /** * \file rendcache.c - * \brief Hidden service desriptor cache. + * \brief Hidden service descriptor cache. **/ +#define RENDCACHE_PRIVATE #include "rendcache.h" #include "config.h" @@ -15,11 +16,11 @@ /** Map from service id (as generated by rend_get_service_id) to * rend_cache_entry_t. */ -static strmap_t *rend_cache = NULL; +STATIC strmap_t *rend_cache = NULL; /** Map from descriptor id to rend_cache_entry_t; only for hidden service * directories. */ -static digestmap_t *rend_cache_v2_dir = NULL; +STATIC digestmap_t *rend_cache_v2_dir = NULL; /** (Client side only) Map from service id to rend_cache_failure_t. This * cache is used to track intro point(IP) failures so we know when to keep @@ -46,10 +47,10 @@ static digestmap_t *rend_cache_v2_dir = NULL; * This scheme allows us to not realy on the descriptor's timestamp (which * is rounded down to the hour) to know if we have a newer descriptor. We * only rely on the usability of intro points from an internal state. */ -static strmap_t *rend_cache_failure = NULL; +STATIC strmap_t *rend_cache_failure = NULL; /** DOCDOC */ -static size_t rend_cache_total_allocation = 0; +STATIC size_t rend_cache_total_allocation = 0; /** Initializes the service descriptor cache. */ @@ -62,7 +63,7 @@ rend_cache_init(void) } /** Return the approximate number of bytes needed to hold <b>e</b>. */ -static size_t +STATIC size_t rend_cache_entry_allocation(const rend_cache_entry_t *e) { if (!e) @@ -80,7 +81,7 @@ rend_cache_get_total_allocation(void) } /** Decrement the total bytes attributed to the rendezvous cache by n. */ -static void +STATIC void rend_cache_decrement_allocation(size_t n) { static int have_underflowed = 0; @@ -97,7 +98,7 @@ rend_cache_decrement_allocation(size_t n) } /** Increase the total bytes attributed to the rendezvous cache by n. */ -static void +STATIC void rend_cache_increment_allocation(size_t n) { static int have_overflowed = 0; @@ -113,7 +114,7 @@ rend_cache_increment_allocation(size_t n) } /** Helper: free a rend cache failure intro object. */ -static void +STATIC void rend_cache_failure_intro_entry_free(rend_cache_failure_intro_t *entry) { if (entry == NULL) { @@ -124,7 +125,7 @@ rend_cache_failure_intro_entry_free(rend_cache_failure_intro_t *entry) /** Allocate a rend cache failure intro object and return it. <b>failure</b> * is set into the object. This function can not fail. */ -static rend_cache_failure_intro_t * +STATIC rend_cache_failure_intro_t * rend_cache_failure_intro_entry_new(rend_intro_point_failure_t failure) { rend_cache_failure_intro_t *entry = tor_malloc(sizeof(*entry)); @@ -134,7 +135,7 @@ rend_cache_failure_intro_entry_new(rend_intro_point_failure_t failure) } /** Helper: free a rend cache failure object. */ -static void +STATIC void rend_cache_failure_entry_free(rend_cache_failure_t *entry) { if (entry == NULL) { @@ -160,7 +161,7 @@ rend_cache_failure_entry_free_(void *entry) /** Allocate a rend cache failure object and return it. This function can * not fail. */ -static rend_cache_failure_t * +STATIC rend_cache_failure_t * rend_cache_failure_entry_new(void) { rend_cache_failure_t *entry = tor_malloc(sizeof(*entry)); @@ -170,7 +171,7 @@ rend_cache_failure_entry_new(void) /** Remove failure cache entry for the service ID in the given descriptor * <b>desc</b>. */ -static void +STATIC void rend_cache_failure_remove(rend_service_descriptor_t *desc) { char service_id[REND_SERVICE_ID_LEN_BASE32 + 1]; @@ -190,7 +191,7 @@ rend_cache_failure_remove(rend_service_descriptor_t *desc) } /** Helper: free storage held by a single service descriptor cache entry. */ -static void +STATIC void rend_cache_entry_free(rend_cache_entry_t *e) { if (!e) @@ -304,7 +305,7 @@ rend_cache_failure_purge(void) * <b>identity</b> and service ID <b>service_id</b>. If found, the intro * failure is set in <b>intro_entry</b> else it stays untouched. Return 1 * iff found else 0. */ -static int +STATIC int cache_failure_intro_lookup(const uint8_t *identity, const char *service_id, rend_cache_failure_intro_t **intro_entry) { @@ -348,7 +349,7 @@ cache_failure_intro_dup(const rend_cache_failure_intro_t *entry) /** Add an intro point failure to the failure cache using the relay * <b>identity</b> and service ID <b>service_id</b>. Record the * <b>failure</b> in that object. */ -static void +STATIC void cache_failure_intro_add(const uint8_t *identity, const char *service_id, rend_intro_point_failure_t failure) { @@ -372,7 +373,7 @@ cache_failure_intro_add(const uint8_t *identity, const char *service_id, * descriptor and kept into the failure cache. Then, each intro points that * are NOT in the descriptor but in the failure cache for the given * <b>service_id</b> are removed from the failure cache. */ -static void +STATIC void validate_intro_point_failure(const rend_service_descriptor_t *desc, const char *service_id) { @@ -652,7 +653,6 @@ rend_cache_store_v2_desc_as_dir(const char *desc) log_info(LD_REND, "Successfully stored service descriptor with desc ID " "'%s' and len %d.", safe_str(desc_id_base32), (int)encoded_size); - /* Statistics: Note down this potentially new HS. */ if (options->HiddenServiceStatistics) { rep_hist_stored_maybe_new_hs(e->parsed->pk); @@ -887,4 +887,3 @@ rend_cache_store_v2_desc_as_client(const char *desc, tor_free(intro_content); return retval; } - diff --git a/src/or/rendcache.h b/src/or/rendcache.h index 0512058..8ba1f6f 100644 --- a/src/or/rendcache.h +++ b/src/or/rendcache.h @@ -76,5 +76,20 @@ void rend_cache_intro_failure_note(rend_intro_point_failure_t failure, const char *service_id); void rend_cache_failure_purge(void); -#endif /* TOR_RENDCACHE_H */ +#ifdef RENDCACHE_PRIVATE +STATIC size_t rend_cache_entry_allocation(const rend_cache_entry_t *e); +STATIC void rend_cache_entry_free(rend_cache_entry_t *e); +STATIC void rend_cache_failure_intro_entry_free(rend_cache_failure_intro_t *entry); +STATIC void rend_cache_failure_entry_free(rend_cache_failure_t *entry); +STATIC int cache_failure_intro_lookup(const uint8_t *identity, const char *service_id, rend_cache_failure_intro_t **intro_entry); +STATIC void rend_cache_decrement_allocation(size_t n); +STATIC void rend_cache_increment_allocation(size_t n); +STATIC rend_cache_failure_intro_t *rend_cache_failure_intro_entry_new(rend_intro_point_failure_t failure); +STATIC rend_cache_failure_t *rend_cache_failure_entry_new(void); +STATIC void rend_cache_failure_remove(rend_service_descriptor_t *desc); +STATIC void cache_failure_intro_add(const uint8_t *identity, const char *service_id, rend_intro_point_failure_t failure); +STATIC void validate_intro_point_failure(const rend_service_descriptor_t *desc, const char *service_id); +#endif + +#endif /* TOR_RENDCACHE_H */ diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 8bd8039..93dc2fe 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -5184,8 +5184,8 @@ hid_serv_acting_as_directory(void) /** Return true if this node is responsible for storing the descriptor ID * in <b>query</b> and false otherwise. */ -int -hid_serv_responsible_for_desc_id(const char *query) +MOCK_IMPL(int, hid_serv_responsible_for_desc_id, + (const char *query)) { const routerinfo_t *me; routerstatus_t *last_rs; @@ -5208,4 +5208,3 @@ hid_serv_responsible_for_desc_id(const char *query) smartlist_free(responsible); return result; } - diff --git a/src/or/routerlist.h b/src/or/routerlist.h index 200533f..ec09f23 100644 --- a/src/or/routerlist.h +++ b/src/or/routerlist.h @@ -201,7 +201,7 @@ void refresh_all_country_info(void); int hid_serv_get_responsible_directories(smartlist_t *responsible_dirs, const char *id); int hid_serv_acting_as_directory(void); -int hid_serv_responsible_for_desc_id(const char *id); +MOCK_DECL(int, hid_serv_responsible_for_desc_id, (const char *id)); void list_pending_microdesc_downloads(digest256map_t *result); void launch_descriptor_downloads(int purpose, @@ -243,4 +243,3 @@ MOCK_DECL(STATIC void, initiate_descriptor_downloads, #endif #endif - diff --git a/src/test/include.am b/src/test/include.am index f7c0204..a9ad570 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -51,6 +51,7 @@ src_test_AM_CPPFLAGS = -DSHARE_DATADIR="\"$(datadir)\"" \ # matters a lot there, and is quite hard to debug if you forget to do it. src_test_test_SOURCES = \ + src/test/rend_test_helpers.c \ src/test/test.c \ src/test/test_accounting.c \ src/test/test_addr.c \ @@ -87,6 +88,7 @@ src_test_test_SOURCES = \ src/test/test_pt.c \ src/test/test_relay.c \ src/test/test_relaycell.c \ + src/test/test_rendcache.c \ src/test/test_replay.c \ src/test/test_routerkeys.c \ src/test/test_routerlist.c \ diff --git a/src/test/rend_test_helpers.c b/src/test/rend_test_helpers.c new file mode 100644 index 0000000..06e40a0 --- /dev/null +++ b/src/test/rend_test_helpers.c @@ -0,0 +1,65 @@ +#include "rend_test_helpers.h" + +#include "test.h" +#include "rendcommon.h" + +/** TODO: Description */ +void +generate_desc(int time_diff, rend_encoded_v2_service_descriptor_t **desc, char **service_id, int intro_points) +{ + rend_service_descriptor_t *generated = NULL; + smartlist_t *descs = smartlist_new(); + time_t now; + + now = time(NULL) + time_diff; + create_descriptor(&generated, service_id, intro_points); + generated->timestamp = now; + + rend_encode_v2_descriptors(descs, generated, now, 0, REND_NO_AUTH, NULL, NULL); + *desc = ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)); + + smartlist_free(descs); + rend_service_descriptor_free(generated); +} + + +/** TODO: Description */ +void +create_descriptor(rend_service_descriptor_t **generated, char **service_id, int intro_points) +{ + crypto_pk_t *pk1 = NULL; + crypto_pk_t *pk2 = NULL; + int i; + + *service_id = tor_malloc(REND_SERVICE_ID_LEN_BASE32+1); + pk1 = pk_generate(0); + pk2 = pk_generate(1); + + *generated = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + (*generated)->pk = crypto_pk_dup_key(pk1); + rend_get_service_id((*generated)->pk, *service_id); + + (*generated)->version = 2; + (*generated)->protocols = 42; + (*generated)->intro_nodes = smartlist_new(); + + for (i = 0; i < intro_points; i++) { + rend_intro_point_t *intro = tor_malloc_zero(sizeof(rend_intro_point_t)); + crypto_pk_t *okey = pk_generate(2 + i); + intro->extend_info = tor_malloc_zero(sizeof(extend_info_t)); + intro->extend_info->onion_key = okey; + crypto_pk_get_digest(intro->extend_info->onion_key, + intro->extend_info->identity_digest); + intro->extend_info->nickname[0] = '$'; + base16_encode(intro->extend_info->nickname + 1, + sizeof(intro->extend_info->nickname) - 1, + intro->extend_info->identity_digest, DIGEST_LEN); + tor_addr_from_ipv4h(&intro->extend_info->addr, crypto_rand_int(65536)); + intro->extend_info->port = 1 + crypto_rand_int(65535); + intro->intro_key = crypto_pk_dup_key(pk2); + smartlist_add((*generated)->intro_nodes, intro); + } + + crypto_pk_free(pk1); + crypto_pk_free(pk2); +} diff --git a/src/test/rend_test_helpers.h b/src/test/rend_test_helpers.h new file mode 100644 index 0000000..00a17be --- /dev/null +++ b/src/test/rend_test_helpers.h @@ -0,0 +1,12 @@ +/* Copyright (c) 2014-2015, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "or.h" + +#ifndef TOR_REND_TEST_HELPERS_H +#define TOR_REND_TEST_HELPERS_H + +void generate_desc(int time_diff, rend_encoded_v2_service_descriptor_t **desc, char **service_id, int intro_points); +void create_descriptor(rend_service_descriptor_t **generated, char **service_id, int intro_points); + +#endif diff --git a/src/test/test.c b/src/test/test.c index e10e260..773764c 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -1148,6 +1148,7 @@ extern struct testcase_t policy_tests[]; extern struct testcase_t pt_tests[]; extern struct testcase_t relay_tests[]; extern struct testcase_t relaycell_tests[]; +extern struct testcase_t rend_cache_tests[]; extern struct testcase_t replaycache_tests[]; extern struct testcase_t router_tests[]; extern struct testcase_t routerkeys_tests[]; @@ -1195,6 +1196,7 @@ struct testgroup_t testgroups[] = { { "pt/", pt_tests }, { "relay/" , relay_tests }, { "relaycell/", relaycell_tests }, + { "rend_cache/", rend_cache_tests }, { "replaycache/", replaycache_tests }, { "routerkeys/", routerkeys_tests }, { "routerlist/", routerlist_tests }, @@ -1208,4 +1210,3 @@ struct testgroup_t testgroups[] = { { "dns/", dns_tests }, END_OF_GROUPS }; - diff --git a/src/test/test_rendcache.c b/src/test/test_rendcache.c new file mode 100644 index 0000000..a005e66 --- /dev/null +++ b/src/test/test_rendcache.c @@ -0,0 +1,1178 @@ +/* Copyright (c) 2010-2015, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "orconfig.h" +#include "or.h" + +#include "test.h" +#define RENDCACHE_PRIVATE +#include "rendcache.h" +#include "router.h" +#include "routerlist.h" +#include "config.h" +#include <openssl/rsa.h> +#include "rend_test_helpers.h" + +#define NS_MODULE rend_cache + +static const int RECENT_TIME = -10; +static const int TIME_IN_THE_PAST = -(REND_CACHE_MAX_AGE + REND_CACHE_MAX_SKEW + 10); +static const int TIME_IN_THE_FUTURE = REND_CACHE_MAX_SKEW + 10; + +extern strmap_t *rend_cache; +extern digestmap_t *rend_cache_v2_dir; +extern strmap_t *rend_cache_failure; +extern size_t rend_cache_total_allocation; + +static rend_data_t +mock_rend_data(char *onion_address) +{ + rend_data_t rend_query; + + memset(&rend_query, 0, sizeof(rend_query)); + strncpy(rend_query.onion_address, onion_address, REND_SERVICE_ID_LEN_BASE32+1); + rend_query.auth_type = REND_NO_AUTH; + rend_query.hsdirs_fp = smartlist_new(); + smartlist_add(rend_query.hsdirs_fp, tor_memdup("aaaaaaaaaaaaaaaaaaaaaaaa", DIGEST_LEN)); + + return rend_query; +} + +static void +test_rend_cache_lookup_entry(void *data) +{ + int ret; + rend_data_t mock_rend_query; + char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; + rend_cache_entry_t *entry = NULL; + rend_encoded_v2_service_descriptor_t *desc_holder = NULL; + char *service_id = NULL; + (void)data; + + rend_cache_init(); + + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + + + ret = rend_cache_lookup_entry("abababababababab", 0, NULL); + tt_int_op(ret, OP_EQ, -ENOENT); + + ret = rend_cache_lookup_entry("invalid query", 2, NULL); + tt_int_op(ret, OP_EQ, -EINVAL); + + ret = rend_cache_lookup_entry("abababababababab", 2, NULL); + tt_int_op(ret, OP_EQ, -ENOENT); + + ret = rend_cache_lookup_entry("abababababababab", 4224, NULL); + tt_int_op(ret, OP_EQ, -ENOENT); + + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); + rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + + ret = rend_cache_lookup_entry(service_id, 2, NULL); + tt_int_op(ret, OP_EQ, 0); + + ret = rend_cache_lookup_entry(service_id, 2, &entry); + tt_assert(entry); + tt_int_op(entry->len, OP_EQ, strlen(desc_holder->desc_str)); + tt_str_op(entry->desc, OP_EQ, desc_holder->desc_str); + + done: + tor_free(desc_holder); + tor_free(entry); + tor_free(service_id); +} + +static void +test_rend_cache_store_v2_desc_as_client(void *data) +{ + rend_cache_store_status_t ret; + rend_data_t mock_rend_query; + char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; + rend_cache_entry_t *entry = NULL; + rend_encoded_v2_service_descriptor_t *desc_holder = NULL; + char *service_id = NULL; + char client_cookie[REND_DESC_COOKIE_LEN]; + (void)data; + + rend_cache_init(); + + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + + // Test success + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, &entry); + + tt_int_op(ret, OP_EQ, RCS_OKAY); + tt_assert(entry); + tt_int_op(entry->len, OP_EQ, strlen(desc_holder->desc_str)); + tt_str_op(entry->desc, OP_EQ, desc_holder->desc_str); + + // Test various failure modes + + // TODO: a too long desc_id_base32 argument crashes the function + /* ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, "3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG", &mock_rend_query, NULL); */ + /* tt_int_op(ret, OP_EQ, RCS_BADDESC); */ + + // Test bad base32 failure + // This causes an assertion failure if we're running with assertions. But when doing coverage, we can test it. +#ifdef TOR_COVERAGE + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, "!xqunszqnaolrrfmtzgaki7mxelgvkj", &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); +#endif + + // Test invalid descriptor + ret = rend_cache_store_v2_desc_as_client("invalid descriptor", "3xqunszqnaolrrfmtzgaki7mxelgvkje", &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + + // TODO: it doesn't seem to be possible to test invalid service ID condition. + // that means it is likely not possible to have that condition without earlier conditions failing first (such as signature checking of the desc) + + // Test mismatch between service ID and onion address + rend_cache_init(); + strncpy(mock_rend_query.onion_address, "abc", REND_SERVICE_ID_LEN_BASE32+1); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + + // Test incorrect descriptor ID + rend_cache_init(); + mock_rend_query = mock_rend_data(service_id); + desc_id_base32[0]++; + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + desc_id_base32[0]--; + + // Test too old descriptor + rend_cache_init(); + tor_free(desc_holder); + tor_free(service_id); + + generate_desc(TIME_IN_THE_PAST, &desc_holder, &service_id, 3); + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); + + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + + // Test too new descriptor (in the future) + rend_cache_init(); + tor_free(desc_holder); + tor_free(service_id); + + generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3); + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); + + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + + // Test when a descriptor is already in the cache + rend_cache_init(); + tor_free(desc_holder); + tor_free(service_id); + tor_free(entry); + + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); + + rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, &entry); + tt_int_op(ret, OP_EQ, RCS_OKAY); + tt_assert(entry); + + // Test unsuccessful decrypting of introduction points + rend_cache_init(); + tor_free(desc_holder); + tor_free(service_id); + + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + mock_rend_query = mock_rend_data(service_id); + mock_rend_query.auth_type = REND_BASIC_AUTH; + client_cookie[0] = 'A'; + memcpy(mock_rend_query.descriptor_cookie, client_cookie, REND_DESC_COOKIE_LEN); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test successful run when we have REND_BASIC_AUTH but not cookie + rend_cache_init(); + tor_free(desc_holder); + tor_free(service_id); + + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + mock_rend_query = mock_rend_data(service_id); + mock_rend_query.auth_type = REND_BASIC_AUTH; + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test when we have no introduction points + rend_cache_init(); + tor_free(desc_holder); + tor_free(service_id); + + generate_desc(RECENT_TIME, &desc_holder, &service_id, 0); + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + + // Test when we have too many intro points + rend_cache_init(); + tor_free(desc_holder); + tor_free(service_id); + + generate_desc(RECENT_TIME, &desc_holder, &service_id, MAX_INTRO_POINTS+1); + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + + done: + rend_encoded_v2_service_descriptor_free(desc_holder); + tor_free(entry); + tor_free(service_id); +} + +static void +test_rend_cache_store_v2_desc_as_client_with_different_time(void *data) +{ + rend_cache_store_status_t ret; + rend_data_t mock_rend_query; + char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; + rend_service_descriptor_t *generated = NULL; + smartlist_t *descs = smartlist_new(); + time_t t; + char *service_id = NULL; + rend_encoded_v2_service_descriptor_t *desc_holder_newer; + rend_encoded_v2_service_descriptor_t *desc_holder_older; + + t = time(NULL); + + create_descriptor(&generated, &service_id, 3); + + generated->timestamp = t + RECENT_TIME; + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, REND_NO_AUTH, NULL, NULL); + desc_holder_newer = ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)); + + smartlist_free(descs); + descs = smartlist_new(); + + generated->timestamp = (t + RECENT_TIME) - 20; + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, REND_NO_AUTH, NULL, NULL); + desc_holder_older = ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)); + + (void)data; + rend_cache_init(); + + // Test when a descriptor is already in the cache and it is newer than the one we submit + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder_newer->desc_id, DIGEST_LEN); + rend_cache_store_v2_desc_as_client(desc_holder_newer->desc_str, desc_id_base32, &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client(desc_holder_older->desc_str, desc_id_base32, &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test when an old descriptor is in the cache and we submit a newer one + rend_cache_init(); + rend_cache_store_v2_desc_as_client(desc_holder_older->desc_str, desc_id_base32, &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client(desc_holder_newer->desc_str, desc_id_base32, &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + done: + rend_encoded_v2_service_descriptor_free(desc_holder_newer); + rend_encoded_v2_service_descriptor_free(desc_holder_older); + smartlist_free(descs); + rend_service_descriptor_free(generated); + tor_free(service_id); +} + + +#define NS_SUBMODULE lookup_v2_desc_as_dir +NS_DECL(const routerinfo_t *, router_get_my_routerinfo, (void)); +NS_DECL(int, hid_serv_responsible_for_desc_id, (const char *id)); + +static routerinfo_t *mock_routerinfo; +static int hid_serv_responsible_for_desc_id_response; + +static const routerinfo_t * +NS(router_get_my_routerinfo)(void) +{ + if(!mock_routerinfo) { + mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); + } + + return mock_routerinfo; +} + +static int +NS(hid_serv_responsible_for_desc_id)(const char *id) +{ + return hid_serv_responsible_for_desc_id_response; +} + +static void +test_rend_cache_lookup_v2_desc_as_dir(void *data) +{ + int ret; + char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; + rend_encoded_v2_service_descriptor_t *desc_holder = NULL; + char *service_id = NULL; + const char *ret_desc = NULL; + + (void)data; + + NS_MOCK(router_get_my_routerinfo); + NS_MOCK(hid_serv_responsible_for_desc_id); + + rend_cache_init(); + + // Test invalid base32 + ret = rend_cache_lookup_v2_desc_as_dir("!bababababababab", NULL); + tt_int_op(ret, OP_EQ, -1); + + // Test non-existent descriptor but well formed + ret = rend_cache_lookup_v2_desc_as_dir("3xqunszqnaolrrfmtzgaki7mxelgvkje", NULL); + tt_int_op(ret, OP_EQ, 0); + + // Test existing descriptor + hid_serv_responsible_for_desc_id_response = 1; + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); + ret = rend_cache_lookup_v2_desc_as_dir(desc_id_base32, &ret_desc); + tt_int_op(ret, OP_EQ, 1); + tt_assert(ret_desc); + + done: + NS_UNMOCK(router_get_my_routerinfo); + NS_UNMOCK(hid_serv_responsible_for_desc_id); + tor_free(mock_routerinfo); +} + +#undef NS_SUBMODULE + +#define NS_SUBMODULE store_v2_desc_as_dir +NS_DECL(const routerinfo_t *, router_get_my_routerinfo, (void)); +NS_DECL(int, hid_serv_responsible_for_desc_id, (const char *id)); + +static routerinfo_t *mock_routerinfo; +static int hid_serv_responsible_for_desc_id_response; + +static const routerinfo_t * +NS(router_get_my_routerinfo)(void) +{ + return mock_routerinfo; +} + +static int +NS(hid_serv_responsible_for_desc_id)(const char *id) +{ + return hid_serv_responsible_for_desc_id_response; +} + +static void +test_rend_cache_store_v2_desc_as_dir(void *data) +{ + (void)data; + rend_cache_store_status_t ret; + rend_encoded_v2_service_descriptor_t *desc_holder = NULL; + char *service_id = NULL; + + NS_MOCK(router_get_my_routerinfo); + NS_MOCK(hid_serv_responsible_for_desc_id); + + rend_cache_init(); + + // Test when we are not an HS dir + mock_routerinfo = NULL; + ret = rend_cache_store_v2_desc_as_dir(""); + tt_int_op(ret, OP_EQ, RCS_NOTDIR); + + // Test when we can't parse the descriptor + mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); + hid_serv_responsible_for_desc_id_response = 1; + ret = rend_cache_store_v2_desc_as_dir("unparseable"); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + + // Test when we are not responsible for an HS + hid_serv_responsible_for_desc_id_response = 0; + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test when we have an old descriptor + hid_serv_responsible_for_desc_id_response = 1; + generate_desc(TIME_IN_THE_PAST, &desc_holder, &service_id, 3); + ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test when we have a descriptor in the future + generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3); + ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test when two descriptors + generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3); + ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test when asking for hidden service statistics HiddenServiceStatistics + rend_cache_purge(); + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + get_options_mutable()->HiddenServiceStatistics = 1; + ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + done: + NS_UNMOCK(router_get_my_routerinfo); + NS_UNMOCK(hid_serv_responsible_for_desc_id); + tor_free(desc_holder); + tor_free(service_id); +} + +static void +test_rend_cache_store_v2_desc_as_dir_with_different_time(void *data) +{ + (void)data; + + rend_cache_store_status_t ret; + rend_service_descriptor_t *generated = NULL; + smartlist_t *descs = smartlist_new(); + time_t t; + char *service_id = NULL; + rend_encoded_v2_service_descriptor_t *desc_holder_newer; + rend_encoded_v2_service_descriptor_t *desc_holder_older; + + NS_MOCK(router_get_my_routerinfo); + NS_MOCK(hid_serv_responsible_for_desc_id); + + rend_cache_init(); + + t = time(NULL); + + create_descriptor(&generated, &service_id, 3); + generated->timestamp = t + RECENT_TIME; + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, REND_NO_AUTH, NULL, NULL); + desc_holder_newer = ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)); + + smartlist_free(descs); + descs = smartlist_new(); + + generated->timestamp = (t + RECENT_TIME) - 20; + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, REND_NO_AUTH, NULL, NULL); + desc_holder_older = ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)); + + // Test when we have a newer descriptor stored + mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); + hid_serv_responsible_for_desc_id_response = 1; + rend_cache_store_v2_desc_as_dir(desc_holder_newer->desc_str); + ret = rend_cache_store_v2_desc_as_dir(desc_holder_older->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test when we have an old descriptor stored + rend_cache_purge(); + rend_cache_store_v2_desc_as_dir(desc_holder_older->desc_str); + ret = rend_cache_store_v2_desc_as_dir(desc_holder_newer->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + done: + NS_UNMOCK(router_get_my_routerinfo); + NS_UNMOCK(hid_serv_responsible_for_desc_id); +} + +static void +test_rend_cache_store_v2_desc_as_dir_with_different_content(void *data) +{ + (void)data; + + rend_cache_store_status_t ret; + rend_service_descriptor_t *generated = NULL; + smartlist_t *descs = smartlist_new(); + time_t t; + char *service_id = NULL; + rend_encoded_v2_service_descriptor_t *desc_holder_one; + rend_encoded_v2_service_descriptor_t *desc_holder_two; + + NS_MOCK(router_get_my_routerinfo); + NS_MOCK(hid_serv_responsible_for_desc_id); + + rend_cache_init(); + + t = time(NULL); + + create_descriptor(&generated, &service_id, 3); + generated->timestamp = t + RECENT_TIME; + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, REND_NO_AUTH, NULL, NULL); + desc_holder_one = ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)); + + smartlist_free(descs); + descs = smartlist_new(); + + generated->timestamp = t + RECENT_TIME; + generated->protocols = 41; + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, REND_NO_AUTH, NULL, NULL); + desc_holder_two = ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)); + + // Test when we have another descriptor stored, with a different descriptor + mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); + hid_serv_responsible_for_desc_id_response = 1; + rend_cache_store_v2_desc_as_dir(desc_holder_one->desc_str); + ret = rend_cache_store_v2_desc_as_dir(desc_holder_two->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + done: + NS_UNMOCK(router_get_my_routerinfo); + NS_UNMOCK(hid_serv_responsible_for_desc_id); +} + + +#undef NS_SUBMODULE + +static void +test_rend_cache_init(void *data) +{ + (void)data; + + tt_assert_msg(!rend_cache, "rend_cache should be NULL when starting"); + tt_assert_msg(!rend_cache_v2_dir, "rend_cache_v2_dir should be NULL when starting"); + tt_assert_msg(!rend_cache_failure, "rend_cache_failure should be NULL when starting"); + + rend_cache_init(); + + tt_assert_msg(rend_cache, "rend_cache should not be NULL after initing"); + tt_assert_msg(rend_cache_v2_dir, "rend_cache_v2_dir should not be NULL after initing"); + tt_assert_msg(rend_cache_failure, "rend_cache_failure should not be NULL after initing"); + + tt_int_op(strmap_size(rend_cache), OP_EQ, 0); + tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); + tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); + + done: + (void)0; +} + +static void +test_rend_cache_decrement_allocation(void *data) +{ + (void)data; + + // Test when the cache has enough allocations + rend_cache_total_allocation = 10; + rend_cache_decrement_allocation(3); + tt_int_op(rend_cache_total_allocation, OP_EQ, 7); + + // Test when there are not enough allocations + rend_cache_total_allocation = 1; + rend_cache_decrement_allocation(2); + tt_int_op(rend_cache_total_allocation, OP_EQ, 0); + + // And again + rend_cache_decrement_allocation(2); + tt_int_op(rend_cache_total_allocation, OP_EQ, 0); + + done: + (void)0; +} + +static void +test_rend_cache_increment_allocation(void *data) +{ + (void)data; + + // Test when the cache is not overflowing + rend_cache_total_allocation = 5; + rend_cache_increment_allocation(3); + tt_int_op(rend_cache_total_allocation, OP_EQ, 8); + + // Test when there are too many allocations + rend_cache_total_allocation = SIZE_MAX-1; + rend_cache_increment_allocation(2); + tt_int_op(rend_cache_total_allocation, OP_EQ, SIZE_MAX); + + // And again + rend_cache_increment_allocation(2); + tt_int_op(rend_cache_total_allocation, OP_EQ, SIZE_MAX); + + done: + (void)0; +} + + +static void +test_rend_cache_failure_intro_entry_new(void *data) +{ + time_t now; + rend_cache_failure_intro_t *entry; + rend_intro_point_failure_t failure; + + (void)data; + + failure = INTRO_POINT_FAILURE_TIMEOUT; + now = time(NULL); + entry = rend_cache_failure_intro_entry_new(failure); + + tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_TIMEOUT); + tt_int_op(entry->created_ts, OP_GE, now-5); + tt_int_op(entry->created_ts, OP_LE, now+5); + + done: + tor_free(entry); +} + +static void +test_rend_cache_failure_intro_lookup(void *data) +{ + (void)data; + int ret; + rend_cache_failure_t *failure; + rend_cache_failure_intro_t *ip; + rend_cache_failure_intro_t *entry; + + rend_cache_init(); + + failure = rend_cache_failure_entry_new(); + ip = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); + digestmap_set(failure->intro_failures, "ip1", ip); + strmap_set_lc(rend_cache_failure, "foo1", failure); + + // Test not found + ret = cache_failure_intro_lookup((const uint8_t *)"foo1", "foo2", NULL); + tt_int_op(ret, OP_EQ, 0); + + // Test found with no intro failures in it + ret = cache_failure_intro_lookup((const uint8_t *)"ip2", "foo1", NULL); + tt_int_op(ret, OP_EQ, 0); + + // Test found + ret = cache_failure_intro_lookup((const uint8_t *)"ip1", "foo1", NULL); + tt_int_op(ret, OP_EQ, 1); + + // Test found and asking for entry + cache_failure_intro_lookup((const uint8_t *)"ip1", "foo1", &entry); + tt_assert(entry); + tt_assert(entry == ip); + + done: + rend_cache_purge(); +} + +static void +test_rend_cache_clean(void *data) +{ + rend_cache_entry_t *one, *two; + rend_service_descriptor_t *desc_one, *desc_two; + strmap_iter_t *iter = NULL; + const char *key; + void *val; + + (void)data; + + rend_cache_init(); + + // Test with empty rendcache + rend_cache_clean(time(NULL)); + tt_int_op(strmap_size(rend_cache), OP_EQ, 0); + + // Test with two old entries + one = tor_malloc_zero(sizeof(rend_cache_entry_t)); + two = tor_malloc_zero(sizeof(rend_cache_entry_t)); + desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + desc_two = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + one->parsed = desc_one; + two->parsed = desc_two; + + desc_one->timestamp = time(NULL) + TIME_IN_THE_PAST; + desc_two->timestamp = (time(NULL) + TIME_IN_THE_PAST) - 10; + desc_one->pk = pk_generate(0); + desc_two->pk = pk_generate(1); + + strmap_set_lc(rend_cache, "foo1", one); + strmap_set_lc(rend_cache, "foo2", two); + + rend_cache_clean(time(NULL)); + tt_int_op(strmap_size(rend_cache), OP_EQ, 0); + + // Test with one old entry and one newer entry + one = tor_malloc_zero(sizeof(rend_cache_entry_t)); + two = tor_malloc_zero(sizeof(rend_cache_entry_t)); + desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + desc_two = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + one->parsed = desc_one; + two->parsed = desc_two; + + desc_one->timestamp = (time(NULL) + TIME_IN_THE_PAST) - 10; + desc_two->timestamp = time(NULL) - 100; + desc_one->pk = pk_generate(0); + desc_two->pk = pk_generate(1); + + strmap_set_lc(rend_cache, "foo1", one); + strmap_set_lc(rend_cache, "foo2", two); + + rend_cache_clean(time(NULL)); + tt_int_op(strmap_size(rend_cache), OP_EQ, 1); + + iter = strmap_iter_init(rend_cache); + strmap_iter_get(iter, &key, &val); + tt_str_op(key, OP_EQ, "foo2"); + + done: + (void)1; +} + +static void +test_rend_cache_failure_entry_new(void *data) +{ + rend_cache_failure_t *failure; + + (void)data; + + failure = rend_cache_failure_entry_new(); + tt_assert(failure); + tt_int_op(digestmap_size(failure->intro_failures), OP_EQ, 0); + + done: + tor_free(failure); +} + +static void +test_rend_cache_failure_entry_free(void *data) +{ + (void)data; + + // Test that it can deal with a NULL argument + rend_cache_failure_entry_free(NULL); + + /* done: */ + /* (void)0; */ +} + +static void +test_rend_cache_failure_clean(void *data) +{ + rend_cache_failure_t *failure; + rend_cache_failure_intro_t *ip_one, *ip_two; + + (void)data; + + rend_cache_init(); + + // Test with empty failure cache + rend_cache_failure_clean(time(NULL)); + tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); + + // Test with one empty failure entry + failure = rend_cache_failure_entry_new(); + strmap_set_lc(rend_cache_failure, "foo1", failure); + rend_cache_failure_clean(time(NULL)); + tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); + + // Test with one new intro point + failure = rend_cache_failure_entry_new(); + ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); + digestmap_set(failure->intro_failures, "ip1", ip_one); + strmap_set_lc(rend_cache_failure, "foo1", failure); + rend_cache_failure_clean(time(NULL)); + tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 1); + + // Test with one old intro point + rend_cache_failure_purge(); + failure = rend_cache_failure_entry_new(); + ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); + ip_one->created_ts = time(NULL) - 7*60; + digestmap_set(failure->intro_failures, "ip1", ip_one); + strmap_set_lc(rend_cache_failure, "foo1", failure); + rend_cache_failure_clean(time(NULL)); + tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); + + + // Test with one old intro point and one new one + rend_cache_failure_purge(); + failure = rend_cache_failure_entry_new(); + ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); + ip_one->created_ts = time(NULL) - 7*60; + digestmap_set(failure->intro_failures, "ip1", ip_one); + ip_two = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); + ip_two->created_ts = time(NULL) - 2*60; + digestmap_set(failure->intro_failures, "ip2", ip_two); + strmap_set_lc(rend_cache_failure, "foo1", failure); + rend_cache_failure_clean(time(NULL)); + tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 1); + tt_int_op(digestmap_size(failure->intro_failures), OP_EQ, 1); + + done: + (void)0; +} + + +static void +test_rend_cache_failure_remove(void *data) +{ + rend_service_descriptor_t *desc; + (void)data; + + rend_cache_init(); + + // Test that it deals well with a NULL desc + rend_cache_failure_remove(NULL); + + // Test a descriptor that isn't in the cache + desc = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + desc->pk = pk_generate(0); + rend_cache_failure_remove(desc); + + // There seems to not exist any way of getting rend_cache_failure_remove() to fail because of a problem with rend_get_service_id from here + + /* done: */ + /* (void)0; */ +} + +static void +test_rend_cache_free_all(void *data) +{ + rend_cache_failure_t *failure; + rend_cache_entry_t *one; + rend_service_descriptor_t *desc_one; + + (void)data; + + rend_cache_init(); + + failure = rend_cache_failure_entry_new(); + strmap_set_lc(rend_cache_failure, "foo1", failure); + + one = tor_malloc_zero(sizeof(rend_cache_entry_t)); + desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + one->parsed = desc_one; + desc_one->timestamp = time(NULL) + TIME_IN_THE_PAST; + desc_one->pk = pk_generate(0); + strmap_set_lc(rend_cache, "foo1", one); + + rend_cache_free_all(); + + tt_assert(!rend_cache); + tt_assert(!rend_cache_v2_dir); + tt_assert(!rend_cache_failure); + tt_assert(!rend_cache_total_allocation); + + done: + (void)0; +} + + +static void +test_rend_cache_entry_free(void *data) +{ + (void)data; + rend_cache_entry_t *e; + + // Handles NULL correctly + rend_cache_entry_free(NULL); + + // Handles NULL descriptor correctly + e = tor_malloc_zero(sizeof(rend_cache_entry_t)); + rend_cache_entry_free(e); + + // Handles non-NULL descriptor correctly + e = tor_malloc_zero(sizeof(rend_cache_entry_t)); + e->desc = (char *)malloc(10); + rend_cache_entry_free(e); + + /* done: */ + /* (void)0; */ +} + + +static void +test_rend_cache_purge(void *data) +{ + strmap_t *our_rend_cache; + + (void)data; + + // Deals with a NULL rend_cache + rend_cache_purge(); + tt_assert(rend_cache); + tt_int_op(strmap_size(rend_cache), OP_EQ, 0); + + // Deals with existing rend_cache + rend_cache_init(); + + our_rend_cache = rend_cache; + rend_cache_purge(); + tt_assert(rend_cache); + tt_assert(rend_cache == our_rend_cache); + + done: + (void)0; +} + +static void +test_rend_cache_failure_intro_add(void *data) +{ + (void)data; + rend_cache_failure_t *fail_entry; + rend_cache_failure_intro_t *entry; + + rend_cache_init(); + + // Adds non-existing entry + cache_failure_intro_add((const uint8_t *)"foo1", "foo2", INTRO_POINT_FAILURE_TIMEOUT); + fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); + tt_assert(fail_entry); + tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); + entry = digestmap_get(fail_entry->intro_failures, "foo1"); + tt_assert(entry); + + // Adds existing entry + cache_failure_intro_add((const uint8_t *)"foo1", "foo2", INTRO_POINT_FAILURE_TIMEOUT); + fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); + tt_assert(fail_entry); + tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); + entry = digestmap_get(fail_entry->intro_failures, "foo1"); + tt_assert(entry); + + done: + rend_cache_purge(); +} + + +static void +test_rend_cache_intro_failure_note(void *data) +{ + (void)data; + rend_cache_failure_t *fail_entry; + rend_cache_failure_intro_t *entry; + + // Test not found + rend_cache_intro_failure_note(INTRO_POINT_FAILURE_TIMEOUT,(const uint8_t *)"foo1", "foo2"); + fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); + tt_assert(fail_entry); + tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); + entry = digestmap_get(fail_entry->intro_failures, "foo1"); + tt_assert(entry); + tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_TIMEOUT); + + // Test found + rend_cache_intro_failure_note(INTRO_POINT_FAILURE_UNREACHABLE,(const uint8_t *)"foo1", "foo2"); + tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_UNREACHABLE); + + done: + rend_cache_purge(); +} + +#define NS_SUBMODULE clean_v2_descs_as_dir +NS_DECL(int, hid_serv_responsible_for_desc_id, (const char *id)); + +static int hid_serv_responsible_for_desc_id_response; + +static int +NS(hid_serv_responsible_for_desc_id)(const char *id) +{ + return hid_serv_responsible_for_desc_id_response; +} + + +static void +test_rend_cache_clean_v2_descs_as_dir(void *data) +{ + rend_cache_entry_t *e; + time_t now; + rend_service_descriptor_t *desc; + now = time(NULL); + + (void)data; + + NS_MOCK(hid_serv_responsible_for_desc_id); + rend_cache_init(); + + // Test running with an empty cache + rend_cache_clean_v2_descs_as_dir(now, 0); + tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); + + // Test with only one new entry + e = tor_malloc_zero(sizeof(rend_cache_entry_t)); + e->last_served = now; + desc = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + desc->timestamp = now; + desc->pk = pk_generate(0); + e->parsed = desc; + digestmap_set(rend_cache_v2_dir, "abcde", e); + + hid_serv_responsible_for_desc_id_response = 1; + rend_cache_clean_v2_descs_as_dir(now, 0); + tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 1); + + // Test with one old entry + desc->timestamp = now - (REND_CACHE_MAX_AGE + REND_CACHE_MAX_SKEW + 1000); + rend_cache_clean_v2_descs_as_dir(now, 0); + tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); + + // Test with one entry that is not under the responsibility of this hidden service + e = tor_malloc_zero(sizeof(rend_cache_entry_t)); + e->last_served = now; + desc = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + desc->timestamp = now; + desc->pk = pk_generate(0); + e->parsed = desc; + digestmap_set(rend_cache_v2_dir, "abcde", e); + + hid_serv_responsible_for_desc_id_response = 0; + rend_cache_clean_v2_descs_as_dir(now, 0); + tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); + + // Test with one entry that has an old last served + e = tor_malloc_zero(sizeof(rend_cache_entry_t)); + e->last_served = now - (REND_CACHE_MAX_AGE + REND_CACHE_MAX_SKEW + 1000); + desc = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + desc->timestamp = now; + desc->pk = pk_generate(0); + e->parsed = desc; + digestmap_set(rend_cache_v2_dir, "abcde", e); + + hid_serv_responsible_for_desc_id_response = 1; + rend_cache_clean_v2_descs_as_dir(now, 0); + tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); + + // Test a run through asking for a large force_remove + e = tor_malloc_zero(sizeof(rend_cache_entry_t)); + e->last_served = now; + desc = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + desc->timestamp = now; + desc->pk = pk_generate(0); + e->parsed = desc; + digestmap_set(rend_cache_v2_dir, "abcde", e); + + hid_serv_responsible_for_desc_id_response = 1; + rend_cache_clean_v2_descs_as_dir(now, 20000); + tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 1); + + + + done: + NS_UNMOCK(hid_serv_responsible_for_desc_id); + rend_cache_purge(); +} + +#undef NS_SUBMODULE + + +static void +test_rend_cache_entry_allocation(void *data) +{ + (void)data; + + int ret; + rend_cache_entry_t *e; + + // Handles a null argument + ret = rend_cache_entry_allocation(NULL); + tt_int_op(ret, OP_EQ, 0); + + // Handles a non-null argument + e = tor_malloc_zero(sizeof(rend_cache_entry_t)); + ret = rend_cache_entry_allocation(e); + tt_int_op(ret, OP_EQ, 88); + + done: + (void)0; +} + +static void +test_rend_cache_failure_intro_entry_free(void *data) +{ + (void)data; + rend_cache_failure_intro_t *entry; + + // Handles a null argument + rend_cache_failure_intro_entry_free(NULL); + + // Handles a non-null argument + entry = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); + rend_cache_failure_intro_entry_free(entry); +} + + +static void +test_rend_cache_failure_purge(void *data) +{ + (void)data; + + // Handles a null failure cache + rend_cache_failure = NULL; + + rend_cache_failure_purge(); + + tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); + + done: + (void)0; +} + +static void +test_rend_cache_validate_intro_point_failure(void *data) +{ + (void)data; + rend_service_descriptor_t *desc = NULL; + char *service_id = NULL; + rend_intro_point_t *intro = NULL; + const uint8_t *identity = NULL; + rend_cache_failure_t *failure; + rend_cache_failure_intro_t *ip; + + rend_cache_init(); + + create_descriptor(&desc, &service_id, 3); + desc->timestamp = time(NULL) + RECENT_TIME; + + intro = (rend_intro_point_t *)smartlist_get(desc->intro_nodes, 0); + identity = (uint8_t *) intro->extend_info->identity_digest; + + failure = rend_cache_failure_entry_new(); + ip = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); + digestmap_set(failure->intro_failures, (char *)identity, ip); + strmap_set_lc(rend_cache_failure, service_id, failure); + + // Test when we have an intro point in our cache + validate_intro_point_failure(desc, service_id); + tt_int_op(smartlist_len(desc->intro_nodes), OP_EQ, 2); + + done: + rend_cache_purge(); +} + +struct testcase_t rend_cache_tests[] = { + { "init", test_rend_cache_init, 0, NULL, NULL }, + { "decrement_allocation", test_rend_cache_decrement_allocation, 0, NULL, NULL }, + { "increment_allocation", test_rend_cache_increment_allocation, 0, NULL, NULL }, + { "clean", test_rend_cache_clean, TT_FORK, NULL, NULL }, + { "clean_v2_descs_as_dir", test_rend_cache_clean_v2_descs_as_dir, 0, NULL, NULL }, + { "entry_allocation", test_rend_cache_entry_allocation, 0, NULL, NULL }, + { "entry_free", test_rend_cache_entry_free, 0, NULL, NULL }, + { "failure_intro_entry_free", test_rend_cache_failure_intro_entry_free, 0, NULL, NULL }, + { "free_all", test_rend_cache_free_all, 0, NULL, NULL }, + { "purge", test_rend_cache_purge, 0, NULL, NULL }, + { "failure_clean", test_rend_cache_failure_clean, 0, NULL, NULL }, + { "failure_entry_new", test_rend_cache_failure_entry_new, 0, NULL, NULL }, + { "failure_entry_free", test_rend_cache_failure_entry_free, 0, NULL, NULL }, + { "failure_intro_add", test_rend_cache_failure_intro_add, 0, NULL, NULL }, + { "failure_intro_entry_new", test_rend_cache_failure_intro_entry_new, 0, NULL, NULL }, + { "failure_intro_lookup", test_rend_cache_failure_intro_lookup, 0, NULL, NULL }, + { "failure_purge", test_rend_cache_failure_purge, 0, NULL, NULL }, + { "failure_remove", test_rend_cache_failure_remove, 0, NULL, NULL }, + { "intro_failure_note", test_rend_cache_intro_failure_note, 0, NULL, NULL }, + { "lookup", test_rend_cache_lookup_entry, 0, NULL, NULL }, + { "lookup_v2_desc_as_dir", test_rend_cache_lookup_v2_desc_as_dir, 0, NULL, NULL }, + { "store_v2_desc_as_client", test_rend_cache_store_v2_desc_as_client, 0, NULL, NULL }, + { "store_v2_desc_as_client_with_different_time", test_rend_cache_store_v2_desc_as_client_with_different_time, 0, NULL, NULL }, + { "store_v2_desc_as_dir", test_rend_cache_store_v2_desc_as_dir, 0, NULL, NULL }, + { "store_v2_desc_as_dir_with_different_time", test_rend_cache_store_v2_desc_as_dir_with_different_time, 0, NULL, NULL }, + { "store_v2_desc_as_dir_with_different_content", test_rend_cache_store_v2_desc_as_dir_with_different_content, 0, NULL, NULL }, + { "validate_intro_point_failure", test_rend_cache_validate_intro_point_failure, 0, NULL, NULL }, + END_OF_TESTCASES +};
[View Less]
1
0
0
0
[tor/master] Merge remote-tracking branch 'twstrike/rendcache_tests'
by nickm@torproject.org
06 Oct '15
06 Oct '15
commit f179abdca935d6d119f66e469232b36955a292b4 Merge: 2592d53 70de8d4 Author: Nick Mathewson <nickm(a)torproject.org> Date: Tue Oct 6 11:32:06 2015 -0400 Merge remote-tracking branch 'twstrike/rendcache_tests' Conflicts: src/test/include.am src/test/rend_test_helpers.c src/test/rend_test_helpers.h src/or/rendcache.c | 34 +- src/or/rendcache.h | 24 + src/or/routerlist.c | 1 - src/or/routerlist.h | 1
…
[View More]
- src/test/include.am | 3 +- src/test/rend_test_helpers.c | 5 +- src/test/test.c | 2 + src/test/test_rendcache.c | 1254 ++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 1303 insertions(+), 21 deletions(-) diff --cc src/or/rendcache.c index 3d3beb0,800cc24..fddedf1 --- a/src/or/rendcache.c +++ b/src/or/rendcache.c @@@ -15,14 -16,11 +16,14 @@@ /** Map from service id (as generated by rend_get_service_id) to * rend_cache_entry_t. */ - static strmap_t *rend_cache = NULL; + STATIC strmap_t *rend_cache = NULL; +/** Map from service id to rend_cache_entry_t; only for hidden services. */ +static strmap_t *rend_cache_local_service = NULL; + /** Map from descriptor id to rend_cache_entry_t; only for hidden service * directories. */ - static digestmap_t *rend_cache_v2_dir = NULL; + STATIC digestmap_t *rend_cache_v2_dir = NULL; /** (Client side only) Map from service id to rend_cache_failure_t. This * cache is used to track intro point(IP) failures so we know when to keep diff --cc src/or/rendcache.h index a5ad2da,4f55240..a0cb68e --- a/src/or/rendcache.h +++ b/src/or/rendcache.h @@@ -85,5 -76,28 +85,29 @@@ void rend_cache_intro_failure_note(rend const char *service_id); void rend_cache_failure_purge(void); + #ifdef RENDCACHE_PRIVATE + + STATIC size_t rend_cache_entry_allocation(const rend_cache_entry_t *e); + STATIC void rend_cache_entry_free(rend_cache_entry_t *e); + STATIC void rend_cache_failure_intro_entry_free(rend_cache_failure_intro_t + *entry); + STATIC void rend_cache_failure_entry_free(rend_cache_failure_t *entry); + STATIC int cache_failure_intro_lookup(const uint8_t *identity, + const char *service_id, + rend_cache_failure_intro_t + **intro_entry); + STATIC void rend_cache_decrement_allocation(size_t n); + STATIC void rend_cache_increment_allocation(size_t n); + STATIC rend_cache_failure_intro_t *rend_cache_failure_intro_entry_new( + rend_intro_point_failure_t failure); + STATIC rend_cache_failure_t *rend_cache_failure_entry_new(void); + STATIC void rend_cache_failure_remove(rend_service_descriptor_t *desc); + STATIC void cache_failure_intro_add(const uint8_t *identity, + const char *service_id, + rend_intro_point_failure_t failure); + STATIC void validate_intro_point_failure(const rend_service_descriptor_t *desc, + const char *service_id); + #endif + #endif /* TOR_RENDCACHE_H */ + diff --cc src/test/include.am index e056138,a9ad570..67bc600 --- a/src/test/include.am +++ b/src/test/include.am @@@ -49,7 -51,7 +49,8 @@@ src_test_AM_CPPFLAGS = -DSHARE_DATADIR= # matters a lot there, and is quite hard to debug if you forget to do it. src_test_test_SOURCES = \ + src/test/log_test_helpers.c \ + src/test/rend_test_helpers.c \ src/test/test.c \ src/test/test_accounting.c \ src/test/test_addr.c \ @@@ -96,12 -97,9 +98,11 @@@ src/test/test_socks.c \ src/test/test_status.c \ src/test/test_threads.c \ + src/test/test_tortls.c \ src/test/test_util.c \ + src/test/test_util_format.c \ src/test/test_helpers.c \ - src/test/rend_test_helpers.c \ - src/test/test_dns.c \ + src/test/test_dns.c \ src/test/testing_common.c \ src/ext/tinytest.c diff --cc src/test/rend_test_helpers.c index 0a1b1c8,615ef7b..f076d76 --- a/src/test/rend_test_helpers.c +++ b/src/test/rend_test_helpers.c @@@ -1,8 -1,9 +1,11 @@@ --#include "rend_test_helpers.h" ++/* Copyright (c) 2014-2015, The Tor Project, Inc. */ ++/* See LICENSE for licensing information */ ++#include "or.h" #include "test.h" #include "rendcommon.h" ++#include "rend_test_helpers.h" -/** TODO: Description */ void generate_desc(int time_diff, rend_encoded_v2_service_descriptor_t **desc, char **service_id, int intro_points) diff --cc src/test/test_rendcache.c index 0000000,1213d54..f21c7c4 mode 000000,100644..100644 --- a/src/test/test_rendcache.c +++ b/src/test/test_rendcache.c @@@ -1,0 -1,1253 +1,1254 @@@ + /* Copyright (c) 2010-2015, The Tor Project, Inc. */ + /* See LICENSE for licensing information */ + + #include "orconfig.h" + #include "or.h" + + #include "test.h" + #define RENDCACHE_PRIVATE + #include "rendcache.h" + #include "router.h" + #include "routerlist.h" + #include "config.h" + #include <openssl/rsa.h> + #include "rend_test_helpers.h" + + #define NS_MODULE rend_cache + + static const int RECENT_TIME = -10; + static const int TIME_IN_THE_PAST = -(REND_CACHE_MAX_AGE + \ + REND_CACHE_MAX_SKEW + 10); + static const int TIME_IN_THE_FUTURE = REND_CACHE_MAX_SKEW + 10; + + extern strmap_t *rend_cache; + extern digestmap_t *rend_cache_v2_dir; + extern strmap_t *rend_cache_failure; + extern size_t rend_cache_total_allocation; + + static rend_data_t + mock_rend_data(char *onion_address) + { + rend_data_t rend_query; + + memset(&rend_query, 0, sizeof(rend_query)); + strncpy(rend_query.onion_address, onion_address, + REND_SERVICE_ID_LEN_BASE32+1); + rend_query.auth_type = REND_NO_AUTH; + rend_query.hsdirs_fp = smartlist_new(); + smartlist_add(rend_query.hsdirs_fp, tor_memdup("aaaaaaaaaaaaaaaaaaaaaaaa", + DIGEST_LEN)); + + return rend_query; + } + + static void + test_rend_cache_lookup_entry(void *data) + { + int ret; + rend_data_t mock_rend_query; + char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; + rend_cache_entry_t *entry = NULL; + rend_encoded_v2_service_descriptor_t *desc_holder = NULL; + char *service_id = NULL; + (void)data; + + rend_cache_init(); + + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + + ret = rend_cache_lookup_entry("abababababababab", 0, NULL); + tt_int_op(ret, OP_EQ, -ENOENT); + + ret = rend_cache_lookup_entry("invalid query", 2, NULL); + tt_int_op(ret, OP_EQ, -EINVAL); + + ret = rend_cache_lookup_entry("abababababababab", 2, NULL); + tt_int_op(ret, OP_EQ, -ENOENT); + + ret = rend_cache_lookup_entry("abababababababab", 4224, NULL); + tt_int_op(ret, OP_EQ, -ENOENT); + + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, + &mock_rend_query, NULL); + + ret = rend_cache_lookup_entry(service_id, 2, NULL); + tt_int_op(ret, OP_EQ, 0); + + ret = rend_cache_lookup_entry(service_id, 2, &entry); + tt_assert(entry); + tt_int_op(entry->len, OP_EQ, strlen(desc_holder->desc_str)); + tt_str_op(entry->desc, OP_EQ, desc_holder->desc_str); + + done: + tor_free(desc_holder); + tor_free(entry); + tor_free(service_id); + } + + static void + test_rend_cache_store_v2_desc_as_client(void *data) + { + rend_cache_store_status_t ret; + rend_data_t mock_rend_query; + char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; + rend_cache_entry_t *entry = NULL; + rend_encoded_v2_service_descriptor_t *desc_holder = NULL; + char *service_id = NULL; + char client_cookie[REND_DESC_COOKIE_LEN]; + (void)data; + + rend_cache_init(); + + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + + // Test success + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + &entry); + + tt_int_op(ret, OP_EQ, RCS_OKAY); + tt_assert(entry); + tt_int_op(entry->len, OP_EQ, strlen(desc_holder->desc_str)); + tt_str_op(entry->desc, OP_EQ, desc_holder->desc_str); + + // Test various failure modes + + // TODO: a too long desc_id_base32 argument crashes the function + /* ret = rend_cache_store_v2_desc_as_client( */ + /* desc_holder->desc_str, */ + /* "3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG", */ + /* &mock_rend_query, NULL); */ + /* tt_int_op(ret, OP_EQ, RCS_BADDESC); */ + + // Test bad base32 failure + // This causes an assertion failure if we're running with assertions. + // But when doing coverage, we can test it. + #ifdef TOR_COVERAGE + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + "!xqunszqnaolrrfmtzgaki7mxelgvkj", &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + #endif + + // Test invalid descriptor + ret = rend_cache_store_v2_desc_as_client("invalid descriptor", + "3xqunszqnaolrrfmtzgaki7mxelgvkje", &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + + // TODO: it doesn't seem to be possible to test invalid service ID condition. + // that means it is likely not possible to have that condition without + // earlier conditions failing first (such as signature checking of the desc) + + // Test mismatch between service ID and onion address + rend_cache_init(); + strncpy(mock_rend_query.onion_address, "abc", REND_SERVICE_ID_LEN_BASE32+1); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, + &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + + // Test incorrect descriptor ID + rend_cache_init(); + mock_rend_query = mock_rend_data(service_id); + desc_id_base32[0]++; + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + desc_id_base32[0]--; + + // Test too old descriptor + rend_cache_init(); + tor_free(desc_holder); + tor_free(service_id); + + generate_desc(TIME_IN_THE_PAST, &desc_holder, &service_id, 3); + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, + &mock_rend_query, NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + + // Test too new descriptor (in the future) + rend_cache_init(); + tor_free(desc_holder); + tor_free(service_id); + + generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3); + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + + // Test when a descriptor is already in the cache + rend_cache_init(); + tor_free(desc_holder); + tor_free(service_id); + tor_free(entry); + + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + + rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, + &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + NULL); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + &entry); + tt_int_op(ret, OP_EQ, RCS_OKAY); + tt_assert(entry); + + // Test unsuccessful decrypting of introduction points + rend_cache_init(); + tor_free(desc_holder); + tor_free(service_id); + + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + mock_rend_query = mock_rend_data(service_id); + mock_rend_query.auth_type = REND_BASIC_AUTH; + client_cookie[0] = 'A'; + memcpy(mock_rend_query.descriptor_cookie, client_cookie, + REND_DESC_COOKIE_LEN); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + NULL); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test successful run when we have REND_BASIC_AUTH but not cookie + rend_cache_init(); + tor_free(desc_holder); + tor_free(service_id); + + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + mock_rend_query = mock_rend_data(service_id); + mock_rend_query.auth_type = REND_BASIC_AUTH; + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + NULL); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test when we have no introduction points + rend_cache_init(); + tor_free(desc_holder); + tor_free(service_id); + + generate_desc(RECENT_TIME, &desc_holder, &service_id, 0); + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + + // Test when we have too many intro points + rend_cache_init(); + tor_free(desc_holder); + tor_free(service_id); + + generate_desc(RECENT_TIME, &desc_holder, &service_id, MAX_INTRO_POINTS+1); + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + NULL); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + + done: + rend_encoded_v2_service_descriptor_free(desc_holder); + tor_free(entry); + tor_free(service_id); + } + + static void + test_rend_cache_store_v2_desc_as_client_with_different_time(void *data) + { + rend_cache_store_status_t ret; + rend_data_t mock_rend_query; + char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; + rend_service_descriptor_t *generated = NULL; + smartlist_t *descs = smartlist_new(); + time_t t; + char *service_id = NULL; + rend_encoded_v2_service_descriptor_t *desc_holder_newer; + rend_encoded_v2_service_descriptor_t *desc_holder_older; + + t = time(NULL); + + create_descriptor(&generated, &service_id, 3); + + generated->timestamp = t + RECENT_TIME; + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, + REND_NO_AUTH, NULL, NULL); + desc_holder_newer = ((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0)); + + smartlist_free(descs); + descs = smartlist_new(); + + generated->timestamp = (t + RECENT_TIME) - 20; + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, + REND_NO_AUTH, NULL, NULL); + desc_holder_older = ((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0)); + + (void)data; + rend_cache_init(); + + // Test when a descriptor is already in the cache and it is newer than the + // one we submit + mock_rend_query = mock_rend_data(service_id); + base32_encode(desc_id_base32, sizeof(desc_id_base32), + desc_holder_newer->desc_id, DIGEST_LEN); + rend_cache_store_v2_desc_as_client(desc_holder_newer->desc_str, + desc_id_base32, &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client(desc_holder_older->desc_str, + desc_id_base32, &mock_rend_query, + NULL); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test when an old descriptor is in the cache and we submit a newer one + rend_cache_init(); + rend_cache_store_v2_desc_as_client(desc_holder_older->desc_str, + desc_id_base32, &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client(desc_holder_newer->desc_str, + desc_id_base32, &mock_rend_query, + NULL); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + done: + rend_encoded_v2_service_descriptor_free(desc_holder_newer); + rend_encoded_v2_service_descriptor_free(desc_holder_older); + smartlist_free(descs); + rend_service_descriptor_free(generated); + tor_free(service_id); + } + + #define NS_SUBMODULE lookup_v2_desc_as_dir + NS_DECL(const routerinfo_t *, router_get_my_routerinfo, (void)); + NS_DECL(int, hid_serv_responsible_for_desc_id, (const char *id)); + + static routerinfo_t *mock_routerinfo; + static int hid_serv_responsible_for_desc_id_response; + + static const routerinfo_t * + NS(router_get_my_routerinfo)(void) + { + if (!mock_routerinfo) { + mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); + } + + return mock_routerinfo; + } + + static int + NS(hid_serv_responsible_for_desc_id)(const char *id) + { + (void)id; + return hid_serv_responsible_for_desc_id_response; + } + + static void + test_rend_cache_lookup_v2_desc_as_dir(void *data) + { + int ret; + char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; + rend_encoded_v2_service_descriptor_t *desc_holder = NULL; + char *service_id = NULL; + const char *ret_desc = NULL; + + (void)data; + + NS_MOCK(router_get_my_routerinfo); + NS_MOCK(hid_serv_responsible_for_desc_id); + + rend_cache_init(); + + // Test invalid base32 + ret = rend_cache_lookup_v2_desc_as_dir("!bababababababab", NULL); + tt_int_op(ret, OP_EQ, -1); + + // Test non-existent descriptor but well formed + ret = rend_cache_lookup_v2_desc_as_dir("3xqunszqnaolrrfmtzgaki7mxelgvkje", + NULL); + tt_int_op(ret, OP_EQ, 0); + + // Test existing descriptor + hid_serv_responsible_for_desc_id_response = 1; + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + ret = rend_cache_lookup_v2_desc_as_dir(desc_id_base32, &ret_desc); + tt_int_op(ret, OP_EQ, 1); + tt_assert(ret_desc); + + done: + NS_UNMOCK(router_get_my_routerinfo); + NS_UNMOCK(hid_serv_responsible_for_desc_id); + tor_free(mock_routerinfo); + } + + #undef NS_SUBMODULE + + #define NS_SUBMODULE store_v2_desc_as_dir + NS_DECL(const routerinfo_t *, router_get_my_routerinfo, (void)); + NS_DECL(int, hid_serv_responsible_for_desc_id, (const char *id)); + + static const routerinfo_t * + NS(router_get_my_routerinfo)(void) + { + return mock_routerinfo; + } + + static int + NS(hid_serv_responsible_for_desc_id)(const char *id) + { + (void)id; + return hid_serv_responsible_for_desc_id_response; + } + + static void + test_rend_cache_store_v2_desc_as_dir(void *data) + { + (void)data; + rend_cache_store_status_t ret; + rend_encoded_v2_service_descriptor_t *desc_holder = NULL; + char *service_id = NULL; + + NS_MOCK(router_get_my_routerinfo); + NS_MOCK(hid_serv_responsible_for_desc_id); + + rend_cache_init(); + + // Test when we are not an HS dir + mock_routerinfo = NULL; + ret = rend_cache_store_v2_desc_as_dir(""); + tt_int_op(ret, OP_EQ, RCS_NOTDIR); + + // Test when we can't parse the descriptor + mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); + hid_serv_responsible_for_desc_id_response = 1; + ret = rend_cache_store_v2_desc_as_dir("unparseable"); + tt_int_op(ret, OP_EQ, RCS_BADDESC); + + // Test when we are not responsible for an HS + hid_serv_responsible_for_desc_id_response = 0; + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test when we have an old descriptor + hid_serv_responsible_for_desc_id_response = 1; + generate_desc(TIME_IN_THE_PAST, &desc_holder, &service_id, 3); + ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test when we have a descriptor in the future + generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3); + ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test when two descriptors + generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3); + ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test when asking for hidden service statistics HiddenServiceStatistics + rend_cache_purge(); + generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); + get_options_mutable()->HiddenServiceStatistics = 1; + ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + done: + NS_UNMOCK(router_get_my_routerinfo); + NS_UNMOCK(hid_serv_responsible_for_desc_id); + tor_free(desc_holder); + tor_free(service_id); + } + + static void + test_rend_cache_store_v2_desc_as_dir_with_different_time(void *data) + { + (void)data; + + rend_cache_store_status_t ret; + rend_service_descriptor_t *generated = NULL; + smartlist_t *descs = smartlist_new(); + time_t t; + char *service_id = NULL; + rend_encoded_v2_service_descriptor_t *desc_holder_newer; + rend_encoded_v2_service_descriptor_t *desc_holder_older; + + NS_MOCK(router_get_my_routerinfo); + NS_MOCK(hid_serv_responsible_for_desc_id); + + rend_cache_init(); + + t = time(NULL); + + create_descriptor(&generated, &service_id, 3); + generated->timestamp = t + RECENT_TIME; + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, + REND_NO_AUTH, NULL, NULL); + desc_holder_newer = ((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0)); + + smartlist_free(descs); + descs = smartlist_new(); + + generated->timestamp = (t + RECENT_TIME) - 20; + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, + REND_NO_AUTH, NULL, NULL); + desc_holder_older = ((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0)); + + // Test when we have a newer descriptor stored + mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); + hid_serv_responsible_for_desc_id_response = 1; + rend_cache_store_v2_desc_as_dir(desc_holder_newer->desc_str); + ret = rend_cache_store_v2_desc_as_dir(desc_holder_older->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + // Test when we have an old descriptor stored + rend_cache_purge(); + rend_cache_store_v2_desc_as_dir(desc_holder_older->desc_str); + ret = rend_cache_store_v2_desc_as_dir(desc_holder_newer->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + done: + NS_UNMOCK(router_get_my_routerinfo); + NS_UNMOCK(hid_serv_responsible_for_desc_id); + } + + static void + test_rend_cache_store_v2_desc_as_dir_with_different_content(void *data) + { + (void)data; + + rend_cache_store_status_t ret; + rend_service_descriptor_t *generated = NULL; + smartlist_t *descs = smartlist_new(); + time_t t; + char *service_id = NULL; + rend_encoded_v2_service_descriptor_t *desc_holder_one; + rend_encoded_v2_service_descriptor_t *desc_holder_two; + + NS_MOCK(router_get_my_routerinfo); + NS_MOCK(hid_serv_responsible_for_desc_id); + + rend_cache_init(); + + t = time(NULL); + + create_descriptor(&generated, &service_id, 3); + generated->timestamp = t + RECENT_TIME; + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, + REND_NO_AUTH, NULL, NULL); + desc_holder_one = ((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0)); + + smartlist_free(descs); + descs = smartlist_new(); + + generated->timestamp = t + RECENT_TIME; + generated->protocols = 41; + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, + REND_NO_AUTH, NULL, NULL); + desc_holder_two = ((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0)); + + // Test when we have another descriptor stored, with a different descriptor + mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); + hid_serv_responsible_for_desc_id_response = 1; + rend_cache_store_v2_desc_as_dir(desc_holder_one->desc_str); + ret = rend_cache_store_v2_desc_as_dir(desc_holder_two->desc_str); + tt_int_op(ret, OP_EQ, RCS_OKAY); + + done: + NS_UNMOCK(router_get_my_routerinfo); + NS_UNMOCK(hid_serv_responsible_for_desc_id); + } + + #undef NS_SUBMODULE + + static void + test_rend_cache_init(void *data) + { + (void)data; + + tt_assert_msg(!rend_cache, "rend_cache should be NULL when starting"); + tt_assert_msg(!rend_cache_v2_dir, "rend_cache_v2_dir should be NULL " + "when starting"); + tt_assert_msg(!rend_cache_failure, "rend_cache_failure should be NULL when " + "starting"); + + rend_cache_init(); + + tt_assert_msg(rend_cache, "rend_cache should not be NULL after initing"); + tt_assert_msg(rend_cache_v2_dir, "rend_cache_v2_dir should not be NULL " + "after initing"); + tt_assert_msg(rend_cache_failure, "rend_cache_failure should not be NULL " + "after initing"); + + tt_int_op(strmap_size(rend_cache), OP_EQ, 0); + tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); + tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); + + done: + (void)0; + } + + static void + test_rend_cache_decrement_allocation(void *data) + { + (void)data; + + // Test when the cache has enough allocations + rend_cache_total_allocation = 10; + rend_cache_decrement_allocation(3); + tt_int_op(rend_cache_total_allocation, OP_EQ, 7); + + // Test when there are not enough allocations + rend_cache_total_allocation = 1; + rend_cache_decrement_allocation(2); + tt_int_op(rend_cache_total_allocation, OP_EQ, 0); + + // And again + rend_cache_decrement_allocation(2); + tt_int_op(rend_cache_total_allocation, OP_EQ, 0); + + done: + (void)0; + } + + static void + test_rend_cache_increment_allocation(void *data) + { + (void)data; + + // Test when the cache is not overflowing + rend_cache_total_allocation = 5; + rend_cache_increment_allocation(3); + tt_int_op(rend_cache_total_allocation, OP_EQ, 8); + + // Test when there are too many allocations + rend_cache_total_allocation = SIZE_MAX-1; + rend_cache_increment_allocation(2); + tt_int_op(rend_cache_total_allocation, OP_EQ, SIZE_MAX); + + // And again + rend_cache_increment_allocation(2); + tt_int_op(rend_cache_total_allocation, OP_EQ, SIZE_MAX); + + done: + (void)0; + } + + static void + test_rend_cache_failure_intro_entry_new(void *data) + { + time_t now; + rend_cache_failure_intro_t *entry; + rend_intro_point_failure_t failure; + + (void)data; + + failure = INTRO_POINT_FAILURE_TIMEOUT; + now = time(NULL); + entry = rend_cache_failure_intro_entry_new(failure); + + tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_TIMEOUT); + tt_int_op(entry->created_ts, OP_GE, now-5); + tt_int_op(entry->created_ts, OP_LE, now+5); + + done: + tor_free(entry); + } + + static void + test_rend_cache_failure_intro_lookup(void *data) + { + (void)data; + int ret; + rend_cache_failure_t *failure; + rend_cache_failure_intro_t *ip; + rend_cache_failure_intro_t *entry; + + rend_cache_init(); + + failure = rend_cache_failure_entry_new(); + ip = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); + digestmap_set(failure->intro_failures, "ip1", ip); + strmap_set_lc(rend_cache_failure, "foo1", failure); + + // Test not found + ret = cache_failure_intro_lookup((const uint8_t *)"foo1", "foo2", NULL); + tt_int_op(ret, OP_EQ, 0); + + // Test found with no intro failures in it + ret = cache_failure_intro_lookup((const uint8_t *)"ip2", "foo1", NULL); + tt_int_op(ret, OP_EQ, 0); + + // Test found + ret = cache_failure_intro_lookup((const uint8_t *)"ip1", "foo1", NULL); + tt_int_op(ret, OP_EQ, 1); + + // Test found and asking for entry + cache_failure_intro_lookup((const uint8_t *)"ip1", "foo1", &entry); + tt_assert(entry); + tt_assert(entry == ip); + + done: + rend_cache_purge(); + } + + static void + test_rend_cache_clean(void *data) + { + rend_cache_entry_t *one, *two; + rend_service_descriptor_t *desc_one, *desc_two; + strmap_iter_t *iter = NULL; + const char *key; + void *val; + + (void)data; + + rend_cache_init(); + + // Test with empty rendcache - rend_cache_clean(time(NULL)); ++ rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT); + tt_int_op(strmap_size(rend_cache), OP_EQ, 0); + + // Test with two old entries + one = tor_malloc_zero(sizeof(rend_cache_entry_t)); + two = tor_malloc_zero(sizeof(rend_cache_entry_t)); + desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + desc_two = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + one->parsed = desc_one; + two->parsed = desc_two; + + desc_one->timestamp = time(NULL) + TIME_IN_THE_PAST; + desc_two->timestamp = (time(NULL) + TIME_IN_THE_PAST) - 10; + desc_one->pk = pk_generate(0); + desc_two->pk = pk_generate(1); + + strmap_set_lc(rend_cache, "foo1", one); + strmap_set_lc(rend_cache, "foo2", two); + - rend_cache_clean(time(NULL)); ++ rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT); + tt_int_op(strmap_size(rend_cache), OP_EQ, 0); + + // Test with one old entry and one newer entry + one = tor_malloc_zero(sizeof(rend_cache_entry_t)); + two = tor_malloc_zero(sizeof(rend_cache_entry_t)); + desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + desc_two = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + one->parsed = desc_one; + two->parsed = desc_two; + + desc_one->timestamp = (time(NULL) + TIME_IN_THE_PAST) - 10; + desc_two->timestamp = time(NULL) - 100; + desc_one->pk = pk_generate(0); + desc_two->pk = pk_generate(1); + + strmap_set_lc(rend_cache, "foo1", one); + strmap_set_lc(rend_cache, "foo2", two); + - rend_cache_clean(time(NULL)); ++ rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT); + tt_int_op(strmap_size(rend_cache), OP_EQ, 1); + + iter = strmap_iter_init(rend_cache); + strmap_iter_get(iter, &key, &val); + tt_str_op(key, OP_EQ, "foo2"); + + done: + (void)1; + } + + static void + test_rend_cache_failure_entry_new(void *data) + { + rend_cache_failure_t *failure; + + (void)data; + + failure = rend_cache_failure_entry_new(); + tt_assert(failure); + tt_int_op(digestmap_size(failure->intro_failures), OP_EQ, 0); + + done: + tor_free(failure); + } + + static void + test_rend_cache_failure_entry_free(void *data) + { + (void)data; + + // Test that it can deal with a NULL argument + rend_cache_failure_entry_free(NULL); + + /* done: */ + /* (void)0; */ + } + + static void + test_rend_cache_failure_clean(void *data) + { + rend_cache_failure_t *failure; + rend_cache_failure_intro_t *ip_one, *ip_two; + + (void)data; + + rend_cache_init(); + + // Test with empty failure cache + rend_cache_failure_clean(time(NULL)); + tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); + + // Test with one empty failure entry + failure = rend_cache_failure_entry_new(); + strmap_set_lc(rend_cache_failure, "foo1", failure); + rend_cache_failure_clean(time(NULL)); + tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); + + // Test with one new intro point + failure = rend_cache_failure_entry_new(); + ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); + digestmap_set(failure->intro_failures, "ip1", ip_one); + strmap_set_lc(rend_cache_failure, "foo1", failure); + rend_cache_failure_clean(time(NULL)); + tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 1); + + // Test with one old intro point + rend_cache_failure_purge(); + failure = rend_cache_failure_entry_new(); + ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); + ip_one->created_ts = time(NULL) - 7*60; + digestmap_set(failure->intro_failures, "ip1", ip_one); + strmap_set_lc(rend_cache_failure, "foo1", failure); + rend_cache_failure_clean(time(NULL)); + tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); + + // Test with one old intro point and one new one + rend_cache_failure_purge(); + failure = rend_cache_failure_entry_new(); + ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); + ip_one->created_ts = time(NULL) - 7*60; + digestmap_set(failure->intro_failures, "ip1", ip_one); + ip_two = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); + ip_two->created_ts = time(NULL) - 2*60; + digestmap_set(failure->intro_failures, "ip2", ip_two); + strmap_set_lc(rend_cache_failure, "foo1", failure); + rend_cache_failure_clean(time(NULL)); + tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 1); + tt_int_op(digestmap_size(failure->intro_failures), OP_EQ, 1); + + done: + (void)0; + } + + static void + test_rend_cache_failure_remove(void *data) + { + rend_service_descriptor_t *desc; + (void)data; + + rend_cache_init(); + + // Test that it deals well with a NULL desc + rend_cache_failure_remove(NULL); + + // Test a descriptor that isn't in the cache + desc = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + desc->pk = pk_generate(0); + rend_cache_failure_remove(desc); + + // There seems to not exist any way of getting rend_cache_failure_remove() + // to fail because of a problem with rend_get_service_id from here + + /* done: */ + /* (void)0; */ + } + + static void + test_rend_cache_free_all(void *data) + { + rend_cache_failure_t *failure; + rend_cache_entry_t *one; + rend_service_descriptor_t *desc_one; + + (void)data; + + rend_cache_init(); + + failure = rend_cache_failure_entry_new(); + strmap_set_lc(rend_cache_failure, "foo1", failure); + + one = tor_malloc_zero(sizeof(rend_cache_entry_t)); + desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + one->parsed = desc_one; + desc_one->timestamp = time(NULL) + TIME_IN_THE_PAST; + desc_one->pk = pk_generate(0); + strmap_set_lc(rend_cache, "foo1", one); + + rend_cache_free_all(); + + tt_assert(!rend_cache); + tt_assert(!rend_cache_v2_dir); + tt_assert(!rend_cache_failure); + tt_assert(!rend_cache_total_allocation); + + done: + (void)0; + } + + static void + test_rend_cache_entry_free(void *data) + { + (void)data; + rend_cache_entry_t *e; + + // Handles NULL correctly + rend_cache_entry_free(NULL); + + // Handles NULL descriptor correctly + e = tor_malloc_zero(sizeof(rend_cache_entry_t)); + rend_cache_entry_free(e); + + // Handles non-NULL descriptor correctly + e = tor_malloc_zero(sizeof(rend_cache_entry_t)); + e->desc = (char *)malloc(10); + rend_cache_entry_free(e); + + /* done: */ + /* (void)0; */ + } + + static void + test_rend_cache_purge(void *data) + { + strmap_t *our_rend_cache; + + (void)data; + + // Deals with a NULL rend_cache + rend_cache_purge(); + tt_assert(rend_cache); + tt_int_op(strmap_size(rend_cache), OP_EQ, 0); + + // Deals with existing rend_cache + rend_cache_init(); + + our_rend_cache = rend_cache; + rend_cache_purge(); + tt_assert(rend_cache); + tt_assert(rend_cache == our_rend_cache); + + done: + (void)0; + } + + static void + test_rend_cache_failure_intro_add(void *data) + { + (void)data; + rend_cache_failure_t *fail_entry; + rend_cache_failure_intro_t *entry; + + rend_cache_init(); + + // Adds non-existing entry + cache_failure_intro_add((const uint8_t *)"foo1", "foo2", + INTRO_POINT_FAILURE_TIMEOUT); + fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); + tt_assert(fail_entry); + tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); + entry = digestmap_get(fail_entry->intro_failures, "foo1"); + tt_assert(entry); + + // Adds existing entry + cache_failure_intro_add((const uint8_t *)"foo1", "foo2", + INTRO_POINT_FAILURE_TIMEOUT); + fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); + tt_assert(fail_entry); + tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); + entry = digestmap_get(fail_entry->intro_failures, "foo1"); + tt_assert(entry); + + done: + rend_cache_purge(); + } + + static void + test_rend_cache_intro_failure_note(void *data) + { + (void)data; + rend_cache_failure_t *fail_entry; + rend_cache_failure_intro_t *entry; + + // Test not found + rend_cache_intro_failure_note(INTRO_POINT_FAILURE_TIMEOUT, + (const uint8_t *)"foo1", "foo2"); + fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); + tt_assert(fail_entry); + tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); + entry = digestmap_get(fail_entry->intro_failures, "foo1"); + tt_assert(entry); + tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_TIMEOUT); + + // Test found + rend_cache_intro_failure_note(INTRO_POINT_FAILURE_UNREACHABLE, + (const uint8_t *)"foo1", "foo2"); + tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_UNREACHABLE); + + done: + rend_cache_purge(); + } + + #define NS_SUBMODULE clean_v2_descs_as_dir + NS_DECL(int, hid_serv_responsible_for_desc_id, (const char *id)); + + static int + NS(hid_serv_responsible_for_desc_id)(const char *id) + { + (void)id; + return hid_serv_responsible_for_desc_id_response; + } + + static void + test_rend_cache_clean_v2_descs_as_dir(void *data) + { + rend_cache_entry_t *e; + time_t now; + rend_service_descriptor_t *desc; + now = time(NULL); + + (void)data; + + NS_MOCK(hid_serv_responsible_for_desc_id); + rend_cache_init(); + + // Test running with an empty cache + rend_cache_clean_v2_descs_as_dir(now, 0); + tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); + + // Test with only one new entry + e = tor_malloc_zero(sizeof(rend_cache_entry_t)); + e->last_served = now; + desc = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + desc->timestamp = now; + desc->pk = pk_generate(0); + e->parsed = desc; + digestmap_set(rend_cache_v2_dir, "abcde", e); + + hid_serv_responsible_for_desc_id_response = 1; + rend_cache_clean_v2_descs_as_dir(now, 0); + tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 1); + + // Test with one old entry + desc->timestamp = now - (REND_CACHE_MAX_AGE + REND_CACHE_MAX_SKEW + 1000); + rend_cache_clean_v2_descs_as_dir(now, 0); + tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); + + // Test with one entry that is not under the responsibility of this + // hidden service + e = tor_malloc_zero(sizeof(rend_cache_entry_t)); + e->last_served = now; + desc = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + desc->timestamp = now; + desc->pk = pk_generate(0); + e->parsed = desc; + digestmap_set(rend_cache_v2_dir, "abcde", e); + + hid_serv_responsible_for_desc_id_response = 0; + rend_cache_clean_v2_descs_as_dir(now, 0); + tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); + + // Test with one entry that has an old last served + e = tor_malloc_zero(sizeof(rend_cache_entry_t)); + e->last_served = now - (REND_CACHE_MAX_AGE + REND_CACHE_MAX_SKEW + 1000); + desc = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + desc->timestamp = now; + desc->pk = pk_generate(0); + e->parsed = desc; + digestmap_set(rend_cache_v2_dir, "abcde", e); + + hid_serv_responsible_for_desc_id_response = 1; + rend_cache_clean_v2_descs_as_dir(now, 0); + tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); + + // Test a run through asking for a large force_remove + e = tor_malloc_zero(sizeof(rend_cache_entry_t)); + e->last_served = now; + desc = tor_malloc_zero(sizeof(rend_service_descriptor_t)); + desc->timestamp = now; + desc->pk = pk_generate(0); + e->parsed = desc; + digestmap_set(rend_cache_v2_dir, "abcde", e); + + hid_serv_responsible_for_desc_id_response = 1; + rend_cache_clean_v2_descs_as_dir(now, 20000); + tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 1); + + done: + NS_UNMOCK(hid_serv_responsible_for_desc_id); + rend_cache_purge(); + } + + #undef NS_SUBMODULE + + static void + test_rend_cache_entry_allocation(void *data) + { + (void)data; + + int ret; + rend_cache_entry_t *e; + + // Handles a null argument + ret = rend_cache_entry_allocation(NULL); + tt_int_op(ret, OP_EQ, 0); + + // Handles a non-null argument + e = tor_malloc_zero(sizeof(rend_cache_entry_t)); + ret = rend_cache_entry_allocation(e); + tt_int_op(ret, OP_EQ, 88); + + done: + (void)0; + } + + static void + test_rend_cache_failure_intro_entry_free(void *data) + { + (void)data; + rend_cache_failure_intro_t *entry; + + // Handles a null argument + rend_cache_failure_intro_entry_free(NULL); + + // Handles a non-null argument + entry = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); + rend_cache_failure_intro_entry_free(entry); + } + + static void + test_rend_cache_failure_purge(void *data) + { + (void)data; + + // Handles a null failure cache + rend_cache_failure = NULL; + + rend_cache_failure_purge(); + + tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); + + done: + (void)0; + } + + static void + test_rend_cache_validate_intro_point_failure(void *data) + { + (void)data; + rend_service_descriptor_t *desc = NULL; + char *service_id = NULL; + rend_intro_point_t *intro = NULL; + const uint8_t *identity = NULL; + rend_cache_failure_t *failure; + rend_cache_failure_intro_t *ip; + + rend_cache_init(); + + create_descriptor(&desc, &service_id, 3); + desc->timestamp = time(NULL) + RECENT_TIME; + + intro = (rend_intro_point_t *)smartlist_get(desc->intro_nodes, 0); + identity = (uint8_t *) intro->extend_info->identity_digest; + + failure = rend_cache_failure_entry_new(); + ip = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); + digestmap_set(failure->intro_failures, (char *)identity, ip); + strmap_set_lc(rend_cache_failure, service_id, failure); + + // Test when we have an intro point in our cache + validate_intro_point_failure(desc, service_id); + tt_int_op(smartlist_len(desc->intro_nodes), OP_EQ, 2); + + done: + rend_cache_purge(); + } + + struct testcase_t rend_cache_tests[] = { + { "init", test_rend_cache_init, 0, NULL, NULL }, + { "decrement_allocation", test_rend_cache_decrement_allocation, 0, + NULL, NULL }, + { "increment_allocation", test_rend_cache_increment_allocation, 0, + NULL, NULL }, + { "clean", test_rend_cache_clean, TT_FORK, NULL, NULL }, + { "clean_v2_descs_as_dir", test_rend_cache_clean_v2_descs_as_dir, 0, + NULL, NULL }, + { "entry_allocation", test_rend_cache_entry_allocation, 0, NULL, NULL }, + { "entry_free", test_rend_cache_entry_free, 0, NULL, NULL }, + { "failure_intro_entry_free", test_rend_cache_failure_intro_entry_free, 0, + NULL, NULL }, + { "free_all", test_rend_cache_free_all, 0, NULL, NULL }, + { "purge", test_rend_cache_purge, 0, NULL, NULL }, + { "failure_clean", test_rend_cache_failure_clean, 0, NULL, NULL }, + { "failure_entry_new", test_rend_cache_failure_entry_new, 0, NULL, NULL }, + { "failure_entry_free", test_rend_cache_failure_entry_free, 0, NULL, NULL }, + { "failure_intro_add", test_rend_cache_failure_intro_add, 0, NULL, NULL }, + { "failure_intro_entry_new", test_rend_cache_failure_intro_entry_new, 0, + NULL, NULL }, + { "failure_intro_lookup", test_rend_cache_failure_intro_lookup, 0, + NULL, NULL }, + { "failure_purge", test_rend_cache_failure_purge, 0, NULL, NULL }, + { "failure_remove", test_rend_cache_failure_remove, 0, NULL, NULL }, + { "intro_failure_note", test_rend_cache_intro_failure_note, 0, NULL, NULL }, + { "lookup", test_rend_cache_lookup_entry, 0, NULL, NULL }, + { "lookup_v2_desc_as_dir", test_rend_cache_lookup_v2_desc_as_dir, 0, + NULL, NULL }, + { "store_v2_desc_as_client", test_rend_cache_store_v2_desc_as_client, 0, + NULL, NULL }, + { "store_v2_desc_as_client_with_different_time", + test_rend_cache_store_v2_desc_as_client_with_different_time, 0, + NULL, NULL }, + { "store_v2_desc_as_dir", test_rend_cache_store_v2_desc_as_dir, 0, + NULL, NULL }, + { "store_v2_desc_as_dir_with_different_time", + test_rend_cache_store_v2_desc_as_dir_with_different_time, 0, NULL, NULL }, + { "store_v2_desc_as_dir_with_different_content", + test_rend_cache_store_v2_desc_as_dir_with_different_content, 0, + NULL, NULL }, + { "validate_intro_point_failure", + test_rend_cache_validate_intro_point_failure, 0, NULL, NULL }, + END_OF_TESTCASES + }; ++
[View Less]
1
0
0
0
[tor/master] Fix spaces and other smaller issues
by nickm@torproject.org
06 Oct '15
06 Oct '15
commit 70de8d4bf86c430969bb314ba8590c00ce4dd374 Author: Ola Bini <ola(a)olabini.se> Date: Mon Oct 5 14:31:10 2015 -0500 Fix spaces and other smaller issues --- src/or/rendcache.h | 20 +++- src/test/rend_test_helpers.c | 10 +- src/test/rend_test_helpers.h | 6 +- src/test/test_rendcache.c | 265 +++++++++++++++++++++++++++--------------- 4 files changed, 194 insertions(+), 107 deletions(-) diff --git a/src/or/rendcache.h b/src/or/rendcache.h index 8ba1f6f..
…
[View More]
4f55240 100644 --- a/src/or/rendcache.h +++ b/src/or/rendcache.h @@ -76,20 +76,28 @@ void rend_cache_intro_failure_note(rend_intro_point_failure_t failure, const char *service_id); void rend_cache_failure_purge(void); - #ifdef RENDCACHE_PRIVATE + STATIC size_t rend_cache_entry_allocation(const rend_cache_entry_t *e); STATIC void rend_cache_entry_free(rend_cache_entry_t *e); -STATIC void rend_cache_failure_intro_entry_free(rend_cache_failure_intro_t *entry); +STATIC void rend_cache_failure_intro_entry_free(rend_cache_failure_intro_t + *entry); STATIC void rend_cache_failure_entry_free(rend_cache_failure_t *entry); -STATIC int cache_failure_intro_lookup(const uint8_t *identity, const char *service_id, rend_cache_failure_intro_t **intro_entry); +STATIC int cache_failure_intro_lookup(const uint8_t *identity, + const char *service_id, + rend_cache_failure_intro_t + **intro_entry); STATIC void rend_cache_decrement_allocation(size_t n); STATIC void rend_cache_increment_allocation(size_t n); -STATIC rend_cache_failure_intro_t *rend_cache_failure_intro_entry_new(rend_intro_point_failure_t failure); +STATIC rend_cache_failure_intro_t *rend_cache_failure_intro_entry_new( + rend_intro_point_failure_t failure); STATIC rend_cache_failure_t *rend_cache_failure_entry_new(void); STATIC void rend_cache_failure_remove(rend_service_descriptor_t *desc); -STATIC void cache_failure_intro_add(const uint8_t *identity, const char *service_id, rend_intro_point_failure_t failure); -STATIC void validate_intro_point_failure(const rend_service_descriptor_t *desc, const char *service_id); +STATIC void cache_failure_intro_add(const uint8_t *identity, + const char *service_id, + rend_intro_point_failure_t failure); +STATIC void validate_intro_point_failure(const rend_service_descriptor_t *desc, + const char *service_id); #endif #endif /* TOR_RENDCACHE_H */ diff --git a/src/test/rend_test_helpers.c b/src/test/rend_test_helpers.c index 06e40a0..615ef7b 100644 --- a/src/test/rend_test_helpers.c +++ b/src/test/rend_test_helpers.c @@ -5,7 +5,8 @@ /** TODO: Description */ void -generate_desc(int time_diff, rend_encoded_v2_service_descriptor_t **desc, char **service_id, int intro_points) +generate_desc(int time_diff, rend_encoded_v2_service_descriptor_t **desc, + char **service_id, int intro_points) { rend_service_descriptor_t *generated = NULL; smartlist_t *descs = smartlist_new(); @@ -15,17 +16,18 @@ generate_desc(int time_diff, rend_encoded_v2_service_descriptor_t **desc, char * create_descriptor(&generated, service_id, intro_points); generated->timestamp = now; - rend_encode_v2_descriptors(descs, generated, now, 0, REND_NO_AUTH, NULL, NULL); + rend_encode_v2_descriptors(descs, generated, now, 0, REND_NO_AUTH, NULL, + NULL); *desc = ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)); smartlist_free(descs); rend_service_descriptor_free(generated); } - /** TODO: Description */ void -create_descriptor(rend_service_descriptor_t **generated, char **service_id, int intro_points) +create_descriptor(rend_service_descriptor_t **generated, char **service_id, + int intro_points) { crypto_pk_t *pk1 = NULL; crypto_pk_t *pk2 = NULL; diff --git a/src/test/rend_test_helpers.h b/src/test/rend_test_helpers.h index 00a17be..4305c15 100644 --- a/src/test/rend_test_helpers.h +++ b/src/test/rend_test_helpers.h @@ -6,7 +6,9 @@ #ifndef TOR_REND_TEST_HELPERS_H #define TOR_REND_TEST_HELPERS_H -void generate_desc(int time_diff, rend_encoded_v2_service_descriptor_t **desc, char **service_id, int intro_points); -void create_descriptor(rend_service_descriptor_t **generated, char **service_id, int intro_points); +void generate_desc(int time_diff, rend_encoded_v2_service_descriptor_t **desc, + char **service_id, int intro_points); +void create_descriptor(rend_service_descriptor_t **generated, + char **service_id, int intro_points); #endif diff --git a/src/test/test_rendcache.c b/src/test/test_rendcache.c index a005e66..1213d54 100644 --- a/src/test/test_rendcache.c +++ b/src/test/test_rendcache.c @@ -16,7 +16,8 @@ #define NS_MODULE rend_cache static const int RECENT_TIME = -10; -static const int TIME_IN_THE_PAST = -(REND_CACHE_MAX_AGE + REND_CACHE_MAX_SKEW + 10); +static const int TIME_IN_THE_PAST = -(REND_CACHE_MAX_AGE + \ + REND_CACHE_MAX_SKEW + 10); static const int TIME_IN_THE_FUTURE = REND_CACHE_MAX_SKEW + 10; extern strmap_t *rend_cache; @@ -30,10 +31,12 @@ mock_rend_data(char *onion_address) rend_data_t rend_query; memset(&rend_query, 0, sizeof(rend_query)); - strncpy(rend_query.onion_address, onion_address, REND_SERVICE_ID_LEN_BASE32+1); + strncpy(rend_query.onion_address, onion_address, + REND_SERVICE_ID_LEN_BASE32+1); rend_query.auth_type = REND_NO_AUTH; rend_query.hsdirs_fp = smartlist_new(); - smartlist_add(rend_query.hsdirs_fp, tor_memdup("aaaaaaaaaaaaaaaaaaaaaaaa", DIGEST_LEN)); + smartlist_add(rend_query.hsdirs_fp, tor_memdup("aaaaaaaaaaaaaaaaaaaaaaaa", + DIGEST_LEN)); return rend_query; } @@ -53,7 +56,6 @@ test_rend_cache_lookup_entry(void *data) generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); - ret = rend_cache_lookup_entry("abababababababab", 0, NULL); tt_int_op(ret, OP_EQ, -ENOENT); @@ -67,8 +69,10 @@ test_rend_cache_lookup_entry(void *data) tt_int_op(ret, OP_EQ, -ENOENT); mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); - rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, + &mock_rend_query, NULL); ret = rend_cache_lookup_entry(service_id, 2, NULL); tt_int_op(ret, OP_EQ, 0); @@ -102,8 +106,11 @@ test_rend_cache_store_v2_desc_as_client(void *data) // Test success mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, &entry); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + &entry); tt_int_op(ret, OP_EQ, RCS_OKAY); tt_assert(entry); @@ -113,34 +120,45 @@ test_rend_cache_store_v2_desc_as_client(void *data) // Test various failure modes // TODO: a too long desc_id_base32 argument crashes the function - /* ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, "3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG", &mock_rend_query, NULL); */ + /* ret = rend_cache_store_v2_desc_as_client( */ + /* desc_holder->desc_str, */ + /* "3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG", */ + /* &mock_rend_query, NULL); */ /* tt_int_op(ret, OP_EQ, RCS_BADDESC); */ // Test bad base32 failure - // This causes an assertion failure if we're running with assertions. But when doing coverage, we can test it. + // This causes an assertion failure if we're running with assertions. + // But when doing coverage, we can test it. #ifdef TOR_COVERAGE - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, "!xqunszqnaolrrfmtzgaki7mxelgvkj", &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + "!xqunszqnaolrrfmtzgaki7mxelgvkj", &mock_rend_query, NULL); tt_int_op(ret, OP_EQ, RCS_BADDESC); #endif // Test invalid descriptor - ret = rend_cache_store_v2_desc_as_client("invalid descriptor", "3xqunszqnaolrrfmtzgaki7mxelgvkje", &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client("invalid descriptor", + "3xqunszqnaolrrfmtzgaki7mxelgvkje", &mock_rend_query, NULL); tt_int_op(ret, OP_EQ, RCS_BADDESC); // TODO: it doesn't seem to be possible to test invalid service ID condition. - // that means it is likely not possible to have that condition without earlier conditions failing first (such as signature checking of the desc) + // that means it is likely not possible to have that condition without + // earlier conditions failing first (such as signature checking of the desc) // Test mismatch between service ID and onion address rend_cache_init(); strncpy(mock_rend_query.onion_address, "abc", REND_SERVICE_ID_LEN_BASE32+1); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, + &mock_rend_query, NULL); tt_int_op(ret, OP_EQ, RCS_BADDESC); // Test incorrect descriptor ID rend_cache_init(); mock_rend_query = mock_rend_data(service_id); desc_id_base32[0]++; - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + NULL); tt_int_op(ret, OP_EQ, RCS_BADDESC); desc_id_base32[0]--; @@ -151,9 +169,12 @@ test_rend_cache_store_v2_desc_as_client(void *data) generate_desc(TIME_IN_THE_PAST, &desc_holder, &service_id, 3); mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, + &mock_rend_query, NULL); tt_int_op(ret, OP_EQ, RCS_BADDESC); // Test too new descriptor (in the future) @@ -163,9 +184,12 @@ test_rend_cache_store_v2_desc_as_client(void *data) generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3); mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + NULL); tt_int_op(ret, OP_EQ, RCS_BADDESC); // Test when a descriptor is already in the cache @@ -176,13 +200,19 @@ test_rend_cache_store_v2_desc_as_client(void *data) generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); - - rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + + rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, + &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + NULL); tt_int_op(ret, OP_EQ, RCS_OKAY); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, &entry); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + &entry); tt_int_op(ret, OP_EQ, RCS_OKAY); tt_assert(entry); @@ -195,9 +225,13 @@ test_rend_cache_store_v2_desc_as_client(void *data) mock_rend_query = mock_rend_data(service_id); mock_rend_query.auth_type = REND_BASIC_AUTH; client_cookie[0] = 'A'; - memcpy(mock_rend_query.descriptor_cookie, client_cookie, REND_DESC_COOKIE_LEN); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + memcpy(mock_rend_query.descriptor_cookie, client_cookie, + REND_DESC_COOKIE_LEN); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + NULL); tt_int_op(ret, OP_EQ, RCS_OKAY); // Test successful run when we have REND_BASIC_AUTH but not cookie @@ -208,8 +242,11 @@ test_rend_cache_store_v2_desc_as_client(void *data) generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); mock_rend_query = mock_rend_data(service_id); mock_rend_query.auth_type = REND_BASIC_AUTH; - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + NULL); tt_int_op(ret, OP_EQ, RCS_OKAY); // Test when we have no introduction points @@ -219,8 +256,11 @@ test_rend_cache_store_v2_desc_as_client(void *data) generate_desc(RECENT_TIME, &desc_holder, &service_id, 0); mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + NULL); tt_int_op(ret, OP_EQ, RCS_BADDESC); // Test when we have too many intro points @@ -230,8 +270,11 @@ test_rend_cache_store_v2_desc_as_client(void *data) generate_desc(RECENT_TIME, &desc_holder, &service_id, MAX_INTRO_POINTS+1); mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, &mock_rend_query, NULL); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); + ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, + desc_id_base32, &mock_rend_query, + NULL); tt_int_op(ret, OP_EQ, RCS_BADDESC); done: @@ -258,30 +301,42 @@ test_rend_cache_store_v2_desc_as_client_with_different_time(void *data) create_descriptor(&generated, &service_id, 3); generated->timestamp = t + RECENT_TIME; - rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, REND_NO_AUTH, NULL, NULL); - desc_holder_newer = ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)); + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, + REND_NO_AUTH, NULL, NULL); + desc_holder_newer = ((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0)); smartlist_free(descs); descs = smartlist_new(); generated->timestamp = (t + RECENT_TIME) - 20; - rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, REND_NO_AUTH, NULL, NULL); - desc_holder_older = ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)); + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, + REND_NO_AUTH, NULL, NULL); + desc_holder_older = ((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0)); (void)data; rend_cache_init(); - // Test when a descriptor is already in the cache and it is newer than the one we submit + // Test when a descriptor is already in the cache and it is newer than the + // one we submit mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder_newer->desc_id, DIGEST_LEN); - rend_cache_store_v2_desc_as_client(desc_holder_newer->desc_str, desc_id_base32, &mock_rend_query, NULL); - ret = rend_cache_store_v2_desc_as_client(desc_holder_older->desc_str, desc_id_base32, &mock_rend_query, NULL); + base32_encode(desc_id_base32, sizeof(desc_id_base32), + desc_holder_newer->desc_id, DIGEST_LEN); + rend_cache_store_v2_desc_as_client(desc_holder_newer->desc_str, + desc_id_base32, &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client(desc_holder_older->desc_str, + desc_id_base32, &mock_rend_query, + NULL); tt_int_op(ret, OP_EQ, RCS_OKAY); // Test when an old descriptor is in the cache and we submit a newer one rend_cache_init(); - rend_cache_store_v2_desc_as_client(desc_holder_older->desc_str, desc_id_base32, &mock_rend_query, NULL); - ret = rend_cache_store_v2_desc_as_client(desc_holder_newer->desc_str, desc_id_base32, &mock_rend_query, NULL); + rend_cache_store_v2_desc_as_client(desc_holder_older->desc_str, + desc_id_base32, &mock_rend_query, NULL); + ret = rend_cache_store_v2_desc_as_client(desc_holder_newer->desc_str, + desc_id_base32, &mock_rend_query, + NULL); tt_int_op(ret, OP_EQ, RCS_OKAY); done: @@ -292,7 +347,6 @@ test_rend_cache_store_v2_desc_as_client_with_different_time(void *data) tor_free(service_id); } - #define NS_SUBMODULE lookup_v2_desc_as_dir NS_DECL(const routerinfo_t *, router_get_my_routerinfo, (void)); NS_DECL(int, hid_serv_responsible_for_desc_id, (const char *id)); @@ -303,7 +357,7 @@ static int hid_serv_responsible_for_desc_id_response; static const routerinfo_t * NS(router_get_my_routerinfo)(void) { - if(!mock_routerinfo) { + if (!mock_routerinfo) { mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); } @@ -313,6 +367,7 @@ NS(router_get_my_routerinfo)(void) static int NS(hid_serv_responsible_for_desc_id)(const char *id) { + (void)id; return hid_serv_responsible_for_desc_id_response; } @@ -337,14 +392,16 @@ test_rend_cache_lookup_v2_desc_as_dir(void *data) tt_int_op(ret, OP_EQ, -1); // Test non-existent descriptor but well formed - ret = rend_cache_lookup_v2_desc_as_dir("3xqunszqnaolrrfmtzgaki7mxelgvkje", NULL); + ret = rend_cache_lookup_v2_desc_as_dir("3xqunszqnaolrrfmtzgaki7mxelgvkje", + NULL); tt_int_op(ret, OP_EQ, 0); // Test existing descriptor hid_serv_responsible_for_desc_id_response = 1; generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, DIGEST_LEN); + base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, + DIGEST_LEN); ret = rend_cache_lookup_v2_desc_as_dir(desc_id_base32, &ret_desc); tt_int_op(ret, OP_EQ, 1); tt_assert(ret_desc); @@ -361,9 +418,6 @@ test_rend_cache_lookup_v2_desc_as_dir(void *data) NS_DECL(const routerinfo_t *, router_get_my_routerinfo, (void)); NS_DECL(int, hid_serv_responsible_for_desc_id, (const char *id)); -static routerinfo_t *mock_routerinfo; -static int hid_serv_responsible_for_desc_id_response; - static const routerinfo_t * NS(router_get_my_routerinfo)(void) { @@ -373,6 +427,7 @@ NS(router_get_my_routerinfo)(void) static int NS(hid_serv_responsible_for_desc_id)(const char *id) { + (void)id; return hid_serv_responsible_for_desc_id_response; } @@ -458,15 +513,19 @@ test_rend_cache_store_v2_desc_as_dir_with_different_time(void *data) create_descriptor(&generated, &service_id, 3); generated->timestamp = t + RECENT_TIME; - rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, REND_NO_AUTH, NULL, NULL); - desc_holder_newer = ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)); + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, + REND_NO_AUTH, NULL, NULL); + desc_holder_newer = ((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0)); smartlist_free(descs); descs = smartlist_new(); generated->timestamp = (t + RECENT_TIME) - 20; - rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, REND_NO_AUTH, NULL, NULL); - desc_holder_older = ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)); + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, + REND_NO_AUTH, NULL, NULL); + desc_holder_older = ((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0)); // Test when we have a newer descriptor stored mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); @@ -508,16 +567,20 @@ test_rend_cache_store_v2_desc_as_dir_with_different_content(void *data) create_descriptor(&generated, &service_id, 3); generated->timestamp = t + RECENT_TIME; - rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, REND_NO_AUTH, NULL, NULL); - desc_holder_one = ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)); + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, + REND_NO_AUTH, NULL, NULL); + desc_holder_one = ((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0)); smartlist_free(descs); descs = smartlist_new(); generated->timestamp = t + RECENT_TIME; generated->protocols = 41; - rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, REND_NO_AUTH, NULL, NULL); - desc_holder_two = ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)); + rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, + REND_NO_AUTH, NULL, NULL); + desc_holder_two = ((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0)); // Test when we have another descriptor stored, with a different descriptor mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); @@ -531,7 +594,6 @@ test_rend_cache_store_v2_desc_as_dir_with_different_content(void *data) NS_UNMOCK(hid_serv_responsible_for_desc_id); } - #undef NS_SUBMODULE static void @@ -540,14 +602,18 @@ test_rend_cache_init(void *data) (void)data; tt_assert_msg(!rend_cache, "rend_cache should be NULL when starting"); - tt_assert_msg(!rend_cache_v2_dir, "rend_cache_v2_dir should be NULL when starting"); - tt_assert_msg(!rend_cache_failure, "rend_cache_failure should be NULL when starting"); + tt_assert_msg(!rend_cache_v2_dir, "rend_cache_v2_dir should be NULL " + "when starting"); + tt_assert_msg(!rend_cache_failure, "rend_cache_failure should be NULL when " + "starting"); rend_cache_init(); tt_assert_msg(rend_cache, "rend_cache should not be NULL after initing"); - tt_assert_msg(rend_cache_v2_dir, "rend_cache_v2_dir should not be NULL after initing"); - tt_assert_msg(rend_cache_failure, "rend_cache_failure should not be NULL after initing"); + tt_assert_msg(rend_cache_v2_dir, "rend_cache_v2_dir should not be NULL " + "after initing"); + tt_assert_msg(rend_cache_failure, "rend_cache_failure should not be NULL " + "after initing"); tt_int_op(strmap_size(rend_cache), OP_EQ, 0); tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); @@ -603,7 +669,6 @@ test_rend_cache_increment_allocation(void *data) (void)0; } - static void test_rend_cache_failure_intro_entry_new(void *data) { @@ -790,7 +855,6 @@ test_rend_cache_failure_clean(void *data) rend_cache_failure_clean(time(NULL)); tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); - // Test with one old intro point and one new one rend_cache_failure_purge(); failure = rend_cache_failure_entry_new(); @@ -809,7 +873,6 @@ test_rend_cache_failure_clean(void *data) (void)0; } - static void test_rend_cache_failure_remove(void *data) { @@ -826,7 +889,8 @@ test_rend_cache_failure_remove(void *data) desc->pk = pk_generate(0); rend_cache_failure_remove(desc); - // There seems to not exist any way of getting rend_cache_failure_remove() to fail because of a problem with rend_get_service_id from here + // There seems to not exist any way of getting rend_cache_failure_remove() + // to fail because of a problem with rend_get_service_id from here /* done: */ /* (void)0; */ @@ -864,7 +928,6 @@ test_rend_cache_free_all(void *data) (void)0; } - static void test_rend_cache_entry_free(void *data) { @@ -887,7 +950,6 @@ test_rend_cache_entry_free(void *data) /* (void)0; */ } - static void test_rend_cache_purge(void *data) { @@ -922,7 +984,8 @@ test_rend_cache_failure_intro_add(void *data) rend_cache_init(); // Adds non-existing entry - cache_failure_intro_add((const uint8_t *)"foo1", "foo2", INTRO_POINT_FAILURE_TIMEOUT); + cache_failure_intro_add((const uint8_t *)"foo1", "foo2", + INTRO_POINT_FAILURE_TIMEOUT); fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); tt_assert(fail_entry); tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); @@ -930,7 +993,8 @@ test_rend_cache_failure_intro_add(void *data) tt_assert(entry); // Adds existing entry - cache_failure_intro_add((const uint8_t *)"foo1", "foo2", INTRO_POINT_FAILURE_TIMEOUT); + cache_failure_intro_add((const uint8_t *)"foo1", "foo2", + INTRO_POINT_FAILURE_TIMEOUT); fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); tt_assert(fail_entry); tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); @@ -941,7 +1005,6 @@ test_rend_cache_failure_intro_add(void *data) rend_cache_purge(); } - static void test_rend_cache_intro_failure_note(void *data) { @@ -950,7 +1013,8 @@ test_rend_cache_intro_failure_note(void *data) rend_cache_failure_intro_t *entry; // Test not found - rend_cache_intro_failure_note(INTRO_POINT_FAILURE_TIMEOUT,(const uint8_t *)"foo1", "foo2"); + rend_cache_intro_failure_note(INTRO_POINT_FAILURE_TIMEOUT, + (const uint8_t *)"foo1", "foo2"); fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); tt_assert(fail_entry); tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); @@ -959,7 +1023,8 @@ test_rend_cache_intro_failure_note(void *data) tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_TIMEOUT); // Test found - rend_cache_intro_failure_note(INTRO_POINT_FAILURE_UNREACHABLE,(const uint8_t *)"foo1", "foo2"); + rend_cache_intro_failure_note(INTRO_POINT_FAILURE_UNREACHABLE, + (const uint8_t *)"foo1", "foo2"); tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_UNREACHABLE); done: @@ -969,15 +1034,13 @@ test_rend_cache_intro_failure_note(void *data) #define NS_SUBMODULE clean_v2_descs_as_dir NS_DECL(int, hid_serv_responsible_for_desc_id, (const char *id)); -static int hid_serv_responsible_for_desc_id_response; - static int NS(hid_serv_responsible_for_desc_id)(const char *id) { + (void)id; return hid_serv_responsible_for_desc_id_response; } - static void test_rend_cache_clean_v2_descs_as_dir(void *data) { @@ -1013,7 +1076,8 @@ test_rend_cache_clean_v2_descs_as_dir(void *data) rend_cache_clean_v2_descs_as_dir(now, 0); tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); - // Test with one entry that is not under the responsibility of this hidden service + // Test with one entry that is not under the responsibility of this + // hidden service e = tor_malloc_zero(sizeof(rend_cache_entry_t)); e->last_served = now; desc = tor_malloc_zero(sizeof(rend_service_descriptor_t)); @@ -1052,8 +1116,6 @@ test_rend_cache_clean_v2_descs_as_dir(void *data) rend_cache_clean_v2_descs_as_dir(now, 20000); tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 1); - - done: NS_UNMOCK(hid_serv_responsible_for_desc_id); rend_cache_purge(); @@ -1061,7 +1123,6 @@ test_rend_cache_clean_v2_descs_as_dir(void *data) #undef NS_SUBMODULE - static void test_rend_cache_entry_allocation(void *data) { @@ -1097,7 +1158,6 @@ test_rend_cache_failure_intro_entry_free(void *data) rend_cache_failure_intro_entry_free(entry); } - static void test_rend_cache_failure_purge(void *data) { @@ -1148,31 +1208,46 @@ test_rend_cache_validate_intro_point_failure(void *data) struct testcase_t rend_cache_tests[] = { { "init", test_rend_cache_init, 0, NULL, NULL }, - { "decrement_allocation", test_rend_cache_decrement_allocation, 0, NULL, NULL }, - { "increment_allocation", test_rend_cache_increment_allocation, 0, NULL, NULL }, + { "decrement_allocation", test_rend_cache_decrement_allocation, 0, + NULL, NULL }, + { "increment_allocation", test_rend_cache_increment_allocation, 0, + NULL, NULL }, { "clean", test_rend_cache_clean, TT_FORK, NULL, NULL }, - { "clean_v2_descs_as_dir", test_rend_cache_clean_v2_descs_as_dir, 0, NULL, NULL }, + { "clean_v2_descs_as_dir", test_rend_cache_clean_v2_descs_as_dir, 0, + NULL, NULL }, { "entry_allocation", test_rend_cache_entry_allocation, 0, NULL, NULL }, { "entry_free", test_rend_cache_entry_free, 0, NULL, NULL }, - { "failure_intro_entry_free", test_rend_cache_failure_intro_entry_free, 0, NULL, NULL }, + { "failure_intro_entry_free", test_rend_cache_failure_intro_entry_free, 0, + NULL, NULL }, { "free_all", test_rend_cache_free_all, 0, NULL, NULL }, { "purge", test_rend_cache_purge, 0, NULL, NULL }, { "failure_clean", test_rend_cache_failure_clean, 0, NULL, NULL }, { "failure_entry_new", test_rend_cache_failure_entry_new, 0, NULL, NULL }, { "failure_entry_free", test_rend_cache_failure_entry_free, 0, NULL, NULL }, { "failure_intro_add", test_rend_cache_failure_intro_add, 0, NULL, NULL }, - { "failure_intro_entry_new", test_rend_cache_failure_intro_entry_new, 0, NULL, NULL }, - { "failure_intro_lookup", test_rend_cache_failure_intro_lookup, 0, NULL, NULL }, + { "failure_intro_entry_new", test_rend_cache_failure_intro_entry_new, 0, + NULL, NULL }, + { "failure_intro_lookup", test_rend_cache_failure_intro_lookup, 0, + NULL, NULL }, { "failure_purge", test_rend_cache_failure_purge, 0, NULL, NULL }, { "failure_remove", test_rend_cache_failure_remove, 0, NULL, NULL }, { "intro_failure_note", test_rend_cache_intro_failure_note, 0, NULL, NULL }, { "lookup", test_rend_cache_lookup_entry, 0, NULL, NULL }, - { "lookup_v2_desc_as_dir", test_rend_cache_lookup_v2_desc_as_dir, 0, NULL, NULL }, - { "store_v2_desc_as_client", test_rend_cache_store_v2_desc_as_client, 0, NULL, NULL }, - { "store_v2_desc_as_client_with_different_time", test_rend_cache_store_v2_desc_as_client_with_different_time, 0, NULL, NULL }, - { "store_v2_desc_as_dir", test_rend_cache_store_v2_desc_as_dir, 0, NULL, NULL }, - { "store_v2_desc_as_dir_with_different_time", test_rend_cache_store_v2_desc_as_dir_with_different_time, 0, NULL, NULL }, - { "store_v2_desc_as_dir_with_different_content", test_rend_cache_store_v2_desc_as_dir_with_different_content, 0, NULL, NULL }, - { "validate_intro_point_failure", test_rend_cache_validate_intro_point_failure, 0, NULL, NULL }, + { "lookup_v2_desc_as_dir", test_rend_cache_lookup_v2_desc_as_dir, 0, + NULL, NULL }, + { "store_v2_desc_as_client", test_rend_cache_store_v2_desc_as_client, 0, + NULL, NULL }, + { "store_v2_desc_as_client_with_different_time", + test_rend_cache_store_v2_desc_as_client_with_different_time, 0, + NULL, NULL }, + { "store_v2_desc_as_dir", test_rend_cache_store_v2_desc_as_dir, 0, + NULL, NULL }, + { "store_v2_desc_as_dir_with_different_time", + test_rend_cache_store_v2_desc_as_dir_with_different_time, 0, NULL, NULL }, + { "store_v2_desc_as_dir_with_different_content", + test_rend_cache_store_v2_desc_as_dir_with_different_content, 0, + NULL, NULL }, + { "validate_intro_point_failure", + test_rend_cache_validate_intro_point_failure, 0, NULL, NULL }, END_OF_TESTCASES };
[View Less]
1
0
0
0
[tor/master] fix check-spaces once more
by nickm@torproject.org
06 Oct '15
06 Oct '15
commit 15bfdbeb9db2bc3585ba623851ed2ee2a0dd0a80 Author: Nick Mathewson <nickm(a)torproject.org> Date: Tue Oct 6 11:32:37 2015 -0400 fix check-spaces once more --- src/or/routerlist.c | 1 + src/or/routerlist.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 2669977..694a148 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -5214,3 +5214,4 @@ MOCK_IMPL(int, hid_serv_responsible_for_desc_id, smartlist_free(
…
[View More]
responsible); return result; } + diff --git a/src/or/routerlist.h b/src/or/routerlist.h index ec09f23..100ab58 100644 --- a/src/or/routerlist.h +++ b/src/or/routerlist.h @@ -243,3 +243,4 @@ MOCK_DECL(STATIC void, initiate_descriptor_downloads, #endif #endif +
[View Less]
1
0
0
0
[tor/master] Actually test success cases as well
by nickm@torproject.org
06 Oct '15
06 Oct '15
commit d0abf16119cf57e47044e171bc310773b45686f6 Author: Ola Bini <ola(a)olabini.se> Date: Sat Oct 3 18:37:29 2015 -0500 Actually test success cases as well --- src/test/test_util_format.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/test/test_util_format.c b/src/test/test_util_format.c index 8ffc2de..e35632f 100644 --- a/src/test/test_util_format.c +++ b/src/test/test_util_format.c @@ -107,10 +107,13 @@
…
[View More]
test_util_format_base64_decode_nopad(void *ignored) int res; int i; char *src; - uint8_t *dst; + uint8_t *dst, *real_dst; + uint8_t expected[] = {0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65}; + char real_src[] = "ZXhhbXBsZQ"; src = tor_malloc_zero(256); dst = tor_malloc_zero(1000); + real_dst = tor_malloc_zero(10); for(i=0;i<256;i++) { src[i] = (char)i; @@ -122,9 +125,14 @@ test_util_format_base64_decode_nopad(void *ignored) res = base64_decode_nopad(dst, 1, src, 5); tt_int_op(res, OP_EQ, -1); + res = base64_decode_nopad(real_dst, 10, real_src, 10); + tt_int_op(res, OP_EQ, 7); + tt_mem_op(real_dst, OP_EQ, expected, 7); + done: tor_free(src); tor_free(dst); + tor_free(real_dst); } @@ -135,10 +143,13 @@ test_util_format_base64_decode(void *ignored) int res; int i; char *src; - char *dst; + char *dst, *real_dst; + uint8_t expected[] = {0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65}; + char real_src[] = "ZXhhbXBsZQ=="; src = tor_malloc_zero(256); dst = tor_malloc_zero(1000); + real_dst = tor_malloc_zero(10); for(i=0;i<256;i++) { src[i] = (char)i; @@ -150,9 +161,14 @@ test_util_format_base64_decode(void *ignored) res = base64_decode(dst, SIZE_T_CEILING+1, src, 10); tt_int_op(res, OP_EQ, -1); + res = base64_decode(real_dst, 10, real_src, 10); + tt_int_op(res, OP_EQ, 7); + tt_mem_op(real_dst, OP_EQ, expected, 7); + done: tor_free(src); tor_free(dst); + tor_free(real_dst); } @@ -164,10 +180,13 @@ test_util_format_base16_decode(void *ignored) int res; int i; char *src; - char *dst; + char *dst, *real_dst; + char expected[] = {0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65}; + char real_src[] = "6578616D706C65"; src = tor_malloc_zero(256); dst = tor_malloc_zero(1000); + real_dst = tor_malloc_zero(10); for(i=0;i<256;i++) { src[i] = (char)i; @@ -182,9 +201,14 @@ test_util_format_base16_decode(void *ignored) res = base16_decode(dst, SIZE_T_CEILING+2, src, 10); tt_int_op(res, OP_EQ, -1); + res = base16_decode(real_dst, 10, real_src, 14); + tt_int_op(res, OP_EQ, 0); + tt_mem_op(real_dst, OP_EQ, expected, 7); + done: tor_free(src); tor_free(dst); + tor_free(real_dst); }
[View Less]
1
0
0
0
[tor/master] Fix spaces warnings
by nickm@torproject.org
06 Oct '15
06 Oct '15
commit b54133fbd9b1c7e08024b3987ff17ca3ef5666a9 Author: Ola Bini <ola(a)olabini.se> Date: Sat Oct 3 18:46:40 2015 -0500 Fix spaces warnings --- src/test/test_util_format.c | 45 ++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/test/test_util_format.c b/src/test/test_util_format.c index e35632f..7be6743 100644 --- a/src/test/test_util_format.c +++ b/src/test/test_util_format.c @@ -23,7 +23,7 @@
…
[View More]
test_util_format_base64_encode(void *ignored) src = tor_malloc_zero(256); dst = tor_malloc_zero(1000); - for(i=0;i<256;i++) { + for (i=0;i<256;i++) { src[i] = (char)i; } @@ -44,22 +44,35 @@ test_util_format_base64_encode(void *ignored) res = base64_encode(dst, 1000, src, 256, 0); tt_int_op(res, OP_EQ, 344); - tt_str_op(dst, OP_EQ, "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=="); - + tt_str_op(dst, OP_EQ, + "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8g" + "ISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BB" + "QkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFi" + "Y2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKD" + "hIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOk" + "paanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TF" + "xsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm" + "5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=="); res = base64_encode(dst, 1000, src, 256, BASE64_ENCODE_MULTILINE); tt_int_op(res, OP_EQ, 350); - tt_str_op(dst, OP_EQ, "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4v\n" - "MDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5f\n" - "YGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6P\n" - "kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/\n" - "wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v\n" + tt_str_op(dst, OP_EQ, + "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8g" + "ISIjJCUmJygpKissLS4v\n" + "MDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9Q" + "UVJTVFVWV1hZWltcXV5f\n" + "YGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+A" + "gYKDhIWGh4iJiouMjY6P\n" + "kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+w" + "sbKztLW2t7i5uru8vb6/\n" + "wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g" + "4eLj5OXm5+jp6uvs7e7v\n" "8PHy8/T19vf4+fr7/P3+/w==\n"); res = base64_encode(dst, 1000, src+1, 255, BASE64_ENCODE_MULTILINE); tt_int_op(res, OP_EQ, 346); - for(i = 0;i<50;i++) { + for (i = 0;i<50;i++) { src[i] = 0; } src[50] = 255; @@ -94,7 +107,6 @@ test_util_format_base64_encode(void *ignored) res = base64_encode(dst, 1000, src+8, 46, BASE64_ENCODE_MULTILINE); tt_int_op(res, OP_EQ, 65); - done: tor_free(src); tor_free(dst); @@ -115,7 +127,7 @@ test_util_format_base64_decode_nopad(void *ignored) dst = tor_malloc_zero(1000); real_dst = tor_malloc_zero(10); - for(i=0;i<256;i++) { + for (i=0;i<256;i++) { src[i] = (char)i; } @@ -135,7 +147,6 @@ test_util_format_base64_decode_nopad(void *ignored) tor_free(real_dst); } - static void test_util_format_base64_decode(void *ignored) { @@ -151,7 +162,7 @@ test_util_format_base64_decode(void *ignored) dst = tor_malloc_zero(1000); real_dst = tor_malloc_zero(10); - for(i=0;i<256;i++) { + for (i=0;i<256;i++) { src[i] = (char)i; } @@ -171,8 +182,6 @@ test_util_format_base64_decode(void *ignored) tor_free(real_dst); } - - static void test_util_format_base16_decode(void *ignored) { @@ -188,7 +197,7 @@ test_util_format_base16_decode(void *ignored) dst = tor_malloc_zero(1000); real_dst = tor_malloc_zero(10); - for(i=0;i<256;i++) { + for (i=0;i<256;i++) { src[i] = (char)i; } @@ -211,10 +220,10 @@ test_util_format_base16_decode(void *ignored) tor_free(real_dst); } - struct testcase_t util_format_tests[] = { { "base64_encode", test_util_format_base64_encode, 0, NULL, NULL }, - { "base64_decode_nopad", test_util_format_base64_decode_nopad, 0, NULL, NULL }, + { "base64_decode_nopad", test_util_format_base64_decode_nopad, + 0, NULL, NULL }, { "base64_decode", test_util_format_base64_decode, 0, NULL, NULL }, { "base16_decode", test_util_format_base16_decode, 0, NULL, NULL }, END_OF_TESTCASES
[View Less]
1
0
0
0
[tor/master] Merge remote-tracking branch 'twstrike/util_format_tests'
by nickm@torproject.org
06 Oct '15
06 Oct '15
commit 2592d537f95173083e397d19e182346955741221 Merge: aaa27b9 b54133f Author: Nick Mathewson <nickm(a)torproject.org> Date: Tue Oct 6 11:20:33 2015 -0400 Merge remote-tracking branch 'twstrike/util_format_tests' Conflicts: src/test/test_util_format.c src/test/test_util_format.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --cc src/test/test_util_format.c index af4997d,7be6743..705dfcf --- a/src/test/test_util_format.
…
[View More]
c +++ b/src/test/test_util_format.c @@@ -127,16 -137,10 +130,20 @@@ test_util_format_base64_decode_nopad(vo res = base64_decode_nopad(dst, 1, src, 5); tt_int_op(res, OP_EQ, -1); + const char *s = "SGVsbG8gd29ybGQ"; + res = base64_decode_nopad(dst, 1000, s, strlen(s)); + tt_int_op(res, OP_EQ, 11); + tt_mem_op(dst, OP_EQ, "Hello world", 11); + + s = "T3BhIG11bmRv"; + res = base64_decode_nopad(dst, 9, s, strlen(s)); + tt_int_op(res, OP_EQ, 9); + tt_mem_op(dst, OP_EQ, "Opa mundo", 9); + + res = base64_decode_nopad(real_dst, 10, real_src, 10); + tt_int_op(res, OP_EQ, 7); + tt_mem_op(real_dst, OP_EQ, expected, 7); + done: tor_free(src); tor_free(dst); @@@ -164,21 -172,10 +175,25 @@@ test_util_format_base64_decode(void *ig res = base64_decode(dst, SIZE_T_CEILING+1, src, 10); tt_int_op(res, OP_EQ, -1); + const char *s = "T3BhIG11bmRv"; + res = base64_decode(dst, 9, s, strlen(s)); + tt_int_op(res, OP_EQ, 9); + tt_mem_op(dst, OP_EQ, "Opa mundo", 9); + + memset(dst, 0, 1000); + res = base64_decode(dst, 100, s, strlen(s)); + tt_int_op(res, OP_EQ, 9); + tt_mem_op(dst, OP_EQ, "Opa mundo", 9); + + s = "SGVsbG8gd29ybGQ="; + res = base64_decode(dst, 100, s, strlen(s)); + tt_int_op(res, OP_EQ, 11); + tt_mem_op(dst, OP_EQ, "Hello world", 11); + + res = base64_decode(real_dst, 10, real_src, 10); + tt_int_op(res, OP_EQ, 7); + tt_mem_op(real_dst, OP_EQ, expected, 7); + done: tor_free(src); tor_free(dst); @@@ -209,19 -210,10 +228,23 @@@ test_util_format_base16_decode(void *ig res = base16_decode(dst, SIZE_T_CEILING+2, src, 10); tt_int_op(res, OP_EQ, -1); + res = base16_decode(dst, 1000, "", 0); + tt_int_op(res, OP_EQ, 0); + + res = base16_decode(dst, 1000, "aabc", 4); + tt_int_op(res, OP_EQ, 0); + tt_mem_op(dst, OP_EQ, "\xaa\xbc", 2); + + res = base16_decode(dst, 1000, "aabcd", 6); + tt_int_op(res, OP_EQ, -1); + + res = base16_decode(dst, 1000, "axxx", 4); + tt_int_op(res, OP_EQ, -1); + + res = base16_decode(real_dst, 10, real_src, 14); + tt_int_op(res, OP_EQ, 0); + tt_mem_op(real_dst, OP_EQ, expected, 7); + done: tor_free(src); tor_free(dst);
[View Less]
1
0
0
0
← Newer
1
...
99
100
101
102
103
104
105
...
119
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
Results per page:
10
25
50
100
200