mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 23:53:32 +01:00
Add parsing+verification for bw weight values.
This commit is contained in:
parent
f9d40649fe
commit
df1ef2f0f0
@ -1784,8 +1784,10 @@ networkstatus_compute_consensus(smartlist_t *votes,
|
|||||||
tor_free(result);
|
tor_free(result);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// XXX: Verify balancing parameters here
|
// Verify balancing parameters
|
||||||
// networkstatus_verify_bw_weights(c);
|
if (consensus_method >= 9) {
|
||||||
|
networkstatus_verify_bw_weights(c);
|
||||||
|
}
|
||||||
networkstatus_vote_free(c);
|
networkstatus_vote_free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2074,6 +2074,23 @@ networkstatus_get_param(networkstatus_t *ns, const char *param_name,
|
|||||||
return get_net_param_from_list(ns->net_params, param_name, default_val);
|
return get_net_param_from_list(ns->net_params, param_name, default_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return the value of a integer bw weight parameter from the networkstatus
|
||||||
|
* <b>ns</b> whose name is <b>weight_name</b>. If <b>ns</b> is NULL, try
|
||||||
|
* loading the latest consensus ourselves. Return <b>default_val</b> if no
|
||||||
|
* latest consensus, or if it has no parameter called <b>param_name</b>. */
|
||||||
|
int32_t
|
||||||
|
networkstatus_get_bw_weight(networkstatus_t *ns, const char *weight_name,
|
||||||
|
int32_t default_val)
|
||||||
|
{
|
||||||
|
if (!ns) /* if they pass in null, go find it ourselves */
|
||||||
|
ns = networkstatus_get_latest_consensus();
|
||||||
|
|
||||||
|
if (!ns || !ns->weight_params)
|
||||||
|
return default_val;
|
||||||
|
|
||||||
|
return get_net_param_from_list(ns->weight_params, weight_name, default_val);
|
||||||
|
}
|
||||||
|
|
||||||
/** Return the name of the consensus flavor <b>flav</b> as used to identify
|
/** Return the name of the consensus flavor <b>flav</b> as used to identify
|
||||||
* the flavor in directory documents. */
|
* the flavor in directory documents. */
|
||||||
const char *
|
const char *
|
||||||
|
@ -1771,6 +1771,10 @@ typedef struct networkstatus_t {
|
|||||||
* consensus, sorted by key. */
|
* consensus, sorted by key. */
|
||||||
smartlist_t *net_params;
|
smartlist_t *net_params;
|
||||||
|
|
||||||
|
/** List of key=value strings for the bw weight parameters in the
|
||||||
|
* consensus. */
|
||||||
|
smartlist_t *weight_params;
|
||||||
|
|
||||||
/** List of networkstatus_voter_info_t. For a vote, only one element
|
/** List of networkstatus_voter_info_t. For a vote, only one element
|
||||||
* is included. For a consensus, one element is included for every voter
|
* is included. For a consensus, one element is included for every voter
|
||||||
* whose vote contributed to the consensus. */
|
* whose vote contributed to the consensus. */
|
||||||
@ -4354,6 +4358,8 @@ int32_t networkstatus_get_param(networkstatus_t *ns, const char *param_name,
|
|||||||
int32_t default_val);
|
int32_t default_val);
|
||||||
int getinfo_helper_networkstatus(control_connection_t *conn,
|
int getinfo_helper_networkstatus(control_connection_t *conn,
|
||||||
const char *question, char **answer);
|
const char *question, char **answer);
|
||||||
|
int32_t networkstatus_get_bw_weight(networkstatus_t *ns, const char *weight,
|
||||||
|
int32_t default_val);
|
||||||
const char *networkstatus_get_flavor_name(consensus_flavor_t flav);
|
const char *networkstatus_get_flavor_name(consensus_flavor_t flav);
|
||||||
int networkstatus_parse_flavor_name(const char *flavname);
|
int networkstatus_parse_flavor_name(const char *flavname);
|
||||||
void document_signature_free(document_signature_t *sig);
|
void document_signature_free(document_signature_t *sig);
|
||||||
@ -5182,6 +5188,7 @@ void dump_distinct_digest_count(int severity);
|
|||||||
|
|
||||||
int compare_routerstatus_entries(const void **_a, const void **_b);
|
int compare_routerstatus_entries(const void **_a, const void **_b);
|
||||||
networkstatus_v2_t *networkstatus_v2_parse_from_string(const char *s);
|
networkstatus_v2_t *networkstatus_v2_parse_from_string(const char *s);
|
||||||
|
int networkstatus_verify_bw_weights(networkstatus_t *ns);
|
||||||
networkstatus_t *networkstatus_parse_vote_from_string(const char *s,
|
networkstatus_t *networkstatus_parse_vote_from_string(const char *s,
|
||||||
const char **eos_out,
|
const char **eos_out,
|
||||||
networkstatus_type_t ns_type);
|
networkstatus_type_t ns_type);
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include "or.h"
|
#include "or.h"
|
||||||
#include "memarea.h"
|
#include "memarea.h"
|
||||||
|
#undef log
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
@ -104,6 +106,7 @@ typedef enum {
|
|||||||
|
|
||||||
K_KNOWN_FLAGS,
|
K_KNOWN_FLAGS,
|
||||||
K_PARAMS,
|
K_PARAMS,
|
||||||
|
K_BW_WEIGHTS,
|
||||||
K_VOTE_DIGEST,
|
K_VOTE_DIGEST,
|
||||||
K_CONSENSUS_DIGEST,
|
K_CONSENSUS_DIGEST,
|
||||||
K_ADDITIONAL_DIGEST,
|
K_ADDITIONAL_DIGEST,
|
||||||
@ -485,6 +488,7 @@ static token_rule_t networkstatus_consensus_token_table[] = {
|
|||||||
/** List of tokens allowable in the footer of v1/v2 directory/networkstatus
|
/** List of tokens allowable in the footer of v1/v2 directory/networkstatus
|
||||||
* footers. */
|
* footers. */
|
||||||
static token_rule_t networkstatus_vote_footer_token_table[] = {
|
static token_rule_t networkstatus_vote_footer_token_table[] = {
|
||||||
|
T01("bandwidth-weights", K_BW_WEIGHTS, ARGS, NO_OBJ ),
|
||||||
T( "directory-signature", K_DIRECTORY_SIGNATURE, GE(2), NEED_OBJ ),
|
T( "directory-signature", K_DIRECTORY_SIGNATURE, GE(2), NEED_OBJ ),
|
||||||
END_OF_TABLE
|
END_OF_TABLE
|
||||||
};
|
};
|
||||||
@ -2327,6 +2331,360 @@ networkstatus_v2_parse_from_string(const char *s)
|
|||||||
return ns;
|
return ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Verify the bandwidth weights of a network status document */
|
||||||
|
int
|
||||||
|
networkstatus_verify_bw_weights(networkstatus_t *ns)
|
||||||
|
{
|
||||||
|
int64_t weight_scale;
|
||||||
|
int64_t G=0, M=0, E=0, D=0, T=0;
|
||||||
|
double Wgg, Wgm, Wgd, Wmg, Wmm, Wme, Wmd, Weg, Wem, Wee, Wed;
|
||||||
|
double Gtotal=0, Mtotal=0, Etotal=0;
|
||||||
|
const char *casename = NULL;
|
||||||
|
int valid = 1;
|
||||||
|
|
||||||
|
weight_scale = networkstatus_get_param(ns, "bwweightscale", BW_WEIGHT_SCALE);
|
||||||
|
Wgg = networkstatus_get_bw_weight(ns, "Wgg", -1);
|
||||||
|
Wgm = networkstatus_get_bw_weight(ns, "Wgm", -1);
|
||||||
|
Wgd = networkstatus_get_bw_weight(ns, "Wgd", -1);
|
||||||
|
Wmg = networkstatus_get_bw_weight(ns, "Wmg", -1);
|
||||||
|
Wmm = networkstatus_get_bw_weight(ns, "Wmm", -1);
|
||||||
|
Wme = networkstatus_get_bw_weight(ns, "Wme", -1);
|
||||||
|
Wmd = networkstatus_get_bw_weight(ns, "Wmd", -1);
|
||||||
|
Weg = networkstatus_get_bw_weight(ns, "Weg", -1);
|
||||||
|
Wem = networkstatus_get_bw_weight(ns, "Wem", -1);
|
||||||
|
Wee = networkstatus_get_bw_weight(ns, "Wee", -1);
|
||||||
|
Wed = networkstatus_get_bw_weight(ns, "Wed", -1);
|
||||||
|
|
||||||
|
if (Wgg<0 || Wgm<0 || Wgd<0 || Wmg<0 || Wmm<0 || Wme<0 || Wmd<0 || Weg<0
|
||||||
|
|| Wem<0 || Wee<0 || Wed<0) {
|
||||||
|
log_warn(LD_BUG, "No bandwidth weights produced in consensus!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First, sanity check basic summing properties that hold for all cases
|
||||||
|
// We use > 1 as the check for these because they are computed as integers.
|
||||||
|
// Sometimes there are rounding errors.
|
||||||
|
if (fabs(Wmm - weight_scale) > 1) {
|
||||||
|
log_warn(LD_BUG, "Wmm=%lf != "I64_FORMAT, Wmm, weight_scale);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fabs(Wem - Wee) > 1) {
|
||||||
|
log_warn(LD_BUG, "Wem=%lf != Wee=%lf", Wem, Wee);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fabs(Wgm - Wgg) > 1) {
|
||||||
|
log_warn(LD_BUG, "Wgm=%lf != Wgg=%lf", Wgm, Wgg);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fabs(Weg - Wed) > 1) {
|
||||||
|
log_warn(LD_BUG, "Wed=%lf != Weg=%lf", Wed, Weg);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fabs(Wgg + Wmg - weight_scale) > 0.001*weight_scale) {
|
||||||
|
log_warn(LD_BUG, "Wgg=%lf != "I64_FORMAT" - Wmg=%lf", Wgg,
|
||||||
|
weight_scale, Wmg);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fabs(Wee + Wme - weight_scale) > 0.001*weight_scale) {
|
||||||
|
log_warn(LD_BUG, "Wee=%lf != "I64_FORMAT" - Wme=%lf", Wee,
|
||||||
|
weight_scale, Wme);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fabs(Wgd + Wmd + Wed - weight_scale) > 0.001*weight_scale) {
|
||||||
|
log_warn(LD_BUG, "Wgd=%lf + Wmd=%lf + Wed=%lf != "I64_FORMAT,
|
||||||
|
Wgd, Wmd, Wed, weight_scale);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Wgg /= weight_scale;
|
||||||
|
Wgm /= weight_scale;
|
||||||
|
Wgd /= weight_scale;
|
||||||
|
|
||||||
|
Wmg /= weight_scale;
|
||||||
|
Wmm /= weight_scale;
|
||||||
|
Wme /= weight_scale;
|
||||||
|
Wmd /= weight_scale;
|
||||||
|
|
||||||
|
Weg /= weight_scale;
|
||||||
|
Wem /= weight_scale;
|
||||||
|
Wee /= weight_scale;
|
||||||
|
Wed /= weight_scale;
|
||||||
|
|
||||||
|
// Then, gather G, M, E, D, T to determine case
|
||||||
|
SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) {
|
||||||
|
if (rs->has_bandwidth) {
|
||||||
|
T += rs->bandwidth;
|
||||||
|
if (rs->is_exit && rs->is_possible_guard) {
|
||||||
|
D += rs->bandwidth;
|
||||||
|
Gtotal += Wgd*rs->bandwidth;
|
||||||
|
Mtotal += Wmd*rs->bandwidth;
|
||||||
|
Etotal += Wed*rs->bandwidth;
|
||||||
|
} else if (rs->is_exit) {
|
||||||
|
E += rs->bandwidth;
|
||||||
|
Mtotal += Wme*rs->bandwidth;
|
||||||
|
Etotal += Wee*rs->bandwidth;
|
||||||
|
} else if (rs->is_possible_guard) {
|
||||||
|
G += rs->bandwidth;
|
||||||
|
Gtotal += Wgg*rs->bandwidth;
|
||||||
|
Mtotal += Wmg*rs->bandwidth;
|
||||||
|
} else {
|
||||||
|
M += rs->bandwidth;
|
||||||
|
Mtotal += Wmm*rs->bandwidth;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log_warn(LD_BUG, "Missing consensus bandwidth for router %s",
|
||||||
|
rs->nickname);
|
||||||
|
}
|
||||||
|
} SMARTLIST_FOREACH_END(rs);
|
||||||
|
|
||||||
|
// Finally, check equality conditions depending upon case 1, 2 or 3
|
||||||
|
// Full equality cases: 1, 3b
|
||||||
|
// Partial equality cases: 2b (E=G), 3a (M=E)
|
||||||
|
// Fully unknown: 2a
|
||||||
|
if (3*E >= T && 3*G >= T) {
|
||||||
|
// Case 1: Neither are scarce
|
||||||
|
casename = "Case 1";
|
||||||
|
if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: Etotal %lf != Mtotal %lf. "
|
||||||
|
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
|
||||||
|
" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Etotal, Mtotal, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: Etotal %lf != Gtotal %lf. "
|
||||||
|
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
|
||||||
|
" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Etotal, Gtotal, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: Mtotal %lf != Gtotal %lf. "
|
||||||
|
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
|
||||||
|
" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Mtotal, Gtotal, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
} else if (3*E < T && 3*G < T) {
|
||||||
|
int64_t R = MIN(E, G);
|
||||||
|
int64_t S = MAX(E, G);
|
||||||
|
/*
|
||||||
|
* Case 2: Both Guards and Exits are scarce
|
||||||
|
* Balance D between E and G, depending upon
|
||||||
|
* D capacity and scarcity. Devote no extra
|
||||||
|
* bandwidth to middle nodes.
|
||||||
|
*/
|
||||||
|
if (R+D < S) { // Subcase a
|
||||||
|
double Rtotal, Stotal;
|
||||||
|
if (E < G) {
|
||||||
|
Rtotal = Etotal;
|
||||||
|
Stotal = Gtotal;
|
||||||
|
} else {
|
||||||
|
Rtotal = Gtotal;
|
||||||
|
Stotal = Etotal;
|
||||||
|
}
|
||||||
|
casename = "Case 2a";
|
||||||
|
// Rtotal < Stotal
|
||||||
|
if (Rtotal > Stotal) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: Rtotal %lf > Stotal %lf. "
|
||||||
|
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
|
||||||
|
" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Rtotal, Stotal, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
// Rtotal < T/3
|
||||||
|
if (3*Rtotal > T) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: 3*Rtotal %lf > T "
|
||||||
|
I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
|
||||||
|
" D="I64_FORMAT" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Rtotal*3, T, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
// Stotal < T/3
|
||||||
|
if (3*Stotal > T) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: 3*Stotal %lf > T "
|
||||||
|
I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
|
||||||
|
" D="I64_FORMAT" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Stotal*3, T, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
// Mtotal > T/3
|
||||||
|
if (3*Mtotal < T) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: 3*Mtotal %lf < T "
|
||||||
|
I64_FORMAT". "
|
||||||
|
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
|
||||||
|
" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Mtotal*3, T, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
} else { // Subcase b: R+D > S
|
||||||
|
casename = "Case 2b";
|
||||||
|
|
||||||
|
/* Check the rare-M redirect case. */
|
||||||
|
if (D != 0 && 3*M < T) {
|
||||||
|
casename = "Case 2b (balanced)";
|
||||||
|
if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: Etotal %lf != Mtotal %lf. "
|
||||||
|
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
|
||||||
|
" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Etotal, Mtotal, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: Etotal %lf != Gtotal %lf. "
|
||||||
|
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
|
||||||
|
" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Etotal, Gtotal, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: Mtotal %lf != Gtotal %lf. "
|
||||||
|
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
|
||||||
|
" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Mtotal, Gtotal, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: Etotal %lf != Gtotal %lf. "
|
||||||
|
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
|
||||||
|
" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Etotal, Gtotal, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // if (E < T/3 || G < T/3) {
|
||||||
|
int64_t S = MIN(E, G);
|
||||||
|
int64_t NS = MAX(E, G);
|
||||||
|
if (3*(S+D) < T) { // Subcase a:
|
||||||
|
double Stotal;
|
||||||
|
double NStotal;
|
||||||
|
if (G < E) {
|
||||||
|
casename = "Case 3a (G scarce)";
|
||||||
|
Stotal = Gtotal;
|
||||||
|
NStotal = Etotal;
|
||||||
|
} else { // if (G >= E) {
|
||||||
|
casename = "Case 3a (E scarce)";
|
||||||
|
NStotal = Gtotal;
|
||||||
|
Stotal = Etotal;
|
||||||
|
}
|
||||||
|
// Stotal < T/3
|
||||||
|
if (3*Stotal > T) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: 3*Stotal %lf > T "
|
||||||
|
I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT
|
||||||
|
" D="I64_FORMAT" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Stotal*3, T, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
if (NS >= M) {
|
||||||
|
if (fabs(NStotal-Mtotal) > 0.01*MAX(NStotal,Mtotal)) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: NStotal %lf != Mtotal %lf. "
|
||||||
|
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
|
||||||
|
" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, NStotal, Mtotal, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if NS < M, NStotal > T/3 because only one of G or E is scarce
|
||||||
|
if (3*NStotal < T) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: 3*NStotal %lf < T "
|
||||||
|
I64_FORMAT". G="I64_FORMAT" M="I64_FORMAT
|
||||||
|
" E="I64_FORMAT" D="I64_FORMAT" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, NStotal*3, T, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // Subcase b: S+D >= T/3
|
||||||
|
casename = "Case 3b";
|
||||||
|
if (fabs(Etotal-Mtotal) > 0.01*MAX(Etotal,Mtotal)) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: Etotal %lf != Mtotal %lf. "
|
||||||
|
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
|
||||||
|
" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Etotal, Mtotal, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
if (fabs(Etotal-Gtotal) > 0.01*MAX(Etotal,Gtotal)) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: Etotal %lf != Gtotal %lf. "
|
||||||
|
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
|
||||||
|
" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Etotal, Gtotal, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
if (fabs(Gtotal-Mtotal) > 0.01*MAX(Gtotal,Mtotal)) {
|
||||||
|
log_warn(LD_DIR,
|
||||||
|
"Bw Weight Failure for %s: Mtotal %lf != Gtotal %lf. "
|
||||||
|
"G="I64_FORMAT" M="I64_FORMAT" E="I64_FORMAT" D="I64_FORMAT
|
||||||
|
" T="I64_FORMAT". "
|
||||||
|
"Wgg=%lf Wgd=%lf Wmg=%lf Wme=%lf Wmd=%lf Wee=%lf Wed=%lf",
|
||||||
|
casename, Mtotal, Gtotal, G, M, E, D, T,
|
||||||
|
Wgg, Wgd, Wmg, Wme, Wmd, Wee, Wed);
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid)
|
||||||
|
log_notice(LD_DIR, "Bandwidth-weight %s is verified and valid.",
|
||||||
|
casename);
|
||||||
|
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
/** Parse a v3 networkstatus vote, opinion, or consensus (depending on
|
/** Parse a v3 networkstatus vote, opinion, or consensus (depending on
|
||||||
* ns_type), from <b>s</b>, and return the result. Return NULL on failure. */
|
* ns_type), from <b>s</b>, and return the result. Return NULL on failure. */
|
||||||
networkstatus_t *
|
networkstatus_t *
|
||||||
@ -2675,6 +3033,26 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tok = find_opt_by_keyword(footer_tokens, K_BW_WEIGHTS);
|
||||||
|
if (tok) {
|
||||||
|
ns->weight_params = smartlist_create();
|
||||||
|
for (i = 0; i < tok->n_args; ++i) {
|
||||||
|
int ok=0;
|
||||||
|
char *eq = strchr(tok->args[i], '=');
|
||||||
|
if (!eq) {
|
||||||
|
log_warn(LD_DIR, "Bad element '%s' in weight params",
|
||||||
|
escaped(tok->args[i]));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
tor_parse_long(eq+1, 10, INT32_MIN, INT32_MAX, &ok, NULL);
|
||||||
|
if (!ok) {
|
||||||
|
log_warn(LD_DIR, "Bad element '%s' in params", escaped(tok->args[i]));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
smartlist_add(ns->weight_params, tor_strdup(tok->args[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SMARTLIST_FOREACH_BEGIN(footer_tokens, directory_token_t *, _tok) {
|
SMARTLIST_FOREACH_BEGIN(footer_tokens, directory_token_t *, _tok) {
|
||||||
char declared_identity[DIGEST_LEN];
|
char declared_identity[DIGEST_LEN];
|
||||||
networkstatus_voter_info_t *v;
|
networkstatus_voter_info_t *v;
|
||||||
|
Loading…
Reference in New Issue
Block a user