diff --git a/ChangeLog b/ChangeLog index ebdbba1774..16046c2d53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -49,6 +49,9 @@ Changes in version 0.2.0.3-alpha - 2007-??-?? o Minor bugfixes (directory): - Fix another crash bug related to extra-info caching. (Bug found by Peter Palfrader.) [Bugfix on 0.2.0.2-alpha] + - Fix a potential crash bug when we load many server descriptors at + once and some of them make others of them obsolete. Fixes bug + 458. [Bugfix on 0.1.2.x] - Directories no longer return a "304 not modified" when they don't have the networkstatus the client asked for. Also fix a memory leak when returning 304 not modified. [Bugfixes on 0.2.0.2-alpha] diff --git a/src/or/control.c b/src/or/control.c index 3f929ffbb5..f103982e0f 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -3013,7 +3013,7 @@ control_event_logmsg(int severity, uint32_t domain, const char *msg) /** Called whenever we receive new router descriptors: tell any * interested control connections. routers is a list of - * DIGEST_LEN-byte identity digests. + * routerinfo_t's. */ int control_event_descriptors_changed(smartlist_t *routers) diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 113b063b78..c75c024dc4 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -2337,7 +2337,10 @@ router_set_status(const char *digest, int up) /** Add router to the routerlist, if we don't already have it. Replace * older entries (if any) with the same key. Note: Callers should not hold * their pointers to router if this function fails; router - * will either be inserted into the routerlist or freed. + * will either be inserted into the routerlist or freed. Similarly, even + * if this call succeeds, they should not hold their pointers to + * router after subsequent calls with other routerinfo's -- they + * might cause the original routerinfo to get freed. * * Returns >= 0 if the router was added; less than 0 if it was not. * @@ -2863,13 +2866,13 @@ router_load_routers_from_string(const char *s, const char *eos, if (purpose != ROUTER_PURPOSE_GENERAL) ri->cache_info.do_not_cache = 1; - if (router_add_to_routerlist(ri, &msg, from_cache, !from_cache) >= 0) + if (router_add_to_routerlist(ri, &msg, from_cache, !from_cache) >= 0) { smartlist_add(changed, ri); + routerlist_descriptors_added(changed); + smartlist_clear(changed); + } }); - if (smartlist_len(changed)) - routerlist_descriptors_added(changed); - routerlist_assert_ok(routerlist); router_rebuild_store(0, 0);