diff options
author | Peter Palfrader <peter@palfrader.org> | 2008-04-24 15:38:57 +0000 |
---|---|---|
committer | Peter Palfrader <peter@palfrader.org> | 2008-04-24 15:38:57 +0000 |
commit | 788404dacff64c0a2d120b317ab5d4c8a2b8f811 (patch) | |
tree | d7fbcac52105dc1f9fd9ebec14a69acb8b5dd516 | |
parent | 006b5762d3635c1d0650704f4a55d0860776ee18 (diff) | |
download | tor-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.c | 1 | ||||
-rw-r--r-- | src/or/directory.c | 69 | ||||
-rw-r--r-- | src/or/networkstatus.c | 2 | ||||
-rw-r--r-- | src/or/or.h | 9 | ||||
-rw-r--r-- | src/or/router.c | 1 | ||||
-rw-r--r-- | src/or/routerlist.c | 1 | ||||
-rw-r--r-- | src/or/routerparse.c | 8 |
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]); |