Merge branch 'fallback_dirsource_v3'

This commit is contained in:
Nick Mathewson
2012-12-13 12:42:29 -05:00
13 changed files with 537 additions and 227 deletions
+181 -50
View File
@@ -81,6 +81,7 @@ static config_abbrev_t option_abbrevs_[] = {
{ "BandwidthRateBytes", "BandwidthRate", 0, 0},
{ "BandwidthBurstBytes", "BandwidthBurst", 0, 0},
{ "DirFetchPostPeriod", "StatusFetchPeriod", 0, 0},
{ "DirServer", "DirAuthority", 0, 0}, /* XXXX024 later, make this warn? */
{ "MaxConn", "ConnLimit", 0, 1},
{ "ORBindAddress", "ORListenAddress", 0, 0},
{ "DirBindAddress", "DirListenAddress", 0, 0},
@@ -206,7 +207,8 @@ static config_var_t option_vars_[] = {
OBSOLETE("DirRecordUsageRetainIPs"),
OBSOLETE("DirRecordUsageSaveInterval"),
V(DirReqStatistics, BOOL, "1"),
VAR("DirServer", LINELIST, DirServers, NULL),
VAR("DirAuthority", LINELIST, DirAuthorities, NULL),
V(DirAuthorityFallbackRate, DOUBLE, "1.0"),
V(DisableAllSwap, BOOL, "0"),
V(DisableDebuggerAttachment, BOOL, "1"),
V(DisableIOCP, BOOL, "1"),
@@ -227,13 +229,9 @@ static config_var_t option_vars_[] = {
V(ExitPortStatistics, BOOL, "0"),
V(ExtendAllowPrivateAddresses, BOOL, "0"),
V(ExtraInfoStatistics, BOOL, "1"),
V(FallbackDir, LINELIST, NULL),
#if defined (WINCE)
V(FallbackNetworkstatusFile, FILENAME, "fallback-consensus"),
#else
V(FallbackNetworkstatusFile, FILENAME,
SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "fallback-consensus"),
#endif
OBSOLETE("FallbackNetworkstatusFile"),
V(FascistFirewall, BOOL, "0"),
V(FirewallPorts, CSV, ""),
V(FastFirstHopPK, BOOL, "1"),
@@ -470,10 +468,11 @@ static int parse_client_transport_line(const char *line, int validate_only);
static int parse_server_transport_line(const char *line, int validate_only);
static char *get_bindaddr_from_transport_listen_line(const char *line,
const char *transport);
static int parse_dir_server_line(const char *line,
static int parse_dir_authority_line(const char *line,
dirinfo_type_t required_type,
int validate_only);
static int parse_dir_fallback_line(const char *line,
int validate_only);
static void port_cfg_free(port_cfg_t *port);
static int parse_ports(or_options_t *options, int validate_only,
char **msg_out, int *n_ports_out);
@@ -756,7 +755,7 @@ static void
add_default_trusted_dir_authorities(dirinfo_type_t type)
{
int i;
const char *dirservers[] = {
const char *authorities[] = {
"moria1 orport=9101 no-v2 "
"v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
"128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
@@ -785,10 +784,27 @@ add_default_trusted_dir_authorities(dirinfo_type_t type)
"154.35.32.5:80 CF6D 0AAF B385 BE71 B8E1 11FC 5CFF 4B47 9237 33BC",
NULL
};
for (i=0; dirservers[i]; i++) {
if (parse_dir_server_line(dirservers[i], type, 0)<0) {
log_err(LD_BUG, "Couldn't parse internal dirserver line %s",
dirservers[i]);
for (i=0; authorities[i]; i++) {
if (parse_dir_authority_line(authorities[i], type, 0)<0) {
log_err(LD_BUG, "Couldn't parse internal DirAuthority line %s",
authorities[i]);
}
}
}
/** Add the default fallback directory servers into the fallback directory
* server list. */
static void
add_default_fallback_dir_servers(void)
{
int i;
const char *fallback[] = {
NULL
};
for (i=0; fallback[i]; i++) {
if (parse_dir_fallback_line(fallback[i], 0)<0) {
log_err(LD_BUG, "Couldn't parse internal FallbackDir line %s",
fallback[i]);
}
}
}
@@ -798,28 +814,28 @@ add_default_trusted_dir_authorities(dirinfo_type_t type)
* user if we changed any dangerous ones.
*/
static int
validate_dir_authorities(or_options_t *options, or_options_t *old_options)
validate_dir_servers(or_options_t *options, or_options_t *old_options)
{
config_line_t *cl;
if (options->DirServers &&
if (options->DirAuthorities &&
(options->AlternateDirAuthority || options->AlternateBridgeAuthority ||
options->AlternateHSAuthority)) {
log_warn(LD_CONFIG,
"You cannot set both DirServers and Alternate*Authority.");
"You cannot set both DirAuthority and Alternate*Authority.");
return -1;
}
/* do we want to complain to the user about being partitionable? */
if ((options->DirServers &&
if ((options->DirAuthorities &&
(!old_options ||
!config_lines_eq(options->DirServers, old_options->DirServers))) ||
!config_lines_eq(options->DirAuthorities, old_options->DirAuthorities))) ||
(options->AlternateDirAuthority &&
(!old_options ||
!config_lines_eq(options->AlternateDirAuthority,
old_options->AlternateDirAuthority)))) {
log_warn(LD_CONFIG,
"You have used DirServer or AlternateDirAuthority to "
"You have used DirAuthority or AlternateDirAuthority to "
"specify alternate directory authorities in "
"your configuration. This is potentially dangerous: it can "
"make you look different from all other Tor users, and hurt "
@@ -830,17 +846,20 @@ validate_dir_authorities(or_options_t *options, or_options_t *old_options)
/* Now go through the four ways you can configure an alternate
* set of directory authorities, and make sure none are broken. */
for (cl = options->DirServers; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_DIRINFO, 1)<0)
for (cl = options->DirAuthorities; cl; cl = cl->next)
if (parse_dir_authority_line(cl->value, NO_DIRINFO, 1)<0)
return -1;
for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_DIRINFO, 1)<0)
if (parse_dir_authority_line(cl->value, NO_DIRINFO, 1)<0)
return -1;
for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_DIRINFO, 1)<0)
if (parse_dir_authority_line(cl->value, NO_DIRINFO, 1)<0)
return -1;
for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_DIRINFO, 1)<0)
if (parse_dir_authority_line(cl->value, NO_DIRINFO, 1)<0)
return -1;
for (cl = options->FallbackDir; cl; cl = cl->next)
if (parse_dir_fallback_line(cl->value, 1)<0)
return -1;
return 0;
}
@@ -849,13 +868,15 @@ validate_dir_authorities(or_options_t *options, or_options_t *old_options)
* as appropriate.
*/
static int
consider_adding_dir_authorities(const or_options_t *options,
const or_options_t *old_options)
consider_adding_dir_servers(const or_options_t *options,
const or_options_t *old_options)
{
config_line_t *cl;
int need_to_update =
!smartlist_len(router_get_trusted_dir_servers()) || !old_options ||
!config_lines_eq(options->DirServers, old_options->DirServers) ||
!smartlist_len(router_get_trusted_dir_servers()) ||
!smartlist_len(router_get_fallback_dir_servers()) || !old_options ||
!config_lines_eq(options->DirAuthorities, old_options->DirAuthorities) ||
!config_lines_eq(options->FallbackDir, old_options->FallbackDir) ||
!config_lines_eq(options->AlternateBridgeAuthority,
old_options->AlternateBridgeAuthority) ||
!config_lines_eq(options->AlternateDirAuthority,
@@ -867,9 +888,9 @@ consider_adding_dir_authorities(const or_options_t *options,
return 0; /* all done */
/* Start from a clean slate. */
clear_trusted_dir_servers();
clear_dir_servers();
if (!options->DirServers) {
if (!options->DirAuthorities) {
/* then we may want some of the defaults */
dirinfo_type_t type = NO_DIRINFO;
if (!options->AlternateBridgeAuthority)
@@ -881,18 +902,23 @@ consider_adding_dir_authorities(const or_options_t *options,
type |= HIDSERV_DIRINFO;
add_default_trusted_dir_authorities(type);
}
if (!options->FallbackDir)
add_default_fallback_dir_servers();
for (cl = options->DirServers; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_DIRINFO, 0)<0)
for (cl = options->DirAuthorities; cl; cl = cl->next)
if (parse_dir_authority_line(cl->value, NO_DIRINFO, 0)<0)
return -1;
for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_DIRINFO, 0)<0)
if (parse_dir_authority_line(cl->value, NO_DIRINFO, 0)<0)
return -1;
for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_DIRINFO, 0)<0)
if (parse_dir_authority_line(cl->value, NO_DIRINFO, 0)<0)
return -1;
for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_DIRINFO, 0)<0)
if (parse_dir_authority_line(cl->value, NO_DIRINFO, 0)<0)
return -1;
for (cl = options->FallbackDir; cl; cl = cl->next)
if (parse_dir_fallback_line(cl->value, 0)<0)
return -1;
return 0;
}
@@ -1216,7 +1242,7 @@ options_act(const or_options_t *old_options)
return -1;
}
if (consider_adding_dir_authorities(options, old_options) < 0)
if (consider_adding_dir_servers(options, old_options) < 0)
return -1;
#ifdef NON_ANONYMOUS_MODE_ENABLED
@@ -1924,18 +1950,18 @@ resolve_my_address(int warn_severity, const or_options_t *options,
addr_string = tor_dup_ip(addr);
if (is_internal_IP(addr, 0)) {
/* make sure we're ok with publishing an internal IP */
if (!options->DirServers && !options->AlternateDirAuthority) {
/* if they are using the default dirservers, disallow internal IPs
if (!options->DirAuthorities && !options->AlternateDirAuthority) {
/* if they are using the default authorities, disallow internal IPs
* always. */
log_fn(warn_severity, LD_CONFIG,
"Address '%s' resolves to private IP address '%s'. "
"Tor servers that use the default DirServers must have public "
"Tor servers that use the default DirAuthorities must have public "
"IP addresses.", hostname, addr_string);
tor_free(addr_string);
return -1;
}
if (!explicit_ip) {
/* even if they've set their own dirservers, require an explicit IP if
/* even if they've set their own authorities, require an explicit IP if
* they're using an internal address. */
log_fn(warn_severity, LD_CONFIG, "Address '%s' resolves to private "
"IP address '%s'. Please set the Address config option to be "
@@ -2843,8 +2869,9 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (validate_addr_policies(options, msg) < 0)
return -1;
if (validate_dir_authorities(options, old_options) < 0)
REJECT("Directory authority line did not parse. See logs for details.");
if (validate_dir_servers(options, old_options) < 0)
REJECT("Directory authority/fallback line did not parse. See logs "
"for details.");
if (options->UseBridges && !options->Bridges)
REJECT("If you set UseBridges, you must specify at least one bridge.");
@@ -2962,7 +2989,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
}
if (options->TestingTorNetwork &&
!(options->DirServers ||
!(options->DirAuthorities ||
(options->AlternateDirAuthority &&
options->AlternateBridgeAuthority))) {
REJECT("TestingTorNetwork may only be configured in combination with "
@@ -2970,7 +2997,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
"and AlternateBridgeAuthority configured.");
}
if (options->AllowSingleHopExits && !options->DirServers) {
if (options->AllowSingleHopExits && !options->DirAuthorities) {
COMPLAIN("You have set AllowSingleHopExits; now your relay will allow "
"others to make one-hop exits. However, since by default most "
"clients avoid relays that set this option, most clients will "
@@ -4322,15 +4349,15 @@ parse_server_transport_line(const char *line, int validate_only)
return r;
}
/** Read the contents of a DirServer line from <b>line</b>. If
/** Read the contents of a DirAuthority line from <b>line</b>. If
* <b>validate_only</b> is 0, and the line is well-formed, and it
* shares any bits with <b>required_type</b> or <b>required_type</b>
* is 0, then add the dirserver described in the line (minus whatever
* bits it's missing) as a valid authority. Return 0 on success,
* or -1 if the line isn't well-formed or if we can't add it. */
static int
parse_dir_server_line(const char *line, dirinfo_type_t required_type,
int validate_only)
parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
int validate_only)
{
smartlist_t *items = NULL;
int r;
@@ -4340,6 +4367,7 @@ parse_dir_server_line(const char *line, dirinfo_type_t required_type,
char v3_digest[DIGEST_LEN];
dirinfo_type_t type = V2_DIRINFO;
int is_not_hidserv_authority = 0, is_not_v2_authority = 0;
double weight = 1.0;
items = smartlist_new();
smartlist_split_string(items, line, NULL,
@@ -4375,6 +4403,14 @@ parse_dir_server_line(const char *line, dirinfo_type_t required_type,
if (!ok)
log_warn(LD_CONFIG, "Invalid orport '%s' on DirServer line.",
portstring);
} else if (!strcmpstart(flag, "weight=")) {
int ok;
const char *wstring = flag + strlen("weight=");
weight = tor_parse_double(wstring, 0, UINT64_MAX, &ok, NULL);
if (!ok) {
log_warn(LD_CONFIG, "Invalid weight '%s' on DirAuthority line.",flag);
weight=1.0;
}
} else if (!strcasecmpstart(flag, "v3ident=")) {
char *idstr = flag + strlen("v3ident=");
if (strlen(idstr) != HEX_DIGEST_LEN ||
@@ -4431,14 +4467,16 @@ parse_dir_server_line(const char *line, dirinfo_type_t required_type,
}
if (!validate_only && (!required_type || required_type & type)) {
dir_server_t *ds;
if (required_type)
type &= required_type; /* pare down what we think of them as an
* authority for. */
log_debug(LD_DIR, "Trusted %d dirserver at %s:%d (%s)", (int)type,
address, (int)dir_port, (char*)smartlist_get(items,0));
if (!add_trusted_dir_server(nickname, address, dir_port, or_port,
digest, v3_digest, type))
if (!(ds = trusted_dir_server_new(nickname, address, dir_port, or_port,
digest, v3_digest, type, weight)))
goto err;
dir_server_add(ds);
}
r = 0;
@@ -4457,6 +4495,99 @@ parse_dir_server_line(const char *line, dirinfo_type_t required_type,
return r;
}
/** Read the contents of a FallbackDir line from <b>line</b>. If
* <b>validate_only</b> is 0, and the line is well-formed, then add the
* dirserver described in the line as a fallback directory. Return 0 on
* success, or -1 if the line isn't well-formed or if we can't add it. */
static int
parse_dir_fallback_line(const char *line,
int validate_only)
{
int r = -1;
smartlist_t *items = smartlist_new(), *positional = smartlist_new();
int orport = -1;
uint16_t dirport;
tor_addr_t addr;
int ok;
char id[DIGEST_LEN];
char *address=NULL;
double weight=1.0;
memset(id, 0, sizeof(id));
smartlist_split_string(items, line, NULL,
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
SMARTLIST_FOREACH_BEGIN(items, const char *, cp) {
const char *eq = strchr(cp, '=');
ok = 1;
if (! eq) {
smartlist_add(positional, (char*)cp);
continue;
}
if (!strcmpstart(cp, "orport=")) {
orport = (int)tor_parse_long(cp+strlen("orport="), 10,
1, 65535, &ok, NULL);
} else if (!strcmpstart(cp, "id=")) {
ok = !base16_decode(id, DIGEST_LEN,
cp+strlen("id="), strlen(cp)-strlen("id="));
} else if (!strcmpstart(cp, "weight=")) {
int ok;
const char *wstring = cp + strlen("weight=");
weight = tor_parse_double(wstring, 0, UINT64_MAX, &ok, NULL);
if (!ok) {
log_warn(LD_CONFIG, "Invalid weight '%s' on FallbackDir line.", cp);
weight=1.0;
}
}
if (!ok) {
log_warn(LD_CONFIG, "Bad FallbackDir option %s", escaped(cp));
goto end;
}
} SMARTLIST_FOREACH_END(cp);
if (smartlist_len(positional) != 1) {
log_warn(LD_CONFIG, "Couldn't parse FallbackDir line %s", escaped(line));
goto end;
}
if (tor_digest_is_zero(id)) {
log_warn(LD_CONFIG, "Missing identity on FallbackDir line");
goto end;
}
if (orport <= 0) {
log_warn(LD_CONFIG, "Missing orport on FallbackDir line");
goto end;
}
if (tor_addr_port_split(LOG_INFO, smartlist_get(positional, 0),
&address, &dirport) < 0 ||
tor_addr_parse(&addr, address)<0) {
log_warn(LD_CONFIG, "Couldn't parse address:port %s on FallbackDir line",
(const char*)smartlist_get(positional, 0));
goto end;
}
if (!validate_only) {
dir_server_t *ds;
ds = fallback_dir_server_new(&addr, dirport, orport, id, weight);
if (!ds) {
log_warn(LD_CONFIG, "Couldn't create FallbackDir %s", escaped(line));
goto end;
}
dir_server_add(ds);
}
r = 0;
end:
SMARTLIST_FOREACH(items, char *, cp, tor_free(cp));
smartlist_free(items);
smartlist_free(positional);
tor_free(address);
return r;
}
/** Free all storage held in <b>port</b> */
static void
port_cfg_free(port_cfg_t *port)
+15 -15
View File
@@ -244,9 +244,9 @@ router_supports_extrainfo(const char *identity_digest, int is_authority)
int
directories_have_accepted_server_descriptor(void)
{
smartlist_t *servers = router_get_trusted_dir_servers();
const smartlist_t *servers = router_get_trusted_dir_servers();
const or_options_t *options = get_options();
SMARTLIST_FOREACH(servers, trusted_dir_server_t *, d, {
SMARTLIST_FOREACH(servers, dir_server_t *, d, {
if ((d->type & options->PublishServerDescriptor_) &&
d->has_accepted_serverdesc) {
return 1;
@@ -280,7 +280,7 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
{
const or_options_t *options = get_options();
int post_via_tor;
smartlist_t *dirservers = router_get_trusted_dir_servers();
const smartlist_t *dirservers = router_get_trusted_dir_servers();
int found = 0;
const int exclude_self = (dir_purpose == DIR_PURPOSE_UPLOAD_VOTE ||
dir_purpose == DIR_PURPOSE_UPLOAD_SIGNATURES);
@@ -288,7 +288,7 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
/* This tries dirservers which we believe to be down, but ultimately, that's
* harmless, and we may as well err on the side of getting things uploaded.
*/
SMARTLIST_FOREACH_BEGIN(dirservers, trusted_dir_server_t *, ds) {
SMARTLIST_FOREACH_BEGIN(dirservers, dir_server_t *, ds) {
routerstatus_t *rs = &(ds->fake_status);
size_t upload_len = payload_len;
tor_addr_t ds_addr;
@@ -474,7 +474,7 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
if (!rs) {
log_info(LD_DIR, "No router found for %s; falling back to "
"dirserver list.", dir_conn_purpose_to_string(dir_purpose));
rs = router_pick_trusteddirserver(type, pds_flags);
rs = router_pick_fallback_dirserver(type, pds_flags);
if (!rs)
get_via_tor = 1; /* last resort: try routing it via Tor */
}
@@ -528,7 +528,7 @@ directory_get_from_all_authorities(uint8_t dir_purpose,
dir_purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES);
SMARTLIST_FOREACH_BEGIN(router_get_trusted_dir_servers(),
trusted_dir_server_t *, ds) {
dir_server_t *, ds) {
routerstatus_t *rs;
if (router_digest_is_me(ds->digest))
continue;
@@ -716,8 +716,8 @@ connection_dir_download_v2_networkstatus_failed(dir_connection_t *conn,
/* We're a non-authoritative directory cache; try again. Ignore status
* code, since we don't want to keep trying forever in a tight loop
* if all the authorities are shutting us out. */
smartlist_t *trusted_dirs = router_get_trusted_dir_servers();
SMARTLIST_FOREACH(trusted_dirs, trusted_dir_server_t *, ds,
const smartlist_t *trusted_dirs = router_get_trusted_dir_servers();
SMARTLIST_FOREACH(trusted_dirs, dir_server_t *, ds,
download_status_failed(&ds->v2_ns_dl_status, 0));
directory_get_from_dirserver(conn->base_.purpose, conn->router_purpose,
"all.z", 0 /* don't retry_if_no_servers */);
@@ -1088,7 +1088,7 @@ directory_get_consensus_url(const char *resource)
smartlist_t *authority_digests = smartlist_new();
SMARTLIST_FOREACH_BEGIN(router_get_trusted_dir_servers(),
trusted_dir_server_t *, ds) {
dir_server_t *, ds) {
char *hex;
if (!(ds->type & V3_DIRINFO))
continue;
@@ -1657,7 +1657,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
if (status_code == 503) {
routerstatus_t *rs;
trusted_dir_server_t *ds;
dir_server_t *ds;
const char *id_digest = conn->identity_digest;
log_info(LD_DIR,"Received http status code %d (%s) from server "
"'%s:%d'. I'll try again soon.",
@@ -1665,7 +1665,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
conn->base_.port);
if ((rs = router_get_mutable_consensus_status_by_id(id_digest)))
rs->last_dir_503_at = now;
if ((ds = router_get_trusteddirserver_by_digest(id_digest)))
if ((ds = router_get_fallback_dirserver_by_digest(id_digest)))
ds->fake_status.last_dir_503_at = now;
tor_free(body); tor_free(headers); tor_free(reason);
@@ -1764,7 +1764,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
source = NS_FROM_DIR_ALL;
which = smartlist_new();
SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
trusted_dir_server_t *, ds,
dir_server_t *, ds,
{
char *hex = tor_malloc(HEX_DIGEST_LEN+1);
base16_encode(hex, HEX_DIGEST_LEN+1, ds->digest, DIGEST_LEN);
@@ -2021,7 +2021,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
if (conn->base_.purpose == DIR_PURPOSE_UPLOAD_DIR) {
switch (status_code) {
case 200: {
trusted_dir_server_t *ds =
dir_server_t *ds =
router_get_trusteddirserver_by_digest(conn->identity_digest);
char *rejected_hdr = http_get_header(headers,
"X-Descriptor-Not-New: ");
@@ -3597,13 +3597,13 @@ dir_networkstatus_download_failed(smartlist_t *failed, int status_code)
return;
SMARTLIST_FOREACH_BEGIN(failed, const char *, fp) {
char digest[DIGEST_LEN];
trusted_dir_server_t *dir;
dir_server_t *dir;
if (base16_decode(digest, DIGEST_LEN, fp, strlen(fp))<0) {
log_warn(LD_BUG, "Called with bad fingerprint in list: %s",
escaped(fp));
continue;
}
dir = router_get_trusteddirserver_by_digest(digest);
dir = router_get_fallback_dirserver_by_digest(digest);
if (dir)
download_status_failed(&dir->v2_ns_dl_status, status_code);
+3 -4
View File
@@ -1471,7 +1471,6 @@ dirserv_set_cached_networkstatus_v2(const char *networkstatus,
time_t published)
{
cached_dir_t *d, *old_d;
smartlist_t *trusted_dirs;
if (!cached_v2_networkstatus)
cached_v2_networkstatus = digestmap_new();
@@ -1494,9 +1493,9 @@ dirserv_set_cached_networkstatus_v2(const char *networkstatus,
}
/* Now purge old entries. */
trusted_dirs = router_get_trusted_dir_servers();
if (digestmap_size(cached_v2_networkstatus) >
smartlist_len(trusted_dirs) + MAX_UNTRUSTED_NETWORKSTATUSES) {
get_n_authorities(V2_DIRINFO) + MAX_UNTRUSTED_NETWORKSTATUSES) {
/* We need to remove the oldest untrusted networkstatus. */
const char *oldest = NULL;
time_t oldest_published = TIME_MAX;
@@ -3127,7 +3126,7 @@ dirserv_get_networkstatus_v2_fingerprints(smartlist_t *result,
}
} else {
SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
trusted_dir_server_t *, ds,
dir_server_t *, ds,
if (ds->type & V2_DIRINFO)
smartlist_add(result, tor_memdup(ds->digest, DIGEST_LEN)));
}
+3 -3
View File
@@ -2787,7 +2787,7 @@ dirvote_fetch_missing_votes(void)
char *resource;
SMARTLIST_FOREACH_BEGIN(router_get_trusted_dir_servers(),
trusted_dir_server_t *, ds) {
dir_server_t *, ds) {
if (!(ds->type & V3_DIRINFO))
continue;
if (!dirvote_get_vote(ds->v3_identity_digest,
@@ -2905,7 +2905,7 @@ list_v3_auth_ids(void)
smartlist_t *known_v3_keys = smartlist_new();
char *keys;
SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
trusted_dir_server_t *, ds,
dir_server_t *, ds,
if ((ds->type & V3_DIRINFO) &&
!tor_digest_is_zero(ds->v3_identity_digest))
smartlist_add(known_v3_keys,
@@ -2926,7 +2926,7 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out)
{
networkstatus_t *vote;
networkstatus_voter_info_t *vi;
trusted_dir_server_t *ds;
dir_server_t *ds;
pending_vote_t *pending_vote = NULL;
const char *end_of_vote = NULL;
int any_failed = 0;
+6 -30
View File
@@ -219,8 +219,6 @@ router_reload_consensus_networkstatus(void)
{
char *filename;
char *s;
struct stat st;
const or_options_t *options = get_options();
const unsigned int flags = NSSET_FROM_CACHE | NSSET_DONT_DOWNLOAD_CERTS;
int flav;
@@ -263,25 +261,6 @@ router_reload_consensus_networkstatus(void)
tor_free(filename);
}
if (!current_consensus ||
(stat(options->FallbackNetworkstatusFile, &st)==0 &&
st.st_mtime > current_consensus->valid_after)) {
s = read_file_to_str(options->FallbackNetworkstatusFile,
RFTS_IGNORE_MISSING, NULL);
if (s) {
if (networkstatus_set_current_consensus(s, "ns",
flags|NSSET_ACCEPT_OBSOLETE)) {
log_info(LD_FS, "Couldn't load consensus networkstatus from \"%s\"",
options->FallbackNetworkstatusFile);
} else {
log_notice(LD_FS,
"Loaded fallback consensus networkstatus from \"%s\"",
options->FallbackNetworkstatusFile);
}
tor_free(s);
}
}
if (!current_consensus) {
if (!named_server_map)
named_server_map = strmap_new();
@@ -565,7 +544,7 @@ networkstatus_check_consensus_signature(networkstatus_t *consensus,
/* Now see whether we're missing any voters entirely. */
SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
trusted_dir_server_t *, ds,
dir_server_t *, ds,
{
if ((ds->type & V3_DIRINFO) &&
!networkstatus_get_voter_by_id(consensus, ds->v3_identity_digest))
@@ -597,7 +576,7 @@ networkstatus_check_consensus_signature(networkstatus_t *consensus,
voter->contact?voter->contact:"n/a",
hex_str(voter->identity_digest, DIGEST_LEN));
});
SMARTLIST_FOREACH(missing_authorities, trusted_dir_server_t *, ds,
SMARTLIST_FOREACH(missing_authorities, dir_server_t *, ds,
{
log(severity, LD_DIR, "Consensus does not include configured "
"authority '%s' at %s:%d (identity %s)",
@@ -739,7 +718,7 @@ router_set_networkstatus_v2(const char *s, time_t arrived_at,
int i, found;
time_t now;
int skewed = 0;
trusted_dir_server_t *trusted_dir = NULL;
dir_server_t *trusted_dir = NULL;
const char *source_desc = NULL;
char fp[HEX_DIGEST_LEN+1];
char published[ISO_TIME_LEN+1];
@@ -1144,7 +1123,7 @@ update_v2_networkstatus_cache_downloads(time_t now)
if (authority) {
/* An authority launches a separate connection for everybody. */
SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, trusted_dir_server_t *, ds)
SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, dir_server_t *, ds)
{
char resource[HEX_DIGEST_LEN+6]; /* fp/hexdigit.z\0 */
tor_addr_t addr;
@@ -1674,9 +1653,6 @@ networkstatus_set_current_consensus(const char *consensus,
if (from_cache && !accept_obsolete &&
c->valid_until < now-OLD_ROUTER_DESC_MAX_AGE) {
/* XXXX If we try to make fallbackconsensus work again, we should
* consider taking this out. Until then, believing obsolete consensuses
* is causing more harm than good. See also bug 887. */
log_info(LD_DIR, "Loaded an expired consensus. Discarding.");
goto done;
}
@@ -2042,7 +2018,7 @@ void
routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
int reset_failures)
{
trusted_dir_server_t *ds;
dir_server_t *ds;
const or_options_t *options = get_options();
int authdir = authdir_mode_v2(options) || authdir_mode_v3(options);
networkstatus_t *ns = current_consensus;
@@ -2062,7 +2038,7 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
/* We have a routerstatus for this router. */
const char *digest = router->cache_info.identity_digest;
ds = router_get_trusteddirserver_by_digest(digest);
ds = router_get_fallback_dirserver_by_digest(digest);
/* Is it the same descriptor, or only the same identity? */
if (tor_memeq(router->cache_info.signed_descriptor_digest,
+6 -1
View File
@@ -1167,8 +1167,13 @@ router_set_status(const char *digest, int up)
node_t *node;
tor_assert(digest);
SMARTLIST_FOREACH(router_get_fallback_dir_servers(),
dir_server_t *, d,
if (tor_memeq(d->digest, digest, DIGEST_LEN))
d->is_running = up);
SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
trusted_dir_server_t *, d,
dir_server_t *, d,
if (tor_memeq(d->digest, digest, DIGEST_LEN))
d->is_running = up);
+17 -8
View File
@@ -2517,6 +2517,8 @@ typedef enum {
MICRODESC_DIRINFO=1 << 6,
} dirinfo_type_t;
#define ALL_DIRINFO ((dirinfo_type_t)((1<<7)-1))
#define CRYPT_PATH_MAGIC 0x70127012u
/** Holds accounting information for a single step in the layered encryption
@@ -3439,7 +3441,14 @@ typedef struct {
/** List of configuration lines for replacement directory authorities.
* If you just want to replace one class of authority at a time,
* use the "Alternate*Authority" options below instead. */
config_line_t *DirServers;
config_line_t *DirAuthorities;
/** List of fallback directory servers */
config_line_t *FallbackDir;
/** Weight to apply to all directory authority rates if considering them
* along with fallbackdirs */
double DirAuthorityFallbackRate;
/** If set, use these main (currently v3) directory authorities and
* not the default ones. */
@@ -3708,10 +3717,6 @@ typedef struct {
* of certain configuration options. */
int TestingTorNetwork;
/** File to check for a consensus networkstatus, if we don't have one
* cached. */
char *FallbackNetworkstatusFile;
/** If true, and we have GeoIP data, and we're a bridge, keep a per-country
* count of how many client addresses have contacted us so that we can help
* the bridge authority guess which countries have blocked access to us. */
@@ -4501,19 +4506,23 @@ typedef struct rend_cache_entry_t {
/********************************* routerlist.c ***************************/
/** Represents information about a single trusted directory server. */
typedef struct trusted_dir_server_t {
/** Represents information about a single trusted or fallback directory
* server. */
typedef struct dir_server_t {
char *description;
char *nickname;
char *address; /**< Hostname. */
uint32_t addr; /**< IPv4 address. */
uint16_t dir_port; /**< Directory port. */
uint16_t or_port; /**< OR port: Used for tunneling connections. */
double weight; /** Weight used when selecting this node at random */
char digest[DIGEST_LEN]; /**< Digest of identity key. */
char v3_identity_digest[DIGEST_LEN]; /**< Digest of v3 (authority only,
* high-security) identity key. */
unsigned int is_running:1; /**< True iff we think this server is running. */
unsigned int is_authority:1; /**< True iff this is a directory authority
* of some kind. */
/** True iff this server has accepted the most recent server descriptor
* we tried to upload to it. */
@@ -4532,7 +4541,7 @@ typedef struct trusted_dir_server_t {
* as a routerstatus_t. Not updated by the
* router-status management code!
**/
} trusted_dir_server_t;
} dir_server_t;
#define ROUTER_REQUIRED_MIN_BANDWIDTH (20*1024)
+4 -3
View File
@@ -517,7 +517,7 @@ init_keys(void)
const or_options_t *options = get_options();
dirinfo_type_t type;
time_t now = time(NULL);
trusted_dir_server_t *ds;
dir_server_t *ds;
int v3_digest_set = 0;
authority_cert_t *cert = NULL;
@@ -732,17 +732,18 @@ init_keys(void)
ds = router_get_trusteddirserver_by_digest(digest);
if (!ds) {
ds = add_trusted_dir_server(options->Nickname, NULL,
ds = trusted_dir_server_new(options->Nickname, NULL,
router_get_advertised_dir_port(options, 0),
router_get_advertised_or_port(options),
digest,
v3_digest,
type);
type, 0.0);
if (!ds) {
log_err(LD_GENERAL,"We want to be a directory authority, but we "
"couldn't add ourselves to the authority list. Failing.");
return -1;
}
dir_server_add(ds);
}
if (ds->type != type) {
log_warn(LD_DIR, "Configured authority type does not match authority "
+249 -93
View File
@@ -45,11 +45,15 @@
static const routerstatus_t *router_pick_directory_server_impl(
dirinfo_type_t auth, int flags);
static const routerstatus_t *router_pick_trusteddirserver_impl(
dirinfo_type_t auth, int flags, int *n_busy_out);
static void mark_all_trusteddirservers_up(void);
const smartlist_t *sourcelist, dirinfo_type_t auth,
int flags, int *n_busy_out);
static const routerstatus_t *router_pick_dirserver_generic(
smartlist_t *sourcelist,
dirinfo_type_t type, int flags);
static void mark_all_dirservers_up(smartlist_t *server_list);
static int router_nickname_matches(const routerinfo_t *router,
const char *nickname);
static void trusted_dir_server_free(trusted_dir_server_t *ds);
static void dir_server_free(dir_server_t *ds);
static int signed_desc_digest_is_recognized(signed_descriptor_t *desc);
static const char *signed_descriptor_get_body_impl(
const signed_descriptor_t *desc,
@@ -72,9 +76,12 @@ DECLARE_TYPED_DIGESTMAP_FNS(eimap_, digest_ei_map_t, extrainfo_t)
/****************************************************************************/
/** Global list of a trusted_dir_server_t object for each trusted directory
* server. */
/** Global list of a dir_server_t object for each directory
* authority. */
static smartlist_t *trusted_dir_servers = NULL;
/** Global list of dir_server_t objects for all directory authorities
* and all fallback directory servers. */
static smartlist_t *fallback_dir_servers = NULL;
/** List of for a given authority, and download status for latest certificate.
*/
@@ -119,7 +126,7 @@ get_n_authorities(dirinfo_type_t type)
int n = 0;
if (!trusted_dir_servers)
return 0;
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
SMARTLIST_FOREACH(trusted_dir_servers, dir_server_t *, ds,
if (ds->type & type)
++n);
return n;
@@ -190,7 +197,7 @@ int
trusted_dirs_load_certs_from_string(const char *contents, int from_store,
int flush)
{
trusted_dir_server_t *ds;
dir_server_t *ds;
const char *s, *eos;
int failure_code = 0;
@@ -530,7 +537,7 @@ authority_certs_fetch_missing(networkstatus_t *status, time_t now)
} SMARTLIST_FOREACH_END(sig);
} SMARTLIST_FOREACH_END(voter);
}
SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, trusted_dir_server_t *, ds) {
SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, dir_server_t *, ds) {
int found = 0;
if (!(ds->type & V3_DIRINFO))
continue;
@@ -914,11 +921,11 @@ router_reload_router_list(void)
return 0;
}
/** Return a smartlist containing a list of trusted_dir_server_t * for all
/** Return a smartlist containing a list of dir_server_t * for all
* known trusted dirservers. Callers must not modify the list or its
* contents.
*/
smartlist_t *
const smartlist_t *
router_get_trusted_dir_servers(void)
{
if (!trusted_dir_servers)
@@ -927,6 +934,15 @@ router_get_trusted_dir_servers(void)
return trusted_dir_servers;
}
const smartlist_t *
router_get_fallback_dir_servers(void)
{
if (!fallback_dir_servers)
fallback_dir_servers = smartlist_new();
return fallback_dir_servers;
}
/** Try to find a running dirserver that supports operations of <b>type</b>.
*
* If there are no running dirservers in our routerlist and the
@@ -960,7 +976,7 @@ router_pick_directory_server(dirinfo_type_t type, int flags)
"No reachable router entries for dirservers. "
"Trying them all again.");
/* mark all authdirservers as up again */
mark_all_trusteddirservers_up();
mark_all_dirservers_up(fallback_dir_servers);
/* try again */
choice = router_pick_directory_server_impl(type, flags);
return choice;
@@ -1007,16 +1023,16 @@ router_get_my_share_of_directory_requests(double *v2_share_out,
return 0;
}
/** Return the trusted_dir_server_t for the directory authority whose identity
/** Return the dir_server_t for the directory authority whose identity
* key hashes to <b>digest</b>, or NULL if no such authority is known.
*/
trusted_dir_server_t *
dir_server_t *
router_get_trusteddirserver_by_digest(const char *digest)
{
if (!trusted_dir_servers)
return NULL;
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
SMARTLIST_FOREACH(trusted_dir_servers, dir_server_t *, ds,
{
if (tor_memeq(ds->digest, digest, DIGEST_LEN))
return ds;
@@ -1025,17 +1041,35 @@ router_get_trusteddirserver_by_digest(const char *digest)
return NULL;
}
/** Return the trusted_dir_server_t for the directory authority whose
/** Return the dir_server_t for the fallback dirserver whose identity
* key hashes to <b>digest</b>, or NULL if no such authority is known.
*/
dir_server_t *
router_get_fallback_dirserver_by_digest(const char *digest)
{
if (!trusted_dir_servers)
return NULL;
SMARTLIST_FOREACH(trusted_dir_servers, dir_server_t *, ds,
{
if (tor_memeq(ds->digest, digest, DIGEST_LEN))
return ds;
});
return NULL;
}
/** Return the dir_server_t for the directory authority whose
* v3 identity key hashes to <b>digest</b>, or NULL if no such authority
* is known.
*/
trusted_dir_server_t *
dir_server_t *
trusteddirserver_get_by_v3_auth_digest(const char *digest)
{
if (!trusted_dir_servers)
return NULL;
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
SMARTLIST_FOREACH(trusted_dir_servers, dir_server_t *, ds,
{
if (tor_memeq(ds->v3_identity_digest, digest, DIGEST_LEN) &&
(ds->type & V3_DIRINFO))
@@ -1045,18 +1079,37 @@ trusteddirserver_get_by_v3_auth_digest(const char *digest)
return NULL;
}
/** Try to find a running trusted dirserver. Flags are as for
/** Try to find a running directory authority. Flags are as for
* router_pick_directory_server.
*/
const routerstatus_t *
router_pick_trusteddirserver(dirinfo_type_t type, int flags)
{
return router_pick_dirserver_generic(trusted_dir_servers, type, flags);
}
/** Try to find a running fallback directory Flags are as for
* router_pick_directory_server.
*/
const routerstatus_t *
router_pick_fallback_dirserver(dirinfo_type_t type, int flags)
{
return router_pick_dirserver_generic(fallback_dir_servers, type, flags);
}
/** Try to find a running fallback directory Flags are as for
* router_pick_directory_server.
*/
static const routerstatus_t *
router_pick_dirserver_generic(smartlist_t *sourcelist,
dirinfo_type_t type, int flags)
{
const routerstatus_t *choice;
int busy = 0;
if (get_options()->PreferTunneledDirConns)
flags |= PDS_PREFER_TUNNELED_DIR_CONNS_;
choice = router_pick_trusteddirserver_impl(type, flags, &busy);
choice = router_pick_trusteddirserver_impl(sourcelist, type, flags, &busy);
if (choice || !(flags & PDS_RETRY_IF_NO_SERVERS))
return choice;
if (busy) {
@@ -1069,9 +1122,9 @@ router_pick_trusteddirserver(dirinfo_type_t type, int flags)
}
log_info(LD_DIR,
"No trusted dirservers are reachable. Trying them all again.");
mark_all_trusteddirservers_up();
return router_pick_trusteddirserver_impl(type, flags, NULL);
"No dirservers are reachable. Trying them all again.");
mark_all_dirservers_up(sourcelist);
return router_pick_trusteddirserver_impl(sourcelist, type, flags, NULL);
}
/** How long do we avoid using a directory server after it's given us a 503? */
@@ -1196,11 +1249,36 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags)
return result ? result->rs : NULL;
}
/** Choose randomly from among the trusted dirservers that are up. Flags
* are as for router_pick_directory_server_impl().
/** Pick a random element from a list of dir_server_t, weighting by their
* <b>weight</b> field. */
static const dir_server_t *
dirserver_choose_by_weight(const smartlist_t *servers, double authority_weight)
{
int n = smartlist_len(servers);
int i;
u64_dbl_t *weights;
const dir_server_t *ds;
weights = tor_malloc(sizeof(u64_dbl_t) * n);
for (i = 0; i < n; ++i) {
ds = smartlist_get(servers, i);
weights[i].dbl = ds->weight;
if (ds->is_authority)
weights[i].dbl *= authority_weight;
}
scale_array_elements_to_u64(weights, n, NULL);
i = choose_array_element_by_weight(weights, n);
tor_free(weights);
return smartlist_get(servers, i);
}
/** Choose randomly from among the dir_server_ts in sourcelist that
* are up. Flags are as for router_pick_directory_server_impl().
*/
static const routerstatus_t *
router_pick_trusteddirserver_impl(dirinfo_type_t type, int flags,
router_pick_trusteddirserver_impl(const smartlist_t *sourcelist,
dirinfo_type_t type, int flags,
int *n_busy_out)
{
const or_options_t *options = get_options();
@@ -1214,10 +1292,13 @@ router_pick_trusteddirserver_impl(dirinfo_type_t type, int flags,
const int prefer_tunnel = (flags & PDS_PREFER_TUNNELED_DIR_CONNS_);
const int no_serverdesc_fetching =(flags & PDS_NO_EXISTING_SERVERDESC_FETCH);
const int no_microdesc_fetching =(flags & PDS_NO_EXISTING_MICRODESC_FETCH);
const double auth_weight = (sourcelist == fallback_dir_servers) ?
options->DirAuthorityFallbackRate : 1.0;
smartlist_t *pick_from;
int n_busy = 0;
int try_excluding = 1, n_excluded = 0;
if (!trusted_dir_servers)
if (!sourcelist)
return NULL;
retry_without_exclude:
@@ -1227,7 +1308,7 @@ router_pick_trusteddirserver_impl(dirinfo_type_t type, int flags,
overloaded_direct = smartlist_new();
overloaded_tunnel = smartlist_new();
SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, trusted_dir_server_t *, d)
SMARTLIST_FOREACH_BEGIN(sourcelist, const dir_server_t *, d)
{
int is_overloaded =
d->fake_status.last_dir_503_at + DIR_503_TIMEOUT > now;
@@ -1273,23 +1354,29 @@ router_pick_trusteddirserver_impl(dirinfo_type_t type, int flags,
d->or_port &&
(!fascistfirewall ||
fascist_firewall_allows_address_or(&addr, d->or_port)))
smartlist_add(is_overloaded ? overloaded_tunnel : tunnel,
&d->fake_status);
smartlist_add(is_overloaded ? overloaded_tunnel : tunnel, (void*)d);
else if (!fascistfirewall ||
fascist_firewall_allows_address_dir(&addr, d->dir_port))
smartlist_add(is_overloaded ? overloaded_direct : direct,
&d->fake_status);
smartlist_add(is_overloaded ? overloaded_direct : direct, (void*)d);
}
SMARTLIST_FOREACH_END(d);
if (smartlist_len(tunnel)) {
result = smartlist_choose(tunnel);
pick_from = tunnel;
} else if (smartlist_len(overloaded_tunnel)) {
result = smartlist_choose(overloaded_tunnel);
pick_from = overloaded_tunnel;
} else if (smartlist_len(direct)) {
result = smartlist_choose(direct);
pick_from = direct;
} else {
result = smartlist_choose(overloaded_direct);
pick_from = overloaded_direct;
}
{
const dir_server_t *selection =
dirserver_choose_by_weight(pick_from, auth_weight);
if (selection)
result = &selection->fake_status;
}
if (n_busy_out)
@@ -1311,19 +1398,19 @@ router_pick_trusteddirserver_impl(dirinfo_type_t type, int flags,
return result;
}
/** Go through and mark the authoritative dirservers as up. */
/** Mark as running every dir_server_t in <b>server_list</b>. */
static void
mark_all_trusteddirservers_up(void)
mark_all_dirservers_up(smartlist_t *server_list)
{
SMARTLIST_FOREACH(nodelist_get_list(), node_t *, node, {
if (router_digest_is_trusted_dir(node->identity))
node->is_running = 1;
});
if (trusted_dir_servers) {
SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, trusted_dir_server_t *, dir) {
if (server_list) {
SMARTLIST_FOREACH_BEGIN(server_list, dir_server_t *, dir) {
routerstatus_t *rs;
node_t *node;
dir->is_running = 1;
download_status_reset(&dir->v2_ns_dl_status);
node = node_get_mutable_by_id(dir->digest);
if (node)
node->is_running = 1;
rs = router_get_mutable_consensus_status_by_id(dir->digest);
if (rs) {
rs->last_dir_503_at = 0;
@@ -1348,7 +1435,7 @@ routers_have_same_or_addrs(const routerinfo_t *r1, const routerinfo_t *r2)
void
router_reset_status_download_failures(void)
{
mark_all_trusteddirservers_up();
mark_all_dirservers_up(fallback_dir_servers);
}
/** Given a <b>router</b>, add every node_t in its family (including the
@@ -2185,7 +2272,7 @@ router_digest_is_trusted_dir_type(const char *digest, dirinfo_type_t type)
return 0;
if (authdir_mode(get_options()) && router_digest_is_me(digest))
return 1;
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ent,
SMARTLIST_FOREACH(trusted_dir_servers, dir_server_t *, ent,
if (tor_memeq(digest, ent->digest, DIGEST_LEN)) {
return (!type) || ((type & ent->type) != 0);
});
@@ -2199,7 +2286,7 @@ router_addr_is_trusted_dir(uint32_t addr)
{
if (!trusted_dir_servers)
return 0;
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ent,
SMARTLIST_FOREACH(trusted_dir_servers, dir_server_t *, ent,
if (ent->addr == addr)
return 1;
);
@@ -2910,12 +2997,10 @@ routerlist_free_all(void)
smartlist_free(warned_nicknames);
warned_nicknames = NULL;
}
if (trusted_dir_servers) {
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
trusted_dir_server_free(ds));
smartlist_free(trusted_dir_servers);
trusted_dir_servers = NULL;
}
clear_dir_servers();
smartlist_free(trusted_dir_servers);
smartlist_free(fallback_dir_servers);
trusted_dir_servers = fallback_dir_servers = NULL;
if (trusted_dir_certs) {
DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) {
SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert,
@@ -3722,47 +3807,47 @@ router_exit_policy_rejects_all(const routerinfo_t *router)
return router->policy_is_reject_star;
}
/** Add to the list of authoritative directory servers one at
* <b>address</b>:<b>port</b>, with identity key <b>digest</b>. If
* <b>address</b> is NULL, add ourself. Return the new trusted directory
* server entry on success or NULL if we couldn't add it. */
trusted_dir_server_t *
add_trusted_dir_server(const char *nickname, const char *address,
uint16_t dir_port, uint16_t or_port,
const char *digest, const char *v3_auth_digest,
dirinfo_type_t type)
/** Create an directory server at <b>address</b>:<b>port</b>, with OR identity
* key <b>digest</b>. If <b>address</b> is NULL, add ourself. If
* <b>is_authority</b>, this is a directory authority. Return the new
* directory server entry on success or NULL on failure. */
static dir_server_t *
dir_server_new(int is_authority,
const char *nickname,
const tor_addr_t *addr,
const char *hostname,
uint16_t dir_port, uint16_t or_port,
const char *digest, const char *v3_auth_digest,
dirinfo_type_t type,
double weight)
{
trusted_dir_server_t *ent;
dir_server_t *ent;
uint32_t a;
char *hostname = NULL;
if (!trusted_dir_servers)
trusted_dir_servers = smartlist_new();
char *hostname_ = NULL;
if (!address) { /* The address is us; we should guess. */
if (resolve_my_address(LOG_WARN, get_options(), &a, &hostname) < 0) {
log_warn(LD_CONFIG,
"Couldn't find a suitable address when adding ourself as a "
"trusted directory server.");
return NULL;
}
} else {
if (tor_lookup_hostname(address, &a)) {
log_warn(LD_CONFIG,
"Unable to lookup address for directory server at '%s'",
address);
return NULL;
}
hostname = tor_strdup(address);
}
if (weight < 0)
return NULL;
ent = tor_malloc_zero(sizeof(trusted_dir_server_t));
if (tor_addr_family(addr) == AF_INET)
a = tor_addr_to_ipv4h(addr);
else
return NULL; /*XXXX Support IPv6 */
if (!hostname)
hostname_ = tor_dup_addr(addr);
else
hostname_ = tor_strdup(hostname);
ent = tor_malloc_zero(sizeof(dir_server_t));
ent->nickname = nickname ? tor_strdup(nickname) : NULL;
ent->address = hostname;
ent->address = hostname_;
ent->addr = a;
ent->dir_port = dir_port;
ent->or_port = or_port;
ent->is_running = 1;
ent->is_authority = is_authority;
ent->type = type;
ent->weight = weight;
memcpy(ent->digest, digest, DIGEST_LEN);
if (v3_auth_digest && (type & V3_DIRINFO))
memcpy(ent->v3_identity_digest, v3_auth_digest, DIGEST_LEN);
@@ -3784,11 +3869,77 @@ add_trusted_dir_server(const char *nickname, const char *address,
ent->fake_status.dir_port = ent->dir_port;
ent->fake_status.or_port = ent->or_port;
smartlist_add(trusted_dir_servers, ent);
router_dir_info_changed();
return ent;
}
/** Create an authoritative directory server at
* <b>address</b>:<b>port</b>, with identity key <b>digest</b>. If
* <b>address</b> is NULL, add ourself. Return the new trusted directory
* server entry on success or NULL if we couldn't add it. */
dir_server_t *
trusted_dir_server_new(const char *nickname, const char *address,
uint16_t dir_port, uint16_t or_port,
const char *digest, const char *v3_auth_digest,
dirinfo_type_t type, double weight)
{
uint32_t a;
tor_addr_t addr;
char *hostname=NULL;
dir_server_t *result;
if (!address) { /* The address is us; we should guess. */
if (resolve_my_address(LOG_WARN, get_options(), &a, &hostname) < 0) {
log_warn(LD_CONFIG,
"Couldn't find a suitable address when adding ourself as a "
"trusted directory server.");
return NULL;
}
} else {
if (tor_lookup_hostname(address, &a)) {
log_warn(LD_CONFIG,
"Unable to lookup address for directory server at '%s'",
address);
return NULL;
}
hostname = tor_strdup(address);
}
tor_addr_from_ipv4h(&addr, a);
result = dir_server_new(1, nickname, &addr, hostname,
dir_port, or_port, digest,
v3_auth_digest, type, weight);
tor_free(hostname);
return result;
}
/** Return a new dir_server_t for a fallback directory server at
* <b>addr</b>:<b>or_port</b>/<b>dir_port</b>, with identity key digest
* <b>id_digest</b> */
dir_server_t *
fallback_dir_server_new(const tor_addr_t *addr,
uint16_t dir_port, uint16_t or_port,
const char *id_digest, double weight)
{
return dir_server_new(0, NULL, addr, NULL, dir_port, or_port, id_digest,
NULL, ALL_DIRINFO, weight);
}
/** Add a directory server to the global list(s). */
void
dir_server_add(dir_server_t *ent)
{
if (!trusted_dir_servers)
trusted_dir_servers = smartlist_new();
if (!fallback_dir_servers)
fallback_dir_servers = smartlist_new();
if (ent->is_authority)
smartlist_add(trusted_dir_servers, ent);
smartlist_add(fallback_dir_servers, ent);
router_dir_info_changed();
}
/** Free storage held in <b>cert</b>. */
void
authority_cert_free(authority_cert_t *cert)
@@ -3805,7 +3956,7 @@ authority_cert_free(authority_cert_t *cert)
/** Free storage held in <b>ds</b>. */
static void
trusted_dir_server_free(trusted_dir_server_t *ds)
dir_server_free(dir_server_t *ds)
{
if (!ds)
return;
@@ -3816,13 +3967,18 @@ trusted_dir_server_free(trusted_dir_server_t *ds)
tor_free(ds);
}
/** Remove all members from the list of trusted dir servers. */
/** Remove all members from the list of dir servers. */
void
clear_trusted_dir_servers(void)
clear_dir_servers(void)
{
if (fallback_dir_servers) {
SMARTLIST_FOREACH(fallback_dir_servers, dir_server_t *, ent,
dir_server_free(ent));
smartlist_clear(fallback_dir_servers);
} else {
fallback_dir_servers = smartlist_new();
}
if (trusted_dir_servers) {
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ent,
trusted_dir_server_free(ent));
smartlist_clear(trusted_dir_servers);
} else {
trusted_dir_servers = smartlist_new();
@@ -4128,7 +4284,7 @@ update_router_descriptor_cache_downloads_v2(time_t now)
*/
n_download = 0;
SMARTLIST_FOREACH_BEGIN(networkstatus_v2_list, networkstatus_v2_t *, ns) {
trusted_dir_server_t *ds;
dir_server_t *ds;
smartlist_t *dl;
dl = downloadable[ns_sl_idx] = smartlist_new();
download_from[ns_sl_idx] = smartlist_new();
@@ -4203,7 +4359,7 @@ update_router_descriptor_cache_downloads_v2(time_t now)
/* Now, we can actually launch our requests. */
for (i=0; i<n; ++i) {
networkstatus_v2_t *ns = smartlist_get(networkstatus_v2_list, i);
trusted_dir_server_t *ds =
dir_server_t *ds =
router_get_trusteddirserver_by_digest(ns->identity_digest);
smartlist_t *dl = download_from[i];
int pds_flags = PDS_RETRY_IF_NO_SERVERS;
@@ -4256,7 +4412,7 @@ update_consensus_router_descriptor_downloads(time_t now, int is_vote,
if (is_vote) {
/* where's it from, so we know whom to ask for descriptors */
trusted_dir_server_t *ds;
dir_server_t *ds;
networkstatus_voter_info_t *voter = smartlist_get(consensus->voters, 0);
tor_assert(voter);
ds = trusteddirserver_get_by_v3_auth_digest(voter->identity_digest);
+19 -9
View File
@@ -25,14 +25,19 @@ void authority_cert_dl_failed(const char *id_digest, int status);
void authority_certs_fetch_missing(networkstatus_t *status, time_t now);
int router_reload_router_list(void);
int authority_cert_dl_looks_uncertain(const char *id_digest);
smartlist_t *router_get_trusted_dir_servers(void);
const smartlist_t *router_get_trusted_dir_servers(void);
const smartlist_t *router_get_fallback_dir_servers(void);
const routerstatus_t *router_pick_directory_server(dirinfo_type_t type,
int flags);
trusted_dir_server_t *router_get_trusteddirserver_by_digest(const char *d);
trusted_dir_server_t *trusteddirserver_get_by_v3_auth_digest(const char *d);
dir_server_t *router_get_trusteddirserver_by_digest(const char *d);
dir_server_t *router_get_fallback_dirserver_by_digest(
const char *digest);
dir_server_t *trusteddirserver_get_by_v3_auth_digest(const char *d);
const routerstatus_t *router_pick_trusteddirserver(dirinfo_type_t type,
int flags);
const routerstatus_t *router_pick_fallback_dirserver(dirinfo_type_t type,
int flags);
int router_get_my_share_of_directory_requests(double *v2_share_out,
double *v3_share_out);
void router_reset_status_download_failures(void);
@@ -127,13 +132,18 @@ void router_load_extrainfo_from_string(const char *s, const char *eos,
void routerlist_retry_directory_downloads(time_t now);
int router_exit_policy_rejects_all(const routerinfo_t *router);
trusted_dir_server_t *add_trusted_dir_server(const char *nickname,
const char *address,
uint16_t dir_port, uint16_t or_port,
const char *digest, const char *v3_auth_digest,
dirinfo_type_t type);
dir_server_t *trusted_dir_server_new(const char *nickname, const char *address,
uint16_t dir_port, uint16_t or_port,
const char *digest, const char *v3_auth_digest,
dirinfo_type_t type, double weight);
dir_server_t *fallback_dir_server_new(const tor_addr_t *addr,
uint16_t dir_port, uint16_t or_port,
const char *id_digest, double weight);
void dir_server_add(dir_server_t *ent);
void authority_cert_free(authority_cert_t *cert);
void clear_trusted_dir_servers(void);
void clear_dir_servers(void);
int any_trusted_dir_is_v1_authority(void);
void update_consensus_router_descriptor_downloads(time_t now, int is_vote,
networkstatus_t *consensus);