diff options
author | Nick Mathewson <nickm@torproject.org> | 2004-10-27 00:48:51 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2004-10-27 00:48:51 +0000 |
commit | b90b2bb848cbbfbc7babda6498e014b687704c29 (patch) | |
tree | 7d94fe9a64882b242064d40e990d4d82a5874497 /src/or/dirserv.c | |
parent | 26f3cb865202160fe6b8ecfb20a0e41fea3a4a6a (diff) | |
download | tor-b90b2bb848cbbfbc7babda6498e014b687704c29.tar.gz tor-b90b2bb848cbbfbc7babda6498e014b687704c29.zip |
Add and document router-status line using new unified liveness/verifiedness format; continue to generate running-routers; continue to parse running-routers when no router-status line is found
svn:r2592
Diffstat (limited to 'src/or/dirserv.c')
-rw-r--r-- | src/or/dirserv.c | 155 |
1 files changed, 85 insertions, 70 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c index f414350bde..74409fe528 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -20,7 +20,8 @@ extern or_options_t options; /**< command-line and config-file options */ static int the_directory_is_dirty = 1; static int runningrouters_is_dirty = 1; -static int list_running_servers(char **nicknames_out); +static int list_server_status(char **running_routers_out, + char **router_status_out); static void directory_remove_unrecognized(void); static int dirserv_regenerate_directory(void); @@ -456,71 +457,80 @@ dirserv_load_from_directory_string(const char *dir) return 0; } -/** Set *<b>nicknames_out</b> to a comma-separated list of all the ORs that we - * believe are currently running (because we have open connections to - * them). Return 0 on success; -1 on error. +/** + * Allocate and return a description of the status of the server <b>desc</b>, + * for use in a running-routers line (if <b>rr_format</b> is true), or in a + * router-status line (if <b>rr_format</b> is false. The server is listed + * as running iff <b>is_live</b> is true. */ -static int -list_running_servers(char **nicknames_out) +static char * +list_single_server_status(descriptor_entry_t *desc, int is_live, + int rr_format) { - connection_t **connection_array; - int n_conns; - connection_t *conn; + char buf[MAX_NICKNAME_LEN+HEX_DIGEST_LEN+4]; /* !nickname=$hexdigest\0 */ char *cp; - int i; - size_t length; - smartlist_t *nicknames_up, *nicknames_down; - char *name; - const char *s; - - *nicknames_out = NULL; - nicknames_up = smartlist_create(); - nicknames_down = smartlist_create(); - smartlist_add(nicknames_up, tor_strdup(options.Nickname)); - - get_connection_array(&connection_array, &n_conns); - for (i = 0; i<n_conns; ++i) { - conn = connection_array[i]; - if (conn->type != CONN_TYPE_OR || !conn->nickname) - continue; /* only list connections to ORs with certificates. */ - s = dirserv_get_nickname_by_digest(conn->identity_digest); - if (s) { - name = tor_strdup(s); - } else { - name = tor_malloc(HEX_DIGEST_LEN+2); - *name = '$'; - base16_encode(name+1, HEX_DIGEST_LEN+1, conn->identity_digest, DIGEST_LEN); - } - if(conn->state == OR_CONN_STATE_OPEN) - smartlist_add(nicknames_up, name); - else - smartlist_add(nicknames_down, name); - } - length = smartlist_len(nicknames_up) + - 2*smartlist_len(nicknames_down) + 1; - /* spaces + EOS + !'s + 1. */ - SMARTLIST_FOREACH(nicknames_up, char *, c, length += strlen(c)); - SMARTLIST_FOREACH(nicknames_down, char *, c, length += strlen(c)); - *nicknames_out = tor_malloc_zero(length); - cp = *nicknames_out; - for (i = 0; i<smartlist_len(nicknames_up); ++i) { - if (i) - strcat(cp, " "); - strcat(cp, (char*)smartlist_get(nicknames_up,i)); /* can't overflow */ - while (*cp) - ++cp; - } - for (i = 0; i<smartlist_len(nicknames_down); ++i) { - strcat(cp, " !"); - strcat(cp, (char*)smartlist_get(nicknames_down,i)); /* can't overflow */ - while (*cp) - ++cp; - } - SMARTLIST_FOREACH(nicknames_up, char *, victim, tor_free(victim)); - SMARTLIST_FOREACH(nicknames_down, char *, victim, tor_free(victim)); - smartlist_free(nicknames_up); - smartlist_free(nicknames_down); + tor_assert(desc); + tor_assert(desc->router); + + cp = buf; + if (!is_live) { + *cp++ = '!'; + } + if (desc->verified) { + strcpy(cp, desc->nickname); + cp += strlen(cp); + if (!rr_format) + *cp++ = '='; + } + if (!desc->verified || !rr_format) { + *cp++ = '$'; + base16_encode(cp, HEX_DIGEST_LEN+1, desc->router->identity_digest, + DIGEST_LEN); + } + return tor_strdup(buf); +} + +/** Allocate the contents of a running-routers line and a router-status line, + * and store them in *<b>running_routers_out</b> and *<b>router_status_out</b> + * respectively. Return 0 on success, -1 on failure. + */ +static int +list_server_status(char **running_routers_out, char **router_status_out) +{ + /* List of entries in running-routers style: An optional !, then either + * a nickname or a dollar-prefixed hexdigest. */ + smartlist_t *rr_entries; + /* List of entries in a router-status style: An optional !, then an optional + * equals-suffixed nickname, then a dollar-prefixed hexdigest. */ + smartlist_t *rs_entries; + + tor_assert(running_routers_out || router_status_out); + + rr_entries = smartlist_create(); + rs_entries = smartlist_create(); + + SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d, + { + int is_live; + tor_assert(d->router); + connection_t *conn = connection_get_by_identity_digest( + d->router->identity_digest, CONN_TYPE_OR); + is_live = (conn && conn->state == OR_CONN_STATE_OPEN); + smartlist_add(rr_entries, list_single_server_status(d, is_live, 1)); + smartlist_add(rs_entries, list_single_server_status(d, is_live, 0)); + }); + + if (running_routers_out) + *running_routers_out = smartlist_join_strings(rr_entries, " ", 0); + if (router_status_out) + *router_status_out = smartlist_join_strings(rs_entries, " ", 0); + + SMARTLIST_FOREACH(rr_entries, char *, cp, tor_free(cp)); + SMARTLIST_FOREACH(rs_entries, char *, cp, tor_free(cp)); + smartlist_free(rr_entries); + smartlist_free(rs_entries); + return 0; } @@ -557,7 +567,8 @@ int dirserv_dump_directory_to_string(char *s, size_t maxlen, crypto_pk_env_t *private_key) { - char *cp, *eos; + char *eos, *cp; + char *running_routers, *router_status; char *identity_pkey; /* Identity key, DER64-encoded. */ char *recommended_versions; char digest[20]; @@ -570,7 +581,7 @@ dirserv_dump_directory_to_string(char *s, size_t maxlen, if (!descriptor_list) descriptor_list = smartlist_create(); - if (list_running_servers(&cp)) + if (list_server_status(&running_routers, &router_status)) return -1; /* ASN.1-encode the public key. This is a temporary measure; once @@ -612,10 +623,13 @@ dirserv_dump_directory_to_string(char *s, size_t maxlen, "published %s\n" "recommended-software %s\n" "running-routers %s\n" + "opt router-status %s\n" "opt dir-signing-key %s\n\n", - published, recommended_versions, cp, identity_pkey); + published, recommended_versions, running_routers, router_status, + identity_pkey); - tor_free(cp); + tor_free(running_routers); + tor_free(router_status); tor_free(identity_pkey); i = strlen(s); cp = s+i; @@ -788,6 +802,7 @@ static size_t runningrouters_len=0; static int generate_runningrouters(crypto_pk_env_t *private_key) { char *s, *cp; + char *router_status; char digest[DIGEST_LEN]; char signature[PK_BYTES]; int i; @@ -798,7 +813,7 @@ static int generate_runningrouters(crypto_pk_env_t *private_key) len = 1024+(MAX_HEX_NICKNAME_LEN+2)*smartlist_len(descriptor_list); s = tor_malloc_zero(len); - if (list_running_servers(&cp)) + if (list_server_status(NULL, &router_status)) return -1; /* ASN.1-encode the public key. This is a temporary measure; once * everyone is running 0.0.9pre3 or later, we can shift to using a @@ -822,12 +837,12 @@ static int generate_runningrouters(crypto_pk_env_t *private_key) format_iso_time(published, published_on); sprintf(s, "network-status\n" "published %s\n" - "running-routers %s\n" + "router-status %s\n" "opt dir-signing-key %s\n" "directory-signature %s\n" "-----BEGIN SIGNATURE-----\n", - published, cp, identity_pkey, options.Nickname); - tor_free(cp); + published, router_status, identity_pkey, options.Nickname); + tor_free(router_status); tor_free(identity_pkey); if (router_get_runningrouters_hash(s,digest)) { log_fn(LOG_WARN,"couldn't compute digest"); |