mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
Merge remote-tracking branch 'public/bug10758'
This commit is contained in:
commit
c6c87fb6d1
4
changes/bug10758
Normal file
4
changes/bug10758
Normal file
@ -0,0 +1,4 @@
|
||||
o Removed code
|
||||
- Remove all code that existed to support the v2 directory system:
|
||||
There are no longer any v2 directory authorities. Resolves
|
||||
bug 10758.
|
@ -215,7 +215,7 @@ static config_var_t option_vars_[] = {
|
||||
V(DisableAllSwap, BOOL, "0"),
|
||||
V(DisableDebuggerAttachment, BOOL, "1"),
|
||||
V(DisableIOCP, BOOL, "1"),
|
||||
V(DisableV2DirectoryInfo_, BOOL, "0"),
|
||||
OBSOLETE("DisableV2DirectoryInfo_"),
|
||||
V(DynamicDHGroups, BOOL, "0"),
|
||||
VPORT(DNSPort, LINELIST, NULL),
|
||||
V(DNSListenAddress, LINELIST, NULL),
|
||||
@ -248,7 +248,7 @@ static config_var_t option_vars_[] = {
|
||||
V(FetchServerDescriptors, BOOL, "1"),
|
||||
V(FetchHidServDescriptors, BOOL, "1"),
|
||||
V(FetchUselessDescriptors, BOOL, "0"),
|
||||
V(FetchV2Networkstatus, BOOL, "0"),
|
||||
OBSOLETE("FetchV2Networkstatus"),
|
||||
V(GeoIPExcludeUnknown, AUTOBOOL, "auto"),
|
||||
#ifdef _WIN32
|
||||
V(GeoIPFile, FILENAME, "<default>"),
|
||||
@ -419,7 +419,7 @@ static config_var_t option_vars_[] = {
|
||||
V(User, STRING, NULL),
|
||||
V(UserspaceIOCPBuffers, BOOL, "0"),
|
||||
VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
|
||||
VAR("V2AuthoritativeDirectory",BOOL, V2AuthoritativeDir, "0"),
|
||||
OBSOLETE("V2AuthoritativeDirectory"),
|
||||
VAR("V3AuthoritativeDirectory",BOOL, V3AuthoritativeDir, "0"),
|
||||
V(TestingV3AuthInitialVotingInterval, INTERVAL, "30 minutes"),
|
||||
V(TestingV3AuthInitialVoteDelay, INTERVAL, "5 minutes"),
|
||||
@ -982,7 +982,7 @@ consider_adding_dir_servers(const or_options_t *options,
|
||||
if (!options->AlternateBridgeAuthority)
|
||||
type |= BRIDGE_DIRINFO;
|
||||
if (!options->AlternateDirAuthority)
|
||||
type |= V1_DIRINFO | V2_DIRINFO | V3_DIRINFO | EXTRAINFO_DIRINFO |
|
||||
type |= V1_DIRINFO | V3_DIRINFO | EXTRAINFO_DIRINFO |
|
||||
MICRODESC_DIRINFO;
|
||||
if (!options->AlternateHSAuthority)
|
||||
type |= HIDSERV_DIRINFO;
|
||||
@ -1136,20 +1136,6 @@ options_act_reversible(const or_options_t *old_options, char **msg)
|
||||
/* No need to roll back, since you can't change the value. */
|
||||
}
|
||||
|
||||
if (directory_caches_v2_dir_info(options)) {
|
||||
char *fn = NULL;
|
||||
tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-status",
|
||||
options->DataDirectory);
|
||||
if (check_private_dir(fn, running_tor ? CPD_CREATE : CPD_CHECK,
|
||||
options->User) < 0) {
|
||||
tor_asprintf(msg,
|
||||
"Couldn't access/create private data directory \"%s\"", fn);
|
||||
tor_free(fn);
|
||||
goto done;
|
||||
}
|
||||
tor_free(fn);
|
||||
}
|
||||
|
||||
/* Bail out at this point if we're not going to be a client or server:
|
||||
* we don't run Tor itself. */
|
||||
if (!running_tor)
|
||||
@ -2378,9 +2364,9 @@ compute_publishserverdescriptor(or_options_t *options)
|
||||
if (options->BridgeRelay)
|
||||
*auth |= BRIDGE_DIRINFO;
|
||||
else
|
||||
*auth |= V2_DIRINFO | V3_DIRINFO;
|
||||
*auth |= V3_DIRINFO;
|
||||
else if (!strcasecmp(string, "v2"))
|
||||
*auth |= V2_DIRINFO;
|
||||
/* obsolete */;
|
||||
else if (!strcasecmp(string, "v3"))
|
||||
*auth |= V3_DIRINFO;
|
||||
else if (!strcasecmp(string, "bridge"))
|
||||
@ -2552,10 +2538,6 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
||||
REJECT("TokenBucketRefillInterval must be between 1 and 1000 inclusive.");
|
||||
}
|
||||
|
||||
if (options->DisableV2DirectoryInfo_ && ! authdir_mode(options)) {
|
||||
REJECT("DisableV2DirectoryInfo_ set, but we aren't an authority.");
|
||||
}
|
||||
|
||||
if (options->ExcludeExitNodes || options->ExcludeNodes) {
|
||||
options->ExcludeExitNodesUnion_ = routerset_new();
|
||||
routerset_union(options->ExcludeExitNodesUnion_,options->ExcludeExitNodes);
|
||||
@ -2613,7 +2595,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
||||
options->DownloadExtraInfo = 1;
|
||||
}
|
||||
if (!(options->BridgeAuthoritativeDir || options->HSAuthoritativeDir ||
|
||||
options->V1AuthoritativeDir || options->V2AuthoritativeDir ||
|
||||
options->V1AuthoritativeDir ||
|
||||
options->V3AuthoritativeDir))
|
||||
REJECT("AuthoritativeDir is set, but none of "
|
||||
"(Bridge/HS/V1/V2/V3)AuthoritativeDir is set.");
|
||||
@ -2826,7 +2808,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
||||
if ((options->BridgeRelay
|
||||
|| options->PublishServerDescriptor_ & BRIDGE_DIRINFO)
|
||||
&& (options->PublishServerDescriptor_
|
||||
& (V1_DIRINFO|V2_DIRINFO|V3_DIRINFO))) {
|
||||
& (V1_DIRINFO|V3_DIRINFO))) {
|
||||
REJECT("Bridges are not supposed to publish router descriptors to the "
|
||||
"directory authorities. Please correct your "
|
||||
"PublishServerDescriptor line.");
|
||||
@ -5037,8 +5019,8 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
|
||||
uint16_t dir_port = 0, or_port = 0;
|
||||
char digest[DIGEST_LEN];
|
||||
char v3_digest[DIGEST_LEN];
|
||||
dirinfo_type_t type = V2_DIRINFO;
|
||||
int is_not_hidserv_authority = 0, is_not_v2_authority = 0;
|
||||
dirinfo_type_t type = 0;
|
||||
int is_not_hidserv_authority = 0;
|
||||
double weight = 1.0;
|
||||
|
||||
items = smartlist_new();
|
||||
@ -5066,8 +5048,6 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
|
||||
is_not_hidserv_authority = 1;
|
||||
} else if (!strcasecmp(flag, "bridge")) {
|
||||
type |= BRIDGE_DIRINFO;
|
||||
} else if (!strcasecmp(flag, "no-v2")) {
|
||||
is_not_v2_authority = 1;
|
||||
} else if (!strcasecmpstart(flag, "orport=")) {
|
||||
int ok;
|
||||
char *portstring = flag + strlen("orport=");
|
||||
@ -5101,8 +5081,6 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type,
|
||||
}
|
||||
if (is_not_hidserv_authority)
|
||||
type &= ~HIDSERV_DIRINFO;
|
||||
if (is_not_v2_authority)
|
||||
type &= ~V2_DIRINFO;
|
||||
|
||||
if (smartlist_len(items) < 2) {
|
||||
log_warn(LD_CONFIG, "Too few arguments to DirAuthority line.");
|
||||
|
@ -1747,39 +1747,7 @@ getinfo_helper_dir(control_connection_t *control_conn,
|
||||
tor_free(url);
|
||||
smartlist_free(descs);
|
||||
} else if (!strcmpstart(question, "dir/status/")) {
|
||||
if (directory_permits_controller_requests(get_options())) {
|
||||
size_t len=0;
|
||||
char *cp;
|
||||
smartlist_t *status_list = smartlist_new();
|
||||
dirserv_get_networkstatus_v2(status_list,
|
||||
question+strlen("dir/status/"));
|
||||
SMARTLIST_FOREACH(status_list, cached_dir_t *, d, len += d->dir_len);
|
||||
cp = *answer = tor_malloc(len+1);
|
||||
SMARTLIST_FOREACH(status_list, cached_dir_t *, d, {
|
||||
memcpy(cp, d->dir, d->dir_len);
|
||||
cp += d->dir_len;
|
||||
});
|
||||
*cp = '\0';
|
||||
smartlist_free(status_list);
|
||||
} else {
|
||||
smartlist_t *fp_list = smartlist_new();
|
||||
smartlist_t *status_list = smartlist_new();
|
||||
dirserv_get_networkstatus_v2_fingerprints(
|
||||
fp_list, question+strlen("dir/status/"));
|
||||
SMARTLIST_FOREACH(fp_list, const char *, fp, {
|
||||
char *s;
|
||||
char *fname = networkstatus_get_cache_filename(fp);
|
||||
s = read_file_to_str(fname, 0, NULL);
|
||||
if (s)
|
||||
smartlist_add(status_list, s);
|
||||
tor_free(fname);
|
||||
});
|
||||
SMARTLIST_FOREACH(fp_list, char *, fp, tor_free(fp));
|
||||
smartlist_free(fp_list);
|
||||
*answer = smartlist_join_strings(status_list, "", 0, NULL);
|
||||
SMARTLIST_FOREACH(status_list, char *, s, tor_free(s));
|
||||
smartlist_free(status_list);
|
||||
}
|
||||
*answer = tor_strdup("");
|
||||
} else if (!strcmp(question, "dir/status-vote/current/consensus")) { /* v3 */
|
||||
if (directory_caches_dir_info(get_options())) {
|
||||
const cached_dir_t *consensus = dirserv_get_consensus("ns");
|
||||
|
@ -67,15 +67,11 @@ static int purpose_needs_anonymity(uint8_t dir_purpose,
|
||||
uint8_t router_purpose);
|
||||
static char *http_get_header(const char *headers, const char *which);
|
||||
static void http_set_address_origin(const char *headers, connection_t *conn);
|
||||
static void connection_dir_download_v2_networkstatus_failed(
|
||||
dir_connection_t *conn, int status_code);
|
||||
static void connection_dir_download_routerdesc_failed(dir_connection_t *conn);
|
||||
static void connection_dir_bridge_routerdesc_failed(dir_connection_t *conn);
|
||||
static void connection_dir_download_cert_failed(
|
||||
dir_connection_t *conn, int status_code);
|
||||
static void connection_dir_retry_bridges(smartlist_t *descs);
|
||||
static void dir_networkstatus_download_failed(smartlist_t *failed,
|
||||
int status_code);
|
||||
static void dir_routerdesc_download_failed(smartlist_t *failed,
|
||||
int status_code,
|
||||
int router_purpose,
|
||||
@ -135,7 +131,6 @@ purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose)
|
||||
if (dir_purpose == DIR_PURPOSE_UPLOAD_DIR ||
|
||||
dir_purpose == DIR_PURPOSE_UPLOAD_VOTE ||
|
||||
dir_purpose == DIR_PURPOSE_UPLOAD_SIGNATURES ||
|
||||
dir_purpose == DIR_PURPOSE_FETCH_V2_NETWORKSTATUS ||
|
||||
dir_purpose == DIR_PURPOSE_FETCH_STATUS_VOTE ||
|
||||
dir_purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES ||
|
||||
dir_purpose == DIR_PURPOSE_FETCH_CONSENSUS ||
|
||||
@ -156,8 +151,6 @@ authdir_type_to_string(dirinfo_type_t auth)
|
||||
smartlist_t *lst = smartlist_new();
|
||||
if (auth & V1_DIRINFO)
|
||||
smartlist_add(lst, (void*)"V1");
|
||||
if (auth & V2_DIRINFO)
|
||||
smartlist_add(lst, (void*)"V2");
|
||||
if (auth & V3_DIRINFO)
|
||||
smartlist_add(lst, (void*)"V3");
|
||||
if (auth & BRIDGE_DIRINFO)
|
||||
@ -189,8 +182,6 @@ dir_conn_purpose_to_string(int purpose)
|
||||
return "server vote upload";
|
||||
case DIR_PURPOSE_UPLOAD_SIGNATURES:
|
||||
return "consensus signature upload";
|
||||
case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS:
|
||||
return "network-status fetch";
|
||||
case DIR_PURPOSE_FETCH_SERVERDESC:
|
||||
return "server descriptor fetch";
|
||||
case DIR_PURPOSE_FETCH_EXTRAINFO:
|
||||
@ -263,8 +254,8 @@ directories_have_accepted_server_descriptor(void)
|
||||
* <b>router_purpose</b> describes the type of descriptor we're
|
||||
* publishing, if we're publishing a descriptor -- e.g. general or bridge.
|
||||
*
|
||||
* <b>type</b> specifies what sort of dir authorities (V1, V2,
|
||||
* HIDSERV, BRIDGE) we should upload to.
|
||||
* <b>type</b> specifies what sort of dir authorities (V1, V3,
|
||||
* HIDSERV, BRIDGE, etc) we should upload to.
|
||||
*
|
||||
* If <b>extrainfo_len</b> is nonzero, the first <b>payload_len</b> bytes of
|
||||
* <b>payload</b> hold a router descriptor, and the next <b>extrainfo_len</b>
|
||||
@ -350,8 +341,7 @@ should_use_directory_guards(const or_options_t *options)
|
||||
/* If we're configured to fetch directory info aggressively or of a
|
||||
* nonstandard type, don't use directory guards. */
|
||||
if (options->DownloadExtraInfo || options->FetchDirInfoEarly ||
|
||||
options->FetchDirInfoExtraEarly || options->FetchUselessDescriptors ||
|
||||
options->FetchV2Networkstatus)
|
||||
options->FetchDirInfoExtraEarly || options->FetchUselessDescriptors)
|
||||
return 0;
|
||||
if (! options->PreferTunneledDirConns)
|
||||
return 0;
|
||||
@ -414,11 +404,6 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
|
||||
(router_purpose == ROUTER_PURPOSE_BRIDGE ? BRIDGE_DIRINFO :
|
||||
V3_DIRINFO);
|
||||
break;
|
||||
case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS:
|
||||
type = V2_DIRINFO;
|
||||
prefer_authority = 1; /* Only v2 authorities have these anyway. */
|
||||
require_authority = 1; /* Don't fallback to asking a non-authority */
|
||||
break;
|
||||
case DIR_PURPOSE_FETCH_SERVERDESC:
|
||||
type = (router_purpose == ROUTER_PURPOSE_BRIDGE ? BRIDGE_DIRINFO :
|
||||
V3_DIRINFO);
|
||||
@ -719,11 +704,7 @@ connection_dir_request_failed(dir_connection_t *conn)
|
||||
}
|
||||
if (!entry_list_is_constrained(get_options()))
|
||||
router_set_status(conn->identity_digest, 0); /* don't try him again */
|
||||
if (conn->base_.purpose == DIR_PURPOSE_FETCH_V2_NETWORKSTATUS) {
|
||||
log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
|
||||
conn->base_.address);
|
||||
connection_dir_download_v2_networkstatus_failed(conn, -1);
|
||||
} else if (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
|
||||
if (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
|
||||
conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO) {
|
||||
log_info(LD_DIR, "Giving up on serverdesc/extrainfo fetch from "
|
||||
"directory server at '%s'; retrying",
|
||||
@ -752,43 +733,6 @@ connection_dir_request_failed(dir_connection_t *conn)
|
||||
}
|
||||
}
|
||||
|
||||
/** Called when an attempt to download one or more network status
|
||||
* documents on connection <b>conn</b> failed. Decide whether to
|
||||
* retry the fetch now, later, or never.
|
||||
*/
|
||||
static void
|
||||
connection_dir_download_v2_networkstatus_failed(dir_connection_t *conn,
|
||||
int status_code)
|
||||
{
|
||||
if (!conn->requested_resource) {
|
||||
/* We never reached directory_send_command, which means that we never
|
||||
* opened a network connection. Either we're out of sockets, or the
|
||||
* network is down. Either way, retrying would be pointless. */
|
||||
return;
|
||||
}
|
||||
if (!strcmpstart(conn->requested_resource, "all")) {
|
||||
/* 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. */
|
||||
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 */);
|
||||
} else if (!strcmpstart(conn->requested_resource, "fp/")) {
|
||||
/* We were trying to download by fingerprint; mark them all as having
|
||||
* failed, and possibly retry them later.*/
|
||||
smartlist_t *failed = smartlist_new();
|
||||
dir_split_resource_into_fingerprints(conn->requested_resource+3,
|
||||
failed, NULL, 0);
|
||||
if (smartlist_len(failed)) {
|
||||
dir_networkstatus_download_failed(failed, status_code);
|
||||
SMARTLIST_FOREACH(failed, char *, cp, tor_free(cp));
|
||||
}
|
||||
smartlist_free(failed);
|
||||
}
|
||||
}
|
||||
|
||||
/** Helper: Attempt to fetch directly the descriptors of each bridge
|
||||
* listed in <b>failed</b>.
|
||||
*/
|
||||
@ -1250,11 +1194,6 @@ directory_send_command(dir_connection_t *conn,
|
||||
}
|
||||
|
||||
switch (purpose) {
|
||||
case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS:
|
||||
tor_assert(resource);
|
||||
httpcommand = "GET";
|
||||
tor_asprintf(&url, "/tor/status/%s", resource);
|
||||
break;
|
||||
case DIR_PURPOSE_FETCH_CONSENSUS:
|
||||
/* resource is optional. If present, it's a flavor name */
|
||||
tor_assert(!payload);
|
||||
@ -1824,77 +1763,6 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
|
||||
}
|
||||
}
|
||||
|
||||
if (conn->base_.purpose == DIR_PURPOSE_FETCH_V2_NETWORKSTATUS) {
|
||||
smartlist_t *which = NULL;
|
||||
v2_networkstatus_source_t source;
|
||||
char *cp;
|
||||
log_info(LD_DIR,"Received networkstatus objects (size %d) from server "
|
||||
"'%s:%d'", (int)body_len, conn->base_.address, conn->base_.port);
|
||||
if (status_code != 200) {
|
||||
static ratelim_t warning_limit = RATELIM_INIT(3600);
|
||||
char *m;
|
||||
if ((m = rate_limit_log(&warning_limit, now))) {
|
||||
log_warn(LD_DIR,
|
||||
"Received http status code %d (%s) from server "
|
||||
"'%s:%d' while fetching \"/tor/status/%s\". "
|
||||
"I'll try again soon.%s",
|
||||
status_code, escaped(reason), conn->base_.address,
|
||||
conn->base_.port, conn->requested_resource, m);
|
||||
tor_free(m);
|
||||
}
|
||||
tor_free(body); tor_free(headers); tor_free(reason);
|
||||
connection_dir_download_v2_networkstatus_failed(conn, status_code);
|
||||
return -1;
|
||||
}
|
||||
if (conn->requested_resource &&
|
||||
!strcmpstart(conn->requested_resource,"fp/")) {
|
||||
source = NS_FROM_DIR_BY_FP;
|
||||
which = smartlist_new();
|
||||
dir_split_resource_into_fingerprints(conn->requested_resource+3,
|
||||
which, NULL, 0);
|
||||
} else if (conn->requested_resource &&
|
||||
!strcmpstart(conn->requested_resource, "all")) {
|
||||
source = NS_FROM_DIR_ALL;
|
||||
which = smartlist_new();
|
||||
SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
|
||||
dir_server_t *, ds,
|
||||
{
|
||||
char *hex = tor_malloc(HEX_DIGEST_LEN+1);
|
||||
base16_encode(hex, HEX_DIGEST_LEN+1, ds->digest, DIGEST_LEN);
|
||||
smartlist_add(which, hex);
|
||||
});
|
||||
} else {
|
||||
/* XXXX Can we even end up here? -- weasel*/
|
||||
source = NS_FROM_DIR_BY_FP;
|
||||
log_warn(LD_BUG, "We received a networkstatus but we didn't ask "
|
||||
"for it by fp, nor did we ask for all.");
|
||||
}
|
||||
cp = body;
|
||||
while (*cp) {
|
||||
char *next = strstr(cp, "\nnetwork-status-version");
|
||||
if (next)
|
||||
next[1] = '\0';
|
||||
/* learn from it, and then remove it from 'which' */
|
||||
if (router_set_networkstatus_v2(cp, now, source, which)<0)
|
||||
break;
|
||||
if (next) {
|
||||
next[1] = 'n';
|
||||
cp = next+1;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
/* launches router downloads as needed */
|
||||
routers_update_all_from_networkstatus(now, 2);
|
||||
directory_info_has_arrived(now, 0);
|
||||
if (which) {
|
||||
if (smartlist_len(which)) {
|
||||
dir_networkstatus_download_failed(which, status_code);
|
||||
}
|
||||
SMARTLIST_FOREACH(which, char *, s, tor_free(s));
|
||||
smartlist_free(which);
|
||||
}
|
||||
}
|
||||
|
||||
if (conn->base_.purpose == DIR_PURPOSE_FETCH_CONSENSUS) {
|
||||
int r;
|
||||
const char *flavname = conn->requested_resource;
|
||||
@ -2563,7 +2431,6 @@ note_client_request(int purpose, int compressed, size_t bytes)
|
||||
char *key;
|
||||
const char *kind = NULL;
|
||||
switch (purpose) {
|
||||
case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS: kind = "dl/status"; break;
|
||||
case DIR_PURPOSE_FETCH_CONSENSUS: kind = "dl/consensus"; break;
|
||||
case DIR_PURPOSE_FETCH_CERTIFICATE: kind = "dl/cert"; break;
|
||||
case DIR_PURPOSE_FETCH_STATUS_VOTE: kind = "dl/vote"; break;
|
||||
@ -2857,40 +2724,13 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!strcmpstart(url,"/tor/status/")
|
||||
|| !strcmpstart(url, "/tor/status-vote/current/consensus")) {
|
||||
/* v2 or v3 network status fetch. */
|
||||
if (!strcmpstart(url, "/tor/status-vote/current/consensus")) {
|
||||
/* v3 network status fetch. */
|
||||
smartlist_t *dir_fps = smartlist_new();
|
||||
int is_v3 = !strcmpstart(url, "/tor/status-vote");
|
||||
const char *request_type = NULL;
|
||||
const char *key = url + strlen("/tor/status/");
|
||||
long lifetime = NETWORKSTATUS_CACHE_LIFETIME;
|
||||
|
||||
if (options->DisableV2DirectoryInfo_ && !is_v3) {
|
||||
static ratelim_t reject_v2_ratelim = RATELIM_INIT(1800);
|
||||
char *m;
|
||||
write_http_status_line(conn, 404, "Not found");
|
||||
smartlist_free(dir_fps);
|
||||
geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND);
|
||||
if ((m = rate_limit_log(&reject_v2_ratelim, approx_time()))) {
|
||||
log_notice(LD_DIR, "Rejected a v2 networkstatus request.%s", m);
|
||||
tor_free(m);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!is_v3) {
|
||||
dirserv_get_networkstatus_v2_fingerprints(dir_fps, key);
|
||||
if (!strcmpstart(key, "fp/"))
|
||||
request_type = compressed?"/tor/status/fp.z":"/tor/status/fp";
|
||||
else if (!strcmpstart(key, "authority"))
|
||||
request_type = compressed?"/tor/status/authority.z":
|
||||
"/tor/status/authority";
|
||||
else if (!strcmpstart(key, "all"))
|
||||
request_type = compressed?"/tor/status/all.z":"/tor/status/all";
|
||||
else
|
||||
request_type = "/tor/status/?";
|
||||
} else {
|
||||
if (1) {
|
||||
networkstatus_t *v;
|
||||
time_t now = time(NULL);
|
||||
const char *want_fps = NULL;
|
||||
@ -2943,8 +2783,7 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
|
||||
if (!smartlist_len(dir_fps)) { /* we failed to create/cache cp */
|
||||
write_http_status_line(conn, 503, "Network status object unavailable");
|
||||
smartlist_free(dir_fps);
|
||||
if (is_v3)
|
||||
geoip_note_ns_response(GEOIP_REJECT_UNAVAILABLE);
|
||||
geoip_note_ns_response(GEOIP_REJECT_UNAVAILABLE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -2952,15 +2791,13 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
|
||||
write_http_status_line(conn, 404, "Not found");
|
||||
SMARTLIST_FOREACH(dir_fps, char *, cp, tor_free(cp));
|
||||
smartlist_free(dir_fps);
|
||||
if (is_v3)
|
||||
geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND);
|
||||
geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND);
|
||||
goto done;
|
||||
} else if (!smartlist_len(dir_fps)) {
|
||||
write_http_status_line(conn, 304, "Not modified");
|
||||
SMARTLIST_FOREACH(dir_fps, char *, cp, tor_free(cp));
|
||||
smartlist_free(dir_fps);
|
||||
if (is_v3)
|
||||
geoip_note_ns_response(GEOIP_REJECT_NOT_MODIFIED);
|
||||
geoip_note_ns_response(GEOIP_REJECT_NOT_MODIFIED);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -2972,12 +2809,12 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
|
||||
write_http_status_line(conn, 503, "Directory busy, try again later");
|
||||
SMARTLIST_FOREACH(dir_fps, char *, fp, tor_free(fp));
|
||||
smartlist_free(dir_fps);
|
||||
if (is_v3)
|
||||
geoip_note_ns_response(GEOIP_REJECT_BUSY);
|
||||
|
||||
geoip_note_ns_response(GEOIP_REJECT_BUSY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (is_v3) {
|
||||
if (1) {
|
||||
struct in_addr in;
|
||||
tor_addr_t addr;
|
||||
if (tor_inet_aton((TO_CONN(conn))->address, &in)) {
|
||||
@ -3718,29 +3555,6 @@ connection_dir_finished_connecting(dir_connection_t *conn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Called when one or more networkstatus fetches have failed (with uppercase
|
||||
* fingerprints listed in <b>failed</b>). Mark those fingerprints as having
|
||||
* failed once, unless they failed with status code 503. */
|
||||
static void
|
||||
dir_networkstatus_download_failed(smartlist_t *failed, int status_code)
|
||||
{
|
||||
if (status_code == 503)
|
||||
return;
|
||||
SMARTLIST_FOREACH_BEGIN(failed, const char *, fp) {
|
||||
char digest[DIGEST_LEN];
|
||||
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_fallback_dirserver_by_digest(digest);
|
||||
|
||||
if (dir)
|
||||
download_status_failed(&dir->v2_ns_dl_status, status_code);
|
||||
} SMARTLIST_FOREACH_END(fp);
|
||||
}
|
||||
|
||||
/** Decide which download schedule we want to use based on descriptor type
|
||||
* in <b>dls</b> and whether we are acting as directory <b>server</b>, and
|
||||
* then return a list of int pointers defining download delays in seconds.
|
||||
|
397
src/or/dirserv.c
397
src/or/dirserv.c
@ -1272,14 +1272,6 @@ directory_fetches_dir_info_later(const or_options_t *options)
|
||||
return options->UseBridges != 0;
|
||||
}
|
||||
|
||||
/** Return 1 if we want to cache v2 dir info (each status file).
|
||||
*/
|
||||
int
|
||||
directory_caches_v2_dir_info(const or_options_t *options)
|
||||
{
|
||||
return options->DirPort_set;
|
||||
}
|
||||
|
||||
/** Return true iff we want to fetch and keep certificates for authorities
|
||||
* that we don't acknowledge as aurthorities ourself.
|
||||
*/
|
||||
@ -1348,10 +1340,6 @@ static cached_dir_t *cached_directory = NULL;
|
||||
* if requested. */
|
||||
static cached_dir_t cached_runningrouters;
|
||||
|
||||
/** Used for other dirservers' v2 network statuses. Map from hexdigest to
|
||||
* cached_dir_t. */
|
||||
static digestmap_t *cached_v2_networkstatus = NULL;
|
||||
|
||||
/** Map from flavor name to the cached_dir_t for the v3 consensuses that we're
|
||||
* currently serving. */
|
||||
static strmap_t *cached_consensuses = NULL;
|
||||
@ -1452,70 +1440,6 @@ dirserv_set_cached_directory(const char *directory, time_t published)
|
||||
cached_directory = new_cached_dir(tor_strdup(directory), published);
|
||||
}
|
||||
|
||||
/** If <b>networkstatus</b> is non-NULL, we've just received a v2
|
||||
* network-status for an authoritative directory with identity digest
|
||||
* <b>identity</b> published at <b>published</b> -- store it so we can
|
||||
* serve it to others.
|
||||
*
|
||||
* If <b>networkstatus</b> is NULL, remove the entry with the given
|
||||
* identity fingerprint from the v2 cache.
|
||||
*/
|
||||
void
|
||||
dirserv_set_cached_networkstatus_v2(const char *networkstatus,
|
||||
const char *identity,
|
||||
time_t published)
|
||||
{
|
||||
cached_dir_t *d, *old_d;
|
||||
if (!cached_v2_networkstatus)
|
||||
cached_v2_networkstatus = digestmap_new();
|
||||
|
||||
old_d = digestmap_get(cached_v2_networkstatus, identity);
|
||||
if (!old_d && !networkstatus)
|
||||
return;
|
||||
|
||||
if (networkstatus) {
|
||||
if (!old_d || published > old_d->published) {
|
||||
d = new_cached_dir(tor_strdup(networkstatus), published);
|
||||
digestmap_set(cached_v2_networkstatus, identity, d);
|
||||
if (old_d)
|
||||
cached_dir_decref(old_d);
|
||||
}
|
||||
} else {
|
||||
if (old_d) {
|
||||
digestmap_remove(cached_v2_networkstatus, identity);
|
||||
cached_dir_decref(old_d);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now purge old entries. */
|
||||
|
||||
if (digestmap_size(cached_v2_networkstatus) >
|
||||
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;
|
||||
digestmap_iter_t *iter;
|
||||
|
||||
for (iter = digestmap_iter_init(cached_v2_networkstatus);
|
||||
!digestmap_iter_done(iter);
|
||||
iter = digestmap_iter_next(cached_v2_networkstatus, iter)) {
|
||||
const char *ident;
|
||||
void *val;
|
||||
digestmap_iter_get(iter, &ident, &val);
|
||||
d = val;
|
||||
if (d->published < oldest_published &&
|
||||
!router_digest_is_trusted_dir(ident)) {
|
||||
oldest = ident;
|
||||
oldest_published = d->published;
|
||||
}
|
||||
}
|
||||
tor_assert(oldest);
|
||||
d = digestmap_remove(cached_v2_networkstatus, oldest);
|
||||
if (d)
|
||||
cached_dir_decref(d);
|
||||
}
|
||||
}
|
||||
|
||||
/** Replace the v3 consensus networkstatus of type <b>flavor_name</b> that
|
||||
* we're serving with <b>networkstatus</b>, published at <b>published</b>. No
|
||||
* validation is performed. */
|
||||
@ -1538,30 +1462,6 @@ dirserv_set_cached_consensus_networkstatus(const char *networkstatus,
|
||||
cached_dir_decref(old_networkstatus);
|
||||
}
|
||||
|
||||
/** Remove any v2 networkstatus from the directory cache that was published
|
||||
* before <b>cutoff</b>. */
|
||||
void
|
||||
dirserv_clear_old_networkstatuses(time_t cutoff)
|
||||
{
|
||||
if (!cached_v2_networkstatus)
|
||||
return;
|
||||
|
||||
DIGESTMAP_FOREACH_MODIFY(cached_v2_networkstatus, id, cached_dir_t *, dir) {
|
||||
if (dir->published < cutoff) {
|
||||
char *fname;
|
||||
fname = networkstatus_get_cache_filename(id);
|
||||
if (file_status(fname) == FN_FILE) {
|
||||
log_info(LD_DIR, "Removing too-old untrusted networkstatus in %s",
|
||||
fname);
|
||||
unlink(fname);
|
||||
}
|
||||
tor_free(fname);
|
||||
cached_dir_decref(dir);
|
||||
MAP_DEL_CURRENT(id);
|
||||
}
|
||||
} DIGESTMAP_FOREACH_END
|
||||
}
|
||||
|
||||
/** Remove any v1 info from the directory cache that was published
|
||||
* too long ago. */
|
||||
void
|
||||
@ -1590,8 +1490,7 @@ dirserv_pick_cached_dir_obj(cached_dir_t *cache_src,
|
||||
dirinfo_type_t auth_type)
|
||||
{
|
||||
const or_options_t *options = get_options();
|
||||
int authority = (auth_type == V1_DIRINFO && authdir_mode_v1(options)) ||
|
||||
(auth_type == V2_DIRINFO && authdir_mode_v2(options));
|
||||
int authority = (auth_type == V1_DIRINFO && authdir_mode_v1(options));
|
||||
|
||||
if (!authority || authdir_mode_bridge(options)) {
|
||||
return cache_src;
|
||||
@ -1728,19 +1627,6 @@ dirserv_get_consensus(const char *flavor_name)
|
||||
return strmap_get(cached_consensuses, flavor_name);
|
||||
}
|
||||
|
||||
/** For authoritative directories: the current (v2) network status. */
|
||||
static cached_dir_t *the_v2_networkstatus = NULL;
|
||||
|
||||
/** Return true iff our opinion of the routers has been stale for long
|
||||
* enough that we should generate a new v2 network status doc. */
|
||||
static int
|
||||
should_generate_v2_networkstatus(void)
|
||||
{
|
||||
return authdir_mode_v2(get_options()) &&
|
||||
the_v2_networkstatus_is_dirty &&
|
||||
the_v2_networkstatus_is_dirty + DIR_REGEN_SLACK_TIME < time(NULL);
|
||||
}
|
||||
|
||||
/** If a router's uptime is at least this value, then it is always
|
||||
* considered stable, regardless of the rest of the network. This
|
||||
* way we resist attacks where an attacker doubles the size of the
|
||||
@ -2411,7 +2297,7 @@ routerstatus_format_entry(const routerstatus_t *rs, const char *version,
|
||||
rs->is_flagged_running?" Running":"",
|
||||
rs->is_stable?" Stable":"",
|
||||
rs->is_unnamed?" Unnamed":"",
|
||||
rs->is_v2_dir?" V2Dir":"",
|
||||
(rs->dir_port!=0)?" V2Dir":"",
|
||||
rs->is_valid?" Valid":"");
|
||||
|
||||
/* length of "opt v \n" */
|
||||
@ -2735,7 +2621,6 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
|
||||
rs->is_bad_exit = listbadexits && node->is_bad_exit;
|
||||
node->is_hs_dir = dirserv_thinks_router_is_hs_dir(ri, node, now);
|
||||
rs->is_hs_dir = vote_on_hsdirs && node->is_hs_dir;
|
||||
rs->is_v2_dir = ri->dir_port != 0;
|
||||
|
||||
if (!strcasecmp(ri->nickname, UNNAMED_ROUTER_NICKNAME))
|
||||
rs->is_named = rs->is_unnamed = 0;
|
||||
@ -2766,7 +2651,7 @@ static void
|
||||
clear_status_flags_on_sybil(routerstatus_t *rs)
|
||||
{
|
||||
rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
|
||||
rs->is_flagged_running = rs->is_named = rs->is_valid = rs->is_v2_dir =
|
||||
rs->is_flagged_running = rs->is_named = rs->is_valid =
|
||||
rs->is_hs_dir = rs->is_possible_guard = rs->is_bad_exit =
|
||||
rs->is_bad_directory = 0;
|
||||
/* FFFF we might want some mechanism to check later on if we
|
||||
@ -3190,270 +3075,6 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
|
||||
return v3_out;
|
||||
}
|
||||
|
||||
/** For v2 authoritative directories only: Replace the contents of
|
||||
* <b>the_v2_networkstatus</b> with a newly generated network status
|
||||
* object. */
|
||||
STATIC cached_dir_t *
|
||||
generate_v2_networkstatus_opinion(void)
|
||||
{
|
||||
cached_dir_t *r = NULL;
|
||||
size_t identity_pkey_len;
|
||||
char *status = NULL, *client_versions = NULL, *server_versions = NULL,
|
||||
*identity_pkey = NULL, *hostname = NULL;
|
||||
const or_options_t *options = get_options();
|
||||
char fingerprint[FINGERPRINT_LEN+1];
|
||||
char published[ISO_TIME_LEN+1];
|
||||
char digest[DIGEST_LEN];
|
||||
uint32_t addr;
|
||||
crypto_pk_t *private_key;
|
||||
routerlist_t *rl = router_get_routerlist();
|
||||
time_t now = time(NULL);
|
||||
time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
|
||||
int naming = options->NamingAuthoritativeDir;
|
||||
int versioning = options->VersioningAuthoritativeDir;
|
||||
int listbaddirs = options->AuthDirListBadDirs;
|
||||
int listbadexits = options->AuthDirListBadExits;
|
||||
int vote_on_hsdirs = options->VoteOnHidServDirectoriesV2;
|
||||
const char *contact;
|
||||
char *version_lines = NULL;
|
||||
smartlist_t *routers = NULL;
|
||||
digestmap_t *omit_as_sybil = NULL;
|
||||
smartlist_t *chunks = NULL;
|
||||
|
||||
private_key = get_server_identity_key();
|
||||
|
||||
if (resolve_my_address(LOG_WARN, options, &addr, NULL, &hostname)<0) {
|
||||
log_warn(LD_NET, "Couldn't resolve my hostname");
|
||||
goto done;
|
||||
}
|
||||
if (!hostname)
|
||||
hostname = tor_dup_ip(addr);
|
||||
|
||||
format_iso_time(published, now);
|
||||
|
||||
client_versions = format_versions_list(options->RecommendedClientVersions);
|
||||
server_versions = format_versions_list(options->RecommendedServerVersions);
|
||||
|
||||
if (crypto_pk_write_public_key_to_string(private_key, &identity_pkey,
|
||||
&identity_pkey_len)<0) {
|
||||
log_warn(LD_BUG,"Writing public key to string failed.");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (crypto_pk_get_fingerprint(private_key, fingerprint, 0)<0) {
|
||||
log_err(LD_BUG, "Error computing fingerprint");
|
||||
goto done;
|
||||
}
|
||||
|
||||
contact = options->ContactInfo;
|
||||
if (!contact)
|
||||
contact = "(none)";
|
||||
|
||||
if (versioning) {
|
||||
tor_asprintf(&version_lines,
|
||||
"client-versions %s\nserver-versions %s\n",
|
||||
client_versions, server_versions);
|
||||
} else {
|
||||
version_lines = tor_strdup("");
|
||||
}
|
||||
|
||||
chunks = smartlist_new();
|
||||
smartlist_add_asprintf(chunks,
|
||||
"network-status-version 2\n"
|
||||
"dir-source %s %s %d\n"
|
||||
"fingerprint %s\n"
|
||||
"contact %s\n"
|
||||
"published %s\n"
|
||||
"dir-options%s%s%s%s\n"
|
||||
"%s" /* client version line, server version line. */
|
||||
"dir-signing-key\n%s",
|
||||
hostname, fmt_addr32(addr),
|
||||
(int)router_get_advertised_dir_port(options, 0),
|
||||
fingerprint,
|
||||
contact,
|
||||
published,
|
||||
naming ? " Names" : "",
|
||||
listbaddirs ? " BadDirectories" : "",
|
||||
listbadexits ? " BadExits" : "",
|
||||
versioning ? " Versions" : "",
|
||||
version_lines,
|
||||
identity_pkey);
|
||||
|
||||
/* precompute this part, since we need it to decide what "stable"
|
||||
* means. */
|
||||
SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
|
||||
dirserv_set_router_is_running(ri, now);
|
||||
});
|
||||
|
||||
routers = smartlist_new();
|
||||
smartlist_add_all(routers, rl->routers);
|
||||
routers_sort_by_identity(routers);
|
||||
omit_as_sybil = get_possible_sybil_list(routers);
|
||||
|
||||
dirserv_compute_performance_thresholds(rl, omit_as_sybil);
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
|
||||
if (ri->cache_info.published_on >= cutoff) {
|
||||
routerstatus_t rs;
|
||||
char *version = version_from_platform(ri->platform);
|
||||
node_t *node = node_get_mutable_by_id(ri->cache_info.identity_digest);
|
||||
if (!node) {
|
||||
tor_free(version);
|
||||
continue;
|
||||
}
|
||||
set_routerstatus_from_routerinfo(&rs, node, ri, now,
|
||||
naming, listbadexits, listbaddirs,
|
||||
vote_on_hsdirs);
|
||||
|
||||
if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
|
||||
clear_status_flags_on_sybil(&rs);
|
||||
|
||||
{
|
||||
char *rsf = routerstatus_format_entry(&rs, version, NS_V2, NULL);
|
||||
if (rsf)
|
||||
smartlist_add(chunks, rsf);
|
||||
}
|
||||
tor_free(version);
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(ri);
|
||||
|
||||
smartlist_add_asprintf(chunks, "directory-signature %s\n",
|
||||
options->Nickname);
|
||||
|
||||
crypto_digest_smartlist(digest, DIGEST_LEN, chunks, "", DIGEST_SHA1);
|
||||
|
||||
note_crypto_pk_op(SIGN_DIR);
|
||||
{
|
||||
char *sig;
|
||||
if (!(sig = router_get_dirobj_signature(digest,DIGEST_LEN,
|
||||
private_key))) {
|
||||
log_warn(LD_BUG, "Unable to sign router status.");
|
||||
goto done;
|
||||
}
|
||||
smartlist_add(chunks, sig);
|
||||
}
|
||||
|
||||
status = smartlist_join_strings(chunks, "", 0, NULL);
|
||||
|
||||
{
|
||||
networkstatus_v2_t *ns;
|
||||
if (!(ns = networkstatus_v2_parse_from_string(status))) {
|
||||
log_err(LD_BUG,"Generated a networkstatus we couldn't parse.");
|
||||
goto done;
|
||||
}
|
||||
networkstatus_v2_free(ns);
|
||||
}
|
||||
|
||||
{
|
||||
cached_dir_t **ns_ptr = &the_v2_networkstatus;
|
||||
if (*ns_ptr)
|
||||
cached_dir_decref(*ns_ptr);
|
||||
*ns_ptr = new_cached_dir(status, now);
|
||||
status = NULL; /* So it doesn't get double-freed. */
|
||||
the_v2_networkstatus_is_dirty = 0;
|
||||
router_set_networkstatus_v2((*ns_ptr)->dir, now, NS_GENERATED, NULL);
|
||||
r = *ns_ptr;
|
||||
}
|
||||
|
||||
done:
|
||||
if (chunks) {
|
||||
SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
|
||||
smartlist_free(chunks);
|
||||
}
|
||||
tor_free(client_versions);
|
||||
tor_free(server_versions);
|
||||
tor_free(version_lines);
|
||||
tor_free(status);
|
||||
tor_free(hostname);
|
||||
tor_free(identity_pkey);
|
||||
smartlist_free(routers);
|
||||
digestmap_free(omit_as_sybil, NULL);
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Given the portion of a networkstatus request URL after "tor/status/" in
|
||||
* <b>key</b>, append to <b>result</b> the digests of the identity keys of the
|
||||
* networkstatus objects that the client has requested. */
|
||||
void
|
||||
dirserv_get_networkstatus_v2_fingerprints(smartlist_t *result,
|
||||
const char *key)
|
||||
{
|
||||
tor_assert(result);
|
||||
|
||||
if (!cached_v2_networkstatus)
|
||||
cached_v2_networkstatus = digestmap_new();
|
||||
|
||||
if (should_generate_v2_networkstatus())
|
||||
generate_v2_networkstatus_opinion();
|
||||
|
||||
if (!strcmp(key,"authority")) {
|
||||
if (authdir_mode_v2(get_options())) {
|
||||
const routerinfo_t *me = router_get_my_routerinfo();
|
||||
if (me)
|
||||
smartlist_add(result,
|
||||
tor_memdup(me->cache_info.identity_digest, DIGEST_LEN));
|
||||
}
|
||||
} else if (!strcmp(key, "all")) {
|
||||
if (digestmap_size(cached_v2_networkstatus)) {
|
||||
digestmap_iter_t *iter;
|
||||
iter = digestmap_iter_init(cached_v2_networkstatus);
|
||||
while (!digestmap_iter_done(iter)) {
|
||||
const char *ident;
|
||||
void *val;
|
||||
digestmap_iter_get(iter, &ident, &val);
|
||||
smartlist_add(result, tor_memdup(ident, DIGEST_LEN));
|
||||
iter = digestmap_iter_next(cached_v2_networkstatus, iter);
|
||||
}
|
||||
} else {
|
||||
SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
|
||||
dir_server_t *, ds,
|
||||
if (ds->type & V2_DIRINFO)
|
||||
smartlist_add(result, tor_memdup(ds->digest, DIGEST_LEN)));
|
||||
}
|
||||
smartlist_sort_digests(result);
|
||||
if (smartlist_len(result) == 0)
|
||||
log_info(LD_DIRSERV,
|
||||
"Client requested 'all' network status objects; we have none.");
|
||||
} else if (!strcmpstart(key, "fp/")) {
|
||||
dir_split_resource_into_fingerprints(key+3, result, NULL,
|
||||
DSR_HEX|DSR_SORT_UNIQ);
|
||||
}
|
||||
}
|
||||
|
||||
/** Look for a network status object as specified by <b>key</b>, which should
|
||||
* be either "authority" (to find a network status generated by us), a hex
|
||||
* identity digest (to find a network status generated by given directory), or
|
||||
* "all" (to return all the v2 network status objects we have).
|
||||
*/
|
||||
void
|
||||
dirserv_get_networkstatus_v2(smartlist_t *result,
|
||||
const char *key)
|
||||
{
|
||||
cached_dir_t *cached;
|
||||
smartlist_t *fingerprints = smartlist_new();
|
||||
tor_assert(result);
|
||||
|
||||
if (!cached_v2_networkstatus)
|
||||
cached_v2_networkstatus = digestmap_new();
|
||||
|
||||
dirserv_get_networkstatus_v2_fingerprints(fingerprints, key);
|
||||
SMARTLIST_FOREACH_BEGIN(fingerprints, const char *, fp) {
|
||||
if (router_digest_is_me(fp) && should_generate_v2_networkstatus())
|
||||
generate_v2_networkstatus_opinion();
|
||||
cached = digestmap_get(cached_v2_networkstatus, fp);
|
||||
if (cached) {
|
||||
smartlist_add(result, cached);
|
||||
} else {
|
||||
char hexbuf[HEX_DIGEST_LEN+1];
|
||||
base16_encode(hexbuf, sizeof(hexbuf), fp, DIGEST_LEN);
|
||||
log_info(LD_DIRSERV, "Don't know about any network status with "
|
||||
"fingerprint '%s'", hexbuf);
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(fp);
|
||||
SMARTLIST_FOREACH(fingerprints, char *, cp, tor_free(cp));
|
||||
smartlist_free(fingerprints);
|
||||
}
|
||||
|
||||
/** As dirserv_get_routerdescs(), but instead of getting signed_descriptor_t
|
||||
* pointers, adds copies of digests to fps_out, and doesn't use the
|
||||
* /tor/server/ prefix. For a /d/ request, adds descriptor digests; for other
|
||||
@ -3753,15 +3374,12 @@ static cached_dir_t *
|
||||
lookup_cached_dir_by_fp(const char *fp)
|
||||
{
|
||||
cached_dir_t *d = NULL;
|
||||
if (tor_digest_is_zero(fp) && cached_consensuses)
|
||||
if (tor_digest_is_zero(fp) && cached_consensuses) {
|
||||
d = strmap_get(cached_consensuses, "ns");
|
||||
else if (memchr(fp, '\0', DIGEST_LEN) && cached_consensuses &&
|
||||
} else if (memchr(fp, '\0', DIGEST_LEN) && cached_consensuses &&
|
||||
(d = strmap_get(cached_consensuses, fp))) {
|
||||
/* this here interface is a nasty hack XXXX024 */;
|
||||
} else if (router_digest_is_me(fp) && the_v2_networkstatus)
|
||||
d = the_v2_networkstatus;
|
||||
else if (cached_v2_networkstatus)
|
||||
d = digestmap_get(cached_v2_networkstatus, fp);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
@ -4156,12 +3774,9 @@ dirserv_free_all(void)
|
||||
|
||||
cached_dir_decref(the_directory);
|
||||
clear_cached_dir(&the_runningrouters);
|
||||
cached_dir_decref(the_v2_networkstatus);
|
||||
cached_dir_decref(cached_directory);
|
||||
clear_cached_dir(&cached_runningrouters);
|
||||
|
||||
digestmap_free(cached_v2_networkstatus, free_cached_dir_);
|
||||
cached_v2_networkstatus = NULL;
|
||||
strmap_free(cached_consensuses, free_cached_dir_);
|
||||
cached_consensuses = NULL;
|
||||
|
||||
|
@ -56,7 +56,6 @@ void dirserv_compute_bridge_flag_thresholds(routerlist_t *rl);
|
||||
int directory_fetches_from_authorities(const or_options_t *options);
|
||||
int directory_fetches_dir_info_early(const or_options_t *options);
|
||||
int directory_fetches_dir_info_later(const or_options_t *options);
|
||||
int directory_caches_v2_dir_info(const or_options_t *options);
|
||||
int directory_caches_unknown_auth_certs(const or_options_t *options);
|
||||
int directory_caches_dir_info(const or_options_t *options);
|
||||
int directory_permits_begindir_requests(const or_options_t *options);
|
||||
@ -68,18 +67,12 @@ void directory_set_dirty(void);
|
||||
cached_dir_t *dirserv_get_directory(void);
|
||||
cached_dir_t *dirserv_get_runningrouters(void);
|
||||
cached_dir_t *dirserv_get_consensus(const char *flavor_name);
|
||||
void dirserv_set_cached_networkstatus_v2(const char *directory,
|
||||
const char *identity,
|
||||
time_t published);
|
||||
void dirserv_set_cached_consensus_networkstatus(const char *consensus,
|
||||
const char *flavor_name,
|
||||
const digests_t *digests,
|
||||
time_t published);
|
||||
void dirserv_clear_old_networkstatuses(time_t cutoff);
|
||||
void dirserv_clear_old_v1_info(time_t now);
|
||||
void dirserv_get_networkstatus_v2(smartlist_t *result, const char *key);
|
||||
void dirserv_get_networkstatus_v2_fingerprints(smartlist_t *result,
|
||||
const char *key);
|
||||
int dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
|
||||
const char **msg,
|
||||
int for_unencrypted_conn,
|
||||
@ -136,7 +129,6 @@ STATIC int dirserv_query_measured_bw_cache_kb(const char *node_id,
|
||||
long *bw_out,
|
||||
time_t *as_of_out);
|
||||
STATIC int dirserv_has_measured_bw(const char *node_id);
|
||||
STATIC cached_dir_t *generate_v2_networkstatus_opinion(void);
|
||||
#endif
|
||||
|
||||
int dirserv_read_measured_bandwidths(const char *from_file,
|
||||
|
@ -1458,8 +1458,6 @@ run_scheduled_events(time_t now)
|
||||
|
||||
/* If any networkstatus documents are no longer recent, we need to
|
||||
* update all the descriptors' running status. */
|
||||
/* purge obsolete entries */
|
||||
networkstatus_v2_list_clean(now);
|
||||
/* Remove dead routers. */
|
||||
routerlist_remove_old_routers();
|
||||
}
|
||||
@ -1948,9 +1946,6 @@ do_main_loop(void)
|
||||
log_warn(LD_DIR,
|
||||
"Couldn't load all cached v3 certificates. Starting anyway.");
|
||||
}
|
||||
if (router_reload_v2_networkstatus()) {
|
||||
return -1;
|
||||
}
|
||||
if (router_reload_consensus_networkstatus()) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -32,18 +32,6 @@
|
||||
#include "routerlist.h"
|
||||
#include "routerparse.h"
|
||||
|
||||
/* For tracking v2 networkstatus documents. Only caches do this now. */
|
||||
|
||||
/** Map from descriptor digest of routers listed in the v2 networkstatus
|
||||
* documents to download_status_t* */
|
||||
static digestmap_t *v2_download_status_map = NULL;
|
||||
/** Global list of all of the current v2 network_status documents that we know
|
||||
* about. This list is kept sorted by published_on. */
|
||||
static smartlist_t *networkstatus_v2_list = NULL;
|
||||
/** True iff any member of networkstatus_v2_list has changed since the last
|
||||
* time we called download_status_map_update_from_v2_networkstatus() */
|
||||
static int networkstatus_v2_list_has_changed = 0;
|
||||
|
||||
/** Map from lowercase nickname to identity digest of named server, if any. */
|
||||
static strmap_t *named_server_map = NULL;
|
||||
/** Map from lowercase nickname to (void*)1 for all names that are listed
|
||||
@ -88,11 +76,6 @@ typedef struct consensus_waiting_for_certs_t {
|
||||
static consensus_waiting_for_certs_t
|
||||
consensus_waiting_for_certs[N_CONSENSUS_FLAVORS];
|
||||
|
||||
/** The last time we tried to download a networkstatus, or 0 for "never". We
|
||||
* use this to rate-limit download attempts for directory caches (including
|
||||
* mirrors). Clients don't use this now. */
|
||||
static time_t last_networkstatus_download_attempted = 0;
|
||||
|
||||
/** A time before which we shouldn't try to replace the current consensus:
|
||||
* this will be at some point after the next consensus becomes valid, but
|
||||
* before the current consensus becomes invalid. */
|
||||
@ -107,7 +90,6 @@ static int have_warned_about_old_version = 0;
|
||||
* listed by the authorities. */
|
||||
static int have_warned_about_new_version = 0;
|
||||
|
||||
static void download_status_map_update_from_v2_networkstatus(void);
|
||||
static void routerstatus_list_update_named_server_map(void);
|
||||
|
||||
/** Forget that we've warned about anything networkstatus-related, so we will
|
||||
@ -131,86 +113,9 @@ void
|
||||
networkstatus_reset_download_failures(void)
|
||||
{
|
||||
int i;
|
||||
const smartlist_t *networkstatus_v2_list = networkstatus_get_v2_list();
|
||||
SMARTLIST_FOREACH_BEGIN(networkstatus_v2_list, networkstatus_v2_t *, ns) {
|
||||
SMARTLIST_FOREACH_BEGIN(ns->entries, routerstatus_t *, rs) {
|
||||
if (!router_get_by_descriptor_digest(rs->descriptor_digest))
|
||||
rs->need_to_mirror = 1;
|
||||
} SMARTLIST_FOREACH_END(rs);
|
||||
} SMARTLIST_FOREACH_END(ns);
|
||||
|
||||
for (i=0; i < N_CONSENSUS_FLAVORS; ++i)
|
||||
download_status_reset(&consensus_dl_status[i]);
|
||||
if (v2_download_status_map) {
|
||||
digestmap_iter_t *iter;
|
||||
digestmap_t *map = v2_download_status_map;
|
||||
const char *key;
|
||||
void *val;
|
||||
download_status_t *dls;
|
||||
for (iter = digestmap_iter_init(map); !digestmap_iter_done(iter);
|
||||
iter = digestmap_iter_next(map, iter) ) {
|
||||
digestmap_iter_get(iter, &key, &val);
|
||||
dls = val;
|
||||
download_status_reset(dls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Repopulate our list of network_status_t objects from the list cached on
|
||||
* disk. Return 0 on success, -1 on failure. */
|
||||
int
|
||||
router_reload_v2_networkstatus(void)
|
||||
{
|
||||
smartlist_t *entries;
|
||||
struct stat st;
|
||||
char *s;
|
||||
char *filename = get_datadir_fname("cached-status");
|
||||
int maybe_delete = !directory_caches_v2_dir_info(get_options());
|
||||
time_t now = time(NULL);
|
||||
if (!networkstatus_v2_list)
|
||||
networkstatus_v2_list = smartlist_new();
|
||||
|
||||
entries = tor_listdir(filename);
|
||||
if (!entries) { /* dir doesn't exist */
|
||||
tor_free(filename);
|
||||
return 0;
|
||||
} else if (!smartlist_len(entries) && maybe_delete) {
|
||||
rmdir(filename);
|
||||
tor_free(filename);
|
||||
smartlist_free(entries);
|
||||
return 0;
|
||||
}
|
||||
tor_free(filename);
|
||||
SMARTLIST_FOREACH_BEGIN(entries, const char *, fn) {
|
||||
char buf[DIGEST_LEN];
|
||||
if (maybe_delete) {
|
||||
filename = get_datadir_fname2("cached-status", fn);
|
||||
remove_file_if_very_old(filename, now);
|
||||
tor_free(filename);
|
||||
continue;
|
||||
}
|
||||
if (strlen(fn) != HEX_DIGEST_LEN ||
|
||||
base16_decode(buf, sizeof(buf), fn, strlen(fn))) {
|
||||
log_info(LD_DIR,
|
||||
"Skipping cached-status file with unexpected name \"%s\"",fn);
|
||||
continue;
|
||||
}
|
||||
filename = get_datadir_fname2("cached-status", fn);
|
||||
s = read_file_to_str(filename, 0, &st);
|
||||
if (s) {
|
||||
if (router_set_networkstatus_v2(s, st.st_mtime, NS_FROM_CACHE,
|
||||
NULL)<0) {
|
||||
log_warn(LD_FS, "Couldn't load networkstatus from \"%s\"",filename);
|
||||
}
|
||||
tor_free(s);
|
||||
}
|
||||
tor_free(filename);
|
||||
} SMARTLIST_FOREACH_END(fn);
|
||||
SMARTLIST_FOREACH(entries, char *, fn, tor_free(fn));
|
||||
smartlist_free(entries);
|
||||
networkstatus_v2_list_clean(time(NULL));
|
||||
routers_update_all_from_networkstatus(time(NULL), 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Read every cached v3 consensus networkstatus from the disk. */
|
||||
@ -303,26 +208,6 @@ routerstatus_free(routerstatus_t *rs)
|
||||
tor_free(rs);
|
||||
}
|
||||
|
||||
/** Free all storage held by the networkstatus object <b>ns</b>. */
|
||||
void
|
||||
networkstatus_v2_free(networkstatus_v2_t *ns)
|
||||
{
|
||||
if (!ns)
|
||||
return;
|
||||
tor_free(ns->source_address);
|
||||
tor_free(ns->contact);
|
||||
if (ns->signing_key)
|
||||
crypto_pk_free(ns->signing_key);
|
||||
tor_free(ns->client_versions);
|
||||
tor_free(ns->server_versions);
|
||||
if (ns->entries) {
|
||||
SMARTLIST_FOREACH(ns->entries, routerstatus_t *, rs,
|
||||
routerstatus_free(rs));
|
||||
smartlist_free(ns->entries);
|
||||
}
|
||||
tor_free(ns);
|
||||
}
|
||||
|
||||
/** Free all storage held in <b>sig</b> */
|
||||
void
|
||||
document_signature_free(document_signature_t *sig)
|
||||
@ -647,286 +532,10 @@ networkstatus_get_cache_filename(const char *identity_digest)
|
||||
return get_datadir_fname2("cached-status", fp);
|
||||
}
|
||||
|
||||
/** Helper for smartlist_sort: Compare two networkstatus objects by
|
||||
* publication date. */
|
||||
static int
|
||||
compare_networkstatus_v2_published_on_(const void **_a, const void **_b)
|
||||
{
|
||||
const networkstatus_v2_t *a = *_a, *b = *_b;
|
||||
if (a->published_on < b->published_on)
|
||||
return -1;
|
||||
else if (a->published_on > b->published_on)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Add the parsed v2 networkstatus in <b>ns</b> (with original document in
|
||||
* <b>s</b>) to the disk cache (and the in-memory directory server cache) as
|
||||
* appropriate. */
|
||||
static int
|
||||
add_networkstatus_to_cache(const char *s,
|
||||
v2_networkstatus_source_t source,
|
||||
networkstatus_v2_t *ns)
|
||||
{
|
||||
if (source != NS_FROM_CACHE) {
|
||||
char *fn = networkstatus_get_cache_filename(ns->identity_digest);
|
||||
if (write_str_to_file(fn, s, 0)<0) {
|
||||
log_notice(LD_FS, "Couldn't write cached network status to \"%s\"", fn);
|
||||
}
|
||||
tor_free(fn);
|
||||
}
|
||||
|
||||
if (directory_caches_v2_dir_info(get_options()))
|
||||
dirserv_set_cached_networkstatus_v2(s,
|
||||
ns->identity_digest,
|
||||
ns->published_on);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** How far in the future do we allow a network-status to get before removing
|
||||
* it? (seconds) */
|
||||
#define NETWORKSTATUS_ALLOW_SKEW (24*60*60)
|
||||
|
||||
/** Given a string <b>s</b> containing a network status that we received at
|
||||
* <b>arrived_at</b> from <b>source</b>, try to parse it, see if we want to
|
||||
* store it, and put it into our cache as necessary.
|
||||
*
|
||||
* If <b>source</b> is NS_FROM_DIR or NS_FROM_CACHE, do not replace our
|
||||
* own networkstatus_t (if we're an authoritative directory server).
|
||||
*
|
||||
* If <b>source</b> is NS_FROM_CACHE, do not write our networkstatus_t to the
|
||||
* cache.
|
||||
*
|
||||
* If <b>requested_fingerprints</b> is provided, it must contain a list of
|
||||
* uppercased identity fingerprints. Do not update any networkstatus whose
|
||||
* fingerprint is not on the list; after updating a networkstatus, remove its
|
||||
* fingerprint from the list.
|
||||
*
|
||||
* Return 0 on success, -1 on failure.
|
||||
*
|
||||
* Callers should make sure that routers_update_all_from_networkstatus() is
|
||||
* invoked after this function succeeds.
|
||||
*/
|
||||
int
|
||||
router_set_networkstatus_v2(const char *s, time_t arrived_at,
|
||||
v2_networkstatus_source_t source,
|
||||
smartlist_t *requested_fingerprints)
|
||||
{
|
||||
networkstatus_v2_t *ns;
|
||||
int i, found;
|
||||
time_t now;
|
||||
int skewed = 0;
|
||||
dir_server_t *trusted_dir = NULL;
|
||||
const char *source_desc = NULL;
|
||||
char fp[HEX_DIGEST_LEN+1];
|
||||
char published[ISO_TIME_LEN+1];
|
||||
|
||||
if (!directory_caches_v2_dir_info(get_options()))
|
||||
return 0; /* Don't bother storing it. */
|
||||
|
||||
ns = networkstatus_v2_parse_from_string(s);
|
||||
if (!ns) {
|
||||
log_warn(LD_DIR, "Couldn't parse network status.");
|
||||
return -1;
|
||||
}
|
||||
base16_encode(fp, HEX_DIGEST_LEN+1, ns->identity_digest, DIGEST_LEN);
|
||||
if (!(trusted_dir =
|
||||
router_get_trusteddirserver_by_digest(ns->identity_digest)) ||
|
||||
!(trusted_dir->type & V2_DIRINFO)) {
|
||||
log_info(LD_DIR, "Network status was signed, but not by an authoritative "
|
||||
"directory we recognize.");
|
||||
source_desc = fp;
|
||||
} else {
|
||||
source_desc = trusted_dir->description;
|
||||
}
|
||||
now = time(NULL);
|
||||
if (arrived_at > now)
|
||||
arrived_at = now;
|
||||
|
||||
ns->received_on = arrived_at;
|
||||
|
||||
format_iso_time(published, ns->published_on);
|
||||
|
||||
if (ns->published_on > now + NETWORKSTATUS_ALLOW_SKEW) {
|
||||
char dbuf[64];
|
||||
long delta = now - ns->published_on;
|
||||
format_time_interval(dbuf, sizeof(dbuf), delta);
|
||||
log_warn(LD_GENERAL, "Network status from %s was published %s in the "
|
||||
"future (%s UTC). Check your time and date settings! "
|
||||
"Not caching.",
|
||||
source_desc, dbuf, published);
|
||||
control_event_general_status(LOG_WARN,
|
||||
"CLOCK_SKEW MIN_SKEW=%ld SOURCE=NETWORKSTATUS:%s:%d",
|
||||
delta, ns->source_address, ns->source_dirport);
|
||||
skewed = 1;
|
||||
}
|
||||
|
||||
if (!networkstatus_v2_list)
|
||||
networkstatus_v2_list = smartlist_new();
|
||||
|
||||
if ( (source == NS_FROM_DIR_BY_FP || source == NS_FROM_DIR_ALL) &&
|
||||
router_digest_is_me(ns->identity_digest)) {
|
||||
/* Don't replace our own networkstatus when we get it from somebody else.*/
|
||||
networkstatus_v2_free(ns);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (requested_fingerprints) {
|
||||
if (smartlist_contains_string(requested_fingerprints, fp)) {
|
||||
smartlist_string_remove(requested_fingerprints, fp);
|
||||
} else {
|
||||
if (source != NS_FROM_DIR_ALL) {
|
||||
char *requested =
|
||||
smartlist_join_strings(requested_fingerprints," ",0,NULL);
|
||||
log_warn(LD_DIR,
|
||||
"We received a network status with a fingerprint (%s) that we "
|
||||
"never requested. (We asked for: %s.) Dropping.",
|
||||
fp, requested);
|
||||
tor_free(requested);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!trusted_dir) {
|
||||
if (!skewed) {
|
||||
/* We got a non-trusted networkstatus, and we're a directory cache.
|
||||
* This means that we asked an authority, and it told us about another
|
||||
* authority we didn't recognize. */
|
||||
log_info(LD_DIR,
|
||||
"We do not recognize authority (%s) but we are willing "
|
||||
"to cache it.", fp);
|
||||
add_networkstatus_to_cache(s, source, ns);
|
||||
networkstatus_v2_free(ns);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
found = 0;
|
||||
for (i=0; i < smartlist_len(networkstatus_v2_list); ++i) {
|
||||
networkstatus_v2_t *old_ns = smartlist_get(networkstatus_v2_list, i);
|
||||
|
||||
if (tor_memeq(old_ns->identity_digest, ns->identity_digest, DIGEST_LEN)) {
|
||||
if (tor_memeq(old_ns->networkstatus_digest,
|
||||
ns->networkstatus_digest, DIGEST_LEN)) {
|
||||
/* Same one we had before. */
|
||||
networkstatus_v2_free(ns);
|
||||
tor_assert(trusted_dir);
|
||||
log_info(LD_DIR,
|
||||
"Not replacing network-status from %s (published %s); "
|
||||
"we already have it.",
|
||||
trusted_dir->description, published);
|
||||
if (old_ns->received_on < arrived_at) {
|
||||
if (source != NS_FROM_CACHE) {
|
||||
char *fn;
|
||||
fn = networkstatus_get_cache_filename(old_ns->identity_digest);
|
||||
/* We use mtime to tell when it arrived, so update that. */
|
||||
touch_file(fn);
|
||||
tor_free(fn);
|
||||
}
|
||||
old_ns->received_on = arrived_at;
|
||||
}
|
||||
download_status_failed(&trusted_dir->v2_ns_dl_status, 0);
|
||||
return 0;
|
||||
} else if (old_ns->published_on >= ns->published_on) {
|
||||
char old_published[ISO_TIME_LEN+1];
|
||||
format_iso_time(old_published, old_ns->published_on);
|
||||
tor_assert(trusted_dir);
|
||||
log_info(LD_DIR,
|
||||
"Not replacing network-status from %s (published %s);"
|
||||
" we have a newer one (published %s) for this authority.",
|
||||
trusted_dir->description, published,
|
||||
old_published);
|
||||
networkstatus_v2_free(ns);
|
||||
download_status_failed(&trusted_dir->v2_ns_dl_status, 0);
|
||||
return 0;
|
||||
} else {
|
||||
networkstatus_v2_free(old_ns);
|
||||
smartlist_set(networkstatus_v2_list, i, ns);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (source != NS_FROM_CACHE && trusted_dir) {
|
||||
download_status_reset(&trusted_dir->v2_ns_dl_status);
|
||||
}
|
||||
|
||||
if (!found)
|
||||
smartlist_add(networkstatus_v2_list, ns);
|
||||
|
||||
/** Retain any routerinfo mentioned in a V2 networkstatus for at least this
|
||||
* long. */
|
||||
#define V2_NETWORKSTATUS_ROUTER_LIFETIME (3*60*60)
|
||||
|
||||
{
|
||||
time_t live_until = ns->published_on + V2_NETWORKSTATUS_ROUTER_LIFETIME;
|
||||
SMARTLIST_FOREACH_BEGIN(ns->entries, routerstatus_t *, rs) {
|
||||
signed_descriptor_t *sd =
|
||||
router_get_by_descriptor_digest(rs->descriptor_digest);
|
||||
if (sd) {
|
||||
if (sd->last_listed_as_valid_until < live_until)
|
||||
sd->last_listed_as_valid_until = live_until;
|
||||
} else {
|
||||
rs->need_to_mirror = 1;
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(rs);
|
||||
}
|
||||
|
||||
log_info(LD_DIR, "Setting networkstatus %s %s (published %s)",
|
||||
source == NS_FROM_CACHE?"cached from":
|
||||
((source == NS_FROM_DIR_BY_FP || source == NS_FROM_DIR_ALL) ?
|
||||
"downloaded from":"generated for"),
|
||||
trusted_dir->description, published);
|
||||
networkstatus_v2_list_has_changed = 1;
|
||||
|
||||
smartlist_sort(networkstatus_v2_list,
|
||||
compare_networkstatus_v2_published_on_);
|
||||
|
||||
if (!skewed)
|
||||
add_networkstatus_to_cache(s, source, ns);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Remove all very-old network_status_t objects from memory and from the
|
||||
* disk cache. */
|
||||
void
|
||||
networkstatus_v2_list_clean(time_t now)
|
||||
{
|
||||
int i;
|
||||
if (!networkstatus_v2_list)
|
||||
return;
|
||||
|
||||
for (i = 0; i < smartlist_len(networkstatus_v2_list); ++i) {
|
||||
networkstatus_v2_t *ns = smartlist_get(networkstatus_v2_list, i);
|
||||
char *fname = NULL;
|
||||
if (ns->published_on + MAX_NETWORKSTATUS_AGE > now)
|
||||
continue;
|
||||
/* Okay, this one is too old. Remove it from the list, and delete it
|
||||
* from the cache. */
|
||||
smartlist_del(networkstatus_v2_list, i--);
|
||||
fname = networkstatus_get_cache_filename(ns->identity_digest);
|
||||
if (file_status(fname) == FN_FILE) {
|
||||
log_info(LD_DIR, "Removing too-old networkstatus in %s", fname);
|
||||
unlink(fname);
|
||||
}
|
||||
tor_free(fname);
|
||||
if (directory_caches_v2_dir_info(get_options())) {
|
||||
dirserv_set_cached_networkstatus_v2(NULL, ns->identity_digest, 0);
|
||||
}
|
||||
networkstatus_v2_free(ns);
|
||||
}
|
||||
|
||||
/* And now go through the directory cache for any cached untrusted
|
||||
* networkstatuses and other network info. */
|
||||
dirserv_clear_old_networkstatuses(now - MAX_NETWORKSTATUS_AGE);
|
||||
dirserv_clear_old_v1_info(now);
|
||||
}
|
||||
|
||||
/** Helper for bsearching a list of routerstatus_t pointers: compare a
|
||||
* digest in the key to the identity digest of a routerstatus_t. */
|
||||
int
|
||||
@ -948,22 +557,6 @@ compare_digest_to_vote_routerstatus_entry(const void *_key,
|
||||
return tor_memcmp(key, vrs->status.identity_digest, DIGEST_LEN);
|
||||
}
|
||||
|
||||
/** As networkstatus_v2_find_entry, but do not return a const pointer */
|
||||
routerstatus_t *
|
||||
networkstatus_v2_find_mutable_entry(networkstatus_v2_t *ns, const char *digest)
|
||||
{
|
||||
return smartlist_bsearch(ns->entries, digest,
|
||||
compare_digest_to_routerstatus_entry);
|
||||
}
|
||||
|
||||
/** Return the entry in <b>ns</b> for the identity digest <b>digest</b>, or
|
||||
* NULL if none was found. */
|
||||
const routerstatus_t *
|
||||
networkstatus_v2_find_entry(networkstatus_v2_t *ns, const char *digest)
|
||||
{
|
||||
return networkstatus_v2_find_mutable_entry(ns, digest);
|
||||
}
|
||||
|
||||
/** As networkstatus_find_entry, but do not return a const pointer */
|
||||
routerstatus_t *
|
||||
networkstatus_vote_find_mutable_entry(networkstatus_t *ns, const char *digest)
|
||||
@ -993,15 +586,6 @@ networkstatus_vote_find_entry_idx(networkstatus_t *ns,
|
||||
found_out);
|
||||
}
|
||||
|
||||
/** Return a list of the v2 networkstatus documents. */
|
||||
const smartlist_t *
|
||||
networkstatus_get_v2_list(void)
|
||||
{
|
||||
if (!networkstatus_v2_list)
|
||||
networkstatus_v2_list = smartlist_new();
|
||||
return networkstatus_v2_list;
|
||||
}
|
||||
|
||||
/** As router_get_consensus_status_by_descriptor_digest, but does not return
|
||||
* a const pointer. */
|
||||
routerstatus_t *
|
||||
@ -1046,8 +630,6 @@ router_get_dl_status_by_descriptor_digest(const char *d)
|
||||
if ((rs = router_get_mutable_consensus_status_by_descriptor_digest(
|
||||
current_ns_consensus, d)))
|
||||
return &rs->dl_status;
|
||||
if (v2_download_status_map)
|
||||
return digestmap_get(v2_download_status_map, d);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -1113,72 +695,6 @@ networkstatus_nickname_is_unnamed(const char *nickname)
|
||||
* networkstatus documents? */
|
||||
#define NONAUTHORITY_NS_CACHE_INTERVAL (60*60)
|
||||
|
||||
/** We are a directory server, and so cache network_status documents.
|
||||
* Initiate downloads as needed to update them. For v2 authorities,
|
||||
* this means asking each trusted directory for its network-status.
|
||||
* For caches, this means asking a random v2 authority for all
|
||||
* network-statuses.
|
||||
*/
|
||||
static void
|
||||
update_v2_networkstatus_cache_downloads(time_t now)
|
||||
{
|
||||
int authority = authdir_mode_v2(get_options());
|
||||
int interval =
|
||||
authority ? AUTHORITY_NS_CACHE_INTERVAL : NONAUTHORITY_NS_CACHE_INTERVAL;
|
||||
const smartlist_t *trusted_dir_servers = router_get_trusted_dir_servers();
|
||||
|
||||
if (last_networkstatus_download_attempted + interval >= now)
|
||||
return;
|
||||
|
||||
last_networkstatus_download_attempted = now;
|
||||
|
||||
if (authority) {
|
||||
/* An authority launches a separate connection for everybody. */
|
||||
SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, dir_server_t *, ds)
|
||||
{
|
||||
char resource[HEX_DIGEST_LEN+6]; /* fp/hexdigit.z\0 */
|
||||
tor_addr_t addr;
|
||||
if (!(ds->type & V2_DIRINFO))
|
||||
continue;
|
||||
if (router_digest_is_me(ds->digest))
|
||||
continue;
|
||||
tor_addr_from_ipv4h(&addr, ds->addr);
|
||||
/* Is this quite sensible with IPv6 or multiple addresses? */
|
||||
if (connection_get_by_type_addr_port_purpose(
|
||||
CONN_TYPE_DIR, &addr, ds->dir_port,
|
||||
DIR_PURPOSE_FETCH_V2_NETWORKSTATUS)) {
|
||||
/* XXX the above dir_port won't be accurate if we're
|
||||
* doing a tunneled conn. In that case it should be or_port.
|
||||
* How to guess from here? Maybe make the function less general
|
||||
* and have it know that it's looking for dir conns. -RD */
|
||||
/* Only directory caches download v2 networkstatuses, and they
|
||||
* don't use tunneled connections. I think it's okay to ignore
|
||||
* this. */
|
||||
continue;
|
||||
}
|
||||
strlcpy(resource, "fp/", sizeof(resource));
|
||||
base16_encode(resource+3, sizeof(resource)-3, ds->digest, DIGEST_LEN);
|
||||
strlcat(resource, ".z", sizeof(resource));
|
||||
directory_initiate_command_routerstatus(
|
||||
&ds->fake_status, DIR_PURPOSE_FETCH_V2_NETWORKSTATUS,
|
||||
ROUTER_PURPOSE_GENERAL,
|
||||
DIRIND_ONEHOP,
|
||||
resource,
|
||||
NULL, 0 /* No payload. */,
|
||||
0 /* No I-M-S. */);
|
||||
}
|
||||
SMARTLIST_FOREACH_END(ds);
|
||||
} else {
|
||||
/* A non-authority cache launches one connection to a random authority. */
|
||||
/* (Check whether we're currently fetching network-status objects.) */
|
||||
if (!connection_get_by_type_purpose(CONN_TYPE_DIR,
|
||||
DIR_PURPOSE_FETCH_V2_NETWORKSTATUS))
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_V2_NETWORKSTATUS,
|
||||
ROUTER_PURPOSE_GENERAL, "all.z",
|
||||
PDS_RETRY_IF_NO_SERVERS);
|
||||
}
|
||||
}
|
||||
|
||||
/** Return true iff, given the options listed in <b>options</b>, <b>flavor</b>
|
||||
* is the flavor of a consensus networkstatus that we would like to fetch. */
|
||||
static int
|
||||
@ -1397,8 +913,6 @@ update_networkstatus_downloads(time_t now)
|
||||
const or_options_t *options = get_options();
|
||||
if (should_delay_dir_fetches(options))
|
||||
return;
|
||||
if (authdir_mode_any_main(options) || options->FetchV2Networkstatus)
|
||||
update_v2_networkstatus_cache_downloads(now);
|
||||
update_consensus_networkstatus_downloads(now);
|
||||
update_certificate_downloads(now);
|
||||
}
|
||||
@ -1505,7 +1019,6 @@ routerstatus_has_changed(const routerstatus_t *a, const routerstatus_t *b)
|
||||
a->is_named != b->is_named ||
|
||||
a->is_unnamed != b->is_unnamed ||
|
||||
a->is_valid != b->is_valid ||
|
||||
a->is_v2_dir != b->is_v2_dir ||
|
||||
a->is_possible_guard != b->is_possible_guard ||
|
||||
a->is_bad_exit != b->is_bad_exit ||
|
||||
a->is_bad_directory != b->is_bad_directory ||
|
||||
@ -1900,9 +1413,6 @@ routers_update_all_from_networkstatus(time_t now, int dir_version)
|
||||
networkstatus_t *consensus = networkstatus_get_reasonably_live_consensus(now,
|
||||
FLAV_NS);
|
||||
|
||||
if (networkstatus_v2_list_has_changed)
|
||||
download_status_map_update_from_v2_networkstatus();
|
||||
|
||||
if (!consensus || dir_version < 3) /* nothing more we should do */
|
||||
return;
|
||||
|
||||
@ -1957,35 +1467,6 @@ routers_update_all_from_networkstatus(time_t now, int dir_version)
|
||||
}
|
||||
}
|
||||
|
||||
/** Update v2_download_status_map to contain an entry for every router
|
||||
* descriptor listed in the v2 networkstatuses. */
|
||||
static void
|
||||
download_status_map_update_from_v2_networkstatus(void)
|
||||
{
|
||||
digestmap_t *dl_status;
|
||||
if (!networkstatus_v2_list)
|
||||
return;
|
||||
if (!v2_download_status_map)
|
||||
v2_download_status_map = digestmap_new();
|
||||
|
||||
dl_status = digestmap_new();
|
||||
SMARTLIST_FOREACH_BEGIN(networkstatus_v2_list, networkstatus_v2_t *, ns) {
|
||||
SMARTLIST_FOREACH_BEGIN(ns->entries, const routerstatus_t *, rs) {
|
||||
const char *d = rs->descriptor_digest;
|
||||
download_status_t *s;
|
||||
if (digestmap_get(dl_status, d))
|
||||
continue;
|
||||
if (!(s = digestmap_remove(v2_download_status_map, d))) {
|
||||
s = tor_malloc_zero(sizeof(download_status_t));
|
||||
}
|
||||
digestmap_set(dl_status, d, s);
|
||||
} SMARTLIST_FOREACH_END(rs);
|
||||
} SMARTLIST_FOREACH_END(ns);
|
||||
digestmap_free(v2_download_status_map, tor_free_);
|
||||
v2_download_status_map = dl_status;
|
||||
networkstatus_v2_list_has_changed = 0;
|
||||
}
|
||||
|
||||
/** Update our view of the list of named servers from the most recently
|
||||
* retrieved networkstatus consensus. */
|
||||
static void
|
||||
@ -2017,14 +1498,11 @@ void
|
||||
routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
|
||||
int reset_failures)
|
||||
{
|
||||
dir_server_t *ds;
|
||||
const or_options_t *options = get_options();
|
||||
int authdir = authdir_mode_v2(options) || authdir_mode_v3(options);
|
||||
int authdir = authdir_mode_v3(options);
|
||||
networkstatus_t *ns = current_consensus;
|
||||
if (!ns || !smartlist_len(ns->routerstatus_list))
|
||||
return;
|
||||
if (!networkstatus_v2_list)
|
||||
networkstatus_v2_list = smartlist_new();
|
||||
|
||||
routers_sort_by_identity(routers);
|
||||
|
||||
@ -2034,11 +1512,6 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
|
||||
router->cache_info.identity_digest, DIGEST_LEN),
|
||||
{
|
||||
}) {
|
||||
/* We have a routerstatus for this router. */
|
||||
const char *digest = router->cache_info.identity_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,
|
||||
rs->descriptor_digest, DIGEST_LEN)) {
|
||||
@ -2056,30 +1529,11 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
|
||||
dirserv_should_launch_reachability_test(router, old_router);
|
||||
}
|
||||
}
|
||||
if (rs->is_flagged_running && ds) {
|
||||
download_status_reset(&ds->v2_ns_dl_status);
|
||||
}
|
||||
if (reset_failures) {
|
||||
download_status_reset(&rs->dl_status);
|
||||
}
|
||||
} SMARTLIST_FOREACH_JOIN_END(rs, router);
|
||||
|
||||
/* Now update last_listed_as_valid_until from v2 networkstatuses. */
|
||||
SMARTLIST_FOREACH_BEGIN(networkstatus_v2_list, networkstatus_v2_t *, ns) {
|
||||
time_t live_until = ns->published_on + V2_NETWORKSTATUS_ROUTER_LIFETIME;
|
||||
SMARTLIST_FOREACH_JOIN(ns->entries, const routerstatus_t *, rs,
|
||||
routers, routerinfo_t *, ri,
|
||||
tor_memcmp(rs->identity_digest,
|
||||
ri->cache_info.identity_digest, DIGEST_LEN),
|
||||
STMT_NIL) {
|
||||
if (tor_memeq(ri->cache_info.signed_descriptor_digest,
|
||||
rs->descriptor_digest, DIGEST_LEN)) {
|
||||
if (live_until > ri->cache_info.last_listed_as_valid_until)
|
||||
ri->cache_info.last_listed_as_valid_until = live_until;
|
||||
}
|
||||
} SMARTLIST_FOREACH_JOIN_END(rs, ri);
|
||||
} SMARTLIST_FOREACH_END(ns);
|
||||
|
||||
router_dir_info_changed();
|
||||
}
|
||||
|
||||
@ -2398,15 +1852,6 @@ void
|
||||
networkstatus_free_all(void)
|
||||
{
|
||||
int i;
|
||||
if (networkstatus_v2_list) {
|
||||
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
|
||||
networkstatus_v2_free(ns));
|
||||
smartlist_free(networkstatus_v2_list);
|
||||
networkstatus_v2_list = NULL;
|
||||
}
|
||||
|
||||
digestmap_free(v2_download_status_map, tor_free_);
|
||||
v2_download_status_map = NULL;
|
||||
networkstatus_vote_free(current_ns_consensus);
|
||||
networkstatus_vote_free(current_md_consensus);
|
||||
current_md_consensus = current_ns_consensus = NULL;
|
||||
|
@ -12,16 +12,10 @@
|
||||
#ifndef TOR_NETWORKSTATUS_H
|
||||
#define TOR_NETWORKSTATUS_H
|
||||
|
||||
/** How old do we allow a v2 network-status to get before removing it
|
||||
* completely? */
|
||||
#define MAX_NETWORKSTATUS_AGE (10*24*60*60)
|
||||
|
||||
void networkstatus_reset_warnings(void);
|
||||
void networkstatus_reset_download_failures(void);
|
||||
int router_reload_v2_networkstatus(void);
|
||||
int router_reload_consensus_networkstatus(void);
|
||||
void routerstatus_free(routerstatus_t *rs);
|
||||
void networkstatus_v2_free(networkstatus_v2_t *ns);
|
||||
void networkstatus_vote_free(networkstatus_t *ns);
|
||||
networkstatus_voter_info_t *networkstatus_get_voter_by_id(
|
||||
networkstatus_t *vote,
|
||||
@ -32,25 +26,16 @@ int networkstatus_check_document_signature(const networkstatus_t *consensus,
|
||||
document_signature_t *sig,
|
||||
const authority_cert_t *cert);
|
||||
char *networkstatus_get_cache_filename(const char *identity_digest);
|
||||
int router_set_networkstatus_v2(const char *s, time_t arrived_at,
|
||||
v2_networkstatus_source_t source,
|
||||
smartlist_t *requested_fingerprints);
|
||||
void networkstatus_v2_list_clean(time_t now);
|
||||
int compare_digest_to_routerstatus_entry(const void *_key,
|
||||
const void **_member);
|
||||
int compare_digest_to_vote_routerstatus_entry(const void *_key,
|
||||
const void **_member);
|
||||
const routerstatus_t *networkstatus_v2_find_entry(networkstatus_v2_t *ns,
|
||||
const char *digest);
|
||||
const routerstatus_t *networkstatus_vote_find_entry(networkstatus_t *ns,
|
||||
const char *digest);
|
||||
routerstatus_t *networkstatus_v2_find_mutable_entry(networkstatus_v2_t *ns,
|
||||
const char *digest);
|
||||
routerstatus_t *networkstatus_vote_find_mutable_entry(networkstatus_t *ns,
|
||||
const char *digest);
|
||||
int networkstatus_vote_find_entry_idx(networkstatus_t *ns,
|
||||
const char *digest, int *found_out);
|
||||
const smartlist_t *networkstatus_get_v2_list(void);
|
||||
download_status_t *router_get_dl_status_by_descriptor_digest(const char *d);
|
||||
const routerstatus_t *router_get_consensus_status_by_id(const char *digest);
|
||||
routerstatus_t *router_get_mutable_consensus_status_by_id(
|
||||
|
@ -213,7 +213,7 @@ void
|
||||
nodelist_set_consensus(networkstatus_t *ns)
|
||||
{
|
||||
const or_options_t *options = get_options();
|
||||
int authdir = authdir_mode_v2(options) || authdir_mode_v3(options);
|
||||
int authdir = authdir_mode_v3(options);
|
||||
int client = !server_mode(options);
|
||||
|
||||
init_nodelist();
|
||||
@ -1333,7 +1333,7 @@ compute_frac_paths_available(const networkstatus_t *consensus,
|
||||
smartlist_t *myexits= smartlist_new();
|
||||
double f_guard, f_mid, f_exit, f_myexit;
|
||||
int np, nu; /* Ignored */
|
||||
const int authdir = authdir_mode_v2(options) || authdir_mode_v3(options);
|
||||
const int authdir = authdir_mode_v3(options);
|
||||
|
||||
count_usable_descriptors(num_present_out, num_usable_out,
|
||||
mid, consensus, options, now, NULL, 0);
|
||||
|
78
src/or/or.h
78
src/or/or.h
@ -407,9 +407,6 @@ typedef enum {
|
||||
/** A connection to a directory server: set after a rendezvous
|
||||
* descriptor is downloaded. */
|
||||
#define DIR_PURPOSE_HAS_FETCHED_RENDDESC 4
|
||||
/** A connection to a directory server: download one or more v2
|
||||
* network-status objects */
|
||||
#define DIR_PURPOSE_FETCH_V2_NETWORKSTATUS 5
|
||||
/** A connection to a directory server: download one or more server
|
||||
* descriptors. */
|
||||
#define DIR_PURPOSE_FETCH_SERVERDESC 6
|
||||
@ -2036,9 +2033,7 @@ typedef struct signed_descriptor_t {
|
||||
* routerlist->old_routers? -1 for none. */
|
||||
int routerlist_index;
|
||||
/** The valid-until time of the most recent consensus that listed this
|
||||
* descriptor, or a bit after the publication time of the most recent v2
|
||||
* networkstatus that listed it. 0 for "never listed in a consensus or
|
||||
* status, so far as we know." */
|
||||
* descriptor. 0 for "never listed in a consensus, so far as we know." */
|
||||
time_t last_listed_as_valid_until;
|
||||
/* If true, we do not ever try to save this object in the cache. */
|
||||
unsigned int do_not_cache : 1;
|
||||
@ -2175,10 +2170,6 @@ typedef struct routerstatus_t {
|
||||
unsigned int is_unnamed:1; /**< True iff "nickname" belongs to another
|
||||
* router. */
|
||||
unsigned int is_valid:1; /**< True iff this router isn't invalid. */
|
||||
unsigned int is_v2_dir:1; /**< True iff this router can serve directory
|
||||
* information with v2 of the directory
|
||||
* protocol. (All directory caches cache v1
|
||||
* directories.) */
|
||||
unsigned int is_possible_guard:1; /**< True iff this router would be a good
|
||||
* choice as an entry guard. */
|
||||
unsigned int is_bad_exit:1; /**< True iff this node is a bad choice for
|
||||
@ -2215,12 +2206,6 @@ typedef struct routerstatus_t {
|
||||
/* ---- The fields below aren't derived from the networkstatus; they
|
||||
* hold local information only. */
|
||||
|
||||
/** True if we, as a directory mirror, want to download the corresponding
|
||||
* routerinfo from the authority who gave us this routerstatus. (That is,
|
||||
* if we don't have the routerinfo, and if we haven't already tried to get it
|
||||
* from this authority.) Applies in v2 networkstatus document only.
|
||||
*/
|
||||
unsigned int need_to_mirror:1;
|
||||
time_t last_dir_503_at; /**< When did this router last tell us that it
|
||||
* was too busy to serve directory info? */
|
||||
download_status_t dl_status;
|
||||
@ -2385,44 +2370,6 @@ typedef struct node_t {
|
||||
|
||||
} node_t;
|
||||
|
||||
/** Contents of a v2 (non-consensus, non-vote) network status object. */
|
||||
typedef struct networkstatus_v2_t {
|
||||
/** When did we receive the network-status document? */
|
||||
time_t received_on;
|
||||
|
||||
/** What was the digest of the document? */
|
||||
char networkstatus_digest[DIGEST_LEN];
|
||||
|
||||
/* These fields come from the actual network-status document.*/
|
||||
time_t published_on; /**< Declared publication date. */
|
||||
|
||||
char *source_address; /**< Canonical directory server hostname. */
|
||||
uint32_t source_addr; /**< Canonical directory server IP. */
|
||||
uint16_t source_dirport; /**< Canonical directory server dirport. */
|
||||
|
||||
unsigned int binds_names:1; /**< True iff this directory server binds
|
||||
* names. */
|
||||
unsigned int recommends_versions:1; /**< True iff this directory server
|
||||
* recommends client and server software
|
||||
* versions. */
|
||||
unsigned int lists_bad_exits:1; /**< True iff this directory server marks
|
||||
* malfunctioning exits as bad. */
|
||||
/** True iff this directory server marks malfunctioning directories as
|
||||
* bad. */
|
||||
unsigned int lists_bad_directories:1;
|
||||
|
||||
char identity_digest[DIGEST_LEN]; /**< Digest of signing key. */
|
||||
char *contact; /**< How to contact directory admin? (may be NULL). */
|
||||
crypto_pk_t *signing_key; /**< Key used to sign this directory. */
|
||||
char *client_versions; /**< comma-separated list of recommended client
|
||||
* versions. */
|
||||
char *server_versions; /**< comma-separated list of recommended server
|
||||
* versions. */
|
||||
|
||||
smartlist_t *entries; /**< List of routerstatus_t*. This list is kept
|
||||
* sorted by identity_digest. */
|
||||
} networkstatus_v2_t;
|
||||
|
||||
/** Linked list of microdesc hash lines for a single router in a directory
|
||||
* vote.
|
||||
*/
|
||||
@ -2686,8 +2633,6 @@ typedef enum {
|
||||
/** Serves/signs v1 directory information: Big lists of routers, and short
|
||||
* routerstatus documents. */
|
||||
V1_DIRINFO = 1 << 0,
|
||||
/** Serves/signs v2 directory information: i.e. v2 networkstatus documents */
|
||||
V2_DIRINFO = 1 << 1,
|
||||
/** Serves/signs v3 directory information: votes, consensuses, certs */
|
||||
V3_DIRINFO = 1 << 2,
|
||||
/** Serves hidden service descriptors. */
|
||||
@ -3593,8 +3538,6 @@ typedef struct {
|
||||
int AuthoritativeDir; /**< Boolean: is this an authoritative directory? */
|
||||
int V1AuthoritativeDir; /**< Boolean: is this an authoritative directory
|
||||
* for version 1 directories? */
|
||||
int V2AuthoritativeDir; /**< Boolean: is this an authoritative directory
|
||||
* for version 2 directories? */
|
||||
int V3AuthoritativeDir; /**< Boolean: is this an authoritative directory
|
||||
* for version 3 directories? */
|
||||
int HSAuthoritativeDir; /**< Boolean: does this an authoritative directory
|
||||
@ -3649,8 +3592,6 @@ typedef struct {
|
||||
int PublishHidServDescriptors;
|
||||
int FetchServerDescriptors; /**< Do we fetch server descriptors as normal? */
|
||||
int FetchHidServDescriptors; /**< and hidden service descriptors? */
|
||||
int FetchV2Networkstatus; /**< Do we fetch v2 networkstatus documents when
|
||||
* we don't need to? */
|
||||
int HidServDirectoryV2; /**< Do we participate in the HS DHT? */
|
||||
|
||||
int VoteOnHidServDirectoriesV2; /**< As a directory authority, vote on
|
||||
@ -4284,16 +4225,6 @@ typedef struct {
|
||||
/** Fraction: */
|
||||
double PathsNeededToBuildCircuits;
|
||||
|
||||
/** Do we serve v2 directory info at all? This is a temporary option, since
|
||||
* we'd like to disable v2 directory serving entirely, but we need a way to
|
||||
* make it temporarily disableable, in order to do fast testing and be
|
||||
* able to turn it back on if it turns out to be non-workable.
|
||||
*
|
||||
* XXXX025 Make this always-on, or always-off. Right now, it's only
|
||||
* enableable for authorities.
|
||||
*/
|
||||
int DisableV2DirectoryInfo_;
|
||||
|
||||
/** What expiry time shall we place on our SSL certs? "0" means we
|
||||
* should guess a suitable value. */
|
||||
int SSLKeyLifetime;
|
||||
@ -4805,11 +4736,6 @@ typedef struct microdesc_cache_t microdesc_cache_t;
|
||||
|
||||
/********************************* networkstatus.c *********************/
|
||||
|
||||
/** Location where we found a v2 networkstatus. */
|
||||
typedef enum {
|
||||
NS_FROM_CACHE, NS_FROM_DIR_BY_FP, NS_FROM_DIR_ALL, NS_GENERATED
|
||||
} v2_networkstatus_source_t;
|
||||
|
||||
/** Possible statuses of a version of Tor, given opinions from the directory
|
||||
* servers. */
|
||||
typedef enum version_status_t {
|
||||
@ -5010,8 +4936,6 @@ typedef struct dir_server_t {
|
||||
/** What kind of authority is this? (Bitfield.) */
|
||||
dirinfo_type_t type;
|
||||
|
||||
download_status_t v2_ns_dl_status; /**< Status of downloading this server's
|
||||
* v2 network status. */
|
||||
time_t addr_current_at; /**< When was the document that we derived the
|
||||
* address information from published? */
|
||||
|
||||
|
@ -933,7 +933,6 @@ init_keys(void)
|
||||
/* 6b. [authdirserver only] add own key to approved directories. */
|
||||
crypto_pk_get_digest(get_server_identity_key(), digest);
|
||||
type = ((options->V1AuthoritativeDir ? V1_DIRINFO : NO_DIRINFO) |
|
||||
(options->V2AuthoritativeDir ? V2_DIRINFO : NO_DIRINFO) |
|
||||
(options->V3AuthoritativeDir ?
|
||||
(V3_DIRINFO|MICRODESC_DIRINFO|EXTRAINFO_DIRINFO) : NO_DIRINFO) |
|
||||
(options->BridgeAuthoritativeDir ? BRIDGE_DIRINFO : NO_DIRINFO) |
|
||||
@ -1260,14 +1259,6 @@ authdir_mode_v1(const or_options_t *options)
|
||||
{
|
||||
return authdir_mode(options) && options->V1AuthoritativeDir != 0;
|
||||
}
|
||||
/** Return true iff we believe ourselves to be a v2 authoritative
|
||||
* directory server.
|
||||
*/
|
||||
int
|
||||
authdir_mode_v2(const or_options_t *options)
|
||||
{
|
||||
return authdir_mode(options) && options->V2AuthoritativeDir != 0;
|
||||
}
|
||||
/** Return true iff we believe ourselves to be a v3 authoritative
|
||||
* directory server.
|
||||
*/
|
||||
@ -1276,12 +1267,11 @@ authdir_mode_v3(const or_options_t *options)
|
||||
{
|
||||
return authdir_mode(options) && options->V3AuthoritativeDir != 0;
|
||||
}
|
||||
/** Return true iff we are a v1, v2, or v3 directory authority. */
|
||||
/** Return true iff we are a v1 or v3 directory authority. */
|
||||
int
|
||||
authdir_mode_any_main(const or_options_t *options)
|
||||
{
|
||||
return options->V1AuthoritativeDir ||
|
||||
options->V2AuthoritativeDir ||
|
||||
options->V3AuthoritativeDir;
|
||||
}
|
||||
/** Return true if we believe ourselves to be any kind of
|
||||
|
@ -51,7 +51,6 @@ int net_is_disabled(void);
|
||||
|
||||
int authdir_mode(const or_options_t *options);
|
||||
int authdir_mode_v1(const or_options_t *options);
|
||||
int authdir_mode_v2(const or_options_t *options);
|
||||
int authdir_mode_v3(const or_options_t *options);
|
||||
int authdir_mode_any_main(const or_options_t *options);
|
||||
int authdir_mode_any_nonhidserv(const or_options_t *options);
|
||||
|
@ -220,8 +220,6 @@ download_status_is_ready_by_sk_in_cl(cert_list_t *cl,
|
||||
return rv;
|
||||
}
|
||||
|
||||
#define get_n_v2_authorities() get_n_authorities(V2_DIRINFO)
|
||||
|
||||
/** Helper: Return the cert_list_t for an authority whose authority ID is
|
||||
* <b>id_digest</b>, allocating a new list if necessary. */
|
||||
static cert_list_t *
|
||||
@ -1272,18 +1270,18 @@ router_pick_directory_server(dirinfo_type_t type, int flags)
|
||||
return choice;
|
||||
}
|
||||
|
||||
/** Try to determine which fraction of v2 and v3 directory requests aimed at
|
||||
* caches will be sent to us. Set *<b>v2_share_out</b> and
|
||||
* *<b>v3_share_out</b> to the fractions of v2 and v3 protocol shares we
|
||||
* expect to see, respectively. Return 0 on success, negative on failure. */
|
||||
/** Try to determine which fraction ofv3 directory requests aimed at
|
||||
* caches will be sent to us. Set
|
||||
* *<b>v3_share_out</b> to the fraction of v3 protocol shares we
|
||||
* expect to see. Return 0 on success, negative on failure. */
|
||||
/* XXXX This function is unused. */
|
||||
int
|
||||
router_get_my_share_of_directory_requests(double *v2_share_out,
|
||||
double *v3_share_out)
|
||||
router_get_my_share_of_directory_requests(double *v3_share_out)
|
||||
{
|
||||
const routerinfo_t *me = router_get_my_routerinfo();
|
||||
const routerstatus_t *rs;
|
||||
const int pds_flags = PDS_ALLOW_SELF|PDS_IGNORE_FASCISTFIREWALL;
|
||||
*v2_share_out = *v3_share_out = 0.0;
|
||||
*v3_share_out = 0.0;
|
||||
if (!me)
|
||||
return -1;
|
||||
rs = router_get_consensus_status_by_id(me->cache_info.identity_digest);
|
||||
@ -1292,15 +1290,6 @@ router_get_my_share_of_directory_requests(double *v2_share_out,
|
||||
|
||||
/* Calling for side effect */
|
||||
/* XXXX This is a bit of a kludge */
|
||||
if (rs->is_v2_dir) {
|
||||
sl_last_total_weighted_bw = 0;
|
||||
router_pick_directory_server(V2_DIRINFO, pds_flags);
|
||||
if (sl_last_total_weighted_bw != 0) {
|
||||
*v2_share_out = U64_TO_DBL(sl_last_weighted_bw_of_me) /
|
||||
U64_TO_DBL(sl_last_total_weighted_bw);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
sl_last_total_weighted_bw = 0;
|
||||
router_pick_directory_server(V3_DIRINFO, pds_flags);
|
||||
@ -1472,8 +1461,6 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags)
|
||||
if (requireother && router_digest_is_me(node->identity))
|
||||
continue;
|
||||
is_trusted = router_digest_is_trusted_dir(node->identity);
|
||||
if ((type & V2_DIRINFO) && !(node->rs->is_v2_dir || is_trusted))
|
||||
continue;
|
||||
if ((type & EXTRAINFO_DIRINFO) &&
|
||||
!router_supports_extrainfo(node->identity, 0))
|
||||
continue;
|
||||
@ -1700,7 +1687,6 @@ mark_all_dirservers_up(smartlist_t *server_list)
|
||||
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;
|
||||
@ -3354,7 +3340,6 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
|
||||
routerinfo_t *old_router;
|
||||
networkstatus_t *consensus =
|
||||
networkstatus_get_latest_consensus_by_flavor(FLAV_NS);
|
||||
const smartlist_t *networkstatus_v2_list = networkstatus_get_v2_list();
|
||||
int in_consensus = 0;
|
||||
|
||||
tor_assert(msg);
|
||||
@ -3425,15 +3410,6 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
|
||||
}
|
||||
|
||||
/* We no longer need a router with this descriptor digest. */
|
||||
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
|
||||
{
|
||||
routerstatus_t *rs =
|
||||
networkstatus_v2_find_mutable_entry(ns, id_digest);
|
||||
if (rs && tor_memeq(rs->descriptor_digest,
|
||||
router->cache_info.signed_descriptor_digest,
|
||||
DIGEST_LEN))
|
||||
rs->need_to_mirror = 0;
|
||||
});
|
||||
if (consensus) {
|
||||
routerstatus_t *rs = networkstatus_vote_find_mutable_entry(
|
||||
consensus, id_digest);
|
||||
@ -3441,7 +3417,6 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
|
||||
router->cache_info.signed_descriptor_digest,
|
||||
DIGEST_LEN)) {
|
||||
in_consensus = 1;
|
||||
rs->need_to_mirror = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3680,11 +3655,7 @@ routerlist_remove_old_routers(void)
|
||||
routerinfo_t *router;
|
||||
signed_descriptor_t *sd;
|
||||
digestset_t *retain;
|
||||
int caches = directory_caches_dir_info(get_options());
|
||||
const networkstatus_t *consensus = networkstatus_get_latest_consensus();
|
||||
const smartlist_t *networkstatus_v2_list = networkstatus_get_v2_list();
|
||||
int have_enough_v2;
|
||||
const or_options_t *options = get_options();
|
||||
|
||||
trusted_dirs_remove_old_certs();
|
||||
|
||||
@ -3700,38 +3671,10 @@ routerlist_remove_old_routers(void)
|
||||
{
|
||||
/* We'll probably retain everything in the consensus. */
|
||||
int n_max_retain = smartlist_len(consensus->routerstatus_list);
|
||||
if (caches && networkstatus_v2_list) {
|
||||
/* If we care about v2 statuses, we'll retain at most as many as are
|
||||
listed any of the v2 statues. This will be at least the length of
|
||||
the largest v2 networkstatus, and in the worst case, this set will be
|
||||
equal to the sum of the lengths of all v2 consensuses. Take the
|
||||
worst case.
|
||||
*/
|
||||
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
|
||||
n_max_retain += smartlist_len(ns->entries));
|
||||
}
|
||||
retain = digestset_new(n_max_retain);
|
||||
}
|
||||
|
||||
cutoff = now - OLD_ROUTER_DESC_MAX_AGE;
|
||||
/* Build a list of all the descriptors that _anybody_ lists. */
|
||||
if (caches && networkstatus_v2_list) {
|
||||
SMARTLIST_FOREACH_BEGIN(networkstatus_v2_list, networkstatus_v2_t *, ns) {
|
||||
/* XXXX The inner loop here gets pretty expensive, and actually shows up
|
||||
* on some profiles. It may be the reason digestmap_set shows up in
|
||||
* profiles too. If instead we kept a per-descriptor digest count of
|
||||
* how many networkstatuses recommended each descriptor, and changed
|
||||
* that only when the networkstatuses changed, that would be a speed
|
||||
* improvement, possibly 1-4% if it also removes digestmap_set from the
|
||||
* profile. Not worth it for 0.1.2.x, though. The new directory
|
||||
* system will obsolete this whole thing in 0.2.0.x. */
|
||||
SMARTLIST_FOREACH_BEGIN(ns->entries, routerstatus_t *, rs) {
|
||||
if (rs->published_on >= cutoff)
|
||||
digestset_add(retain, rs->descriptor_digest);
|
||||
} SMARTLIST_FOREACH_END(rs);
|
||||
} SMARTLIST_FOREACH_END(ns);
|
||||
}
|
||||
|
||||
/* Retain anything listed in the consensus. */
|
||||
if (consensus) {
|
||||
SMARTLIST_FOREACH(consensus->routerstatus_list, routerstatus_t *, rs,
|
||||
@ -3739,18 +3682,13 @@ routerlist_remove_old_routers(void)
|
||||
digestset_add(retain, rs->descriptor_digest));
|
||||
}
|
||||
|
||||
/* If we have a consensus, and nearly as many v2 networkstatuses as we want,
|
||||
/* If we have a consensus,
|
||||
* we should consider pruning current routers that are too old and that
|
||||
* nobody recommends. (If we don't have a consensus or enough v2
|
||||
* networkstatuses, then we should get more before we decide to kill
|
||||
* routers.) */
|
||||
/* we set this to true iff we don't care about v2 info, or we have enough. */
|
||||
have_enough_v2 = !caches ||
|
||||
!(authdir_mode_any_main(options) || options->FetchV2Networkstatus) ||
|
||||
(networkstatus_v2_list &&
|
||||
smartlist_len(networkstatus_v2_list) > get_n_v2_authorities() / 2);
|
||||
|
||||
if (have_enough_v2 && consensus) {
|
||||
if (consensus) {
|
||||
cutoff = now - ROUTER_MAX_AGE;
|
||||
/* Remove too-old unrecommended members of routerlist->routers. */
|
||||
for (i = 0; i < smartlist_len(routerlist->routers); ++i) {
|
||||
@ -4049,8 +3987,6 @@ signed_desc_digest_is_recognized(signed_descriptor_t *desc)
|
||||
{
|
||||
const routerstatus_t *rs;
|
||||
networkstatus_t *consensus = networkstatus_get_latest_consensus();
|
||||
int caches = directory_caches_dir_info(get_options());
|
||||
const smartlist_t *networkstatus_v2_list = networkstatus_get_v2_list();
|
||||
|
||||
if (consensus) {
|
||||
rs = networkstatus_vote_find_entry(consensus, desc->identity_digest);
|
||||
@ -4058,16 +3994,6 @@ signed_desc_digest_is_recognized(signed_descriptor_t *desc)
|
||||
desc->signed_descriptor_digest, DIGEST_LEN))
|
||||
return 1;
|
||||
}
|
||||
if (caches && networkstatus_v2_list) {
|
||||
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
|
||||
{
|
||||
if (!(rs = networkstatus_v2_find_entry(ns, desc->identity_digest)))
|
||||
continue;
|
||||
if (tor_memeq(rs->descriptor_digest,
|
||||
desc->signed_descriptor_digest, DIGEST_LEN))
|
||||
return 1;
|
||||
});
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4083,7 +4009,7 @@ update_all_descriptor_downloads(time_t now)
|
||||
launch_dummy_descriptor_download_as_needed(now, get_options());
|
||||
}
|
||||
|
||||
/** Clear all our timeouts for fetching v2 and v3 directory stuff, and then
|
||||
/** Clear all our timeouts for fetching v3 directory stuff, and then
|
||||
* give it all a try again. */
|
||||
void
|
||||
routerlist_retry_directory_downloads(time_t now)
|
||||
@ -4564,152 +4490,6 @@ launch_descriptor_downloads(int purpose,
|
||||
}
|
||||
}
|
||||
|
||||
/** Launch downloads for router status as needed, using the strategy used by
|
||||
* authorities and caches: based on the v2 networkstatuses we have, download
|
||||
* every descriptor we don't have but would serve, from a random authority
|
||||
* that lists it. */
|
||||
static void
|
||||
update_router_descriptor_cache_downloads_v2(time_t now)
|
||||
{
|
||||
smartlist_t **downloadable; /* For each authority, what can we dl from it? */
|
||||
smartlist_t **download_from; /* ... and, what will we dl from it? */
|
||||
digestmap_t *map; /* Which descs are in progress, or assigned? */
|
||||
int i, j, n;
|
||||
int n_download;
|
||||
const or_options_t *options = get_options();
|
||||
const smartlist_t *networkstatus_v2_list = networkstatus_get_v2_list();
|
||||
|
||||
if (! directory_fetches_dir_info_early(options)) {
|
||||
log_warn(LD_BUG, "Called update_router_descriptor_cache_downloads_v2() "
|
||||
"on a non-dir-mirror?");
|
||||
}
|
||||
|
||||
if (!networkstatus_v2_list || !smartlist_len(networkstatus_v2_list))
|
||||
return;
|
||||
|
||||
map = digestmap_new();
|
||||
n = smartlist_len(networkstatus_v2_list);
|
||||
|
||||
downloadable = tor_malloc_zero(sizeof(smartlist_t*) * n);
|
||||
download_from = tor_malloc_zero(sizeof(smartlist_t*) * n);
|
||||
|
||||
/* Set map[d]=1 for the digest of every descriptor that we are currently
|
||||
* downloading. */
|
||||
list_pending_descriptor_downloads(map, 0);
|
||||
|
||||
/* For the digest of every descriptor that we don't have, and that we aren't
|
||||
* downloading, add d to downloadable[i] if the i'th networkstatus knows
|
||||
* about that descriptor, and we haven't already failed to get that
|
||||
* descriptor from the corresponding authority.
|
||||
*/
|
||||
n_download = 0;
|
||||
SMARTLIST_FOREACH_BEGIN(networkstatus_v2_list, networkstatus_v2_t *, ns) {
|
||||
dir_server_t *ds;
|
||||
smartlist_t *dl;
|
||||
dl = downloadable[ns_sl_idx] = smartlist_new();
|
||||
download_from[ns_sl_idx] = smartlist_new();
|
||||
if (ns->published_on + MAX_NETWORKSTATUS_AGE+10*60 < now) {
|
||||
/* Don't download if the networkstatus is almost ancient. */
|
||||
/* Actually, I suspect what's happening here is that we ask
|
||||
* for the descriptor when we have a given networkstatus,
|
||||
* and then we get a newer networkstatus, and then we receive
|
||||
* the descriptor. Having a networkstatus actually expire is
|
||||
* probably a rare event, and we'll probably be happiest if
|
||||
* we take this clause out. -RD */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Don't try dirservers that we think are down -- we might have
|
||||
* just tried them and just marked them as down. */
|
||||
ds = router_get_trusteddirserver_by_digest(ns->identity_digest);
|
||||
if (ds && !ds->is_running)
|
||||
continue;
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(ns->entries, routerstatus_t * , rs) {
|
||||
if (!rs->need_to_mirror)
|
||||
continue;
|
||||
if (router_get_by_descriptor_digest(rs->descriptor_digest)) {
|
||||
log_warn(LD_BUG,
|
||||
"We have a router descriptor, but need_to_mirror=1.");
|
||||
rs->need_to_mirror = 0;
|
||||
continue;
|
||||
}
|
||||
if (authdir_mode(options) && dirserv_would_reject_router(rs)) {
|
||||
rs->need_to_mirror = 0;
|
||||
continue;
|
||||
}
|
||||
if (digestmap_get(map, rs->descriptor_digest)) {
|
||||
/* We're downloading it already. */
|
||||
continue;
|
||||
} else {
|
||||
/* We could download it from this guy. */
|
||||
smartlist_add(dl, rs->descriptor_digest);
|
||||
++n_download;
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(rs);
|
||||
} SMARTLIST_FOREACH_END(ns);
|
||||
|
||||
/* At random, assign descriptors to authorities such that:
|
||||
* - if d is a member of some downloadable[x], d is a member of some
|
||||
* download_from[y]. (Everything we want to download, we try to download
|
||||
* from somebody.)
|
||||
* - If d is a member of download_from[y], d is a member of downloadable[y].
|
||||
* (We only try to download descriptors from authorities who claim to have
|
||||
* them.)
|
||||
* - No d is a member of download_from[x] and download_from[y] s.t. x != y.
|
||||
* (We don't try to download anything from two authorities concurrently.)
|
||||
*/
|
||||
while (n_download) {
|
||||
int which_ns = crypto_rand_int(n);
|
||||
smartlist_t *dl = downloadable[which_ns];
|
||||
int idx;
|
||||
char *d;
|
||||
if (!smartlist_len(dl))
|
||||
continue;
|
||||
idx = crypto_rand_int(smartlist_len(dl));
|
||||
d = smartlist_get(dl, idx);
|
||||
if (! digestmap_get(map, d)) {
|
||||
smartlist_add(download_from[which_ns], d);
|
||||
digestmap_set(map, d, (void*) 1);
|
||||
}
|
||||
smartlist_del(dl, idx);
|
||||
--n_download;
|
||||
}
|
||||
|
||||
/* Now, we can actually launch our requests. */
|
||||
for (i=0; i<n; ++i) {
|
||||
networkstatus_v2_t *ns = smartlist_get(networkstatus_v2_list, i);
|
||||
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;
|
||||
if (! authdir_mode_any_nonhidserv(options))
|
||||
pds_flags |= PDS_NO_EXISTING_SERVERDESC_FETCH; /* XXXX ignored*/
|
||||
|
||||
if (!ds) {
|
||||
log_info(LD_DIR, "Networkstatus with no corresponding authority!");
|
||||
continue;
|
||||
}
|
||||
if (! smartlist_len(dl))
|
||||
continue;
|
||||
log_info(LD_DIR, "Requesting %d descriptors from authority \"%s\"",
|
||||
smartlist_len(dl), ds->nickname);
|
||||
for (j=0; j < smartlist_len(dl); j += MAX_DL_PER_REQUEST) {
|
||||
initiate_descriptor_downloads(&(ds->fake_status),
|
||||
DIR_PURPOSE_FETCH_SERVERDESC, dl, j,
|
||||
j+MAX_DL_PER_REQUEST, pds_flags);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<n; ++i) {
|
||||
smartlist_free(download_from[i]);
|
||||
smartlist_free(downloadable[i]);
|
||||
}
|
||||
tor_free(download_from);
|
||||
tor_free(downloadable);
|
||||
digestmap_free(map,NULL);
|
||||
}
|
||||
|
||||
/** For any descriptor that we want that's currently listed in
|
||||
* <b>consensus</b>, download it as appropriate. */
|
||||
void
|
||||
@ -4874,9 +4654,6 @@ update_router_descriptor_downloads(time_t now)
|
||||
return;
|
||||
if (!we_fetch_router_descriptors(options))
|
||||
return;
|
||||
if (directory_fetches_dir_info_early(options)) {
|
||||
update_router_descriptor_cache_downloads_v2(now);
|
||||
}
|
||||
|
||||
update_consensus_router_descriptor_downloads(now, 0,
|
||||
networkstatus_get_reasonably_live_consensus(now, FLAV_NS));
|
||||
|
@ -54,8 +54,7 @@ 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);
|
||||
int router_get_my_share_of_directory_requests(double *v3_share_out);
|
||||
void router_reset_status_download_failures(void);
|
||||
int routers_have_same_or_addrs(const routerinfo_t *r1, const routerinfo_t *r2);
|
||||
const routerinfo_t *routerlist_find_my_routerinfo(void);
|
||||
|
@ -353,31 +353,6 @@ static token_rule_t rtrstatus_token_table[] = {
|
||||
END_OF_TABLE
|
||||
};
|
||||
|
||||
/** List of tokens recognized in the header part of v2 networkstatus documents.
|
||||
*/
|
||||
static token_rule_t netstatus_token_table[] = {
|
||||
T1( "published", K_PUBLISHED, CONCAT_ARGS, NO_OBJ ),
|
||||
T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ),
|
||||
T1( "contact", K_CONTACT, CONCAT_ARGS, NO_OBJ ),
|
||||
T1( "dir-signing-key", K_DIR_SIGNING_KEY, NO_ARGS, NEED_KEY_1024 ),
|
||||
T1( "fingerprint", K_FINGERPRINT, CONCAT_ARGS, NO_OBJ ),
|
||||
T1_START("network-status-version", K_NETWORK_STATUS_VERSION,
|
||||
GE(1), NO_OBJ ),
|
||||
T1( "dir-source", K_DIR_SOURCE, GE(3), NO_OBJ ),
|
||||
T01("dir-options", K_DIR_OPTIONS, ARGS, NO_OBJ ),
|
||||
T01("client-versions", K_CLIENT_VERSIONS, CONCAT_ARGS, NO_OBJ ),
|
||||
T01("server-versions", K_SERVER_VERSIONS, CONCAT_ARGS, NO_OBJ ),
|
||||
|
||||
END_OF_TABLE
|
||||
};
|
||||
|
||||
/** List of tokens recognized in the footer of v1/v2 directory/networkstatus
|
||||
* footers. */
|
||||
static token_rule_t dir_footer_token_table[] = {
|
||||
T1("directory-signature", K_DIRECTORY_SIGNATURE, EQ(1), NEED_OBJ ),
|
||||
END_OF_TABLE
|
||||
};
|
||||
|
||||
/** List of tokens common to V3 authority certificates and V3 consensuses. */
|
||||
#define CERTIFICATE_MEMBERS \
|
||||
T1("dir-key-certificate-version", K_DIR_KEY_CERTIFICATE_VERSION, \
|
||||
@ -640,17 +615,6 @@ router_get_runningrouters_hash(const char *s, char *digest)
|
||||
DIGEST_SHA1);
|
||||
}
|
||||
|
||||
/** Set <b>digest</b> to the SHA-1 digest of the hash of the network-status
|
||||
* string in <b>s</b>. Return 0 on success, -1 on failure. */
|
||||
int
|
||||
router_get_networkstatus_v2_hash(const char *s, char *digest)
|
||||
{
|
||||
return router_get_hash_impl(s, strlen(s), digest,
|
||||
"network-status-version","\ndirectory-signature",
|
||||
'\n',
|
||||
DIGEST_SHA1);
|
||||
}
|
||||
|
||||
/** Set <b>digests</b> to all the digests of the consensus document in
|
||||
* <b>s</b> */
|
||||
int
|
||||
@ -1943,8 +1907,6 @@ routerstatus_parse_entry_from_string(memarea_t *area,
|
||||
rs->is_named = 1;
|
||||
else if (!strcmp(tok->args[i], "Valid"))
|
||||
rs->is_valid = 1;
|
||||
else if (!strcmp(tok->args[i], "V2Dir"))
|
||||
rs->is_v2_dir = 1;
|
||||
else if (!strcmp(tok->args[i], "Guard"))
|
||||
rs->is_possible_guard = 1;
|
||||
else if (!strcmp(tok->args[i], "BadExit"))
|
||||
@ -2095,188 +2057,6 @@ compare_vote_routerstatus_entries(const void **_a, const void **_b)
|
||||
DIGEST_LEN);
|
||||
}
|
||||
|
||||
/** Helper: used in call to _smartlist_uniq to clear out duplicate entries. */
|
||||
static void
|
||||
free_duplicate_routerstatus_entry_(void *e)
|
||||
{
|
||||
log_warn(LD_DIR,
|
||||
"Network-status has two entries for the same router. "
|
||||
"Dropping one.");
|
||||
routerstatus_free(e);
|
||||
}
|
||||
|
||||
/** Given a v2 network-status object in <b>s</b>, try to
|
||||
* parse it and return the result. Return NULL on failure. Check the
|
||||
* signature of the network status, but do not (yet) check the signing key for
|
||||
* authority.
|
||||
*/
|
||||
networkstatus_v2_t *
|
||||
networkstatus_v2_parse_from_string(const char *s)
|
||||
{
|
||||
const char *eos, *s_dup = s;
|
||||
smartlist_t *tokens = smartlist_new();
|
||||
smartlist_t *footer_tokens = smartlist_new();
|
||||
networkstatus_v2_t *ns = NULL;
|
||||
char ns_digest[DIGEST_LEN];
|
||||
char tmp_digest[DIGEST_LEN];
|
||||
struct in_addr in;
|
||||
directory_token_t *tok;
|
||||
int i;
|
||||
memarea_t *area = NULL;
|
||||
|
||||
if (router_get_networkstatus_v2_hash(s, ns_digest)) {
|
||||
log_warn(LD_DIR, "Unable to compute digest of network-status");
|
||||
goto err;
|
||||
}
|
||||
|
||||
area = memarea_new();
|
||||
eos = find_start_of_next_routerstatus(s);
|
||||
if (tokenize_string(area, s, eos, tokens, netstatus_token_table,0)) {
|
||||
log_warn(LD_DIR, "Error tokenizing network-status header.");
|
||||
goto err;
|
||||
}
|
||||
ns = tor_malloc_zero(sizeof(networkstatus_v2_t));
|
||||
memcpy(ns->networkstatus_digest, ns_digest, DIGEST_LEN);
|
||||
|
||||
tok = find_by_keyword(tokens, K_NETWORK_STATUS_VERSION);
|
||||
tor_assert(tok->n_args >= 1);
|
||||
if (strcmp(tok->args[0], "2")) {
|
||||
log_warn(LD_BUG, "Got a non-v2 networkstatus. Version was "
|
||||
"%s", escaped(tok->args[0]));
|
||||
goto err;
|
||||
}
|
||||
|
||||
tok = find_by_keyword(tokens, K_DIR_SOURCE);
|
||||
tor_assert(tok->n_args >= 3);
|
||||
ns->source_address = tor_strdup(tok->args[0]);
|
||||
if (tor_inet_aton(tok->args[1], &in) == 0) {
|
||||
log_warn(LD_DIR, "Error parsing network-status source address %s",
|
||||
escaped(tok->args[1]));
|
||||
goto err;
|
||||
}
|
||||
ns->source_addr = ntohl(in.s_addr);
|
||||
ns->source_dirport =
|
||||
(uint16_t) tor_parse_long(tok->args[2],10,0,65535,NULL,NULL);
|
||||
if (ns->source_dirport == 0) {
|
||||
log_warn(LD_DIR, "Directory source without dirport; skipping.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
tok = find_by_keyword(tokens, K_FINGERPRINT);
|
||||
tor_assert(tok->n_args);
|
||||
if (base16_decode(ns->identity_digest, DIGEST_LEN, tok->args[0],
|
||||
strlen(tok->args[0]))) {
|
||||
log_warn(LD_DIR, "Couldn't decode networkstatus fingerprint %s",
|
||||
escaped(tok->args[0]));
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((tok = find_opt_by_keyword(tokens, K_CONTACT))) {
|
||||
tor_assert(tok->n_args);
|
||||
ns->contact = tor_strdup(tok->args[0]);
|
||||
}
|
||||
|
||||
tok = find_by_keyword(tokens, K_DIR_SIGNING_KEY);
|
||||
tor_assert(tok->key);
|
||||
ns->signing_key = tok->key;
|
||||
tok->key = NULL;
|
||||
|
||||
if (crypto_pk_get_digest(ns->signing_key, tmp_digest)<0) {
|
||||
log_warn(LD_DIR, "Couldn't compute signing key digest");
|
||||
goto err;
|
||||
}
|
||||
if (tor_memneq(tmp_digest, ns->identity_digest, DIGEST_LEN)) {
|
||||
log_warn(LD_DIR,
|
||||
"network-status fingerprint did not match dir-signing-key");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((tok = find_opt_by_keyword(tokens, K_DIR_OPTIONS))) {
|
||||
for (i=0; i < tok->n_args; ++i) {
|
||||
if (!strcmp(tok->args[i], "Names"))
|
||||
ns->binds_names = 1;
|
||||
if (!strcmp(tok->args[i], "Versions"))
|
||||
ns->recommends_versions = 1;
|
||||
if (!strcmp(tok->args[i], "BadExits"))
|
||||
ns->lists_bad_exits = 1;
|
||||
if (!strcmp(tok->args[i], "BadDirectories"))
|
||||
ns->lists_bad_directories = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ns->recommends_versions) {
|
||||
if (!(tok = find_opt_by_keyword(tokens, K_CLIENT_VERSIONS))) {
|
||||
log_warn(LD_DIR, "Missing client-versions on versioning directory");
|
||||
goto err;
|
||||
}
|
||||
ns->client_versions = tor_strdup(tok->args[0]);
|
||||
|
||||
if (!(tok = find_opt_by_keyword(tokens, K_SERVER_VERSIONS)) ||
|
||||
tok->n_args<1) {
|
||||
log_warn(LD_DIR, "Missing server-versions on versioning directory");
|
||||
goto err;
|
||||
}
|
||||
ns->server_versions = tor_strdup(tok->args[0]);
|
||||
}
|
||||
|
||||
tok = find_by_keyword(tokens, K_PUBLISHED);
|
||||
tor_assert(tok->n_args == 1);
|
||||
if (parse_iso_time(tok->args[0], &ns->published_on) < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ns->entries = smartlist_new();
|
||||
s = eos;
|
||||
SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
|
||||
smartlist_clear(tokens);
|
||||
memarea_clear(area);
|
||||
while (!strcmpstart(s, "r ")) {
|
||||
routerstatus_t *rs;
|
||||
if ((rs = routerstatus_parse_entry_from_string(area, &s, tokens,
|
||||
NULL, NULL, 0, 0)))
|
||||
smartlist_add(ns->entries, rs);
|
||||
}
|
||||
smartlist_sort(ns->entries, compare_routerstatus_entries);
|
||||
smartlist_uniq(ns->entries, compare_routerstatus_entries,
|
||||
free_duplicate_routerstatus_entry_);
|
||||
|
||||
if (tokenize_string(area,s, NULL, footer_tokens, dir_footer_token_table,0)) {
|
||||
log_warn(LD_DIR, "Error tokenizing network-status footer.");
|
||||
goto err;
|
||||
}
|
||||
if (smartlist_len(footer_tokens) < 1) {
|
||||
log_warn(LD_DIR, "Too few items in network-status footer.");
|
||||
goto err;
|
||||
}
|
||||
tok = smartlist_get(footer_tokens, smartlist_len(footer_tokens)-1);
|
||||
if (tok->tp != K_DIRECTORY_SIGNATURE) {
|
||||
log_warn(LD_DIR,
|
||||
"Expected network-status footer to end with a signature.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
note_crypto_pk_op(VERIFY_DIR);
|
||||
if (check_signature_token(ns_digest, DIGEST_LEN, tok, ns->signing_key, 0,
|
||||
"network-status") < 0)
|
||||
goto err;
|
||||
|
||||
goto done;
|
||||
err:
|
||||
dump_desc(s_dup, "v2 networkstatus");
|
||||
networkstatus_v2_free(ns);
|
||||
ns = NULL;
|
||||
done:
|
||||
SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
|
||||
smartlist_free(tokens);
|
||||
SMARTLIST_FOREACH(footer_tokens, directory_token_t *, t, token_clear(t));
|
||||
smartlist_free(footer_tokens);
|
||||
if (area) {
|
||||
DUMP_AREA(area, "v2 networkstatus");
|
||||
memarea_drop_all(area);
|
||||
}
|
||||
return ns;
|
||||
}
|
||||
|
||||
/** Verify the bandwidth weights of a network status document */
|
||||
int
|
||||
networkstatus_verify_bw_weights(networkstatus_t *ns, int consensus_method)
|
||||
|
@ -15,7 +15,6 @@
|
||||
int router_get_router_hash(const char *s, size_t s_len, char *digest);
|
||||
int router_get_dir_hash(const char *s, char *digest);
|
||||
int router_get_runningrouters_hash(const char *s, char *digest);
|
||||
int router_get_networkstatus_v2_hash(const char *s, char *digest);
|
||||
int router_get_networkstatus_v3_hashes(const char *s, digests_t *digests);
|
||||
int router_get_extrainfo_hash(const char *s, size_t s_len, char *digest);
|
||||
#define DIROBJ_MAX_SIG_LEN 256
|
||||
@ -54,7 +53,6 @@ void dump_distinct_digest_count(int severity);
|
||||
|
||||
int compare_routerstatus_entries(const void **_a, const void **_b);
|
||||
int compare_vote_routerstatus_entries(const void **_a, const void **_b);
|
||||
networkstatus_v2_t *networkstatus_v2_parse_from_string(const char *s);
|
||||
int networkstatus_verify_bw_weights(networkstatus_t *ns, int);
|
||||
networkstatus_t *networkstatus_parse_vote_from_string(const char *s,
|
||||
const char **eos_out,
|
||||
|
@ -941,7 +941,7 @@ gen_routerstatus_for_v3ns(int idx, time_t now)
|
||||
tor_addr_copy(&rs->ipv6_addr, &addr_ipv6);
|
||||
rs->ipv6_orport = 4711;
|
||||
rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running =
|
||||
rs->is_valid = rs->is_v2_dir = rs->is_possible_guard = 1;
|
||||
rs->is_valid = rs->is_possible_guard = 1;
|
||||
break;
|
||||
case 2:
|
||||
/* Generate the third routerstatus. */
|
||||
@ -956,7 +956,7 @@ gen_routerstatus_for_v3ns(int idx, time_t now)
|
||||
rs->or_port = 400;
|
||||
rs->dir_port = 9999;
|
||||
rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
|
||||
rs->is_flagged_running = rs->is_valid = rs->is_v2_dir =
|
||||
rs->is_flagged_running = rs->is_valid =
|
||||
rs->is_possible_guard = 1;
|
||||
break;
|
||||
case 3:
|
||||
@ -1065,7 +1065,7 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
|
||||
test_eq(rs->addr, 0x99008801);
|
||||
test_eq(rs->or_port, 443);
|
||||
test_eq(rs->dir_port, 8000);
|
||||
test_eq(vrs->flags, U64_LITERAL(16)); // no flags except "running"
|
||||
test_eq(vrs->flags, U64_LITERAL(80)); // no flags except "running"
|
||||
} else if (tor_memeq(rs->identity_digest,
|
||||
"\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
|
||||
"\x5\x5\x5\x5",
|
||||
@ -1090,10 +1090,10 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
|
||||
test_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
|
||||
test_eq(rs->ipv6_orport, 4711);
|
||||
if (voter == 1) {
|
||||
test_eq(vrs->flags, U64_LITERAL(254)); // all flags except "authority."
|
||||
test_eq(vrs->flags, U64_LITERAL(190)); // all except "authority","v2dir"
|
||||
} else {
|
||||
/* 1023 - authority(1) - madeofcheese(16) - madeoftin(32) */
|
||||
test_eq(vrs->flags, U64_LITERAL(974));
|
||||
/* 1023 - authority(1) - madeofcheese(16) - madeoftin(32) - v2dir(256) */
|
||||
test_eq(vrs->flags, U64_LITERAL(718));
|
||||
}
|
||||
} else if (tor_memeq(rs->identity_digest,
|
||||
"\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
|
||||
@ -1161,7 +1161,6 @@ test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now)
|
||||
test_assert(!rs->is_stable);
|
||||
/* (If it wasn't running it wouldn't be here) */
|
||||
test_assert(rs->is_flagged_running);
|
||||
test_assert(!rs->is_v2_dir);
|
||||
test_assert(!rs->is_valid);
|
||||
test_assert(!rs->is_named);
|
||||
/* XXXX check version */
|
||||
@ -1188,7 +1187,6 @@ test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now)
|
||||
test_assert(rs->is_possible_guard);
|
||||
test_assert(rs->is_stable);
|
||||
test_assert(rs->is_flagged_running);
|
||||
test_assert(rs->is_v2_dir);
|
||||
test_assert(rs->is_valid);
|
||||
test_assert(!rs->is_named);
|
||||
/* XXXX check version */
|
||||
@ -1889,7 +1887,7 @@ gen_routerstatus_for_umbw(int idx, time_t now)
|
||||
tor_addr_copy(&rs->ipv6_addr, &addr_ipv6);
|
||||
rs->ipv6_orport = 4711;
|
||||
rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running =
|
||||
rs->is_valid = rs->is_v2_dir = rs->is_possible_guard = 1;
|
||||
rs->is_valid = rs->is_possible_guard = 1;
|
||||
/*
|
||||
* This one has measured bandwidth above the clip cutoff, and
|
||||
* so shouldn't be clipped; we'll have to test that it isn't
|
||||
@ -1912,7 +1910,7 @@ gen_routerstatus_for_umbw(int idx, time_t now)
|
||||
rs->or_port = 400;
|
||||
rs->dir_port = 9999;
|
||||
rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
|
||||
rs->is_flagged_running = rs->is_valid = rs->is_v2_dir =
|
||||
rs->is_flagged_running = rs->is_valid =
|
||||
rs->is_possible_guard = 1;
|
||||
/*
|
||||
* This one has unmeasured bandwidth above the clip cutoff, and
|
||||
@ -2148,7 +2146,6 @@ test_routerstatus_for_umbw(routerstatus_t *rs, time_t now)
|
||||
test_assert(!rs->is_stable);
|
||||
/* (If it wasn't running it wouldn't be here) */
|
||||
test_assert(rs->is_flagged_running);
|
||||
test_assert(!rs->is_v2_dir);
|
||||
test_assert(!rs->is_valid);
|
||||
test_assert(!rs->is_named);
|
||||
/* This one should have measured bandwidth below the clip cutoff */
|
||||
@ -2179,7 +2176,6 @@ test_routerstatus_for_umbw(routerstatus_t *rs, time_t now)
|
||||
test_assert(rs->is_possible_guard);
|
||||
test_assert(rs->is_stable);
|
||||
test_assert(rs->is_flagged_running);
|
||||
test_assert(rs->is_v2_dir);
|
||||
test_assert(rs->is_valid);
|
||||
test_assert(!rs->is_named);
|
||||
/* This one should have measured bandwidth above the clip cutoff */
|
||||
@ -2257,82 +2253,6 @@ test_dir_clip_unmeasured_bw_kb_alt(void)
|
||||
test_routerstatus_for_umbw);
|
||||
}
|
||||
|
||||
extern time_t time_of_process_start; /* from main.c */
|
||||
|
||||
static void
|
||||
test_dir_v2_dir(void *arg)
|
||||
{
|
||||
/* Runs in a forked process: acts like a v2 directory just enough to make and
|
||||
* sign a v2 networkstatus opinion */
|
||||
|
||||
cached_dir_t *v2 = NULL;
|
||||
or_options_t *options = get_options_mutable();
|
||||
crypto_pk_t *id_key = pk_generate(4);
|
||||
(void) arg;
|
||||
|
||||
options->ORPort_set = 1; /* So we believe we're a server. */
|
||||
options->DirPort_set = 1;
|
||||
options->Address = tor_strdup("99.99.99.99");
|
||||
options->Nickname = tor_strdup("TestV2Auth");
|
||||
options->ContactInfo = tor_strdup("TestV2Auth <testv2auth@example.com>");
|
||||
{
|
||||
/* Give it a DirPort */
|
||||
smartlist_t *ports = (smartlist_t *)get_configured_ports();
|
||||
port_cfg_t *port = tor_malloc_zero(sizeof(port_cfg_t));
|
||||
port->type = CONN_TYPE_DIR_LISTENER;
|
||||
port->port = 9999;
|
||||
smartlist_add(ports, port);
|
||||
}
|
||||
set_server_identity_key(id_key);
|
||||
set_client_identity_key(id_key);
|
||||
|
||||
/* Add a router. */
|
||||
{
|
||||
was_router_added_t wra;
|
||||
const char *msg = NULL;
|
||||
routerinfo_t *r1 = tor_malloc_zero(sizeof(routerinfo_t));
|
||||
r1->address = tor_strdup("18.244.0.1");
|
||||
r1->addr = 0xc0a80001u; /* 192.168.0.1 */
|
||||
r1->cache_info.published_on = time(NULL)-60;
|
||||
r1->or_port = 9000;
|
||||
r1->dir_port = 9003;
|
||||
tor_addr_parse(&r1->ipv6_addr, "1:2:3:4::");
|
||||
r1->ipv6_orport = 9999;
|
||||
r1->onion_pkey = pk_generate(1);
|
||||
r1->identity_pkey = pk_generate(2);
|
||||
r1->bandwidthrate = 1000;
|
||||
r1->bandwidthburst = 5000;
|
||||
r1->bandwidthcapacity = 10000;
|
||||
r1->exit_policy = NULL;
|
||||
r1->nickname = tor_strdup("Magri");
|
||||
r1->platform = tor_strdup("Tor 0.2.7.7-gamma");
|
||||
r1->cache_info.routerlist_index = -1;
|
||||
r1->cache_info.signed_descriptor_body =
|
||||
router_dump_router_to_string(r1, r1->identity_pkey);
|
||||
r1->cache_info.signed_descriptor_len =
|
||||
strlen(r1->cache_info.signed_descriptor_body);
|
||||
wra = router_add_to_routerlist(r1, &msg, 0, 0);
|
||||
tt_int_op(wra, ==, ROUTER_ADDED_SUCCESSFULLY);
|
||||
}
|
||||
|
||||
/* Prevent call of rep_hist_note_router_unreachable(). */
|
||||
time_of_process_start = time(NULL);
|
||||
|
||||
/* Make a directory so there's somewhere to store the thing */
|
||||
#ifdef _WIN32
|
||||
tt_int_op(mkdir(get_fname("cached-status")), ==, 0);
|
||||
#else
|
||||
tt_int_op(mkdir(get_fname("cached-status"), 0700), ==, 0);
|
||||
#endif
|
||||
|
||||
v2 = generate_v2_networkstatus_opinion();
|
||||
tt_assert(v2);
|
||||
|
||||
done:
|
||||
crypto_pk_free(id_key);
|
||||
cached_dir_decref(v2);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dir_fmt_control_ns(void *arg)
|
||||
{
|
||||
@ -2360,7 +2280,7 @@ test_dir_fmt_control_ns(void *arg)
|
||||
"r TetsuoMilk U3RhdGVseSwgcGx1bXAgQnVjayA "
|
||||
"TXVsbGlnYW4gY2FtZSB1cCBmcm8 2013-04-02 17:53:18 "
|
||||
"32.48.64.80 9001 9002\n"
|
||||
"s Exit Fast Running\n"
|
||||
"s Exit Fast Running V2Dir\n"
|
||||
"w Bandwidth=1000\n");
|
||||
|
||||
done:
|
||||
@ -2455,7 +2375,6 @@ struct testcase_t dir_tests[] = {
|
||||
DIR(scale_bw, 0),
|
||||
DIR_LEGACY(clip_unmeasured_bw_kb),
|
||||
DIR_LEGACY(clip_unmeasured_bw_kb_alt),
|
||||
DIR(v2_dir, TT_FORK),
|
||||
DIR(fmt_control_ns, 0),
|
||||
DIR(http_handling, 0),
|
||||
END_OF_TESTCASES
|
||||
|
Loading…
Reference in New Issue
Block a user