mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 12:23:32 +01:00
Add tests for the rend cache
This commit is contained in:
parent
a444b11323
commit
ade5005853
@ -3,9 +3,10 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* \file rendcache.c
|
* \file rendcache.c
|
||||||
* \brief Hidden service desriptor cache.
|
* \brief Hidden service descriptor cache.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
#define RENDCACHE_PRIVATE
|
||||||
#include "rendcache.h"
|
#include "rendcache.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -15,11 +16,11 @@
|
|||||||
|
|
||||||
/** Map from service id (as generated by rend_get_service_id) to
|
/** Map from service id (as generated by rend_get_service_id) to
|
||||||
* rend_cache_entry_t. */
|
* 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
|
/** Map from descriptor id to rend_cache_entry_t; only for hidden service
|
||||||
* directories. */
|
* 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
|
/** (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
|
* 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
|
* 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
|
* 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. */
|
* 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 */
|
/** DOCDOC */
|
||||||
static size_t rend_cache_total_allocation = 0;
|
STATIC size_t rend_cache_total_allocation = 0;
|
||||||
|
|
||||||
/** Initializes the service descriptor cache.
|
/** 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>. */
|
/** 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)
|
rend_cache_entry_allocation(const rend_cache_entry_t *e)
|
||||||
{
|
{
|
||||||
if (!e)
|
if (!e)
|
||||||
@ -80,7 +81,7 @@ rend_cache_get_total_allocation(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Decrement the total bytes attributed to the rendezvous cache by n. */
|
/** Decrement the total bytes attributed to the rendezvous cache by n. */
|
||||||
static void
|
STATIC void
|
||||||
rend_cache_decrement_allocation(size_t n)
|
rend_cache_decrement_allocation(size_t n)
|
||||||
{
|
{
|
||||||
static int have_underflowed = 0;
|
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. */
|
/** Increase the total bytes attributed to the rendezvous cache by n. */
|
||||||
static void
|
STATIC void
|
||||||
rend_cache_increment_allocation(size_t n)
|
rend_cache_increment_allocation(size_t n)
|
||||||
{
|
{
|
||||||
static int have_overflowed = 0;
|
static int have_overflowed = 0;
|
||||||
@ -113,7 +114,7 @@ rend_cache_increment_allocation(size_t n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Helper: free a rend cache failure intro object. */
|
/** Helper: free a rend cache failure intro object. */
|
||||||
static void
|
STATIC void
|
||||||
rend_cache_failure_intro_entry_free(rend_cache_failure_intro_t *entry)
|
rend_cache_failure_intro_entry_free(rend_cache_failure_intro_t *entry)
|
||||||
{
|
{
|
||||||
if (entry == NULL) {
|
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>
|
/** Allocate a rend cache failure intro object and return it. <b>failure</b>
|
||||||
* is set into the object. This function can not fail. */
|
* 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_entry_new(rend_intro_point_failure_t failure)
|
||||||
{
|
{
|
||||||
rend_cache_failure_intro_t *entry = tor_malloc(sizeof(*entry));
|
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. */
|
/** Helper: free a rend cache failure object. */
|
||||||
static void
|
STATIC void
|
||||||
rend_cache_failure_entry_free(rend_cache_failure_t *entry)
|
rend_cache_failure_entry_free(rend_cache_failure_t *entry)
|
||||||
{
|
{
|
||||||
if (entry == NULL) {
|
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
|
/** Allocate a rend cache failure object and return it. This function can
|
||||||
* not fail. */
|
* not fail. */
|
||||||
static rend_cache_failure_t *
|
STATIC rend_cache_failure_t *
|
||||||
rend_cache_failure_entry_new(void)
|
rend_cache_failure_entry_new(void)
|
||||||
{
|
{
|
||||||
rend_cache_failure_t *entry = tor_malloc(sizeof(*entry));
|
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
|
/** Remove failure cache entry for the service ID in the given descriptor
|
||||||
* <b>desc</b>. */
|
* <b>desc</b>. */
|
||||||
static void
|
STATIC void
|
||||||
rend_cache_failure_remove(rend_service_descriptor_t *desc)
|
rend_cache_failure_remove(rend_service_descriptor_t *desc)
|
||||||
{
|
{
|
||||||
char service_id[REND_SERVICE_ID_LEN_BASE32 + 1];
|
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. */
|
/** Helper: free storage held by a single service descriptor cache entry. */
|
||||||
static void
|
STATIC void
|
||||||
rend_cache_entry_free(rend_cache_entry_t *e)
|
rend_cache_entry_free(rend_cache_entry_t *e)
|
||||||
{
|
{
|
||||||
if (!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
|
* <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
|
* failure is set in <b>intro_entry</b> else it stays untouched. Return 1
|
||||||
* iff found else 0. */
|
* iff found else 0. */
|
||||||
static int
|
STATIC int
|
||||||
cache_failure_intro_lookup(const uint8_t *identity, const char *service_id,
|
cache_failure_intro_lookup(const uint8_t *identity, const char *service_id,
|
||||||
rend_cache_failure_intro_t **intro_entry)
|
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
|
/** 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>identity</b> and service ID <b>service_id</b>. Record the
|
||||||
* <b>failure</b> in that object. */
|
* <b>failure</b> in that object. */
|
||||||
static void
|
STATIC void
|
||||||
cache_failure_intro_add(const uint8_t *identity, const char *service_id,
|
cache_failure_intro_add(const uint8_t *identity, const char *service_id,
|
||||||
rend_intro_point_failure_t failure)
|
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
|
* 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
|
* are NOT in the descriptor but in the failure cache for the given
|
||||||
* <b>service_id</b> are removed from the failure cache. */
|
* <b>service_id</b> are removed from the failure cache. */
|
||||||
static void
|
STATIC void
|
||||||
validate_intro_point_failure(const rend_service_descriptor_t *desc,
|
validate_intro_point_failure(const rend_service_descriptor_t *desc,
|
||||||
const char *service_id)
|
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 "
|
log_info(LD_REND, "Successfully stored service descriptor with desc ID "
|
||||||
"'%s' and len %d.",
|
"'%s' and len %d.",
|
||||||
safe_str(desc_id_base32), (int)encoded_size);
|
safe_str(desc_id_base32), (int)encoded_size);
|
||||||
|
|
||||||
/* Statistics: Note down this potentially new HS. */
|
/* Statistics: Note down this potentially new HS. */
|
||||||
if (options->HiddenServiceStatistics) {
|
if (options->HiddenServiceStatistics) {
|
||||||
rep_hist_stored_maybe_new_hs(e->parsed->pk);
|
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);
|
tor_free(intro_content);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,5 +76,20 @@ void rend_cache_intro_failure_note(rend_intro_point_failure_t failure,
|
|||||||
const char *service_id);
|
const char *service_id);
|
||||||
void rend_cache_failure_purge(void);
|
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 */
|
||||||
|
@ -5184,8 +5184,8 @@ hid_serv_acting_as_directory(void)
|
|||||||
|
|
||||||
/** Return true if this node is responsible for storing the descriptor ID
|
/** Return true if this node is responsible for storing the descriptor ID
|
||||||
* in <b>query</b> and false otherwise. */
|
* in <b>query</b> and false otherwise. */
|
||||||
int
|
MOCK_IMPL(int, hid_serv_responsible_for_desc_id,
|
||||||
hid_serv_responsible_for_desc_id(const char *query)
|
(const char *query))
|
||||||
{
|
{
|
||||||
const routerinfo_t *me;
|
const routerinfo_t *me;
|
||||||
routerstatus_t *last_rs;
|
routerstatus_t *last_rs;
|
||||||
@ -5208,4 +5208,3 @@ hid_serv_responsible_for_desc_id(const char *query)
|
|||||||
smartlist_free(responsible);
|
smartlist_free(responsible);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ void refresh_all_country_info(void);
|
|||||||
int hid_serv_get_responsible_directories(smartlist_t *responsible_dirs,
|
int hid_serv_get_responsible_directories(smartlist_t *responsible_dirs,
|
||||||
const char *id);
|
const char *id);
|
||||||
int hid_serv_acting_as_directory(void);
|
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 list_pending_microdesc_downloads(digest256map_t *result);
|
||||||
void launch_descriptor_downloads(int purpose,
|
void launch_descriptor_downloads(int purpose,
|
||||||
@ -243,4 +243,3 @@ MOCK_DECL(STATIC void, initiate_descriptor_downloads,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -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.
|
# matters a lot there, and is quite hard to debug if you forget to do it.
|
||||||
|
|
||||||
src_test_test_SOURCES = \
|
src_test_test_SOURCES = \
|
||||||
|
src/test/rend_test_helpers.c \
|
||||||
src/test/test.c \
|
src/test/test.c \
|
||||||
src/test/test_accounting.c \
|
src/test/test_accounting.c \
|
||||||
src/test/test_addr.c \
|
src/test/test_addr.c \
|
||||||
@ -87,6 +88,7 @@ src_test_test_SOURCES = \
|
|||||||
src/test/test_pt.c \
|
src/test/test_pt.c \
|
||||||
src/test/test_relay.c \
|
src/test/test_relay.c \
|
||||||
src/test/test_relaycell.c \
|
src/test/test_relaycell.c \
|
||||||
|
src/test/test_rendcache.c \
|
||||||
src/test/test_replay.c \
|
src/test/test_replay.c \
|
||||||
src/test/test_routerkeys.c \
|
src/test/test_routerkeys.c \
|
||||||
src/test/test_routerlist.c \
|
src/test/test_routerlist.c \
|
||||||
|
65
src/test/rend_test_helpers.c
Normal file
65
src/test/rend_test_helpers.c
Normal file
@ -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);
|
||||||
|
}
|
12
src/test/rend_test_helpers.h
Normal file
12
src/test/rend_test_helpers.h
Normal file
@ -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
|
@ -1148,6 +1148,7 @@ extern struct testcase_t policy_tests[];
|
|||||||
extern struct testcase_t pt_tests[];
|
extern struct testcase_t pt_tests[];
|
||||||
extern struct testcase_t relay_tests[];
|
extern struct testcase_t relay_tests[];
|
||||||
extern struct testcase_t relaycell_tests[];
|
extern struct testcase_t relaycell_tests[];
|
||||||
|
extern struct testcase_t rend_cache_tests[];
|
||||||
extern struct testcase_t replaycache_tests[];
|
extern struct testcase_t replaycache_tests[];
|
||||||
extern struct testcase_t router_tests[];
|
extern struct testcase_t router_tests[];
|
||||||
extern struct testcase_t routerkeys_tests[];
|
extern struct testcase_t routerkeys_tests[];
|
||||||
@ -1195,6 +1196,7 @@ struct testgroup_t testgroups[] = {
|
|||||||
{ "pt/", pt_tests },
|
{ "pt/", pt_tests },
|
||||||
{ "relay/" , relay_tests },
|
{ "relay/" , relay_tests },
|
||||||
{ "relaycell/", relaycell_tests },
|
{ "relaycell/", relaycell_tests },
|
||||||
|
{ "rend_cache/", rend_cache_tests },
|
||||||
{ "replaycache/", replaycache_tests },
|
{ "replaycache/", replaycache_tests },
|
||||||
{ "routerkeys/", routerkeys_tests },
|
{ "routerkeys/", routerkeys_tests },
|
||||||
{ "routerlist/", routerlist_tests },
|
{ "routerlist/", routerlist_tests },
|
||||||
@ -1208,4 +1210,3 @@ struct testgroup_t testgroups[] = {
|
|||||||
{ "dns/", dns_tests },
|
{ "dns/", dns_tests },
|
||||||
END_OF_GROUPS
|
END_OF_GROUPS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
1178
src/test/test_rendcache.c
Normal file
1178
src/test/test_rendcache.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user