diff options
author | Nick Mathewson <nickm@torproject.org> | 2011-07-07 11:14:04 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2011-07-07 11:14:04 -0400 |
commit | 174cbff8cf855dc1bbf690694f539ba3f85a508c (patch) | |
tree | 34fbd173ca70e2c2dc946c20234481f91ff483be /src/or/microdesc.c | |
parent | 6b670d6032b33f255f88e31a727b8f042b1dfcef (diff) | |
parent | 4ba9f3e31702020eaa336ccb33294568cda256eb (diff) | |
download | tor-174cbff8cf855dc1bbf690694f539ba3f85a508c.tar.gz tor-174cbff8cf855dc1bbf690694f539ba3f85a508c.zip |
Merge remote-tracking branch 'public/bug3153'
Conflicts:
src/or/nodelist.c
Diffstat (limited to 'src/or/microdesc.c')
-rw-r--r-- | src/or/microdesc.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/src/or/microdesc.c b/src/or/microdesc.c index cae31fe4cb..1b0c333dae 100644 --- a/src/or/microdesc.c +++ b/src/or/microdesc.c @@ -238,6 +238,7 @@ microdescs_add_list_to_cache(microdesc_cache_t *cache, md->no_save = no_save; HT_INSERT(microdesc_map, &cache->map, md); + md->held_in_map = 1; smartlist_add(added, md); ++cache->n_seen; cache->total_len_seen += md->bodylen; @@ -266,6 +267,7 @@ microdesc_cache_clear(microdesc_cache_t *cache) for (entry = HT_START(microdesc_map, &cache->map); entry; entry = next) { microdesc_t *md = *entry; next = HT_NEXT_RMV(microdesc_map, &cache->map, entry); + md->held_in_map = 0; microdesc_free(md); } HT_CLEAR(microdesc_map, &cache->map); @@ -354,6 +356,7 @@ microdesc_cache_clean(microdesc_cache_t *cache, time_t cutoff, int force) ++dropped; victim = *mdp; mdp = HT_NEXT_RMV(microdesc_map, &cache->map, mdp); + victim->held_in_map = 0; bytes_dropped += victim->bodylen; microdesc_free(victim); } else { @@ -503,7 +506,43 @@ microdesc_free(microdesc_t *md) { if (!md) return; - /* Must be removed from hash table! */ + + /* Make sure that the microdesc was really removed from the appropriate data + structures. */ + if (md->held_in_map) { + microdesc_cache_t *cache = get_microdesc_cache(); + microdesc_t *md2 = HT_FIND(microdesc_map, &cache->map, md); + if (md2 == md) { + log_warn(LD_BUG, "microdesc_free() called, but md was still in " + "microdesc_map"); + HT_REMOVE(microdesc_map, &cache->map, md); + } else { + log_warn(LD_BUG, "microdesc_free() called with held_in_map set, but " + "microdesc was not in the map."); + } + tor_fragile_assert(); + } + if (md->held_by_node) { + int found=0; + const smartlist_t *nodes = nodelist_get_list(); + SMARTLIST_FOREACH(nodes, node_t *, node, { + if (node->md == md) { + ++found; + node->md = NULL; + } + }); + if (found) { + log_warn(LD_BUG, "microdesc_free() called, but md was still referenced " + "%d node(s)", found); + } else { + log_warn(LD_BUG, "microdesc_free() called with held_by_node set, but " + "md was not refrenced by any nodes"); + } + tor_fragile_assert(); + } + //tor_assert(md->held_in_map == 0); + //tor_assert(md->held_by_node == 0); + if (md->onion_pkey) crypto_free_pk_env(md->onion_pkey); if (md->body && md->saved_location != SAVED_IN_CACHE) |