/** Reschedule the directory-authority voting event. Run this whenever the * schedule has changed. */ void reschedule_dirvote(const or_options_t *options) { if (authdir_mode_v3(options)) { periodic_event_reschedule(&dirvote_event); } }
/** * Scheduled callback: Run directory-authority voting functionality. * * The schedule is a bit complicated here, so dirvote_act() manages the * schedule itself. **/ static int dirvote_callback(time_t now, const or_options_t *options) { if (!authdir_mode_v3(options)) { tor_assert_nonfatal_unreached(); return 3600; } time_t next = dirvote_act(options, now); if (BUG(next == TIME_MAX)) { /* This shouldn't be returned unless we called dirvote_act() without * being an authority. If it happens, maybe our configuration will * fix itself in an hour or so? */ return 3600; } return safe_timer_diff(now, next); }
/** Tell the nodelist that the current usable consensus is <b>ns</b>. * This makes the nodelist change all of the routerstatus entries for * the nodes, drop nodes that no longer have enough info to get used, * and grab microdescriptors into nodes as appropriate. */ void nodelist_set_consensus(networkstatus_t *ns) { const or_options_t *options = get_options(); int authdir = authdir_mode_v3(options); int client = !server_mode(options); init_nodelist(); if (ns->flavor == FLAV_MICRODESC) (void) get_microdesc_cache(); /* Make sure it exists first. */ SMARTLIST_FOREACH(the_nodelist->nodes, node_t *, node, node->rs = NULL); SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) { node_t *node = node_get_or_create(rs->identity_digest); node->rs = rs; if (ns->flavor == FLAV_MICRODESC) { if (node->md == NULL || tor_memneq(node->md->digest,rs->descriptor_digest,DIGEST256_LEN)) { if (node->md) node->md->held_by_nodes--; node->md = microdesc_cache_lookup_by_digest256(NULL, rs->descriptor_digest); if (node->md) node->md->held_by_nodes++; } } node_set_country(node); /* If we're not an authdir, believe others. */ if (!authdir) { node->is_valid = rs->is_valid; node->is_running = rs->is_flagged_running; node->is_fast = rs->is_fast; node->is_stable = rs->is_stable; node->is_possible_guard = rs->is_possible_guard; node->is_exit = rs->is_exit; node->is_bad_directory = rs->is_bad_directory; node->is_bad_exit = rs->is_bad_exit; node->is_hs_dir = rs->is_hs_dir; node->ipv6_preferred = 0; if (client && options->ClientPreferIPv6ORPort == 1 && (tor_addr_is_null(&rs->ipv6_addr) == 0 || (node->md && tor_addr_is_null(&node->md->ipv6_addr) == 0))) node->ipv6_preferred = 1; } } SMARTLIST_FOREACH_END(rs); nodelist_purge(); if (! authdir) { SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) { /* We have no routerstatus for this router. Clear flags so we can skip * it, maybe.*/ if (!node->rs) { tor_assert(node->ri); /* if it had only an md, or nothing, purge * would have removed it. */ if (node->ri->purpose == ROUTER_PURPOSE_GENERAL) { /* Clear all flags. */ node->is_valid = node->is_running = node->is_hs_dir = node->is_fast = node->is_stable = node->is_possible_guard = node->is_exit = node->is_bad_exit = node->is_bad_directory = node->ipv6_preferred = 0; } } } SMARTLIST_FOREACH_END(node); }