Loading changes/bug23817 0 → 100644 +3 −0 Original line number Diff line number Diff line o Minor bugfixes (descriptors): - Don't try fetching microdescriptors from relays that have failed to deliver them in the past. Fixes bug 23817; bugfix on 0.3.0.1-alpha. src/or/directory.c +2 −2 Original line number Diff line number Diff line Loading @@ -464,7 +464,7 @@ directory_pick_generic_dirserver(dirinfo_type_t type, int pds_flags, log_warn(LD_BUG, "Called when we have UseBridges set."); if (should_use_directory_guards(options)) { const node_t *node = guards_choose_dirguard(guard_state_out); const node_t *node = guards_choose_dirguard(dir_purpose, guard_state_out); if (node) rs = node->rs; } else { Loading Loading @@ -598,7 +598,7 @@ directory_get_from_dirserver,( * sort of dir fetch we'll be doing, so it won't return a bridge * that can't answer our question. */ const node_t *node = guards_choose_dirguard(&guard_state); const node_t *node = guards_choose_dirguard(dir_purpose, &guard_state); if (node && node->ri) { /* every bridge has a routerinfo. */ routerinfo_t *ri = node->ri; Loading src/or/entrynodes.c +84 −11 Original line number Diff line number Diff line Loading @@ -1460,6 +1460,70 @@ guard_in_node_family(const entry_guard_t *guard, const node_t *node) } } /* Allocate and return a new exit guard restriction (where <b>exit_id</b> is of * size DIGEST_LEN) */ STATIC entry_guard_restriction_t * guard_create_exit_restriction(const uint8_t *exit_id) { entry_guard_restriction_t *rst = NULL; rst = tor_malloc_zero(sizeof(entry_guard_restriction_t)); rst->type = RST_EXIT_NODE; memcpy(rst->exclude_id, exit_id, DIGEST_LEN); return rst; } /** Allocate and return an outdated md guard restriction. */ STATIC entry_guard_restriction_t * guard_create_dirserver_md_restriction(void) { entry_guard_restriction_t *rst = NULL; rst = tor_malloc_zero(sizeof(entry_guard_restriction_t)); rst->type = RST_OUTDATED_MD_DIRSERVER; return rst; } /* Return True if <b>guard</b> obeys the exit restriction <b>rst</b>. */ static int guard_obeys_exit_restriction(const entry_guard_t *guard, const entry_guard_restriction_t *rst) { tor_assert(rst->type == RST_EXIT_NODE); // Exclude the exit ID and all of its family. const node_t *node = node_get_by_id((const char*)rst->exclude_id); if (node && guard_in_node_family(guard, node)) return 0; return tor_memneq(guard->identity, rst->exclude_id, DIGEST_LEN); } /** Return True if <b>guard</b> should be used as a dirserver for fetching * microdescriptors. */ static int guard_obeys_md_dirserver_restriction(const entry_guard_t *guard) { /* Don't enforce dirserver restrictions for bridges since we might not have * many of those. Be willing to try them over and over again for now. */ /* XXX: Improvement might be possible here */ if (guard->bridge_addr) { return 1; } /* If this guard is an outdated dirserver, don't use it. */ if (microdesc_relay_is_outdated_dirserver(guard->identity)) { log_info(LD_GENERAL, "Skipping %s dirserver: outdated", hex_str(guard->identity, DIGEST_LEN)); return 0; } log_debug(LD_GENERAL, "%s dirserver obeys md restrictions", hex_str(guard->identity, DIGEST_LEN)); return 1; } /** * Return true iff <b>guard</b> obeys the restrictions defined in <b>rst</b>. * (If <b>rst</b> is NULL, there are no restrictions.) Loading @@ -1472,13 +1536,14 @@ entry_guard_obeys_restriction(const entry_guard_t *guard, if (! rst) return 1; // No restriction? No problem. // Only one kind of restriction exists right now: excluding an exit // ID and all of its family. const node_t *node = node_get_by_id((const char*)rst->exclude_id); if (node && guard_in_node_family(guard, node)) return 0; if (rst->type == RST_EXIT_NODE) { return guard_obeys_exit_restriction(guard, rst); } else if (rst->type == RST_OUTDATED_MD_DIRSERVER) { return guard_obeys_md_dirserver_restriction(guard); } return tor_memneq(guard->identity, rst->exclude_id, DIGEST_LEN); tor_assert_nonfatal_unreached(); return 0; } /** Loading Loading @@ -2105,7 +2170,7 @@ entry_guard_has_higher_priority(entry_guard_t *a, entry_guard_t *b) } /** Release all storage held in <b>restriction</b> */ static void STATIC void entry_guard_restriction_free(entry_guard_restriction_t *rst) { tor_free(rst); Loading Loading @@ -3358,8 +3423,8 @@ guards_choose_guard(cpath_build_state_t *state, /* We're building to a targeted exit node, so that node can't be * chosen as our guard for this circuit. Remember that fact in a * restriction. */ rst = tor_malloc_zero(sizeof(entry_guard_restriction_t)); memcpy(rst->exclude_id, exit_id, DIGEST_LEN); rst = guard_create_exit_restriction(exit_id); tor_assert(rst); } if (entry_guard_pick_for_circuit(get_guard_selection_info(), GUARD_USAGE_TRAFFIC, Loading Loading @@ -3411,12 +3476,20 @@ remove_all_entry_guards(void) /** Helper: pick a directory guard, with whatever algorithm is used. */ const node_t * guards_choose_dirguard(circuit_guard_state_t **guard_state_out) guards_choose_dirguard(uint8_t dir_purpose, circuit_guard_state_t **guard_state_out) { const node_t *r = NULL; entry_guard_restriction_t *rst = NULL; /* If we are fetching microdescs, don't query outdated dirservers. */ if (dir_purpose == DIR_PURPOSE_FETCH_MICRODESC) { rst = guard_create_dirserver_md_restriction(); } if (entry_guard_pick_for_circuit(get_guard_selection_info(), GUARD_USAGE_DIRGUARD, NULL, rst, &r, guard_state_out) < 0) { tor_assert(r == NULL); Loading src/or/entrynodes.h +27 −10 Original line number Diff line number Diff line Loading @@ -272,22 +272,28 @@ struct guard_selection_s { struct entry_guard_handle_t; /** Types of restrictions we impose when picking guard nodes */ typedef enum guard_restriction_type_t { /* Don't pick the same guard node as our exit node (or its family) */ RST_EXIT_NODE = 0, /* Don't pick dirguards that have previously shown to be outdated */ RST_OUTDATED_MD_DIRSERVER = 1 } guard_restriction_type_t; /** * A restriction to remember which entry guards are off-limits for a given * circuit. * * Right now, we only use restrictions to block a single guard and its family * from being selected; this mechanism is designed to be more extensible in * the future, however. * * Note: This mechanism is NOT for recording which guards are never to be * used: only which guards cannot be used on <em>one particular circuit</em>. */ struct entry_guard_restriction_t { /** * The guard's RSA identity digest must not equal this; and it must not * be in the same family as any node with this digest. */ /* What type of restriction are we imposing? */ guard_restriction_type_t type; /* In case of restriction type RST_EXIT_NODE, the guard's RSA identity * digest must not equal this; and it must not be in the same family as any * node with this digest. */ uint8_t exclude_id[DIGEST_LEN]; }; Loading Loading @@ -316,7 +322,8 @@ struct circuit_guard_state_t { int guards_update_all(void); const node_t *guards_choose_guard(cpath_build_state_t *state, circuit_guard_state_t **guard_state_out); const node_t *guards_choose_dirguard(circuit_guard_state_t **guard_state_out); const node_t *guards_choose_dirguard(uint8_t dir_purpose, circuit_guard_state_t **guard_state_out); #if 1 /* XXXX NM I would prefer that all of this stuff be private to Loading Loading @@ -550,7 +557,17 @@ STATIC unsigned entry_guards_note_guard_success(guard_selection_t *gs, unsigned old_state); STATIC int entry_guard_has_higher_priority(entry_guard_t *a, entry_guard_t *b); STATIC char *getinfo_helper_format_single_entry_guard(const entry_guard_t *e); #endif STATIC entry_guard_restriction_t * guard_create_exit_restriction(const uint8_t *exit_id); STATIC entry_guard_restriction_t * guard_create_dirserver_md_restriction(void); STATIC void entry_guard_restriction_free(entry_guard_restriction_t *rst); #endif /* defined(ENTRYNODES_PRIVATE) */ void remove_all_entry_guards_for_guard_selection(guard_selection_t *gs); void remove_all_entry_guards(void); Loading Loading
changes/bug23817 0 → 100644 +3 −0 Original line number Diff line number Diff line o Minor bugfixes (descriptors): - Don't try fetching microdescriptors from relays that have failed to deliver them in the past. Fixes bug 23817; bugfix on 0.3.0.1-alpha.
src/or/directory.c +2 −2 Original line number Diff line number Diff line Loading @@ -464,7 +464,7 @@ directory_pick_generic_dirserver(dirinfo_type_t type, int pds_flags, log_warn(LD_BUG, "Called when we have UseBridges set."); if (should_use_directory_guards(options)) { const node_t *node = guards_choose_dirguard(guard_state_out); const node_t *node = guards_choose_dirguard(dir_purpose, guard_state_out); if (node) rs = node->rs; } else { Loading Loading @@ -598,7 +598,7 @@ directory_get_from_dirserver,( * sort of dir fetch we'll be doing, so it won't return a bridge * that can't answer our question. */ const node_t *node = guards_choose_dirguard(&guard_state); const node_t *node = guards_choose_dirguard(dir_purpose, &guard_state); if (node && node->ri) { /* every bridge has a routerinfo. */ routerinfo_t *ri = node->ri; Loading
src/or/entrynodes.c +84 −11 Original line number Diff line number Diff line Loading @@ -1460,6 +1460,70 @@ guard_in_node_family(const entry_guard_t *guard, const node_t *node) } } /* Allocate and return a new exit guard restriction (where <b>exit_id</b> is of * size DIGEST_LEN) */ STATIC entry_guard_restriction_t * guard_create_exit_restriction(const uint8_t *exit_id) { entry_guard_restriction_t *rst = NULL; rst = tor_malloc_zero(sizeof(entry_guard_restriction_t)); rst->type = RST_EXIT_NODE; memcpy(rst->exclude_id, exit_id, DIGEST_LEN); return rst; } /** Allocate and return an outdated md guard restriction. */ STATIC entry_guard_restriction_t * guard_create_dirserver_md_restriction(void) { entry_guard_restriction_t *rst = NULL; rst = tor_malloc_zero(sizeof(entry_guard_restriction_t)); rst->type = RST_OUTDATED_MD_DIRSERVER; return rst; } /* Return True if <b>guard</b> obeys the exit restriction <b>rst</b>. */ static int guard_obeys_exit_restriction(const entry_guard_t *guard, const entry_guard_restriction_t *rst) { tor_assert(rst->type == RST_EXIT_NODE); // Exclude the exit ID and all of its family. const node_t *node = node_get_by_id((const char*)rst->exclude_id); if (node && guard_in_node_family(guard, node)) return 0; return tor_memneq(guard->identity, rst->exclude_id, DIGEST_LEN); } /** Return True if <b>guard</b> should be used as a dirserver for fetching * microdescriptors. */ static int guard_obeys_md_dirserver_restriction(const entry_guard_t *guard) { /* Don't enforce dirserver restrictions for bridges since we might not have * many of those. Be willing to try them over and over again for now. */ /* XXX: Improvement might be possible here */ if (guard->bridge_addr) { return 1; } /* If this guard is an outdated dirserver, don't use it. */ if (microdesc_relay_is_outdated_dirserver(guard->identity)) { log_info(LD_GENERAL, "Skipping %s dirserver: outdated", hex_str(guard->identity, DIGEST_LEN)); return 0; } log_debug(LD_GENERAL, "%s dirserver obeys md restrictions", hex_str(guard->identity, DIGEST_LEN)); return 1; } /** * Return true iff <b>guard</b> obeys the restrictions defined in <b>rst</b>. * (If <b>rst</b> is NULL, there are no restrictions.) Loading @@ -1472,13 +1536,14 @@ entry_guard_obeys_restriction(const entry_guard_t *guard, if (! rst) return 1; // No restriction? No problem. // Only one kind of restriction exists right now: excluding an exit // ID and all of its family. const node_t *node = node_get_by_id((const char*)rst->exclude_id); if (node && guard_in_node_family(guard, node)) return 0; if (rst->type == RST_EXIT_NODE) { return guard_obeys_exit_restriction(guard, rst); } else if (rst->type == RST_OUTDATED_MD_DIRSERVER) { return guard_obeys_md_dirserver_restriction(guard); } return tor_memneq(guard->identity, rst->exclude_id, DIGEST_LEN); tor_assert_nonfatal_unreached(); return 0; } /** Loading Loading @@ -2105,7 +2170,7 @@ entry_guard_has_higher_priority(entry_guard_t *a, entry_guard_t *b) } /** Release all storage held in <b>restriction</b> */ static void STATIC void entry_guard_restriction_free(entry_guard_restriction_t *rst) { tor_free(rst); Loading Loading @@ -3358,8 +3423,8 @@ guards_choose_guard(cpath_build_state_t *state, /* We're building to a targeted exit node, so that node can't be * chosen as our guard for this circuit. Remember that fact in a * restriction. */ rst = tor_malloc_zero(sizeof(entry_guard_restriction_t)); memcpy(rst->exclude_id, exit_id, DIGEST_LEN); rst = guard_create_exit_restriction(exit_id); tor_assert(rst); } if (entry_guard_pick_for_circuit(get_guard_selection_info(), GUARD_USAGE_TRAFFIC, Loading Loading @@ -3411,12 +3476,20 @@ remove_all_entry_guards(void) /** Helper: pick a directory guard, with whatever algorithm is used. */ const node_t * guards_choose_dirguard(circuit_guard_state_t **guard_state_out) guards_choose_dirguard(uint8_t dir_purpose, circuit_guard_state_t **guard_state_out) { const node_t *r = NULL; entry_guard_restriction_t *rst = NULL; /* If we are fetching microdescs, don't query outdated dirservers. */ if (dir_purpose == DIR_PURPOSE_FETCH_MICRODESC) { rst = guard_create_dirserver_md_restriction(); } if (entry_guard_pick_for_circuit(get_guard_selection_info(), GUARD_USAGE_DIRGUARD, NULL, rst, &r, guard_state_out) < 0) { tor_assert(r == NULL); Loading
src/or/entrynodes.h +27 −10 Original line number Diff line number Diff line Loading @@ -272,22 +272,28 @@ struct guard_selection_s { struct entry_guard_handle_t; /** Types of restrictions we impose when picking guard nodes */ typedef enum guard_restriction_type_t { /* Don't pick the same guard node as our exit node (or its family) */ RST_EXIT_NODE = 0, /* Don't pick dirguards that have previously shown to be outdated */ RST_OUTDATED_MD_DIRSERVER = 1 } guard_restriction_type_t; /** * A restriction to remember which entry guards are off-limits for a given * circuit. * * Right now, we only use restrictions to block a single guard and its family * from being selected; this mechanism is designed to be more extensible in * the future, however. * * Note: This mechanism is NOT for recording which guards are never to be * used: only which guards cannot be used on <em>one particular circuit</em>. */ struct entry_guard_restriction_t { /** * The guard's RSA identity digest must not equal this; and it must not * be in the same family as any node with this digest. */ /* What type of restriction are we imposing? */ guard_restriction_type_t type; /* In case of restriction type RST_EXIT_NODE, the guard's RSA identity * digest must not equal this; and it must not be in the same family as any * node with this digest. */ uint8_t exclude_id[DIGEST_LEN]; }; Loading Loading @@ -316,7 +322,8 @@ struct circuit_guard_state_t { int guards_update_all(void); const node_t *guards_choose_guard(cpath_build_state_t *state, circuit_guard_state_t **guard_state_out); const node_t *guards_choose_dirguard(circuit_guard_state_t **guard_state_out); const node_t *guards_choose_dirguard(uint8_t dir_purpose, circuit_guard_state_t **guard_state_out); #if 1 /* XXXX NM I would prefer that all of this stuff be private to Loading Loading @@ -550,7 +557,17 @@ STATIC unsigned entry_guards_note_guard_success(guard_selection_t *gs, unsigned old_state); STATIC int entry_guard_has_higher_priority(entry_guard_t *a, entry_guard_t *b); STATIC char *getinfo_helper_format_single_entry_guard(const entry_guard_t *e); #endif STATIC entry_guard_restriction_t * guard_create_exit_restriction(const uint8_t *exit_id); STATIC entry_guard_restriction_t * guard_create_dirserver_md_restriction(void); STATIC void entry_guard_restriction_free(entry_guard_restriction_t *rst); #endif /* defined(ENTRYNODES_PRIVATE) */ void remove_all_entry_guards_for_guard_selection(guard_selection_t *gs); void remove_all_entry_guards(void); Loading