diff --git a/src/or/or.h b/src/or/or.h index 2f1307d050..a33ad80e11 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -4994,7 +4994,8 @@ typedef enum was_router_added_t { ROUTER_NOT_IN_CONSENSUS = -3, ROUTER_NOT_IN_CONSENSUS_OR_NETWORKSTATUS = -4, ROUTER_AUTHDIR_REJECTS = -5, - ROUTER_WAS_NOT_WANTED = -6 + ROUTER_WAS_NOT_WANTED = -6, + ROUTER_WAS_TOO_OLD = -7, } was_router_added_t; /********************************* routerparse.c ************************/ diff --git a/src/or/routerlist.c b/src/or/routerlist.c index e851845280..b3b1979074 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -2937,12 +2937,12 @@ routerlist_insert(routerlist_t *rl, routerinfo_t *ri) } /** Adds the extrainfo_t ei to the routerlist rl, if there is a - * corresponding router in rl-\>routers or rl-\>old_routers. Return true iff - * we actually inserted ei. Free ei if it isn't inserted. */ -MOCK_IMPL(STATIC int, + * corresponding router in rl-\>routers or rl-\>old_routers. Return the status + * of inserting ei. Free ei if it isn't inserted. */ +MOCK_IMPL(STATIC was_router_added_t, extrainfo_insert,(routerlist_t *rl, extrainfo_t *ei)) { - int r = 0; + was_router_added_t r; routerinfo_t *ri = rimap_get(rl->identity_map, ei->cache_info.identity_digest); signed_descriptor_t *sd = @@ -2956,9 +2956,11 @@ extrainfo_insert,(routerlist_t *rl, extrainfo_t *ei)) if (!ri) { /* This router is unknown; we can't even verify the signature. Give up.*/ + r = ROUTER_NOT_IN_CONSENSUS; goto done; } if (routerinfo_incompatible_with_extrainfo(ri, ei, sd, NULL)) { + r = (sd->extrainfo_is_bogus) ? ROUTER_BAD_EI : ROUTER_NOT_IN_CONSENSUS; goto done; } @@ -2968,7 +2970,7 @@ extrainfo_insert,(routerlist_t *rl, extrainfo_t *ei)) ei_tmp = eimap_set(rl->extra_info_map, ei->cache_info.signed_descriptor_digest, ei); - r = 1; + r = ROUTER_ADDED_SUCCESSFULLY; if (ei_tmp) { rl->extrainfo_store.bytes_dropped += ei_tmp->cache_info.signed_descriptor_len; @@ -2976,7 +2978,7 @@ extrainfo_insert,(routerlist_t *rl, extrainfo_t *ei)) } done: - if (r == 0) + if (r != ROUTER_ADDED_SUCCESSFULLY) extrainfo_free(ei); #ifdef DEBUG_ROUTERLIST @@ -3302,7 +3304,7 @@ routerlist_reset_warnings(void) MOCK_IMPL(int, router_descriptor_is_older_than,(const routerinfo_t *router, int seconds)) { - return router->cache_info.published_on < time(NULL) - seconds; + return router->cache_info.published_on < approx_time() - seconds; } /** Add router to the routerlist, if we don't already have it. Replace @@ -3477,7 +3479,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg, router_descriptor_is_older_than(router, OLD_ROUTER_DESC_MAX_AGE)) { *msg = "Router descriptor was really old."; routerinfo_free(router); - return ROUTER_WAS_NOT_NEW; + return ROUTER_WAS_TOO_OLD; } /* We haven't seen a router with this identity before. Add it to the end of @@ -3498,21 +3500,18 @@ was_router_added_t router_add_extrainfo_to_routerlist(extrainfo_t *ei, const char **msg, int from_cache, int from_fetch) { - int inserted; + was_router_added_t inserted; (void)from_fetch; if (msg) *msg = NULL; /*XXXX023 Do something with msg */ inserted = extrainfo_insert(router_get_routerlist(), ei); - if (inserted && !from_cache) + if (WRA_WAS_ADDED(inserted) && !from_cache) signed_desc_append_to_journal(&ei->cache_info, &routerlist->extrainfo_store); - if (inserted) - return ROUTER_ADDED_SUCCESSFULLY; - else - return ROUTER_BAD_EI; + return inserted; } /** Sorting helper: return <0, 0, or >0 depending on whether the @@ -3912,7 +3911,7 @@ router_load_routers_from_string(const char *s, const char *eos, smartlist_add(changed, ri); routerlist_descriptors_added(changed, from_cache); smartlist_clear(changed); - } else if (WRA_WAS_REJECTED(r)) { + } else if (WRA_NEVER_DOWNLOADABLE(r)) { download_status_t *dl_status; dl_status = router_get_dl_status_by_descriptor_digest(d); if (dl_status) { @@ -3977,6 +3976,8 @@ router_load_extrainfo_from_string(const char *s, const char *eos, SMARTLIST_FOREACH_BEGIN(extrainfo_list, extrainfo_t *, ei) { was_router_added_t added = router_add_extrainfo_to_routerlist(ei, &msg, from_cache, !from_cache); + uint8_t d[DIGEST_LEN]; + memcpy(d, ei->cache_info.signed_descriptor_digest, DIGEST_LEN); if (WRA_WAS_ADDED(added) && requested_fingerprints) { char fp[HEX_DIGEST_LEN+1]; base16_encode(fp, sizeof(fp), descriptor_digests ? @@ -3988,6 +3989,14 @@ router_load_extrainfo_from_string(const char *s, const char *eos, * so long as we would have wanted them anyway. Since we always fetch * all the extrainfos we want, and we never actually act on them * inside Tor, this should be harmless. */ + } else if (WRA_NEVER_DOWNLOADABLE(added)) { + signed_descriptor_t *sd = router_get_by_extrainfo_digest((char*)d); + if (sd) { + log_info(LD_GENERAL, "Marking extrainfo with descriptor %s as " + "unparseable, and therefore undownloadable", + hex_str((char*)d,DIGEST_LEN)); + download_status_mark_impossible(&sd->ei_dl_status); + } } } SMARTLIST_FOREACH_END(ei); diff --git a/src/or/routerlist.h b/src/or/routerlist.h index 950320aa14..a0f43d430c 100644 --- a/src/or/routerlist.h +++ b/src/or/routerlist.h @@ -100,6 +100,7 @@ void routerlist_reset_warnings(void); static int WRA_WAS_ADDED(was_router_added_t s); static int WRA_WAS_OUTDATED(was_router_added_t s); static int WRA_WAS_REJECTED(was_router_added_t s); +static int WRA_NEVER_DOWNLOADABLE(was_router_added_t s); /** Return true iff the outcome code in s indicates that the descriptor * was added. It might still be necessary to check whether the descriptor * generator should be notified. @@ -116,7 +117,8 @@ WRA_WAS_ADDED(was_router_added_t s) { */ static INLINE int WRA_WAS_OUTDATED(was_router_added_t s) { - return (s == ROUTER_WAS_NOT_NEW || + return (s == ROUTER_WAS_TOO_OLD || + s == ROUTER_WAS_NOT_NEW || s == ROUTER_NOT_IN_CONSENSUS || s == ROUTER_NOT_IN_CONSENSUS_OR_NETWORKSTATUS); } @@ -126,6 +128,14 @@ static INLINE int WRA_WAS_REJECTED(was_router_added_t s) { return (s == ROUTER_AUTHDIR_REJECTS); } +/** Return true iff the outcome code in s indicates that the descriptor + * was flat-out rejected. */ +static INLINE int WRA_NEVER_DOWNLOADABLE(was_router_added_t s) +{ + return (s == ROUTER_AUTHDIR_REJECTS || + s == ROUTER_BAD_EI || + s == ROUTER_WAS_TOO_OLD); +} was_router_added_t router_add_to_routerlist(routerinfo_t *router, const char **msg, int from_cache, @@ -216,7 +226,8 @@ STATIC void scale_array_elements_to_u64(u64_dbl_t *entries, int n_entries, MOCK_DECL(int, router_descriptor_is_older_than, (const routerinfo_t *router, int seconds)); -MOCK_DECL(STATIC int, extrainfo_insert,(routerlist_t *rl, extrainfo_t *ei)); +MOCK_DECL(STATIC was_router_added_t, extrainfo_insert, + (routerlist_t *rl, extrainfo_t *ei)); #endif diff --git a/src/test/test_dir.c b/src/test/test_dir.c index 0499251352..e03efbeff5 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -618,6 +618,8 @@ test_dir_load_routers(void *arg) MOCK(router_get_dl_status_by_descriptor_digest, mock_router_get_dl_status); + update_approx_time(1412510400); + smartlist_add(chunks, tor_strdup(EX_RI_MINIMAL)); smartlist_add(chunks, tor_strdup(EX_RI_BAD_FINGERPRINT)); smartlist_add(chunks, tor_strdup(EX_RI_BAD_SIG2)); @@ -708,12 +710,12 @@ mock_get_by_ei_desc_digest(const char *d) } static smartlist_t *mock_ei_insert_list = NULL; -static int +static was_router_added_t mock_ei_insert(routerlist_t *rl, extrainfo_t *ei) { (void) rl; smartlist_add(mock_ei_insert_list, ei); - return 1; + return ROUTER_ADDED_SUCCESSFULLY; } static void