aboutsummaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2005-10-14 04:56:20 +0000
committerNick Mathewson <nickm@torproject.org>2005-10-14 04:56:20 +0000
commit6101468cbe28fe50faa82d251ca95c481ed40fe7 (patch)
treeea37f76c73e208b18549c45bcc7c5f7d11a7b70c /src/or
parent998cf8d6222607113fbd8fa8563d507a808ee869 (diff)
downloadtor-6101468cbe28fe50faa82d251ca95c481ed40fe7.tar
tor-6101468cbe28fe50faa82d251ca95c481ed40fe7.tar.gz
Enable trivial "download by descriptor digest" functionality.
svn:r5250
Diffstat (limited to 'src/or')
-rw-r--r--src/or/directory.c32
-rw-r--r--src/or/dirserv.c28
-rw-r--r--src/or/or.h4
-rw-r--r--src/or/routerlist.c26
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;
}
+