[tor/master] Merge remote branch 'origin/maint-0.2.2'
Mon Feb 28 22:06:02 UTC 2011
commit 1b8f2ef5505a3ee4d824abf70141e1ad8b48e66c
Merge: b7b01d9 ed87738
Author: Nick Mathewson <nickm at torproject.org>
Date: Sat Jan 15 12:03:44 2011 -0500
Merge remote branch 'origin/maint-0.2.2'
changes/bug2332 | 4 +++
changes/tolen_asserts | 8 +++++++
src/common/crypto.c | 53 ++++++++++++++++++++++++++++++++++++++----------
src/common/crypto.h | 12 ++++++----
src/or/config.c | 4 +-
src/or/dnsserv.c | 2 +-
src/or/networkstatus.c | 1 +
src/or/onion.c | 2 +
src/or/rendclient.c | 1 +
src/or/rendservice.c | 6 +++-
src/or/routerlist.c | 3 +-
src/or/routerparse.c | 18 ++++++++++------
src/test/test_crypto.c | 32 +++++++++++++++++-----------
13 files changed, 104 insertions(+), 42 deletions(-)
diff --combined src/common/crypto.h
index 8fcc58c,29ba36c..b44efcc
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@@ -123,23 -123,25 +123,25 @@@ crypto_pk_env_t *crypto_pk_dup_key(cryp
crypto_pk_env_t *crypto_pk_copy_full(crypto_pk_env_t *orig);
int crypto_pk_key_is_private(const crypto_pk_env_t *key);
- int crypto_pk_public_encrypt(crypto_pk_env_t *env, char *to,
+ int crypto_pk_public_encrypt(crypto_pk_env_t *env, char *to, size_t tolen,
const char *from, size_t fromlen, int padding);
- int crypto_pk_private_decrypt(crypto_pk_env_t *env, char *to,
+ int crypto_pk_private_decrypt(crypto_pk_env_t *env, char *to, size_t tolen,
const char *from, size_t fromlen,
int padding, int warnOnFailure);
- int crypto_pk_public_checksig(crypto_pk_env_t *env, char *to,
+ int crypto_pk_public_checksig(crypto_pk_env_t *env, char *to, size_t tolen,
const char *from, size_t fromlen);
int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const char *data,
size_t datalen, const char *sig, size_t siglen);
- int crypto_pk_private_sign(crypto_pk_env_t *env, char *to,
+ int crypto_pk_private_sign(crypto_pk_env_t *env, char *to, size_t tolen,
const char *from, size_t fromlen);
- int crypto_pk_private_sign_digest(crypto_pk_env_t *env, char *to,
+ int crypto_pk_private_sign_digest(crypto_pk_env_t *env, char *to, size_t tolen,
const char *from, size_t fromlen);
int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, char *to,
+ size_t tolen,
const char *from, size_t fromlen,
int padding, int force);
int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env, char *to,
+ size_t tolen,
const char *from, size_t fromlen,
int padding, int warnOnFailure);
@@@ -238,8 -240,7 +240,8 @@@ void secret_to_key(char *key_out, size_
size_t secret_len, const char *s2k_specifier);
#ifdef CRYPTO_PRIVATE
-/* Prototypes for private functions only used by tortls.c and crypto.c */
+/* Prototypes for private functions only used by tortls.c, crypto.c, and the
+ * unit tests. */
struct rsa_st;
struct evp_pkey_st;
struct dh_st;
diff --combined src/or/config.c
index 00a01f5,b124db1..c7376a2
--- a/src/or/config.c
+++ b/src/or/config.c
@@@ -44,8 -44,6 +44,8 @@@ typedef enum config_type_t
CONFIG_TYPE_FILENAME, /**< A filename: some prefixes get expanded. */
CONFIG_TYPE_UINT, /**< A non-negative integer less than MAX_INT */
CONFIG_TYPE_INTERVAL, /**< A number of seconds, with optional units*/
+ CONFIG_TYPE_MSEC_INTERVAL,/**< A number of milliseconds, with optional
+ * units */
CONFIG_TYPE_MEMUNIT, /**< A number of bytes, with optional units*/
CONFIG_TYPE_DOUBLE, /**< A floating-point value */
CONFIG_TYPE_BOOL, /**< A boolean value, expressed as 0 or 1. */
@@@ -200,7 -198,6 +200,7 @@@ static config_var_t _option_vars[] =
V(ClientOnly, BOOL, "0"),
V(ConsensusParams, STRING, NULL),
V(ConnLimit, UINT, "1000"),
+ V(ConnDirectionStatistics, BOOL, "0"),
V(ConstrainedSockets, BOOL, "0"),
V(ConstrainedSockSize, MEMUNIT, "8192"),
V(ContactInfo, STRING, NULL),
@@@ -224,10 -221,9 +224,10 @@@
OBSOLETE("DirRecordUsageGranularity"),
OBSOLETE("DirRecordUsageRetainIPs"),
OBSOLETE("DirRecordUsageSaveInterval"),
- V(DirReqStatistics, BOOL, "0"),
+ V(DirReqStatistics, BOOL, "1"),
VAR("DirServer", LINELIST, DirServers, NULL),
V(DisableAllSwap, BOOL, "0"),
+ V(DisableIOCP, BOOL, "1"),
V(DNSPort, UINT, "0"),
V(DNSListenAddress, LINELIST, NULL),
V(DownloadExtraInfo, BOOL, "0"),
@@@ -242,7 -238,7 +242,7 @@@
V(ExitPolicy, LINELIST, NULL),
V(ExitPolicyRejectPrivate, BOOL, "1"),
V(ExitPortStatistics, BOOL, "0"),
- V(ExtraInfoStatistics, BOOL, "0"),
+ V(ExtraInfoStatistics, BOOL, "1"),
#if defined (WINCE)
V(FallbackNetworkstatusFile, FILENAME, "fallback-consensus"),
@@@ -294,7 -290,6 +294,7 @@@
OBSOLETE("LinkPadding"),
OBSOLETE("LogLevel"),
OBSOLETE("LogFile"),
+ V(LogTimeGranularity, MSEC_INTERVAL, "1 second"),
V(LongLivedPorts, CSV,
"21,22,706,1863,5050,5190,5222,5223,6667,6697,8300"),
VAR("MapAddress", LINELIST, AddressMap, NULL),
@@@ -311,7 -306,7 +311,7 @@@
V(WarnUnsafeSocks, BOOL, "1"),
OBSOLETE("NoPublish"),
VAR("NodeFamily", LINELIST, NodeFamilies, NULL),
- V(NumCPUs, UINT, "1"),
+ V(NumCPUs, UINT, "0"),
V(NumEntryGuards, UINT, "3"),
V(ORListenAddress, LINELIST, NULL),
V(ORPort, UINT, "0"),
@@@ -321,8 -316,6 +321,8 @@@
V(PerConnBWRate, MEMUNIT, "0"),
V(PidFile, STRING, NULL),
V(TestingTorNetwork, BOOL, "0"),
+ V(PortForwarding, BOOL, "0"),
+ V(PortForwardingHelper, FILENAME, "tor-fw-helper"),
V(PreferTunneledDirConns, BOOL, "1"),
V(ProtocolWarnings, BOOL, "0"),
V(PublishServerDescriptor, CSV, "1"),
@@@ -391,7 -384,6 +391,7 @@@
VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "0"),
V(VirtualAddrNetwork, STRING, "127.192.0.0/10"),
V(WarnPlaintextPorts, CSV, "23,109,110,143"),
+ V(_UseFilteringSSLBufferevents, BOOL, "0"),
VAR("__ReloadTorrcOnSIGHUP", BOOL, ReloadTorrcOnSIGHUP, "1"),
VAR("__AllDirActionsPrivate", BOOL, AllDirActionsPrivate, "0"),
VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits, "0"),
@@@ -563,9 -555,8 +563,9 @@@ static int is_listening_on_low_port(uin
const config_line_t *listen_options);
static uint64_t config_parse_memunit(const char *s, int *ok);
+static int config_parse_msec_interval(const char *s, int *ok);
static int config_parse_interval(const char *s, int *ok);
-static void init_libevent(void);
+static void init_libevent(const or_options_t *options);
static int opt_streq(const char *s1, const char *s2);
/** Magic value for or_options_t. */
@@@ -699,11 -690,6 +699,11 @@@ or_options_free(or_options_t *options
return;
routerset_free(options->_ExcludeExitNodesUnion);
+ if (options->NodeFamilySets) {
+ SMARTLIST_FOREACH(options->NodeFamilySets, routerset_t *,
+ rs, routerset_free(rs));
+ smartlist_free(options->NodeFamilySets);
+ }
config_free(&options_format, options);
}
@@@ -971,7 -957,7 +971,7 @@@ options_act_reversible(or_options_t *ol
/* Set up libevent. (We need to do this before we can register the
* listeners as listeners.) */
if (running_tor && !libevent_initialized) {
- init_libevent();
+ init_libevent(options);
libevent_initialized = 1;
}
@@@ -1247,17 -1233,6 +1247,17 @@@ options_act(or_options_t *old_options
if (accounting_is_enabled(options))
configure_accounting(time(NULL));
+#ifdef USE_BUFFEREVENTS
+ /* If we're using the bufferevents implementation and our rate limits
+ * changed, we need to tell the rate-limiting system about it. */
+ if (!old_options ||
+ old_options->BandwidthRate != options->BandwidthRate ||
+ old_options->BandwidthBurst != options->BandwidthBurst ||
+ old_options->RelayBandwidthRate != options->RelayBandwidthRate ||
+ old_options->RelayBandwidthBurst != options->RelayBandwidthBurst)
+ connection_bucket_init();
+#endif
+
/* parse RefuseUnknownExits tristate */
if (!strcmp(options->RefuseUnknownExits, "0"))
options->RefuseUnknownExits_ = 0;
@@@ -1369,52 -1344,44 +1369,52 @@@
tor_free(actual_fname);
}
- if (options->DirReqStatistics && !geoip_is_loaded()) {
- /* Check if GeoIP database could be loaded. */
- log_warn(LD_CONFIG, "Configured to measure directory request "
- "statistics, but no GeoIP database found!");
- return -1;
- }
-
- if (options->EntryStatistics) {
- if (should_record_bridge_info(options)) {
- /* Don't allow measuring statistics on entry guards when configured
- * as bridge. */
- log_warn(LD_CONFIG, "Bridges cannot be configured to measure "
- "additional GeoIP statistics as entry guards.");
- return -1;
- } else if (!geoip_is_loaded()) {
- /* Check if GeoIP database could be loaded. */
- log_warn(LD_CONFIG, "Configured to measure entry node statistics, "
- "but no GeoIP database found!");
- return -1;
- }
- }
-
if (options->CellStatistics || options->DirReqStatistics ||
- options->EntryStatistics || options->ExitPortStatistics) {
+ options->EntryStatistics || options->ExitPortStatistics ||
+ options->ConnDirectionStatistics) {
time_t now = time(NULL);
+ int print_notice = 0;
if ((!old_options || !old_options->CellStatistics) &&
- options->CellStatistics)
+ options->CellStatistics) {
rep_hist_buffer_stats_init(now);
+ print_notice = 1;
+ }
if ((!old_options || !old_options->DirReqStatistics) &&
- options->DirReqStatistics)
- geoip_dirreq_stats_init(now);
+ options->DirReqStatistics) {
+ if (geoip_is_loaded()) {
+ geoip_dirreq_stats_init(now);
+ print_notice = 1;
+ } else {
+ options->DirReqStatistics = 0;
+ log_notice(LD_CONFIG, "Configured to measure directory request "
+ "statistics, but no GeoIP database found! "
+ "Please specify a GeoIP database using the "
+ "GeoIPFile option!");
+ }
+ }
if ((!old_options || !old_options->EntryStatistics) &&
- options->EntryStatistics)
- geoip_entry_stats_init(now);
+ options->EntryStatistics && !should_record_bridge_info(options)) {
+ if (geoip_is_loaded()) {
+ geoip_entry_stats_init(now);
+ print_notice = 1;
+ } else {
+ options->EntryStatistics = 0;
+ log_notice(LD_CONFIG, "Configured to measure entry node "
+ "statistics, but no GeoIP database found! "
+ "Please specify a GeoIP database using the "
+ "GeoIPFile option!");
+ }
+ }
if ((!old_options || !old_options->ExitPortStatistics) &&
- options->ExitPortStatistics)
+ options->ExitPortStatistics) {
rep_hist_exit_stats_init(now);
- if (!old_options)
+ print_notice = 1;
+ }
+ if ((!old_options || !old_options->ConnDirectionStatistics) &&
+ options->ConnDirectionStatistics) {
+ rep_hist_conn_stats_init(now);
+ }
+ if (print_notice)
log_notice(LD_CONFIG, "Configured to measure statistics. Look for "
"the *-stats files that will first be written to the "
"data directory in 24 hours from now.");
@@@ -1432,9 -1399,6 +1432,9 @@@
if (old_options && old_options->ExitPortStatistics &&
!options->ExitPortStatistics)
rep_hist_exit_stats_term();
+ if (old_options && old_options->ConnDirectionStatistics &&
+ !options->ConnDirectionStatistics)
+ rep_hist_conn_stats_term();
/* Check if we need to parse and add the EntryNodes config option. */
if (options->EntryNodes &&
@@@ -1740,18 -1704,6 +1740,18 @@@ config_assign_value(config_format_t *fm
break;
}
+ case CONFIG_TYPE_MSEC_INTERVAL: {
+ i = config_parse_msec_interval(c->value, &ok);
+ if (!ok) {
+ tor_asprintf(msg,
+ "Msec interval '%s %s' is malformed or out of bounds.",
+ c->key, c->value);
+ return -1;
+ }
+ *(int *)lvalue = i;
+ break;
+ }
+
case CONFIG_TYPE_MEMUNIT: {
uint64_t u64 = config_parse_memunit(c->value, &ok);
if (!ok) {
@@@ -2039,7 -1991,6 +2039,7 @@@ get_assigned_option(config_format_t *fm
escape_val = 0; /* Can't need escape. */
break;
case CONFIG_TYPE_INTERVAL:
+ case CONFIG_TYPE_MSEC_INTERVAL:
case CONFIG_TYPE_UINT:
/* This means every or_options_t uint or bool element
* needs to be an int. Not, say, a uint16_t or char. */
@@@ -2267,7 -2218,6 +2267,7 @@@ option_clear(config_format_t *fmt, or_o
*(time_t*)lvalue = 0;
break;
case CONFIG_TYPE_INTERVAL:
+ case CONFIG_TYPE_MSEC_INTERVAL:
case CONFIG_TYPE_UINT:
case CONFIG_TYPE_BOOL:
*(int*)lvalue = 0;
@@@ -2374,7 -2324,7 +2374,7 @@@ resolve_my_address(int warn_severity, o
int explicit_ip=1;
int explicit_hostname=1;
int from_interface=0;
- char tmpbuf[INET_NTOA_BUF_LEN];
+ char *addr_string = NULL;
const char *address = options->Address;
int notice_severity = warn_severity <= LOG_NOTICE ?
LOG_NOTICE : warn_severity;
@@@ -2416,43 -2366,48 +2416,43 @@@
return -1;
}
from_interface = 1;
- in.s_addr = htonl(interface_ip);
- tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
+ addr = interface_ip;
log_fn(notice_severity, LD_CONFIG, "Learned IP address '%s' for "
- "local interface. Using that.", tmpbuf);
+ "local interface. Using that.", fmt_addr32(addr));
strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
} else { /* resolved hostname into addr */
- in.s_addr = htonl(addr);
-
if (!explicit_hostname &&
- is_internal_IP(ntohl(in.s_addr), 0)) {
+ is_internal_IP(addr, 0)) {
uint32_t interface_ip;
- tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
log_fn(notice_severity, LD_CONFIG, "Guessed local hostname '%s' "
- "resolves to a private IP address (%s). Trying something "
- "else.", hostname, tmpbuf);
+ "resolves to a private IP address (%s). Trying something "
+ "else.", hostname, fmt_addr32(addr));
if (get_interface_address(warn_severity, &interface_ip)) {
log_fn(warn_severity, LD_CONFIG,
"Could not get local interface IP address. Too bad.");
} else if (is_internal_IP(interface_ip, 0)) {
- struct in_addr in2;
- in2.s_addr = htonl(interface_ip);
- tor_inet_ntoa(&in2,tmpbuf,sizeof(tmpbuf));
log_fn(notice_severity, LD_CONFIG,
"Interface IP address '%s' is a private address too. "
- "Ignoring.", tmpbuf);
+ "Ignoring.", fmt_addr32(interface_ip));
} else {
from_interface = 1;
- in.s_addr = htonl(interface_ip);
- tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
+ addr = interface_ip;
log_fn(notice_severity, LD_CONFIG,
"Learned IP address '%s' for local interface."
- " Using that.", tmpbuf);
+ " Using that.", fmt_addr32(addr));
strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname));
}
}
}
+ } else {
+ addr = ntohl(in.s_addr); /* set addr so that addr_string is not
+ * illformed */
}
- tor_inet_ntoa(&in,tmpbuf,sizeof(tmpbuf));
- if (is_internal_IP(ntohl(in.s_addr), 0)) {
+ addr_string = tor_dup_ip(addr);
+ if (is_internal_IP(addr, 0)) {
/* make sure we're ok with publishing an internal IP */
if (!options->DirServers && !options->AlternateDirAuthority) {
/* if they are using the default dirservers, disallow internal IPs
@@@ -2460,8 -2415,7 +2460,8 @@@
log_fn(warn_severity, LD_CONFIG,
"Address '%s' resolves to private IP address '%s'. "
"Tor servers that use the default DirServers must have public "
- "IP addresses.", hostname, tmpbuf);
+ "IP addresses.", hostname, addr_string);
+ tor_free(addr_string);
return -1;
}
if (!explicit_ip) {
@@@ -2469,20 -2423,19 +2469,20 @@@
* they're using an internal address. */
log_fn(warn_severity, LD_CONFIG, "Address '%s' resolves to private "
"IP address '%s'. Please set the Address config option to be "
- "the IP address you want to use.", hostname, tmpbuf);
+ "the IP address you want to use.", hostname, addr_string);
+ tor_free(addr_string);
return -1;
}
}
- log_debug(LD_CONFIG, "Resolved Address to '%s'.", tmpbuf);
- *addr_out = ntohl(in.s_addr);
+ log_debug(LD_CONFIG, "Resolved Address to '%s'.", fmt_addr32(addr));
+ *addr_out = addr;
if (last_resolved_addr && last_resolved_addr != *addr_out) {
/* Leave this as a notice, regardless of the requested severity,
* at least until dynamic IP address support becomes bulletproof. */
log_notice(LD_NET,
"Your IP address seems to have changed to %s. Updating.",
- tmpbuf);
+ addr_string);
ip_address_changed(0);
}
if (last_resolved_addr != *addr_out) {
@@@ -2501,12 -2454,11 +2501,12 @@@
}
control_event_server_status(LOG_NOTICE,
"EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s %s%s",
- tmpbuf, method, h?"HOSTNAME=":"", h);
+ addr_string, method, h?"HOSTNAME=":"", h);
}
last_resolved_addr = *addr_out;
if (hostname_out)
*hostname_out = tor_strdup(hostname);
+ tor_free(addr_string);
return 0;
}
@@@ -3111,24 -3063,17 +3111,24 @@@ options_validate(or_options_t *old_opti
routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeNodes);
}
+ if (options->NodeFamilies) {
+ options->NodeFamilySets = smartlist_create();
+ for (cl = options->NodeFamilies; cl; cl = cl->next) {
+ routerset_t *rs = routerset_new();
+ if (routerset_parse(rs, cl->value, cl->key) == 0) {
+ smartlist_add(options->NodeFamilySets, rs);
+ } else {
+ routerset_free(rs);
+ }
+ }
+ }
+
if (options->ExcludeNodes && options->StrictNodes) {
COMPLAIN("You have asked to exclude certain relays from all positions "
"in your circuits. Expect hidden services and other Tor "
"features to be broken in unpredictable ways.");
}
- if (options->EntryNodes && !routerset_is_list(options->EntryNodes)) {
- /* XXXX fix this; see entry_guards_prepend_from_config(). */
- REJECT("IPs or countries are not yet supported in EntryNodes.");
- }
-
if (options->AuthoritativeDir) {
if (!options->ContactInfo && !options->TestingTorNetwork)
REJECT("Authoritative directory servers must set ContactInfo");
@@@ -3589,12 -3534,8 +3589,12 @@@
if (check_nickname_list(options->MyFamily, "MyFamily", msg))
return -1;
for (cl = options->NodeFamilies; cl; cl = cl->next) {
- if (check_nickname_list(cl->value, "NodeFamily", msg))
+ routerset_t *rs = routerset_new();
+ if (routerset_parse(rs, cl->value, cl->key)) {
+ routerset_free(rs);
return -1;
+ }
+ routerset_free(rs);
}
if (validate_addr_policies(options, msg) < 0)
@@@ -4374,35 -4315,6 +4374,35 @@@ options_init_logs(or_options_t *options
options->RunAsDaemon;
#endif
+ if (options->LogTimeGranularity <= 0) {
+ log_warn(LD_CONFIG, "Log time granularity '%d' has to be positive.",
+ options->LogTimeGranularity);
+ return -1;
+ } else if (1000 % options->LogTimeGranularity != 0 &&
+ options->LogTimeGranularity % 1000 != 0) {
+ int granularity = options->LogTimeGranularity;
+ if (granularity < 40) {
+ do granularity++;
+ while (1000 % granularity != 0);
+ } else if (granularity < 1000) {
+ granularity = 1000 / granularity;
+ while (1000 % granularity != 0)
+ granularity--;
+ granularity = 1000 / granularity;
+ } else {
+ granularity = 1000 * ((granularity / 1000) + 1);
+ }
+ log_warn(LD_CONFIG, "Log time granularity '%d' has to be either a "
+ "divisor or a multiple of 1 second. Changing to "
+ "'%d'.",
+ options->LogTimeGranularity, granularity);
+ if (!validate_only)
+ set_log_time_granularity(granularity);
+ } else {
+ if (!validate_only)
+ set_log_time_granularity(options->LogTimeGranularity);
+ }
+
ok = 1;
elts = smartlist_create();
@@@ -4891,26 -4803,6 +4891,26 @@@ static struct unit_table_t time_units[
{ NULL, 0 },
};
+/** Table to map the names of time units to the number of milliseconds
+ * they contain. */
+static struct unit_table_t time_msec_units[] = {
+ { "", 1 },
+ { "msec", 1 },
+ { "millisecond", 1 },
+ { "milliseconds", 1 },
+ { "second", 1000 },
+ { "seconds", 1000 },
+ { "minute", 60*1000 },
+ { "minutes", 60*1000 },
+ { "hour", 60*60*1000 },
+ { "hours", 60*60*1000 },
+ { "day", 24*60*60*1000 },
+ { "days", 24*60*60*1000 },
+ { "week", 7*24*60*60*1000 },
+ { "weeks", 7*24*60*60*1000 },
+ { NULL, 0 },
+};
+
/** Parse a string <b>val</b> containing a number, zero or more
* spaces, and an optional unit string. If the unit appears in the
* table <b>u</b>, then multiply the number by the unit multiplier.
@@@ -4974,25 -4866,6 +4974,25 @@@ config_parse_memunit(const char *s, in
return u;
}
+/** Parse a string in the format "number unit", where unit is a unit of
+ * time in milliseconds. On success, set *<b>ok</b> to true and return
+ * the number of milliseconds in the provided interval. Otherwise, set
+ * *<b>ok</b> to 0 and return -1. */
+static int
+config_parse_msec_interval(const char *s, int *ok)
+{
+ uint64_t r;
+ r = config_parse_units(s, time_msec_units, ok);
+ if (!ok)
+ return -1;
+ if (r > INT_MAX) {
+ log_warn(LD_CONFIG, "Msec interval '%s' is too long", s);
+ *ok = 0;
+ return -1;
+ }
+ return (int)r;
+}
+
/** Parse a string in the format "number unit", where unit is a unit of time.
* On success, set *<b>ok</b> to true and return the number of seconds in
* the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
@@@ -5012,29 -4885,13 +5012,29 @@@ config_parse_interval(const char *s, in
return (int)r;
}
+/** Return the number of cpus configured in <b>options</b>. If we are
+ * told to auto-detect the number of cpus, return the auto-detected number. */
+int
+get_num_cpus(const or_options_t *options)
+{
+ if (options->NumCPUs == 0) {
+ int n = compute_num_cpus();
+ return (n >= 1) ? n : 1;
+ } else {
+ return options->NumCPUs;
+ }
+}
+
/**
* Initialize the libevent library.
*/
static void
-init_libevent(void)
+init_libevent(const or_options_t *options)
{
const char *badness=NULL;
+ tor_libevent_cfg cfg;
+
+ tor_assert(options);
configure_libevent_logging();
/* If the kernel complains that some method (say, epoll) doesn't
@@@ -5044,11 -4901,7 +5044,11 @@@
tor_check_libevent_header_compatibility();
- tor_libevent_initialize();
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.disable_iocp = options->DisableIOCP;
+ cfg.num_cpus = get_num_cpus(options);
+
+ tor_libevent_initialize(&cfg);
suppress_libevent_log_msg(NULL);
@@@ -5329,8 -5182,8 +5329,8 @@@ or_state_save(time_t now
tor_free(state);
fname = get_datadir_fname("state");
if (write_str_to_file(fname, contents, 0)<0) {
- log_warn(LD_FS, "Unable to write state to file \"%s\"; will try later",
- fname);
+ log_warn(LD_FS, "Unable to write state to file \"%s\"; "
+ "will try again later", fname);
global_state->LastWritten = -1;
tor_free(fname);
tor_free(contents);
@@@ -5389,7 -5242,6 +5389,7 @@@ getinfo_helper_config(control_connectio
case CONFIG_TYPE_FILENAME: type = "Filename"; break;
case CONFIG_TYPE_UINT: type = "Integer"; break;
case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
+ case CONFIG_TYPE_MSEC_INTERVAL: type = "TimeMsecInterval"; break;
case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
case CONFIG_TYPE_DOUBLE: type = "Float"; break;
case CONFIG_TYPE_BOOL: type = "Boolean"; break;
diff --combined src/or/networkstatus.c
index 405db12,dfc3a45..68dc9f6
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@@ -20,9 -20,7 +20,9 @@@
#include "dirserv.h"
#include "dirvote.h"
#include "main.h"
+#include "microdesc.h"
#include "networkstatus.h"
+#include "nodelist.h"
#include "relay.h"
#include "router.h"
#include "routerlist.h"
@@@ -46,19 -44,8 +46,19 @@@ static strmap_t *named_server_map = NUL
* as unnamed for some server in the consensus. */
static strmap_t *unnamed_server_map = NULL;
-/** Most recently received and validated v3 consensus network status. */
-static networkstatus_t *current_consensus = NULL;
+/** Most recently received and validated v3 consensus network status,
+ * of whichever type we are using for our own circuits. This will be the same
+ * as one of current_ns_consensus or current_md_consensus.
+ */
+#define current_consensus current_ns_consensus
+
+/** Most recently received and validated v3 "ns"-flavored consensus network
+ * status. */
+static networkstatus_t *current_ns_consensus = NULL;
+
+/** Most recently received and validated v3 "microdec"-flavored consensus
+ * network status. */
+static networkstatus_t *current_md_consensus = NULL;
/** A v3 consensus networkstatus that we've received, but which we don't
* have enough certificates to be happy about. */
@@@ -107,8 -94,9 +107,8 @@@ voi
networkstatus_reset_warnings(void)
{
if (current_consensus) {
- SMARTLIST_FOREACH(current_consensus->routerstatus_list,
- routerstatus_t *, rs,
- rs->name_lookup_warned = 0);
+ SMARTLIST_FOREACH(nodelist_get_list(), node_t *, node,
+ node->name_lookup_warned = 0);
}
have_warned_about_old_version = 0;
@@@ -283,7 -271,6 +283,7 @@@ router_reload_consensus_networkstatus(v
update_certificate_downloads(time(NULL));
routers_update_all_from_networkstatus(time(NULL), 3);
+ update_microdescs_from_networkstatus(time(NULL));
return 0;
}
@@@ -452,6 -439,7 +452,7 @@@ networkstatus_check_document_signature(
signed_digest = tor_malloc(signed_digest_len);
if (crypto_pk_public_checksig(cert->signing_key,
signed_digest,
+ signed_digest_len,
sig->signature,
sig->signature_len) < dlen ||
memcmp(signed_digest, consensus->digests.d[sig->alg], dlen)) {
@@@ -939,9 -927,10 +940,9 @@@ compare_digest_to_routerstatus_entry(co
return memcmp(key, rs->identity_digest, DIGEST_LEN);
}
-/** Return the entry in <b>ns</b> for the identity digest <b>digest</b>, or
- * NULL if none was found. */
+/** As networkstatus_v2_find_entry, but do not return a const pointer */
routerstatus_t *
-networkstatus_v2_find_entry(networkstatus_v2_t *ns, const char *digest)
+networkstatus_v2_find_mutable_entry(networkstatus_v2_t *ns, const char *digest)
{
return smartlist_bsearch(ns->entries, digest,
compare_digest_to_routerstatus_entry);
@@@ -949,29 -938,14 +950,29 @@@
/** 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_entry(networkstatus_t *ns, const char *digest)
+networkstatus_vote_find_mutable_entry(networkstatus_t *ns, const char *digest)
{
return smartlist_bsearch(ns->routerstatus_list, digest,
compare_digest_to_routerstatus_entry);
}
-/*XXXX make this static once functions are moved into this file. */
+/** Return the entry in <b>ns</b> for the identity digest <b>digest</b>, or
+ * NULL if none was found. */
+const routerstatus_t *
+networkstatus_vote_find_entry(networkstatus_t *ns, const char *digest)
+{
+ return networkstatus_vote_find_mutable_entry(ns, digest);
+}
+
+/*XXXX MOVE make this static once functions are moved into this file. */
/** Search the routerstatuses in <b>ns</b> for one whose identity digest is
* <b>digest</b>. Return value and set *<b>found_out</b> as for
* smartlist_bsearch_idx(). */
@@@ -993,37 -967,22 +994,37 @@@ networkstatus_get_v2_list(void
return networkstatus_v2_list;
}
-/** Return the consensus view of the status of the router whose current
- * <i>descriptor</i> digest is <b>digest</b>, or NULL if no such router is
- * known. */
+/* As router_get_consensus_status_by_descriptor_digest, but does not return
+ * a const pointer */
routerstatus_t *
-router_get_consensus_status_by_descriptor_digest(const char *digest)
+router_get_mutable_consensus_status_by_descriptor_digest(
+ networkstatus_t *consensus,
+ const char *digest)
{
- if (!current_consensus) return NULL;
- if (!current_consensus->desc_digest_map) {
- digestmap_t * m = current_consensus->desc_digest_map = digestmap_new();
- SMARTLIST_FOREACH(current_consensus->routerstatus_list,
+ if (!consensus)
+ consensus = current_consensus;
+ if (!consensus)
+ return NULL;
+ if (!consensus->desc_digest_map) {
+ digestmap_t *m = consensus->desc_digest_map = digestmap_new();
+ SMARTLIST_FOREACH(consensus->routerstatus_list,
routerstatus_t *, rs,
{
digestmap_set(m, rs->descriptor_digest, rs);
});
}
- return digestmap_get(current_consensus->desc_digest_map, digest);
+ return digestmap_get(consensus->desc_digest_map, digest);
+}
+
+/** Return the consensus view of the status of the router whose current
+ * <i>descriptor</i> digest in <b>consensus</b> is <b>digest</b>, or NULL if
+ * no such router is known. */
+const routerstatus_t *
+router_get_consensus_status_by_descriptor_digest(networkstatus_t *consensus,
+ const char *digest)
+{
+ return router_get_mutable_consensus_status_by_descriptor_digest(
+ consensus, digest);
}
/** Given the digest of a router descriptor, return its current download
@@@ -1032,10 -991,7 +1033,10 @@@ download_status_t
router_get_dl_status_by_descriptor_digest(const char *d)
{
routerstatus_t *rs;
- if ((rs = router_get_consensus_status_by_descriptor_digest(d)))
+ if (!current_ns_consensus)
+ return NULL;
+ 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);
@@@ -1043,9 -999,10 +1044,9 @@@
return NULL;
}
-/** Return the consensus view of the status of the router whose identity
- * digest is <b>digest</b>, or NULL if we don't know about any such router. */
+/** As router_get_consensus_status_by_id, but do not return a const pointer */
routerstatus_t *
-router_get_consensus_status_by_id(const char *digest)
+router_get_mutable_consensus_status_by_id(const char *digest)
{
if (!current_consensus)
return NULL;
@@@ -1053,27 -1010,100 +1054,27 @@@
compare_digest_to_routerstatus_entry);
}
+/** Return the consensus view of the status of the router whose identity
+ * digest is <b>digest</b>, or NULL if we don't know about any such router. */
+const routerstatus_t *
+router_get_consensus_status_by_id(const char *digest)
+{
+ return router_get_mutable_consensus_status_by_id(digest);
+}
+
/** Given a nickname (possibly verbose, possibly a hexadecimal digest), return
* the corresponding routerstatus_t, or NULL if none exists. Warn the
* user if <b>warn_if_unnamed</b> is set, and they have specified a router by
* nickname, but the Named flag isn't set for that router. */
-routerstatus_t *
+const routerstatus_t *
router_get_consensus_status_by_nickname(const char *nickname,
int warn_if_unnamed)
{
- char digest[DIGEST_LEN];
- routerstatus_t *best=NULL;
- smartlist_t *matches=NULL;
- const char *named_id=NULL;
-
- if (!current_consensus || !nickname)
- return NULL;
-
- /* Is this name really a hexadecimal identity digest? */
- if (nickname[0] == '$') {
- if (base16_decode(digest, DIGEST_LEN, nickname+1, strlen(nickname+1))<0)
- return NULL;
- return networkstatus_vote_find_entry(current_consensus, digest);
- } else if (strlen(nickname) == HEX_DIGEST_LEN &&
- (base16_decode(digest, DIGEST_LEN, nickname, strlen(nickname))==0)) {
- return networkstatus_vote_find_entry(current_consensus, digest);
- }
-
- /* Is there a server that is Named with this name? */
- if (named_server_map)
- named_id = strmap_get_lc(named_server_map, nickname);
- if (named_id)
- return networkstatus_vote_find_entry(current_consensus, named_id);
-
- /* Okay; is this name listed as Unnamed? */
- if (unnamed_server_map &&
- strmap_get_lc(unnamed_server_map, nickname)) {
- log_info(LD_GENERAL, "The name %s is listed as Unnamed; it is not the "
- "canonical name of any server we know.", escaped(nickname));
+ const node_t *node = node_get_by_nickname(nickname, warn_if_unnamed);
+ if (node)
+ return node->rs;
+ else
return NULL;
- }
-
- /* This name is not canonical for any server; go through the list and
- * see who it matches. */
- /*XXXX This is inefficient; optimize it if it matters. */
- matches = smartlist_create();
- SMARTLIST_FOREACH(current_consensus->routerstatus_list,
- routerstatus_t *, lrs,
- {
- if (!strcasecmp(lrs->nickname, nickname)) {
- if (lrs->is_named) {
- tor_fragile_assert() /* This should never happen. */
- smartlist_free(matches);
- return lrs;
- } else {
- if (lrs->is_unnamed) {
- tor_fragile_assert(); /* nor should this. */
- smartlist_clear(matches);
- best=NULL;
- break;
- }
- smartlist_add(matches, lrs);
- best = lrs;
- }
- }
- });
-
- if (smartlist_len(matches)>1 && warn_if_unnamed) {
- int any_unwarned=0;
- SMARTLIST_FOREACH(matches, routerstatus_t *, lrs,
- {
- if (! lrs->name_lookup_warned) {
- lrs->name_lookup_warned=1;
- any_unwarned=1;
- }
- });
- if (any_unwarned) {
- log_warn(LD_CONFIG,"There are multiple matches for the nickname \"%s\","
- " but none is listed as named by the directory authorities. "
- "Choosing one arbitrarily.", nickname);
- }
- } else if (warn_if_unnamed && best && !best->name_lookup_warned) {
- char fp[HEX_DIGEST_LEN+1];
- base16_encode(fp, sizeof(fp),
- best->identity_digest, DIGEST_LEN);
- log_warn(LD_CONFIG,
- "When looking up a status, you specified a server \"%s\" by name, "
- "but the directory authorities do not have any key registered for "
- "this nickname -- so it could be used by any server, "
- "not just the one you meant. "
- "To make sure you get the same server in the future, refer to "
- "it by key, as \"$%s\".", nickname, fp);
- best->name_lookup_warned = 1;
- }
- smartlist_free(matches);
- return best;
}
/** Return the identity digest that's mapped to officially by
@@@ -1170,25 -1200,6 +1171,25 @@@ update_v2_networkstatus_cache_downloads
}
}
+/** DOCDOC */
+static int
+we_want_to_fetch_flavor(or_options_t *options, int flavor)
+{
+ if (flavor < 0 || flavor > N_CONSENSUS_FLAVORS) {
+ /* This flavor is crazy; we don't want it */
+ /*XXXX handle unrecognized flavors later */
+ return 0;
+ }
+ if (authdir_mode_v3(options) || directory_caches_dir_info(options)) {
+ /* We want to serve all flavors to others, regardless if we would use
+ * it ourselves. */
+ return 1;
+ }
+ /* Otherwise, we want the flavor only if we want to use it to build
+ * circuits. */
+ return (flavor == USABLE_CONSENSUS_FLAVOR);
+}
+
/** How many times will we try to fetch a consensus before we give up? */
#define CONSENSUS_NETWORKSTATUS_MAX_DL_TRIES 8
/** How long will we hang onto a possibly live consensus for which we're
@@@ -1201,65 -1212,48 +1202,65 @@@ static voi
update_consensus_networkstatus_downloads(time_t now)
{
int i;
+ or_options_t *options = get_options();
+
if (!networkstatus_get_live_consensus(now))
time_to_download_next_consensus = now; /* No live consensus? Get one now!*/
if (time_to_download_next_consensus > now)
return; /* Wait until the current consensus is older. */
- /* XXXXNM Microdescs: may need to download more types. */
- if (!download_status_is_ready(&consensus_dl_status[FLAV_NS], now,
- CONSENSUS_NETWORKSTATUS_MAX_DL_TRIES))
- return; /* We failed downloading a consensus too recently. */
- if (connection_get_by_type_purpose(CONN_TYPE_DIR,
- DIR_PURPOSE_FETCH_CONSENSUS))
- return; /* There's an in-progress download.*/
for (i=0; i < N_CONSENSUS_FLAVORS; ++i) {
- consensus_waiting_for_certs_t *waiting = &consensus_waiting_for_certs[i];
+ /* XXXX need some way to download unknown flavors if we are caching. */
+ const char *resource;
+ consensus_waiting_for_certs_t *waiting;
+
+ if (! we_want_to_fetch_flavor(options, i))
+ continue;
+
+ resource = i==FLAV_NS ? NULL : networkstatus_get_flavor_name(i);
+
+ if (!download_status_is_ready(&consensus_dl_status[i], now,
+ CONSENSUS_NETWORKSTATUS_MAX_DL_TRIES))
+ continue; /* We failed downloading a consensus too recently. */
+ if (connection_dir_get_by_purpose_and_resource(
+ DIR_PURPOSE_FETCH_CONSENSUS, resource))
+ continue; /* There's an in-progress download.*/
+
+ waiting = &consensus_waiting_for_certs[i];
if (waiting->consensus) {
/* XXXX make sure this doesn't delay sane downloads. */
- if (waiting->set_at + DELAY_WHILE_FETCHING_CERTS > now)
- return; /* We're still getting certs for this one. */
- else {
+ if (waiting->set_at + DELAY_WHILE_FETCHING_CERTS > now) {
+ continue; /* We're still getting certs for this one. */
+ } else {
if (!waiting->dl_failed) {
- download_status_failed(&consensus_dl_status[FLAV_NS], 0);
+ download_status_failed(&consensus_dl_status[i], 0);
waiting->dl_failed=1;
}
}
}
- }
- log_info(LD_DIR, "Launching networkstatus consensus download.");
- directory_get_from_dirserver(DIR_PURPOSE_FETCH_CONSENSUS,
- ROUTER_PURPOSE_GENERAL, NULL,
- PDS_RETRY_IF_NO_SERVERS);
+ log_info(LD_DIR, "Launching %s networkstatus consensus download.",
+ networkstatus_get_flavor_name(i));
+
+ directory_get_from_dirserver(DIR_PURPOSE_FETCH_CONSENSUS,
+ ROUTER_PURPOSE_GENERAL, resource,
+ PDS_RETRY_IF_NO_SERVERS);
+ }
}
/** Called when an attempt to download a consensus fails: note that the
* failure occurred, and possibly retry. */
void
-networkstatus_consensus_download_failed(int status_code)
+networkstatus_consensus_download_failed(int status_code, const char *flavname)
{
- /* XXXXNM Microdescs: may need to handle more types. */
- download_status_failed(&consensus_dl_status[FLAV_NS], status_code);
- /* Retry immediately, if appropriate. */
- update_consensus_networkstatus_downloads(time(NULL));
+ int flav = networkstatus_parse_flavor_name(flavname);
+ if (flav >= 0) {
+ tor_assert(flav < N_CONSENSUS_FLAVORS);
+ /* XXXX handle unrecognized flavors */
+ download_status_failed(&consensus_dl_status[flav], status_code);
+ /* Retry immediately, if appropriate. */
+ update_consensus_networkstatus_downloads(time(NULL));
+ }
}
/** How long do we (as a cache) wait after a consensus becomes non-fresh
@@@ -1380,10 -1374,7 +1381,10 @@@ update_certificate_downloads(time_t now
now);
}
- authority_certs_fetch_missing(current_consensus, now);
+ if (current_ns_consensus)
+ authority_certs_fetch_missing(current_ns_consensus, now);
+ if (current_md_consensus)
+ authority_certs_fetch_missing(current_md_consensus, now);
}
/** Return 1 if we have a consensus but we don't have enough certificates
@@@ -1415,18 -1406,6 +1416,18 @@@ networkstatus_get_latest_consensus(void
return current_consensus;
}
+/** DOCDOC */
+networkstatus_t *
+networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
+{
+ if (f == FLAV_NS)
+ return current_ns_consensus;
+ else if (f == FLAV_MICRODESC)
+ return current_md_consensus;
+ else
+ tor_assert(0);
+}
+
/** Return the most recent consensus that we have downloaded, or NULL if it is
* no longer live. */
networkstatus_t *
@@@ -1446,15 -1425,13 +1447,15 @@@ networkstatus_get_live_consensus(time_
/** As networkstatus_get_live_consensus(), but is way more tolerant of expired
* consensuses. */
networkstatus_t *
-networkstatus_get_reasonably_live_consensus(time_t now)
+networkstatus_get_reasonably_live_consensus(time_t now, int flavor)
{
#define REASONABLY_LIVE_TIME (24*60*60)
- if (current_consensus &&
- current_consensus->valid_after <= now &&
- now <= current_consensus->valid_until+REASONABLY_LIVE_TIME)
- return current_consensus;
+ networkstatus_t *consensus =
+ networkstatus_get_latest_consensus_by_flavor(flavor);
+ if (consensus &&
+ consensus->valid_after <= now &&
+ now <= consensus->valid_until+REASONABLY_LIVE_TIME)
+ return consensus;
else
return NULL;
}
@@@ -1475,7 -1452,7 +1476,7 @@@ routerstatus_has_changed(const routerst
a->is_exit != b->is_exit ||
a->is_stable != b->is_stable ||
a->is_fast != b->is_fast ||
- a->is_running != b->is_running ||
+ a->is_flagged_running != b->is_flagged_running ||
a->is_named != b->is_named ||
a->is_unnamed != b->is_unnamed ||
a->is_valid != b->is_valid ||
@@@ -1516,14 -1493,13 +1517,14 @@@ notify_control_networkstatus_changed(co
}
changed = smartlist_create();
- SMARTLIST_FOREACH_JOIN(old_c->routerstatus_list, routerstatus_t *, rs_old,
- new_c->routerstatus_list, routerstatus_t *, rs_new,
- memcmp(rs_old->identity_digest,
- rs_new->identity_digest, DIGEST_LEN),
- smartlist_add(changed, rs_new)) {
+ SMARTLIST_FOREACH_JOIN(
+ old_c->routerstatus_list, const routerstatus_t *, rs_old,
+ new_c->routerstatus_list, const routerstatus_t *, rs_new,
+ memcmp(rs_old->identity_digest,
+ rs_new->identity_digest, DIGEST_LEN),
+ smartlist_add(changed, (void*) rs_new)) {
if (routerstatus_has_changed(rs_old, rs_new))
- smartlist_add(changed, rs_new);
+ smartlist_add(changed, (void*)rs_new);
} SMARTLIST_FOREACH_JOIN_END(rs_old, rs_new);
control_event_networkstatus_changed(changed);
@@@ -1547,6 -1523,7 +1548,6 @@@ networkstatus_copy_old_consensus_info(n
rs_new->identity_digest, DIGEST_LEN),
STMT_NIL) {
/* Okay, so we're looking at the same identity. */
- rs_new->name_lookup_warned = rs_old->name_lookup_warned;
rs_new->last_dir_503_at = rs_old->last_dir_503_at;
if (!memcmp(rs_old->descriptor_digest, rs_new->descriptor_digest,
@@@ -1639,16 -1616,9 +1640,16 @@@ networkstatus_set_current_consensus(con
if (!strcmp(flavor, "ns")) {
consensus_fname = get_datadir_fname("cached-consensus");
unverified_fname = get_datadir_fname("unverified-consensus");
- if (current_consensus) {
- current_digests = ¤t_consensus->digests;
- current_valid_after = current_consensus->valid_after;
+ if (current_ns_consensus) {
+ current_digests = ¤t_ns_consensus->digests;
+ current_valid_after = current_ns_consensus->valid_after;
+ }
+ } else if (!strcmp(flavor, "microdesc")) {
+ consensus_fname = get_datadir_fname("cached-microdesc-consensus");
+ unverified_fname = get_datadir_fname("unverified-microdesc-consensus");
+ if (current_md_consensus) {
+ current_digests = ¤t_md_consensus->digests;
+ current_valid_after = current_md_consensus->valid_after;
}
} else {
cached_dir_t *cur;
@@@ -1734,27 -1704,15 +1735,27 @@@
if (flav == USABLE_CONSENSUS_FLAVOR) {
notify_control_networkstatus_changed(current_consensus, c);
-
- if (current_consensus) {
- networkstatus_copy_old_consensus_info(c, current_consensus);
- networkstatus_vote_free(current_consensus);
+ }
+ if (flav == FLAV_NS) {
+ if (current_ns_consensus) {
+ networkstatus_copy_old_consensus_info(c, current_ns_consensus);
+ networkstatus_vote_free(current_ns_consensus);
/* Defensive programming : we should set current_consensus very soon,
* but we're about to call some stuff in the meantime, and leaving this
* dangling pointer around has proven to be trouble. */
- current_consensus = NULL;
+ current_ns_consensus = NULL;
+ }
+ current_ns_consensus = c;
+ free_consensus = 0; /* avoid free */
+ } else if (flav == FLAV_MICRODESC) {
+ if (current_md_consensus) {
+ networkstatus_copy_old_consensus_info(c, current_md_consensus);
+ networkstatus_vote_free(current_md_consensus);
+ /* more defensive programming */
+ current_md_consensus = NULL;
}
+ current_md_consensus = c;
+ free_consensus = 0; /* avoid free */
}
waiting = &consensus_waiting_for_certs[flav];
@@@ -1780,11 -1738,11 +1781,11 @@@
}
if (flav == USABLE_CONSENSUS_FLAVOR) {
- current_consensus = c;
- free_consensus = 0; /* Prevent free. */
-
/* XXXXNM Microdescs: needs a non-ns variant. */
update_consensus_networkstatus_fetch_time(now);
+
+ nodelist_set_consensus(current_consensus);
+
dirvote_recalculate_timing(options, now);
routerstatus_list_update_named_server_map();
cell_ewma_set_scale_factor(options, current_consensus);
@@@ -1806,11 -1764,11 +1807,11 @@@
write_str_to_file(consensus_fname, consensus, 0);
}
- if (ftime_definitely_before(now, current_consensus->valid_after)) {
+ if (time_definitely_before(now, c->valid_after, 60)) {
char tbuf[ISO_TIME_LEN+1];
char dbuf[64];
- long delta = now - current_consensus->valid_after;
- format_iso_time(tbuf, current_consensus->valid_after);
+ long delta = now - c->valid_after;
+ format_iso_time(tbuf, c->valid_after);
format_time_interval(dbuf, sizeof(dbuf), delta);
log_warn(LD_GENERAL, "Our clock is %s behind the time published in the "
"consensus network status document (%s GMT). Tor needs an "
@@@ -1861,8 -1819,7 +1862,8 @@@ voi
routers_update_all_from_networkstatus(time_t now, int dir_version)
{
routerlist_t *rl = router_get_routerlist();
- networkstatus_t *consensus = networkstatus_get_live_consensus(now);
+ networkstatus_t *consensus = networkstatus_get_reasonably_live_consensus(now,
+ FLAV_NS);
if (networkstatus_v2_list_has_changed)
download_status_map_update_from_v2_networkstatus();
@@@ -1934,7 -1891,7 +1935,7 @@@ download_status_map_update_from_v2_netw
dl_status = digestmap_new();
SMARTLIST_FOREACH_BEGIN(networkstatus_v2_list, networkstatus_v2_t *, ns) {
- SMARTLIST_FOREACH_BEGIN(ns->entries, routerstatus_t *, rs) {
+ 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))
@@@ -1962,8 -1919,7 +1963,8 @@@ routerstatus_list_update_named_server_m
named_server_map = strmap_new();
strmap_free(unnamed_server_map, NULL);
unnamed_server_map = strmap_new();
- SMARTLIST_FOREACH(current_consensus->routerstatus_list, routerstatus_t *, rs,
+ SMARTLIST_FOREACH(current_consensus->routerstatus_list,
+ const routerstatus_t *, rs,
{
if (rs->is_named) {
strmap_set_lc(named_server_map, rs->nickname,
@@@ -1985,6 -1941,7 +1986,6 @@@ routers_update_status_from_consensus_ne
trusted_dir_server_t *ds;
or_options_t *options = get_options();
int authdir = authdir_mode_v2(options) || authdir_mode_v3(options);
- int namingdir = authdir && options->NamingAuthoritativeDir;
networkstatus_t *ns = current_consensus;
if (!ns || !smartlist_len(ns->routerstatus_list))
return;
@@@ -1998,19 -1955,25 +1999,19 @@@
memcmp(rs->identity_digest,
router->cache_info.identity_digest, DIGEST_LEN),
{
+#if 0
/* We have no routerstatus for this router. Clear flags and skip it. */
- if (!namingdir)
- router->is_named = 0;
if (!authdir) {
if (router->purpose == ROUTER_PURPOSE_GENERAL)
router_clear_status_flags(router);
}
+#endif
}) {
/* We have a routerstatus for this router. */
const char *digest = router->cache_info.identity_digest;
ds = router_get_trusteddirserver_by_digest(digest);
- if (!namingdir) {
- if (rs->is_named && !strcasecmp(router->nickname, rs->nickname))
- router->is_named = 1;
- else
- router->is_named = 0;
- }
/* Is it the same descriptor, or only the same identity? */
if (!memcmp(router->cache_info.signed_descriptor_digest,
rs->descriptor_digest, DIGEST_LEN)) {
@@@ -2018,17 -1981,28 +2019,17 @@@
router->cache_info.last_listed_as_valid_until = ns->valid_until;
}
- if (!authdir) {
- /* If we're not an authdir, believe others. */
- router->is_valid = rs->is_valid;
- router->is_running = rs->is_running;
- router->is_fast = rs->is_fast;
- router->is_stable = rs->is_stable;
- router->is_possible_guard = rs->is_possible_guard;
- router->is_exit = rs->is_exit;
- router->is_bad_directory = rs->is_bad_directory;
- router->is_bad_exit = rs->is_bad_exit;
- router->is_hs_dir = rs->is_hs_dir;
- } else {
+ if (authdir) {
/* If we _are_ an authority, we should check whether this router
* is one that will cause us to need a reachability test. */
routerinfo_t *old_router =
- router_get_by_digest(router->cache_info.identity_digest);
+ router_get_mutable_by_digest(router->cache_info.identity_digest);
if (old_router != router) {
router->needs_retest_if_added =
dirserv_should_launch_reachability_test(router, old_router);
}
}
- if (router->is_running && ds) {
+ if (rs->is_flagged_running && ds) {
download_status_reset(&ds->v2_ns_dl_status);
}
if (reset_failures) {
@@@ -2037,9 -2011,10 +2038,9 @@@
} SMARTLIST_FOREACH_JOIN_END(rs, router);
/* Now update last_listed_as_valid_until from v2 networkstatuses. */
- /* XXXX If this is slow, we need to rethink the code. */
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns, {
time_t live_until = ns->published_on + V2_NETWORKSTATUS_ROUTER_LIFETIME;
- SMARTLIST_FOREACH_JOIN(ns->entries, routerstatus_t *, rs,
+ SMARTLIST_FOREACH_JOIN(ns->entries, const routerstatus_t *, rs,
routers, routerinfo_t *, ri,
memcmp(rs->identity_digest,
ri->cache_info.identity_digest, DIGEST_LEN),
@@@ -2060,7 -2035,7 +2061,7 @@@
void
signed_descs_update_status_from_consensus_networkstatus(smartlist_t *descs)
{
- networkstatus_t *ns = current_consensus;
+ networkstatus_t *ns = current_ns_consensus;
if (!ns)
return;
@@@ -2068,11 -2043,11 +2069,11 @@@
char dummy[DIGEST_LEN];
/* instantiates the digest map. */
memset(dummy, 0, sizeof(dummy));
- router_get_consensus_status_by_descriptor_digest(dummy);
+ router_get_consensus_status_by_descriptor_digest(ns, dummy);
}
SMARTLIST_FOREACH(descs, signed_descriptor_t *, d,
{
- routerstatus_t *rs = digestmap_get(ns->desc_digest_map,
+ const routerstatus_t *rs = digestmap_get(ns->desc_digest_map,
d->signed_descriptor_digest);
if (rs) {
if (ns->valid_until > d->last_listed_as_valid_until)
@@@ -2085,7 -2060,7 +2086,7 @@@
* return the result in a newly allocated string. Used only by controller
* interface (for now.) */
char *
-networkstatus_getinfo_helper_single(routerstatus_t *rs)
+networkstatus_getinfo_helper_single(const routerstatus_t *rs)
{
char buf[RS_ENTRY_LEN+1];
routerstatus_format_entry(buf, sizeof(buf), rs, NULL, NS_CONTROL_PORT);
@@@ -2118,9 -2093,6 +2119,9 @@@ networkstatus_getinfo_by_purpose(const
statuses = smartlist_create();
SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
+ node_t *node = node_get_mutable_by_id(ri->cache_info.identity_digest);
+ if (!node)
+ continue;
if (ri->cache_info.published_on < cutoff)
continue;
if (ri->purpose != purpose)
@@@ -2128,7 -2100,7 +2129,7 @@@
if (bridge_auth && ri->purpose == ROUTER_PURPOSE_BRIDGE)
dirserv_set_router_is_running(ri, now);
/* then generate and write out status lines for each of them */
- set_routerstatus_from_routerinfo(&rs, ri, now, 0, 0, 0);
+ set_routerstatus_from_routerinfo(&rs, node, ri, now, 0, 0, 0);
smartlist_add(statuses, networkstatus_getinfo_helper_single(&rs));
});
@@@ -2244,7 -2216,7 +2245,7 @@@ getinfo_helper_networkstatus(control_co
const char *question, char **answer,
const char **errmsg)
{
- routerstatus_t *status;
+ const routerstatus_t *status;
(void) conn;
if (!current_consensus) {
@@@ -2255,7 -2227,7 +2256,7 @@@
if (!strcmp(question, "ns/all")) {
smartlist_t *statuses = smartlist_create();
SMARTLIST_FOREACH(current_consensus->routerstatus_list,
- routerstatus_t *, rs,
+ const routerstatus_t *, rs,
{
smartlist_add(statuses, networkstatus_getinfo_helper_single(rs));
});
@@@ -2299,9 -2271,8 +2300,9 @@@ networkstatus_free_all(void
digestmap_free(v2_download_status_map, _tor_free);
v2_download_status_map = NULL;
- networkstatus_vote_free(current_consensus);
- current_consensus = NULL;
+ networkstatus_vote_free(current_ns_consensus);
+ networkstatus_vote_free(current_md_consensus);
+ current_md_consensus = current_ns_consensus = NULL;
for (i=0; i < N_CONSENSUS_FLAVORS; ++i) {
consensus_waiting_for_certs_t *waiting = &consensus_waiting_for_certs[i];
diff --combined src/or/rendclient.c
index 88c9fd7,b8526b6..1907d5a
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@@ -16,7 -16,6 +16,7 @@@
#include "connection_edge.h"
#include "directory.h"
#include "main.h"
+#include "nodelist.h"
#include "relay.h"
#include "rendclient.h"
#include "rendcommon.h"
@@@ -185,6 -184,7 +185,7 @@@ rend_client_send_introduction(origin_ci
/*XXX maybe give crypto_pk_public_hybrid_encrypt a max_len arg,
* to avoid buffer overflows? */
r = crypto_pk_public_hybrid_encrypt(intro_key, payload+DIGEST_LEN,
+ sizeof(payload)-DIGEST_LEN,
tmp,
(int)(dh_offset+DH_KEY_LEN),
PK_PKCS1_OAEP_PADDING, 0);
@@@ -415,7 -415,7 +416,7 @@@ directory_get_from_hs_dir(const char *d
SMARTLIST_FOREACH(responsible_dirs, routerstatus_t *, dir, {
if (lookup_last_hid_serv_request(dir, desc_id_base32, 0, 0) +
REND_HID_SERV_DIR_REQUERY_PERIOD >= now ||
- !router_get_by_digest(dir->identity_digest))
+ !router_get_by_id_digest(dir->identity_digest))
SMARTLIST_DEL_CURRENT(responsible_dirs, dir);
});
@@@ -740,6 -740,7 +741,6 @@@ rend_client_get_random_intro(const rend
int i;
rend_cache_entry_t *entry;
rend_intro_point_t *intro;
- routerinfo_t *router;
if (rend_cache_lookup_entry(rend_query->onion_address, -1, &entry) < 1) {
log_warn(LD_REND,
@@@ -756,12 -757,11 +757,12 @@@
intro = smartlist_get(entry->parsed->intro_nodes, i);
/* Do we need to look up the router or is the extend info complete? */
if (!intro->extend_info->onion_key) {
+ const node_t *node;
if (tor_digest_is_zero(intro->extend_info->identity_digest))
- router = router_get_by_hexdigest(intro->extend_info->nickname);
+ node = node_get_by_hex_id(intro->extend_info->nickname);
else
- router = router_get_by_digest(intro->extend_info->identity_digest);
- if (!router) {
+ node = node_get_by_id(intro->extend_info->identity_digest);
+ if (!node) {
log_info(LD_REND, "Unknown router with nickname '%s'; trying another.",
intro->extend_info->nickname);
rend_intro_point_free(intro);
@@@ -769,7 -769,7 +770,7 @@@
goto again;
}
extend_info_free(intro->extend_info);
- intro->extend_info = extend_info_from_router(router);
+ intro->extend_info = extend_info_from_node(node);
}
return extend_info_dup(intro->extend_info);
}
diff --combined src/or/rendservice.c
index 9f775ef,1d64cf4..9f364b0
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@@ -14,7 -14,6 +14,7 @@@
#include "config.h"
#include "directory.h"
#include "networkstatus.h"
+#include "nodelist.h"
#include "rendclient.h"
#include "rendcommon.h"
#include "rendservice.h"
@@@ -929,7 -928,8 +929,8 @@@ rend_service_introduce(origin_circuit_
/* Next N bytes is encrypted with service key */
note_crypto_pk_op(REND_SERVER);
r = crypto_pk_private_hybrid_decrypt(
- intro_key,buf,(char*)(request+DIGEST_LEN),request_len-DIGEST_LEN,
+ intro_key,buf,sizeof(buf),
+ (char*)(request+DIGEST_LEN),request_len-DIGEST_LEN,
PK_PKCS1_OAEP_PADDING,1);
if (r<0) {
log_warn(LD_PROTOCOL, "Couldn't decrypt INTRODUCE2 cell.");
@@@ -1002,7 -1002,7 +1003,7 @@@
} else {
char *rp_nickname;
size_t nickname_field_len;
- routerinfo_t *router;
+ const node_t *node;
int version;
if (*buf == 1) {
rp_nickname = buf+1;
@@@ -1029,8 -1029,8 +1030,8 @@@
len -= nickname_field_len;
len -= rp_nickname - buf; /* also remove header space used by version, if
* any */
- router = router_get_by_nickname(rp_nickname, 0);
- if (!router) {
+ node = node_get_by_nickname(rp_nickname, 0);
+ if (!node) {
log_info(LD_REND, "Couldn't find router %s named in introduce2 cell.",
escaped_safe_str_client(rp_nickname));
/* XXXX Add a no-such-router reason? */
@@@ -1038,7 -1038,7 +1039,7 @@@
goto err;
}
- extend_info = extend_info_from_router(router);
+ extend_info = extend_info_from_node(node);
}
if (len != REND_COOKIE_LEN+DH_KEY_LEN) {
@@@ -1366,7 -1366,8 +1367,8 @@@ rend_service_intro_has_opened(origin_ci
goto err;
len += 20;
note_crypto_pk_op(REND_SERVER);
- r = crypto_pk_private_sign_digest(intro_key, buf+len, buf, len);
+ r = crypto_pk_private_sign_digest(intro_key, buf+len, sizeof(buf)-len,
+ buf, len);
if (r<0) {
log_warn(LD_BUG, "Internal error: couldn't sign introduction request.");
reason = END_CIRC_REASON_INTERNAL;
@@@ -1579,7 -1580,7 +1581,7 @@@ directory_post_to_hs_dir(rend_service_d
hs_dir->identity_digest))
/* Don't upload descriptor if we succeeded in doing so last time. */
continue;
- if (!router_get_by_digest(hs_dir->identity_digest)) {
+ if (!router_get_by_id_digest(hs_dir->identity_digest)) {
log_info(LD_REND, "Not sending publish request for v2 descriptor to "
"hidden service directory '%s'; we don't have its "
"router descriptor. Queuing for later upload.",
@@@ -1756,19 -1757,19 +1758,19 @@@ voi
rend_services_introduce(void)
{
int i,j,r;
- routerinfo_t *router;
+ const node_t *node;
rend_service_t *service;
rend_intro_point_t *intro;
int changed, prev_intro_nodes;
- smartlist_t *intro_routers;
+ smartlist_t *intro_nodes;
time_t now;
or_options_t *options = get_options();
- intro_routers = smartlist_create();
+ intro_nodes = smartlist_create();
now = time(NULL);
for (i=0; i < smartlist_len(rend_service_list); ++i) {
- smartlist_clear(intro_routers);
+ smartlist_clear(intro_nodes);
service = smartlist_get(rend_service_list, i);
tor_assert(service);
@@@ -1788,8 -1789,8 +1790,8 @@@
service. */
for (j=0; j < smartlist_len(service->intro_nodes); ++j) {
intro = smartlist_get(service->intro_nodes, j);
- router = router_get_by_digest(intro->extend_info->identity_digest);
- if (!router || !find_intro_circuit(intro, service->pk_digest)) {
+ node = node_get_by_id(intro->extend_info->identity_digest);
+ if (!node || !find_intro_circuit(intro, service->pk_digest)) {
log_info(LD_REND,"Giving up on %s as intro point for %s.",
intro->extend_info->nickname, service->service_id);
if (service->desc) {
@@@ -1808,8 -1809,8 +1810,8 @@@
smartlist_del(service->intro_nodes,j--);
changed = 1;
}
- if (router)
- smartlist_add(intro_routers, router);
+ if (node)
+ smartlist_add(intro_nodes, (void*)node);
}
/* We have enough intro points, and the intro points we thought we had were
@@@ -1838,26 -1839,26 +1840,26 @@@
#define NUM_INTRO_POINTS_INIT (NUM_INTRO_POINTS + 2)
for (j=prev_intro_nodes; j < (prev_intro_nodes == 0 ?
NUM_INTRO_POINTS_INIT : NUM_INTRO_POINTS); ++j) {
- router_crn_flags_t flags = CRN_NEED_UPTIME;
+ router_crn_flags_t flags = CRN_NEED_UPTIME|CRN_NEED_DESC;
if (get_options()->_AllowInvalid & ALLOW_INVALID_INTRODUCTION)
flags |= CRN_ALLOW_INVALID;
- router = router_choose_random_node(intro_routers,
- options->ExcludeNodes, flags);
- if (!router) {
+ node = router_choose_random_node(intro_nodes,
+ options->ExcludeNodes, flags);
+ if (!node) {
log_warn(LD_REND,
"Could only establish %d introduction points for %s.",
smartlist_len(service->intro_nodes), service->service_id);
break;
}
changed = 1;
- smartlist_add(intro_routers, router);
+ smartlist_add(intro_nodes, (void*)node);
intro = tor_malloc_zero(sizeof(rend_intro_point_t));
- intro->extend_info = extend_info_from_router(router);
+ intro->extend_info = extend_info_from_node(node);
intro->intro_key = crypto_new_pk_env();
tor_assert(!crypto_pk_generate_key(intro->intro_key));
smartlist_add(service->intro_nodes, intro);
log_info(LD_REND, "Picked router %s as an intro point for %s.",
- router->nickname, service->service_id);
+ node_get_nickname(node), service->service_id);
}
/* If there's no need to launch new circuits, stop here. */
@@@ -1874,7 -1875,7 +1876,7 @@@
}
}
}
- smartlist_free(intro_routers);
+ smartlist_free(intro_nodes);
}
/** Regenerate and upload rendezvous service descriptors for all
diff --combined src/or/routerlist.c
index 539e540,e29b4c4..96cc01b
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@@ -22,9 -22,7 +22,9 @@@
#include "geoip.h"
#include "hibernate.h"
#include "main.h"
+#include "microdesc.h"
#include "networkstatus.h"
+#include "nodelist.h"
#include "policies.h"
#include "reasons.h"
#include "rendcommon.h"
@@@ -39,21 -37,20 +39,21 @@@
/****************************************************************************/
/* static function prototypes */
-static routerstatus_t *router_pick_directory_server_impl(
+static const routerstatus_t *router_pick_directory_server_impl(
authority_type_t auth, int flags);
-static routerstatus_t *router_pick_trusteddirserver_impl(
+static const routerstatus_t *router_pick_trusteddirserver_impl(
authority_type_t auth, int flags, int *n_busy_out);
static void mark_all_trusteddirservers_up(void);
-static int router_nickname_matches(routerinfo_t *router, const char *nickname);
+static int router_nickname_matches(const routerinfo_t *router,
+ const char *nickname);
+static int node_nickname_matches(const node_t *router,
+ const char *nickname);
static void trusted_dir_server_free(trusted_dir_server_t *ds);
-static void launch_router_descriptor_downloads(smartlist_t *downloadable,
- routerstatus_t *source,
- time_t now);
static int signed_desc_digest_is_recognized(signed_descriptor_t *desc);
static void update_router_have_minimum_dir_info(void);
-static const char *signed_descriptor_get_body_impl(signed_descriptor_t *desc,
- int with_annotations);
+static const char *signed_descriptor_get_body_impl(
+ const signed_descriptor_t *desc,
+ int with_annotations);
static void list_pending_downloads(digestmap_t *result,
int purpose, const char *prefix);
@@@ -315,7 -312,6 +315,7 @@@ trusted_dirs_remove_old_certs(void
time_t now = time(NULL);
#define DEAD_CERT_LIFETIME (2*24*60*60)
#define OLD_CERT_LIFETIME (7*24*60*60)
+#define CERT_EXPIRY_SKEW (60*60)
if (!trusted_dir_certs)
return;
@@@ -332,7 -328,7 +332,7 @@@
time_t cert_published;
if (newest == cert)
continue;
- expired = ftime_definitely_after(now, cert->expires);
+ expired = time_definitely_after(now, cert->expires, CERT_EXPIRY_SKEW);
cert_published = cert->cache_info.published_on;
/* Store expired certs for 48 hours after a newer arrives;
*/
@@@ -524,7 -520,7 +524,7 @@@ authority_certs_fetch_missing(networkst
continue;
cl = get_cert_list(ds->v3_identity_digest);
SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert, {
- if (!ftime_definitely_after(now, cert->expires)) {
+ if (! time_definitely_after(now, cert->expires, CERT_EXPIRY_SKEW)) {
/* It's not expired, and we weren't looking for something to
* verify a consensus with. Call it done. */
download_status_reset(&cl->dl_status);
@@@ -604,7 -600,7 +604,7 @@@ router_should_rebuild_store(desc_store_
/** Return the desc_store_t in <b>rl</b> that should be used to store
* <b>sd</b>. */
static INLINE desc_store_t *
-desc_get_store(routerlist_t *rl, signed_descriptor_t *sd)
+desc_get_store(routerlist_t *rl, const signed_descriptor_t *sd)
{
if (sd->is_extrainfo)
return &rl->extrainfo_store;
@@@ -930,10 -926,10 +930,10 @@@ router_get_trusted_dir_servers(void
* Don't pick an authority if any non-authority is viable; try to avoid using
* servers that have returned 503 recently.
*/
-routerstatus_t *
+const routerstatus_t *
router_pick_directory_server(authority_type_t type, int flags)
{
- routerstatus_t *choice;
+ const routerstatus_t *choice;
if (get_options()->PreferTunneledDirConns)
flags |= _PDS_PREFER_TUNNELED_DIR_CONNS;
@@@ -962,8 -958,8 +962,8 @@@ in
router_get_my_share_of_directory_requests(double *v2_share_out,
double *v3_share_out)
{
- routerinfo_t *me = router_get_my_routerinfo();
- routerstatus_t *rs;
+ 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;
if (!me)
@@@ -1036,10 -1032,10 +1036,10 @@@ trusteddirserver_get_by_v3_auth_digest(
/** Try to find a running trusted dirserver. Flags are as for
* router_pick_directory_server.
*/
-routerstatus_t *
+const routerstatus_t *
router_pick_trusteddirserver(authority_type_t type, int flags)
{
- routerstatus_t *choice;
+ const routerstatus_t *choice;
int busy = 0;
if (get_options()->PreferTunneledDirConns)
flags |= _PDS_PREFER_TUNNELED_DIR_CONNS;
@@@ -1051,8 -1047,7 +1051,8 @@@
/* If the reason that we got no server is that servers are "busy",
* we must be excluding good servers because we already have serverdesc
* fetches with them. Do not mark down servers up because of this. */
- tor_assert((flags & PDS_NO_EXISTING_SERVERDESC_FETCH));
+ tor_assert((flags & (PDS_NO_EXISTING_SERVERDESC_FETCH|
+ PDS_NO_EXISTING_MICRODESC_FETCH)));
return NULL;
}
@@@ -1072,10 -1067,10 +1072,10 @@@
* If the _PDS_PREFER_TUNNELED_DIR_CONNS flag is set, prefer directory servers
* that we can use with BEGINDIR.
*/
-static routerstatus_t *
+static const routerstatus_t *
router_pick_directory_server_impl(authority_type_t type, int flags)
{
- routerstatus_t *result;
+ const node_t *result;
smartlist_t *direct, *tunnel;
smartlist_t *trusted_direct, *trusted_tunnel;
smartlist_t *overloaded_direct, *overloaded_tunnel;
@@@ -1096,54 -1091,49 +1096,54 @@@
overloaded_tunnel = smartlist_create();
/* Find all the running dirservers we know about. */
- SMARTLIST_FOREACH_BEGIN(consensus->routerstatus_list, routerstatus_t *,
- status) {
+ SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), const node_t *, node) {
int is_trusted;
- int is_overloaded = status->last_dir_503_at + DIR_503_TIMEOUT > now;
+ int is_overloaded;
tor_addr_t addr;
- if (!status->is_running || !status->dir_port || !status->is_valid)
+ const routerstatus_t *status = node->rs;
+ if (!status)
continue;
- if (status->is_bad_directory)
+
+ if (!node->is_running || !status->dir_port || !node->is_valid)
+ continue;
+ if (node->is_bad_directory)
continue;
- if (requireother && router_digest_is_me(status->identity_digest))
+ if (requireother && router_digest_is_me(node->identity))
continue;
if (type & V3_AUTHORITY) {
if (!(status->version_supports_v3_dir ||
- router_digest_is_trusted_dir_type(status->identity_digest,
+ router_digest_is_trusted_dir_type(node->identity,
V3_AUTHORITY)))
continue;
}
- is_trusted = router_digest_is_trusted_dir(status->identity_digest);
- if ((type & V2_AUTHORITY) && !(status->is_v2_dir || is_trusted))
+ is_trusted = router_digest_is_trusted_dir(node->identity);
+ if ((type & V2_AUTHORITY) && !(node->rs->is_v2_dir || is_trusted))
continue;
if ((type & EXTRAINFO_CACHE) &&
- !router_supports_extrainfo(status->identity_digest, 0))
+ !router_supports_extrainfo(node->identity, 0))
continue;
/* XXXX IP6 proposal 118 */
- tor_addr_from_ipv4h(&addr, status->addr);
+ tor_addr_from_ipv4h(&addr, node->rs->addr);
+
+ is_overloaded = status->last_dir_503_at + DIR_503_TIMEOUT > now;
if (prefer_tunnel &&
status->version_supports_begindir &&
(!fascistfirewall ||
fascist_firewall_allows_address_or(&addr, status->or_port)))
smartlist_add(is_trusted ? trusted_tunnel :
- is_overloaded ? overloaded_tunnel : tunnel, status);
+ is_overloaded ? overloaded_tunnel : tunnel, (void*)node);
else if (!fascistfirewall ||
fascist_firewall_allows_address_dir(&addr, status->dir_port))
smartlist_add(is_trusted ? trusted_direct :
- is_overloaded ? overloaded_direct : direct, status);
- } SMARTLIST_FOREACH_END(status);
+ is_overloaded ? overloaded_direct : direct, (void*)node);
+ } SMARTLIST_FOREACH_END(node);
if (smartlist_len(tunnel)) {
- result = routerstatus_sl_choose_by_bandwidth(tunnel, WEIGHT_FOR_DIR);
+ result = node_sl_choose_by_bandwidth(tunnel, WEIGHT_FOR_DIR);
} else if (smartlist_len(overloaded_tunnel)) {
- result = routerstatus_sl_choose_by_bandwidth(overloaded_tunnel,
+ result = node_sl_choose_by_bandwidth(overloaded_tunnel,
WEIGHT_FOR_DIR);
} else if (smartlist_len(trusted_tunnel)) {
/* FFFF We don't distinguish between trusteds and overloaded trusteds
@@@ -1152,10 -1142,10 +1152,10 @@@
* is a feature, but it could easily be a bug. -RD */
result = smartlist_choose(trusted_tunnel);
} else if (smartlist_len(direct)) {
- result = routerstatus_sl_choose_by_bandwidth(direct, WEIGHT_FOR_DIR);
+ result = node_sl_choose_by_bandwidth(direct, WEIGHT_FOR_DIR);
} else if (smartlist_len(overloaded_direct)) {
- result = routerstatus_sl_choose_by_bandwidth(overloaded_direct,
- WEIGHT_FOR_DIR);
+ result = node_sl_choose_by_bandwidth(overloaded_direct,
+ WEIGHT_FOR_DIR);
} else {
result = smartlist_choose(trusted_direct);
}
@@@ -1165,26 -1155,25 +1165,26 @@@
smartlist_free(trusted_tunnel);
smartlist_free(overloaded_direct);
smartlist_free(overloaded_tunnel);
- return result;
+ return result ? result->rs : NULL;
}
/** Choose randomly from among the trusted dirservers that are up. Flags
* are as for router_pick_directory_server_impl().
*/
-static routerstatus_t *
+static const routerstatus_t *
router_pick_trusteddirserver_impl(authority_type_t type, int flags,
int *n_busy_out)
{
smartlist_t *direct, *tunnel;
smartlist_t *overloaded_direct, *overloaded_tunnel;
- routerinfo_t *me = router_get_my_routerinfo();
- routerstatus_t *result;
+ const routerinfo_t *me = router_get_my_routerinfo();
+ const routerstatus_t *result;
time_t now = time(NULL);
const int requireother = ! (flags & PDS_ALLOW_SELF);
const int fascistfirewall = ! (flags & PDS_IGNORE_FASCISTFIREWALL);
const int prefer_tunnel = (flags & _PDS_PREFER_TUNNELED_DIR_CONNS);
const int no_serverdesc_fetching =(flags & PDS_NO_EXISTING_SERVERDESC_FETCH);
+ const int no_microdesc_fetching =(flags & PDS_NO_EXISTING_MICRODESC_FETCH);
int n_busy = 0;
if (!trusted_dir_servers)
@@@ -1223,13 -1212,6 +1223,13 @@@
continue;
}
}
+ if (no_microdesc_fetching) {
+ if (connection_get_by_type_addr_port_purpose(
+ CONN_TYPE_DIR, &addr, d->dir_port, DIR_PURPOSE_FETCH_MICRODESC)) {
+ ++n_busy;
+ continue;
+ }
+ }
if (prefer_tunnel &&
d->or_port &&
@@@ -1268,18 -1250,22 +1268,18 @@@
static void
mark_all_trusteddirservers_up(void)
{
- if (routerlist) {
- SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
- if (router_digest_is_trusted_dir(router->cache_info.identity_digest) &&
- router->dir_port > 0) {
- router->is_running = 1;
- });
- }
+ SMARTLIST_FOREACH(nodelist_get_list(), node_t *, node, {
+ if (router_digest_is_trusted_dir(node->identity))
+ node->is_running = 1;
+ });
if (trusted_dir_servers) {
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, dir,
{
routerstatus_t *rs;
dir->is_running = 1;
download_status_reset(&dir->v2_ns_dl_status);
- rs = router_get_consensus_status_by_id(dir->digest);
- if (rs && !rs->is_running) {
- rs->is_running = 1;
+ rs = router_get_mutable_consensus_status_by_id(dir->digest);
+ if (rs) {
rs->last_dir_503_at = 0;
control_event_networkstatus_changed_single(rs);
}
@@@ -1303,14 -1289,25 +1303,14 @@@ router_reset_status_download_failures(v
mark_all_trusteddirservers_up();
}
-/** Return true iff router1 and router2 have the same /16 network. */
+/** Return true iff router1 and router2 have similar enough network addresses
+ * that we should treat them as being in the same family */
static INLINE int
-routers_in_same_network_family(routerinfo_t *r1, routerinfo_t *r2)
-{
- return (r1->addr & 0xffff0000) == (r2->addr & 0xffff0000);
-}
-
-/** Look through the routerlist and identify routers that
- * advertise the same /16 network address as <b>router</b>.
- * Add each of them to <b>sl</b>.
- */
-static void
-routerlist_add_network_family(smartlist_t *sl, routerinfo_t *router)
+addrs_in_same_network_family(const tor_addr_t *a1,
+ const tor_addr_t *a2)
{
- SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, r,
- {
- if (router != r && routers_in_same_network_family(router, r))
- smartlist_add(sl, r);
- });
+ /* XXXX MOVE ? */
+ return 0 == tor_addr_compare_masked(a1, a2, 16, CMP_SEMANTIC);
}
/** Add all the family of <b>router</b> to the smartlist <b>sl</b>.
@@@ -1318,132 -1315,122 +1318,132 @@@
* or pick more than one relay from a family for our entry guard list.
*/
void
-routerlist_add_family(smartlist_t *sl, routerinfo_t *router)
+nodelist_add_node_family(smartlist_t *sl, const node_t *node)
{
- routerinfo_t *r;
- config_line_t *cl;
+ /* XXXX MOVE */
+ const smartlist_t *all_nodes = nodelist_get_list();
+ const smartlist_t *declared_family;
or_options_t *options = get_options();
- /* First, add any routers with similar network addresses. */
- if (options->EnforceDistinctSubnets)
- routerlist_add_network_family(sl, router);
+ tor_assert(node);
- if (router->declared_family) {
- /* Add every r such that router declares familyness with r, and r
+ declared_family = node_get_declared_family(node);
+
+ /* First, add any nodes with similar network addresses. */
+ if (options->EnforceDistinctSubnets) {
+ tor_addr_t node_addr;
+ node_get_addr(node, &node_addr);
+
+ SMARTLIST_FOREACH_BEGIN(all_nodes, const node_t *, node2) {
+ tor_addr_t a;
+ node_get_addr(node2, &a);
+ if (addrs_in_same_network_family(&a, &node_addr))
+ smartlist_add(sl, (void*)node2);
+ } SMARTLIST_FOREACH_END(node2);
+ }
+
+ /* Now, add all nodes in the declared_family of this node, if they
+ * also declare this node to be in their family. */
+ if (declared_family) {
+ /* Add every r such that router declares familyness with node, and node
* declares familyhood with router. */
- SMARTLIST_FOREACH(router->declared_family, const char *, n,
- {
- if (!(r = router_get_by_nickname(n, 0)))
- continue;
- if (!r->declared_family)
- continue;
- SMARTLIST_FOREACH(r->declared_family, const char *, n2,
- {
- if (router_nickname_matches(router, n2))
- smartlist_add(sl, r);
- });
- });
+ SMARTLIST_FOREACH_BEGIN(declared_family, const char *, name) {
+ const node_t *node2;
+ const smartlist_t *family2;
+ if (!(node2 = node_get_by_nickname(name, 0)))
+ continue;
+ if (!(family2 = node_get_declared_family(node2)))
+ continue;
+ SMARTLIST_FOREACH_BEGIN(family2, const char *, name2) {
+ if (node_nickname_matches(node, name2)) {
+ smartlist_add(sl, (void*)node2);
+ break;
+ }
+ } SMARTLIST_FOREACH_END(name2);
+ } SMARTLIST_FOREACH_END(name);
}
/* If the user declared any families locally, honor those too. */
- for (cl = options->NodeFamilies; cl; cl = cl->next) {
- if (router_nickname_is_in_list(router, cl->value)) {
- add_nickname_list_to_smartlist(sl, cl->value, 0);
- }
+ if (options->NodeFamilySets) {
+ SMARTLIST_FOREACH(options->NodeFamilySets, const routerset_t *, rs, {
+ if (routerset_contains_node(rs, node)) {
+ routerset_get_all_nodes(sl, rs, 0);
+ }
+ });
+ }
+}
+
+/** Given a <b>router</b>, add every node_t in its family to <b>sl</b>.
+ *
+ * Note the type mismatch: This function takes a routerinfo, but adds nodes
+ * to the smartlist!
+ */
+static void
+routerlist_add_nodes_in_family(smartlist_t *sl, const routerinfo_t *router)
+{
+ /* XXXX MOVE ? */
+ node_t fake_node;
+ const node_t *node = node_get_by_id(router->cache_info.identity_digest);;
+ if (node == NULL) {
+ memset(&fake_node, 0, sizeof(fake_node));
+ fake_node.ri = (routerinfo_t *)router;
+ memcpy(fake_node.identity, router->cache_info.identity_digest, DIGEST_LEN);
+ node = &fake_node;
}
+ nodelist_add_node_family(sl, node);
}
-/** Return true iff r is named by some nickname in <b>lst</b>. */
+/** Return true iff <b>node</b> is named by some nickname in <b>lst</b>. */
static INLINE int
-router_in_nickname_smartlist(smartlist_t *lst, routerinfo_t *r)
+node_in_nickname_smartlist(const smartlist_t *lst, const node_t *node)
{
+ /* XXXX MOVE */
if (!lst) return 0;
- SMARTLIST_FOREACH(lst, const char *, name,
- if (router_nickname_matches(r, name))
- return 1;);
+ SMARTLIST_FOREACH(lst, const char *, name, {
+ if (node_nickname_matches(node, name))
+ return 1;
+ });
return 0;
}
/** Return true iff r1 and r2 are in the same family, but not the same
* router. */
int
-routers_in_same_family(routerinfo_t *r1, routerinfo_t *r2)
+nodes_in_same_family(const node_t *node1, const node_t *node2)
{
+ /* XXXX MOVE */
or_options_t *options = get_options();
- config_line_t *cl;
-
- if (options->EnforceDistinctSubnets && routers_in_same_network_family(r1,r2))
- return 1;
- if (router_in_nickname_smartlist(r1->declared_family, r2) &&
- router_in_nickname_smartlist(r2->declared_family, r1))
- return 1;
-
- for (cl = options->NodeFamilies; cl; cl = cl->next) {
- if (router_nickname_is_in_list(r1, cl->value) &&
- router_nickname_is_in_list(r2, cl->value))
+ /* Are they in the same family because of their addresses? */
+ if (options->EnforceDistinctSubnets) {
+ tor_addr_t a1, a2;
+ node_get_addr(node1, &a1);
+ node_get_addr(node2, &a2);
+ if (addrs_in_same_network_family(&a1, &a2))
return 1;
}
- return 0;
-}
-/** Given a (possibly NULL) comma-and-whitespace separated list of nicknames,
- * see which nicknames in <b>list</b> name routers in our routerlist, and add
- * the routerinfos for those routers to <b>sl</b>. If <b>must_be_running</b>,
- * only include routers that we think are running.
- * Warn if any non-Named routers are specified by nickname.
- */
-void
-add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
- int must_be_running)
-{
- routerinfo_t *router;
- smartlist_t *nickname_list;
- int have_dir_info = router_have_minimum_dir_info();
-
- if (!list)
- return; /* nothing to do */
- tor_assert(sl);
-
- nickname_list = smartlist_create();
- if (!warned_nicknames)
- warned_nicknames = smartlist_create();
+ /* Are they in the same family because the agree they are? */
+ {
+ const smartlist_t *f1, *f2;
+ f1 = node_get_declared_family(node1);
+ f2 = node_get_declared_family(node2);
+ if (f1 && f2 &&
+ node_in_nickname_smartlist(f1, node2) &&
+ node_in_nickname_smartlist(f2, node1))
+ return 1;
+ }
- smartlist_split_string(nickname_list, list, ",",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+ /* Are they in the same option because the user says they are? */
+ if (options->NodeFamilySets) {
+ SMARTLIST_FOREACH(options->NodeFamilySets, const routerset_t *, rs, {
+ if (routerset_contains_node(rs, node1) &&
+ routerset_contains_node(rs, node2))
+ return 1;
+ });
+ }
- SMARTLIST_FOREACH(nickname_list, const char *, nick, {
- int warned;
- if (!is_legal_nickname_or_hexdigest(nick)) {
- log_warn(LD_CONFIG, "Nickname '%s' is misformed; skipping", nick);
- continue;
- }
- router = router_get_by_nickname(nick, 1);
- warned = smartlist_string_isin(warned_nicknames, nick);
- if (router) {
- if (!must_be_running || router->is_running) {
- smartlist_add(sl,router);
- }
- } else if (!router_get_consensus_status_by_nickname(nick,1)) {
- if (!warned) {
- log_fn(have_dir_info ? LOG_WARN : LOG_INFO, LD_CONFIG,
- "Nickname list includes '%s' which isn't a known router.",nick);
- smartlist_add(warned_nicknames, tor_strdup(nick));
- }
- }
- });
- SMARTLIST_FOREACH(nickname_list, char *, nick, tor_free(nick));
- smartlist_free(nickname_list);
+ return 0;
}
/** Return 1 iff any member of the (possibly NULL) comma-separated list
@@@ -1451,7 -1438,7 +1451,7 @@@
* return 0.
*/
int
-router_nickname_is_in_list(routerinfo_t *router, const char *list)
+router_nickname_is_in_list(const routerinfo_t *router, const char *list)
{
smartlist_t *nickname_list;
int v = 0;
@@@ -1470,32 -1457,34 +1470,32 @@@
return v;
}
-/** Add every suitable router from our routerlist to <b>sl</b>, so that
+/** Add every suitable node from our nodelist to <b>sl</b>, so that
* we can pick a node for a circuit.
*/
static void
-router_add_running_routers_to_smartlist(smartlist_t *sl, int allow_invalid,
- int need_uptime, int need_capacity,
- int need_guard)
-{
- if (!routerlist)
- return;
+router_add_running_nodes_to_smartlist(smartlist_t *sl, int allow_invalid,
+ int need_uptime, int need_capacity,
+ int need_guard, int need_desc)
+{ /* XXXX MOVE */
+ SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), const node_t *, node) {
+ if (!node->is_running ||
+ (!node->is_valid && !allow_invalid))
+ continue;
+ if (need_desc && !(node->ri || (node->rs && node->md)))
+ continue;
+ if (node->ri && node->ri->purpose != ROUTER_PURPOSE_GENERAL)
+ continue;
+ if (node_is_unreliable(node, need_uptime, need_capacity, need_guard))
+ continue;
- SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
- {
- if (router->is_running &&
- router->purpose == ROUTER_PURPOSE_GENERAL &&
- (router->is_valid || allow_invalid) &&
- !router_is_unreliable(router, need_uptime,
- need_capacity, need_guard)) {
- /* If it's running, and it's suitable according to the
- * other flags we had in mind */
- smartlist_add(sl, router);
- }
- });
+ smartlist_add(sl, (void *)node);
+ } SMARTLIST_FOREACH_END(node);
}
/** Look through the routerlist until we find a router that has my key.
Return it. */
-routerinfo_t *
+const routerinfo_t *
routerlist_find_my_routerinfo(void)
{
if (!routerlist)
@@@ -1513,9 -1502,9 +1513,9 @@@
* that allows exit to this address:port, or return NULL if there
* isn't a good one.
*/
-routerinfo_t *
+const node_t *
router_find_exact_exit_enclave(const char *address, uint16_t port)
-{
+{/*XXXX MOVE*/
uint32_t addr;
struct in_addr in;
tor_addr_t a;
@@@ -1526,12 -1515,13 +1526,12 @@@
tor_addr_from_ipv4h(&a, addr);
- SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
- {
- if (router->addr == addr &&
- router->is_running &&
- compare_tor_addr_to_addr_policy(&a, port, router->exit_policy) ==
+ SMARTLIST_FOREACH(nodelist_get_list(), const node_t *, node, {
+ if (node_get_addr_ipv4h(node) == addr &&
+ node->is_running &&
+ compare_tor_addr_to_node_policy(&a, port, node) ==
ADDR_POLICY_ACCEPTED)
- return router;
+ return node;
});
return NULL;
}
@@@ -1543,14 -1533,14 +1543,14 @@@
* If <b>need_guard</b>, we require that the router is a possible entry guard.
*/
int
-router_is_unreliable(routerinfo_t *router, int need_uptime,
- int need_capacity, int need_guard)
+node_is_unreliable(const node_t *node, int need_uptime,
+ int need_capacity, int need_guard)
{
- if (need_uptime && !router->is_stable)
+ if (need_uptime && !node->is_stable)
return 1;
- if (need_capacity && !router->is_fast)
+ if (need_capacity && !node->is_fast)
return 1;
- if (need_guard && !router->is_possible_guard)
+ if (need_guard && !node->is_possible_guard)
return 1;
return 0;
}
@@@ -1558,7 -1548,7 +1558,7 @@@
/** Return the smaller of the router's configured BandwidthRate
* and its advertised capacity. */
uint32_t
-router_get_advertised_bandwidth(routerinfo_t *router)
+router_get_advertised_bandwidth(const routerinfo_t *router)
{
if (router->bandwidthcapacity < router->bandwidthrate)
return router->bandwidthcapacity;
@@@ -1572,7 -1562,7 +1572,7 @@@
/** Return the smaller of the router's configured BandwidthRate
* and its advertised capacity, capped by max-believe-bw. */
uint32_t
-router_get_advertised_bandwidth_capped(routerinfo_t *router)
+router_get_advertised_bandwidth_capped(const routerinfo_t *router)
{
uint32_t result = router->bandwidthcapacity;
if (result > router->bandwidthrate)
@@@ -1614,10 -1604,13 +1614,10 @@@ kb_to_bytes(uint32_t bw
}
/** Helper function:
- * choose a random element of smartlist <b>sl</b>, weighted by
+ * choose a random element of smartlist <b>sl</b> of nodes, weighted by
* the advertised bandwidth of each element using the consensus
* bandwidth weights.
*
- * If <b>statuses</b> is zero, then <b>sl</b> is a list of
- * routerinfo_t's. Otherwise it's a list of routerstatus_t's.
- *
* If <b>rule</b>==WEIGHT_FOR_EXIT. we're picking an exit node: consider all
* nodes' bandwidth equally regardless of their Exit status, since there may
* be some in the list because they exit to obscure ports. If
@@@ -1627,9 -1620,10 +1627,9 @@@
* guard node: consider all guard's bandwidth equally. Otherwise, weight
* guards proportionally less.
*/
-static void *
-smartlist_choose_by_bandwidth_weights(smartlist_t *sl,
- bandwidth_weight_rule_t rule,
- int statuses)
+static const node_t *
+smartlist_choose_node_by_bandwidth_weights(smartlist_t *sl,
+ bandwidth_weight_rule_t rule)
{
int64_t weight_scale;
int64_t rand_bw;
@@@ -1724,14 -1718,15 +1724,14 @@@
bandwidths = tor_malloc_zero(sizeof(double)*smartlist_len(sl));
// Cycle through smartlist and total the bandwidth.
- for (i = 0; i < (unsigned)smartlist_len(sl); ++i) {
+ SMARTLIST_FOREACH_BEGIN(sl, const node_t *, node) {
int is_exit = 0, is_guard = 0, is_dir = 0, this_bw = 0, is_me = 0;
double weight = 1;
- if (statuses) {
- routerstatus_t *status = smartlist_get(sl, i);
- is_exit = status->is_exit;
- is_guard = status->is_possible_guard;
- is_dir = (status->dir_port != 0);
- if (!status->has_bandwidth) {
+ is_exit = node->is_exit;
+ is_guard = node->is_possible_guard;
+ is_dir = node_is_dir(node);
+ if (node->rs) {
+ if (!node->rs->has_bandwidth) {
tor_free(bandwidths);
/* This should never happen, unless all the authorites downgrade
* to 0.2.0 or rogue routerstatuses get inserted into our consensus. */
@@@ -1740,17 -1735,26 +1740,17 @@@
"old router selection algorithm.");
return NULL;
}
- this_bw = kb_to_bytes(status->bandwidth);
- if (router_digest_is_me(status->identity_digest))
- is_me = 1;
+ this_bw = kb_to_bytes(node->rs->bandwidth);
+ } else if (node->ri) {
+ /* bridge or other descriptor not in our consensus */
+ this_bw = bridge_get_advertised_bandwidth_bounded(node->ri);
+ have_unknown = 1;
} else {
- routerstatus_t *rs;
- routerinfo_t *router = smartlist_get(sl, i);
- rs = router_get_consensus_status_by_id(
- router->cache_info.identity_digest);
- is_exit = router->is_exit;
- is_guard = router->is_possible_guard;
- is_dir = (router->dir_port != 0);
- if (rs && rs->has_bandwidth) {
- this_bw = kb_to_bytes(rs->bandwidth);
- } else { /* bridge or other descriptor not in our consensus */
- this_bw = bridge_get_advertised_bandwidth_bounded(router);
- have_unknown = 1;
- }
- if (router_digest_is_me(router->cache_info.identity_digest))
- is_me = 1;
+ /* We can't use this one. */
+ continue;
}
+ is_me = router_digest_is_me(node->identity);
+
if (is_guard && is_exit) {
weight = (is_dir ? Wdb*Wd : Wd);
} else if (is_guard) {
@@@ -1761,11 -1765,11 +1761,11 @@@
weight = (is_dir ? Wmb*Wm : Wm);
}
- bandwidths[i] = weight*this_bw;
+ bandwidths[node_sl_idx] = weight*this_bw;
weighted_bw += weight*this_bw;
if (is_me)
sl_last_weighted_bw_of_me = weight*this_bw;
- }
+ } SMARTLIST_FOREACH_END(node);
/* XXXX022 this is a kludge to expose these values. */
sl_last_total_weighted_bw = weighted_bw;
@@@ -1813,9 -1817,12 +1813,9 @@@
}
/** Helper function:
- * choose a random element of smartlist <b>sl</b>, weighted by
+ * choose a random node_t element of smartlist <b>sl</b>, weighted by
* the advertised bandwidth of each element.
*
- * If <b>statuses</b> is zero, then <b>sl</b> is a list of
- * routerinfo_t's. Otherwise it's a list of routerstatus_t's.
- *
* If <b>rule</b>==WEIGHT_FOR_EXIT. we're picking an exit node: consider all
* nodes' bandwidth equally regardless of their Exit status, since there may
* be some in the list because they exit to obscure ports. If
@@@ -1825,11 -1832,13 +1825,11 @@@
* guard node: consider all guard's bandwidth equally. Otherwise, weight
* guards proportionally less.
*/
-static void *
-smartlist_choose_by_bandwidth(smartlist_t *sl, bandwidth_weight_rule_t rule,
- int statuses)
+static const node_t *
+smartlist_choose_node_by_bandwidth(smartlist_t *sl,
+ bandwidth_weight_rule_t rule)
{
- unsigned int i;
- routerinfo_t *router;
- routerstatus_t *status=NULL;
+ unsigned i;
int32_t *bandwidths;
int is_exit;
int is_guard;
@@@ -1870,34 -1879,49 +1870,34 @@@
guard_bits = bitarray_init_zero(smartlist_len(sl));
/* Iterate over all the routerinfo_t or routerstatus_t, and */
- for (i = 0; i < (unsigned)smartlist_len(sl); ++i) {
+ SMARTLIST_FOREACH_BEGIN(sl, const node_t *, node) {
/* first, learn what bandwidth we think i has */
int is_known = 1;
int32_t flags = 0;
uint32_t this_bw = 0;
- if (statuses) {
- status = smartlist_get(sl, i);
- if (router_digest_is_me(status->identity_digest))
- me_idx = i;
- router = router_get_by_digest(status->identity_digest);
- is_exit = status->is_exit;
- is_guard = status->is_possible_guard;
- if (status->has_bandwidth) {
- this_bw = kb_to_bytes(status->bandwidth);
+ i = node_sl_idx;
+
+ if (router_digest_is_me(node->identity))
+ me_idx = node_sl_idx;
+
+ is_exit = node->is_exit;
+ is_guard = node->is_possible_guard;
+ if (node->rs) {
+ if (node->rs->has_bandwidth) {
+ this_bw = kb_to_bytes(node->rs->bandwidth);
} else { /* guess */
/* XXX022 once consensuses always list bandwidths, we can take
* this guessing business out. -RD */
is_known = 0;
- flags = status->is_fast ? 1 : 0;
+ flags = node->rs->is_fast ? 1 : 0;
flags |= is_exit ? 2 : 0;
flags |= is_guard ? 4 : 0;
}
- } else {
- routerstatus_t *rs;
- router = smartlist_get(sl, i);
- rs = router_get_consensus_status_by_id(
- router->cache_info.identity_digest);
- if (router_digest_is_me(router->cache_info.identity_digest))
- me_idx = i;
- is_exit = router->is_exit;
- is_guard = router->is_possible_guard;
- if (rs && rs->has_bandwidth) {
- this_bw = kb_to_bytes(rs->bandwidth);
- } else if (rs) { /* guess; don't trust the descriptor */
- /* XXX022 once consensuses always list bandwidths, we can take
- * this guessing business out. -RD */
- is_known = 0;
- flags = router->is_fast ? 1 : 0;
- flags |= is_exit ? 2 : 0;
- flags |= is_guard ? 4 : 0;
- } else /* bridge or other descriptor not in our consensus */
- this_bw = bridge_get_advertised_bandwidth_bounded(router);
+ } else if (node->ri) {
+ /* Must be a bridge if we're willing to use it */
+ this_bw = bridge_get_advertised_bandwidth_bounded(node->ri);
}
+
if (is_exit)
bitarray_set(exit_bits, i);
if (is_guard)
@@@ -1917,9 -1941,9 +1917,9 @@@
total_nonexit_bw += this_bw;
} else {
++n_unknown;
- bandwidths[i] = -flags;
+ bandwidths[node_sl_idx] = -flags;
}
- }
+ } SMARTLIST_FOREACH_END(node);
/* Now, fill in the unknown values. */
if (n_unknown) {
@@@ -2061,23 -2085,40 +2061,23 @@@
return smartlist_get(sl, i);
}
-/** Choose a random element of router list <b>sl</b>, weighted by
- * the advertised bandwidth of each router.
- */
-routerinfo_t *
-routerlist_sl_choose_by_bandwidth(smartlist_t *sl,
- bandwidth_weight_rule_t rule)
-{
- routerinfo_t *ret;
- if ((ret = smartlist_choose_by_bandwidth_weights(sl, rule, 0))) {
- return ret;
- } else {
- return smartlist_choose_by_bandwidth(sl, rule, 0);
- }
-}
-
/** Choose a random element of status list <b>sl</b>, weighted by
- * the advertised bandwidth of each status.
- */
-routerstatus_t *
-routerstatus_sl_choose_by_bandwidth(smartlist_t *sl,
- bandwidth_weight_rule_t rule)
-{
- /* We are choosing neither exit nor guard here. Weight accordingly. */
- routerstatus_t *ret;
- if ((ret = smartlist_choose_by_bandwidth_weights(sl, rule, 1))) {
+ * the advertised bandwidth of each node */
+const node_t *
+node_sl_choose_by_bandwidth(smartlist_t *sl,
+ bandwidth_weight_rule_t rule)
+{ /*XXXX MOVE */
+ const node_t *ret;
+ if ((ret = smartlist_choose_node_by_bandwidth_weights(sl, rule))) {
return ret;
} else {
- return smartlist_choose_by_bandwidth(sl, rule, 1);
+ return smartlist_choose_node_by_bandwidth(sl, rule);
}
}
-/** Return a random running router from the routerlist. Never
- * pick a node whose routerinfo is in
- * <b>excludedsmartlist</b>, or whose routerinfo matches <b>excludedset</b>,
+/** Return a random running node from the nodelist. Never
+ * pick a node that is in
+ * <b>excludedsmartlist</b>, or which matches <b>excludedset</b>,
* even if they are the only nodes available.
* If <b>CRN_NEED_UPTIME</b> is set in flags and any router has more than
* a minimum uptime, return one of those.
@@@ -2089,26 -2130,21 +2089,26 @@@
* If <b>CRN_WEIGHT_AS_EXIT</b> is set in flags, we weight bandwidths as if
* picking an exit node, otherwise we weight bandwidths for picking a relay
* node (that is, possibly discounting exit nodes).
+ * If <b>CRN_NEED_DESC</b> is set in flags, we only consider nodes that
+ * have a routerinfo or microdescriptor -- that is, enough info to be
+ * used to build a circuit.
*/
-routerinfo_t *
+const node_t *
router_choose_random_node(smartlist_t *excludedsmartlist,
routerset_t *excludedset,
router_crn_flags_t flags)
-{
+{ /* XXXX MOVE */
const int need_uptime = (flags & CRN_NEED_UPTIME) != 0;
const int need_capacity = (flags & CRN_NEED_CAPACITY) != 0;
const int need_guard = (flags & CRN_NEED_GUARD) != 0;
const int allow_invalid = (flags & CRN_ALLOW_INVALID) != 0;
const int weight_for_exit = (flags & CRN_WEIGHT_AS_EXIT) != 0;
+ const int need_desc = (flags & CRN_NEED_DESC) != 0;
smartlist_t *sl=smartlist_create(),
- *excludednodes=smartlist_create();
- routerinfo_t *choice = NULL, *r;
+ *excludednodes=smartlist_create();
+ const node_t *choice = NULL;
+ const routerinfo_t *r;
bandwidth_weight_rule_t rule;
tor_assert(!(weight_for_exit && need_guard));
@@@ -2118,30 -2154,29 +2118,30 @@@
/* Exclude relays that allow single hop exit circuits, if the user
* wants to (such relays might be risky) */
if (get_options()->ExcludeSingleHopRelays) {
- routerlist_t *rl = router_get_routerlist();
- SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
- if (r->allow_single_hop_exits) {
- smartlist_add(excludednodes, r);
+ SMARTLIST_FOREACH(nodelist_get_list(), node_t *, node,
+ if (node_allows_single_hop_exits(node)) {
+ smartlist_add(excludednodes, node);
});
}
if ((r = routerlist_find_my_routerinfo())) {
- smartlist_add(excludednodes, r);
- routerlist_add_family(excludednodes, r);
+ const node_t *me = node_get_by_id(r->cache_info.identity_digest);
+ if (me)
+ smartlist_add(excludednodes, (void *)me);
+ routerlist_add_nodes_in_family(excludednodes, r);
}
- router_add_running_routers_to_smartlist(sl, allow_invalid,
- need_uptime, need_capacity,
- need_guard);
+ router_add_running_nodes_to_smartlist(sl, allow_invalid,
+ need_uptime, need_capacity,
+ need_guard, need_desc);
smartlist_subtract(sl,excludednodes);
if (excludedsmartlist)
smartlist_subtract(sl,excludedsmartlist);
if (excludedset)
- routerset_subtract_routers(sl,excludedset);
+ routerset_subtract_nodes(sl,excludedset);
// Always weight by bandwidth
- choice = routerlist_sl_choose_by_bandwidth(sl, rule);
+ choice = node_sl_choose_by_bandwidth(sl, rule);
smartlist_free(sl);
if (!choice && (need_uptime || need_capacity || need_guard)) {
@@@ -2164,88 -2199,35 +2164,88 @@@
return choice;
}
-/** Helper: Return true iff the <b>identity_digest</b> and <b>nickname</b>
- * combination of a router, encoded in hexadecimal, matches <b>hexdigest</b>
- * (which is optionally prefixed with a single dollar sign). Return false if
- * <b>hexdigest</b> is malformed, or it doesn't match. */
-static INLINE int
-hex_digest_matches(const char *hexdigest, const char *identity_digest,
- const char *nickname, int is_named)
+/** Helper: given an extended nickname in <b>hexdigest</b> try to decode it.
+ * Return 0 on success, -1 on failure. Store the result into the
+ * DIGEST_LEN-byte buffer at <b>digest_out</b>, the single character at
+ * <b>nickname_qualifier_char_out</b>, and the MAXNICKNAME_LEN+1-byte buffer
+ * at <b>nickname_out</b>.
+ *
+ * The recognized format is:
+ * HexName = Dollar? HexDigest NamePart?
+ * Dollar = '?'
+ * HexDigest = HexChar*20
+ * HexChar = 'a'..'f' | 'A'..'F' | '0'..'9'
+ * NamePart = QualChar Name
+ * QualChar = '=' | '~'
+ * Name = NameChar*(1..MAX_NICKNAME_LEN)
+ * NameChar = Any ASCII alphanumeric character
+ */
+int
+hex_digest_nickname_decode(const char *hexdigest,
+ char *digest_out,
+ char *nickname_qualifier_char_out,
+ char *nickname_out)
{
- char digest[DIGEST_LEN];
size_t len;
+
tor_assert(hexdigest);
if (hexdigest[0] == '$')
++hexdigest;
len = strlen(hexdigest);
- if (len < HEX_DIGEST_LEN)
+ if (len < HEX_DIGEST_LEN) {
+ return -1;
+ } else if (len > HEX_DIGEST_LEN && (hexdigest[HEX_DIGEST_LEN] == '=' ||
+ hexdigest[HEX_DIGEST_LEN] == '~') &&
+ len <= HEX_DIGEST_LEN+1+MAX_NICKNAME_LEN) {
+ *nickname_qualifier_char_out = hexdigest[HEX_DIGEST_LEN];
+ strlcpy(nickname_out, hexdigest+HEX_DIGEST_LEN+1 , MAX_NICKNAME_LEN+1);
+ } else if (len == HEX_DIGEST_LEN) {
+ ;
+ } else {
+ return -1;
+ }
+
+ if (base16_decode(digest_out, DIGEST_LEN, hexdigest, HEX_DIGEST_LEN)<0)
+ return -1;
+ return 0;
+}
+
+/** Helper: Return true iff the <b>identity_digest</b> and <b>nickname</b>
+ * combination of a router, encoded in hexadecimal, matches <b>hexdigest</b>
+ * (which is optionally prefixed with a single dollar sign). Return false if
+ * <b>hexdigest</b> is malformed, or it doesn't match. */
+static int
+hex_digest_nickname_matches(const char *hexdigest, const char *identity_digest,
+ const char *nickname, int is_named)
+{
+ char digest[DIGEST_LEN];
+ char nn_char='\0';
+ char nn_buf[MAX_NICKNAME_LEN+1];
+
+ if (hex_digest_nickname_decode(hexdigest, digest, &nn_char, nn_buf) == -1)
return 0;
- else if (len > HEX_DIGEST_LEN &&
- (hexdigest[HEX_DIGEST_LEN] == '=' ||
- hexdigest[HEX_DIGEST_LEN] == '~')) {
- if (strcasecmp(hexdigest+HEX_DIGEST_LEN+1, nickname))
+
+ if (nn_char == '=' || nn_char == '~') {
+ if (strcasecmp(nn_buf, nickname))
return 0;
- if (hexdigest[HEX_DIGEST_LEN] == '=' && !is_named)
+ if (nn_char == '=' && !is_named)
return 0;
}
- if (base16_decode(digest, DIGEST_LEN, hexdigest, HEX_DIGEST_LEN)<0)
- return 0;
- return (!memcmp(digest, identity_digest, DIGEST_LEN));
+ return !memcmp(digest, identity_digest, DIGEST_LEN);
+}
+
+/* Return true iff <b>router</b> is listed as named in the current
+ * consensus. */
+static int
+router_is_named(const routerinfo_t *router)
+{
+ const char *digest =
+ networkstatus_get_router_digest_by_nickname(router->nickname);
+
+ return (digest &&
+ !memcmp(digest, router->cache_info.identity_digest, DIGEST_LEN));
}
/** Return true iff the digest of <b>router</b>'s identity key,
@@@ -2253,12 -2235,10 +2253,12 @@@
* optionally prefixed with a single dollar sign). Return false if
* <b>hexdigest</b> is malformed, or it doesn't match. */
static INLINE int
-router_hex_digest_matches(routerinfo_t *router, const char *hexdigest)
+router_hex_digest_matches(const routerinfo_t *router, const char *hexdigest)
{
- return hex_digest_matches(hexdigest, router->cache_info.identity_digest,
- router->nickname, router->is_named);
+ return hex_digest_nickname_matches(hexdigest,
+ router->cache_info.identity_digest,
+ router->nickname,
+ router_is_named(router));
}
/** Return true if <b>router</b>'s nickname matches <b>nickname</b>
@@@ -2266,43 -2246,20 +2266,43 @@@
* matches a hexadecimal value stored in <b>nickname</b>. Return
* false otherwise. */
static int
-router_nickname_matches(routerinfo_t *router, const char *nickname)
+router_nickname_matches(const routerinfo_t *router, const char *nickname)
{
if (nickname[0]!='$' && !strcasecmp(router->nickname, nickname))
return 1;
return router_hex_digest_matches(router, nickname);
}
+/** Return true if <b>node</b>'s nickname matches <b>nickname</b>
+ * (case-insensitive), or if <b>node's</b> identity key digest
+ * matches a hexadecimal value stored in <b>nickname</b>. Return
+ * false otherwise. */
+static int
+node_nickname_matches(const node_t *node, const char *nickname)
+{
+ const char *n = node_get_nickname(node);
+ if (n && nickname[0]!='$' && !strcasecmp(n, nickname))
+ return 1;
+ return hex_digest_nickname_matches(nickname,
+ node->identity,
+ n,
+ node_is_named(node));
+}
+
/** Return the router in our routerlist whose (case-insensitive)
* nickname or (case-sensitive) hexadecimal key digest is
* <b>nickname</b>. Return NULL if no such router is known.
*/
-routerinfo_t *
+const routerinfo_t *
router_get_by_nickname(const char *nickname, int warn_if_unnamed)
{
+#if 1
+ const node_t *node = node_get_by_nickname(nickname, warn_if_unnamed);
+ if (node)
+ return node->ri;
+ else
+ return NULL;
+#else
int maybedigest;
char digest[DIGEST_LEN];
routerinfo_t *best_match=NULL;
@@@ -2348,14 -2305,15 +2348,14 @@@
if (warn_if_unnamed && n_matches > 1) {
smartlist_t *fps = smartlist_create();
int any_unwarned = 0;
- SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
- {
+ SMARTLIST_FOREACH_BEGIN(routerlist->routers, routerinfo_t *, router) {
routerstatus_t *rs;
char *desc;
size_t dlen;
char fp[HEX_DIGEST_LEN+1];
if (strcasecmp(router->nickname, nickname))
continue;
- rs = router_get_consensus_status_by_id(
+ rs = router_get_mutable_consensus_status_by_id(
router->cache_info.identity_digest);
if (rs && !rs->name_lookup_warned) {
rs->name_lookup_warned = 1;
@@@ -2368,7 -2326,7 +2368,7 @@@
tor_snprintf(desc, dlen, "\"$%s\" for the one at %s:%d",
fp, router->address, router->or_port);
smartlist_add(fps, desc);
- });
+ } SMARTLIST_FOREACH_END(router);
if (any_unwarned) {
char *alternatives = smartlist_join_strings(fps, "; ",0,NULL);
log_warn(LD_CONFIG,
@@@ -2381,7 -2339,7 +2381,7 @@@
SMARTLIST_FOREACH(fps, char *, cp, tor_free(cp));
smartlist_free(fps);
} else if (warn_if_unnamed) {
- routerstatus_t *rs = router_get_consensus_status_by_id(
+ routerstatus_t *rs = router_get_mutable_consensus_status_by_id(
best_match->cache_info.identity_digest);
if (rs && !rs->name_lookup_warned) {
char fp[HEX_DIGEST_LEN+1];
@@@ -2397,8 -2355,8 +2397,8 @@@
}
return best_match;
}
-
return NULL;
+#endif
}
/** Try to find a routerinfo for <b>digest</b>. If we don't have one,
@@@ -2407,7 -2365,7 +2407,7 @@@
int
router_digest_version_as_new_as(const char *digest, const char *cutoff)
{
- routerinfo_t *router = router_get_by_digest(digest);
+ const routerinfo_t *router = router_get_by_id_digest(digest);
if (!router)
return 1;
return tor_version_as_new_as(router->platform, cutoff);
@@@ -2461,20 -2419,44 +2461,20 @@@ hexdigest_to_digest(const char *hexdige
/** Return the router in our routerlist whose hexadecimal key digest
* is <b>hexdigest</b>. Return NULL if no such router is known. */
-routerinfo_t *
+const routerinfo_t *
router_get_by_hexdigest(const char *hexdigest)
{
- char digest[DIGEST_LEN];
- size_t len;
- routerinfo_t *ri;
-
- tor_assert(hexdigest);
- if (!routerlist)
- return NULL;
- if (hexdigest[0]=='$')
- ++hexdigest;
- len = strlen(hexdigest);
- if (hexdigest_to_digest(hexdigest, digest) < 0)
+ if (is_legal_nickname(hexdigest))
return NULL;
- ri = router_get_by_digest(digest);
-
- if (ri && len > HEX_DIGEST_LEN) {
- if (hexdigest[HEX_DIGEST_LEN] == '=') {
- if (strcasecmp(ri->nickname, hexdigest+HEX_DIGEST_LEN+1) ||
- !ri->is_named)
- return NULL;
- } else if (hexdigest[HEX_DIGEST_LEN] == '~') {
- if (strcasecmp(ri->nickname, hexdigest+HEX_DIGEST_LEN+1))
- return NULL;
- } else {
- return NULL;
- }
- }
-
- return ri;
+ /* It's not a legal nickname, so it must be a hexdigest or nothing. */
+ return router_get_by_nickname(hexdigest, 1);
}
-/** Return the router in our routerlist whose 20-byte key digest
- * is <b>digest</b>. Return NULL if no such router is known. */
+/** As router_get_by_id_digest,but return a pointer that you're allowed to
+ * modify */
routerinfo_t *
-router_get_by_digest(const char *digest)
+router_get_mutable_by_digest(const char *digest)
{
tor_assert(digest);
@@@ -2485,14 -2467,6 +2485,14 @@@
return rimap_get(routerlist->identity_map, digest);
}
+/** Return the router in our routerlist whose 20-byte key digest
+ * is <b>digest</b>. Return NULL if no such router is known. */
+const routerinfo_t *
+router_get_by_id_digest(const char *digest)
+{
+ return router_get_mutable_by_digest(digest);
+}
+
/** Return the router in our routerlist whose 20-byte descriptor
* is <b>digest</b>. Return NULL if no such router is known. */
signed_descriptor_t *
@@@ -2543,7 -2517,7 +2543,7 @@@ extrainfo_get_by_descriptor_digest(cons
* The caller must not free the string returned.
*/
static const char *
-signed_descriptor_get_body_impl(signed_descriptor_t *desc,
+signed_descriptor_get_body_impl(const signed_descriptor_t *desc,
int with_annotations)
{
const char *r = NULL;
@@@ -2592,7 -2566,7 +2592,7 @@@
* The caller must not free the string returned.
*/
const char *
-signed_descriptor_get_body(signed_descriptor_t *desc)
+signed_descriptor_get_body(const signed_descriptor_t *desc)
{
return signed_descriptor_get_body_impl(desc, 0);
}
@@@ -2600,7 -2574,7 +2600,7 @@@
/** As signed_descriptor_get_body(), but points to the beginning of the
* annotations section rather than the beginning of the descriptor. */
const char *
-signed_descriptor_get_annotations(signed_descriptor_t *desc)
+signed_descriptor_get_annotations(const signed_descriptor_t *desc)
{
return signed_descriptor_get_body_impl(desc, 1);
}
@@@ -2653,6 -2627,7 +2653,6 @@@ routerinfo_free(routerinfo_t *router
}
addr_policy_list_free(router->exit_policy);
- /* XXXX Remove if this turns out to affect performance. */
memset(router, 77, sizeof(routerinfo_t));
tor_free(router);
@@@ -2667,6 -2642,7 +2667,6 @@@ extrainfo_free(extrainfo_t *extrainfo
tor_free(extrainfo->cache_info.signed_descriptor_body);
tor_free(extrainfo->pending_sig);
- /* XXXX remove this if it turns out to slow us down. */
memset(extrainfo, 88, sizeof(extrainfo_t)); /* debug bad memory usage */
tor_free(extrainfo);
}
@@@ -2680,6 -2656,7 +2680,6 @@@ signed_descriptor_free(signed_descripto
tor_free(sd->signed_descriptor_body);
- /* XXXX remove this once more bugs go away. */
memset(sd, 99, sizeof(signed_descriptor_t)); /* Debug bad mem usage */
tor_free(sd);
}
@@@ -2785,7 -2762,8 +2785,7 @@@ routerlist_insert(routerlist_t *rl, rou
routerinfo_t *ri_old;
signed_descriptor_t *sd_old;
{
- /* XXXX Remove if this slows us down. */
- routerinfo_t *ri_generated = router_get_my_routerinfo();
+ const routerinfo_t *ri_generated = router_get_my_routerinfo();
tor_assert(ri_generated != ri);
}
tor_assert(ri->cache_info.routerlist_index == -1);
@@@ -2807,7 -2785,6 +2807,7 @@@
&ri->cache_info);
smartlist_add(rl->routers, ri);
ri->cache_info.routerlist_index = smartlist_len(rl->routers) - 1;
+ nodelist_add_routerinfo(ri);
router_dir_info_changed();
#ifdef DEBUG_ROUTERLIST
routerlist_assert_ok(rl);
@@@ -2828,6 -2805,7 +2828,6 @@@ extrainfo_insert(routerlist_t *rl, extr
extrainfo_t *ei_tmp;
{
- /* XXXX remove this code if it slows us down. */
extrainfo_t *ei_generated = router_get_my_extrainfo();
tor_assert(ei_generated != ei);
}
@@@ -2873,7 -2851,8 +2873,7 @@@ static voi
routerlist_insert_old(routerlist_t *rl, routerinfo_t *ri)
{
{
- /* XXXX remove this code if it slows us down. */
- routerinfo_t *ri_generated = router_get_my_routerinfo();
+ const routerinfo_t *ri_generated = router_get_my_routerinfo();
tor_assert(ri_generated != ri);
}
tor_assert(ri->cache_info.routerlist_index == -1);
@@@ -2913,8 -2892,6 +2913,8 @@@ routerlist_remove(routerlist_t *rl, rou
tor_assert(0 <= idx && idx < smartlist_len(rl->routers));
tor_assert(smartlist_get(rl->routers, idx) == ri);
+ nodelist_remove_routerinfo(ri);
+
/* make sure the rephist module knows that it's not running */
rep_hist_note_router_unreachable(ri->cache_info.identity_digest, now);
@@@ -3026,7 -3003,8 +3026,7 @@@ routerlist_replace(routerlist_t *rl, ro
routerinfo_t *ri_tmp;
extrainfo_t *ei_tmp;
{
- /* XXXX Remove this if it turns out to slow us down. */
- routerinfo_t *ri_generated = router_get_my_routerinfo();
+ const routerinfo_t *ri_generated = router_get_my_routerinfo();
tor_assert(ri_generated != ri_new);
}
tor_assert(ri_old != ri_new);
@@@ -3036,9 -3014,6 +3036,9 @@@
tor_assert(0 <= idx && idx < smartlist_len(rl->routers));
tor_assert(smartlist_get(rl->routers, idx) == ri_old);
+ nodelist_remove_routerinfo(ri_old);
+ nodelist_add_routerinfo(ri_new);
+
router_dir_info_changed();
if (idx >= 0) {
smartlist_set(rl->routers, idx, ri_new);
@@@ -3185,27 -3160,28 +3185,27 @@@ routerlist_reset_warnings(void
void
router_set_status(const char *digest, int up)
{
- routerinfo_t *router;
- routerstatus_t *status;
+ node_t *node;
tor_assert(digest);
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, d,
if (!memcmp(d->digest, digest, DIGEST_LEN))
d->is_running = up);
- router = router_get_by_digest(digest);
- if (router) {
- log_debug(LD_DIR,"Marking router '%s/%s' as %s.",
- router->nickname, router->address, up ? "up" : "down");
- if (!up && router_is_me(router) && !we_are_hibernating())
+ node = node_get_mutable_by_id(digest);
+ if (node) {
+#if 0
+ char buf[MAX_VERBOSE_NICKNAME_LEN+1];
+ node_get_verbose_nickname(node,buf);
+ log_debug(LD_DIR,"Marking router %s as %s.",
+ buf, up ? "up" : "down");
+#endif
+ if (!up && node_is_me(node) && !we_are_hibernating())
log_warn(LD_NET, "We just marked ourself as down. Are your external "
"addresses reachable?");
- router->is_running = up;
- }
- status = router_get_consensus_status_by_id(digest);
- if (status && status->is_running != up) {
- status->is_running = up;
- control_event_networkstatus_changed_single(status);
+ node->is_running = up;
}
+
router_dir_info_changed();
}
@@@ -3248,7 -3224,7 +3248,7 @@@ router_add_to_routerlist(routerinfo_t *
id_digest = router->cache_info.identity_digest;
- old_router = router_get_by_digest(id_digest);
+ old_router = router_get_mutable_by_digest(id_digest);
/* Make sure that we haven't already got this exact descriptor. */
if (sdmap_get(routerlist->desc_digest_map,
@@@ -3279,12 -3255,12 +3279,12 @@@
if (authdir) {
if (authdir_wants_to_reject_router(router, msg,
- !from_cache && !from_fetch)) {
+ !from_cache && !from_fetch,
+ &authdir_believes_valid)) {
tor_assert(*msg);
routerinfo_free(router);
return ROUTER_AUTHDIR_REJECTS;
}
- authdir_believes_valid = router->is_valid;
} else if (from_fetch) {
/* Only check the descriptor digest against the network statuses when
* we are receiving in response to a fetch. */
@@@ -3311,15 -3287,14 +3311,15 @@@
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
{
routerstatus_t *rs =
- networkstatus_v2_find_entry(ns, id_digest);
+ networkstatus_v2_find_mutable_entry(ns, id_digest);
if (rs && !memcmp(rs->descriptor_digest,
router->cache_info.signed_descriptor_digest,
DIGEST_LEN))
rs->need_to_mirror = 0;
});
if (consensus) {
- routerstatus_t *rs = networkstatus_vote_find_entry(consensus, id_digest);
+ routerstatus_t *rs = networkstatus_vote_find_mutable_entry(
+ consensus, id_digest);
if (rs && !memcmp(rs->descriptor_digest,
router->cache_info.signed_descriptor_digest,
DIGEST_LEN)) {
@@@ -3919,7 -3894,7 +3919,7 @@@ router_load_extrainfo_from_string(cons
static int
signed_desc_digest_is_recognized(signed_descriptor_t *desc)
{
- routerstatus_t *rs;
+ 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();
@@@ -3952,34 -3927,33 +3952,34 @@@ routerlist_retry_directory_downloads(ti
router_reset_descriptor_download_failures();
update_networkstatus_downloads(now);
update_router_descriptor_downloads(now);
+ update_microdesc_downloads(now);
}
-/** Return 1 if all running sufficiently-stable routers will reject
+/** Return 1 if all running sufficiently-stable routers we can use will reject
* addr:port, return 0 if any might accept it. */
int
-router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port,
- int need_uptime)
-{
+router_exit_policy_all_nodes_reject(uint32_t addr, uint16_t port,
+ int need_uptime)
+{ /* XXXX MOVE */
addr_policy_result_t r;
- if (!routerlist) return 1;
- SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
- {
- if (router->is_running &&
- !router_is_unreliable(router, need_uptime, 0, 0)) {
- r = compare_addr_to_addr_policy(addr, port, router->exit_policy);
+ SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), const node_t *, node) {
+ if (node->is_running &&
+ !node_is_unreliable(node, need_uptime, 0, 0)) {
+
+ r = compare_addr_to_node_policy(addr, port, node);
+
if (r != ADDR_POLICY_REJECTED && r != ADDR_POLICY_PROBABLY_REJECTED)
return 0; /* this one could be ok. good enough. */
}
- });
+ } SMARTLIST_FOREACH_END(node);
return 1; /* all will reject. */
}
/** Return true iff <b>router</b> does not permit exit streams.
*/
int
-router_exit_policy_rejects_all(routerinfo_t *router)
+router_exit_policy_rejects_all(const routerinfo_t *router)
{
return router->policy_is_reject_star;
}
@@@ -4114,9 -4088,7 +4114,9 @@@ any_trusted_dir_is_v1_authority(void
/** For every current directory connection whose purpose is <b>purpose</b>,
* and where the resource being downloaded begins with <b>prefix</b>, split
* rest of the resource into base16 fingerprints, decode them, and set the
- * corresponding elements of <b>result</b> to a nonzero value. */
+ * corresponding elements of <b>result</b> to a nonzero value.
+ * DOCDOC purpose==microdesc
+ */
static void
list_pending_downloads(digestmap_t *result,
int purpose, const char *prefix)
@@@ -4124,23 -4096,20 +4124,23 @@@
const size_t p_len = strlen(prefix);
smartlist_t *tmp = smartlist_create();
smartlist_t *conns = get_connection_array();
+ int flags = DSR_HEX;
+ if (purpose == DIR_PURPOSE_FETCH_MICRODESC)
+ flags = DSR_DIGEST256|DSR_BASE64;
tor_assert(result);
- SMARTLIST_FOREACH(conns, connection_t *, conn,
- {
+ SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
if (conn->type == CONN_TYPE_DIR &&
conn->purpose == purpose &&
!conn->marked_for_close) {
const char *resource = TO_DIR_CONN(conn)->requested_resource;
if (!strcmpstart(resource, prefix))
dir_split_resource_into_fingerprints(resource + p_len,
- tmp, NULL, DSR_HEX);
+ tmp, NULL, flags);
}
- });
+ } SMARTLIST_FOREACH_END(conn);
+
SMARTLIST_FOREACH(tmp, char *, d,
{
digestmap_set(result, d, (void*)1);
@@@ -4160,21 -4129,13 +4160,21 @@@ list_pending_descriptor_downloads(diges
list_pending_downloads(result, purpose, "d/");
}
-/** Launch downloads for all the descriptors whose digests are listed
- * as digests[i] for lo <= i < hi. (Lo and hi may be out of range.)
- * If <b>source</b> is given, download from <b>source</b>; otherwise,
- * download from an appropriate random directory server.
+/** DOCDOC */
+/*XXXX NM should use digest256, if one comes into being. */
+void
+list_pending_microdesc_downloads(digestmap_t *result)
+{
+ list_pending_downloads(result, DIR_PURPOSE_FETCH_MICRODESC, "d/");
+}
+
+/** Launch downloads for all the descriptors whose digests or digests256
+ * are listed as digests[i] for lo <= i < hi. (Lo and hi may be out of
+ * range.) If <b>source</b> is given, download from <b>source</b>;
+ * otherwise, download from an appropriate random directory server.
*/
static void
-initiate_descriptor_downloads(routerstatus_t *source,
+initiate_descriptor_downloads(const routerstatus_t *source,
int purpose,
smartlist_t *digests,
int lo, int hi, int pds_flags)
@@@ -4182,20 -4143,6 +4182,20 @@@
int i, n = hi-lo;
char *resource, *cp;
size_t r_len;
+
+ int digest_len = DIGEST_LEN, enc_digest_len = HEX_DIGEST_LEN;
+ char sep = '+';
+ int b64_256 = 0;
+
+ if (purpose == DIR_PURPOSE_FETCH_MICRODESC) {
+ /* Microdescriptors are downloaded by "-"-separated base64-encoded
+ * 256-bit digests. */
+ digest_len = DIGEST256_LEN;
+ enc_digest_len = BASE64_DIGEST256_LEN;
+ sep = '-';
+ b64_256 = 1;
+ }
+
if (n <= 0)
return;
if (lo < 0)
@@@ -4203,19 -4150,15 +4203,19 @@@
if (hi > smartlist_len(digests))
hi = smartlist_len(digests);
- r_len = 8 + (HEX_DIGEST_LEN+1)*n;
+ r_len = 8 + (enc_digest_len+1)*n;
cp = resource = tor_malloc(r_len);
memcpy(cp, "d/", 2);
cp += 2;
for (i = lo; i < hi; ++i) {
- base16_encode(cp, r_len-(cp-resource),
- smartlist_get(digests,i), DIGEST_LEN);
- cp += HEX_DIGEST_LEN;
- *cp++ = '+';
+ if (b64_256) {
+ digest256_to_base64(cp, smartlist_get(digests, i));
+ } else {
+ base16_encode(cp, r_len-(cp-resource),
+ smartlist_get(digests,i), digest_len);
+ }
+ cp += enc_digest_len;
+ *cp++ = sep;
}
memcpy(cp-1, ".z", 3);
@@@ -4238,7 -4181,7 +4238,7 @@@
static INLINE int
client_would_use_router(routerstatus_t *rs, time_t now, or_options_t *options)
{
- if (!rs->is_running && !options->FetchUselessDescriptors) {
+ if (!rs->is_flagged_running && !options->FetchUselessDescriptors) {
/* If we had this router descriptor, we wouldn't even bother using it.
* But, if we want to have a complete list, fetch it anyway. */
return 0;
@@@ -4262,7 -4205,6 +4262,7 @@@
* So use 96 because it's a nice number.
*/
#define MAX_DL_PER_REQUEST 96
+#define MAX_MICRODESC_DL_PER_REQUEST 92
/** Don't split our requests so finely that we are requesting fewer than
* this number per server. */
#define MIN_DL_PER_REQUEST 4
@@@ -4277,33 -4219,21 +4277,33 @@@
* them until they have more, or until this amount of time has passed. */
#define MAX_CLIENT_INTERVAL_WITHOUT_REQUEST (10*60)
-/** Given a list of router descriptor digests in <b>downloadable</b>, decide
- * whether to delay fetching until we have more. If we don't want to delay,
- * launch one or more requests to the appropriate directory authorities. */
-static void
-launch_router_descriptor_downloads(smartlist_t *downloadable,
- routerstatus_t *source, time_t now)
+/** Given a <b>purpose</b> (FETCH_MICRODESC or FETCH_SERVERDESC) and a list of
+ * router descriptor digests or microdescriptor digest256s in
+ * <b>downloadable</b>, decide whether to delay fetching until we have more.
+ * If we don't want to delay, launch one or more requests to the appropriate
+ * directory authorities.
+ */
+void
+launch_descriptor_downloads(int purpose,
+ smartlist_t *downloadable,
+ const routerstatus_t *source, time_t now)
{
int should_delay = 0, n_downloadable;
or_options_t *options = get_options();
+ const char *descname;
+
+ tor_assert(purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
+ purpose == DIR_PURPOSE_FETCH_MICRODESC);
+
+ descname = (purpose == DIR_PURPOSE_FETCH_SERVERDESC) ?
+ "routerdesc" : "microdesc";
n_downloadable = smartlist_len(downloadable);
if (!directory_fetches_dir_info_early(options)) {
if (n_downloadable >= MAX_DL_TO_DELAY) {
log_debug(LD_DIR,
- "There are enough downloadable routerdescs to launch requests.");
+ "There are enough downloadable %ss to launch requests.",
+ descname);
should_delay = 0;
} else {
should_delay = (last_routerdesc_download_attempted +
@@@ -4311,15 -4241,13 +4311,15 @@@
if (!should_delay && n_downloadable) {
if (last_routerdesc_download_attempted) {
log_info(LD_DIR,
- "There are not many downloadable routerdescs, but we've "
+ "There are not many downloadable %ss, but we've "
"been waiting long enough (%d seconds). Downloading.",
+ descname,
(int)(now-last_routerdesc_download_attempted));
} else {
log_info(LD_DIR,
- "There are not many downloadable routerdescs, but we haven't "
- "tried downloading descriptors recently. Downloading.");
+ "There are not many downloadable %ss, but we haven't "
+ "tried downloading descriptors recently. Downloading.",
+ descname);
}
}
}
@@@ -4346,19 -4274,12 +4346,19 @@@
* update_router_descriptor_downloads() later on, once the connections
* have succeeded or failed.
*/
- pds_flags |= PDS_NO_EXISTING_SERVERDESC_FETCH;
+ pds_flags |= (purpose == DIR_PURPOSE_FETCH_MICRODESC) ?
+ PDS_NO_EXISTING_MICRODESC_FETCH :
+ PDS_NO_EXISTING_SERVERDESC_FETCH;
}
n_per_request = CEIL_DIV(n_downloadable, MIN_REQUESTS);
- if (n_per_request > MAX_DL_PER_REQUEST)
- n_per_request = MAX_DL_PER_REQUEST;
+ if (purpose == DIR_PURPOSE_FETCH_MICRODESC) {
+ if (n_per_request > MAX_MICRODESC_DL_PER_REQUEST)
+ n_per_request = MAX_MICRODESC_DL_PER_REQUEST;
+ } else {
+ if (n_per_request > MAX_DL_PER_REQUEST)
+ n_per_request = MAX_DL_PER_REQUEST;
+ }
if (n_per_request < MIN_DL_PER_REQUEST)
n_per_request = MIN_DL_PER_REQUEST;
@@@ -4373,7 -4294,7 +4373,7 @@@
req_plural, n_downloadable, rtr_plural, n_per_request);
smartlist_sort_digests(downloadable);
for (i=0; i < n_downloadable; i += n_per_request) {
- initiate_descriptor_downloads(source, DIR_PURPOSE_FETCH_SERVERDESC,
+ initiate_descriptor_downloads(source, purpose,
downloadable, i, i+n_per_request,
pds_flags);
}
@@@ -4563,14 -4484,15 +4563,14 @@@ update_consensus_router_descriptor_down
map = digestmap_new();
list_pending_descriptor_downloads(map, 0);
- SMARTLIST_FOREACH(consensus->routerstatus_list, void *, rsp,
- {
+ SMARTLIST_FOREACH_BEGIN(consensus->routerstatus_list, void *, rsp) {
routerstatus_t *rs =
is_vote ? &(((vote_routerstatus_t *)rsp)->status) : rsp;
signed_descriptor_t *sd;
if ((sd = router_get_by_descriptor_digest(rs->descriptor_digest))) {
- routerinfo_t *ri;
+ const routerinfo_t *ri;
++n_have;
- if (!(ri = router_get_by_digest(rs->identity_digest)) ||
+ if (!(ri = router_get_by_id_digest(rs->identity_digest)) ||
memcmp(ri->cache_info.signed_descriptor_digest,
sd->signed_descriptor_digest, DIGEST_LEN)) {
/* We have a descriptor with this digest, but either there is no
@@@ -4603,8 -4525,7 +4603,8 @@@
if (is_vote && source) {
char time_bufnew[ISO_TIME_LEN+1];
char time_bufold[ISO_TIME_LEN+1];
- routerinfo_t *oldrouter = router_get_by_digest(rs->identity_digest);
+ const routerinfo_t *oldrouter;
+ oldrouter = router_get_by_id_digest(rs->identity_digest);
format_iso_time(time_bufnew, rs->published_on);
if (oldrouter)
format_iso_time(time_bufold, oldrouter->cache_info.published_on);
@@@ -4614,7 -4535,7 +4614,7 @@@
source->nickname, oldrouter ? "known" : "unknown");
}
smartlist_add(downloadable, rs->descriptor_digest);
- });
+ } SMARTLIST_FOREACH_END(rsp);
if (!authdir_mode_handles_descs(options, ROUTER_PURPOSE_GENERAL)
&& smartlist_len(no_longer_old)) {
@@@ -4646,8 -4567,7 +4646,8 @@@
smartlist_len(downloadable), n_delayed, n_have, n_in_oldrouters,
n_would_reject, n_wouldnt_use, n_inprogress);
- launch_router_descriptor_downloads(downloadable, source, now);
+ launch_descriptor_downloads(DIR_PURPOSE_FETCH_SERVERDESC,
+ downloadable, source, now);
digestmap_free(map, NULL);
done:
@@@ -4672,13 -4592,10 +4672,13 @@@ update_router_descriptor_downloads(time
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));
+ networkstatus_get_reasonably_live_consensus(now, FLAV_NS));
/* XXXX021 we could be smarter here; see notes on bug 652. */
+ /* XXXX NM Microdescs: if we're not fetching microdescriptors, we need
+ * to make something else invoke this. */
/* If we're a server that doesn't have a configured address, we rely on
* directory fetches to learn when our address changes. So if we haven't
* tried to get any routerdescs in a long time, try a dummy fetch now. */
@@@ -4725,7 -4642,7 +4725,7 @@@ update_extrainfo_downloads(time_t now
sd = &((routerinfo_t*)smartlist_get(lst, i))->cache_info;
if (sd->is_extrainfo)
continue; /* This should never happen. */
- if (old_routers && !router_get_by_digest(sd->identity_digest))
+ if (old_routers && !router_get_by_id_digest(sd->identity_digest))
continue; /* Couldn't check the signature if we got it. */
if (sd->extrainfo_is_bogus)
continue;
@@@ -4826,7 -4743,7 +4826,7 @@@ count_usable_descriptors(int *num_prese
SMARTLIST_FOREACH(consensus->routerstatus_list, routerstatus_t *, rs,
{
- if (in_set && ! routerset_contains_routerstatus(in_set, rs))
+ if (in_set && ! routerset_contains_routerstatus(in_set, rs, -1))
continue;
if (client_would_use_router(rs, now, options)) {
++*num_usable; /* the consensus says we want it. */
@@@ -4849,7 -4766,7 +4849,7 @@@ count_loading_descriptors_progress(void
int num_present = 0, num_usable=0;
time_t now = time(NULL);
const networkstatus_t *consensus =
- networkstatus_get_reasonably_live_consensus(now);
+ networkstatus_get_reasonably_live_consensus(now, FLAV_NS);
double fraction;
if (!consensus)
@@@ -4879,7 -4796,7 +4879,7 @@@ update_router_have_minimum_dir_info(voi
int res;
or_options_t *options = get_options();
const networkstatus_t *consensus =
- networkstatus_get_reasonably_live_consensus(now);
+ networkstatus_get_reasonably_live_consensus(now, FLAV_NS);
if (!consensus) {
if (!networkstatus_get_latest_consensus())
@@@ -4989,7 -4906,7 +4989,7 @@@ router_reset_descriptor_download_failur
* would not cause a recent (post 0.1.1.6) dirserver to republish.
*/
int
-router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2)
+router_differences_are_cosmetic(const routerinfo_t *r1, const routerinfo_t *r2)
{
time_t r1pub, r2pub;
long time_difference;
@@@ -4997,7 -4914,7 +4997,7 @@@
/* r1 should be the one that was published first. */
if (r1->cache_info.published_on > r2->cache_info.published_on) {
- routerinfo_t *ri_tmp = r2;
+ const routerinfo_t *ri_tmp = r2;
r2 = r1;
r1 = ri_tmp;
}
@@@ -5016,6 -4933,7 +5016,6 @@@
(r1->contact_info && r2->contact_info &&
strcasecmp(r1->contact_info, r2->contact_info)) ||
r1->is_hibernating != r2->is_hibernating ||
- r1->has_old_dnsworkers != r2->has_old_dnsworkers ||
cmp_addr_policies(r1->exit_policy, r2->exit_policy))
return 0;
if ((r1->declared_family == NULL) != (r2->declared_family == NULL))
@@@ -5070,8 -4988,7 +5070,8 @@@
* incompatibility (if any).
**/
int
-routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei,
+routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri,
+ extrainfo_t *ei,
signed_descriptor_t *sd,
const char **msg)
{
@@@ -5079,7 -4996,7 +5079,7 @@@
tor_assert(ri);
tor_assert(ei);
if (!sd)
- sd = &ri->cache_info;
+ sd = (signed_descriptor_t*)&ri->cache_info;
if (ei->bad_sig) {
if (msg) *msg = "Extrainfo signature was bad, or signed with wrong key.";
@@@ -5099,7 -5016,8 +5099,8 @@@
if (ei->pending_sig) {
char signed_digest[128];
- if (crypto_pk_public_checksig(ri->identity_pkey, signed_digest,
+ if (crypto_pk_public_checksig(ri->identity_pkey,
+ signed_digest, sizeof(signed_digest),
ei->pending_sig, ei->pending_sig_len) != DIGEST_LEN ||
memcmp(signed_digest, ei->cache_info.signed_descriptor_digest,
DIGEST_LEN)) {
@@@ -5142,7 -5060,7 +5143,7 @@@
/** Assert that the internal representation of <b>rl</b> is
* self-consistent. */
void
-routerlist_assert_ok(routerlist_t *rl)
+routerlist_assert_ok(const routerlist_t *rl)
{
routerinfo_t *r2;
signed_descriptor_t *sd2;
@@@ -5232,7 -5150,7 +5233,7 @@@
* If <b>router</b> is NULL, it just frees its internal memory and returns.
*/
const char *
-esc_router_info(routerinfo_t *router)
+esc_router_info(const routerinfo_t *router)
{
static char *info=NULL;
char *esc_contact, *esc_platform;
@@@ -5334,6 -5252,38 +5335,6 @@@ routerset_get_countryname(const char *c
return country;
}
-#if 0
-/** Add the GeoIP database's integer index (+1) of a valid two-character
- * country code to the routerset's <b>countries</b> bitarray. Return the
- * integer index if the country code is valid, -1 otherwise.*/
-static int
-routerset_add_country(const char *c)
-{
- char country[3];
- country_t cc;
-
- /* XXXX: Country codes must be of the form \{[a-z\?]{2}\} but this accepts
- \{[.]{2}\}. Do we need to be strict? -RH */
- /* Nope; if the country code is bad, we'll get 0 when we look it up. */
-
- if (!geoip_is_loaded()) {
- log(LOG_WARN, LD_CONFIG, "GeoIP database not loaded: Cannot add country"
- "entry %s, ignoring.", c);
- return -1;
- }
-
- memcpy(country, c+1, 2);
- country[2] = '\0';
- tor_strlower(country);
-
- if ((cc=geoip_get_country(country))==-1) {
- log(LOG_WARN, LD_CONFIG, "Country code '%s' is not valid, ignoring.",
- country);
- }
- return cc;
-}
-#endif
-
/** Update the routerset's <b>countries</b> bitarray_t. Called whenever
* the GeoIP database is reloaded.
*/
@@@ -5435,7 -5385,7 +5436,7 @@@ refresh_all_country_info(void
if (options->_ExcludeExitNodesUnion)
routerset_refresh_countries(options->_ExcludeExitNodesUnion);
- routerlist_refresh_countries();
+ nodelist_refresh_countries();
}
/** Add all members of the set <b>source</b> to <b>target</b>. */
@@@ -5485,10 -5435,11 +5486,10 @@@ routerset_is_empty(const routerset_t *s
static int
routerset_contains(const routerset_t *set, const tor_addr_t *addr,
uint16_t orport,
- const char *nickname, const char *id_digest, int is_named,
+ const char *nickname, const char *id_digest,
country_t country)
{
if (!set || !set->list) return 0;
- (void) is_named; /* not supported */
if (nickname && strmap_get_lc(set->names, nickname))
return 4;
if (id_digest && digestmap_get(set->digests, id_digest))
@@@ -5516,14 -5467,13 +5517,14 @@@ routerset_contains_extendinfo(const rou
ei->port,
ei->nickname,
ei->identity_digest,
-1 /*country*/);
}
-/** Return true iff <b>ri</b> is in <b>set</b>. */
+/** Return true iff <b>ri</b> is in <b>set</b>. If country is <b>-1</b>, we
+ * look up the country. */
int
-routerset_contains_router(const routerset_t *set, routerinfo_t *ri)
+routerset_contains_router(const routerset_t *set, const routerinfo_t *ri,
+ country_t country)
{
tor_addr_t addr;
tor_addr_from_ipv4h(&addr, ri->addr);
@@@ -5532,15 -5482,13 +5533,15 @@@
ri->or_port,
ri->nickname,
ri->cache_info.identity_digest,
- ri->is_named,
- ri->country);
+ country);
}
-/** Return true iff <b>rs</b> is in <b>set</b>. */
+/** Return true iff <b>rs</b> is in <b>set</b>. If country is <b>-1</b>, we
+ * look up the country. */
int
-routerset_contains_routerstatus(const routerset_t *set, routerstatus_t *rs)
+routerset_contains_routerstatus(const routerset_t *set,
+ const routerstatus_t *rs,
+ country_t country)
{
tor_addr_t addr;
tor_addr_from_ipv4h(&addr, rs->addr);
@@@ -5549,55 -5497,46 +5550,55 @@@
rs->or_port,
rs->nickname,
rs->identity_digest,
- rs->is_named,
- -1);
+ country);
+}
+
+/** Return true iff <b>node</b> is in <b>set</b>. */
+int
+routerset_contains_node(const routerset_t *set, const node_t *node)
+{
+ if (node->rs)
+ return routerset_contains_routerstatus(set, node->rs, node->country);
+ else if (node->ri)
+ return routerset_contains_router(set, node->ri, node->country);
+ else
+ return 0;
}
-/** Add every known routerinfo_t that is a member of <b>routerset</b> to
+/** Add every known node_t that is a member of <b>routerset</b> to
* <b>out</b>. If <b>running_only</b>, only add the running ones. */
void
-routerset_get_all_routers(smartlist_t *out, const routerset_t *routerset,
- int running_only)
-{
+routerset_get_all_nodes(smartlist_t *out, const routerset_t *routerset,
+ int running_only)
+{ /* XXXX MOVE */
tor_assert(out);
if (!routerset || !routerset->list)
return;
- if (!warned_nicknames)
- warned_nicknames = smartlist_create();
- if (routerset_is_list(routerset)) {
+ if (routerset_is_list(routerset)) {
/* No routers are specified by type; all are given by name or digest.
* we can do a lookup in O(len(list)). */
SMARTLIST_FOREACH(routerset->list, const char *, name, {
- routerinfo_t *router = router_get_by_nickname(name, 1);
- if (router) {
- if (!running_only || router->is_running)
- smartlist_add(out, router);
+ const node_t *node = node_get_by_nickname(name, 1);
+ if (node) {
+ if (!running_only || node->is_running)
+ smartlist_add(out, (void*)node);
}
});
} else {
/* We need to iterate over the routerlist to get all the ones of the
* right kind. */
- routerlist_t *rl = router_get_routerlist();
- SMARTLIST_FOREACH(rl->routers, routerinfo_t *, router, {
- if (running_only && !router->is_running)
+ smartlist_t *nodes = nodelist_get_list();
+ SMARTLIST_FOREACH(nodes, const node_t *, node, {
+ if (running_only && !node->is_running)
continue;
- if (routerset_contains_router(routerset, router))
- smartlist_add(out, router);
+ if (routerset_contains_node(routerset, node))
+ smartlist_add(out, (void*)node);
});
}
}
-/** Add to <b>target</b> every routerinfo_t from <b>source</b> except:
+/** Add to <b>target</b> every node_t from <b>source</b> except:
*
* 1) Don't add it if <b>include</b> is non-empty and the relay isn't in
* <b>include</b>; and
@@@ -5606,39 -5545,39 +5607,39 @@@
* 3) If <b>running_only</b>, don't add non-running routers.
*/
void
-routersets_get_disjunction(smartlist_t *target,
+routersets_get_node_disjunction(smartlist_t *target,
const smartlist_t *source,
const routerset_t *include,
const routerset_t *exclude, int running_only)
{
- SMARTLIST_FOREACH(source, routerinfo_t *, router, {
+ SMARTLIST_FOREACH(source, const node_t *, node, {
int include_result;
- if (running_only && !router->is_running)
+ if (running_only && !node->is_running)
continue;
if (!routerset_is_empty(include))
- include_result = routerset_contains_router(include, router);
+ include_result = routerset_contains_node(include, node);
else
include_result = 1;
if (include_result) {
- int exclude_result = routerset_contains_router(exclude, router);
+ int exclude_result = routerset_contains_node(exclude, node);
if (include_result >= exclude_result)
- smartlist_add(target, router);
+ smartlist_add(target, (void*)node);
}
});
}
-/** Remove every routerinfo_t from <b>lst</b> that is in <b>routerset</b>. */
+/** Remove every node_t from <b>lst</b> that is in <b>routerset</b>. */
void
-routerset_subtract_routers(smartlist_t *lst, const routerset_t *routerset)
-{
+routerset_subtract_nodes(smartlist_t *lst, const routerset_t *routerset)
+{ /*XXXX MOVE ? */
tor_assert(lst);
if (!routerset)
return;
- SMARTLIST_FOREACH(lst, routerinfo_t *, r, {
- if (routerset_contains_router(routerset, r)) {
+ SMARTLIST_FOREACH(lst, const node_t *, node, {
+ if (routerset_contains_node(routerset, node)) {
//log_debug(LD_DIR, "Subtracting %s",r->nickname);
- SMARTLIST_DEL_CURRENT(lst, r);
+ SMARTLIST_DEL_CURRENT(lst, node);
}
});
}
@@@ -5699,23 -5638,18 +5700,23 @@@ routerset_free(routerset_t *routerset
/** Refresh the country code of <b>ri</b>. This function MUST be called on
* each router when the GeoIP database is reloaded, and on all new routers. */
void
-routerinfo_set_country(routerinfo_t *ri)
+node_set_country(node_t *node)
{
- ri->country = geoip_get_country_by_ip(ri->addr);
+ if (node->rs)
+ node->country = geoip_get_country_by_ip(node->rs->addr);
+ else if (node->ri)
+ node->country = geoip_get_country_by_ip(node->ri->addr);
+ else
+ node->country = -1;
}
/** Set the country code of all routers in the routerlist. */
void
-routerlist_refresh_countries(void)
+nodelist_refresh_countries(void) /* MOVE */
{
- routerlist_t *rl = router_get_routerlist();
- SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri,
- routerinfo_set_country(ri));
+ smartlist_t *nodes = nodelist_get_list();
+ SMARTLIST_FOREACH(nodes, node_t *, node,
+ node_set_country(node));
}
/** Determine the routers that are responsible for <b>id</b> (binary) and
@@@ -5764,9 -5698,9 +5765,9 @@@ hid_serv_get_responsible_directories(sm
int
hid_serv_acting_as_directory(void)
{
- routerinfo_t *me = router_get_my_routerinfo();
+ const routerinfo_t *me = router_get_my_routerinfo();
networkstatus_t *c;
- routerstatus_t *rs;
+ const routerstatus_t *rs;
if (!me)
return 0;
if (!get_options()->HidServDirectoryV2) {
@@@ -5798,7 -5732,7 +5799,7 @@@
int
hid_serv_responsible_for_desc_id(const char *query)
{
- routerinfo_t *me;
+ const routerinfo_t *me;
routerstatus_t *last_rs;
const char *my_id, *last_id;
int result;
diff --combined src/or/routerparse.c
index 1822517,66d024e..56d86bd
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@@ -69,6 -69,7 +69,6 @@@ typedef enum
K_V,
K_W,
K_M,
- K_EVENTDNS,
K_EXTRA_INFO,
K_EXTRA_INFO_DIGEST,
K_CACHES_EXTRA_INFO,
@@@ -285,6 -286,7 +285,6 @@@ static token_rule_t routerdesc_token_ta
T01("family", K_FAMILY, ARGS, NO_OBJ ),
T01("caches-extra-info", K_CACHES_EXTRA_INFO, NO_ARGS, NO_OBJ ),
- T01("eventdns", K_EVENTDNS, ARGS, NO_OBJ ),
T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ),
T1( "bandwidth", K_BANDWIDTH, GE(3), NO_OBJ ),
@@@ -700,11 -702,13 +700,13 @@@ router_append_dirobj_signature(char *bu
size_t digest_len, crypto_pk_env_t *private_key)
{
char *signature;
- size_t i;
+ size_t i, keysize;
int siglen;
- signature = tor_malloc(crypto_pk_keysize(private_key));
- siglen = crypto_pk_private_sign(private_key, signature, digest, digest_len);
+ keysize = crypto_pk_keysize(private_key);
+ signature = tor_malloc(keysize);
+ siglen = crypto_pk_private_sign(private_key, signature, keysize,
+ digest, digest_len);
if (siglen < 0) {
log_warn(LD_BUG,"Couldn't sign digest.");
goto err;
@@@ -1057,6 -1061,7 +1059,7 @@@ check_signature_token(const char *diges
const char *doctype)
{
char *signed_digest;
+ size_t keysize;
const int check_authority = (flags & CST_CHECK_AUTHORITY);
const int check_objtype = ! (flags & CST_NO_CHECK_OBJTYPE);
@@@ -1078,10 -1083,11 +1081,11 @@@
}
}
- signed_digest = tor_malloc(tok->object_size);
- if (crypto_pk_public_checksig(pkey, signed_digest, tok->object_body,
- tok->object_size)
- < digest_len) {
+ keysize = crypto_pk_keysize(pkey);
+ signed_digest = tor_malloc(keysize);
+ if (crypto_pk_public_checksig(pkey, signed_digest, keysize,
+ tok->object_body, tok->object_size)
+ < DIGEST_LEN) {
log_warn(LD_DIR, "Error reading %s: invalid signature.", doctype);
tor_free(signed_digest);
return -1;
@@@ -1350,6 -1356,7 +1354,6 @@@ router_parse_entry_from_string(const ch
tor_assert(tok->n_args >= 5);
router = tor_malloc_zero(sizeof(routerinfo_t));
- router->country = -1;
router->cache_info.routerlist_index = -1;
router->cache_info.annotations_len = s-start_of_annotations + prepend_len;
router->cache_info.signed_descriptor_len = end-s;
@@@ -1490,6 -1497,13 +1494,6 @@@
router->contact_info = tor_strdup(tok->args[0]);
}
- if ((tok = find_opt_by_keyword(tokens, K_EVENTDNS))) {
- router->has_old_dnsworkers = tok->n_args && !strcmp(tok->args[0], "0");
- } else if (router->platform) {
- if (! tor_version_as_new_as(router->platform, "0.1.2.2-alpha"))
- router->has_old_dnsworkers = 1;
- }
-
exit_policy_tokens = find_all_exitpolicy(tokens);
if (!smartlist_len(exit_policy_tokens)) {
log_warn(LD_DIR, "No exit policy tokens in descriptor.");
@@@ -1548,6 -1562,8 +1552,6 @@@
"router descriptor") < 0)
goto err;
- routerinfo_set_country(router);
-
if (!router->or_port) {
log_warn(LD_DIR,"or_port unreadable or 0. Failing.");
goto err;
@@@ -1937,7 -1953,6 +1941,7 @@@ routerstatus_parse_entry_from_string(me
if (!consensus_method)
flav = FLAV_NS;
+ tor_assert(flav == FLAV_NS || flav == FLAV_MICRODESC);
eos = find_start_of_next_routerstatus(*s);
@@@ -1950,16 -1965,15 +1954,16 @@@
goto err;
}
tok = find_by_keyword(tokens, K_R);
- tor_assert(tok->n_args >= 7);
+ tor_assert(tok->n_args >= 7); /* guaranteed by GE(7) in K_R setup */
if (flav == FLAV_NS) {
if (tok->n_args < 8) {
log_warn(LD_DIR, "Too few arguments to r");
goto err;
}
- } else {
- offset = -1;
+ } else if (flav == FLAV_MICRODESC) {
+ offset = -1; /* There is no identity digest */
}
+
if (vote_rs) {
rs = &vote_rs->status;
} else {
@@@ -2033,7 -2047,7 +2037,7 @@@
else if (!strcmp(tok->args[i], "Fast"))
rs->is_fast = 1;
else if (!strcmp(tok->args[i], "Running"))
- rs->is_running = 1;
+ rs->is_flagged_running = 1;
else if (!strcmp(tok->args[i], "Named"))
rs->is_named = 1;
else if (!strcmp(tok->args[i], "Valid"))
@@@ -2135,16 -2149,6 +2139,16 @@@
vote_rs->microdesc = line;
}
} SMARTLIST_FOREACH_END(t);
+ } else if (flav == FLAV_MICRODESC) {
+ tok = find_opt_by_keyword(tokens, K_M);
+ if (tok) {
+ tor_assert(tok->n_args);
+ if (digest256_from_base64(rs->descriptor_digest, tok->args[0])) {
+ log_warn(LD_DIR, "Error decoding microdescriptor digest %s",
+ escaped(tok->args[0]));
+ goto err;
+ }
+ }
}
if (!strcasecmp(rs->nickname, UNNAMED_ROUTER_NICKNAME))
@@@ -4311,7 -4315,7 +4315,7 @@@ microdescs_parse_from_string(const cha
}
if ((tok = find_opt_by_keyword(tokens, K_P))) {
- md->exitsummary = tor_strdup(tok->args[0]);
+ md->exit_policy = parse_short_policy(tok->args[0]);
}
crypto_digest256(md->digest, md->body, md->bodylen, DIGEST_SHA256);
More information about the tor-commits
mailing list