summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-11-08 18:15:49 +0000
committerNick Mathewson <nickm@torproject.org>2007-11-08 18:15:49 +0000
commit1bdbd3b98e79cadeac3d4fecc6b24463df89ed14 (patch)
treee5c3a5c01bb1fdfab53c5d25df5001dd277ff82a
parente0b9c893bc4e60cb3e6d8aa65d49a2a4ba2b6260 (diff)
downloadtor-1bdbd3b98e79cadeac3d4fecc6b24463df89ed14.tar.gz
tor-1bdbd3b98e79cadeac3d4fecc6b24463df89ed14.zip
r16582@catbus: nickm | 2007-11-08 13:14:16 -0500
Try to bulletproof the parse logic for router-stability. svn:r12441
-rw-r--r--ChangeLog3
-rw-r--r--src/or/dirserv.c16
-rw-r--r--src/or/main.c2
-rw-r--r--src/or/rephist.c63
4 files changed, 66 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 68c1540f96..cb20327328 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -42,6 +42,9 @@ Changes in version 0.2.0.10-alpha - 2007-11-07
requests for all of them.
- Correctly back off from failing certificate downloads. Fixes bug
546.
+ - Authorities don't vote on the Running flag if they have been running
+ for less than 30 minutes themselves. Fixes bug 547, where a newly
+ started authority would vote that everyone was down.
o New requirements:
- Drop support for OpenSSL version 0.9.6. Just about nobody was using
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index b0793cc118..36f661a4ca 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -27,6 +27,8 @@ const char dirserv_c_id[] =
/** If a v1 running-routers is older than this, discard it. */
#define MAX_V1_RR_AGE (7*24*60*60)
+extern time_t time_of_process_start; /* from main.c */
+
/** Do we need to regenerate the directory when someone asks for it? */
static int the_directory_is_dirty = 1;
static int runningrouters_is_dirty = 1;
@@ -1926,6 +1928,10 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
rs->dir_port = ri->dir_port;
}
+/** If we've been around for less than this amount of time, our reachability
+ * information is not accurate. */
+#define DIRSERV_TIME_TO_GET_REACHABILITY_INFO (30*60)
+
/** Return a new networkstatus_vote_t* containing our current opinion. (For v3
* authorities */
networkstatus_vote_t *
@@ -1949,10 +1955,14 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
networkstatus_voter_info_t *voter = NULL;
vote_timing_t timing;
digestmap_t *omit_as_sybil = NULL;
+ int vote_on_reachability = 1;
tor_assert(private_key);
tor_assert(cert);
+ if (now - time_of_process_start < DIRSERV_TIME_TO_GET_REACHABILITY_INFO)
+ vote_on_reachability = 0;
+
if (resolve_my_address(LOG_WARN, options, &addr, &hostname)<0) {
log_warn(LD_NET, "Couldn't resolve my hostname");
return NULL;
@@ -2014,6 +2024,8 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
rs->is_running = rs->is_named = rs->is_valid = rs->is_v2_dir =
rs->is_possible_guard = 0;
}
+ if (!vote_on_reachability)
+ rs->is_running = 0;
vrs->version = version_from_platform(ri->platform);
smartlist_add(routerstatuses, vrs);
@@ -2057,8 +2069,10 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
v3_out->server_versions = server_versions;
v3_out->known_flags = smartlist_create();
smartlist_split_string(v3_out->known_flags,
- "Authority Exit Fast Guard HSDir Running Stable V2Dir Valid",
+ "Authority Exit Fast Guard HSDir Stable V2Dir Valid",
0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ if (vote_on_reachability)
+ smartlist_add(v3_out->known_flags, tor_strdup("Running"));
if (listbadexits)
smartlist_add(v3_out->known_flags, tor_strdup("BadExit"));
if (naming) {
diff --git a/src/or/main.c b/src/or/main.c
index 0f628fa226..775c5f656f 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -53,7 +53,7 @@ static int stats_prev_global_write_bucket;
static uint64_t stats_n_bytes_read = 0;
static uint64_t stats_n_bytes_written = 0;
/** What time did this process start up? */
-long time_of_process_start = 0;
+time_t time_of_process_start = 0;
/** How many seconds have we been running? */
long stats_n_seconds_working = 0;
/** When do we next download a directory? */
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 30c54fa473..bd4d837fbc 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -684,7 +684,7 @@ rep_hist_record_mtbf_data(void)
base16_encode(dbuf, sizeof(dbuf), digest, DIGEST_LEN);
PRINTF((f, "R %s\n", dbuf));
- if (hist->start_of_run) {
+ if (hist->start_of_run > 0) {
format_iso_time(time_buf, hist->start_of_run);
t = time_buf;
}
@@ -692,7 +692,7 @@ rep_hist_record_mtbf_data(void)
hist->weighted_run_length, hist->total_run_weights,
t ? " S=" : "", t ? t : ""));
t = NULL;
- if (hist->start_of_downtime) {
+ if (hist->start_of_downtime > 0) {
format_iso_time(time_buf, hist->start_of_downtime);
t = time_buf;
}
@@ -728,6 +728,43 @@ find_next_with(smartlist_t *sl, int i, const char *prefix)
return -1;
}
+static int n_bogus_times = 0;
+/** DOCDOC */
+static int
+parse_possibly_bad_iso_time(const char *s, time_t *time_out)
+{
+ int year;
+ char b[5];
+ strlcpy(b, s, sizeof(b));
+ b[4] = '\0';
+ year = atoi(b);
+ if (year < 1970) {
+ *time_out = 0;
+ ++n_bogus_times;
+ return 0;
+ } else
+ return parse_iso_time(s, time_out);
+}
+
+/** DOCDOC */
+static INLINE time_t
+correct_time(time_t t, time_t now, time_t stored_at, time_t started_measuring)
+{
+ if (t < started_measuring - 24*60*60*365)
+ return 0;
+ else if (t < started_measuring)
+ return started_measuring;
+ else if (t > stored_at)
+ return 0;
+ else {
+ long run_length = stored_at - t;
+ t = now - run_length;
+ if (t < started_measuring)
+ t = started_measuring;
+ return t;
+ }
+}
+
/** Load MTBF data from disk. Returns 0 on success or recoverable error, -1
* on failure. */
int
@@ -799,6 +836,8 @@ rep_hist_load_mtbf_data(time_t now)
if (line && !strcmp(line, "data"))
++i;
+ n_bogus_times = 0;
+
for (; i < smartlist_len(lines); ++i) {
char digest[DIGEST_LEN];
char hexbuf[HEX_DIGEST_LEN+1];
@@ -874,16 +913,12 @@ rep_hist_load_mtbf_data(time_t now)
if (have_mtbf) {
if (mtbf_timebuf[0]) {
mtbf_timebuf[10] = ' ';
- if (parse_iso_time(mtbf_timebuf, &start_of_run)<0)
+ if (parse_possibly_bad_iso_time(mtbf_timebuf, &start_of_run)<0)
log_warn(LD_GENERAL, "Couldn't parse time %s",
escaped(mtbf_timebuf));
}
- if (!start_of_run || start_of_run > stored_at) {
- hist->start_of_run = 0;
- } else {
- long run_length = stored_at - start_of_run;
- hist->start_of_run = now - run_length;
- }
+ hist->start_of_run = correct_time(start_of_run, now, stored_at,
+ tracked_since);
if (hist->start_of_run < latest_possible_start + wrl)
latest_possible_start = hist->start_of_run - wrl;
@@ -893,16 +928,12 @@ rep_hist_load_mtbf_data(time_t now)
if (have_wfu) {
if (wfu_timebuf[0]) {
wfu_timebuf[10] = ' ';
- if (parse_iso_time(wfu_timebuf, &start_of_downtime)<0)
+ if (parse_possibly_bad_iso_time(wfu_timebuf, &start_of_downtime)<0)
log_warn(LD_GENERAL, "Couldn't parse time %s", escaped(wfu_timebuf));
}
}
- if (!start_of_downtime || start_of_downtime > stored_at) {
- hist->start_of_downtime = 0;
- } else {
- long down_length = stored_at - start_of_downtime;
- hist->start_of_downtime = start_of_downtime - down_length;
- }
+ hist->start_of_downtime = correct_time(start_of_downtime, now, stored_at,
+ tracked_since);
hist->weighted_uptime = wt_uptime;
hist->total_weighted_time = total_wt_time;
}