mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 06:13:31 +01:00
r12403@catbus: nickm | 2007-04-16 13:55:03 -0400
Code to generate extrainfo whenever routerdesc is regenerated; code to check extrainfo against routerdesc. svn:r9970
This commit is contained in:
parent
7fb7658a45
commit
2bb5e64289
@ -2892,6 +2892,7 @@ void check_descriptor_ipaddress_changed(time_t now);
|
|||||||
void router_new_address_suggestion(const char *suggestion);
|
void router_new_address_suggestion(const char *suggestion);
|
||||||
int router_compare_to_my_exit_policy(edge_connection_t *conn);
|
int router_compare_to_my_exit_policy(edge_connection_t *conn);
|
||||||
routerinfo_t *router_get_my_routerinfo(void);
|
routerinfo_t *router_get_my_routerinfo(void);
|
||||||
|
const char *router_get_my_extrainfo(void);
|
||||||
const char *router_get_my_descriptor(void);
|
const char *router_get_my_descriptor(void);
|
||||||
int router_digest_is_me(const char *digest);
|
int router_digest_is_me(const char *digest);
|
||||||
int router_is_me(routerinfo_t *router);
|
int router_is_me(routerinfo_t *router);
|
||||||
@ -2900,6 +2901,8 @@ int router_pick_published_address(or_options_t *options, uint32_t *addr);
|
|||||||
int router_rebuild_descriptor(int force);
|
int router_rebuild_descriptor(int force);
|
||||||
int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
|
int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
|
||||||
crypto_pk_env_t *ident_key);
|
crypto_pk_env_t *ident_key);
|
||||||
|
int extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
|
||||||
|
crypto_pk_env_t *ident_key);
|
||||||
int is_legal_nickname(const char *s);
|
int is_legal_nickname(const char *s);
|
||||||
int is_legal_nickname_or_hexdigest(const char *s);
|
int is_legal_nickname_or_hexdigest(const char *s);
|
||||||
int is_legal_hexdigest(const char *s);
|
int is_legal_hexdigest(const char *s);
|
||||||
@ -3048,6 +3051,7 @@ void networkstatus_list_update_recent(time_t now);
|
|||||||
void router_reset_descriptor_download_failures(void);
|
void router_reset_descriptor_download_failures(void);
|
||||||
void router_reset_status_download_failures(void);
|
void router_reset_status_download_failures(void);
|
||||||
int router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2);
|
int router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2);
|
||||||
|
int routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei);
|
||||||
const char *esc_router_info(routerinfo_t *router);
|
const char *esc_router_info(routerinfo_t *router);
|
||||||
|
|
||||||
char *networkstatus_getinfo_helper_single(routerstatus_t *rs);
|
char *networkstatus_getinfo_helper_single(routerstatus_t *rs);
|
||||||
|
131
src/or/router.c
131
src/or/router.c
@ -710,6 +710,8 @@ router_is_clique_mode(routerinfo_t *router)
|
|||||||
|
|
||||||
/** My routerinfo. */
|
/** My routerinfo. */
|
||||||
static routerinfo_t *desc_routerinfo = NULL;
|
static routerinfo_t *desc_routerinfo = NULL;
|
||||||
|
/** DOCDOC */
|
||||||
|
static extrainfo_t *desc_extrainfo = NULL;
|
||||||
/** Since when has our descriptor been "clean"? 0 if we need to regenerate it
|
/** Since when has our descriptor been "clean"? 0 if we need to regenerate it
|
||||||
* now. */
|
* now. */
|
||||||
static time_t desc_clean_since = 0;
|
static time_t desc_clean_since = 0;
|
||||||
@ -812,6 +814,17 @@ router_get_my_descriptor(void)
|
|||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
|
const char *
|
||||||
|
router_get_my_extrainfo(void)
|
||||||
|
{
|
||||||
|
if (!server_mode(get_options()))
|
||||||
|
return NULL;
|
||||||
|
if (router_rebuild_descriptor(0))
|
||||||
|
return NULL;
|
||||||
|
return desc_extrainfo->cache_info.signed_descriptor_body;
|
||||||
|
}
|
||||||
|
|
||||||
/** A list of nicknames that we've warned about including in our family
|
/** A list of nicknames that we've warned about including in our family
|
||||||
* declaration verbatim rather than as digests. */
|
* declaration verbatim rather than as digests. */
|
||||||
static smartlist_t *warned_nonexistent_family = NULL;
|
static smartlist_t *warned_nonexistent_family = NULL;
|
||||||
@ -839,11 +852,13 @@ router_pick_published_address(or_options_t *options, uint32_t *addr)
|
|||||||
/** If <b>force</b> is true, or our descriptor is out-of-date, rebuild
|
/** If <b>force</b> is true, or our descriptor is out-of-date, rebuild
|
||||||
* a fresh routerinfo and signed server descriptor for this OR.
|
* a fresh routerinfo and signed server descriptor for this OR.
|
||||||
* Return 0 on success, -1 on temporary error.
|
* Return 0 on success, -1 on temporary error.
|
||||||
|
* DOCDOC extrainfo.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
router_rebuild_descriptor(int force)
|
router_rebuild_descriptor(int force)
|
||||||
{
|
{
|
||||||
routerinfo_t *ri;
|
routerinfo_t *ri;
|
||||||
|
extrainfo_t *ei;
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
char platform[256];
|
char platform[256];
|
||||||
int hibernating = we_are_hibernating();
|
int hibernating = we_are_hibernating();
|
||||||
@ -946,6 +961,27 @@ router_rebuild_descriptor(int force)
|
|||||||
|
|
||||||
smartlist_free(family);
|
smartlist_free(family);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now generate the extrainfo. */
|
||||||
|
ei = tor_malloc_zero(sizeof(extrainfo_t));
|
||||||
|
strlcpy(ei->nickname, get_options()->Nickname, sizeof(ei->nickname));
|
||||||
|
ei->cache_info.published_on = ri->cache_info.published_on;
|
||||||
|
memcpy(ei->cache_info.identity_digest, ri->cache_info.identity_digest,
|
||||||
|
DIGEST_LEN);
|
||||||
|
ei->cache_info.signed_descriptor_body = tor_malloc(8192);
|
||||||
|
if (extrainfo_dump_to_string(ei->cache_info.signed_descriptor_body, 8192,
|
||||||
|
ei, get_identity_key()) < 0) {
|
||||||
|
log_warn(LD_BUG, "Couldn't generate extra-info descriptor.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ei->cache_info.signed_descriptor_len =
|
||||||
|
strlen(ei->cache_info.signed_descriptor_body);
|
||||||
|
router_get_extrainfo_hash(ei->cache_info.signed_descriptor_body,
|
||||||
|
ei->cache_info.signed_descriptor_digest);
|
||||||
|
|
||||||
|
/* Now finish the router descriptor. */
|
||||||
|
memcpy(ri->extra_info_digest, ei->cache_info.signed_descriptor_digest,
|
||||||
|
DIGEST_LEN);
|
||||||
ri->cache_info.signed_descriptor_body = tor_malloc(8192);
|
ri->cache_info.signed_descriptor_body = tor_malloc(8192);
|
||||||
if (router_dump_router_to_string(ri->cache_info.signed_descriptor_body, 8192,
|
if (router_dump_router_to_string(ri->cache_info.signed_descriptor_body, 8192,
|
||||||
ri, get_identity_key())<0) {
|
ri, get_identity_key())<0) {
|
||||||
@ -954,13 +990,19 @@ router_rebuild_descriptor(int force)
|
|||||||
}
|
}
|
||||||
ri->cache_info.signed_descriptor_len =
|
ri->cache_info.signed_descriptor_len =
|
||||||
strlen(ri->cache_info.signed_descriptor_body);
|
strlen(ri->cache_info.signed_descriptor_body);
|
||||||
|
/* XXXX020 router_get_router_hash??? */
|
||||||
crypto_digest(ri->cache_info.signed_descriptor_digest,
|
crypto_digest(ri->cache_info.signed_descriptor_digest,
|
||||||
ri->cache_info.signed_descriptor_body,
|
ri->cache_info.signed_descriptor_body,
|
||||||
ri->cache_info.signed_descriptor_len);
|
ri->cache_info.signed_descriptor_len);
|
||||||
|
|
||||||
|
tor_assert(! routerinfo_incompatible_with_extrainfo(ri, ei));
|
||||||
|
|
||||||
if (desc_routerinfo)
|
if (desc_routerinfo)
|
||||||
routerinfo_free(desc_routerinfo);
|
routerinfo_free(desc_routerinfo);
|
||||||
desc_routerinfo = ri;
|
desc_routerinfo = ri;
|
||||||
|
if (desc_extrainfo)
|
||||||
|
extrainfo_free(desc_extrainfo);
|
||||||
|
desc_extrainfo = ei;
|
||||||
|
|
||||||
desc_clean_since = time(NULL);
|
desc_clean_since = time(NULL);
|
||||||
desc_needs_upload = 1;
|
desc_needs_upload = 1;
|
||||||
@ -1161,17 +1203,13 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
|
|||||||
char digest[DIGEST_LEN];
|
char digest[DIGEST_LEN];
|
||||||
char published[ISO_TIME_LEN+1];
|
char published[ISO_TIME_LEN+1];
|
||||||
char fingerprint[FINGERPRINT_LEN+1];
|
char fingerprint[FINGERPRINT_LEN+1];
|
||||||
|
char extra_info_digest[HEX_DIGEST_LEN+1];
|
||||||
size_t onion_pkeylen, identity_pkeylen;
|
size_t onion_pkeylen, identity_pkeylen;
|
||||||
size_t written;
|
size_t written;
|
||||||
int result=0;
|
int result=0;
|
||||||
addr_policy_t *tmpe;
|
addr_policy_t *tmpe;
|
||||||
char *bandwidth_usage;
|
char *bandwidth_usage;
|
||||||
char *family_line;
|
char *family_line;
|
||||||
#ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
|
|
||||||
char *s_dup;
|
|
||||||
const char *cp;
|
|
||||||
routerinfo_t *ri_tmp;
|
|
||||||
#endif
|
|
||||||
or_options_t *options = get_options();
|
or_options_t *options = get_options();
|
||||||
|
|
||||||
/* Make sure the identity key matches the one in the routerinfo. */
|
/* Make sure the identity key matches the one in the routerinfo. */
|
||||||
@ -1219,6 +1257,9 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
|
|||||||
family_line = tor_strdup("");
|
family_line = tor_strdup("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base16_encode(extra_info_digest, sizeof(extra_info_digest),
|
||||||
|
router->extra_info_digest, DIGEST_LEN);
|
||||||
|
|
||||||
/* Generate the easy portion of the router descriptor. */
|
/* Generate the easy portion of the router descriptor. */
|
||||||
result = tor_snprintf(s, maxlen,
|
result = tor_snprintf(s, maxlen,
|
||||||
"router %s %s %d 0 %d\n"
|
"router %s %s %d 0 %d\n"
|
||||||
@ -1227,6 +1268,7 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
|
|||||||
"opt fingerprint %s\n"
|
"opt fingerprint %s\n"
|
||||||
"uptime %ld\n"
|
"uptime %ld\n"
|
||||||
"bandwidth %d %d %d\n"
|
"bandwidth %d %d %d\n"
|
||||||
|
"opt extra-info-digest %s\n"
|
||||||
"onion-key\n%s"
|
"onion-key\n%s"
|
||||||
"signing-key\n%s"
|
"signing-key\n%s"
|
||||||
"%s%s%s",
|
"%s%s%s",
|
||||||
@ -1241,6 +1283,7 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
|
|||||||
(int) router->bandwidthrate,
|
(int) router->bandwidthrate,
|
||||||
(int) router->bandwidthburst,
|
(int) router->bandwidthburst,
|
||||||
(int) router->bandwidthcapacity,
|
(int) router->bandwidthcapacity,
|
||||||
|
extra_info_digest,
|
||||||
onion_pkey, identity_pkey,
|
onion_pkey, identity_pkey,
|
||||||
family_line, bandwidth_usage,
|
family_line, bandwidth_usage,
|
||||||
we_are_hibernating() ? "opt hibernating 1\n" : "");
|
we_are_hibernating() ? "opt hibernating 1\n" : "");
|
||||||
@ -1319,21 +1362,78 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
|
|||||||
s[written+1] = 0;
|
s[written+1] = 0;
|
||||||
|
|
||||||
#ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
|
#ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
|
||||||
cp = s_dup = tor_strdup(s);
|
{
|
||||||
ri_tmp = router_parse_entry_from_string(cp, NULL, 1);
|
char *s_dup;
|
||||||
if (!ri_tmp) {
|
const char *cp;
|
||||||
log_err(LD_BUG,
|
routerinfo_t *ri_tmp;
|
||||||
"We just generated a router descriptor we can't parse.");
|
cp = s_dup = tor_strdup(s);
|
||||||
log_err(LD_BUG, "Descriptor was: <<%s>>", s);
|
ri_tmp = router_parse_entry_from_string(cp, NULL, 1);
|
||||||
return -1;
|
if (!ri_tmp) {
|
||||||
|
log_err(LD_BUG,
|
||||||
|
"We just generated a router descriptor we can't parse.");
|
||||||
|
log_err(LD_BUG, "Descriptor was: <<%s>>", s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tor_free(s_dup);
|
||||||
|
routerinfo_free(ri_tmp);
|
||||||
}
|
}
|
||||||
tor_free(s_dup);
|
|
||||||
routerinfo_free(ri_tmp);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return written+1;
|
return written+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
|
int
|
||||||
|
extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
|
||||||
|
crypto_pk_env_t *ident_key)
|
||||||
|
{
|
||||||
|
char identity[HEX_DIGEST_LEN+1];
|
||||||
|
char published[ISO_TIME_LEN+1];
|
||||||
|
char digest[DIGEST_LEN];
|
||||||
|
char *bandwidth_usage;
|
||||||
|
int result;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
base16_encode(identity, sizeof(identity),
|
||||||
|
extrainfo->cache_info.identity_digest, DIGEST_LEN);
|
||||||
|
format_iso_time(published, extrainfo->cache_info.published_on);
|
||||||
|
bandwidth_usage = rep_hist_get_bandwidth_lines();
|
||||||
|
|
||||||
|
result = tor_snprintf(s, maxlen,
|
||||||
|
"extra-info %s %s\n"
|
||||||
|
"published %s\n%s"
|
||||||
|
"router-signature\n",
|
||||||
|
extrainfo->nickname, identity,
|
||||||
|
published, bandwidth_usage);
|
||||||
|
tor_free(bandwidth_usage);
|
||||||
|
if (result<0)
|
||||||
|
return -1;
|
||||||
|
len = strlen(s);
|
||||||
|
if (router_get_extrainfo_hash(s, digest)<0)
|
||||||
|
return -1;
|
||||||
|
if (router_append_dirobj_signature(s+len, maxlen-len, digest, ident_key)<0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
#ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
|
||||||
|
{
|
||||||
|
char *cp, *s_dup;
|
||||||
|
extrainfo_t *ei_tmp;
|
||||||
|
cp = s_dup = tor_strdup(s);
|
||||||
|
ei_tmp = extrainfo_parse_entry_from_string(cp, NULL, 1, NULL);
|
||||||
|
if (!ei_tmp) {
|
||||||
|
log_err(LD_BUG,
|
||||||
|
"We just generated an extrainfo descriptor we can't parse.");
|
||||||
|
log_err(LD_BUG, "Descriptor was: <<%s>>", s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tor_free(s_dup);
|
||||||
|
extrainfo_free(ei_tmp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return strlen(s)+1;
|
||||||
|
}
|
||||||
|
|
||||||
/** Return true iff <b>s</b> is a legally valid server nickname. */
|
/** Return true iff <b>s</b> is a legally valid server nickname. */
|
||||||
int
|
int
|
||||||
is_legal_nickname(const char *s)
|
is_legal_nickname(const char *s)
|
||||||
@ -1420,6 +1520,9 @@ router_free_all(void)
|
|||||||
tor_mutex_free(key_lock);
|
tor_mutex_free(key_lock);
|
||||||
if (desc_routerinfo)
|
if (desc_routerinfo)
|
||||||
routerinfo_free(desc_routerinfo);
|
routerinfo_free(desc_routerinfo);
|
||||||
|
if (desc_extrainfo)
|
||||||
|
extrainfo_free(desc_extrainfo);
|
||||||
|
|
||||||
if (warned_nonexistent_family) {
|
if (warned_nonexistent_family) {
|
||||||
SMARTLIST_FOREACH(warned_nonexistent_family, char *, cp, tor_free(cp));
|
SMARTLIST_FOREACH(warned_nonexistent_family, char *, cp, tor_free(cp));
|
||||||
smartlist_free(warned_nonexistent_family);
|
smartlist_free(warned_nonexistent_family);
|
||||||
|
@ -4422,6 +4422,37 @@ router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** DOCDOC */
|
||||||
|
int
|
||||||
|
routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei)
|
||||||
|
{
|
||||||
|
tor_assert(ri);
|
||||||
|
tor_assert(ei);
|
||||||
|
|
||||||
|
if (strcmp(ri->nickname, ei->nickname) ||
|
||||||
|
memcmp(ri->cache_info.identity_digest, ei->cache_info.identity_digest,
|
||||||
|
DIGEST_LEN))
|
||||||
|
return 1; /* different servers */
|
||||||
|
|
||||||
|
if (ei->pending_sig) {
|
||||||
|
char signed_digest[128];
|
||||||
|
if (crypto_pk_public_checksig(ri->identity_pkey, signed_digest,
|
||||||
|
ei->pending_sig, 128) != 20 ||
|
||||||
|
memcmp(signed_digest, ei->cache_info.signed_descriptor_digest,
|
||||||
|
DIGEST_LEN))
|
||||||
|
return 1; /* Bad signature, or no match. */
|
||||||
|
|
||||||
|
tor_free(ei->pending_sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ei->cache_info.published_on < ei->cache_info.published_on)
|
||||||
|
return 1;
|
||||||
|
else if (ei->cache_info.published_on > ei->cache_info.published_on)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Generate networkstatus lines for a single routerstatus_t object, and
|
/** Generate networkstatus lines for a single routerstatus_t object, and
|
||||||
* return the result in a newly allocated string. Used only by controller
|
* return the result in a newly allocated string. Used only by controller
|
||||||
* interface (for now.) */
|
* interface (for now.) */
|
||||||
|
@ -835,7 +835,6 @@ router_parse_entry_from_string(const char *s, const char *end,
|
|||||||
router->cache_info.signed_descriptor_len = end-s;
|
router->cache_info.signed_descriptor_len = end-s;
|
||||||
memcpy(router->cache_info.signed_descriptor_digest, digest, DIGEST_LEN);
|
memcpy(router->cache_info.signed_descriptor_digest, digest, DIGEST_LEN);
|
||||||
|
|
||||||
|
|
||||||
router->nickname = tor_strdup(tok->args[0]);
|
router->nickname = tor_strdup(tok->args[0]);
|
||||||
if (!is_legal_nickname(router->nickname)) {
|
if (!is_legal_nickname(router->nickname)) {
|
||||||
log_warn(LD_DIR,"Router nickname is invalid");
|
log_warn(LD_DIR,"Router nickname is invalid");
|
||||||
@ -1070,6 +1069,7 @@ extrainfo_parse_entry_from_string(const char *s, const char *end,
|
|||||||
extrainfo->cache_info.signed_descriptor_body = tor_strndup(s, end-s);
|
extrainfo->cache_info.signed_descriptor_body = tor_strndup(s, end-s);
|
||||||
extrainfo->cache_info.signed_descriptor_len = end-s;
|
extrainfo->cache_info.signed_descriptor_len = end-s;
|
||||||
memcpy(extrainfo->cache_info.signed_descriptor_digest, digest, DIGEST_LEN);
|
memcpy(extrainfo->cache_info.signed_descriptor_digest, digest, DIGEST_LEN);
|
||||||
|
|
||||||
tor_assert(tok->n_args >= 2);
|
tor_assert(tok->n_args >= 2);
|
||||||
if (!is_legal_nickname(tok->args[0])) {
|
if (!is_legal_nickname(tok->args[0])) {
|
||||||
log_warn(LD_DIR,"Bad nickname %s on \"extra-info\"",escaped(tok->args[0]));
|
log_warn(LD_DIR,"Bad nickname %s on \"extra-info\"",escaped(tok->args[0]));
|
||||||
|
@ -1743,6 +1743,7 @@ test_dir_format(void)
|
|||||||
* uptime, that still wouldn't make it right, because the two
|
* uptime, that still wouldn't make it right, because the two
|
||||||
* descriptors might be made on different seconds... hm. */
|
* descriptors might be made on different seconds... hm. */
|
||||||
"bandwidth 1000 5000 10000\n"
|
"bandwidth 1000 5000 10000\n"
|
||||||
|
"opt extra-info-digest 0000000000000000000000000000000000000000\n"
|
||||||
"onion-key\n", sizeof(buf2));
|
"onion-key\n", sizeof(buf2));
|
||||||
strlcat(buf2, pk1_str, sizeof(buf2));
|
strlcat(buf2, pk1_str, sizeof(buf2));
|
||||||
strlcat(buf2, "signing-key\n", sizeof(buf2));
|
strlcat(buf2, "signing-key\n", sizeof(buf2));
|
||||||
|
Loading…
Reference in New Issue
Block a user