|
@@ -748,7 +748,7 @@ router_parse_entry_from_string(const char *s, const char *end)
|
|
|
router = tor_malloc_zero(sizeof(routerinfo_t));
|
|
|
router->signed_descriptor = tor_strndup(s, end-s);
|
|
|
router->signed_descriptor_len = end-s;
|
|
|
- crypto_digest(router->signed_descriptor_digest, s, end-s);
|
|
|
+ memcpy(router->signed_descriptor_digest, digest, DIGEST_LEN);
|
|
|
ports_set = bw_set = 0;
|
|
|
|
|
|
if (tok->n_args == 2 || tok->n_args == 5 || tok->n_args == 6) {
|
|
@@ -957,12 +957,9 @@ find_start_of_next_routerstatus(const char *s)
|
|
|
static routerstatus_t *
|
|
|
routerstatus_parse_entry_from_string(const char **s, smartlist_t *tokens)
|
|
|
{
|
|
|
-#define BASE64_DIGEST_LEN 27
|
|
|
const char *eos;
|
|
|
routerstatus_t *rs = NULL;
|
|
|
directory_token_t *tok;
|
|
|
- char base64buf_in[BASE64_DIGEST_LEN+3];
|
|
|
- char base64buf_out[256];
|
|
|
char timebuf[ISO_TIME_LEN+1];
|
|
|
struct in_addr in;
|
|
|
|
|
@@ -1000,33 +997,15 @@ routerstatus_parse_entry_from_string(const char **s, smartlist_t *tokens)
|
|
|
}
|
|
|
strlcpy(rs->nickname, tok->args[0], sizeof(rs->nickname));
|
|
|
|
|
|
- if (strlen(tok->args[1]) != BASE64_DIGEST_LEN) {
|
|
|
- log_fn(LOG_WARN, "Digest '%s' is wrong length in router status; skipping.",
|
|
|
- tok->args[1]);
|
|
|
- goto err;
|
|
|
- }
|
|
|
- memcpy(base64buf_in, tok->args[1], BASE64_DIGEST_LEN);
|
|
|
- memcpy(base64buf_in+BASE64_DIGEST_LEN, "=\n\0", 3);
|
|
|
- if (base64_decode(base64buf_out, sizeof(base64buf_out),
|
|
|
- base64buf_in, sizeof(base64buf_in)-1) != DIGEST_LEN) {
|
|
|
+ if (digest_from_base64(rs->identity_digest, tok->args[1])) {
|
|
|
log_fn(LOG_WARN, "Error decoding digest '%s'", tok->args[1]);
|
|
|
goto err;
|
|
|
}
|
|
|
- memcpy(rs->identity_digest, base64buf_out, DIGEST_LEN);
|
|
|
|
|
|
- if (strlen(tok->args[2]) != BASE64_DIGEST_LEN) {
|
|
|
- log_fn(LOG_WARN, "Digest '%s' is wrong length in router status; skipping.",
|
|
|
- tok->args[2]);
|
|
|
- goto err;
|
|
|
- }
|
|
|
- memcpy(base64buf_in, tok->args[2], BASE64_DIGEST_LEN);
|
|
|
- memcpy(base64buf_in+BASE64_DIGEST_LEN, "=\n\0", 3);
|
|
|
- if (base64_decode(base64buf_out, sizeof(base64buf_out),
|
|
|
- base64buf_in, sizeof(base64buf_in)-1) != DIGEST_LEN) {
|
|
|
+ if (digest_from_base64(rs->descriptor_digest, tok->args[2])) {
|
|
|
log_fn(LOG_WARN, "Error decoding digest '%s'", tok->args[2]);
|
|
|
goto err;
|
|
|
}
|
|
|
- memcpy(rs->descriptor_digest, base64buf_out, DIGEST_LEN);
|
|
|
|
|
|
if (tor_snprintf(timebuf, sizeof(timebuf), "%s %s",
|
|
|
tok->args[3], tok->args[4]) < 0 ||
|
|
@@ -1083,6 +1062,12 @@ _compare_routerstatus_entries(const void **_a, const void **_b)
|
|
|
return memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN);
|
|
|
}
|
|
|
|
|
|
+void
|
|
|
+sort_routerstatus_entries(smartlist_t *sl)
|
|
|
+{
|
|
|
+ smartlist_sort(sl, _compare_routerstatus_entries);
|
|
|
+}
|
|
|
+
|
|
|
/** Given a versioned (v2 or later) network-status object in <b>s</b>, try to
|
|
|
* parse it and return the result. Return NULL on failure. Check the
|
|
|
* signature of the network status, but do not (yet) check the signing key for
|
|
@@ -1098,6 +1083,7 @@ networkstatus_parse_from_string(const char *s)
|
|
|
char tmp_digest[DIGEST_LEN];
|
|
|
struct in_addr in;
|
|
|
directory_token_t *tok;
|
|
|
+ int i;
|
|
|
|
|
|
if (router_get_networkstatus_v2_hash(s, ns_digest)) {
|
|
|
log_fn(LOG_WARN, "Unable to compute digest of network-status");
|
|
@@ -1209,7 +1195,6 @@ networkstatus_parse_from_string(const char *s)
|
|
|
}
|
|
|
|
|
|
if ((tok = find_first_by_keyword(tokens, K_DIR_OPTIONS))) {
|
|
|
- int i;
|
|
|
for (i=0; i < tok->n_args; ++i) {
|
|
|
if (!strcmp(tok->args[i], "Names"))
|
|
|
ns->binds_names = 1;
|
|
@@ -1227,6 +1212,18 @@ networkstatus_parse_from_string(const char *s)
|
|
|
}
|
|
|
smartlist_sort(ns->entries, _compare_routerstatus_entries);
|
|
|
|
|
|
+ /* Kill duplicate entries. */
|
|
|
+ for (i=0; i < smartlist_len(ns->entries)-1; ++i) {
|
|
|
+ routerstatus_t *rs1 = smartlist_get(ns->entries, i);
|
|
|
+ routerstatus_t *rs2 = smartlist_get(ns->entries, i+1);
|
|
|
+ if (!memcmp(rs1->identity_digest,
|
|
|
+ rs2->identity_digest, DIGEST_LEN)) {
|
|
|
+ log_fn(LOG_WARN, "Network-status has two entries for the same router. Dropping one.");
|
|
|
+ smartlist_del_keeporder(ns->entries, i--);
|
|
|
+ routerstatus_free(rs1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (tokenize_string(s, NULL, tokens, NETSTATUS)) {
|
|
|
log_fn(LOG_WARN, "Error tokenizing network-status footer.");
|
|
|
goto err;
|