diff --git a/doc/TODO b/doc/TODO index b5f2b7effe..0de26f1042 100644 --- a/doc/TODO +++ b/doc/TODO @@ -75,7 +75,10 @@ Things we'd like to do in 0.2.0.x: o Implement directory-protocol side. o Implement storage in memory o Implement cache on disk. - - Have routers upload extra-info documents. + o Have routers upload extra-info documents to authorities running + version 0.2.0.0-alpha-dev (r10070) or later. + . Implement, but make it option-controlled. + - Make it always-on once it seems to work. - Implement option to download and cache extra-info documents. - Drop bandwidth history from router-descriptors - 105: Version negotiation for the Tor protocol (finalize by Jun 1) diff --git a/src/or/config.c b/src/or/config.c index 82b684eedb..9983b676d6 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -261,6 +261,10 @@ static config_var_t _option_vars[] = { VAR("__AllDirActionsPrivate",BOOL, AllDirActionsPrivate, "0"), VAR("__DisablePredictedCircuits",BOOL,DisablePredictedCircuits,"0"), VAR("__LeaveStreamsUnattached", BOOL,LeaveStreamsUnattached, "0"), + + /* XXXX020 Testing only. This will become "always on" once we confirm + * that it works. */ + VAR("_UploadExtraInfo", BOOL, _UploadExtraInfo, "0"), { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL } }; #undef VAR diff --git a/src/or/directory.c b/src/or/directory.c index 796c0f0a01..088b04ae62 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -87,10 +87,12 @@ purpose_is_private(uint8_t purpose) * connection purpose 'purpose' and uploading the payload 'payload' * (length 'payload_len'). The purpose should be one of * 'DIR_PURPOSE_UPLOAD_DIR' or 'DIR_PURPOSE_UPLOAD_RENDDESC'. + * + * DOCDOC extrainfo_len is in addition to payload_len. */ void directory_post_to_dirservers(uint8_t purpose, const char *payload, - size_t payload_len) + size_t payload_len, size_t extrainfo_len) { smartlist_t *dirservers; int post_via_tor; @@ -106,6 +108,9 @@ directory_post_to_dirservers(uint8_t purpose, const char *payload, SMARTLIST_FOREACH(dirservers, trusted_dir_server_t *, ds, { routerstatus_t *rs = &(ds->fake_status.status); + local_routerstatus_t *lrs = router_get_combined_status_by_digest( + ds->digest); + size_t upload_len = payload_len; if (post_to_hidserv_only && !ds->is_hidserv_authority) continue; if (!post_to_hidserv_only && @@ -113,10 +118,17 @@ directory_post_to_dirservers(uint8_t purpose, const char *payload, continue; if (purpose == DIR_PURPOSE_UPLOAD_DIR) ds->has_accepted_serverdesc = 0; + if (extrainfo_len && lrs && + lrs->status.version_supports_extrainfo_upload) { + upload_len += extrainfo_len; + /* XXXX020 Disable this once it's tested. */ + log_notice(LD_DIR, "I am going to try to upload an extrainfo. How " + "exciting! (length %d)", (int) extrainfo_len); + } post_via_tor = purpose_is_private(purpose) || !fascist_firewall_allows_address_dir(ds->addr, ds->dir_port); directory_initiate_command_routerstatus(rs, purpose, post_via_tor, - NULL, payload, payload_len); + NULL, payload, upload_len); }); } diff --git a/src/or/or.h b/src/or/or.h index 2fe0faee45..f2f4eac688 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1191,6 +1191,8 @@ typedef struct routerstatus_t { unsigned int version_known:1; /** True iff this router is a version that supports BEGIN_DIR cells. */ unsigned int version_supports_begindir:1; + /** True iff this router is a version that we can post extrainfo docs to. */ + unsigned int version_supports_extrainfo_upload:1; /** True if we, as a directory mirror, want to download the corresponding * routerinfo from the authority who gave us this routerstatus. (That is, @@ -1878,6 +1880,9 @@ typedef struct { * with weird characters. */ /** If true, we try resolving hostnames with weird characters. */ int ServerDNSAllowNonRFC953Hostnames; + + /*XXXX020 remove me once no longer needed */ + int _UploadExtraInfo; } or_options_t; /** Persistent state for an onion router, as saved to disk. */ @@ -2483,7 +2488,7 @@ int assign_to_cpuworker(connection_t *cpuworker, uint8_t question_type, /********************************* directory.c ***************************/ void directory_post_to_dirservers(uint8_t purpose, const char *payload, - size_t payload_len); + size_t payload_len, size_t extrainfo_len); void directory_get_from_dirserver(uint8_t purpose, const char *resource, int retry_if_no_servers); void directory_initiate_command_routerstatus(routerstatus_t *status, diff --git a/src/or/rendservice.c b/src/or/rendservice.c index fdacefaa97..d59aed3590 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -947,7 +947,7 @@ upload_service_descriptor(rend_service_t *service, int version) } /* Post it to the dirservers */ - directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_RENDDESC, desc, desc_len); + directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_RENDDESC, desc, desc_len, 0); tor_free(desc); service->desc_is_dirty = 0; diff --git a/src/or/router.c b/src/or/router.c index 1516bf374d..47a60b3226 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -726,19 +726,38 @@ static int desc_needs_upload = 0; void router_upload_dir_desc_to_dirservers(int force) { - const char *s; + routerinfo_t *ri; + extrainfo_t *ei; + char *msg; + size_t desc_len, extra_len = 0, total_len; + int post_extra; - s = router_get_my_descriptor(); - if (!s) { + ri = router_get_my_routerinfo(); + if (!ri) { log_info(LD_GENERAL, "No descriptor; skipping upload"); return; } + ei = router_get_my_extrainfo(); + post_extra = ei && get_options()->_UploadExtraInfo; if (!get_options()->PublishServerDescriptor) return; if (!force && !desc_needs_upload) return; desc_needs_upload = 0; - directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_DIR, s, strlen(s)); + + desc_len = ri->cache_info.signed_descriptor_len; + extra_len = (ei && post_extra) ? ei->cache_info.signed_descriptor_len : 0; + total_len = desc_len + extra_len + 1; + msg = tor_malloc(total_len); + memcpy(msg, ri->cache_info.signed_descriptor_body, desc_len); + if (ei && post_extra) { + memcpy(msg+desc_len, ei->cache_info.signed_descriptor_body, extra_len); + } + msg[desc_len+extra_len] = 0; + + directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_DIR, msg, desc_len, + extra_len); + tor_free(msg); } /** OR only: Check whether my exit policy says to allow connection to diff --git a/src/or/routerlist.c b/src/or/routerlist.c index d00e6673a9..2a4405d386 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -3797,6 +3797,7 @@ routerstatus_list_update_from_networkstatus(time_t now) int n_v2_dir=0, n_fast=0, n_stable=0, n_exit=0, n_guard=0, n_bad_exit=0; int n_bad_directory=0; int n_version_known=0, n_supports_begindir=0; + int n_supports_extrainfo_upload=0; int n_desc_digests=0, highest_count=0; const char *the_name = NULL; local_routerstatus_t *rs_out, *rs_old; @@ -3890,6 +3891,8 @@ routerstatus_list_update_from_networkstatus(time_t now) ++n_version_known; if (rs->version_supports_begindir) ++n_supports_begindir; + if (rs->version_supports_extrainfo_upload) + ++n_supports_extrainfo_upload; } /* Go over the descriptor digests and figure out which descriptor we * want. */ @@ -3945,6 +3948,8 @@ routerstatus_list_update_from_networkstatus(time_t now) rs_out->status.version_known = n_version_known > 0; rs_out->status.version_supports_begindir = n_supports_begindir > n_version_known/2; + rs_out->status.version_supports_extrainfo_upload = + n_supports_extrainfo_upload > n_version_known/2; if (!rs_old || memcmp(rs_old, rs_out, sizeof(local_routerstatus_t))) smartlist_add(changed_list, rs_out); } diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 86ab1c0170..6d2b9a5579 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -1271,9 +1271,12 @@ routerstatus_parse_entry_from_string(const char **s, smartlist_t *tokens) rs->version_known = 1; if (strcmpstart(tok->args[0], "Tor ")) { rs->version_supports_begindir = 1; + rs->version_supports_extrainfo_upload = 1; } else { rs->version_supports_begindir = tor_version_as_new_as(tok->args[0], "0.1.2.2-alpha"); + rs->version_supports_begindir = + tor_version_as_new_as(tok->args[0], "0.2.0.0-alpha-dev (r10070)"); } }