diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/config.c | 33 | ||||
-rw-r--r-- | src/or/or.h | 2 | ||||
-rw-r--r-- | src/or/router.c | 3 | ||||
-rw-r--r-- | src/or/routerlist.c | 131 | ||||
-rw-r--r-- | src/or/routerlist.h | 15 |
5 files changed, 125 insertions, 59 deletions
diff --git a/src/or/config.c b/src/or/config.c index 432038478..a4ccf0741 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -471,8 +471,7 @@ static int parse_client_transport_line(const char *line, int validate_only); static int parse_server_transport_line(const char *line, int validate_only); static char *get_bindaddr_from_transport_listen_line(const char *line, const char *transport); - -static int parse_dir_server_line(const char *line, +static int parse_dir_authority_line(const char *line, dirinfo_type_t required_type, int validate_only); static void port_cfg_free(port_cfg_t *port); @@ -787,7 +786,7 @@ add_default_trusted_dir_authorities(dirinfo_type_t type) NULL }; for (i=0; dirservers[i]; i++) { - if (parse_dir_server_line(dirservers[i], type, 0)<0) { + if (parse_dir_authority_line(dirservers[i], type, 0)<0) { log_err(LD_BUG, "Couldn't parse internal dirserver line %s", dirservers[i]); } @@ -832,16 +831,16 @@ validate_dir_authorities(or_options_t *options, or_options_t *old_options) /* Now go through the four ways you can configure an alternate * set of directory authorities, and make sure none are broken. */ for (cl = options->DirAuthorities; cl; cl = cl->next) - if (parse_dir_server_line(cl->value, NO_DIRINFO, 1)<0) + if (parse_dir_authority_line(cl->value, NO_DIRINFO, 1)<0) return -1; for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next) - if (parse_dir_server_line(cl->value, NO_DIRINFO, 1)<0) + if (parse_dir_authority_line(cl->value, NO_DIRINFO, 1)<0) return -1; for (cl = options->AlternateDirAuthority; cl; cl = cl->next) - if (parse_dir_server_line(cl->value, NO_DIRINFO, 1)<0) + if (parse_dir_authority_line(cl->value, NO_DIRINFO, 1)<0) return -1; for (cl = options->AlternateHSAuthority; cl; cl = cl->next) - if (parse_dir_server_line(cl->value, NO_DIRINFO, 1)<0) + if (parse_dir_authority_line(cl->value, NO_DIRINFO, 1)<0) return -1; return 0; } @@ -885,16 +884,16 @@ consider_adding_dir_authorities(const or_options_t *options, } for (cl = options->DirAuthorities; cl; cl = cl->next) - if (parse_dir_server_line(cl->value, NO_DIRINFO, 0)<0) + if (parse_dir_authority_line(cl->value, NO_DIRINFO, 0)<0) return -1; for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next) - if (parse_dir_server_line(cl->value, NO_DIRINFO, 0)<0) + if (parse_dir_authority_line(cl->value, NO_DIRINFO, 0)<0) return -1; for (cl = options->AlternateDirAuthority; cl; cl = cl->next) - if (parse_dir_server_line(cl->value, NO_DIRINFO, 0)<0) + if (parse_dir_authority_line(cl->value, NO_DIRINFO, 0)<0) return -1; for (cl = options->AlternateHSAuthority; cl; cl = cl->next) - if (parse_dir_server_line(cl->value, NO_DIRINFO, 0)<0) + if (parse_dir_authority_line(cl->value, NO_DIRINFO, 0)<0) return -1; return 0; } @@ -4324,15 +4323,15 @@ parse_server_transport_line(const char *line, int validate_only) return r; } -/** Read the contents of a DirServer line from <b>line</b>. If +/** Read the contents of a DirAuthority line from <b>line</b>. If * <b>validate_only</b> is 0, and the line is well-formed, and it * shares any bits with <b>required_type</b> or <b>required_type</b> * is 0, then add the dirserver described in the line (minus whatever * bits it's missing) as a valid authority. Return 0 on success, * or -1 if the line isn't well-formed or if we can't add it. */ static int -parse_dir_server_line(const char *line, dirinfo_type_t required_type, - int validate_only) +parse_dir_authority_line(const char *line, dirinfo_type_t required_type, + int validate_only) { smartlist_t *items = NULL; int r; @@ -4433,14 +4432,16 @@ parse_dir_server_line(const char *line, dirinfo_type_t required_type, } if (!validate_only && (!required_type || required_type & type)) { + dir_server_t *ds; if (required_type) type &= required_type; /* pare down what we think of them as an * authority for. */ log_debug(LD_DIR, "Trusted %d dirserver at %s:%d (%s)", (int)type, address, (int)dir_port, (char*)smartlist_get(items,0)); - if (!add_trusted_dir_server(nickname, address, dir_port, or_port, - digest, v3_digest, type)) + if (!(ds = trusted_dir_server_new(nickname, address, dir_port, or_port, + digest, v3_digest, type))) goto err; + dir_server_add(ds); } r = 0; diff --git a/src/or/or.h b/src/or/or.h index a90cd6702..70490a6e0 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2517,6 +2517,8 @@ typedef enum { MICRODESC_DIRINFO=1 << 6, } dirinfo_type_t; +#define ALL_DIRINFO ((dirinfo_type_t)((1<<7)-1)) + #define CRYPT_PATH_MAGIC 0x70127012u /** Holds accounting information for a single step in the layered encryption diff --git a/src/or/router.c b/src/or/router.c index 7d069f9fa..34eb66af1 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -732,7 +732,7 @@ init_keys(void) ds = router_get_trusteddirserver_by_digest(digest); if (!ds) { - ds = add_trusted_dir_server(options->Nickname, NULL, + ds = trusted_dir_server_new(options->Nickname, NULL, router_get_advertised_dir_port(options, 0), router_get_advertised_or_port(options), digest, @@ -743,6 +743,7 @@ init_keys(void) "couldn't add ourselves to the authority list. Failing."); return -1; } + dir_server_add(ds); } if (ds->type != type) { log_warn(LD_DIR, "Configured authority type does not match authority " diff --git a/src/or/routerlist.c b/src/or/routerlist.c index b095b4d2a..ac4e46d7a 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -53,7 +53,7 @@ static const routerstatus_t *router_pick_dirserver_generic( static void mark_all_dirservers_up(smartlist_t *server_list); static int router_nickname_matches(const routerinfo_t *router, const char *nickname); -static void trusted_dir_server_free(dir_server_t *ds); +static void dir_server_free(dir_server_t *ds); static int signed_desc_digest_is_recognized(signed_descriptor_t *desc); static const char *signed_descriptor_get_body_impl( const signed_descriptor_t *desc, @@ -3774,49 +3774,41 @@ router_exit_policy_rejects_all(const routerinfo_t *router) return router->policy_is_reject_star; } -/** Add to the list of authoritative directory servers one at - * <b>address</b>:<b>port</b>, with identity key <b>digest</b>. If - * <b>address</b> is NULL, add ourself. Return the new trusted directory - * server entry on success or NULL if we couldn't add it. */ -dir_server_t * -add_trusted_dir_server(const char *nickname, const char *address, - uint16_t dir_port, uint16_t or_port, - const char *digest, const char *v3_auth_digest, - dirinfo_type_t type) +/** Create an directory server at <b>address</b>:<b>port</b>, with OR identity + * key <b>digest</b>. If <b>address</b> is NULL, add ourself. If + * <b>is_authority</b>, this is a directory authority. Return the new + * directory server entry on success or NULL on failure. */ +static dir_server_t * +dir_server_new(int is_authority, + const char *nickname, + const tor_addr_t *addr, + const char *hostname, + uint16_t dir_port, uint16_t or_port, + const char *digest, const char *v3_auth_digest, + dirinfo_type_t type) { dir_server_t *ent; uint32_t a; - char *hostname = NULL; - if (!trusted_dir_servers) - trusted_dir_servers = smartlist_new(); - if (!fallback_dir_servers) - trusted_dir_servers = smartlist_new(); + char *hostname_ = NULL; - if (!address) { /* The address is us; we should guess. */ - if (resolve_my_address(LOG_WARN, get_options(), &a, &hostname) < 0) { - log_warn(LD_CONFIG, - "Couldn't find a suitable address when adding ourself as a " - "trusted directory server."); - return NULL; - } - } else { - if (tor_lookup_hostname(address, &a)) { - log_warn(LD_CONFIG, - "Unable to lookup address for directory server at '%s'", - address); - return NULL; - } - hostname = tor_strdup(address); - } + if (tor_addr_family(addr) == AF_INET) + a = tor_addr_to_ipv4h(addr); + else + return NULL; /*XXXX Support IPv6 */ + + if (!hostname) + hostname_ = tor_dup_addr(addr); + else + hostname_ = tor_strdup(hostname); ent = tor_malloc_zero(sizeof(dir_server_t)); ent->nickname = nickname ? tor_strdup(nickname) : NULL; - ent->address = hostname; + ent->address = hostname_; ent->addr = a; ent->dir_port = dir_port; ent->or_port = or_port; ent->is_running = 1; - ent->is_authority = 1; + ent->is_authority = is_authority; ent->type = type; memcpy(ent->digest, digest, DIGEST_LEN); if (v3_auth_digest && (type & V3_DIRINFO)) @@ -3839,10 +3831,75 @@ add_trusted_dir_server(const char *nickname, const char *address, ent->fake_status.dir_port = ent->dir_port; ent->fake_status.or_port = ent->or_port; - smartlist_add(trusted_dir_servers, ent); + return ent; +} + +/** Create an authoritative directory server at + * <b>address</b>:<b>port</b>, with identity key <b>digest</b>. If + * <b>address</b> is NULL, add ourself. Return the new trusted directory + * server entry on success or NULL if we couldn't add it. */ +dir_server_t * +trusted_dir_server_new(const char *nickname, const char *address, + uint16_t dir_port, uint16_t or_port, + const char *digest, const char *v3_auth_digest, + dirinfo_type_t type) +{ + uint32_t a; + tor_addr_t addr; + char *hostname=NULL; + dir_server_t *result; + + if (!address) { /* The address is us; we should guess. */ + if (resolve_my_address(LOG_WARN, get_options(), &a, &hostname) < 0) { + log_warn(LD_CONFIG, + "Couldn't find a suitable address when adding ourself as a " + "trusted directory server."); + return NULL; + } + } else { + if (tor_lookup_hostname(address, &a)) { + log_warn(LD_CONFIG, + "Unable to lookup address for directory server at '%s'", + address); + return NULL; + } + hostname = tor_strdup(address); + } + tor_addr_from_ipv4h(&addr, a); + + result = dir_server_new(1, nickname, &addr, hostname, + dir_port, or_port, digest, + v3_auth_digest, type); + tor_free(hostname); + return result; +} + +/** Return a new dir_server_t for a fallback directory server at + * <b>addr</b>:<b>or_port</b>/<b>dir_port</b>, with identity key digest + * <b>id_digest</b> */ +dir_server_t * +fallback_dir_server_new(const tor_addr_t *addr, + uint16_t dir_port, uint16_t or_port, + const char *id_digest) +{ + return dir_server_new(0, NULL, addr, NULL, dir_port, or_port, id_digest, + NULL, ALL_DIRINFO); +} + +/** Add a directory server to the global list(s). */ +void +dir_server_add(dir_server_t *ent) +{ + if (!trusted_dir_servers) + trusted_dir_servers = smartlist_new(); + if (!fallback_dir_servers) + fallback_dir_servers = smartlist_new(); + + if (ent->is_authority) + smartlist_add(trusted_dir_servers, ent); + smartlist_add(fallback_dir_servers, ent); router_dir_info_changed(); - return ent; } /** Free storage held in <b>cert</b>. */ @@ -3861,7 +3918,7 @@ authority_cert_free(authority_cert_t *cert) /** Free storage held in <b>ds</b>. */ static void -trusted_dir_server_free(dir_server_t *ds) +dir_server_free(dir_server_t *ds) { if (!ds) return; @@ -3878,7 +3935,7 @@ clear_dir_servers(void) { if (fallback_dir_servers) { SMARTLIST_FOREACH(fallback_dir_servers, dir_server_t *, ent, - trusted_dir_server_free(ent)); + dir_server_free(ent)); smartlist_clear(fallback_dir_servers); } else { fallback_dir_servers = smartlist_new(); diff --git a/src/or/routerlist.h b/src/or/routerlist.h index 95867552c..1d527d022 100644 --- a/src/or/routerlist.h +++ b/src/or/routerlist.h @@ -132,11 +132,16 @@ void router_load_extrainfo_from_string(const char *s, const char *eos, void routerlist_retry_directory_downloads(time_t now); int router_exit_policy_rejects_all(const routerinfo_t *router); -dir_server_t *add_trusted_dir_server(const char *nickname, - const char *address, - uint16_t dir_port, uint16_t or_port, - const char *digest, const char *v3_auth_digest, - dirinfo_type_t type); + +dir_server_t *trusted_dir_server_new(const char *nickname, const char *address, + uint16_t dir_port, uint16_t or_port, + const char *digest, const char *v3_auth_digest, + dirinfo_type_t type); +dir_server_t *fallback_dir_server_new(const tor_addr_t *addr, + uint16_t dir_port, uint16_t or_port, + const char *id_digest); +void dir_server_add(dir_server_t *ent); + void authority_cert_free(authority_cert_t *cert); void clear_dir_servers(void); int any_trusted_dir_is_v1_authority(void); |