r14202@Kushana: nickm | 2007-08-24 09:55:30 -0400

Add purposes for new things we need to fetch for v3 directory system.


svn:r11268
This commit is contained in:
Nick Mathewson 2007-08-24 14:41:06 +00:00
parent c3805e753a
commit cf2ac9b9e1
3 changed files with 117 additions and 56 deletions

View File

@ -1139,7 +1139,7 @@ $Id$
An authority SHOULD publish its vote immediately at the start of each voting An authority SHOULD publish its vote immediately at the start of each voting
period (minus VoteSeconds+DistSeconds). It does this by making it period (minus VoteSeconds+DistSeconds). It does this by making it
available at available at
http://<hostname>/tor/status-vote/current/authority.z http://<hostname>/tor/status-vote/next/authority.z
and sending it in an HTTP POST request to each other authority at the URL and sending it in an HTTP POST request to each other authority at the URL
http://<hostname>/tor/post/vote http://<hostname>/tor/post/vote
@ -1149,7 +1149,7 @@ $Id$
Once an authority has a vote from another authority, it makes it available Once an authority has a vote from another authority, it makes it available
at at
http://<hostname>/tor/status-vote/current/<fp>.z http://<hostname>/tor/status-vote/next/<fp>.z
where <fp> is the fingerprint of the other authority's identity key. where <fp> is the fingerprint of the other authority's identity key.
The consensus status, along with as many signatures as the server The consensus status, along with as many signatures as the server

View File

@ -86,6 +86,10 @@ purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose)
dir_purpose == DIR_PURPOSE_UPLOAD_SIGNATURES || dir_purpose == DIR_PURPOSE_UPLOAD_SIGNATURES ||
dir_purpose == DIR_PURPOSE_FETCH_RUNNING_LIST || dir_purpose == DIR_PURPOSE_FETCH_RUNNING_LIST ||
dir_purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS || dir_purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS ||
dir_purpose == DIR_PURPOSE_FETCH_STATUS_VOTE ||
dir_purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES ||
dir_purpose == DIR_PURPOSE_FETCH_CONSENSUS ||
dir_purpose == DIR_PURPOSE_FETCH_CERTIFICATE ||
dir_purpose == DIR_PURPOSE_FETCH_SERVERDESC || dir_purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
dir_purpose == DIR_PURPOSE_FETCH_EXTRAINFO) dir_purpose == DIR_PURPOSE_FETCH_EXTRAINFO)
return 0; return 0;
@ -115,6 +119,46 @@ authority_type_to_string(authority_type_t auth)
return result; return result;
} }
/** Return a string describing a given directory connection purpose. */
static const char *
dir_conn_purpose_to_string(int purpose)
{
switch (purpose)
{
case DIR_PURPOSE_FETCH_DIR:
return "v1 directory fetch";
case DIR_PURPOSE_FETCH_RENDDESC:
return "hidden-service descriptor fetch";
case DIR_PURPOSE_UPLOAD_DIR:
return "server descriptor upload";
case DIR_PURPOSE_UPLOAD_RENDDESC:
return "hidden-service descriptor upload";
case DIR_PURPOSE_UPLOAD_VOTE:
return "server vote upload";
case DIR_PURPOSE_UPLOAD_SIGNATURES:
return "consensus signature upload";
case DIR_PURPOSE_FETCH_RUNNING_LIST:
return "running-routers fetch";
case DIR_PURPOSE_FETCH_NETWORKSTATUS:
return "network-status fetch";
case DIR_PURPOSE_FETCH_SERVERDESC:
return "server descriptor fetch";
case DIR_PURPOSE_FETCH_EXTRAINFO:
return "extra-info fetch";
case DIR_PURPOSE_FETCH_CONSENSUS:
return "consensus network-status fetch";
case DIR_PURPOSE_FETCH_CERTIFICATE:
return "authority cert fetch";
case DIR_PURPOSE_FETCH_STATUS_VOTE:
return "status vote fetch";
case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
return "consensus signature fetch";
}
log_warn(LD_BUG, "Called with unknown purpose %d", purpose);
return "(unknown)";
}
/** Return true iff <b>identity_digest</b> is the digest of a router we /** Return true iff <b>identity_digest</b> is the digest of a router we
* believe to support extrainfo downloads. (If <b>is_authority</b> we do * believe to support extrainfo downloads. (If <b>is_authority</b> we do
* additional checking that's only valid for authorities.) */ * additional checking that's only valid for authorities.) */
@ -234,6 +278,12 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
case DIR_PURPOSE_FETCH_RENDDESC: case DIR_PURPOSE_FETCH_RENDDESC:
type = HIDSERV_AUTHORITY; type = HIDSERV_AUTHORITY;
break; break;
case DIR_PURPOSE_FETCH_STATUS_VOTE:
case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
case DIR_PURPOSE_FETCH_CONSENSUS:
case DIR_PURPOSE_FETCH_CERTIFICATE:
type = V3_AUTHORITY;
break;
default: default:
log_warn(LD_BUG, "Unexpected purpose %d", (int)dir_purpose); log_warn(LD_BUG, "Unexpected purpose %d", (int)dir_purpose);
return; return;
@ -267,18 +317,8 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
rs = router_pick_directory_server(1, 1, type, rs = router_pick_directory_server(1, 1, type,
retry_if_no_servers); retry_if_no_servers);
if (!rs) { if (!rs) {
const char *which; log_info(LD_DIR, "No router found for %s; falling back to "
if (dir_purpose == DIR_PURPOSE_FETCH_DIR) "dirserver list.", dir_conn_purpose_to_string(dir_purpose));
which = "directory";
else if (dir_purpose == DIR_PURPOSE_FETCH_RUNNING_LIST)
which = "status list";
else if (dir_purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS)
which = "network status";
else // if (dir_purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS)
which = "server descriptors";
log_info(LD_DIR,
"No router found for %s; falling back to dirserver list",
which);
rs = router_pick_trusteddirserver(type, 1, 1, rs = router_pick_trusteddirserver(type, 1, 1,
retry_if_no_servers); retry_if_no_servers);
if (!rs) if (!rs)
@ -410,6 +450,8 @@ connection_dir_request_failed(dir_connection_t *conn)
log_info(LD_DIR, "Giving up on directory server at '%s'; retrying", log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
conn->_base.address); conn->_base.address);
connection_dir_download_routerdesc_failed(conn); connection_dir_download_routerdesc_failed(conn);
} else {
/* XXXX020 handle failing: votes. signatures. certificates. consensus. */
} }
} }
@ -494,41 +536,7 @@ directory_initiate_command(const char *address, uint32_t addr,
log_debug(LD_DIR, "anonymized %d, want_to_tunnel %d.", log_debug(LD_DIR, "anonymized %d, want_to_tunnel %d.",
anonymized_connection, want_to_tunnel); anonymized_connection, want_to_tunnel);
switch (dir_purpose) { log_debug(LD_DIR, "Initiating %s", dir_conn_purpose_to_string(dir_purpose));
case DIR_PURPOSE_FETCH_DIR:
log_debug(LD_DIR,"initiating directory fetch");
break;
case DIR_PURPOSE_FETCH_RENDDESC:
log_debug(LD_DIR,"initiating hidden-service descriptor fetch");
break;
case DIR_PURPOSE_UPLOAD_DIR:
log_debug(LD_OR,"initiating server descriptor upload");
break;
case DIR_PURPOSE_UPLOAD_RENDDESC:
log_debug(LD_REND,"initiating hidden-service descriptor upload");
break;
case DIR_PURPOSE_UPLOAD_VOTE:
log_debug(LD_OR,"initiating server vote upload");
break;
case DIR_PURPOSE_UPLOAD_SIGNATURES:
log_debug(LD_OR,"initiating consensus signature upload");
break;
case DIR_PURPOSE_FETCH_RUNNING_LIST:
log_debug(LD_DIR,"initiating running-routers fetch");
break;
case DIR_PURPOSE_FETCH_NETWORKSTATUS:
log_debug(LD_DIR,"initiating network-status fetch");
break;
case DIR_PURPOSE_FETCH_SERVERDESC:
log_debug(LD_DIR,"initiating server descriptor fetch");
break;
case DIR_PURPOSE_FETCH_EXTRAINFO:
log_debug(LD_DIR,"initiating extra-info fetch");
break;
default:
log_err(LD_BUG, "Unrecognized directory connection purpose.");
tor_assert(0);
}
conn = TO_DIR_CONN(connection_new(CONN_TYPE_DIR, AF_INET)); conn = TO_DIR_CONN(connection_new(CONN_TYPE_DIR, AF_INET));
@ -679,6 +687,34 @@ directory_send_command(dir_connection_t *conn,
url = tor_malloc(len); url = tor_malloc(len);
tor_snprintf(url, len, "/tor/status/%s", resource); tor_snprintf(url, len, "/tor/status/%s", resource);
break; break;
case DIR_PURPOSE_FETCH_CONSENSUS:
tor_assert(!resource);
tor_assert(!payload);
httpcommand = "GET";
url = tor_strdup("/tor/status-vote/current/consensus.z");
break;
case DIR_PURPOSE_FETCH_CERTIFICATE:
tor_assert(resource);
tor_assert(!payload);
httpcommand = "GET";
len = strlen(resource)+32;
url = tor_malloc(len);
tor_snprintf(url, len, "/tor/keys/%s", resource);
break;
case DIR_PURPOSE_FETCH_STATUS_VOTE:
tor_assert(resource);
tor_assert(!payload);
httpcommand = "GET";
len = strlen(resource)+32;
url = tor_malloc(len);
tor_snprintf(url, len, "/tor/status-vote/next/%s", resource);
break;
case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
tor_assert(!resource);
tor_assert(!payload);
httpcommand = "GET";
url = tor_strdup("/tor/status-vote/next/consensus-signatures.z");
break;
case DIR_PURPOSE_FETCH_SERVERDESC: case DIR_PURPOSE_FETCH_SERVERDESC:
httpcommand = "GET"; httpcommand = "GET";
len = strlen(resource)+32; len = strlen(resource)+32;
@ -1258,6 +1294,19 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
} }
} }
if (conn->_base.purpose == DIR_PURPOSE_FETCH_CONSENSUS) {
/*XXXX020*/;
}
if (conn->_base.purpose == DIR_PURPOSE_FETCH_CERTIFICATE) {
/*XXXX020*/;
}
if (conn->_base.purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) {
/*XXXX020*/;
}
if (conn->_base.purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES) {
/*XXXX020*/;
}
if (conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC || if (conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO) { conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO) {
int was_ei = conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO; int was_ei = conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO;
@ -1953,17 +2002,17 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
* since it wants to be spooled. */ * since it wants to be spooled. */
if ((item = dirvote_get_pending_consensus())) if ((item = dirvote_get_pending_consensus()))
smartlist_add(items, (char*)item); smartlist_add(items, (char*)item);
} else if (current && !strcmp(url, "consensus-signatures")) { } else if (!current && !strcmp(url, "consensus-signatures")) {
/* XXXX020 the spec says that we should implement /* XXXX020 the spec says that we should implement
* currrent/consensus-signatures too. Why? */ * currrent/consensus-signatures too. Why? */
const char *item; const char *item;
if ((item=dirvote_get_pending_detached_signatures())) if ((item=dirvote_get_pending_detached_signatures()))
smartlist_add(items, (char*)item); smartlist_add(items, (char*)item);
} else if (current && !strcmp(url, "authority")) { } else if (!current && !strcmp(url, "authority")) {
const cached_dir_t *d; const cached_dir_t *d;
if ((d=dirvote_get_vote(NULL))) if ((d=dirvote_get_vote(NULL)))
smartlist_add(dir_items, (cached_dir_t*)d); smartlist_add(dir_items, (cached_dir_t*)d);
} else if (current) { } else if (!current) {
const cached_dir_t *d; const cached_dir_t *d;
smartlist_t *fps = smartlist_create(); smartlist_t *fps = smartlist_create();
dir_split_resource_into_fingerprints(url, fps, NULL, 1, 1); dir_split_resource_into_fingerprints(url, fps, NULL, 1, 1);

View File

@ -381,10 +381,22 @@ typedef enum {
#define DIR_PURPOSE_FETCH_VOTE 11 #define DIR_PURPOSE_FETCH_VOTE 11
/** A connection to a directory server: upload a v3 consensus signature */ /** A connection to a directory server: upload a v3 consensus signature */
#define DIR_PURPOSE_UPLOAD_SIGNATURES 12 #define DIR_PURPOSE_UPLOAD_SIGNATURES 12
/** A connection to a directory server: download one or more network-status
* objects */
#define DIR_PURPOSE_FETCH_STATUS_VOTE 13
/** A connection to a directory server: download one or more network-status
* objects */
#define DIR_PURPOSE_FETCH_DETACHED_SIGNATURES 14
/** A connection to a directory server: download one or more network-status
* objects */
#define DIR_PURPOSE_FETCH_CONSENSUS 15
/** A connection to a directory server: download one or more network-status
* objects */
#define DIR_PURPOSE_FETCH_CERTIFICATE 16
/** Purpose for connection at a directory server. */ /** Purpose for connection at a directory server. */
#define DIR_PURPOSE_SERVER 13 #define DIR_PURPOSE_SERVER 17
#define _DIR_PURPOSE_MAX 13 #define _DIR_PURPOSE_MAX 17
#define _EXIT_PURPOSE_MIN 1 #define _EXIT_PURPOSE_MIN 1
/** This exit stream wants to do an ordinary connect. */ /** This exit stream wants to do an ordinary connect. */
@ -393,7 +405,7 @@ typedef enum {
#define EXIT_PURPOSE_RESOLVE 2 #define EXIT_PURPOSE_RESOLVE 2
#define _EXIT_PURPOSE_MAX 2 #define _EXIT_PURPOSE_MAX 2
/* !!!! If any connection purpose is ever over over 15, we must grow the type /* !!!! If any connection purpose is ever over over 31, we must grow the type
* field in connection_t. */ * field in connection_t. */
/** Circuit state: I'm the origin, still haven't done all my handshakes. */ /** Circuit state: I'm the origin, still haven't done all my handshakes. */
@ -763,7 +775,7 @@ typedef struct connection_t {
uint8_t state; /**< Current state of this connection. */ uint8_t state; /**< Current state of this connection. */
uint8_t type:4; /**< What kind of connection is this? */ uint8_t type:4; /**< What kind of connection is this? */
uint8_t purpose:4; /**< Only used for DIR and EXIT types currently. */ uint8_t purpose:5; /**< Only used for DIR and EXIT types currently. */
/* The next fields are all one-bit booleans. Some are only applicable to /* The next fields are all one-bit booleans. Some are only applicable to
* connection subtypes, but we hold them here anyway, to save space. * connection subtypes, but we hold them here anyway, to save space.