summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-03-11 23:30:25 -0500
committerNick Mathewson <nickm@torproject.org>2011-03-11 23:30:25 -0500
commitd34a5cdc597824e72453009ed209e5644f158e90 (patch)
tree30a08d2b6afa8bf267cc8ae1668343959a41b777
parent600ad7bf8d499d04259586bcf91afed7dfb88f99 (diff)
parent3a0c6021556abc96f4c610d5e097e3890216595f (diff)
downloadtor-d34a5cdc597824e72453009ed209e5644f158e90.tar.gz
tor-d34a5cdc597824e72453009ed209e5644f158e90.zip
Merge branch 'hsdir_assignment' into maint-0.2.2
-rw-r--r--changes/hsdir_assignment8
-rw-r--r--src/or/dirserv.c19
-rw-r--r--src/or/rephist.c14
-rw-r--r--src/or/rephist.h1
4 files changed, 41 insertions, 1 deletions
diff --git a/changes/hsdir_assignment b/changes/hsdir_assignment
new file mode 100644
index 0000000000..5c04b9b9bb
--- /dev/null
+++ b/changes/hsdir_assignment
@@ -0,0 +1,8 @@
+ o Security fixes:
+ - Directory authorities now use data collected from rephist when
+ choosing whether to assign the HSDir flag to relays, instead of
+ trusting the uptime value the relay reports in its descriptor.
+ This helps prevent an attack where a small set of nodes with
+ frequently-changing identity keys can blackhole a hidden service.
+ (Only authorities need upgrade; others will be fine once they do.)
+ Bugfix on 0.2.0.10-alpha; fixes bug 2709.
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index aeeab45383..40136a18e3 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -43,6 +43,8 @@
extern time_t time_of_process_start; /* from main.c */
+extern long stats_n_seconds_working; /* from main.c */
+
/** Do we need to regenerate the v1 directory when someone asks for it? */
static time_t the_directory_is_dirty = 1;
/** Do we need to regenerate the v1 runningrouters document when somebody
@@ -1775,7 +1777,22 @@ dirserv_thinks_router_is_unreliable(time_t now,
static int
dirserv_thinks_router_is_hs_dir(routerinfo_t *router, time_t now)
{
- long uptime = real_uptime(router, now);
+
+ long uptime;
+
+ /* If we haven't been running for at least
+ * get_options()->MinUptimeHidServDirectoryV2 seconds, we can't
+ * have accurate data telling us a relay has been up for at least
+ * that long. We also want to allow a bit of slack: Reachability
+ * tests aren't instant. If we haven't been running long enough,
+ * trust the relay. */
+
+ if (stats_n_seconds_working >
+ get_options()->MinUptimeHidServDirectoryV2 * 1.1)
+ uptime = MIN(rep_hist_get_uptime(router->cache_info.identity_digest, now),
+ real_uptime(router, now));
+ else
+ uptime = real_uptime(router, now);
/* XXX We shouldn't need to check dir_port, but we do because of
* bug 1693. In the future, once relays set wants_to_be_hs_dir
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 53214d61ef..e4afe62b67 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -528,6 +528,20 @@ get_weighted_fractional_uptime(or_history_t *hist, time_t when)
return ((double) up) / total;
}
+/** Return how long the router whose identity digest is <b>id</b> has
+ * been reachable. Return 0 if the router is unknown or currently deemed
+ * unreachable. */
+long
+rep_hist_get_uptime(const char *id, time_t when)
+{
+ or_history_t *hist = get_or_history(id);
+ if (!hist)
+ return 0;
+ if (!hist->start_of_run || when < hist->start_of_run)
+ return 0;
+ return when - hist->start_of_run;
+}
+
/** Return an estimated MTBF for the router whose identity digest is
* <b>id</b>. Return 0 if the router is unknown. */
double
diff --git a/src/or/rephist.h b/src/or/rephist.h
index 5f6b9f9b45..b06a39ed59 100644
--- a/src/or/rephist.h
+++ b/src/or/rephist.h
@@ -40,6 +40,7 @@ int rep_hist_record_mtbf_data(time_t now, int missing_means_down);
int rep_hist_load_mtbf_data(time_t now);
time_t rep_hist_downrate_old_runs(time_t now);
+long rep_hist_get_uptime(const char *id, time_t when);
double rep_hist_get_stability(const char *id, time_t when);
double rep_hist_get_weighted_fractional_uptime(const char *id, time_t when);
long rep_hist_get_weighted_time_known(const char *id, time_t when);