tor-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 213386 discussions

[tor/master] we're not reachable if we don't have a routerinfo yet
by nickm@torproject.org 14 Mar '11
by nickm@torproject.org 14 Mar '11
14 Mar '11
commit 1a9d19e9728c21ffa37f2b751df8e8e97c1835d3
Author: Roger Dingledine <arma(a)torproject.org>
Date: Sun Mar 13 15:47:59 2011 -0400
we're not reachable if we don't have a routerinfo yet
---
changes/bug1172 | 9 +++++++++
src/or/router.c | 20 +++++---------------
2 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/changes/bug1172 b/changes/bug1172
new file mode 100644
index 0000000..3abd743
--- /dev/null
+++ b/changes/bug1172
@@ -0,0 +1,9 @@
+ o Minor bugfixes:
+ - When we restart our relay, we might get a successful connection
+ from the outside before we've started our reachability tests,
+ triggering a warning: "ORPort found reachable, but I have no
+ routerinfo yet. Failing to inform controller of success." This
+ bug was harmless unless Tor is running under a controller
+ like Vidalia, in which case the controller would never get a
+ REACHABILITY_SUCCEEDED status event. Bugfix on 0.1.2.6-alpha;
+ fixes bug 1172.
diff --git a/src/or/router.c b/src/or/router.c
index 75f592d..ba7be3d 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -793,19 +793,14 @@ consider_testing_reachability(int test_or, int test_dir)
void
router_orport_found_reachable(void)
{
- if (!can_reach_or_port) {
- routerinfo_t *me = router_get_my_routerinfo();
+ routerinfo_t *me = router_get_my_routerinfo();
+ if (!can_reach_or_port && me) {
log_notice(LD_OR,"Self-testing indicates your ORPort is reachable from "
"the outside. Excellent.%s",
get_options()->_PublishServerDescriptor != NO_AUTHORITY ?
" Publishing server descriptor." : "");
can_reach_or_port = 1;
mark_my_descriptor_dirty();
- if (!me) { /* should never happen */
- log_warn(LD_BUG, "ORPort found reachable, but I have no routerinfo "
- "yet. Failing to inform controller of success.");
- return;
- }
control_event_server_status(LOG_NOTICE,
"REACHABILITY_SUCCEEDED ORADDRESS=%s:%d",
me->address, me->or_port);
@@ -816,18 +811,13 @@ router_orport_found_reachable(void)
void
router_dirport_found_reachable(void)
{
- if (!can_reach_dir_port) {
- routerinfo_t *me = router_get_my_routerinfo();
+ routerinfo_t *me = router_get_my_routerinfo();
+ if (!can_reach_dir_port && me) {
log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable "
"from the outside. Excellent.");
can_reach_dir_port = 1;
- if (!me || decide_to_advertise_dirport(get_options(), me->dir_port))
+ if (decide_to_advertise_dirport(get_options(), me->dir_port))
mark_my_descriptor_dirty();
- if (!me) { /* should never happen */
- log_warn(LD_BUG, "DirPort found reachable, but I have no routerinfo "
- "yet. Failing to inform controller of success.");
- return;
- }
control_event_server_status(LOG_NOTICE,
"REACHABILITY_SUCCEEDED DIRADDRESS=%s:%d",
me->address, me->dir_port);
1
0

[tor/master] Merge remote branch 'origin/maint-0.2.1' into maint-0.2.2
by nickm@torproject.org 14 Mar '11
by nickm@torproject.org 14 Mar '11
14 Mar '11
commit b97d9abd0940037b249a1ee56724dbfed904263b
Merge: 0588330 1a9d19e
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Mon Mar 14 17:04:53 2011 -0400
Merge remote branch 'origin/maint-0.2.1' into maint-0.2.2
changes/bug1172 | 9 +++++++++
src/or/router.c | 20 +++++---------------
2 files changed, 14 insertions(+), 15 deletions(-)
diff --combined src/or/router.c
index 4c5eb7a,ba7be3d..c15b9b2
--- a/src/or/router.c
+++ b/src/or/router.c
@@@ -7,24 -7,6 +7,24 @@@
#define ROUTER_PRIVATE
#include "or.h"
+#include "circuitlist.h"
+#include "circuituse.h"
+#include "config.h"
+#include "connection.h"
+#include "control.h"
+#include "directory.h"
+#include "dirserv.h"
+#include "dns.h"
+#include "geoip.h"
+#include "hibernate.h"
+#include "main.h"
+#include "networkstatus.h"
+#include "policies.h"
+#include "relay.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerlist.h"
+#include "routerparse.h"
/**
* \file router.c
@@@ -49,15 -31,11 +49,15 @@@ static crypto_pk_env_t *onionkey=NULL
/** Previous private onionskin decryption key: used to decode CREATE cells
* generated by clients that have an older version of our descriptor. */
static crypto_pk_env_t *lastonionkey=NULL;
-/** Private "identity key": used to sign directory info and TLS
+/** Private server "identity key": used to sign directory info and TLS
* certificates. Never changes. */
-static crypto_pk_env_t *identitykey=NULL;
-/** Digest of identitykey. */
-static char identitykey_digest[DIGEST_LEN];
+static crypto_pk_env_t *server_identitykey=NULL;
+/** Digest of server_identitykey. */
+static char server_identitykey_digest[DIGEST_LEN];
+/** Private client "identity key": used to sign bridges' and clients'
+ * outbound TLS certificates. Regenerated on startup and on IP address
+ * change. */
+static crypto_pk_env_t *client_identitykey=NULL;
/** Signing key used for v3 directory material; only set for authorities. */
static crypto_pk_env_t *authority_signing_key = NULL;
/** Key certificate to authenticate v3 directory material; only set for
@@@ -83,7 -61,8 +83,7 @@@ static voi
set_onion_key(crypto_pk_env_t *k)
{
tor_mutex_acquire(key_lock);
- if (onionkey)
- crypto_free_pk_env(onionkey);
+ crypto_free_pk_env(onionkey);
onionkey = k;
onionkey_set_at = time(NULL);
tor_mutex_release(key_lock);
@@@ -127,78 -106,32 +127,78 @@@ get_onion_key_set_at(void
return onionkey_set_at;
}
-/** Set the current identity key to k.
+/** Set the current server identity key to <b>k</b>.
*/
void
-set_identity_key(crypto_pk_env_t *k)
+set_server_identity_key(crypto_pk_env_t *k)
{
- if (identitykey)
- crypto_free_pk_env(identitykey);
- identitykey = k;
- crypto_pk_get_digest(identitykey, identitykey_digest);
+ crypto_free_pk_env(server_identitykey);
+ server_identitykey = k;
+ crypto_pk_get_digest(server_identitykey, server_identitykey_digest);
}
-/** Returns the current identity key; requires that the identity key has been
- * set.
+/** Make sure that we have set up our identity keys to match or not match as
+ * appropriate, and die with an assertion if we have not. */
+static void
+assert_identity_keys_ok(void)
+{
+ tor_assert(client_identitykey);
+ if (public_server_mode(get_options())) {
+ /* assert that we have set the client and server keys to be equal */
+ tor_assert(server_identitykey);
+ tor_assert(0==crypto_pk_cmp_keys(client_identitykey, server_identitykey));
+ } else {
+ /* assert that we have set the client and server keys to be unequal */
+ if (server_identitykey)
+ tor_assert(0!=crypto_pk_cmp_keys(client_identitykey,
+ server_identitykey));
+ }
+}
+
+/** Returns the current server identity key; requires that the key has
+ * been set, and that we are running as a Tor server.
*/
crypto_pk_env_t *
-get_identity_key(void)
+get_server_identity_key(void)
{
- tor_assert(identitykey);
- return identitykey;
+ tor_assert(server_identitykey);
+ tor_assert(server_mode(get_options()));
+ assert_identity_keys_ok();
+ return server_identitykey;
}
-/** Return true iff the identity key has been set. */
+/** Return true iff the server identity key has been set. */
int
-identity_key_is_set(void)
+server_identity_key_is_set(void)
{
- return identitykey != NULL;
+ return server_identitykey != NULL;
+}
+
+/** Set the current client identity key to <b>k</b>.
+ */
+void
+set_client_identity_key(crypto_pk_env_t *k)
+{
+ crypto_free_pk_env(client_identitykey);
+ client_identitykey = k;
+}
+
+/** Returns the current client identity key for use on outgoing TLS
+ * connections; requires that the key has been set.
+ */
+crypto_pk_env_t *
+get_tlsclient_identity_key(void)
+{
+ tor_assert(client_identitykey);
+ assert_identity_keys_ok();
+ return client_identitykey;
+}
+
+/** Return true iff the client identity key has been set. */
+int
+client_identity_key_is_set(void)
+{
+ return client_identitykey != NULL;
}
/** Return the key certificate for this v3 (voting) authority, or NULL
@@@ -268,7 -201,8 +268,7 @@@ rotate_onion_key(void
}
log_info(LD_GENERAL, "Rotating onion key");
tor_mutex_acquire(key_lock);
- if (lastonionkey)
- crypto_free_pk_env(lastonionkey);
+ crypto_free_pk_env(lastonionkey);
lastonionkey = onionkey;
onionkey = prkey;
now = time(NULL);
@@@ -397,9 -331,10 +397,9 @@@ load_authority_keyset(int legacy, crypt
goto done;
}
- if (*key_out)
- crypto_free_pk_env(*key_out);
- if (*cert_out)
- authority_cert_free(*cert_out);
+ crypto_free_pk_env(*key_out);
+ authority_cert_free(*cert_out);
+
*key_out = signing_key;
*cert_out = parsed;
r = 0;
@@@ -409,8 -344,10 +409,8 @@@
done:
tor_free(fname);
tor_free(cert);
- if (signing_key)
- crypto_free_pk_env(signing_key);
- if (parsed)
- authority_cert_free(parsed);
+ crypto_free_pk_env(signing_key);
+ authority_cert_free(parsed);
return r;
}
@@@ -505,9 -442,7 +505,9 @@@ init_keys(void
key_lock = tor_mutex_new();
/* There are a couple of paths that put us here before */
- if (crypto_global_init(get_options()->HardwareAccel)) {
+ if (crypto_global_init(get_options()->HardwareAccel,
+ get_options()->AccelName,
+ get_options()->AccelDir)) {
log_err(LD_BUG, "Unable to initialize OpenSSL. Exiting.");
return -1;
}
@@@ -521,12 -456,9 +521,12 @@@
crypto_free_pk_env(prkey);
return -1;
}
- set_identity_key(prkey);
- /* Create a TLS context; default the client nickname to "client". */
- if (tor_tls_context_new(get_identity_key(), MAX_SSL_KEY_LIFETIME) < 0) {
+ set_client_identity_key(prkey);
+ /* Create a TLS context. */
+ if (tor_tls_context_init(0,
+ get_tlsclient_identity_key(),
+ NULL,
+ MAX_SSL_KEY_LIFETIME) < 0) {
log_err(LD_GENERAL,"Error creating TLS context for Tor client.");
return -1;
}
@@@ -561,28 -493,13 +561,28 @@@
}
}
- /* 1. Read identity key. Make it if none is found. */
+ /* 1b. Read identity key. Make it if none is found. */
keydir = get_datadir_fname2("keys", "secret_id_key");
log_info(LD_GENERAL,"Reading/making identity key \"%s\"...",keydir);
prkey = init_key_from_file(keydir, 1, LOG_ERR);
tor_free(keydir);
if (!prkey) return -1;
- set_identity_key(prkey);
+ set_server_identity_key(prkey);
+
+ /* 1c. If we are configured as a bridge, generate a client key;
+ * otherwise, set the server identity key as our client identity
+ * key. */
+ if (public_server_mode(options)) {
+ set_client_identity_key(crypto_pk_dup_key(prkey)); /* set above */
+ } else {
+ if (!(prkey = crypto_new_pk_env()))
+ return -1;
+ if (crypto_pk_generate_key(prkey)) {
+ crypto_free_pk_env(prkey);
+ return -1;
+ }
+ set_client_identity_key(prkey);
+ }
/* 2. Read onion key. Make it if none is found. */
keydir = get_datadir_fname2("keys", "secret_onion_key");
@@@ -619,22 -536,18 +619,22 @@@
tor_free(keydir);
/* 3. Initialize link key and TLS context. */
- if (tor_tls_context_new(get_identity_key(), MAX_SSL_KEY_LIFETIME) < 0) {
+ if (tor_tls_context_init(public_server_mode(options),
+ get_tlsclient_identity_key(),
+ get_server_identity_key(),
+ MAX_SSL_KEY_LIFETIME) < 0) {
log_err(LD_GENERAL,"Error initializing TLS context");
return -1;
}
/* 4. Build our router descriptor. */
/* Must be called after keys are initialized. */
mydesc = router_get_my_descriptor();
- if (authdir_mode(options)) {
+ if (authdir_mode_handles_descs(options, ROUTER_PURPOSE_GENERAL)) {
const char *m = NULL;
routerinfo_t *ri;
/* We need to add our own fingerprint so it gets recognized. */
- if (dirserv_add_own_fingerprint(options->Nickname, get_identity_key())) {
+ if (dirserv_add_own_fingerprint(options->Nickname,
+ get_server_identity_key())) {
log_err(LD_GENERAL,"Error adding own fingerprint to approved set");
return -1;
}
@@@ -655,8 -568,7 +655,8 @@@
/* 5. Dump fingerprint to 'fingerprint' */
keydir = get_datadir_fname("fingerprint");
log_info(LD_GENERAL,"Dumping fingerprint to \"%s\"...",keydir);
- if (crypto_pk_get_fingerprint(get_identity_key(), fingerprint, 0)<0) {
+ if (crypto_pk_get_fingerprint(get_server_identity_key(),
+ fingerprint, 0) < 0) {
log_err(LD_GENERAL,"Error computing fingerprint");
tor_free(keydir);
return -1;
@@@ -694,7 -606,7 +694,7 @@@
return -1;
}
/* 6b. [authdirserver only] add own key to approved directories. */
- crypto_pk_get_digest(get_identity_key(), digest);
+ crypto_pk_get_digest(get_server_identity_key(), digest);
type = ((options->V1AuthoritativeDir ? V1_AUTHORITY : NO_AUTHORITY) |
(options->V2AuthoritativeDir ? V2_AUTHORITY : NO_AUTHORITY) |
(options->V3AuthoritativeDir ? V3_AUTHORITY : NO_AUTHORITY) |
@@@ -881,19 -793,14 +881,14 @@@ consider_testing_reachability(int test_
void
router_orport_found_reachable(void)
{
- if (!can_reach_or_port) {
- routerinfo_t *me = router_get_my_routerinfo();
+ routerinfo_t *me = router_get_my_routerinfo();
+ if (!can_reach_or_port && me) {
log_notice(LD_OR,"Self-testing indicates your ORPort is reachable from "
"the outside. Excellent.%s",
get_options()->_PublishServerDescriptor != NO_AUTHORITY ?
" Publishing server descriptor." : "");
can_reach_or_port = 1;
mark_my_descriptor_dirty();
- if (!me) { /* should never happen */
- log_warn(LD_BUG, "ORPort found reachable, but I have no routerinfo "
- "yet. Failing to inform controller of success.");
- return;
- }
control_event_server_status(LOG_NOTICE,
"REACHABILITY_SUCCEEDED ORADDRESS=%s:%d",
me->address, me->or_port);
@@@ -904,18 -811,13 +899,13 @@@
void
router_dirport_found_reachable(void)
{
- if (!can_reach_dir_port) {
- routerinfo_t *me = router_get_my_routerinfo();
+ routerinfo_t *me = router_get_my_routerinfo();
+ if (!can_reach_dir_port && me) {
log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable "
"from the outside. Excellent.");
can_reach_dir_port = 1;
- if (!me || decide_to_advertise_dirport(get_options(), me->dir_port))
+ if (decide_to_advertise_dirport(get_options(), me->dir_port))
mark_my_descriptor_dirty();
- if (!me) { /* should never happen */
- log_warn(LD_BUG, "DirPort found reachable, but I have no routerinfo "
- "yet. Failing to inform controller of success.");
- return;
- }
control_event_server_status(LOG_NOTICE,
"REACHABILITY_SUCCEEDED DIRADDRESS=%s:%d",
me->address, me->dir_port);
@@@ -1050,28 -952,6 +1040,28 @@@ server_mode(or_options_t *options
return (options->ORPort != 0 || options->ORListenAddress);
}
+/** Return true iff we are trying to be a non-bridge server.
+ */
+int
+public_server_mode(or_options_t *options)
+{
+ if (!server_mode(options)) return 0;
+ return (!options->BridgeRelay);
+}
+
+/** Return true iff the combination of options in <b>options</b> and parameters
+ * in the consensus mean that we don't want to allow exits from circuits
+ * we got from addresses not known to be servers. */
+int
+should_refuse_unknown_exits(or_options_t *options)
+{
+ if (options->RefuseUnknownExits_ != -1) {
+ return options->RefuseUnknownExits_;
+ } else {
+ return networkstatus_get_param(NULL, "refuseunknownexits", 1, 0, 1);
+ }
+}
+
/** Remember if we've advertised ourselves to the dirservers. */
static int server_is_advertised=0;
@@@ -1099,7 -979,7 +1089,7 @@@ proxy_mode(or_options_t *options
{
return (options->SocksPort != 0 || options->SocksListenAddress ||
options->TransPort != 0 || options->TransListenAddress ||
- options->NatdPort != 0 || options->NatdListenAddress ||
+ options->NATDPort != 0 || options->NATDListenAddress ||
options->DNSPort != 0 || options->DNSListenAddress);
}
@@@ -1234,24 -1114,12 +1224,24 @@@ router_compare_to_my_exit_policy(edge_c
desc_routerinfo->exit_policy) != ADDR_POLICY_ACCEPTED;
}
+/** Return true iff my exit policy is reject *:*. Return -1 if we don't
+ * have a descriptor */
+int
+router_my_exit_policy_is_reject_star(void)
+{
+ if (!router_get_my_routerinfo()) /* make sure desc_routerinfo exists */
+ return -1;
+
+ return desc_routerinfo->policy_is_reject_star;
+}
+
/** Return true iff I'm a server and <b>digest</b> is equal to
- * my identity digest. */
+ * my server identity key digest. */
int
router_digest_is_me(const char *digest)
{
- return identitykey && !memcmp(identitykey_digest, digest, DIGEST_LEN);
+ return (server_identitykey &&
+ !memcmp(server_identitykey_digest, digest, DIGEST_LEN));
}
/** Return true iff I'm a server and <b>digest</b> is equal to
@@@ -1341,8 -1209,6 +1331,8 @@@ static int router_guess_address_from_di
int
router_pick_published_address(or_options_t *options, uint32_t *addr)
{
+ char buf[INET_NTOA_BUF_LEN];
+ struct in_addr a;
if (resolve_my_address(LOG_INFO, options, addr, NULL) < 0) {
log_info(LD_CONFIG, "Could not determine our address locally. "
"Checking if directory headers provide any hints.");
@@@ -1352,9 -1218,6 +1342,9 @@@
return -1;
}
}
+ a.s_addr = htonl(*addr);
+ tor_inet_ntoa(&a, buf, sizeof(buf));
+ log_info(LD_CONFIG,"Success: chose address '%s'.", buf);
return 0;
}
@@@ -1377,7 -1240,7 +1367,7 @@@ router_rebuild_descriptor(int force
if (router_pick_published_address(options, &addr) < 0) {
/* Stop trying to rebuild our descriptor every second. We'll
- * learn that it's time to try again when server_has_changed_ip()
+ * learn that it's time to try again when ip_address_changed()
* marks it dirty. */
desc_clean_since = time(NULL);
return -1;
@@@ -1393,7 -1256,7 +1383,7 @@@
ri->cache_info.published_on = time(NULL);
ri->onion_pkey = crypto_pk_dup_key(get_onion_key()); /* must invoke from
* main thread */
- ri->identity_pkey = crypto_pk_dup_key(get_identity_key());
+ ri->identity_pkey = crypto_pk_dup_key(get_server_identity_key());
if (crypto_pk_get_digest(ri->identity_pkey,
ri->cache_info.identity_digest)<0) {
routerinfo_free(ri);
@@@ -1410,16 -1273,9 +1400,16 @@@
ri->bandwidthcapacity = hibernating ? 0 : rep_hist_bandwidth_assess();
- policies_parse_exit_policy(options->ExitPolicy, &ri->exit_policy,
- options->ExitPolicyRejectPrivate,
- ri->address);
+ if (dns_seems_to_be_broken() || has_dns_init_failed()) {
+ /* DNS is screwed up; don't claim to be an exit. */
+ policies_exit_policy_append_reject_star(&ri->exit_policy);
+ } else {
+ policies_parse_exit_policy(options->ExitPolicy, &ri->exit_policy,
+ options->ExitPolicyRejectPrivate,
+ ri->address, !options->BridgeRelay);
+ }
+ ri->policy_is_reject_star =
+ policy_is_reject_star(ri->exit_policy);
if (desc_routerinfo) { /* inherit values */
ri->is_valid = desc_routerinfo->is_valid;
@@@ -1490,30 -1346,26 +1480,30 @@@
ei->cache_info.published_on = ri->cache_info.published_on;
memcpy(ei->cache_info.identity_digest, ri->cache_info.identity_digest,
DIGEST_LEN);
- ei->cache_info.signed_descriptor_body = tor_malloc(8192);
- if (extrainfo_dump_to_string(ei->cache_info.signed_descriptor_body, 8192,
- ei, get_identity_key()) < 0) {
+ if (extrainfo_dump_to_string(&ei->cache_info.signed_descriptor_body,
+ ei, get_server_identity_key()) < 0) {
log_warn(LD_BUG, "Couldn't generate extra-info descriptor.");
- routerinfo_free(ri);
extrainfo_free(ei);
- return -1;
+ ei = NULL;
+ } else {
+ ei->cache_info.signed_descriptor_len =
+ strlen(ei->cache_info.signed_descriptor_body);
+ router_get_extrainfo_hash(ei->cache_info.signed_descriptor_body,
+ ei->cache_info.signed_descriptor_digest);
}
- ei->cache_info.signed_descriptor_len =
- strlen(ei->cache_info.signed_descriptor_body);
- router_get_extrainfo_hash(ei->cache_info.signed_descriptor_body,
- ei->cache_info.signed_descriptor_digest);
/* Now finish the router descriptor. */
- memcpy(ri->cache_info.extra_info_digest,
- ei->cache_info.signed_descriptor_digest,
- DIGEST_LEN);
+ if (ei) {
+ memcpy(ri->cache_info.extra_info_digest,
+ ei->cache_info.signed_descriptor_digest,
+ DIGEST_LEN);
+ } else {
+ /* ri was allocated with tor_malloc_zero, so there is no need to
+ * zero ri->cache_info.extra_info_digest here. */
+ }
ri->cache_info.signed_descriptor_body = tor_malloc(8192);
if (router_dump_router_to_string(ri->cache_info.signed_descriptor_body, 8192,
- ri, get_identity_key())<0) {
+ ri, get_server_identity_key()) < 0) {
log_warn(LD_BUG, "Couldn't generate router descriptor.");
routerinfo_free(ri);
extrainfo_free(ei);
@@@ -1528,7 -1380,7 +1518,7 @@@
/* Let bridges serve their own descriptors unencrypted, so they can
* pass reachability testing. (If they want to be harder to notice,
* they can always leave the DirPort off). */
- if (!options->BridgeRelay)
+ if (ei && !options->BridgeRelay)
ei->cache_info.send_unencrypted = 1;
router_get_router_hash(ri->cache_info.signed_descriptor_body,
@@@ -1537,13 -1389,13 +1527,13 @@@
routerinfo_set_country(ri);
- tor_assert(! routerinfo_incompatible_with_extrainfo(ri, ei, NULL, NULL));
+ if (ei) {
+ tor_assert(! routerinfo_incompatible_with_extrainfo(ri, ei, NULL, NULL));
+ }
- if (desc_routerinfo)
- routerinfo_free(desc_routerinfo);
+ routerinfo_free(desc_routerinfo);
desc_routerinfo = ri;
- if (desc_extrainfo)
- extrainfo_free(desc_extrainfo);
+ extrainfo_free(desc_extrainfo);
desc_extrainfo = ei;
desc_clean_since = time(NULL);
@@@ -1724,6 -1576,8 +1714,6 @@@ router_guess_address_from_dir_headers(u
return -1;
}
-extern const char tor_svn_revision[]; /* from tor_main.c */
-
/** Set <b>platform</b> (max length <b>len</b>) to a NUL-terminated short
* string describing the version of Tor and the operating system we're
* currently running on.
@@@ -1754,7 -1608,6 +1744,7 @@@ router_dump_router_to_string(char *s, s
char digest[DIGEST_LEN];
char published[ISO_TIME_LEN+1];
char fingerprint[FINGERPRINT_LEN+1];
+ int has_extra_info_digest;
char extra_info_digest[HEX_DIGEST_LEN+1];
size_t onion_pkeylen, identity_pkeylen;
size_t written;
@@@ -1783,7 -1636,7 +1773,7 @@@
return -1;
}
- /* PEM-encode the identity key key */
+ /* PEM-encode the identity key */
if (crypto_pk_write_public_key_to_string(router->identity_pkey,
&identity_pkey,&identity_pkeylen)<0) {
log_warn(LD_BUG,"write identity_pkey to string failed!");
@@@ -1805,13 -1658,8 +1795,13 @@@
family_line = tor_strdup("");
}
- base16_encode(extra_info_digest, sizeof(extra_info_digest),
- router->cache_info.extra_info_digest, DIGEST_LEN);
+ has_extra_info_digest =
+ ! tor_digest_is_zero(router->cache_info.extra_info_digest);
+
+ if (has_extra_info_digest) {
+ base16_encode(extra_info_digest, sizeof(extra_info_digest),
+ router->cache_info.extra_info_digest, DIGEST_LEN);
+ }
/* Generate the easy portion of the router descriptor. */
result = tor_snprintf(s, maxlen,
@@@ -1822,7 -1670,7 +1812,7 @@@
"opt fingerprint %s\n"
"uptime %ld\n"
"bandwidth %d %d %d\n"
- "opt extra-info-digest %s\n%s"
+ "%s%s%s%s"
"onion-key\n%s"
"signing-key\n%s"
"%s%s%s%s",
@@@ -1837,9 -1685,7 +1827,9 @@@
(int) router->bandwidthrate,
(int) router->bandwidthburst,
(int) router->bandwidthcapacity,
- extra_info_digest,
+ has_extra_info_digest ? "opt extra-info-digest " : "",
+ has_extra_info_digest ? extra_info_digest : "",
+ has_extra_info_digest ? "\n" : "",
options->DownloadExtraInfo ? "opt caches-extra-info\n" : "",
onion_pkey, identity_pkey,
family_line,
@@@ -1871,7 -1717,9 +1861,7 @@@
}
/* Write the exit policy to the end of 's'. */
- if (dns_seems_to_be_broken() || has_dns_init_failed() ||
- !router->exit_policy || !smartlist_len(router->exit_policy)) {
- /* DNS is screwed up; don't claim to be an exit. */
+ if (!router->exit_policy || !smartlist_len(router->exit_policy)) {
strlcat(s+written, "reject *:*\n", maxlen-written);
written += strlen("reject *:*\n");
tmpe = NULL;
@@@ -1894,8 -1742,7 +1884,8 @@@
}
}
- if (written+256 > maxlen) { /* Not enough room for signature. */
+ if (written + DIROBJ_MAX_SIG_LEN > maxlen) {
+ /* Not enough room for signature. */
log_warn(LD_BUG,"not enough room left in descriptor for signature!");
return -1;
}
@@@ -1910,7 -1757,7 +1900,7 @@@
note_crypto_pk_op(SIGN_RTR);
if (router_append_dirobj_signature(s+written,maxlen-written,
- digest,ident_key)<0) {
+ digest,DIGEST_LEN,ident_key)<0) {
log_warn(LD_BUG, "Couldn't sign router descriptor");
return -1;
}
@@@ -1945,62 -1792,11 +1935,62 @@@
return (int)written+1;
}
-/** Write the contents of <b>extrainfo</b> to the <b>maxlen</b>-byte string
- * <b>s</b>, signing them with <b>ident_key</b>. Return 0 on success,
- * negative on failure. */
+/** Load the contents of <b>filename</b>, find the last line starting with
+ * <b>end_line</b>, ensure that its timestamp is not more than 25 hours in
+ * the past or more than 1 hour in the future with respect to <b>now</b>,
+ * and write the file contents starting with that line to *<b>out</b>.
+ * Return 1 for success, 0 if the file does not exist, or -1 if the file
+ * does not contain a line matching these criteria or other failure. */
+static int
+load_stats_file(const char *filename, const char *end_line, time_t now,
+ char **out)
+{
+ int r = -1;
+ char *fname = get_datadir_fname(filename);
+ char *contents, *start = NULL, *tmp, timestr[ISO_TIME_LEN+1];
+ time_t written;
+ switch (file_status(fname)) {
+ case FN_FILE:
+ /* X022 Find an alternative to reading the whole file to memory. */
+ if ((contents = read_file_to_str(fname, 0, NULL))) {
+ tmp = strstr(contents, end_line);
+ /* Find last block starting with end_line */
+ while (tmp) {
+ start = tmp;
+ tmp = strstr(tmp + 1, end_line);
+ }
+ if (!start)
+ goto notfound;
+ if (strlen(start) < strlen(end_line) + 1 + sizeof(timestr))
+ goto notfound;
+ strlcpy(timestr, start + 1 + strlen(end_line), sizeof(timestr));
+ if (parse_iso_time(timestr, &written) < 0)
+ goto notfound;
+ if (written < now - (25*60*60) || written > now + (1*60*60))
+ goto notfound;
+ *out = tor_strdup(start);
+ r = 1;
+ }
+ notfound:
+ tor_free(contents);
+ break;
+ case FN_NOENT:
+ r = 0;
+ break;
+ case FN_ERROR:
+ case FN_DIR:
+ default:
+ break;
+ }
+ tor_free(fname);
+ return r;
+}
+
+/** Write the contents of <b>extrainfo</b> and aggregated statistics to
+ * *<b>s_out</b>, signing them with <b>ident_key</b>. Return 0 on
+ * success, negative on failure. */
int
-extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
+extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo,
crypto_pk_env_t *ident_key)
{
or_options_t *options = get_options();
@@@ -2009,128 -1805,87 +1999,128 @@@
char digest[DIGEST_LEN];
char *bandwidth_usage;
int result;
- size_t len;
+ static int write_stats_to_extrainfo = 1;
+ char sig[DIROBJ_MAX_SIG_LEN+1];
+ char *s, *pre, *contents, *cp, *s_dup = NULL;
+ time_t now = time(NULL);
+ smartlist_t *chunks = smartlist_create();
+ extrainfo_t *ei_tmp = NULL;
base16_encode(identity, sizeof(identity),
extrainfo->cache_info.identity_digest, DIGEST_LEN);
format_iso_time(published, extrainfo->cache_info.published_on);
- bandwidth_usage = rep_hist_get_bandwidth_lines(1);
+ bandwidth_usage = rep_hist_get_bandwidth_lines();
- result = tor_snprintf(s, maxlen,
- "extra-info %s %s\n"
- "published %s\n%s",
- extrainfo->nickname, identity,
- published, bandwidth_usage);
+ tor_asprintf(&pre, "extra-info %s %s\npublished %s\n%s",
+ extrainfo->nickname, identity,
+ published, bandwidth_usage);
tor_free(bandwidth_usage);
- if (result<0)
- return -1;
+ smartlist_add(chunks, pre);
+
+ if (options->ExtraInfoStatistics && write_stats_to_extrainfo) {
+ log_info(LD_GENERAL, "Adding stats to extra-info descriptor.");
+ if (options->DirReqStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"dirreq-stats",
+ "dirreq-stats-end", now, &contents) > 0) {
+ smartlist_add(chunks, contents);
+ }
+ if (options->EntryStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"entry-stats",
+ "entry-stats-end", now, &contents) > 0) {
+ smartlist_add(chunks, contents);
+ }
+ if (options->CellStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"buffer-stats",
+ "cell-stats-end", now, &contents) > 0) {
+ smartlist_add(chunks, contents);
+ }
+ if (options->ExitPortStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"exit-stats",
+ "exit-stats-end", now, &contents) > 0) {
+ smartlist_add(chunks, contents);
+ }
+ }
- if (should_record_bridge_info(options)) {
- char *geoip_summary = extrainfo_get_client_geoip_summary(time(NULL));
- if (geoip_summary) {
- char geoip_start[ISO_TIME_LEN+1];
- format_iso_time(geoip_start, geoip_get_history_start());
- result = tor_snprintf(s+strlen(s), maxlen-strlen(s),
- "geoip-start-time %s\n"
- "geoip-client-origins %s\n",
- geoip_start, geoip_summary);
- control_event_clients_seen(geoip_start, geoip_summary);
- tor_free(geoip_summary);
- if (result<0)
- return -1;
+ if (should_record_bridge_info(options) && write_stats_to_extrainfo) {
+ const char *bridge_stats = geoip_get_bridge_stats_extrainfo(now);
+ if (bridge_stats) {
+ smartlist_add(chunks, tor_strdup(bridge_stats));
}
}
- len = strlen(s);
- strlcat(s+len, "router-signature\n", maxlen-len);
- len += strlen(s+len);
- if (router_get_extrainfo_hash(s, digest)<0)
- return -1;
- if (router_append_dirobj_signature(s+len, maxlen-len, digest, ident_key)<0)
- return -1;
+ smartlist_add(chunks, tor_strdup("router-signature\n"));
+ s = smartlist_join_strings(chunks, "", 0, NULL);
+
+ while (strlen(s) > MAX_EXTRAINFO_UPLOAD_SIZE - DIROBJ_MAX_SIG_LEN) {
+ /* So long as there are at least two chunks (one for the initial
+ * extra-info line and one for the router-signature), we can keep removing
+ * things. */
+ if (smartlist_len(chunks) > 2) {
+ /* We remove the next-to-last element (remember, len-1 is the last
+ element), since we need to keep the router-signature element. */
+ int idx = smartlist_len(chunks) - 2;
+ char *e = smartlist_get(chunks, idx);
+ smartlist_del_keeporder(chunks, idx);
+ log_warn(LD_GENERAL, "We just generated an extra-info descriptor "
+ "with statistics that exceeds the 50 KB "
+ "upload limit. Removing last added "
+ "statistics.");
+ tor_free(e);
+ tor_free(s);
+ s = smartlist_join_strings(chunks, "", 0, NULL);
+ } else {
+ log_warn(LD_BUG, "We just generated an extra-info descriptors that "
+ "exceeds the 50 KB upload limit.");
+ goto err;
+ }
+ }
-#ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
- {
- char *cp, *s_dup;
- extrainfo_t *ei_tmp;
- cp = s_dup = tor_strdup(s);
- ei_tmp = extrainfo_parse_entry_from_string(cp, NULL, 1, NULL);
- if (!ei_tmp) {
- log_err(LD_BUG,
- "We just generated an extrainfo descriptor we can't parse.");
- log_err(LD_BUG, "Descriptor was: <<%s>>", s);
- tor_free(s_dup);
- return -1;
+ memset(sig, 0, sizeof(sig));
+ if (router_get_extrainfo_hash(s, digest) < 0 ||
+ router_append_dirobj_signature(sig, sizeof(sig), digest, DIGEST_LEN,
+ ident_key) < 0) {
+ log_warn(LD_BUG, "Could not append signature to extra-info "
+ "descriptor.");
+ goto err;
+ }
+ smartlist_add(chunks, tor_strdup(sig));
+ tor_free(s);
+ s = smartlist_join_strings(chunks, "", 0, NULL);
+
+ cp = s_dup = tor_strdup(s);
+ ei_tmp = extrainfo_parse_entry_from_string(cp, NULL, 1, NULL);
+ if (!ei_tmp) {
+ if (write_stats_to_extrainfo) {
+ log_warn(LD_GENERAL, "We just generated an extra-info descriptor "
+ "with statistics that we can't parse. Not "
+ "adding statistics to this or any future "
+ "extra-info descriptors.");
+ write_stats_to_extrainfo = 0;
+ result = extrainfo_dump_to_string(s_out, extrainfo, ident_key);
+ goto done;
+ } else {
+ log_warn(LD_BUG, "We just generated an extrainfo descriptor we "
+ "can't parse.");
+ goto err;
}
- tor_free(s_dup);
- extrainfo_free(ei_tmp);
}
-#endif
- return (int)strlen(s)+1;
-}
+ *s_out = s;
+ s = NULL; /* prevent free */
+ result = 0;
+ goto done;
-/** Wrapper function for geoip_get_client_history(). It first discards
- * any items in the client history that are too old -- it dumps anything
- * more than 48 hours old, but it only considers whether to dump at most
- * once per 48 hours, so we aren't too precise to an observer (see also
- * r14780).
- */
-char *
-extrainfo_get_client_geoip_summary(time_t now)
-{
- static time_t last_purged_at = 0;
- int geoip_purge_interval = 48*60*60;
-#ifdef ENABLE_GEOIP_STATS
- if (get_options()->DirRecordUsageByCountry)
- geoip_purge_interval = get_options()->DirRecordUsageRetainIPs;
-#endif
- if (now > last_purged_at+geoip_purge_interval) {
- geoip_remove_old_clients(now-geoip_purge_interval);
- last_purged_at = now;
- }
- return geoip_get_client_history(now, GEOIP_CLIENT_CONNECT);
+ err:
+ result = -1;
+
+ done:
+ tor_free(s);
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_free(chunks);
+ tor_free(s_dup);
+ extrainfo_free(ei_tmp);
+
+ return result;
}
/** Return true iff <b>s</b> is a legally valid server nickname. */
@@@ -2257,17 -2012,26 +2247,17 @@@ router_purpose_from_string(const char *
void
router_free_all(void)
{
- if (onionkey)
- crypto_free_pk_env(onionkey);
- if (lastonionkey)
- crypto_free_pk_env(lastonionkey);
- if (identitykey)
- crypto_free_pk_env(identitykey);
- if (key_lock)
- tor_mutex_free(key_lock);
- if (desc_routerinfo)
- routerinfo_free(desc_routerinfo);
- if (desc_extrainfo)
- extrainfo_free(desc_extrainfo);
- if (authority_signing_key)
- crypto_free_pk_env(authority_signing_key);
- if (authority_key_certificate)
- authority_cert_free(authority_key_certificate);
- if (legacy_signing_key)
- crypto_free_pk_env(legacy_signing_key);
- if (legacy_key_certificate)
- authority_cert_free(legacy_key_certificate);
+ crypto_free_pk_env(onionkey);
+ crypto_free_pk_env(lastonionkey);
+ crypto_free_pk_env(server_identitykey);
+ crypto_free_pk_env(client_identitykey);
+ tor_mutex_free(key_lock);
+ routerinfo_free(desc_routerinfo);
+ extrainfo_free(desc_extrainfo);
+ crypto_free_pk_env(authority_signing_key);
+ authority_cert_free(authority_key_certificate);
+ crypto_free_pk_env(legacy_signing_key);
+ authority_cert_free(legacy_key_certificate);
if (warned_nonexistent_family) {
SMARTLIST_FOREACH(warned_nonexistent_family, char *, cp, tor_free(cp));
1
0
commit ebf6786ab3597ec96ef2c026d7dc32c26fbc84e4
Merge: 50c9d31 b97d9ab
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Mon Mar 14 17:22:38 2011 -0400
Merge remote branch 'origin/maint-0.2.2'
Fixed conflict: router_get_my_routerinfo now returns const
Conflicts:
src/or/router.c
changes/bug1172 | 9 +++++++++
src/or/router.c | 20 +++++---------------
2 files changed, 14 insertions(+), 15 deletions(-)
diff --combined src/or/router.c
index 3f1a0a0,c15b9b2..eb4d6b5
--- a/src/or/router.c
+++ b/src/or/router.c
@@@ -7,7 -7,6 +7,7 @@@
#define ROUTER_PRIVATE
#include "or.h"
+#include "circuitbuild.h"
#include "circuitlist.h"
#include "circuituse.h"
#include "config.h"
@@@ -20,7 -19,6 +20,7 @@@
#include "hibernate.h"
#include "main.h"
#include "networkstatus.h"
+#include "nodelist.h"
#include "policies.h"
#include "relay.h"
#include "rephist.h"
@@@ -152,8 -150,8 +152,8 @@@ assert_identity_keys_ok(void
} else {
/* assert that we have set the client and server keys to be unequal */
if (server_identitykey)
- tor_assert(0!=crypto_pk_cmp_keys(client_identitykey,
- server_identitykey));
+ tor_assert(0!=crypto_pk_cmp_keys(client_identitykey,
+ server_identitykey));
}
}
@@@ -849,21 -847,18 +849,21 @@@ decide_to_advertise_dirport(or_options_
void
consider_testing_reachability(int test_or, int test_dir)
{
- routerinfo_t *me = router_get_my_routerinfo();
+ const routerinfo_t *me = router_get_my_routerinfo();
int orport_reachable = check_whether_orport_reachable();
tor_addr_t addr;
if (!me)
return;
if (test_or && (!orport_reachable || !circuit_enough_testing_circs())) {
+ extend_info_t *ei;
log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.",
!orport_reachable ? "reachability" : "bandwidth",
me->address, me->or_port);
- circuit_launch_by_router(CIRCUIT_PURPOSE_TESTING, me,
- CIRCLAUNCH_NEED_CAPACITY|CIRCLAUNCH_IS_INTERNAL);
+ ei = extend_info_from_router(me);
+ circuit_launch_by_extend_info(CIRCUIT_PURPOSE_TESTING, ei,
+ CIRCLAUNCH_NEED_CAPACITY|CIRCLAUNCH_IS_INTERNAL);
+ extend_info_free(ei);
}
tor_addr_from_ipv4h(&addr, me->addr);
@@@ -886,19 -881,14 +886,14 @@@
void
router_orport_found_reachable(void)
{
- if (!can_reach_or_port) {
- const routerinfo_t *me = router_get_my_routerinfo();
- routerinfo_t *me = router_get_my_routerinfo();
++ const routerinfo_t *me = router_get_my_routerinfo();
+ if (!can_reach_or_port && me) {
log_notice(LD_OR,"Self-testing indicates your ORPort is reachable from "
"the outside. Excellent.%s",
get_options()->_PublishServerDescriptor != NO_AUTHORITY ?
" Publishing server descriptor." : "");
can_reach_or_port = 1;
mark_my_descriptor_dirty();
- if (!me) { /* should never happen */
- log_warn(LD_BUG, "ORPort found reachable, but I have no routerinfo "
- "yet. Failing to inform controller of success.");
- return;
- }
control_event_server_status(LOG_NOTICE,
"REACHABILITY_SUCCEEDED ORADDRESS=%s:%d",
me->address, me->or_port);
@@@ -909,18 -899,13 +904,13 @@@
void
router_dirport_found_reachable(void)
{
- if (!can_reach_dir_port) {
- const routerinfo_t *me = router_get_my_routerinfo();
- routerinfo_t *me = router_get_my_routerinfo();
++ const routerinfo_t *me = router_get_my_routerinfo();
+ if (!can_reach_dir_port && me) {
log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable "
"from the outside. Excellent.");
can_reach_dir_port = 1;
- if (!me || decide_to_advertise_dirport(get_options(), me->dir_port))
+ if (decide_to_advertise_dirport(get_options(), me->dir_port))
mark_my_descriptor_dirty();
- if (!me) { /* should never happen */
- log_warn(LD_BUG, "DirPort found reachable, but I have no routerinfo "
- "yet. Failing to inform controller of success.");
- return;
- }
control_event_server_status(LOG_NOTICE,
"REACHABILITY_SUCCEEDED DIRADDRESS=%s:%d",
me->address, me->dir_port);
@@@ -1181,7 -1166,7 +1171,7 @@@ static int desc_needs_upload = 0
void
router_upload_dir_desc_to_dirservers(int force)
{
- routerinfo_t *ri;
+ const routerinfo_t *ri;
extrainfo_t *ei;
char *msg;
size_t desc_len, extra_len = 0, total_len;
@@@ -1275,7 -1260,7 +1265,7 @@@ router_extrainfo_digest_is_me(const cha
/** A wrapper around router_digest_is_me(). */
int
-router_is_me(routerinfo_t *router)
+router_is_me(const routerinfo_t *router)
{
return router_digest_is_me(router->cache_info.identity_digest);
}
@@@ -1294,7 -1279,7 +1284,7 @@@ router_fingerprint_is_me(const char *fp
/** Return a routerinfo for this OR, rebuilding a fresh one if
* necessary. Return NULL on error, or if called on an OP. */
-routerinfo_t *
+const routerinfo_t *
router_get_my_routerinfo(void)
{
if (!server_mode(get_options()))
@@@ -1346,6 -1331,8 +1336,6 @@@ static int router_guess_address_from_di
int
router_pick_published_address(or_options_t *options, uint32_t *addr)
{
- char buf[INET_NTOA_BUF_LEN];
- struct in_addr a;
if (resolve_my_address(LOG_INFO, options, addr, NULL) < 0) {
log_info(LD_CONFIG, "Could not determine our address locally. "
"Checking if directory headers provide any hints.");
@@@ -1355,7 -1342,9 +1345,7 @@@
return -1;
}
}
- a.s_addr = htonl(*addr);
- tor_inet_ntoa(&a, buf, sizeof(buf));
- log_info(LD_CONFIG,"Success: chose address '%s'.", buf);
+ log_info(LD_CONFIG,"Success: chose address '%s'.", fmt_addr32(*addr));
return 0;
}
@@@ -1422,12 -1411,13 +1412,12 @@@ router_rebuild_descriptor(int force
ri->policy_is_reject_star =
policy_is_reject_star(ri->exit_policy);
- if (desc_routerinfo) { /* inherit values */
- ri->is_valid = desc_routerinfo->is_valid;
- ri->is_running = desc_routerinfo->is_running;
- ri->is_named = desc_routerinfo->is_named;
- }
+#if 0
+ /* XXXX NM NM I belive this is safe to remove */
if (authdir_mode(options))
ri->is_valid = ri->is_named = 1; /* believe in yourself */
+#endif
+
if (options->MyFamily) {
smartlist_t *family;
if (!warned_nonexistent_family)
@@@ -1436,12 -1426,13 +1426,12 @@@
ri->declared_family = smartlist_create();
smartlist_split_string(family, options->MyFamily, ",",
SPLIT_SKIP_SPACE|SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- SMARTLIST_FOREACH(family, char *, name,
- {
- routerinfo_t *member;
+ SMARTLIST_FOREACH_BEGIN(family, char *, name) {
+ const node_t *member;
if (!strcasecmp(name, options->Nickname))
- member = ri;
+ goto skip; /* Don't list ourself, that's redundant */
else
- member = router_get_by_nickname(name, 1);
+ member = node_get_by_nickname(name, 1);
if (!member) {
int is_legal = is_legal_nickname_or_hexdigest(name);
if (!smartlist_string_isin(warned_nonexistent_family, name) &&
@@@ -1461,21 -1452,19 +1451,21 @@@
smartlist_add(ri->declared_family, name);
name = NULL;
}
- } else if (router_is_me(member)) {
+ } else if (router_digest_is_me(member->identity)) {
/* Don't list ourself in our own family; that's redundant */
+ /* XXX shouldn't be possible */
} else {
char *fp = tor_malloc(HEX_DIGEST_LEN+2);
fp[0] = '$';
base16_encode(fp+1,HEX_DIGEST_LEN+1,
- member->cache_info.identity_digest, DIGEST_LEN);
+ member->identity, DIGEST_LEN);
smartlist_add(ri->declared_family, fp);
if (smartlist_string_isin(warned_nonexistent_family, name))
smartlist_string_remove(warned_nonexistent_family, name);
}
+ skip:
tor_free(name);
- });
+ } SMARTLIST_FOREACH_END(name);
/* remove duplicates from the list */
smartlist_sort_strings(ri->declared_family);
@@@ -1536,6 -1525,8 +1526,6 @@@
strlen(ri->cache_info.signed_descriptor_body),
ri->cache_info.signed_descriptor_digest);
- routerinfo_set_country(ri);
-
if (ei) {
tor_assert(! routerinfo_incompatible_with_extrainfo(ri, ei, NULL, NULL));
}
@@@ -2026,12 -2017,6 +2016,12 @@@ extrainfo_dump_to_string(char **s_out,
tor_free(bandwidth_usage);
smartlist_add(chunks, pre);
+ if (geoip_is_loaded()) {
+ char *chunk=NULL;
+ tor_asprintf(&chunk, "geoip-db-digest %s\n", geoip_db_digest());
+ smartlist_add(chunks, chunk);
+ }
+
if (options->ExtraInfoStatistics && write_stats_to_extrainfo) {
log_info(LD_GENERAL, "Adding stats to extra-info descriptor.");
if (options->DirReqStatistics &&
@@@ -2054,11 -2039,6 +2044,11 @@@
"exit-stats-end", now, &contents) > 0) {
smartlist_add(chunks, contents);
}
+ if (options->ConnDirectionStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"conn-stats",
+ "conn-bi-direct", now, &contents) > 0) {
+ smartlist_add(chunks, contents);
+ }
}
if (should_record_bridge_info(options) && write_stats_to_extrainfo) {
@@@ -2197,15 -2177,10 +2187,15 @@@ is_legal_hexdigest(const char *s
void
router_get_verbose_nickname(char *buf, const routerinfo_t *router)
{
+ const char *good_digest = networkstatus_get_router_digest_by_nickname(
+ router->nickname);
+ int is_named = good_digest && !memcmp(good_digest,
+ router->cache_info.identity_digest,
+ DIGEST_LEN);
buf[0] = '$';
base16_encode(buf+1, HEX_DIGEST_LEN+1, router->cache_info.identity_digest,
DIGEST_LEN);
- buf[1+HEX_DIGEST_LEN] = router->is_named ? '=' : '~';
+ buf[1+HEX_DIGEST_LEN] = is_named ? '=' : '~';
strlcpy(buf+1+HEX_DIGEST_LEN+1, router->nickname, MAX_NICKNAME_LEN+1);
}
1
0

14 Mar '11
commit 72b89c96bff877b5097c5e831d5469086d28c24c
Author: Roger Dingledine <arma(a)torproject.org>
Date: Sun Mar 13 16:56:41 2011 -0400
fix two issues pointed out by nickm
---
src/or/or.h | 1 +
src/or/routerlist.c | 6 ++++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/or/or.h b/src/or/or.h
index 752de21..e899f60 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3499,6 +3499,7 @@ typedef enum was_router_added_t {
ROUTER_NOT_IN_CONSENSUS = -3,
ROUTER_NOT_IN_CONSENSUS_OR_NETWORKSTATUS = -4,
ROUTER_AUTHDIR_REJECTS = -5,
+ ROUTER_WAS_NOT_WANTED = -6
} was_router_added_t;
/********************************* routerparse.c ************************/
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index bbd08f3..4421d5c 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -3209,7 +3209,8 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
int from_cache, int from_fetch)
{
const char *id_digest;
- int authdir = authdir_mode_handles_descs(get_options(), router->purpose);
+ or_options_t *options = get_options();
+ int authdir = authdir_mode_handles_descs(options, router->purpose);
int authdir_believes_valid = 0;
routerinfo_t *old_router;
networkstatus_t *consensus = networkstatus_get_latest_consensus();
@@ -3319,12 +3320,13 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
* descriptor. Otherwise we could end up using it as one of our entry
* guards even if it isn't in our Bridge config lines. */
if (router->purpose == ROUTER_PURPOSE_BRIDGE && from_cache &&
+ !authdir_mode_bridge(options) &&
!routerinfo_is_a_configured_bridge(router)) {
log_info(LD_DIR, "Dropping bridge descriptor for '%s' because we have "
"no bridge configured at that address.", router->nickname);
*msg = "Router descriptor was not a configured bridge.";
routerinfo_free(router);
- return ROUTER_WAS_NOT_NEW;
+ return ROUTER_WAS_NOT_WANTED;
}
/* If we have a router with the same identity key, choose the newer one. */
1
0

[tor/release-0.2.2] Merge remote branch 'arma/bug2716' into maint-0.2.2
by arma@torproject.org 14 Mar '11
by arma@torproject.org 14 Mar '11
14 Mar '11
commit b639add1a010d5816ceb693c68ddc3b48655b752
Merge: d34a5cd 61f648a
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Mon Mar 14 15:29:02 2011 -0400
Merge remote branch 'arma/bug2716' into maint-0.2.2
changes/bug2716 | 5 +++++
src/or/dirserv.c | 22 ++++++++++++++++------
src/or/dirserv.h | 12 ++++++++++++
src/or/main.c | 7 +++++--
4 files changed, 38 insertions(+), 8 deletions(-)
diff --combined src/or/dirserv.c
index 40136a1,09da66d..18abd18
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@@ -43,8 -43,6 +43,8 @@@
extern time_t time_of_process_start; /* from main.c */
+extern long stats_n_seconds_working; /* from main.c */
+
/** Do we need to regenerate the v1 directory when someone asks for it? */
static time_t the_directory_is_dirty = 1;
/** Do we need to regenerate the v1 runningrouters document when somebody
@@@ -971,8 -969,18 +971,18 @@@ dirserv_set_router_is_running(routerinf
}
if (!answer && running_long_enough_to_decide_unreachable()) {
- /* not considered reachable. tell rephist. */
- rep_hist_note_router_unreachable(router->cache_info.identity_digest, now);
+ /* Not considered reachable. tell rephist about that.
+
+ Because we launch a reachability test for each router every
+ REACHABILITY_TEST_CYCLE_PERIOD seconds, then the router has probably
+ been down since at least that time after we last successfully reached
+ it.
+ */
+ time_t when = now;
+ if (router->last_reachable &&
+ router->last_reachable + REACHABILITY_TEST_CYCLE_PERIOD < now)
+ when = router->last_reachable + REACHABILITY_TEST_CYCLE_PERIOD;
+ rep_hist_note_router_unreachable(router->cache_info.identity_digest, when);
}
router->is_running = answer;
@@@ -1777,22 -1785,7 +1787,22 @@@ dirserv_thinks_router_is_unreliable(tim
static int
dirserv_thinks_router_is_hs_dir(routerinfo_t *router, time_t now)
{
- long uptime = real_uptime(router, now);
+
+ long uptime;
+
+ /* If we haven't been running for at least
+ * get_options()->MinUptimeHidServDirectoryV2 seconds, we can't
+ * have accurate data telling us a relay has been up for at least
+ * that long. We also want to allow a bit of slack: Reachability
+ * tests aren't instant. If we haven't been running long enough,
+ * trust the relay. */
+
+ if (stats_n_seconds_working >
+ get_options()->MinUptimeHidServDirectoryV2 * 1.1)
+ uptime = MIN(rep_hist_get_uptime(router->cache_info.identity_digest, now),
+ real_uptime(router, now));
+ else
+ uptime = real_uptime(router, now);
/* XXX We shouldn't need to check dir_port, but we do because of
* bug 1693. In the future, once relays set wants_to_be_hs_dir
@@@ -3204,8 -3197,8 +3214,8 @@@ dirserv_single_reachability_test(time_
* try a few connections per call.
*
* The load balancing is such that if we get called once every ten
- * seconds, we will cycle through all the tests in 1280 seconds (a
- * bit over 20 minutes).
+ * seconds, we will cycle through all the tests in
+ * REACHABILITY_TEST_CYCLE_PERIOD seconds (a bit over 20 minutes).
*/
void
dirserv_test_reachability(time_t now)
@@@ -3231,11 -3224,11 +3241,11 @@@
continue; /* bridge authorities only test reachability on bridges */
// if (router->cache_info.published_on > cutoff)
// continue;
- if ((((uint8_t)id_digest[0]) % 128) == ctr) {
+ if ((((uint8_t)id_digest[0]) % REACHABILITY_MODULO_PER_TEST) == ctr) {
dirserv_single_reachability_test(now, router);
}
} SMARTLIST_FOREACH_END(router);
- ctr = (ctr + 1) % 128; /* increment ctr */
+ ctr = (ctr + 1) % REACHABILITY_MODULO_PER_TEST; /* increment ctr */
}
/** Given a fingerprint <b>fp</b> which is either set if we're looking for a
1
0

14 Mar '11
commit cb101c48155729fa05cef2f255d1de0ad40d6b72
Merge: 7d2a91f 72b89c9
Author: Roger Dingledine <arma(a)torproject.org>
Date: Mon Mar 14 15:52:53 2011 -0400
Merge branch 'bug2511' into bug2510
src/or/or.h | 1 +
src/or/routerlist.c | 6 ++++--
2 files changed, 5 insertions(+), 2 deletions(-)
1
0

[tor/release-0.2.2] Merge remote branch 'arma/bug2510' into maint-0.2.2
by arma@torproject.org 14 Mar '11
by arma@torproject.org 14 Mar '11
14 Mar '11
commit 0588330c1d66960353c412812d1d073fdb37e310
Merge: b639add cb101c4
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Mon Mar 14 16:14:54 2011 -0400
Merge remote branch 'arma/bug2510' into maint-0.2.2
changes/bug2510 | 8 ++++++++
changes/bug2511 | 6 ++++++
src/or/circuitbuild.c | 25 +++++++++++++++++++++++++
src/or/or.h | 1 +
src/or/routerlist.c | 17 ++++++++++++++++-
5 files changed, 56 insertions(+), 1 deletions(-)
diff --combined src/or/circuitbuild.c
index 6be27d2,d1cb547..a54f232
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@@ -4063,6 -4063,7 +4063,6 @@@ choose_random_entry(cpath_build_state_
int preferred_min, consider_exit_family = 0;
if (chosen_exit) {
- smartlist_add(exit_family, chosen_exit);
routerlist_add_family(exit_family, chosen_exit);
consider_exit_family = 1;
}
@@@ -4085,8 -4086,6 +4085,8 @@@
r = entry_is_live(entry, need_uptime, need_capacity, 0, &msg);
if (!r)
continue; /* down, no point */
+ if (r == chosen_exit)
+ continue; /* don't pick the same node for entry and exit */
if (consider_exit_family && smartlist_isin(exit_family, r))
continue; /* avoid relays that are family members of our exit */
if (options->EntryNodes &&
@@@ -4671,6 -4670,29 +4671,29 @@@ fetch_bridge_descriptors(or_options_t *
SMARTLIST_FOREACH_END(bridge);
}
+ /** If our <b>bridge</b> is configured to be a different address than
+ * the bridge gives in its routerinfo <b>ri</b>, rewrite the routerinfo
+ * we received to use the address we meant to use. Now we handle
+ * multihomed bridges better.
+ */
+ static void
+ rewrite_routerinfo_address_for_bridge(bridge_info_t *bridge, routerinfo_t *ri)
+ {
+ tor_addr_t addr;
+ tor_addr_from_ipv4h(&addr, ri->addr);
+
+ if (!tor_addr_compare(&bridge->addr, &addr, CMP_EXACT) &&
+ bridge->port == ri->or_port)
+ return; /* they match, so no need to do anything */
+
+ ri->addr = tor_addr_to_ipv4h(&bridge->addr);
+ tor_free(ri->address);
+ ri->address = tor_dup_ip(ri->addr);
+ ri->or_port = bridge->port;
+ log_info(LD_DIR, "Adjusted bridge '%s' to match configured address %s:%d.",
+ ri->nickname, ri->address, ri->or_port);
+ }
+
/** We just learned a descriptor for a bridge. See if that
* digest is in our entry guard list, and add it if not. */
void
@@@ -4689,6 -4711,8 +4712,8 @@@ learned_bridge_descriptor(routerinfo_t
if (!from_cache)
download_status_reset(&bridge->fetch_status);
+ rewrite_routerinfo_address_for_bridge(bridge, ri);
+
add_an_entry_guard(ri, 1);
log_notice(LD_DIR, "new bridge descriptor '%s' (%s)", ri->nickname,
from_cache ? "cached" : "fresh");
@@@ -4728,8 -4752,7 +4753,8 @@@ any_pending_bridge_descriptor_fetches(v
conn->purpose == DIR_PURPOSE_FETCH_SERVERDESC &&
TO_DIR_CONN(conn)->router_purpose == ROUTER_PURPOSE_BRIDGE &&
!conn->marked_for_close &&
- conn->linked && !conn->linked_conn->marked_for_close) {
+ conn->linked &&
+ conn->linked_conn && !conn->linked_conn->marked_for_close) {
log_debug(LD_DIR, "found one: %s", conn->address);
return 1;
}
diff --combined src/or/or.h
index 3ce1425,e899f60..910bf8d
--- a/src/or/or.h
+++ b/src/or/or.h
@@@ -2345,9 -2345,6 +2345,9 @@@ typedef struct
config_line_t *Logs; /**< New-style list of configuration lines
* for logs */
+ int LogMessageDomains; /**< Boolean: Should we log the domain(s) in which
+ * each log message occurs? */
+
char *DebugLogFile; /**< Where to send verbose log messages. */
char *DataDirectory; /**< OR only: where to store long-term data. */
char *Nickname; /**< OR only: nickname of this onion router. */
@@@ -2841,11 -2838,6 +2841,11 @@@
*/
double CircuitPriorityHalflife;
+ /** Set to true if the TestingTorNetwork configuration option is set.
+ * This is used so that options_validate() has a chance to realize that
+ * the defaults have changed. */
+ int _UsingTestNetworkDefaults;
+
} or_options_t;
/** Persistent state for an onion router, as saved to disk. */
@@@ -2877,25 -2869,19 +2877,25 @@@ typedef struct
* bandwidth usage. The "Interval" fields hold the granularity, in seconds,
* of the entries of Values. The "Values" lists hold decimal string
* representations of the number of bytes read or written in each
- * interval. */
+ * interval. The "Maxima" list holds decimal strings describing the highest
+ * rate achieved during the interval.
+ */
time_t BWHistoryReadEnds;
int BWHistoryReadInterval;
smartlist_t *BWHistoryReadValues;
+ smartlist_t *BWHistoryReadMaxima;
time_t BWHistoryWriteEnds;
int BWHistoryWriteInterval;
smartlist_t *BWHistoryWriteValues;
+ smartlist_t *BWHistoryWriteMaxima;
time_t BWHistoryDirReadEnds;
int BWHistoryDirReadInterval;
smartlist_t *BWHistoryDirReadValues;
+ smartlist_t *BWHistoryDirReadMaxima;
time_t BWHistoryDirWriteEnds;
int BWHistoryDirWriteInterval;
smartlist_t *BWHistoryDirWriteValues;
+ smartlist_t *BWHistoryDirWriteMaxima;
/** Build time histogram */
config_line_t * BuildtimeHistogram;
@@@ -3513,6 -3499,7 +3513,7 @@@ typedef enum was_router_added_t
ROUTER_NOT_IN_CONSENSUS = -3,
ROUTER_NOT_IN_CONSENSUS_OR_NETWORKSTATUS = -4,
ROUTER_AUTHDIR_REJECTS = -5,
+ ROUTER_WAS_NOT_WANTED = -6
} was_router_added_t;
/********************************* routerparse.c ************************/
1
0

14 Mar '11
commit 626912a81a9d494d496de38c4fd46e058d9039f2
Merge: af04bd4 b97d9ab
Author: Roger Dingledine <arma(a)torproject.org>
Date: Mon Mar 14 17:21:36 2011 -0400
Merge branch 'maint-0.2.2' into release-0.2.2
changes/bug1172 | 9 +++++++++
changes/bug2510 | 8 ++++++++
changes/bug2511 | 6 ++++++
changes/bug2716 | 5 +++++
changes/hsdir_assignment | 8 ++++++++
src/or/circuitbuild.c | 25 +++++++++++++++++++++++++
src/or/dirserv.c | 41 ++++++++++++++++++++++++++++++++++-------
src/or/dirserv.h | 12 ++++++++++++
src/or/dirvote.c | 2 +-
src/or/main.c | 7 +++++--
src/or/or.h | 1 +
src/or/rephist.c | 14 ++++++++++++++
src/or/rephist.h | 1 +
src/or/router.c | 20 +++++---------------
src/or/routerlist.c | 17 ++++++++++++++++-
15 files changed, 150 insertions(+), 26 deletions(-)
1
0

[tor/release-0.2.2] Merge remote branch 'origin/maint-0.2.1' into maint-0.2.2
by arma@torproject.org 14 Mar '11
by arma@torproject.org 14 Mar '11
14 Mar '11
commit b97d9abd0940037b249a1ee56724dbfed904263b
Merge: 0588330 1a9d19e
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Mon Mar 14 17:04:53 2011 -0400
Merge remote branch 'origin/maint-0.2.1' into maint-0.2.2
changes/bug1172 | 9 +++++++++
src/or/router.c | 20 +++++---------------
2 files changed, 14 insertions(+), 15 deletions(-)
diff --combined src/or/router.c
index 4c5eb7a,ba7be3d..c15b9b2
--- a/src/or/router.c
+++ b/src/or/router.c
@@@ -7,24 -7,6 +7,24 @@@
#define ROUTER_PRIVATE
#include "or.h"
+#include "circuitlist.h"
+#include "circuituse.h"
+#include "config.h"
+#include "connection.h"
+#include "control.h"
+#include "directory.h"
+#include "dirserv.h"
+#include "dns.h"
+#include "geoip.h"
+#include "hibernate.h"
+#include "main.h"
+#include "networkstatus.h"
+#include "policies.h"
+#include "relay.h"
+#include "rephist.h"
+#include "router.h"
+#include "routerlist.h"
+#include "routerparse.h"
/**
* \file router.c
@@@ -49,15 -31,11 +49,15 @@@ static crypto_pk_env_t *onionkey=NULL
/** Previous private onionskin decryption key: used to decode CREATE cells
* generated by clients that have an older version of our descriptor. */
static crypto_pk_env_t *lastonionkey=NULL;
-/** Private "identity key": used to sign directory info and TLS
+/** Private server "identity key": used to sign directory info and TLS
* certificates. Never changes. */
-static crypto_pk_env_t *identitykey=NULL;
-/** Digest of identitykey. */
-static char identitykey_digest[DIGEST_LEN];
+static crypto_pk_env_t *server_identitykey=NULL;
+/** Digest of server_identitykey. */
+static char server_identitykey_digest[DIGEST_LEN];
+/** Private client "identity key": used to sign bridges' and clients'
+ * outbound TLS certificates. Regenerated on startup and on IP address
+ * change. */
+static crypto_pk_env_t *client_identitykey=NULL;
/** Signing key used for v3 directory material; only set for authorities. */
static crypto_pk_env_t *authority_signing_key = NULL;
/** Key certificate to authenticate v3 directory material; only set for
@@@ -83,7 -61,8 +83,7 @@@ static voi
set_onion_key(crypto_pk_env_t *k)
{
tor_mutex_acquire(key_lock);
- if (onionkey)
- crypto_free_pk_env(onionkey);
+ crypto_free_pk_env(onionkey);
onionkey = k;
onionkey_set_at = time(NULL);
tor_mutex_release(key_lock);
@@@ -127,78 -106,32 +127,78 @@@ get_onion_key_set_at(void
return onionkey_set_at;
}
-/** Set the current identity key to k.
+/** Set the current server identity key to <b>k</b>.
*/
void
-set_identity_key(crypto_pk_env_t *k)
+set_server_identity_key(crypto_pk_env_t *k)
{
- if (identitykey)
- crypto_free_pk_env(identitykey);
- identitykey = k;
- crypto_pk_get_digest(identitykey, identitykey_digest);
+ crypto_free_pk_env(server_identitykey);
+ server_identitykey = k;
+ crypto_pk_get_digest(server_identitykey, server_identitykey_digest);
}
-/** Returns the current identity key; requires that the identity key has been
- * set.
+/** Make sure that we have set up our identity keys to match or not match as
+ * appropriate, and die with an assertion if we have not. */
+static void
+assert_identity_keys_ok(void)
+{
+ tor_assert(client_identitykey);
+ if (public_server_mode(get_options())) {
+ /* assert that we have set the client and server keys to be equal */
+ tor_assert(server_identitykey);
+ tor_assert(0==crypto_pk_cmp_keys(client_identitykey, server_identitykey));
+ } else {
+ /* assert that we have set the client and server keys to be unequal */
+ if (server_identitykey)
+ tor_assert(0!=crypto_pk_cmp_keys(client_identitykey,
+ server_identitykey));
+ }
+}
+
+/** Returns the current server identity key; requires that the key has
+ * been set, and that we are running as a Tor server.
*/
crypto_pk_env_t *
-get_identity_key(void)
+get_server_identity_key(void)
{
- tor_assert(identitykey);
- return identitykey;
+ tor_assert(server_identitykey);
+ tor_assert(server_mode(get_options()));
+ assert_identity_keys_ok();
+ return server_identitykey;
}
-/** Return true iff the identity key has been set. */
+/** Return true iff the server identity key has been set. */
int
-identity_key_is_set(void)
+server_identity_key_is_set(void)
{
- return identitykey != NULL;
+ return server_identitykey != NULL;
+}
+
+/** Set the current client identity key to <b>k</b>.
+ */
+void
+set_client_identity_key(crypto_pk_env_t *k)
+{
+ crypto_free_pk_env(client_identitykey);
+ client_identitykey = k;
+}
+
+/** Returns the current client identity key for use on outgoing TLS
+ * connections; requires that the key has been set.
+ */
+crypto_pk_env_t *
+get_tlsclient_identity_key(void)
+{
+ tor_assert(client_identitykey);
+ assert_identity_keys_ok();
+ return client_identitykey;
+}
+
+/** Return true iff the client identity key has been set. */
+int
+client_identity_key_is_set(void)
+{
+ return client_identitykey != NULL;
}
/** Return the key certificate for this v3 (voting) authority, or NULL
@@@ -268,7 -201,8 +268,7 @@@ rotate_onion_key(void
}
log_info(LD_GENERAL, "Rotating onion key");
tor_mutex_acquire(key_lock);
- if (lastonionkey)
- crypto_free_pk_env(lastonionkey);
+ crypto_free_pk_env(lastonionkey);
lastonionkey = onionkey;
onionkey = prkey;
now = time(NULL);
@@@ -397,9 -331,10 +397,9 @@@ load_authority_keyset(int legacy, crypt
goto done;
}
- if (*key_out)
- crypto_free_pk_env(*key_out);
- if (*cert_out)
- authority_cert_free(*cert_out);
+ crypto_free_pk_env(*key_out);
+ authority_cert_free(*cert_out);
+
*key_out = signing_key;
*cert_out = parsed;
r = 0;
@@@ -409,8 -344,10 +409,8 @@@
done:
tor_free(fname);
tor_free(cert);
- if (signing_key)
- crypto_free_pk_env(signing_key);
- if (parsed)
- authority_cert_free(parsed);
+ crypto_free_pk_env(signing_key);
+ authority_cert_free(parsed);
return r;
}
@@@ -505,9 -442,7 +505,9 @@@ init_keys(void
key_lock = tor_mutex_new();
/* There are a couple of paths that put us here before */
- if (crypto_global_init(get_options()->HardwareAccel)) {
+ if (crypto_global_init(get_options()->HardwareAccel,
+ get_options()->AccelName,
+ get_options()->AccelDir)) {
log_err(LD_BUG, "Unable to initialize OpenSSL. Exiting.");
return -1;
}
@@@ -521,12 -456,9 +521,12 @@@
crypto_free_pk_env(prkey);
return -1;
}
- set_identity_key(prkey);
- /* Create a TLS context; default the client nickname to "client". */
- if (tor_tls_context_new(get_identity_key(), MAX_SSL_KEY_LIFETIME) < 0) {
+ set_client_identity_key(prkey);
+ /* Create a TLS context. */
+ if (tor_tls_context_init(0,
+ get_tlsclient_identity_key(),
+ NULL,
+ MAX_SSL_KEY_LIFETIME) < 0) {
log_err(LD_GENERAL,"Error creating TLS context for Tor client.");
return -1;
}
@@@ -561,28 -493,13 +561,28 @@@
}
}
- /* 1. Read identity key. Make it if none is found. */
+ /* 1b. Read identity key. Make it if none is found. */
keydir = get_datadir_fname2("keys", "secret_id_key");
log_info(LD_GENERAL,"Reading/making identity key \"%s\"...",keydir);
prkey = init_key_from_file(keydir, 1, LOG_ERR);
tor_free(keydir);
if (!prkey) return -1;
- set_identity_key(prkey);
+ set_server_identity_key(prkey);
+
+ /* 1c. If we are configured as a bridge, generate a client key;
+ * otherwise, set the server identity key as our client identity
+ * key. */
+ if (public_server_mode(options)) {
+ set_client_identity_key(crypto_pk_dup_key(prkey)); /* set above */
+ } else {
+ if (!(prkey = crypto_new_pk_env()))
+ return -1;
+ if (crypto_pk_generate_key(prkey)) {
+ crypto_free_pk_env(prkey);
+ return -1;
+ }
+ set_client_identity_key(prkey);
+ }
/* 2. Read onion key. Make it if none is found. */
keydir = get_datadir_fname2("keys", "secret_onion_key");
@@@ -619,22 -536,18 +619,22 @@@
tor_free(keydir);
/* 3. Initialize link key and TLS context. */
- if (tor_tls_context_new(get_identity_key(), MAX_SSL_KEY_LIFETIME) < 0) {
+ if (tor_tls_context_init(public_server_mode(options),
+ get_tlsclient_identity_key(),
+ get_server_identity_key(),
+ MAX_SSL_KEY_LIFETIME) < 0) {
log_err(LD_GENERAL,"Error initializing TLS context");
return -1;
}
/* 4. Build our router descriptor. */
/* Must be called after keys are initialized. */
mydesc = router_get_my_descriptor();
- if (authdir_mode(options)) {
+ if (authdir_mode_handles_descs(options, ROUTER_PURPOSE_GENERAL)) {
const char *m = NULL;
routerinfo_t *ri;
/* We need to add our own fingerprint so it gets recognized. */
- if (dirserv_add_own_fingerprint(options->Nickname, get_identity_key())) {
+ if (dirserv_add_own_fingerprint(options->Nickname,
+ get_server_identity_key())) {
log_err(LD_GENERAL,"Error adding own fingerprint to approved set");
return -1;
}
@@@ -655,8 -568,7 +655,8 @@@
/* 5. Dump fingerprint to 'fingerprint' */
keydir = get_datadir_fname("fingerprint");
log_info(LD_GENERAL,"Dumping fingerprint to \"%s\"...",keydir);
- if (crypto_pk_get_fingerprint(get_identity_key(), fingerprint, 0)<0) {
+ if (crypto_pk_get_fingerprint(get_server_identity_key(),
+ fingerprint, 0) < 0) {
log_err(LD_GENERAL,"Error computing fingerprint");
tor_free(keydir);
return -1;
@@@ -694,7 -606,7 +694,7 @@@
return -1;
}
/* 6b. [authdirserver only] add own key to approved directories. */
- crypto_pk_get_digest(get_identity_key(), digest);
+ crypto_pk_get_digest(get_server_identity_key(), digest);
type = ((options->V1AuthoritativeDir ? V1_AUTHORITY : NO_AUTHORITY) |
(options->V2AuthoritativeDir ? V2_AUTHORITY : NO_AUTHORITY) |
(options->V3AuthoritativeDir ? V3_AUTHORITY : NO_AUTHORITY) |
@@@ -881,19 -793,14 +881,14 @@@ consider_testing_reachability(int test_
void
router_orport_found_reachable(void)
{
- if (!can_reach_or_port) {
- routerinfo_t *me = router_get_my_routerinfo();
+ routerinfo_t *me = router_get_my_routerinfo();
+ if (!can_reach_or_port && me) {
log_notice(LD_OR,"Self-testing indicates your ORPort is reachable from "
"the outside. Excellent.%s",
get_options()->_PublishServerDescriptor != NO_AUTHORITY ?
" Publishing server descriptor." : "");
can_reach_or_port = 1;
mark_my_descriptor_dirty();
- if (!me) { /* should never happen */
- log_warn(LD_BUG, "ORPort found reachable, but I have no routerinfo "
- "yet. Failing to inform controller of success.");
- return;
- }
control_event_server_status(LOG_NOTICE,
"REACHABILITY_SUCCEEDED ORADDRESS=%s:%d",
me->address, me->or_port);
@@@ -904,18 -811,13 +899,13 @@@
void
router_dirport_found_reachable(void)
{
- if (!can_reach_dir_port) {
- routerinfo_t *me = router_get_my_routerinfo();
+ routerinfo_t *me = router_get_my_routerinfo();
+ if (!can_reach_dir_port && me) {
log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable "
"from the outside. Excellent.");
can_reach_dir_port = 1;
- if (!me || decide_to_advertise_dirport(get_options(), me->dir_port))
+ if (decide_to_advertise_dirport(get_options(), me->dir_port))
mark_my_descriptor_dirty();
- if (!me) { /* should never happen */
- log_warn(LD_BUG, "DirPort found reachable, but I have no routerinfo "
- "yet. Failing to inform controller of success.");
- return;
- }
control_event_server_status(LOG_NOTICE,
"REACHABILITY_SUCCEEDED DIRADDRESS=%s:%d",
me->address, me->dir_port);
@@@ -1050,28 -952,6 +1040,28 @@@ server_mode(or_options_t *options
return (options->ORPort != 0 || options->ORListenAddress);
}
+/** Return true iff we are trying to be a non-bridge server.
+ */
+int
+public_server_mode(or_options_t *options)
+{
+ if (!server_mode(options)) return 0;
+ return (!options->BridgeRelay);
+}
+
+/** Return true iff the combination of options in <b>options</b> and parameters
+ * in the consensus mean that we don't want to allow exits from circuits
+ * we got from addresses not known to be servers. */
+int
+should_refuse_unknown_exits(or_options_t *options)
+{
+ if (options->RefuseUnknownExits_ != -1) {
+ return options->RefuseUnknownExits_;
+ } else {
+ return networkstatus_get_param(NULL, "refuseunknownexits", 1, 0, 1);
+ }
+}
+
/** Remember if we've advertised ourselves to the dirservers. */
static int server_is_advertised=0;
@@@ -1099,7 -979,7 +1089,7 @@@ proxy_mode(or_options_t *options
{
return (options->SocksPort != 0 || options->SocksListenAddress ||
options->TransPort != 0 || options->TransListenAddress ||
- options->NatdPort != 0 || options->NatdListenAddress ||
+ options->NATDPort != 0 || options->NATDListenAddress ||
options->DNSPort != 0 || options->DNSListenAddress);
}
@@@ -1234,24 -1114,12 +1224,24 @@@ router_compare_to_my_exit_policy(edge_c
desc_routerinfo->exit_policy) != ADDR_POLICY_ACCEPTED;
}
+/** Return true iff my exit policy is reject *:*. Return -1 if we don't
+ * have a descriptor */
+int
+router_my_exit_policy_is_reject_star(void)
+{
+ if (!router_get_my_routerinfo()) /* make sure desc_routerinfo exists */
+ return -1;
+
+ return desc_routerinfo->policy_is_reject_star;
+}
+
/** Return true iff I'm a server and <b>digest</b> is equal to
- * my identity digest. */
+ * my server identity key digest. */
int
router_digest_is_me(const char *digest)
{
- return identitykey && !memcmp(identitykey_digest, digest, DIGEST_LEN);
+ return (server_identitykey &&
+ !memcmp(server_identitykey_digest, digest, DIGEST_LEN));
}
/** Return true iff I'm a server and <b>digest</b> is equal to
@@@ -1341,8 -1209,6 +1331,8 @@@ static int router_guess_address_from_di
int
router_pick_published_address(or_options_t *options, uint32_t *addr)
{
+ char buf[INET_NTOA_BUF_LEN];
+ struct in_addr a;
if (resolve_my_address(LOG_INFO, options, addr, NULL) < 0) {
log_info(LD_CONFIG, "Could not determine our address locally. "
"Checking if directory headers provide any hints.");
@@@ -1352,9 -1218,6 +1342,9 @@@
return -1;
}
}
+ a.s_addr = htonl(*addr);
+ tor_inet_ntoa(&a, buf, sizeof(buf));
+ log_info(LD_CONFIG,"Success: chose address '%s'.", buf);
return 0;
}
@@@ -1377,7 -1240,7 +1367,7 @@@ router_rebuild_descriptor(int force
if (router_pick_published_address(options, &addr) < 0) {
/* Stop trying to rebuild our descriptor every second. We'll
- * learn that it's time to try again when server_has_changed_ip()
+ * learn that it's time to try again when ip_address_changed()
* marks it dirty. */
desc_clean_since = time(NULL);
return -1;
@@@ -1393,7 -1256,7 +1383,7 @@@
ri->cache_info.published_on = time(NULL);
ri->onion_pkey = crypto_pk_dup_key(get_onion_key()); /* must invoke from
* main thread */
- ri->identity_pkey = crypto_pk_dup_key(get_identity_key());
+ ri->identity_pkey = crypto_pk_dup_key(get_server_identity_key());
if (crypto_pk_get_digest(ri->identity_pkey,
ri->cache_info.identity_digest)<0) {
routerinfo_free(ri);
@@@ -1410,16 -1273,9 +1400,16 @@@
ri->bandwidthcapacity = hibernating ? 0 : rep_hist_bandwidth_assess();
- policies_parse_exit_policy(options->ExitPolicy, &ri->exit_policy,
- options->ExitPolicyRejectPrivate,
- ri->address);
+ if (dns_seems_to_be_broken() || has_dns_init_failed()) {
+ /* DNS is screwed up; don't claim to be an exit. */
+ policies_exit_policy_append_reject_star(&ri->exit_policy);
+ } else {
+ policies_parse_exit_policy(options->ExitPolicy, &ri->exit_policy,
+ options->ExitPolicyRejectPrivate,
+ ri->address, !options->BridgeRelay);
+ }
+ ri->policy_is_reject_star =
+ policy_is_reject_star(ri->exit_policy);
if (desc_routerinfo) { /* inherit values */
ri->is_valid = desc_routerinfo->is_valid;
@@@ -1490,30 -1346,26 +1480,30 @@@
ei->cache_info.published_on = ri->cache_info.published_on;
memcpy(ei->cache_info.identity_digest, ri->cache_info.identity_digest,
DIGEST_LEN);
- ei->cache_info.signed_descriptor_body = tor_malloc(8192);
- if (extrainfo_dump_to_string(ei->cache_info.signed_descriptor_body, 8192,
- ei, get_identity_key()) < 0) {
+ if (extrainfo_dump_to_string(&ei->cache_info.signed_descriptor_body,
+ ei, get_server_identity_key()) < 0) {
log_warn(LD_BUG, "Couldn't generate extra-info descriptor.");
- routerinfo_free(ri);
extrainfo_free(ei);
- return -1;
+ ei = NULL;
+ } else {
+ ei->cache_info.signed_descriptor_len =
+ strlen(ei->cache_info.signed_descriptor_body);
+ router_get_extrainfo_hash(ei->cache_info.signed_descriptor_body,
+ ei->cache_info.signed_descriptor_digest);
}
- ei->cache_info.signed_descriptor_len =
- strlen(ei->cache_info.signed_descriptor_body);
- router_get_extrainfo_hash(ei->cache_info.signed_descriptor_body,
- ei->cache_info.signed_descriptor_digest);
/* Now finish the router descriptor. */
- memcpy(ri->cache_info.extra_info_digest,
- ei->cache_info.signed_descriptor_digest,
- DIGEST_LEN);
+ if (ei) {
+ memcpy(ri->cache_info.extra_info_digest,
+ ei->cache_info.signed_descriptor_digest,
+ DIGEST_LEN);
+ } else {
+ /* ri was allocated with tor_malloc_zero, so there is no need to
+ * zero ri->cache_info.extra_info_digest here. */
+ }
ri->cache_info.signed_descriptor_body = tor_malloc(8192);
if (router_dump_router_to_string(ri->cache_info.signed_descriptor_body, 8192,
- ri, get_identity_key())<0) {
+ ri, get_server_identity_key()) < 0) {
log_warn(LD_BUG, "Couldn't generate router descriptor.");
routerinfo_free(ri);
extrainfo_free(ei);
@@@ -1528,7 -1380,7 +1518,7 @@@
/* Let bridges serve their own descriptors unencrypted, so they can
* pass reachability testing. (If they want to be harder to notice,
* they can always leave the DirPort off). */
- if (!options->BridgeRelay)
+ if (ei && !options->BridgeRelay)
ei->cache_info.send_unencrypted = 1;
router_get_router_hash(ri->cache_info.signed_descriptor_body,
@@@ -1537,13 -1389,13 +1527,13 @@@
routerinfo_set_country(ri);
- tor_assert(! routerinfo_incompatible_with_extrainfo(ri, ei, NULL, NULL));
+ if (ei) {
+ tor_assert(! routerinfo_incompatible_with_extrainfo(ri, ei, NULL, NULL));
+ }
- if (desc_routerinfo)
- routerinfo_free(desc_routerinfo);
+ routerinfo_free(desc_routerinfo);
desc_routerinfo = ri;
- if (desc_extrainfo)
- extrainfo_free(desc_extrainfo);
+ extrainfo_free(desc_extrainfo);
desc_extrainfo = ei;
desc_clean_since = time(NULL);
@@@ -1724,6 -1576,8 +1714,6 @@@ router_guess_address_from_dir_headers(u
return -1;
}
-extern const char tor_svn_revision[]; /* from tor_main.c */
-
/** Set <b>platform</b> (max length <b>len</b>) to a NUL-terminated short
* string describing the version of Tor and the operating system we're
* currently running on.
@@@ -1754,7 -1608,6 +1744,7 @@@ router_dump_router_to_string(char *s, s
char digest[DIGEST_LEN];
char published[ISO_TIME_LEN+1];
char fingerprint[FINGERPRINT_LEN+1];
+ int has_extra_info_digest;
char extra_info_digest[HEX_DIGEST_LEN+1];
size_t onion_pkeylen, identity_pkeylen;
size_t written;
@@@ -1783,7 -1636,7 +1773,7 @@@
return -1;
}
- /* PEM-encode the identity key key */
+ /* PEM-encode the identity key */
if (crypto_pk_write_public_key_to_string(router->identity_pkey,
&identity_pkey,&identity_pkeylen)<0) {
log_warn(LD_BUG,"write identity_pkey to string failed!");
@@@ -1805,13 -1658,8 +1795,13 @@@
family_line = tor_strdup("");
}
- base16_encode(extra_info_digest, sizeof(extra_info_digest),
- router->cache_info.extra_info_digest, DIGEST_LEN);
+ has_extra_info_digest =
+ ! tor_digest_is_zero(router->cache_info.extra_info_digest);
+
+ if (has_extra_info_digest) {
+ base16_encode(extra_info_digest, sizeof(extra_info_digest),
+ router->cache_info.extra_info_digest, DIGEST_LEN);
+ }
/* Generate the easy portion of the router descriptor. */
result = tor_snprintf(s, maxlen,
@@@ -1822,7 -1670,7 +1812,7 @@@
"opt fingerprint %s\n"
"uptime %ld\n"
"bandwidth %d %d %d\n"
- "opt extra-info-digest %s\n%s"
+ "%s%s%s%s"
"onion-key\n%s"
"signing-key\n%s"
"%s%s%s%s",
@@@ -1837,9 -1685,7 +1827,9 @@@
(int) router->bandwidthrate,
(int) router->bandwidthburst,
(int) router->bandwidthcapacity,
- extra_info_digest,
+ has_extra_info_digest ? "opt extra-info-digest " : "",
+ has_extra_info_digest ? extra_info_digest : "",
+ has_extra_info_digest ? "\n" : "",
options->DownloadExtraInfo ? "opt caches-extra-info\n" : "",
onion_pkey, identity_pkey,
family_line,
@@@ -1871,7 -1717,9 +1861,7 @@@
}
/* Write the exit policy to the end of 's'. */
- if (dns_seems_to_be_broken() || has_dns_init_failed() ||
- !router->exit_policy || !smartlist_len(router->exit_policy)) {
- /* DNS is screwed up; don't claim to be an exit. */
+ if (!router->exit_policy || !smartlist_len(router->exit_policy)) {
strlcat(s+written, "reject *:*\n", maxlen-written);
written += strlen("reject *:*\n");
tmpe = NULL;
@@@ -1894,8 -1742,7 +1884,8 @@@
}
}
- if (written+256 > maxlen) { /* Not enough room for signature. */
+ if (written + DIROBJ_MAX_SIG_LEN > maxlen) {
+ /* Not enough room for signature. */
log_warn(LD_BUG,"not enough room left in descriptor for signature!");
return -1;
}
@@@ -1910,7 -1757,7 +1900,7 @@@
note_crypto_pk_op(SIGN_RTR);
if (router_append_dirobj_signature(s+written,maxlen-written,
- digest,ident_key)<0) {
+ digest,DIGEST_LEN,ident_key)<0) {
log_warn(LD_BUG, "Couldn't sign router descriptor");
return -1;
}
@@@ -1945,62 -1792,11 +1935,62 @@@
return (int)written+1;
}
-/** Write the contents of <b>extrainfo</b> to the <b>maxlen</b>-byte string
- * <b>s</b>, signing them with <b>ident_key</b>. Return 0 on success,
- * negative on failure. */
+/** Load the contents of <b>filename</b>, find the last line starting with
+ * <b>end_line</b>, ensure that its timestamp is not more than 25 hours in
+ * the past or more than 1 hour in the future with respect to <b>now</b>,
+ * and write the file contents starting with that line to *<b>out</b>.
+ * Return 1 for success, 0 if the file does not exist, or -1 if the file
+ * does not contain a line matching these criteria or other failure. */
+static int
+load_stats_file(const char *filename, const char *end_line, time_t now,
+ char **out)
+{
+ int r = -1;
+ char *fname = get_datadir_fname(filename);
+ char *contents, *start = NULL, *tmp, timestr[ISO_TIME_LEN+1];
+ time_t written;
+ switch (file_status(fname)) {
+ case FN_FILE:
+ /* X022 Find an alternative to reading the whole file to memory. */
+ if ((contents = read_file_to_str(fname, 0, NULL))) {
+ tmp = strstr(contents, end_line);
+ /* Find last block starting with end_line */
+ while (tmp) {
+ start = tmp;
+ tmp = strstr(tmp + 1, end_line);
+ }
+ if (!start)
+ goto notfound;
+ if (strlen(start) < strlen(end_line) + 1 + sizeof(timestr))
+ goto notfound;
+ strlcpy(timestr, start + 1 + strlen(end_line), sizeof(timestr));
+ if (parse_iso_time(timestr, &written) < 0)
+ goto notfound;
+ if (written < now - (25*60*60) || written > now + (1*60*60))
+ goto notfound;
+ *out = tor_strdup(start);
+ r = 1;
+ }
+ notfound:
+ tor_free(contents);
+ break;
+ case FN_NOENT:
+ r = 0;
+ break;
+ case FN_ERROR:
+ case FN_DIR:
+ default:
+ break;
+ }
+ tor_free(fname);
+ return r;
+}
+
+/** Write the contents of <b>extrainfo</b> and aggregated statistics to
+ * *<b>s_out</b>, signing them with <b>ident_key</b>. Return 0 on
+ * success, negative on failure. */
int
-extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
+extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo,
crypto_pk_env_t *ident_key)
{
or_options_t *options = get_options();
@@@ -2009,128 -1805,87 +1999,128 @@@
char digest[DIGEST_LEN];
char *bandwidth_usage;
int result;
- size_t len;
+ static int write_stats_to_extrainfo = 1;
+ char sig[DIROBJ_MAX_SIG_LEN+1];
+ char *s, *pre, *contents, *cp, *s_dup = NULL;
+ time_t now = time(NULL);
+ smartlist_t *chunks = smartlist_create();
+ extrainfo_t *ei_tmp = NULL;
base16_encode(identity, sizeof(identity),
extrainfo->cache_info.identity_digest, DIGEST_LEN);
format_iso_time(published, extrainfo->cache_info.published_on);
- bandwidth_usage = rep_hist_get_bandwidth_lines(1);
+ bandwidth_usage = rep_hist_get_bandwidth_lines();
- result = tor_snprintf(s, maxlen,
- "extra-info %s %s\n"
- "published %s\n%s",
- extrainfo->nickname, identity,
- published, bandwidth_usage);
+ tor_asprintf(&pre, "extra-info %s %s\npublished %s\n%s",
+ extrainfo->nickname, identity,
+ published, bandwidth_usage);
tor_free(bandwidth_usage);
- if (result<0)
- return -1;
+ smartlist_add(chunks, pre);
+
+ if (options->ExtraInfoStatistics && write_stats_to_extrainfo) {
+ log_info(LD_GENERAL, "Adding stats to extra-info descriptor.");
+ if (options->DirReqStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"dirreq-stats",
+ "dirreq-stats-end", now, &contents) > 0) {
+ smartlist_add(chunks, contents);
+ }
+ if (options->EntryStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"entry-stats",
+ "entry-stats-end", now, &contents) > 0) {
+ smartlist_add(chunks, contents);
+ }
+ if (options->CellStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"buffer-stats",
+ "cell-stats-end", now, &contents) > 0) {
+ smartlist_add(chunks, contents);
+ }
+ if (options->ExitPortStatistics &&
+ load_stats_file("stats"PATH_SEPARATOR"exit-stats",
+ "exit-stats-end", now, &contents) > 0) {
+ smartlist_add(chunks, contents);
+ }
+ }
- if (should_record_bridge_info(options)) {
- char *geoip_summary = extrainfo_get_client_geoip_summary(time(NULL));
- if (geoip_summary) {
- char geoip_start[ISO_TIME_LEN+1];
- format_iso_time(geoip_start, geoip_get_history_start());
- result = tor_snprintf(s+strlen(s), maxlen-strlen(s),
- "geoip-start-time %s\n"
- "geoip-client-origins %s\n",
- geoip_start, geoip_summary);
- control_event_clients_seen(geoip_start, geoip_summary);
- tor_free(geoip_summary);
- if (result<0)
- return -1;
+ if (should_record_bridge_info(options) && write_stats_to_extrainfo) {
+ const char *bridge_stats = geoip_get_bridge_stats_extrainfo(now);
+ if (bridge_stats) {
+ smartlist_add(chunks, tor_strdup(bridge_stats));
}
}
- len = strlen(s);
- strlcat(s+len, "router-signature\n", maxlen-len);
- len += strlen(s+len);
- if (router_get_extrainfo_hash(s, digest)<0)
- return -1;
- if (router_append_dirobj_signature(s+len, maxlen-len, digest, ident_key)<0)
- return -1;
+ smartlist_add(chunks, tor_strdup("router-signature\n"));
+ s = smartlist_join_strings(chunks, "", 0, NULL);
+
+ while (strlen(s) > MAX_EXTRAINFO_UPLOAD_SIZE - DIROBJ_MAX_SIG_LEN) {
+ /* So long as there are at least two chunks (one for the initial
+ * extra-info line and one for the router-signature), we can keep removing
+ * things. */
+ if (smartlist_len(chunks) > 2) {
+ /* We remove the next-to-last element (remember, len-1 is the last
+ element), since we need to keep the router-signature element. */
+ int idx = smartlist_len(chunks) - 2;
+ char *e = smartlist_get(chunks, idx);
+ smartlist_del_keeporder(chunks, idx);
+ log_warn(LD_GENERAL, "We just generated an extra-info descriptor "
+ "with statistics that exceeds the 50 KB "
+ "upload limit. Removing last added "
+ "statistics.");
+ tor_free(e);
+ tor_free(s);
+ s = smartlist_join_strings(chunks, "", 0, NULL);
+ } else {
+ log_warn(LD_BUG, "We just generated an extra-info descriptors that "
+ "exceeds the 50 KB upload limit.");
+ goto err;
+ }
+ }
-#ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
- {
- char *cp, *s_dup;
- extrainfo_t *ei_tmp;
- cp = s_dup = tor_strdup(s);
- ei_tmp = extrainfo_parse_entry_from_string(cp, NULL, 1, NULL);
- if (!ei_tmp) {
- log_err(LD_BUG,
- "We just generated an extrainfo descriptor we can't parse.");
- log_err(LD_BUG, "Descriptor was: <<%s>>", s);
- tor_free(s_dup);
- return -1;
+ memset(sig, 0, sizeof(sig));
+ if (router_get_extrainfo_hash(s, digest) < 0 ||
+ router_append_dirobj_signature(sig, sizeof(sig), digest, DIGEST_LEN,
+ ident_key) < 0) {
+ log_warn(LD_BUG, "Could not append signature to extra-info "
+ "descriptor.");
+ goto err;
+ }
+ smartlist_add(chunks, tor_strdup(sig));
+ tor_free(s);
+ s = smartlist_join_strings(chunks, "", 0, NULL);
+
+ cp = s_dup = tor_strdup(s);
+ ei_tmp = extrainfo_parse_entry_from_string(cp, NULL, 1, NULL);
+ if (!ei_tmp) {
+ if (write_stats_to_extrainfo) {
+ log_warn(LD_GENERAL, "We just generated an extra-info descriptor "
+ "with statistics that we can't parse. Not "
+ "adding statistics to this or any future "
+ "extra-info descriptors.");
+ write_stats_to_extrainfo = 0;
+ result = extrainfo_dump_to_string(s_out, extrainfo, ident_key);
+ goto done;
+ } else {
+ log_warn(LD_BUG, "We just generated an extrainfo descriptor we "
+ "can't parse.");
+ goto err;
}
- tor_free(s_dup);
- extrainfo_free(ei_tmp);
}
-#endif
- return (int)strlen(s)+1;
-}
+ *s_out = s;
+ s = NULL; /* prevent free */
+ result = 0;
+ goto done;
-/** Wrapper function for geoip_get_client_history(). It first discards
- * any items in the client history that are too old -- it dumps anything
- * more than 48 hours old, but it only considers whether to dump at most
- * once per 48 hours, so we aren't too precise to an observer (see also
- * r14780).
- */
-char *
-extrainfo_get_client_geoip_summary(time_t now)
-{
- static time_t last_purged_at = 0;
- int geoip_purge_interval = 48*60*60;
-#ifdef ENABLE_GEOIP_STATS
- if (get_options()->DirRecordUsageByCountry)
- geoip_purge_interval = get_options()->DirRecordUsageRetainIPs;
-#endif
- if (now > last_purged_at+geoip_purge_interval) {
- geoip_remove_old_clients(now-geoip_purge_interval);
- last_purged_at = now;
- }
- return geoip_get_client_history(now, GEOIP_CLIENT_CONNECT);
+ err:
+ result = -1;
+
+ done:
+ tor_free(s);
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_free(chunks);
+ tor_free(s_dup);
+ extrainfo_free(ei_tmp);
+
+ return result;
}
/** Return true iff <b>s</b> is a legally valid server nickname. */
@@@ -2257,17 -2012,26 +2247,17 @@@ router_purpose_from_string(const char *
void
router_free_all(void)
{
- if (onionkey)
- crypto_free_pk_env(onionkey);
- if (lastonionkey)
- crypto_free_pk_env(lastonionkey);
- if (identitykey)
- crypto_free_pk_env(identitykey);
- if (key_lock)
- tor_mutex_free(key_lock);
- if (desc_routerinfo)
- routerinfo_free(desc_routerinfo);
- if (desc_extrainfo)
- extrainfo_free(desc_extrainfo);
- if (authority_signing_key)
- crypto_free_pk_env(authority_signing_key);
- if (authority_key_certificate)
- authority_cert_free(authority_key_certificate);
- if (legacy_signing_key)
- crypto_free_pk_env(legacy_signing_key);
- if (legacy_key_certificate)
- authority_cert_free(legacy_key_certificate);
+ crypto_free_pk_env(onionkey);
+ crypto_free_pk_env(lastonionkey);
+ crypto_free_pk_env(server_identitykey);
+ crypto_free_pk_env(client_identitykey);
+ tor_mutex_free(key_lock);
+ routerinfo_free(desc_routerinfo);
+ extrainfo_free(desc_extrainfo);
+ crypto_free_pk_env(authority_signing_key);
+ authority_cert_free(authority_key_certificate);
+ crypto_free_pk_env(legacy_signing_key);
+ authority_cert_free(legacy_key_certificate);
if (warned_nonexistent_family) {
SMARTLIST_FOREACH(warned_nonexistent_family, char *, cp, tor_free(cp));
1
0

[tor/release-0.2.2] don't use old non-configured bridges (bug 2511)
by arma@torproject.org 14 Mar '11
by arma@torproject.org 14 Mar '11
14 Mar '11
commit 9a1a96ba0947e1c9b0e43aef6600b0d083586cf5
Author: Roger Dingledine <arma(a)torproject.org>
Date: Tue Feb 8 08:08:47 2011 -0500
don't use old non-configured bridges (bug 2511)
---
changes/bug2511 | 6 ++++++
src/or/routerlist.c | 13 +++++++++++++
2 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/changes/bug2511 b/changes/bug2511
new file mode 100644
index 0000000..a27696a
--- /dev/null
+++ b/changes/bug2511
@@ -0,0 +1,6 @@
+ o Major bugfixes:
+ - If you configured Tor to use bridge A, and then quit and
+ configured Tor to use bridge B instead, it would happily continue
+ to use bridge A if it's still reachable. While this behavior is
+ a feature if your goal is connectivity, in some scenarios it's a
+ dangerous bug. Bugfix on Tor 0.2.0.1-alpha; fixes bug 2511.
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 6d63862..bbd08f3 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -3314,6 +3314,19 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
return ROUTER_NOT_IN_CONSENSUS;
}
+ /* If we're reading a bridge descriptor from our cache, and we don't
+ * recognize it as one of our currently configured bridges, drop the
+ * descriptor. Otherwise we could end up using it as one of our entry
+ * guards even if it isn't in our Bridge config lines. */
+ if (router->purpose == ROUTER_PURPOSE_BRIDGE && from_cache &&
+ !routerinfo_is_a_configured_bridge(router)) {
+ log_info(LD_DIR, "Dropping bridge descriptor for '%s' because we have "
+ "no bridge configured at that address.", router->nickname);
+ *msg = "Router descriptor was not a configured bridge.";
+ routerinfo_free(router);
+ return ROUTER_WAS_NOT_NEW;
+ }
+
/* If we have a router with the same identity key, choose the newer one. */
if (old_router) {
if (!in_consensus && (router->cache_info.published_on <=
1
0