diff options
author | Nick Mathewson <nickm@torproject.org> | 2017-09-08 12:13:48 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-09-08 12:13:48 -0400 |
commit | ca19a95d5402e2f74e027761223f6d7605534c2c (patch) | |
tree | d6e6c23ba6280bfeb846d2429eeae758063e8caf | |
parent | 2264172fb32134c6c2fb0dab67229c820696ccb5 (diff) | |
parent | 22295759afa90f19b06e2b657ce84d518c2390fd (diff) | |
download | tor-ca19a95d5402e2f74e027761223f6d7605534c2c.tar.gz tor-ca19a95d5402e2f74e027761223f6d7605534c2c.zip |
Merge remote-tracking branch 'dgoulet/ticket23355_032_01'
-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 e2392b52e3..5c675acca4 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -4124,16 +4124,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 57b9a4a1df..5b51bb9fae 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 e7d316b745..f85ebc8473 100644 --- a/src/or/hs_client.c +++ b/src/or/hs_client.c @@ -33,6 +33,30 @@ #include "circuitbuild.h" #include "networkstatus.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. */ @@ -1275,3 +1299,24 @@ hs_client_free_all(void) hs_purge_last_hid_serv_requests(); } +/* 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 d8b8acf750..5227704506 100644 --- a/src/or/hs_client.h +++ b/src/or/hs_client.h @@ -46,6 +46,8 @@ 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); + void hs_client_free_all(void); #ifdef HS_CLIENT_PRIVATE diff --git a/src/or/main.c b/src/or/main.c index cd726776c4..c987ddc61b 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -81,6 +81,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" @@ -1144,7 +1145,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(); |