aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Palfrader <peter@palfrader.org>2008-04-24 15:38:57 +0000
committerPeter Palfrader <peter@palfrader.org>2008-04-24 15:38:57 +0000
commit788404dacff64c0a2d120b317ab5d4c8a2b8f811 (patch)
treed7fbcac52105dc1f9fd9ebec14a69acb8b5dd516
parent006b5762d3635c1d0650704f4a55d0860776ee18 (diff)
downloadtor-788404dacff64c0a2d120b317ab5d4c8a2b8f811.tar
tor-788404dacff64c0a2d120b317ab5d4c8a2b8f811.tar.gz
and the client part of the consensus-by-authority-fpr proposal (ifdef'ed out)
svn:r14446
-rw-r--r--src/or/circuitbuild.c1
-rw-r--r--src/or/directory.c69
-rw-r--r--src/or/networkstatus.c2
-rw-r--r--src/or/or.h9
-rw-r--r--src/or/router.c1
-rw-r--r--src/or/routerlist.c1
-rw-r--r--src/or/routerparse.c8
7 files changed, 88 insertions, 3 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index f879f13ca..2ac6ac318 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -2924,6 +2924,7 @@ launch_direct_bridge_descriptor_fetch(char *address, bridge_info_t *bridge)
return; /* it's already on the way */
directory_initiate_command(address, bridge->addr,
bridge->port, 0,
+ 0, /* does not matter */
1, bridge->identity,
DIR_PURPOSE_FETCH_SERVERDESC,
ROUTER_PURPOSE_BRIDGE,
diff --git a/src/or/directory.c b/src/or/directory.c
index 7765c2102..f8f48ec74 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -37,6 +37,7 @@ const char directory_c_id[] =
static void directory_send_command(dir_connection_t *conn,
int purpose, int direct, const char *resource,
const char *payload, size_t payload_len,
+ int supports_conditional_consensus,
time_t if_modified_since);
static int directory_handle_command(dir_connection_t *conn);
static int body_is_plausible(const char *body, size_t body_len, int purpose);
@@ -339,10 +340,13 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
/* want to ask a running bridge for which we have a descriptor. */
/* XXX021 we assume that all of our bridges can answer any
* possible directory question. This won't be true forever. -RD */
+ /* It certainly is not true with conditional consensus downloading,
+ * so, for now, never assume the server supports that. */
routerinfo_t *ri = choose_random_entry(NULL);
if (ri) {
directory_initiate_command(ri->address, ri->addr,
ri->or_port, 0,
+ 0, /* don't use conditional consensus url */
1, ri->cache_info.identity_digest,
dir_purpose,
router_purpose,
@@ -464,6 +468,7 @@ directory_initiate_command_routerstatus(routerstatus_t *status,
}
directory_initiate_command(address, status->addr,
status->or_port, status->dir_port,
+ status->version_supports_conditional_consensus,
status->version_supports_begindir,
status->identity_digest,
dir_purpose, router_purpose,
@@ -645,6 +650,7 @@ directory_command_should_use_begindir(or_options_t *options, uint32_t addr,
void
directory_initiate_command(const char *address, uint32_t addr,
uint16_t or_port, uint16_t dir_port,
+ int supports_conditional_consensus,
int supports_begindir, const char *digest,
uint8_t dir_purpose, uint8_t router_purpose,
int anonymized_connection, const char *resource,
@@ -707,7 +713,9 @@ directory_initiate_command(const char *address, uint32_t addr,
case 0:
/* queue the command on the outbuf */
directory_send_command(conn, dir_purpose, 1, resource,
- payload, payload_len, if_modified_since);
+ payload, payload_len,
+ supports_conditional_consensus,
+ if_modified_since);
connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
/* writable indicates finish, readable indicates broken link,
error indicates broken link in windowsland. */
@@ -744,7 +752,9 @@ directory_initiate_command(const char *address, uint32_t addr,
conn->_base.state = DIR_CONN_STATE_CLIENT_SENDING;
/* queue the command on the outbuf */
directory_send_command(conn, dir_purpose, 0, resource,
- payload, payload_len, if_modified_since);
+ payload, payload_len,
+ supports_conditional_consensus,
+ if_modified_since);
connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
connection_start_reading(TO_CONN(linked_conn));
}
@@ -763,6 +773,55 @@ connection_dir_is_encrypted(dir_connection_t *conn)
return TO_CONN(conn)->linked;
}
+/** Return the URL we should use for a consensus download.
+ *
+ * This url depends on whether or not the server we go to
+ * is sufficiently new to support conditional consensus downloading,
+ * i.e. GET .../consensus/<fpr>+<fpr>+<fpr>
+ */
+#define CONDITIONAL_CONSENSUS_FPR_LEN 3
+#if (CONDITIONAL_CONSENSUS_FPR_LEN > DIGEST_LEN)
+#error "conditional consensus fingerprint length is larger than digest length
+#endif
+static char *
+directory_get_consensus_url(int supports_conditional_consensus)
+{
+ char *url;
+ int len;
+
+#ifndef SUPPORTS_CONDITIONAL_CONSENSUS_SINCE_VERSION
+ supports_conditional_consensus = 0;
+#endif
+
+ if (supports_conditional_consensus) {
+ char *authority_id_list;
+ smartlist_t *authority_digets = smartlist_create();
+
+ SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
+ trusted_dir_server_t *, ds,
+ {
+ char *hex = tor_malloc(2*CONDITIONAL_CONSENSUS_FPR_LEN+1);
+ base16_encode(hex, 2*CONDITIONAL_CONSENSUS_FPR_LEN+1,
+ ds->digest, CONDITIONAL_CONSENSUS_FPR_LEN);
+ smartlist_add(authority_digets, hex);
+ });
+ authority_id_list = smartlist_join_strings(authority_digets,
+ "+", 0, NULL);
+
+ len = strlen(authority_id_list)+64;
+ url = tor_malloc(len);
+ tor_snprintf(url, len, "/tor/status-vote/current/consensus/%s.z",
+ authority_id_list);
+
+ SMARTLIST_FOREACH(authority_digets, char *, cp, tor_free(cp));
+ smartlist_free(authority_digets);
+ tor_free(authority_id_list);
+ } else {
+ url = tor_strdup("/tor/status-vote/current/consensus.z");
+ }
+ return url;
+}
+
/** Queue an appropriate HTTP command on conn-\>outbuf. The other args
* are as in directory_initiate_command.
*/
@@ -770,6 +829,7 @@ static void
directory_send_command(dir_connection_t *conn,
int purpose, int direct, const char *resource,
const char *payload, size_t payload_len,
+ int supports_conditional_consensus,
time_t if_modified_since)
{
char proxystring[256];
@@ -852,7 +912,10 @@ directory_send_command(dir_connection_t *conn,
tor_assert(!resource);
tor_assert(!payload);
httpcommand = "GET";
- url = tor_strdup("/tor/status-vote/current/consensus.z");
+ url = directory_get_consensus_url(supports_conditional_consensus);
+ /* XXX021: downgrade/remove once done with conditional consensus fu */
+ log_notice(LD_DIR, "Downloading consensus from %s using %s",
+ hoststring, url);
break;
case DIR_PURPOSE_FETCH_CERTIFICATE:
tor_assert(resource);
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 5ec72daf4..f56ffff19 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -1280,6 +1280,8 @@ routerstatus_has_changed(const routerstatus_t *a, const routerstatus_t *b)
a->version_supports_begindir != b->version_supports_begindir ||
a->version_supports_extrainfo_upload !=
b->version_supports_extrainfo_upload ||
+ a->version_supports_conditional_consensus !=
+ b->version_supports_conditional_consensus ||
a->version_supports_v3_dir != b->version_supports_v3_dir;
}
diff --git a/src/or/or.h b/src/or/or.h
index 8c2506421..4dffef89f 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -709,6 +709,11 @@ typedef enum {
/** Largest number of bytes that can fit in a relay cell payload. */
#define RELAY_PAYLOAD_SIZE (CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE)
+/** Version that started supporting conditional consensus downloading
+ * as a dirserver. This define can go once we know the answer and
+ * want to use the feature. */
+// #define SUPPORTS_CONDITIONAL_CONSENSUS_SINCE_VERSION "0.2.1.1"
+
/** Parsed onion routing cell. All communication between nodes
* is via cells. */
typedef struct cell_t {
@@ -1369,6 +1374,9 @@ typedef struct routerstatus_t {
unsigned int version_known:1;
/** True iff this router is a version that supports BEGIN_DIR cells. */
unsigned int version_supports_begindir:1;
+ /** True iff this router is a version that supports conditional consensus
+ * downloads (signed by list of authorities). */
+ unsigned int version_supports_conditional_consensus:1;
/** True iff this router is a version that we can post extrainfo docs to. */
unsigned int version_supports_extrainfo_upload:1;
/** True iff this router is a version that, if it caches directory info,
@@ -3048,6 +3056,7 @@ int connection_dir_finished_connecting(dir_connection_t *conn);
void connection_dir_request_failed(dir_connection_t *conn);
void directory_initiate_command(const char *address, uint32_t addr,
uint16_t or_port, uint16_t dir_port,
+ int supports_conditional_consensus,
int supports_begindir, const char *digest,
uint8_t dir_purpose, uint8_t router_purpose,
int anonymized_connection,
diff --git a/src/or/router.c b/src/or/router.c
index 91518141c..84c05fdf6 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -726,6 +726,7 @@ consider_testing_reachability(int test_or, int test_dir)
/* ask myself, via tor, for my server descriptor. */
directory_initiate_command(me->address, me->addr,
me->or_port, me->dir_port,
+ 0, /* does not matter */
0, me->cache_info.identity_digest,
DIR_PURPOSE_FETCH_SERVERDESC,
ROUTER_PURPOSE_GENERAL,
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 994d019f5..e909e6165 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -3512,6 +3512,7 @@ add_trusted_dir_server(const char *nickname, const char *address,
if (ent->or_port)
ent->fake_status.version_supports_begindir = 1;
+ ent->fake_status.version_supports_conditional_consensus = 1;
smartlist_add(trusted_dir_servers, ent);
router_dir_info_changed();
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 7ff6c6311..2ea9487d0 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -1828,6 +1828,7 @@ routerstatus_parse_entry_from_string(memarea_t *area,
if (strcmpstart(tok->args[0], "Tor ")) {
rs->version_supports_begindir = 1;
rs->version_supports_extrainfo_upload = 1;
+ rs->version_supports_conditional_consensus = 1;
} else {
rs->version_supports_begindir =
tor_version_as_new_as(tok->args[0], "0.2.0.1-alpha");
@@ -1835,6 +1836,13 @@ routerstatus_parse_entry_from_string(memarea_t *area,
tor_version_as_new_as(tok->args[0], "0.2.0.0-alpha-dev (r10070)");
rs->version_supports_v3_dir =
tor_version_as_new_as(tok->args[0], "0.2.0.8-alpha");
+#ifdef SUPPORTS_CONDITIONAL_CONSENSUS_SINCE_VERSION
+ rs->version_supports_conditional_consensus =
+ tor_version_as_new_as(tok->args[0],
+ SUPPORTS_CONDITIONAL_CONSENSUS_SINCE_VERSION);
+#else
+ rs->version_supports_conditional_consensus = 0;
+#endif
}
if (vote_rs) {
vote_rs->version = tor_strdup(tok->args[0]);