"Running" -- A router is 'Running' if the authority managed to connect to
it successfully within the last 30 minutes.
- "Stable" -- A router is 'Stable' if it is active, and either its
- Weighted MTBF is at least the median for known active routers or
- its Weighted MTBF is at least 10 days. Routers are never called Stable if
- they are running a version of Tor known to drop circuits stupidly.
- (0.1.1.10-alpha through 0.1.1.16-rc are stupid this way.)
+ "Stable" -- A router is 'Stable' if it is active, and either its Weighted
+ MTBF is at least the median for known active routers or its Weighted MTBF
+ corresponds to at least 7 days. Routers are never called Stable if they are
+ running a version of Tor known to drop circuits stupidly. (0.1.1.10-alpha
+ through 0.1.1.16-rc are stupid this way.)
To calculate weighted MTBF, compute the weighted mean of the lengths
of all intervals when the router was observed to be up, weighting
either in the top 7/8ths for known active routers or at least 100KB/s.
"Guard" -- A router is a possible 'Guard' if its Weighted Fractional
- Uptime is at least the median for known active routers, and its bandwidth
- is either at least the median for known active routers or at least
- 250KB/s. If the total bandwidth of active non-BadExit Exit servers is less
+ Uptime is at least the median for "familiar" active routers, and if
+ its bandwidth is at least median or at least 250KB/s.
+ If the total bandwidth of active non-BadExit Exit servers is less
than one third of the total bandwidth of all active servers, no Exit is
listed as a Guard.
of time that the router is up in any given day, weighting so that
downtime and uptime in the past counts less.
+ A node is 'familiar' if 1/8 of all active nodes have appeared more
+ recently than it, OR it has been around for a few weeks.
+
"Authority" -- A router is called an 'Authority' if the authority
generating the network-status document believes it is an authority.
* current guards. */
#define UPTIME_TO_GUARANTEE_STABLE (3600*24*30)
/** If a router's MTBF is at least this value, then it is always stable.
- * See above. */
-#define MTBF_TO_GUARANTEE_STABLE (60*60*24*10)
+ * 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 (100*1024)
/** 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.
+ */
+#define TIME_KNOWN_TO_GUARANTEE_FAMILIAR (8*24*60*60)
+/** Similarly, every node with sufficient WFU is around enough to be a guard.
+ */
+#define WFU_TO_GUARANTEE_GUARD (0.995)
/* Thresholds for server performance: set by
* dirserv_compute_performance_thresholds, and used by
static double stable_mtbf = 0.0;
static int enough_mtbf_info = 0;
static double guard_wfu = 0.0;
+static long guard_tk = 0;
static uint32_t fast_bandwidth = 0;
static uint32_t guard_bandwidth_including_exits = 0;
static uint32_t guard_bandwidth_excluding_exits = 0;
} else {
double mtbf =
rep_hist_get_stability(router->cache_info.identity_digest, now);
- if (mtbf < stable_mtbf && mtbf < MTBF_TO_GUARANTEE_STABLE)
+ if (mtbf < stable_mtbf)
return 1;
}
}
if (need_capacity) {
uint32_t bw = router_get_advertised_bandwidth(router);
- if (bw < fast_bandwidth && bw < BANDWIDTH_TO_GUARANTEE_FAST)
+ if (bw < fast_bandwidth)
return 1;
}
return 0;
static void
dirserv_compute_performance_thresholds(routerlist_t *rl)
{
- int n_active, n_active_nonexit;
+ int n_active, n_active_nonexit, n_familiar;
uint32_t *uptimes, *bandwidths, *bandwidths_excluding_exits;
+ long *tks;
double *mtbfs, *wfus;
time_t now = time(NULL);
+ /* DOCDOC this is a litle tricky; comment this function better. */
+
/* initialize these all here, in case there are no routers */
stable_uptime = 0;
+ stable_mtbf = 0;
fast_bandwidth = 0;
guard_bandwidth_including_exits = 0;
guard_bandwidth_excluding_exits = 0;
+ guard_tk = 0;
+ guard_wfu = 0;
total_bandwidth = 0;
total_exit_bandwidth = 0;
bandwidths_excluding_exits =
tor_malloc(sizeof(uint32_t)*smartlist_len(rl->routers));
mtbfs = tor_malloc(sizeof(double)*smartlist_len(rl->routers));
+ tks = tor_malloc(sizeof(long)*smartlist_len(rl->routers));
wfus = tor_malloc(sizeof(double)*smartlist_len(rl->routers));
SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
ri->is_exit = exit_policy_is_general_exit(ri->exit_policy);
uptimes[n_active] = real_uptime(ri, now);
mtbfs[n_active] = rep_hist_get_stability(id, now);
- wfus [n_active] = rep_hist_get_weighted_fractional_uptime(id, now);
+ tks [n_active] = rep_hist_get_weighted_time_known(id, now);
bandwidths[n_active] = bw = router_get_advertised_bandwidth(ri);
total_bandwidth += bw;
if (ri->is_exit && !ri->is_bad_exit) {
if (n_active) {
stable_uptime = median_uint32(uptimes, n_active);
stable_mtbf = median_double(mtbfs, n_active);
- guard_wfu = median_double(wfus, n_active);
fast_bandwidth = find_nth_uint32(bandwidths, n_active, n_active/8);
/* Now bandwidths is sorted. */
if (fast_bandwidth < ROUTER_REQUIRED_MIN_BANDWIDTH)
fast_bandwidth = bandwidths[n_active/4];
guard_bandwidth_including_exits = bandwidths[(n_active-1)/2];
+ guard_tk = find_nth_long(tks, n_active, n_active/8);
}
+ 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;
+
+ n_familiar = 0;
+ SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
+ if (router_is_active(ri, now)) {
+ const char *id = ri->cache_info.identity_digest;
+ long tk = rep_hist_get_weighted_time_known(id, now);
+ if (tk < guard_tk)
+ continue;
+ wfus[n_familiar++] = rep_hist_get_weighted_fractional_uptime(id, now);
+ }
+ });
+ if (n_familiar)
+ guard_wfu = median_double(wfus, n_familiar);
+ if (guard_wfu > WFU_TO_GUARANTEE_GUARD)
+ guard_wfu = WFU_TO_GUARANTEE_GUARD;
+
enough_mtbf_info = rep_hist_have_measured_enough_stability();
if (n_active_nonexit) {
median_uint32(bandwidths_excluding_exits, n_active_nonexit);
}
- /*XXXX020 Log the other stuff too. */
log(LOG_INFO, LD_DIRSERV,
- "Cutoffs: %lus uptime, %lu b/s fast, %lu or %lu b/s guard.",
+ "Cutoffs: For Stable, %lu sec uptime, %lu sec MTBF. "
+ "For Fast: %lu bytes/sec."
+ "For Guard: WFU %.03lf%%, time-known %lu sec, "
+ "and bandwidth %lu or %lu bytes/sec.",
(unsigned long)stable_uptime,
+ (unsigned long)stable_mtbf,
(unsigned long)fast_bandwidth,
+ guard_wfu*100,
+ (unsigned long)guard_tk,
(unsigned long)guard_bandwidth_including_exits,
(unsigned long)guard_bandwidth_excluding_exits);
tor_free(uptimes);
tor_free(mtbfs);
- tor_free(wfus);
tor_free(bandwidths);
tor_free(bandwidths_excluding_exits);
+ tor_free(tks);
+ tor_free(wfus);
}
/** Given a platform string as in a routerinfo_t (possibly null), return a
router_get_advertised_bandwidth(ri) >=
(exits_can_be_guards ? guard_bandwidth_including_exits :
guard_bandwidth_excluding_exits))) {
+ long tk = rep_hist_get_weighted_time_known(
+ ri->cache_info.identity_digest, now);
double wfu = rep_hist_get_weighted_fractional_uptime(
ri->cache_info.identity_digest, now);
- rs->is_possible_guard = (wfu >= guard_wfu) ? 1 : 0;
+ rs->is_possible_guard = (wfu >= guard_wfu && tk >= guard_tk) ? 1 : 0;
} else {
rs->is_possible_guard = 0;
}
return total / total_weights;
}
-/* Until we've known about you for this long, you simply can't be up. */
-#define MIN_WEIGHTED_TIME_TO_BE_UP (18*60*60)
+/** DODDOC */
+static long
+get_total_weighted_time(or_history_t *hist, time_t when)
+{
+ long total = hist->total_weighted_time;
+ if (hist->start_of_run) {
+ total += (when - hist->start_of_run);
+ } else if (hist->start_of_downtime) {
+ total += (when - hist->start_of_downtime);
+ }
+ return total;
+}
/** Helper: Return the weighted percent-of-time-online of the router with
* history <b>hist</b>. */
} else if (hist->start_of_downtime) {
total += (when - hist->start_of_downtime);
}
- if (total < MIN_WEIGHTED_TIME_TO_BE_UP)
- return 0.0;
return ((double) up) / total;
}
return get_weighted_fractional_uptime(hist, when);
}
+/** Return a number representing how long we've known about the router whose
+ * digest is <b>id</b>. Return 0 if the router is unknown.
+ *
+ * Be careful: this measure incresases monotonically as we know the router for
+ * longer and longer, but it doesn't increase linearly.
+ */
+long
+rep_hist_get_weighted_time_known(const char *id, time_t when)
+{
+ or_history_t *hist = get_or_history(id);
+ if (!hist)
+ return 0;
+
+ return get_total_weighted_time(hist, when);
+}
+
/** Return true if we've been measuring MTBFs for long enough to
* prounounce on Stability. */
int