|
@@ -66,6 +66,9 @@ static cached_dir_t *the_directory = NULL;
|
|
|
|
|
|
static cached_dir_t the_runningrouters;
|
|
|
|
|
|
+
|
|
|
+static int routers_with_measured_bw = 0;
|
|
|
+
|
|
|
static void directory_remove_invalid(void);
|
|
|
static cached_dir_t *dirserv_regenerate_directory(void);
|
|
|
static char *format_versions_list(config_line_t *ln);
|
|
@@ -86,6 +89,7 @@ static const signed_descriptor_t *get_signed_descriptor_by_fp(
|
|
|
static was_router_added_t dirserv_add_extrainfo(extrainfo_t *ei,
|
|
|
const char **msg);
|
|
|
static uint32_t dirserv_get_bandwidth_for_router(const routerinfo_t *ri);
|
|
|
+static uint32_t dirserv_get_credible_bandwidth(const routerinfo_t *ri);
|
|
|
|
|
|
|
|
|
|
|
@@ -1877,12 +1881,18 @@ dirserv_thinks_router_is_hs_dir(const routerinfo_t *router,
|
|
|
* include a router in our calculations, and return true iff we should. */
|
|
|
static int
|
|
|
router_counts_toward_thresholds(const node_t *node, time_t now,
|
|
|
- const digestmap_t *omit_as_sybil)
|
|
|
+ const digestmap_t *omit_as_sybil,
|
|
|
+ int require_mbw)
|
|
|
{
|
|
|
+
|
|
|
+ int have_mbw =
|
|
|
+ dirserv_query_measured_bw_cache(node->ri->cache_info.identity_digest,
|
|
|
+ NULL, NULL);
|
|
|
+
|
|
|
return node->ri && router_is_active(node->ri, node, now) &&
|
|
|
!digestmap_get(omit_as_sybil, node->ri->cache_info.identity_digest) &&
|
|
|
- (dirserv_get_bandwidth_for_router(node->ri) >=
|
|
|
- ABSOLUTE_MIN_BW_VALUE_TO_CONSIDER);
|
|
|
+ (dirserv_get_credible_bandwidth(node->ri) >=
|
|
|
+ ABSOLUTE_MIN_BW_VALUE_TO_CONSIDER) && (have_mbw || !require_mbw);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1904,6 +1914,11 @@ dirserv_compute_performance_thresholds(routerlist_t *rl,
|
|
|
time_t now = time(NULL);
|
|
|
const or_options_t *options = get_options();
|
|
|
|
|
|
+
|
|
|
+ int require_mbw =
|
|
|
+ (routers_with_measured_bw >
|
|
|
+ options->MinMeasuredBWsForAuthToIgnoreAdvertised) ? 1 : 0;
|
|
|
+
|
|
|
|
|
|
stable_uptime = 0;
|
|
|
stable_mtbf = 0;
|
|
@@ -1936,7 +1951,8 @@ dirserv_compute_performance_thresholds(routerlist_t *rl,
|
|
|
|
|
|
|
|
|
SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), node_t *, node) {
|
|
|
- if (router_counts_toward_thresholds(node, now, omit_as_sybil)) {
|
|
|
+ if (router_counts_toward_thresholds(node, now, omit_as_sybil,
|
|
|
+ require_mbw)) {
|
|
|
routerinfo_t *ri = node->ri;
|
|
|
const char *id = ri->cache_info.identity_digest;
|
|
|
uint32_t bw;
|
|
@@ -1945,7 +1961,7 @@ dirserv_compute_performance_thresholds(routerlist_t *rl,
|
|
|
uptimes[n_active] = (uint32_t)real_uptime(ri, now);
|
|
|
mtbfs[n_active] = rep_hist_get_stability(id, now);
|
|
|
tks [n_active] = rep_hist_get_weighted_time_known(id, now);
|
|
|
- bandwidths[n_active] = bw = dirserv_get_bandwidth_for_router(ri);
|
|
|
+ bandwidths[n_active] = bw = dirserv_get_credible_bandwidth(ri);
|
|
|
total_bandwidth += bw;
|
|
|
if (node->is_exit && !node->is_bad_exit) {
|
|
|
total_exit_bandwidth += bw;
|
|
@@ -2001,7 +2017,8 @@ dirserv_compute_performance_thresholds(routerlist_t *rl,
|
|
|
n_familiar = 0;
|
|
|
|
|
|
SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), node_t *, node) {
|
|
|
- if (router_counts_toward_thresholds(node, now, omit_as_sybil)) {
|
|
|
+ if (router_counts_toward_thresholds(node, now,
|
|
|
+ omit_as_sybil, require_mbw)) {
|
|
|
routerinfo_t *ri = node->ri;
|
|
|
const char *id = ri->cache_info.identity_digest;
|
|
|
long tk = rep_hist_get_weighted_time_known(id, now);
|
|
@@ -2182,6 +2199,59 @@ dirserv_get_bandwidth_for_router(const routerinfo_t *ri)
|
|
|
return bw;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ * how many measured bandwidths we know. This is used to decide whether we
|
|
|
+ * ever trust advertised bandwidths for purposes of assigning flags. */
|
|
|
+static void
|
|
|
+dirserv_count_measured_bws(routerlist_t *rl)
|
|
|
+{
|
|
|
+
|
|
|
+ routers_with_measured_bw = 0;
|
|
|
+
|
|
|
+ tor_assert(rl);
|
|
|
+ tor_assert(rl->routers);
|
|
|
+
|
|
|
+
|
|
|
+ SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, ri) {
|
|
|
+
|
|
|
+ if (dirserv_query_measured_bw_cache(ri->cache_info.identity_digest,
|
|
|
+ NULL, NULL)) {
|
|
|
+ ++routers_with_measured_bw;
|
|
|
+ }
|
|
|
+ } SMARTLIST_FOREACH_END(ri);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ * over advertised, and if we have above a threshold quantity of measured
|
|
|
+ * bandwidths, we don't want to ever give flags to unmeasured routers, so
|
|
|
+ * return 0. */
|
|
|
+static uint32_t
|
|
|
+dirserv_get_credible_bandwidth(const routerinfo_t *ri)
|
|
|
+{
|
|
|
+ int threshold;
|
|
|
+ uint32_t bw = 0;
|
|
|
+ long mbw;
|
|
|
+
|
|
|
+ tor_assert(ri);
|
|
|
+
|
|
|
+ if (!(dirserv_query_measured_bw_cache(ri->cache_info.identity_digest,
|
|
|
+ &mbw, NULL))) {
|
|
|
+ threshold = get_options()->MinMeasuredBWsForAuthToIgnoreAdvertised;
|
|
|
+ if (routers_with_measured_bw > threshold) {
|
|
|
+
|
|
|
+ bw = 0;
|
|
|
+ } else {
|
|
|
+
|
|
|
+ bw = router_get_advertised_bandwidth(ri);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+
|
|
|
+ bw = (uint32_t)mbw;
|
|
|
+ }
|
|
|
+
|
|
|
+ return bw;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
* in a vote document. */
|
|
|
char *
|
|
@@ -2604,7 +2674,7 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
|
|
|
int listbaddirs, int vote_on_hsdirs)
|
|
|
{
|
|
|
const or_options_t *options = get_options();
|
|
|
- uint32_t routerbw = dirserv_get_bandwidth_for_router(ri);
|
|
|
+ uint32_t routerbw = dirserv_get_credible_bandwidth(ri);
|
|
|
|
|
|
memset(rs, 0, sizeof(routerstatus_t));
|
|
|
|
|
@@ -2927,6 +2997,14 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
|
|
|
*/
|
|
|
if (options->V3BandwidthsFile) {
|
|
|
dirserv_read_measured_bandwidths(options->V3BandwidthsFile, NULL);
|
|
|
+ } else {
|
|
|
+
|
|
|
+ * No bandwidths file; clear the measured bandwidth cache in case we had
|
|
|
+ * one last time around.
|
|
|
+ */
|
|
|
+ if (dirserv_get_measured_bw_cache_size() > 0) {
|
|
|
+ dirserv_clear_measured_bw_cache();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -2945,6 +3023,10 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
|
|
|
rep_hist_make_router_pessimal(sybil_id, now);
|
|
|
} DIGESTMAP_FOREACH_END;
|
|
|
|
|
|
+
|
|
|
+ * this must come before dirserv_compute_performance_thresholds() */
|
|
|
+ dirserv_count_measured_bws(rl);
|
|
|
+
|
|
|
dirserv_compute_performance_thresholds(rl, omit_as_sybil);
|
|
|
|
|
|
routerstatuses = smartlist_new();
|
|
@@ -2989,6 +3071,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
|
|
|
smartlist_free(routers);
|
|
|
digestmap_free(omit_as_sybil, NULL);
|
|
|
|
|
|
+
|
|
|
if (options->V3BandwidthsFile) {
|
|
|
dirserv_read_measured_bandwidths(options->V3BandwidthsFile,
|
|
|
routerstatuses);
|