diff options
author | David Goulet <dgoulet@torproject.org> | 2017-08-30 09:15:54 -0400 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2017-08-30 09:15:54 -0400 |
commit | 22295759afa90f19b06e2b657ce84d518c2390fd (patch) | |
tree | 87ab2f6eeca8091e4c775c031910863b918077b3 | |
parent | 209bfe715cc8c1c59b2578c406749a0d4a5bd8cb (diff) | |
download | tor-22295759afa90f19b06e2b657ce84d518c2390fd.tar.gz tor-22295759afa90f19b06e2b657ce84d518c2390fd.zip |
prop224: Purge client state on NEWNYM
Closes #23355
Signed-off-by: David Goulet <dgoulet@torproject.org>
-rw-r--r-- | src/or/connection.c | 19 | ||||
-rw-r--r-- | src/or/connection.h | 1 | ||||
-rw-r--r-- | src/or/hs_cache.c | 31 | ||||
-rw-r--r-- | src/or/hs_cache.h | 2 | ||||
-rw-r--r-- | src/or/hs_client.c | 45 | ||||
-rw-r--r-- | src/or/hs_client.h | 2 | ||||
-rw-r--r-- | src/or/main.c | 3 | ||||
-rw-r--r-- | src/or/rendcache.c | 4 |
8 files changed, 100 insertions, 7 deletions
diff --git a/src/or/connection.c b/src/or/connection.c index 31a682387d..01d7752e8d 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -4113,16 +4113,27 @@ connection_write_to_buf_impl_,(const char *string, size_t len, return ret_conns; \ STMT_END -/* Return a list of connections that aren't close and matches the given state. - * The returned list can be empty and must be freed using smartlist_free(). - * The caller does NOT have owernship of the objects in the list so it must - * not free them nor reference them as they can disapear. */ +/* Return a list of connections that aren't close and matches the given type + * and state. The returned list can be empty and must be freed using + * smartlist_free(). The caller does NOT have owernship of the objects in the + * list so it must not free them nor reference them as they can disappear. */ smartlist_t * connection_list_by_type_state(int type, int state) { CONN_GET_ALL_TEMPLATE(conn, (conn->type == type && conn->state == state)); } +/* Return a list of connections that aren't close and matches the given type + * and purpose. The returned list can be empty and must be freed using + * smartlist_free(). The caller does NOT have owernship of the objects in the + * list so it must not free them nor reference them as they can disappear. */ +smartlist_t * +connection_list_by_type_purpose(int type, int purpose) +{ + CONN_GET_ALL_TEMPLATE(conn, + (conn->type == type && conn->purpose == purpose)); +} + /** Return a connection_t * from get_connection_array() that satisfies test on * var, and that is not marked for close. */ #define CONN_GET_TEMPLATE(var, test) \ diff --git a/src/or/connection.h b/src/or/connection.h index 0bcf0ccdce..0aa13ada30 100644 --- a/src/or/connection.h +++ b/src/or/connection.h @@ -183,6 +183,7 @@ connection_t *connection_get_by_type_state(int type, int state); connection_t *connection_get_by_type_state_rendquery(int type, int state, const char *rendquery); smartlist_t *connection_list_by_type_state(int type, int state); +smartlist_t *connection_list_by_type_purpose(int type, int purpose); smartlist_t *connection_dir_list_by_purpose_and_resource( int purpose, const char *resource); diff --git a/src/or/hs_cache.c b/src/or/hs_cache.c index 6962c5ce44..78e2adacf6 100644 --- a/src/or/hs_cache.c +++ b/src/or/hs_cache.c @@ -726,6 +726,23 @@ hs_cache_clean_as_client(time_t now) cache_clean_v3_as_client(now); } +/* Purge the client descriptor cache. */ +void +hs_cache_purge_as_client(void) +{ + DIGEST256MAP_FOREACH_MODIFY(hs_cache_v3_client, key, + hs_cache_client_descriptor_t *, entry) { + size_t entry_size = cache_get_client_entry_size(entry); + MAP_DEL_CURRENT(key); + cache_client_desc_free(entry); + /* Update our OOM. We didn't use the remove() function because we are in + * a loop so we have to explicitely decrement. */ + rend_cache_decrement_allocation(entry_size); + } DIGEST256MAP_FOREACH_END; + + log_info(LD_REND, "Hidden service client descriptor cache purged."); +} + /* For a given service identity public key and an introduction authentication * key, note the given failure in the client intro state cache. */ void @@ -779,6 +796,20 @@ hs_cache_client_intro_state_clean(time_t now) } DIGEST256MAP_FOREACH_END; } +/* Purge the client introduction state cache. */ +void +hs_cache_client_intro_state_purge(void) +{ + DIGEST256MAP_FOREACH_MODIFY(hs_cache_client_intro_state, key, + hs_cache_client_intro_state_t *, cache) { + MAP_DEL_CURRENT(key); + cache_client_intro_state_free(cache); + } DIGEST256MAP_FOREACH_END; + + log_info(LD_REND, "Hidden service client introduction point state " + "cache purged."); +} + /**************** Generics *********************************/ /* Do a round of OOM cleanup on all directory caches. Return the amount of diff --git a/src/or/hs_cache.h b/src/or/hs_cache.h index 2a4d2dbb2f..8dbc842b95 100644 --- a/src/or/hs_cache.h +++ b/src/or/hs_cache.h @@ -84,6 +84,7 @@ hs_cache_lookup_as_client(const ed25519_public_key_t *key); int hs_cache_store_as_client(const char *desc_str, const ed25519_public_key_t *identity_pk); void hs_cache_clean_as_client(time_t now); +void hs_cache_purge_as_client(void); /* Client failure cache. */ void hs_cache_client_intro_state_note(const ed25519_public_key_t *service_pk, @@ -93,6 +94,7 @@ const hs_cache_intro_state_t *hs_cache_client_intro_state_find( const ed25519_public_key_t *service_pk, const ed25519_public_key_t *auth_key); void hs_cache_client_intro_state_clean(time_t now); +void hs_cache_client_intro_state_purge(void); #ifdef HS_CACHE_PRIVATE diff --git a/src/or/hs_client.c b/src/or/hs_client.c index 99be058eb7..0015a90168 100644 --- a/src/or/hs_client.c +++ b/src/or/hs_client.c @@ -29,6 +29,30 @@ #include "hs_ntor.h" #include "circuitbuild.h" +/* Cancel all descriptor fetches currently in progress. */ +static void +cancel_descriptor_fetches(void) +{ + smartlist_t *conns = + connection_list_by_type_state(CONN_TYPE_DIR, DIR_PURPOSE_FETCH_HSDESC); + SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) { + const hs_ident_dir_conn_t *ident = TO_DIR_CONN(conn)->hs_ident; + if (BUG(ident == NULL)) { + /* A directory connection fetching a service descriptor can't have an + * empty hidden service identifier. */ + continue; + } + log_debug(LD_REND, "Marking for close a directory connection fetching " + "a hidden service descriptor for service %s.", + safe_str_client(ed25519_fmt(&ident->identity_pk))); + connection_mark_for_close(conn); + } SMARTLIST_FOREACH_END(conn); + + /* No ownership of the objects in this list. */ + smartlist_free(conns); + log_info(LD_REND, "Hidden service client descriptor fetches cancelled."); +} + /* Get all connections that are waiting on a circuit and flag them back to * waiting for a hidden service descriptor for the given service key * service_identity_pk. */ @@ -1251,3 +1275,24 @@ hs_client_reextend_intro_circuit(origin_circuit_t *circ) return ret; } +/* Purge all potentially remotely-detectable state held in the hidden + * service client code. Called on SIGNAL NEWNYM. */ +void +hs_client_purge_state(void) +{ + /* v2 subsystem. */ + rend_client_purge_state(); + + /* Cancel all descriptor fetches. Do this first so once done we are sure + * that our descriptor cache won't modified. */ + cancel_descriptor_fetches(); + /* Purge the introduction point state cache. */ + hs_cache_client_intro_state_purge(); + /* Purge the descriptor cache. */ + hs_cache_purge_as_client(); + /* Purge the last hidden service request cache. */ + hs_purge_last_hid_serv_requests(); + + log_info(LD_REND, "Hidden service client state has been purged."); +} + diff --git a/src/or/hs_client.h b/src/or/hs_client.h index 8ed0501c91..a0f7c6b466 100644 --- a/src/or/hs_client.h +++ b/src/or/hs_client.h @@ -46,5 +46,7 @@ extend_info_t *hs_client_get_random_intro_from_edge( int hs_client_reextend_intro_circuit(origin_circuit_t *circ); +void hs_client_purge_state(void); + #endif /* TOR_HS_CLIENT_H */ diff --git a/src/or/main.c b/src/or/main.c index 5d51d1dead..b67e725448 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -80,6 +80,7 @@ #include "hibernate.h" #include "hs_cache.h" #include "hs_circuitmap.h" +#include "hs_client.h" #include "keypin.h" #include "main.h" #include "microdesc.h" @@ -1142,7 +1143,7 @@ signewnym_impl(time_t now) circuit_mark_all_dirty_circs_as_unusable(); addressmap_clear_transient(); - rend_client_purge_state(); + hs_client_purge_state(); time_of_last_signewnym = now; signewnym_is_pending = 0; diff --git a/src/or/rendcache.c b/src/or/rendcache.c index 792f6a1302..b98b2bccfa 100644 --- a/src/or/rendcache.c +++ b/src/or/rendcache.c @@ -303,7 +303,7 @@ void rend_cache_purge(void) { if (rend_cache) { - log_info(LD_REND, "Purging HS descriptor cache"); + log_info(LD_REND, "Purging HS v2 descriptor cache"); strmap_free(rend_cache, rend_cache_entry_free_); } rend_cache = strmap_new(); @@ -315,7 +315,7 @@ void rend_cache_failure_purge(void) { if (rend_cache_failure) { - log_info(LD_REND, "Purging HS failure cache"); + log_info(LD_REND, "Purging HS v2 failure cache"); strmap_free(rend_cache_failure, rend_cache_failure_entry_free_); } rend_cache_failure = strmap_new(); |