diff options
-rw-r--r-- | src/common/compat.h | 2 | ||||
-rw-r--r-- | src/common/util.c | 15 | ||||
-rw-r--r-- | src/common/util.h | 1 | ||||
-rw-r--r-- | src/or/config.c | 15 | ||||
-rw-r--r-- | src/or/control.c | 63 | ||||
-rw-r--r-- | src/or/directory.c | 8 | ||||
-rw-r--r-- | src/or/dirserv.c | 101 | ||||
-rw-r--r-- | src/or/or.h | 23 | ||||
-rw-r--r-- | src/or/router.c | 17 | ||||
-rw-r--r-- | src/or/routerlist.c | 39 | ||||
-rw-r--r-- | src/or/routerparse.c | 16 |
11 files changed, 206 insertions, 94 deletions
diff --git a/src/common/compat.h b/src/common/compat.h index f813becbcb..801f1893f2 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -86,6 +86,8 @@ int tor_snprintf(char *str, size_t size, const char *format, ...) CHECK_PRINTF(3,4); int tor_vsnprintf(char *str, size_t size, const char *format, va_list args); +#define TOR_ISAPLHA(c) isalpha((int)(unsigned char)(c)) +#define TOR_ISALNUM(c) isalnum((int)(unsigned char)(c)) #define TOR_ISSPACE(c) isspace((int)(unsigned char)(c)) #define TOR_ISXDIGIT(c) isxdigit((int)(unsigned char)(c)) #define TOR_ISDIGIT(c) isdigit((int)(unsigned char)(c)) diff --git a/src/common/util.c b/src/common/util.c index 339572e449..50e81603de 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1266,6 +1266,21 @@ tor_inet_ntoa(struct in_addr *in, char *buf, size_t buf_len) (int)(uint8_t)((a )&0xff)); } +/* DOCDOC */ +int +is_plausible_address(const char *name) +{ + const char *cp; + tor_assert(name); + /* We could check better here. */ + for (cp=name; *cp; cp++) { + if (*cp != '.' && *cp != '-' && !TOR_ISALNUM(*cp)) + return 0; + } + + return 1; +} + /* ===== * Process helpers * ===== */ diff --git a/src/common/util.h b/src/common/util.h index fde2557f58..65c0f105ae 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -128,6 +128,7 @@ int parse_addr_and_port_range(const char *s, uint32_t *addr_out, uint16_t *port_max_out); #define INET_NTOA_BUF_LEN 16 int tor_inet_ntoa(struct in_addr *in, char *buf, size_t buf_len); +int is_plausible_address(const char *name); /* Process helpers */ void start_daemon(const char *desired_cwd); diff --git a/src/or/config.c b/src/or/config.c index d55af562d6..4ae2476b86 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -123,7 +123,7 @@ static config_var_t config_vars[] = { VAR("ExcludeNodes", STRING, ExcludeNodes, NULL), VAR("TrackHostExits", CSV, TrackHostExits, NULL), VAR("TrackHostExitsExpire",INTERVAL, TrackHostExitsExpire, "30 minutes"), - VAR("AddressMap", LINELIST, AddressMap, NULL), + VAR("MapAddress", LINELIST, AddressMap, NULL), VAR("FascistFirewall", BOOL, FascistFirewall, "0"), VAR("FirewallPorts", CSV, FirewallPorts, "80,443"), VAR("MyFamily", STRING, MyFamily, NULL), @@ -1824,9 +1824,18 @@ config_register_addressmaps(or_options_t *options) { if (smartlist_len(elts) >= 2) { from = smartlist_get(elts,0); to = smartlist_get(elts,1); - addressmap_register(from, tor_strdup(to), 0); + if (!is_plausible_address(from)) { + log_fn(LOG_WARN,"Skipping invalid argument '%s' to MapAddress",from); + } else if (!is_plausible_address(to)) { + log_fn(LOG_WARN,"Skipping invalid argument '%s' to MapAddress",to); + } else { + addressmap_register(from, tor_strdup(to), 0); + if (smartlist_len(elts)>2) { + log_fn(LOG_WARN,"Ignoring extra arguments to MapAddress."); + } + } } else { - log_fn(LOG_WARN,"AddressMap '%s' has too few arguments. Ignoring.", opt->value); + log_fn(LOG_WARN,"MapAddress '%s' has too few arguments. Ignoring.", opt->value); } SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp)); smartlist_clear(elts); diff --git a/src/or/control.c b/src/or/control.c index ebcce1e73d..27498d4ca2 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -117,6 +117,7 @@ static void update_global_event_mask(void); static void send_control_message(connection_t *conn, uint16_t type, uint16_t len, const char *body); static void send_control_done(connection_t *conn); +static void send_control_done2(connection_t *conn, const char *msg, size_t len); static void send_control_error(connection_t *conn, uint16_t error, const char *message); static void send_control_event(uint16_t event, uint16_t len, const char *body); @@ -192,6 +193,11 @@ send_control_done(connection_t *conn) send_control_message(conn, CONTROL_CMD_DONE, 0, NULL); } +static void send_control_done2(connection_t *conn, const char *msg, size_t len) +{ + send_control_message(conn, CONTROL_CMD_DONE, len, msg); +} + /** Send an error message with error code <b>error</b> and body * <b>message</b> down the connection <b>conn</b> */ static void @@ -445,7 +451,46 @@ handle_control_signal(connection_t *conn, uint16_t len, static int handle_control_mapaddress(connection_t *conn, uint16_t len, const char *body) { - send_control_error(conn,ERR_UNRECOGNIZED_TYPE,"not yet implemented"); + smartlist_t *elts; + smartlist_t *lines; + smartlist_t *reply; + char *r; + size_t sz; + lines = smartlist_create(); + elts = smartlist_create(); + reply = smartlist_create(); + smartlist_split_string(lines, body, "\n", + SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); + SMARTLIST_FOREACH(lines, const char *, line, + { + smartlist_split_string(elts, body, " ", 0, 2); + if (smartlist_len(elts) == 2) { + const char *from = smartlist_get(elts,0); + const char *to = smartlist_get(elts,1); + if (!is_plausible_address(from)) { + log_fn(LOG_WARN,"Skipping invalid argument '%s' in MapAddress msg",from); + } else if (!is_plausible_address(to)) { + log_fn(LOG_WARN,"Skipping invalid argument '%s' in AddressMap msg",to); + } else { + addressmap_register(from, tor_strdup(to), 0); + smartlist_add(reply, tor_strdup(line)); + } + } else { + log_fn(LOG_WARN, "Skipping MapAddress line with wrong number of items."); + } + SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp)); + smartlist_clear(elts); + }); + SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp)); + smartlist_free(lines); + smartlist_free(elts); + + r = smartlist_join_strings(reply, "\n", 1, &sz); + send_control_done2(conn,sz,r); + + SMARTLIST_FOREACH(reply, char *, cp, tor_free(cp)); + smartlist_free(reply); + tor_free(r); return 0; } @@ -455,7 +500,12 @@ handle_getinfo_helper(const char *question) if (!strcmp(question, "version")) { return tor_strdup(VERSION); } else if (!strcmpstart(question, "desc/id/")) { - return NULL; /* XXXX */ + routerinfo_t *ri = router_get_by_hexdigest(question+strlen("desc/id/")); + if (!ri) + return NULL; + if (!ri->signed_descriptor) + return NULL; + return tor_strdup(ri->signed_descriptor); } else if (!strcmp(question, "desc/all-ids")) { routerlist_t *rl; char *answer, *cp; @@ -540,7 +590,14 @@ static int handle_control_postdescriptor(connection_t *conn, uint16_t len, const char *body) { - send_control_error(conn,ERR_UNRECOGNIZED_TYPE,"not yet implemented"); + if (router_load_single_router(body)<0) { + /* XXXX a more specific error would be nice. */ + send_control_error(conn,ERR_UNSPECIFIED, + "Could not parse descriptor or add it"); + return 0; + } + + send_control_done(conn); return 0; } diff --git a/src/or/directory.c b/src/or/directory.c index b81f38d8ca..a9cb64ee7a 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -723,9 +723,11 @@ connection_dir_client_reached_eof(connection_t *conn) return -1; } router_get_routerlist(&rl); - if (rl) - routerlist_update_from_runningrouters(rl,rrs); - running_routers_free(rrs); + if (rl) { + routerlist_set_runningrouters(rl,rrs); + } else { + running_routers_free(rrs); + } } if (conn->purpose == DIR_PURPOSE_UPLOAD_DIR) { diff --git a/src/or/dirserv.c b/src/or/dirserv.c index dac5105ab5..e1da307e14 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -249,29 +249,12 @@ dirserv_free_fingerprint_list() * Descriptor list */ -/** A directory server's view of a server descriptor. Contains both - * parsed and unparsed versions. */ -typedef struct descriptor_entry_t { - char *nickname; - time_t published; - size_t desc_len; - char *descriptor; - int verified; - routerinfo_t *router; -} descriptor_entry_t; - -/** List of all server descriptors that this dirserv is holding. */ +/** List of routerinfo_t for all server descriptors that this dirserv + * is holding. + * XXXX This should eventually get coalesced into routerlist.c + */ static smartlist_t *descriptor_list = NULL; -/** Release the storage held by <b>desc</b> */ -static void free_descriptor_entry(descriptor_entry_t *desc) -{ - tor_free(desc->descriptor); - tor_free(desc->nickname); - routerinfo_free(desc->router); - tor_free(desc); -} - /** Release all storage that the dirserv is holding for server * descriptors. */ void @@ -279,8 +262,8 @@ dirserv_free_descriptors() { if (!descriptor_list) return; - SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d, - free_descriptor_entry(d)); + SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri, + routerinfo_free(ri)); smartlist_clear(descriptor_list); } @@ -319,12 +302,10 @@ dirserv_router_has_valid_address(routerinfo_t *ri) int dirserv_add_descriptor(const char **desc, const char **msg) { - descriptor_entry_t *ent = NULL; - routerinfo_t *ri = NULL; + routerinfo_t *ri = NULL, *ri_old=NULL; int i, r, found=-1; char *start, *end; char *desc_tmp = NULL; - const char *cp; size_t desc_len; time_t now; int verified=1; /* whether we knew its fingerprint already */ @@ -346,10 +327,10 @@ dirserv_add_descriptor(const char **desc, const char **msg) end = start+strlen(start); } desc_len = end-start; - cp = desc_tmp = tor_strndup(start, desc_len); + desc_tmp = tor_strndup(start, desc_len); /* Is this strndup still needed???*/ /* Check: is the descriptor syntactically valid? */ - ri = router_parse_entry_from_string(cp, NULL); + ri = router_parse_entry_from_string(desc_tmp, NULL); tor_free(desc_tmp); if (!ri) { log(LOG_WARN, "Couldn't parse descriptor"); @@ -402,15 +383,15 @@ dirserv_add_descriptor(const char **desc, const char **msg) /* Do we already have an entry for this router? */ for (i = 0; i < smartlist_len(descriptor_list); ++i) { - ent = smartlist_get(descriptor_list, i); - if (!strcasecmp(ri->nickname, ent->nickname)) { + ri_old = smartlist_get(descriptor_list, i); + if (!strcasecmp(ri->nickname, ri_old->nickname)) { found = i; break; } } if (found >= 0) { /* if so, decide whether to update it. */ - if (ent->published >= ri->published_on) { + if (ri_old->published_on >= ri->published_on) { /* We already have a newer or equal-time descriptor */ log_fn(LOG_INFO,"We already have a new enough desc for nickname '%s'. Not adding.",ri->nickname); *msg = "We already have a newer descriptor."; @@ -419,10 +400,10 @@ dirserv_add_descriptor(const char **desc, const char **msg) *desc = end; return verified; } - /* We don't have a newer one; we'll update this one. */ + /* We don't alrady have a newer one; we'll update this one. */ log_fn(LOG_INFO,"Dirserv updating desc for nickname '%s'",ri->nickname); *msg = verified?"Verified server updated":"Unverified server updated. (Have you sent us your key fingerprint?)"; - free_descriptor_entry(ent); + routerinfo_free(ri_old); smartlist_del_keeporder(descriptor_list, found); } else { /* Add at the end. */ @@ -430,14 +411,8 @@ dirserv_add_descriptor(const char **desc, const char **msg) *msg = verified?"Verified server added":"Unverified server added. (Have you sent us your key fingerprint?)"; } - ent = tor_malloc(sizeof(descriptor_entry_t)); - ent->nickname = tor_strdup(ri->nickname); - ent->published = ri->published_on; - ent->desc_len = desc_len; - ent->descriptor = tor_strndup(start,desc_len); - ent->router = ri; - ent->verified = verified; - smartlist_add(descriptor_list, ent); + ri->is_verified = verified; + smartlist_add(descriptor_list, ri); *desc = end; directory_set_dirty(); @@ -453,16 +428,16 @@ static void directory_remove_unrecognized(void) { int i; - descriptor_entry_t *ent; + routerinfo_t *ent; if (!descriptor_list) descriptor_list = smartlist_create(); for (i = 0; i < smartlist_len(descriptor_list); ++i) { ent = smartlist_get(descriptor_list, i); - if (dirserv_router_fingerprint_is_known(ent->router)<=0) { + if (dirserv_router_fingerprint_is_known(ent)<=0) { log(LOG_INFO, "Router '%s' is no longer recognized", ent->nickname); - free_descriptor_entry(ent); + routerinfo_free(ent); smartlist_del(descriptor_list, i--); } } @@ -510,28 +485,27 @@ dirserv_load_from_directory_string(const char *dir) * as running iff <b>is_live</b> is true. */ static char * -list_single_server_status(descriptor_entry_t *desc, int is_live, +list_single_server_status(routerinfo_t *desc, int is_live, int rr_format) { char buf[MAX_NICKNAME_LEN+HEX_DIGEST_LEN+4]; /* !nickname=$hexdigest\0 */ char *cp; tor_assert(desc); - tor_assert(desc->router); cp = buf; if (!is_live) { *cp++ = '!'; } - if (desc->verified) { + if (desc->is_verified) { strlcpy(cp, desc->nickname, sizeof(buf)-(cp-buf)); cp += strlen(cp); if (!rr_format) *cp++ = '='; } - if (!desc->verified || !rr_format) { + if (!desc->is_verified || !rr_format) { *cp++ = '$'; - base16_encode(cp, HEX_DIGEST_LEN+1, desc->router->identity_digest, + base16_encode(cp, HEX_DIGEST_LEN+1, desc->identity_digest, DIGEST_LEN); } return tor_strdup(buf); @@ -556,20 +530,19 @@ list_server_status(char **running_routers_out, char **router_status_out) rr_entries = smartlist_create(); rs_entries = smartlist_create(); - SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d, + SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri, { int is_live; connection_t *conn; - tor_assert(d->router); conn = connection_get_by_identity_digest( - d->router->identity_digest, CONN_TYPE_OR); + ri->identity_digest, CONN_TYPE_OR); /* Treat a router as alive if * - It's me, and I'm not hibernating. * or - we're connected to it. */ - is_live = (router_is_me(d->router) && !we_are_hibernating()) || + is_live = (router_is_me(ri) && !we_are_hibernating()) || (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)); + smartlist_add(rr_entries, list_single_server_status(ri, is_live, 1)); + smartlist_add(rs_entries, list_single_server_status(ri, is_live, 0)); }); if (running_routers_out) @@ -593,16 +566,16 @@ dirserv_remove_old_servers(int age) { int i; time_t cutoff; - descriptor_entry_t *ent; + routerinfo_t *ent; if (!descriptor_list) descriptor_list = smartlist_create(); cutoff = time(NULL) - age; for (i = 0; i < smartlist_len(descriptor_list); ++i) { ent = smartlist_get(descriptor_list, i); - if (ent->published <= cutoff) { + if (ent->published_on <= cutoff) { /* descriptor_list[i] is too old. Remove it. */ - free_descriptor_entry(ent); + routerinfo_free(ent); smartlist_del(descriptor_list, i--); directory_set_dirty(); } @@ -677,8 +650,8 @@ dirserv_dump_directory_to_string(char **dir_out, buf_len = 2048+strlen(recommended_versions)+strlen(running_routers)+ strlen(router_status); - SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d, - buf_len += strlen(d->descriptor)); + SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri, + buf_len += strlen(ri->signed_descriptor)); buf = tor_malloc(buf_len); /* We'll be comparing against buf_len throughout the rest of the function, though strictly speaking we shouldn't be able to exceed @@ -702,8 +675,8 @@ dirserv_dump_directory_to_string(char **dir_out, i = strlen(buf); cp = buf+i; - SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d, - if (strlcat(buf, d->descriptor, buf_len) >= buf_len) + SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri, + if (strlcat(buf, ri->signed_descriptor, buf_len) >= buf_len) goto truncated); /* These multiple strlcat calls are inefficient, but dwarfed by the RSA @@ -1010,8 +983,8 @@ dirserv_free_all(void) fingerprint_list = NULL; } if (descriptor_list) { - SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t*, d, - free_descriptor_entry(d)); + SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri, + routerinfo_free(ri)); smartlist_free(descriptor_list); descriptor_list = NULL; } diff --git a/src/or/or.h b/src/or/or.h index d864115b84..21db3f5fc9 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -620,6 +620,8 @@ typedef struct addr_policy_t { /** Information about another onion router in the network. */ typedef struct { + char *signed_descriptor; /**< The original signed descriptor for this router*/ + char *address; /**< Location of OR: either a hostname or an IP address. */ char *nickname; /**< Human-readable OR name. */ @@ -654,6 +656,14 @@ typedef struct { * claims are its family. */ } routerinfo_t; +/** Contents of a running-routers list */ +typedef struct running_routers_t { + time_t published_on; /**< When was the list marked as published? */ + /** Which ORs are on the list? Entries may be prefixed with ! and $. */ + smartlist_t *running_routers; + int is_running_routers_format; /**< Are we using the old entry format? */ +} running_routers_t; + /** Contents of a directory of onion routers. */ typedef struct { /** List of routerinfo_t */ @@ -665,18 +675,13 @@ typedef struct { */ time_t published_on; time_t running_routers_updated_on; + /** DOCDOC + */ + running_routers_t *running_routers; /** Which router is claimed to have signed it? */ char *signing_router; } routerlist_t; -/** Contents of a running-routers list */ -typedef struct running_routers_t { - time_t published_on; /**< When was the list marked as published? */ - /** Which ORs are on the list? Entries may be prefixed with ! and $. */ - smartlist_t *running_routers; - int is_running_routers_format; /**< Are we using the old entry format? */ -} running_routers_t; - /** Holds accounting information for a single step in the layered encryption * performed by a circuit. Used only at the client edge of a circuit. */ struct crypt_path_t { @@ -1696,6 +1701,7 @@ void free_trusted_dir_servers(void); routerinfo_t *routerinfo_copy(const routerinfo_t *router); void router_mark_as_down(const char *digest); void routerlist_remove_old_routers(int age); +int router_load_single_router(const char *s); int router_load_routerlist_from_directory(const char *s,crypto_pk_env_t *pkey, int dir_is_recent, int dir_is_cached); int router_compare_addr_to_addr_policy(uint32_t addr, uint16_t port, @@ -1708,6 +1714,7 @@ int router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port, int router_exit_policy_rejects_all(routerinfo_t *router); void running_routers_free(running_routers_t *rr); +void routerlist_set_runningrouters(routerlist_t *list, running_routers_t *rr); void routerlist_update_from_runningrouters(routerlist_t *list, running_routers_t *rr); int routers_update_status_from_entry(smartlist_t *routers, diff --git a/src/or/router.c b/src/or/router.c index ebcf7b56c1..c8b2d2a83c 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -427,8 +427,6 @@ int router_is_clique_mode(routerinfo_t *router) { /** My routerinfo. */ static routerinfo_t *desc_routerinfo = NULL; -/** String representation of my descriptor, signed by me. */ -static char descriptor[8192]; /** Boolean: do we need to regenerate the above? */ static int desc_is_dirty = 1; /** Boolean: do we need to regenerate the above? */ @@ -527,8 +525,8 @@ const char *router_get_my_descriptor(void) { if (router_rebuild_descriptor(1)) return NULL; } - log_fn(LOG_DEBUG,"my desc is '%s'",descriptor); - return descriptor; + log_fn(LOG_DEBUG,"my desc is '%s'",desc_routerinfo->signed_descriptor); + return desc_routerinfo->signed_descriptor; } /** Rebuild a fresh routerinfo and signed server descriptor for this @@ -579,14 +577,17 @@ int router_rebuild_descriptor(int force) { smartlist_split_string(ri->declared_family, options->MyFamily, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); } + ri->signed_descriptor = tor_malloc(8192); + if (router_dump_router_to_string(ri->signed_descriptor, 8192, + ri, get_identity_key())<0) { + log_fn(LOG_WARN, "Couldn't dump router to string."); + return -1; + } if (desc_routerinfo) routerinfo_free(desc_routerinfo); desc_routerinfo = ri; - if (router_dump_router_to_string(descriptor, 8192, ri, get_identity_key())<0) { - log_fn(LOG_WARN, "Couldn't dump router to string."); - return -1; - } + desc_is_dirty = 0; desc_needs_upload = 1; return 0; diff --git a/src/or/routerlist.c b/src/or/routerlist.c index d2de86eb0f..d3b9ebb295 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -659,6 +659,7 @@ void routerinfo_free(routerinfo_t *router) if (!router) return; + tor_free(router->signed_descriptor); tor_free(router->address); tor_free(router->nickname); tor_free(router->platform); @@ -713,6 +714,7 @@ void routerlist_free(routerlist_t *rl) SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r, routerinfo_free(r)); smartlist_free(rl->routers); + running_routers_free(rl->running_routers); tor_free(rl->software_versions); tor_free(rl); } @@ -856,6 +858,29 @@ routerlist_remove_old_routers(int age) /* * Code to parse router descriptors and directories. */ +int +router_load_single_router(const char *s) +{ + routerinfo_t *ri; + + if (!(ri = router_parse_entry_from_string(s, NULL))) { + log_fn(LOG_WARN, "Error parsing router descriptor; dropping."); + return -1; + } + if (routerlist && routerlist->running_routers) { + running_routers_t *rr = routerlist->running_routers; + router_update_status_from_smartlist(ri, + rr->published_on, + rr->running_routers, + rr->is_running_routers_format); + } + if (router_add_to_routerlist(ri)<0) { + log_fn(LOG_WARN, "Couldn't add router to list; dropping."); + return -1; + } + log_fn(LOG_DEBUG, "Added router to list"); + return 0; +} /** Add to the current routerlist each router stored in the * signed directory <b>s</b>. If pkey is provided, check the signature against @@ -1137,7 +1162,8 @@ int router_exit_policy_rejects_all(routerinfo_t *router) { /** Release all space held in <b>rr</b>. */ void running_routers_free(running_routers_t *rr) { - tor_assert(rr); + if (!rr) + return; if (rr->running_routers) { SMARTLIST_FOREACH(rr->running_routers, char *, s, tor_free(s)); smartlist_free(rr->running_routers); @@ -1145,6 +1171,17 @@ void running_routers_free(running_routers_t *rr) tor_free(rr); } +/** DOCDOC*/ +void +routerlist_set_runningrouters(routerlist_t *list, running_routers_t *rr) +{ + routerlist_update_from_runningrouters(list,rr); + if (list->running_routers != rr) { + running_routers_free(list->running_routers); + list->running_routers = rr; + } +} + /** Update the running/not-running status of every router in <b>list</b>, based * on the contents of <b>rr</b>. */ /* Note: this function is not yet used, since nobody publishes just diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 0cb996c17b..d4b5cba49a 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -312,6 +312,7 @@ router_parse_routerlist_from_directory(const char *str, char digest[DIGEST_LEN]; routerlist_t *new_dir = NULL; char *versions = NULL; + int nickname_list_is_running_routers; smartlist_t *good_nickname_list = NULL; time_t published_on; int i, r; @@ -426,6 +427,7 @@ router_parse_routerlist_from_directory(const char *str, } } + nickname_list_is_running_routers = (tok->tp == K_RUNNING_ROUTERS); good_nickname_list = smartlist_create(); for (i=0; i<tok->n_args; ++i) { smartlist_add(good_nickname_list, tok->args[i]); @@ -459,6 +461,11 @@ router_parse_routerlist_from_directory(const char *str, new_dir->software_versions = versions; versions = NULL; new_dir->published_on = published_on; + new_dir->running_routers = tor_malloc_zero(sizeof(running_routers_t)); + new_dir->running_routers->published_on = published_on; + new_dir->running_routers->running_routers = good_nickname_list; + new_dir->running_routers->is_running_routers_format = + nickname_list_is_running_routers; SMARTLIST_FOREACH(tokens, directory_token_t *, tok, token_free(tok)); smartlist_free(tokens); @@ -475,16 +482,16 @@ router_parse_routerlist_from_directory(const char *str, if (new_dir) routerlist_free(new_dir); tor_free(versions); + if (good_nickname_list) { + SMARTLIST_FOREACH(good_nickname_list, char *, n, tor_free(n)); + smartlist_free(good_nickname_list); + } done: if (declared_key) crypto_free_pk_env(declared_key); if (tokens) { SMARTLIST_FOREACH(tokens, directory_token_t *, tok, token_free(tok)); smartlist_free(tokens); } - if (good_nickname_list) { - SMARTLIST_FOREACH(good_nickname_list, char *, n, tor_free(n)); - smartlist_free(good_nickname_list); - } return r; } @@ -802,6 +809,7 @@ routerinfo_t *router_parse_entry_from_string(const char *s, } router = tor_malloc_zero(sizeof(routerinfo_t)); + router->signed_descriptor = tor_strndup(s, end-s); ports_set = bw_set = 0; if (tok->n_args == 2 || tok->n_args == 5 || tok->n_args == 6) { |