diff options
author | Nick Mathewson <nickm@torproject.org> | 2005-10-14 04:56:20 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2005-10-14 04:56:20 +0000 |
commit | 6101468cbe28fe50faa82d251ca95c481ed40fe7 (patch) | |
tree | ea37f76c73e208b18549c45bcc7c5f7d11a7b70c /src | |
parent | 998cf8d6222607113fbd8fa8563d507a808ee869 (diff) | |
download | tor-6101468cbe28fe50faa82d251ca95c481ed40fe7.tar tor-6101468cbe28fe50faa82d251ca95c481ed40fe7.tar.gz |
Enable trivial "download by descriptor digest" functionality.
svn:r5250
Diffstat (limited to 'src')
-rw-r--r-- | src/or/directory.c | 32 | ||||
-rw-r--r-- | src/or/dirserv.c | 28 | ||||
-rw-r--r-- | src/or/or.h | 4 | ||||
-rw-r--r-- | src/or/routerlist.c | 26 |
4 files changed, 66 insertions, 24 deletions
diff --git a/src/or/directory.c b/src/or/directory.c index 89ef3b630..1ebd6f126 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -316,7 +316,7 @@ connection_dir_download_networkstatus_failed(connection_t *conn) * failed, and possibly retry them later.*/ smartlist_t *failed = smartlist_create(); dir_split_resource_into_fingerprints(conn->requested_resource+3, - failed, NULL); + failed, NULL, 0); if (smartlist_len(failed)) { dir_networkstatus_download_failed(failed); SMARTLIST_FOREACH(failed, char *, cp, tor_free(cp)); @@ -956,7 +956,7 @@ connection_dir_client_reached_eof(connection_t *conn) !strcmpstart(conn->requested_resource,"fp/")) { which = smartlist_create(); dir_split_resource_into_fingerprints(conn->requested_resource+3, - which, NULL); + which, NULL, 0); } cp = body; while (*cp) { @@ -993,7 +993,7 @@ connection_dir_client_reached_eof(connection_t *conn) !strcmpstart(conn->requested_resource,"fp/")) { which = smartlist_create(); dir_split_resource_into_fingerprints(conn->requested_resource+3, - which, NULL); + which, NULL, 0); n_asked_for = smartlist_len(which); } if (status_code != 200) { @@ -1653,11 +1653,14 @@ dir_routerdesc_download_failed(smartlist_t *failed) /* Given a directory <b>resource</b> request generated by us, containing zero * or more strings separated by plus signs, followed optionally by ".z", store * the strings, in order, into <b>fp_out</b>. If <b>compressed_out</b> is - * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0. + * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0. If + * decode_hex is true, then delete all elements that aren't hex digests, and + * decode the rest. */ int dir_split_resource_into_fingerprints(const char *resource, - smartlist_t *fp_out, int *compressed_out) + smartlist_t *fp_out, int *compressed_out, + int decode_hex) { smartlist_split_string(fp_out, resource, "+", 0, 0); if (compressed_out) @@ -1671,6 +1674,25 @@ dir_split_resource_into_fingerprints(const char *resource, *compressed_out = 1; } } + if (decode_hex) { + int i; + char *cp, *d; + for (i = 0; i < smartlist_len(fp_out); ++i) { + cp = smartlist_get(fp_out, i); + if (strlen(cp) != HEX_DIGEST_LEN) { + smartlist_del(fp_out, i--); + continue; + } + d = tor_malloc_zero(DIGEST_LEN); + if (base16_decode(d, DIGEST_LEN, cp, HEX_DIGEST_LEN)<0) { + tor_free(d); + smartlist_del(fp_out, i--); + continue; + } + tor_free(cp); + smartlist_set(fp_out, i, d); + } + } return 0; } diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 23f4d952c..0cc21af97 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1361,7 +1361,7 @@ dirserv_get_networkstatus_v2(smartlist_t *result, log_fn(LOG_WARN, "Client requested 'all' network status objects; we have none."); } else if (!strcmpstart(key, "fp/")) { smartlist_t *hexdigests = smartlist_create(); - dir_split_resource_into_fingerprints(key+3, hexdigests, NULL); + dir_split_resource_into_fingerprints(key+3, hexdigests, NULL, 0); SMARTLIST_FOREACH(hexdigests, char *, cp, { cached_dir_t *cached; @@ -1403,22 +1403,22 @@ dirserv_get_routerdescs(smartlist_t *descs_out, const char *key) routerinfo_t *ri = router_get_my_routerinfo(); if (ri) smartlist_add(descs_out, ri); + } else if (!strcmpstart(key, "/tor/server/d/")) { + smartlist_t *digests = smartlist_create(); + dir_split_resource_into_fingerprints(key, digests, NULL, 1); + key += strlen("/tor/server/d/"); + SMARTLIST_FOREACH(digests, const char *, d, + { + routerinfo_t *ri = router_get_by_descriptor_digest(d); + if (ri) + smartlist_add(descs_out,ri); + }); + SMARTLIST_FOREACH(digests, char *, d, tor_free(d)); + smartlist_free(digests); } else if (!strcmpstart(key, "/tor/server/fp/")) { - smartlist_t *hexdigests = smartlist_create(); smartlist_t *digests = smartlist_create(); key += strlen("/tor/server/fp/"); - dir_split_resource_into_fingerprints(key, hexdigests, NULL); - SMARTLIST_FOREACH(hexdigests, char *, cp, - { - char *d; - if (strlen(cp) != HEX_DIGEST_LEN) - continue; - d = tor_malloc_zero(DIGEST_LEN); - base16_decode(d, DIGEST_LEN, cp, HEX_DIGEST_LEN); - tor_free(cp); - smartlist_add(digests, d); - }); - smartlist_free(hexdigests); + dir_split_resource_into_fingerprints(key, digests, NULL, 1); SMARTLIST_FOREACH(digests, const char *, d, { if (router_digest_is_me(d)) { diff --git a/src/or/or.h b/src/or/or.h index 635654946..08fdd3de7 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1754,7 +1754,8 @@ void connection_dir_request_failed(connection_t *conn); void parse_dir_policy(void); void free_dir_policy(void); int dir_split_resource_into_fingerprints(const char *resource, - smartlist_t *fp_out, int *compresseed_out); + smartlist_t *fp_out, int *compresseed_out, + int decode_hex); /********************************* dirserv.c ***************************/ @@ -2130,6 +2131,7 @@ routerinfo_t *router_get_by_nickname(const char *nickname, int warn_if_unnamed); routerinfo_t *router_get_by_hexdigest(const char *hexdigest); routerinfo_t *router_get_by_digest(const char *digest); +routerinfo_t *router_get_by_descriptor_digest(const char *digest); int router_digest_is_trusted_dir(const char *digest); void router_get_routerlist(routerlist_t **prouterlist); void routerlist_reset_warnings(void); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index e0c69b65a..e6521e396 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1005,6 +1005,25 @@ router_get_by_digest(const char *digest) return NULL; } + +/** Return the router in our routerlist whose 20-byte descriptor + * is <b>digest</b>. Return NULL if no such router is known. */ +routerinfo_t * +router_get_by_descriptor_digest(const char *digest) +{ + tor_assert(digest); + + if (!routerlist) return NULL; + + SMARTLIST_FOREACH(routerlist->routers, routerinfo_t*, router, + { + if (0 == memcmp(router->signed_descriptor_digest, digest, DIGEST_LEN)) + return router; + }); + + return NULL; +} + /** Set *<b>prouterlist</b> to the current list of all known routers. */ void router_get_routerlist(routerlist_t **prouterlist) @@ -2625,7 +2644,7 @@ router_list_downloadable(void) if (!strcmpstart(conn->requested_resource, "all")) n_downloadable = 0; dir_split_resource_into_fingerprints(conn->requested_resource, - downloading, NULL); + downloading, NULL, 1); } } @@ -2635,11 +2654,9 @@ router_list_downloadable(void) smartlist_sort_strings(downloading); */ if (n_downloadable) { - SMARTLIST_FOREACH(downloading, const char *, dl, + SMARTLIST_FOREACH(downloading, const char *, d, { - char d[DIGEST_LEN]; local_routerstatus_t *rs; - base16_decode(d, DIGEST_LEN, dl, strlen(dl)); if ((rs = router_get_combined_status_by_digest(d)) && rs->should_download) { rs->should_download = 0; --n_downloadable; @@ -2919,3 +2936,4 @@ router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2) /* Otherwise, the difference is cosmetic. */ return 1; } + |