Fix directory self-testing logic

When I removed version_supports_begindir, I accidentally removed the
mechanism we had been using to make a directory cache self-test its
directory port.  This caused bug 6815, which caused 6814 (both in
0.2.4.2-alpha).

To fix this bug, I'm replacing the "anonymized_connection" argument to
directory_initiate_command_* with an enumeration to say how indirectly
to connect to a directory server.  (I don't want to reinstate the
"version_supports_begindir" argument as "begindir_ok" or anything --
these functions already take too many arguments.)

For safety, I made sure that passing 0 and 1 for 'indirection' gives
the same result as you would have gotten before -- just in case I
missed any 0s or 1s.
This commit is contained in:
Nick Mathewson 2012-09-12 10:15:58 -04:00
parent 75c9ccd4f8
commit 5cbeb60805
9 changed files with 63 additions and 25 deletions

6
changes/bug6815 Normal file
View File

@ -0,0 +1,6 @@
o Major bugfixes:
- Allow routers to correctly detect their own DirPorts as running.
When we removed support for versions_supports_begindir, we also
accidentally removed the mechanism we used to self-test our
DirPort. Diagnosed with help from kargig. Fixes bugs 6814 and
6815; bugfix on 0.2.4.2-alpha.

View File

@ -5479,7 +5479,7 @@ launch_direct_bridge_descriptor_fetch(bridge_info_t *bridge)
bridge->identity,
DIR_PURPOSE_FETCH_SERVERDESC,
ROUTER_PURPOSE_BRIDGE,
0, "authority.z", NULL, 0, 0);
DIRIND_ONEHOP, "authority.z", NULL, 0, 0);
tor_free(address);
}

View File

@ -91,7 +91,7 @@ static void directory_initiate_command_rend(const char *address,
const char *digest,
uint8_t dir_purpose,
uint8_t router_purpose,
int anonymized_connection,
dir_indirection_t indirection,
const char *resource,
const char *payload,
size_t payload_len,
@ -432,7 +432,8 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
ri->cache_info.identity_digest,
dir_purpose,
router_purpose,
0, resource, NULL, 0, if_modified_since);
DIRIND_ONEHOP,
resource, NULL, 0, if_modified_since);
} else
log_notice(LD_DIR, "Ignoring directory request, since no bridge "
"nodes are available yet.");
@ -493,13 +494,15 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
}
}
if (rs)
if (rs) {
const dir_indirection_t indirection =
get_via_tor ? DIRIND_ANONYMOUS : DIRIND_ONEHOP;
directory_initiate_command_routerstatus(rs, dir_purpose,
router_purpose,
get_via_tor,
indirection,
resource, NULL, 0,
if_modified_since);
else {
} else {
log_notice(LD_DIR,
"While fetching directory info, "
"no running dirservers known. Will try again later. "
@ -531,17 +534,25 @@ directory_get_from_all_authorities(uint8_t dir_purpose,
continue;
rs = &ds->fake_status;
directory_initiate_command_routerstatus(rs, dir_purpose, router_purpose,
0, resource, NULL, 0, 0);
DIRIND_ONEHOP, resource, NULL,
0, 0);
} SMARTLIST_FOREACH_END(ds);
}
/** Return true iff <b>ind</b> requires a multihop circuit. */
static int
dirind_is_anon(dir_indirection_t ind)
{
return ind == DIRIND_ANON_DIRPORT || ind == DIRIND_ANONYMOUS;
}
/** Same as directory_initiate_command_routerstatus(), but accepts
* rendezvous data to fetch a hidden service descriptor. */
void
directory_initiate_command_routerstatus_rend(const routerstatus_t *status,
uint8_t dir_purpose,
uint8_t router_purpose,
int anonymized_connection,
dir_indirection_t indirection,
const char *resource,
const char *payload,
size_t payload_len,
@ -554,6 +565,7 @@ directory_initiate_command_routerstatus_rend(const routerstatus_t *status,
struct in_addr in;
const char *address;
tor_addr_t addr;
const int anonymized_connection = dirind_is_anon(indirection);
node = node_get_by_id(status->identity_digest);
if (!node && anonymized_connection) {
@ -585,7 +597,7 @@ directory_initiate_command_routerstatus_rend(const routerstatus_t *status,
status->or_port, status->dir_port,
status->identity_digest,
dir_purpose, router_purpose,
anonymized_connection, resource,
indirection, resource,
payload, payload_len, if_modified_since,
rend_query);
}
@ -608,7 +620,7 @@ void
directory_initiate_command_routerstatus(const routerstatus_t *status,
uint8_t dir_purpose,
uint8_t router_purpose,
int anonymized_connection,
dir_indirection_t indirection,
const char *resource,
const char *payload,
size_t payload_len,
@ -616,7 +628,7 @@ directory_initiate_command_routerstatus(const routerstatus_t *status,
{
directory_initiate_command_routerstatus_rend(status, dir_purpose,
router_purpose,
anonymized_connection, resource,
indirection, resource,
payload, payload_len,
if_modified_since, NULL);
}
@ -818,11 +830,13 @@ static int
directory_command_should_use_begindir(const or_options_t *options,
const tor_addr_t *addr,
int or_port, uint8_t router_purpose,
int anonymized_connection)
dir_indirection_t indirection)
{
if (!or_port)
return 0; /* We don't know an ORPort -- no chance. */
if (!anonymized_connection)
if (indirection == DIRIND_DIRECT_CONN || indirection == DIRIND_ANON_DIRPORT)
return 0;
if (indirection == DIRIND_ONEHOP)
if (!fascist_firewall_allows_address_or(addr, or_port) ||
directory_fetches_from_authorities(options))
return 0; /* We're firewalled or are acting like a relay -- also no. */
@ -842,13 +856,13 @@ directory_initiate_command(const char *address, const tor_addr_t *_addr,
uint16_t or_port, uint16_t dir_port,
const char *digest,
uint8_t dir_purpose, uint8_t router_purpose,
int anonymized_connection, const char *resource,
dir_indirection_t indirection, const char *resource,
const char *payload, size_t payload_len,
time_t if_modified_since)
{
directory_initiate_command_rend(address, _addr, or_port, dir_port,
digest, dir_purpose,
router_purpose, anonymized_connection,
router_purpose, indirection,
resource, payload, payload_len,
if_modified_since, NULL);
}
@ -874,7 +888,7 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
uint16_t or_port, uint16_t dir_port,
const char *digest,
uint8_t dir_purpose, uint8_t router_purpose,
int anonymized_connection,
dir_indirection_t indirection,
const char *resource,
const char *payload, size_t payload_len,
time_t if_modified_since,
@ -884,7 +898,8 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
const or_options_t *options = get_options();
int socket_error = 0;
int use_begindir = directory_command_should_use_begindir(options, _addr,
or_port, router_purpose, anonymized_connection);
or_port, router_purpose, indirection);
const int anonymized_connection = dirind_is_anon(indirection);
tor_addr_t addr;
tor_assert(address);
@ -930,6 +945,7 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
conn->_base.state = DIR_CONN_STATE_CONNECTING;
/* decide whether we can learn our IP address from this conn */
/* XXXX This is a bad name for this field now. */
conn->dirconn_direct = !anonymized_connection;
/* copy rendezvous data, if any */

View File

@ -22,10 +22,24 @@ void directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
void directory_get_from_all_authorities(uint8_t dir_purpose,
uint8_t router_purpose,
const char *resource);
/** Enumeration of ways to connect to a directory server */
typedef enum {
/** Default: connect over a one-hop Tor circuit but fall back to direct
* connection */
DIRIND_ONEHOP=0,
/** Connect over a multi-hop anonymizing Tor circuit */
DIRIND_ANONYMOUS=1,
/** Conncet to the DirPort directly */
DIRIND_DIRECT_CONN,
/** Connect over a multi-hop anonymizing Tor circuit to our dirport */
DIRIND_ANON_DIRPORT,
} dir_indirection_t;
void directory_initiate_command_routerstatus(const routerstatus_t *status,
uint8_t dir_purpose,
uint8_t router_purpose,
int anonymized_connection,
dir_indirection_t indirection,
const char *resource,
const char *payload,
size_t payload_len,
@ -33,7 +47,7 @@ void directory_initiate_command_routerstatus(const routerstatus_t *status,
void directory_initiate_command_routerstatus_rend(const routerstatus_t *status,
uint8_t dir_purpose,
uint8_t router_purpose,
int anonymized_connection,
dir_indirection_t indirection,
const char *resource,
const char *payload,
size_t payload_len,
@ -53,7 +67,7 @@ void directory_initiate_command(const char *address, const tor_addr_t *addr,
uint16_t or_port, uint16_t dir_port,
const char *digest,
uint8_t dir_purpose, uint8_t router_purpose,
int anonymized_connection,
dir_indirection_t indirection,
const char *resource,
const char *payload, size_t payload_len,
time_t if_modified_since);

View File

@ -1168,7 +1168,7 @@ update_v2_networkstatus_cache_downloads(time_t now)
directory_initiate_command_routerstatus(
&ds->fake_status, DIR_PURPOSE_FETCH_V2_NETWORKSTATUS,
ROUTER_PURPOSE_GENERAL,
0, /* Not private */
DIRIND_ONEHOP,
resource,
NULL, 0 /* No payload. */,
0 /* No I-M-S. */);

View File

@ -617,7 +617,8 @@ directory_get_from_hs_dir(const char *desc_id, const rend_data_t *rend_query)
directory_initiate_command_routerstatus_rend(hs_dir,
DIR_PURPOSE_FETCH_RENDDESC_V2,
ROUTER_PURPOSE_GENERAL,
!tor2web_mode, desc_id_base32,
tor2web_mode?DIRIND_ONEHOP:DIRIND_ANONYMOUS,
desc_id_base32,
NULL, 0, 0,
rend_query);
log_info(LD_REND, "Sending fetch request for v2 descriptor for "

View File

@ -2782,7 +2782,8 @@ directory_post_to_hs_dir(rend_service_descriptor_t *renddesc,
directory_initiate_command_routerstatus(hs_dir,
DIR_PURPOSE_UPLOAD_RENDDESC_V2,
ROUTER_PURPOSE_GENERAL,
1, NULL, desc->desc_str,
DIRIND_ANONYMOUS, NULL,
desc->desc_str,
strlen(desc->desc_str), 0);
base32_encode(desc_id_base32, sizeof(desc_id_base32),
desc->desc_id, DIGEST_LEN);

View File

@ -957,7 +957,7 @@ consider_testing_reachability(int test_or, int test_dir)
me->cache_info.identity_digest,
DIR_PURPOSE_FETCH_SERVERDESC,
ROUTER_PURPOSE_GENERAL,
1, "authority.z", NULL, 0, 0);
DIRIND_ANON_DIRPORT, "authority.z", NULL, 0, 0);
}
}

View File

@ -4326,7 +4326,7 @@ initiate_descriptor_downloads(const routerstatus_t *source,
/* We know which authority we want. */
directory_initiate_command_routerstatus(source, purpose,
ROUTER_PURPOSE_GENERAL,
0, /* not private */
DIRIND_ONEHOP,
resource, NULL, 0, 0);
} else {
directory_get_from_dirserver(purpose, ROUTER_PURPOSE_GENERAL, resource,