aboutsummaryrefslogtreecommitdiff
path: root/src/or/dirserv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/dirserv.c')
-rw-r--r--src/or/dirserv.c137
1 files changed, 109 insertions, 28 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index d22a0538d..f4bbca850 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -232,7 +232,7 @@ dirserv_load_fingerprint_file(void)
}
tor_free(fname);
- result = config_get_lines(cf, &front);
+ result = config_get_lines(cf, &front, 0);
tor_free(cf);
if (result < 0) {
log_warn(LD_CONFIG, "Error reading from fingerprint file");
@@ -1212,7 +1212,7 @@ directory_fetches_from_authorities(const or_options_t *options)
return 1; /* we don't know our IP address; ask an authority. */
refuseunknown = ! router_my_exit_policy_is_reject_star() &&
should_refuse_unknown_exits(options);
- if (options->DirPort == 0 && !refuseunknown)
+ if (options->DirPort == NULL && !refuseunknown)
return 0;
if (!server_mode(options) || !advertised_server_mode())
return 0;
@@ -1248,7 +1248,7 @@ directory_fetches_dir_info_later(const or_options_t *options)
int
directory_caches_v2_dir_info(const or_options_t *options)
{
- return options->DirPort != 0;
+ return options->DirPort != NULL;
}
/** Return 1 if we want to keep descriptors, networkstatuses, etc around
@@ -1273,7 +1273,7 @@ directory_caches_dir_info(const or_options_t *options)
int
directory_permits_begindir_requests(const or_options_t *options)
{
- return options->BridgeRelay != 0 || options->DirPort != 0;
+ return options->BridgeRelay != 0 || options->DirPort != NULL;
}
/** Return 1 if we want to allow controllers to ask us directory
@@ -1282,7 +1282,7 @@ directory_permits_begindir_requests(const or_options_t *options)
int
directory_permits_controller_requests(const or_options_t *options)
{
- return options->DirPort != 0;
+ return options->DirPort != NULL;
}
/** Return 1 if we have no need to fetch new descriptors. This generally
@@ -1720,12 +1720,6 @@ should_generate_v2_networkstatus(void)
/** If a router's MTBF is at least this value, then it is always stable.
* See above. (Corresponds to about 7 days for current decay rates.) */
#define MTBF_TO_GUARANTEE_STABLE (60*60*24*5)
-/** Similarly, we protect sufficiently fast nodes from being pushed
- * out of the set of Fast nodes. */
-#define BANDWIDTH_TO_GUARANTEE_FAST ROUTER_REQUIRED_MIN_BANDWIDTH
-/** Similarly, every node with sufficient bandwidth can be considered
- * for Guard status. */
-#define BANDWIDTH_TO_GUARANTEE_GUARD (250*1024)
/** Similarly, every node with at least this much weighted time known can be
* considered familiar enough to be a guard. Corresponds to about 20 days for
* current decay rates.
@@ -1870,6 +1864,7 @@ dirserv_compute_performance_thresholds(routerlist_t *rl)
long *tks;
double *mtbfs, *wfus;
time_t now = time(NULL);
+ const or_options_t *options = get_options();
/* initialize these all here, in case there are no routers */
stable_uptime = 0;
@@ -1942,8 +1937,11 @@ dirserv_compute_performance_thresholds(routerlist_t *rl)
if (guard_tk > TIME_KNOWN_TO_GUARANTEE_FAMILIAR)
guard_tk = TIME_KNOWN_TO_GUARANTEE_FAMILIAR;
- if (fast_bandwidth > BANDWIDTH_TO_GUARANTEE_FAST)
- fast_bandwidth = BANDWIDTH_TO_GUARANTEE_FAST;
+ /* Protect sufficiently fast nodes from being pushed out of the set
+ * of Fast nodes. */
+ if (options->AuthDirFastGuarantee &&
+ fast_bandwidth > options->AuthDirFastGuarantee)
+ fast_bandwidth = (uint32_t)options->AuthDirFastGuarantee;
/* Now that we have a time-known that 7/8 routers are known longer than,
* fill wfus with the wfu of every such "familiar" router. */
@@ -2288,6 +2286,75 @@ get_possible_sybil_list(const smartlist_t *routers)
return omit_as_sybil;
}
+/** Return non-zero iff a relay running the Tor version specified in
+ * <b>platform</b> is suitable for use as a potential entry guard. */
+static int
+is_router_version_good_for_possible_guard(const char *platform)
+{
+ static int parsed_versions_initialized = 0;
+ static tor_version_t first_good_0_2_1_guard_version;
+ static tor_version_t first_good_0_2_2_guard_version;
+ static tor_version_t first_good_later_guard_version;
+
+ tor_version_t router_version;
+
+ /* XXX023 This block should be extracted into its own function. */
+ /* XXXX Begin code copied from tor_version_as_new_as (in routerparse.c) */
+ {
+ char *s, *s2, *start;
+ char tmp[128];
+
+ tor_assert(platform);
+
+ /* nonstandard Tor; be safe and say yes */
+ if (strcmpstart(platform,"Tor "))
+ return 1;
+
+ start = (char *)eat_whitespace(platform+3);
+ if (!*start) return 0;
+ s = (char *)find_whitespace(start); /* also finds '\0', which is fine */
+ s2 = (char*)eat_whitespace(s);
+ if (!strcmpstart(s2, "(r") || !strcmpstart(s2, "(git-"))
+ s = (char*)find_whitespace(s2);
+
+ if ((size_t)(s-start+1) >= sizeof(tmp)) /* too big, no */
+ return 0;
+ strlcpy(tmp, start, s-start+1);
+
+ if (tor_version_parse(tmp, &router_version)<0) {
+ log_info(LD_DIR,"Router version '%s' unparseable.",tmp);
+ return 1; /* be safe and say yes */
+ }
+ }
+ /* XXXX End code copied from tor_version_as_new_as (in routerparse.c) */
+
+ if (!parsed_versions_initialized) {
+ /* CVE-2011-2769 was fixed on the relay side in Tor versions
+ * 0.2.1.31, 0.2.2.34, and 0.2.3.6-alpha. */
+ tor_assert(tor_version_parse("0.2.1.31",
+ &first_good_0_2_1_guard_version)>=0);
+ tor_assert(tor_version_parse("0.2.2.34",
+ &first_good_0_2_2_guard_version)>=0);
+ tor_assert(tor_version_parse("0.2.3.6-alpha",
+ &first_good_later_guard_version)>=0);
+
+ /* Don't parse these constant version strings once for every relay
+ * for every vote. */
+ parsed_versions_initialized = 1;
+ }
+
+ return ((tor_version_same_series(&first_good_0_2_1_guard_version,
+ &router_version) &&
+ tor_version_compare(&first_good_0_2_1_guard_version,
+ &router_version) <= 0) ||
+ (tor_version_same_series(&first_good_0_2_2_guard_version,
+ &router_version) &&
+ tor_version_compare(&first_good_0_2_2_guard_version,
+ &router_version) <= 0) ||
+ (tor_version_compare(&first_good_later_guard_version,
+ &router_version) <= 0));
+}
+
/** Extract status information from <b>ri</b> and from other authority
* functions and store it in <b>rs</b>>. If <b>naming</b>, consider setting
* the named flag in <b>rs</b>.
@@ -2303,8 +2370,11 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
int naming, int listbadexits,
int listbaddirs, int vote_on_hsdirs)
{
+ const or_options_t *options = get_options();
int unstable_version =
!tor_version_as_new_as(ri->platform,"0.1.1.16-rc-cvs");
+ uint32_t routerbw = router_get_advertised_bandwidth(ri);
+
memset(rs, 0, sizeof(routerstatus_t));
rs->is_authority =
@@ -2330,12 +2400,16 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
rs->is_valid = node->is_valid;
if (node->is_fast &&
- (router_get_advertised_bandwidth(ri) >= BANDWIDTH_TO_GUARANTEE_GUARD ||
- router_get_advertised_bandwidth(ri) >=
- MIN(guard_bandwidth_including_exits,
- guard_bandwidth_excluding_exits))) {
- long tk = rep_hist_get_weighted_time_known(node->identity, now);
- double wfu = rep_hist_get_weighted_fractional_uptime(node->identity, now);
+ ((options->AuthDirGuardBWGuarantee &&
+ routerbw >= options->AuthDirGuardBWGuarantee) ||
+ routerbw >= MIN(guard_bandwidth_including_exits,
+ guard_bandwidth_excluding_exits)) &&
+ (options->GiveGuardFlagTo_CVE_2011_2768_VulnerableRelays ||
+ is_router_version_good_for_possible_guard(ri->platform))) {
+ long tk = rep_hist_get_weighted_time_known(
+ node->identity, now);
+ double wfu = rep_hist_get_weighted_fractional_uptime(
+ node->identity, now);
rs->is_possible_guard = (wfu >= guard_wfu && tk >= guard_tk) ? 1 : 0;
} else {
rs->is_possible_guard = 0;
@@ -2814,7 +2888,7 @@ generate_v2_networkstatus_opinion(void)
goto done;
}
- contact = get_options()->ContactInfo;
+ contact = options->ContactInfo;
if (!contact)
contact = "(none)";
@@ -2897,7 +2971,7 @@ generate_v2_networkstatus_opinion(void)
});
if (tor_snprintf(outp, endp-outp, "directory-signature %s\n",
- get_options()->Nickname)<0) {
+ options->Nickname)<0) {
log_warn(LD_BUG, "Unable to write signature line.");
goto done;
}
@@ -3207,7 +3281,7 @@ dirserv_orconn_tls_done(const char *address,
log_info(LD_DIRSERV, "Found router %s to be reachable at %s:%d. Yay.",
router_describe(ri),
address, ri->or_port);
- if (tor_addr_from_str(&addr, ri->address) != -1)
+ if (tor_addr_parse(&addr, ri->address) != -1)
addrp = &addr;
else
log_warn(LD_BUG, "Couldn't parse IP address \"%s\"", ri->address);
@@ -3482,15 +3556,14 @@ connection_dirserv_finish_spooling(dir_connection_t *conn)
static int
connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
{
-#ifdef TRACK_SERVED_TIME
- time_t now = time(NULL);
-#endif
int by_fp = (conn->dir_spool_src == DIR_SPOOL_SERVER_BY_FP ||
conn->dir_spool_src == DIR_SPOOL_EXTRA_BY_FP);
int extra = (conn->dir_spool_src == DIR_SPOOL_EXTRA_BY_FP ||
conn->dir_spool_src == DIR_SPOOL_EXTRA_BY_DIGEST);
time_t publish_cutoff = time(NULL)-ROUTER_MAX_AGE_TO_PUBLISH;
+ const or_options_t *options = get_options();
+
while (smartlist_len(conn->fingerprint_stack) &&
connection_get_outbuf_len(TO_CONN(conn)) < DIRSERV_BUFFER_MIN) {
const char *body;
@@ -3512,9 +3585,17 @@ connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
* unknown bridge descriptor has shown up between then and now. */
continue;
}
-#ifdef TRACK_SERVED_TIME
- sd->last_served_at = now;
-#endif
+
+ /** If we are the bridge authority and the descriptor is a bridge
+ * descriptor, remember that we served this descriptor for desc stats. */
+ if (options->BridgeAuthoritativeDir && by_fp) {
+ const routerinfo_t *router =
+ router_get_by_id_digest(sd->identity_digest);
+ /* router can be NULL here when the bridge auth is asked for its own
+ * descriptor. */
+ if (router && router->purpose == ROUTER_PURPOSE_BRIDGE)
+ rep_hist_note_desc_served(sd->identity_digest);
+ }
body = signed_descriptor_get_body(sd);
if (conn->zlib_state) {
/* XXXX022 This 'last' business should actually happen on the last