mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
handle fetching bridge descriptors from the bridge authority too.
svn:r10898
This commit is contained in:
parent
56d3119581
commit
6fc336d217
@ -1583,8 +1583,7 @@ choose_good_middle_server(uint8_t purpose,
|
||||
options->ExcludeNodes, excluded,
|
||||
state->need_uptime, state->need_capacity, 0,
|
||||
options->_AllowInvalid & ALLOW_INVALID_MIDDLE, 0, 0);
|
||||
if (preferred)
|
||||
tor_free(preferred);
|
||||
tor_free(preferred);
|
||||
smartlist_free(excluded);
|
||||
return choice;
|
||||
}
|
||||
@ -1885,8 +1884,8 @@ entry_guard_set_status(entry_guard_t *e, routerinfo_t *ri,
|
||||
return changed;
|
||||
}
|
||||
|
||||
/** Return true iff enough time has passed since we last tried connect to the
|
||||
* unreachable guard <b>e</b> that we're willing to try again. */
|
||||
/** Return true iff enough time has passed since we last tried to connect
|
||||
* to the unreachable guard <b>e</b> that we're willing to try again. */
|
||||
static int
|
||||
entry_is_time_to_retry(entry_guard_t *e, time_t now)
|
||||
{
|
||||
@ -1913,7 +1912,7 @@ entry_is_time_to_retry(entry_guard_t *e, time_t now)
|
||||
* if demanded by <b>need_uptime</b> or <b>need_capacity</b>;
|
||||
* (This check is currently redundant with the Guard flag, but in
|
||||
* the future that might change. Best to leave it in for now.)
|
||||
* - Allowed by our current ReachableAddresses config option; and
|
||||
* - Allowed by our current ReachableORAddresses config option; and
|
||||
* - Currently thought to be reachable by us (unless assume_reachable
|
||||
* is true).
|
||||
*/
|
||||
@ -1937,8 +1936,7 @@ entry_is_live(entry_guard_t *e, int need_uptime, int need_capacity,
|
||||
return NULL;
|
||||
if (router_is_unreliable(r, need_uptime, need_capacity, 0))
|
||||
return NULL;
|
||||
if (firewall_is_fascist_or() &&
|
||||
!fascist_firewall_allows_address_or(r->addr,r->or_port))
|
||||
if (!fascist_firewall_allows_address_or(r->addr,r->or_port))
|
||||
return NULL;
|
||||
return r;
|
||||
}
|
||||
@ -2778,10 +2776,10 @@ fetch_bridge_descriptors(time_t now)
|
||||
|
||||
SMARTLIST_FOREACH(bridge_list, bridge_info_t *, bridge,
|
||||
{
|
||||
if (bridge->fetch_status.next_attempt_at >= now)
|
||||
if (bridge->fetch_status.next_attempt_at > now)
|
||||
continue; /* don't bother, no need to retry yet */
|
||||
|
||||
/* schedule another fetch as if this one failed, in case it does */
|
||||
/* schedule another fetch as if this one will fail, in case it does */
|
||||
bridge_fetch_status_increment(bridge, now);
|
||||
|
||||
in.s_addr = htonl(bridge->addr);
|
||||
@ -2813,8 +2811,18 @@ fetch_bridge_descriptors(time_t now)
|
||||
0, "authority.z", NULL, 0);
|
||||
}
|
||||
} else {
|
||||
/* we have a digest and we want to ask an authority. */
|
||||
// XXX
|
||||
/* We have a digest and we want to ask an authority. We could
|
||||
* combine all the requests into one, but that may give more
|
||||
* hints to the bridge authority than we want to give. */
|
||||
char resource[10 + HEX_DIGEST_LEN];
|
||||
memcpy(resource, "fp/", 3);
|
||||
base16_encode(resource+3, HEX_DIGEST_LEN+1,
|
||||
bridge->identity, DIGEST_LEN);
|
||||
memcpy(resource+3+HEX_DIGEST_LEN, ".z", 3);
|
||||
log_info(LD_DIR, "Fetching bridge info '%s' from bridge authority.",
|
||||
resource);
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_SERVERDESC,
|
||||
ROUTER_PURPOSE_BRIDGE, resource, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ directory_send_command(dir_connection_t *conn,
|
||||
const char *payload, size_t payload_len);
|
||||
static int directory_handle_command(dir_connection_t *conn);
|
||||
static int body_is_plausible(const char *body, size_t body_len, int purpose);
|
||||
static int purpose_needs_anonymity(uint8_t purpose);
|
||||
static int purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose);
|
||||
static char *http_get_header(const char *headers, const char *which);
|
||||
static void http_set_address_origin(const char *headers, connection_t *conn);
|
||||
static void connection_dir_download_networkstatus_failed(
|
||||
@ -71,16 +71,18 @@ static void note_request(const char *key, size_t bytes);
|
||||
/** Return true iff the directory purpose 'purpose' must use an
|
||||
* anonymous connection to a directory. */
|
||||
static int
|
||||
purpose_needs_anonymity(uint8_t purpose)
|
||||
purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose)
|
||||
{
|
||||
if (get_options()->AllDirActionsPrivate)
|
||||
return 1;
|
||||
if (purpose == DIR_PURPOSE_FETCH_DIR ||
|
||||
purpose == DIR_PURPOSE_UPLOAD_DIR ||
|
||||
purpose == DIR_PURPOSE_FETCH_RUNNING_LIST ||
|
||||
purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS ||
|
||||
purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
|
||||
purpose == DIR_PURPOSE_FETCH_EXTRAINFO)
|
||||
if (router_purpose == ROUTER_PURPOSE_BRIDGE)
|
||||
return 1; /* if we have to ask, better make it anonymous */
|
||||
if (dir_purpose == DIR_PURPOSE_FETCH_DIR ||
|
||||
dir_purpose == DIR_PURPOSE_UPLOAD_DIR ||
|
||||
dir_purpose == DIR_PURPOSE_FETCH_RUNNING_LIST ||
|
||||
dir_purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS ||
|
||||
dir_purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
|
||||
dir_purpose == DIR_PURPOSE_FETCH_EXTRAINFO)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
@ -147,7 +149,8 @@ router_supports_extrainfo(const char *identity_digest, int is_authority)
|
||||
* support it.
|
||||
*/
|
||||
void
|
||||
directory_post_to_dirservers(uint8_t purpose, authority_type_t type,
|
||||
directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
|
||||
authority_type_t type,
|
||||
const char *payload,
|
||||
size_t payload_len, size_t extrainfo_len)
|
||||
{
|
||||
@ -167,7 +170,7 @@ directory_post_to_dirservers(uint8_t purpose, authority_type_t type,
|
||||
continue;
|
||||
|
||||
found = 1; /* at least one authority of this type was listed */
|
||||
if (purpose == DIR_PURPOSE_UPLOAD_DIR)
|
||||
if (dir_purpose == DIR_PURPOSE_UPLOAD_DIR)
|
||||
ds->has_accepted_serverdesc = 0;
|
||||
|
||||
if (extrainfo_len && router_supports_extrainfo(ds->digest, 1)) {
|
||||
@ -175,10 +178,10 @@ directory_post_to_dirservers(uint8_t purpose, authority_type_t type,
|
||||
log_info(LD_DIR, "Uploading an extrainfo (length %d)",
|
||||
(int) extrainfo_len);
|
||||
}
|
||||
post_via_tor = purpose_needs_anonymity(purpose) ||
|
||||
post_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose) ||
|
||||
!fascist_firewall_allows_address_dir(ds->addr, ds->dir_port);
|
||||
directory_initiate_command_routerstatus(rs, purpose,
|
||||
ROUTER_PURPOSE_GENERAL,
|
||||
directory_initiate_command_routerstatus(rs, dir_purpose,
|
||||
router_purpose,
|
||||
post_via_tor,
|
||||
NULL, payload, upload_len);
|
||||
});
|
||||
@ -191,29 +194,33 @@ directory_post_to_dirservers(uint8_t purpose, authority_type_t type,
|
||||
}
|
||||
|
||||
/** Start a connection to a random running directory server, using
|
||||
* connection purpose 'purpose' and requesting 'resource'.
|
||||
* connection purpose <b>dir_purpose</b>, intending to fetch descriptors
|
||||
* of purpose <b>router_purpose</b>, and requesting <b>resource</b>.
|
||||
* If <b>retry_if_no_servers</b>, then if all the possible servers seem
|
||||
* down, mark them up and try again.
|
||||
*/
|
||||
void
|
||||
directory_get_from_dirserver(uint8_t dir_purpose, const char *resource,
|
||||
int retry_if_no_servers)
|
||||
directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
|
||||
const char *resource, int retry_if_no_servers)
|
||||
{
|
||||
routerstatus_t *rs = NULL;
|
||||
or_options_t *options = get_options();
|
||||
int prefer_authority = server_mode(options) && options->DirPort != 0;
|
||||
int directconn = !purpose_needs_anonymity(dir_purpose);
|
||||
int get_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose);
|
||||
authority_type_t type;
|
||||
|
||||
/* FFFF we could break this switch into its own function, and call
|
||||
* it elsewhere in directory.c. -RD */
|
||||
switch (dir_purpose) {
|
||||
case DIR_PURPOSE_FETCH_EXTRAINFO:
|
||||
type = EXTRAINFO_CACHE | V2_AUTHORITY;
|
||||
type = EXTRAINFO_CACHE |
|
||||
(router_purpose == ROUTER_PURPOSE_BRIDGE ? BRIDGE_AUTHORITY :
|
||||
V2_AUTHORITY);
|
||||
break;
|
||||
case DIR_PURPOSE_FETCH_NETWORKSTATUS:
|
||||
case DIR_PURPOSE_FETCH_SERVERDESC:
|
||||
type = V2_AUTHORITY;
|
||||
type = (router_purpose == ROUTER_PURPOSE_BRIDGE ? BRIDGE_AUTHORITY :
|
||||
V2_AUTHORITY);
|
||||
break;
|
||||
case DIR_PURPOSE_FETCH_DIR:
|
||||
case DIR_PURPOSE_FETCH_RUNNING_LIST:
|
||||
@ -230,21 +237,21 @@ directory_get_from_dirserver(uint8_t dir_purpose, const char *resource,
|
||||
if (!options->FetchServerDescriptors && type != HIDSERV_AUTHORITY)
|
||||
return;
|
||||
|
||||
if (directconn && options->UseBridges) {
|
||||
/* want to pick a bridge for which we have a descriptor. */
|
||||
if (!get_via_tor && options->UseBridges) {
|
||||
/* want to ask a running bridge for which we have a descriptor. */
|
||||
routerinfo_t *ri = choose_random_entry(NULL);
|
||||
if (ri) {
|
||||
directory_initiate_command(ri->address, ri->addr,
|
||||
ri->or_port, 0,
|
||||
1, ri->cache_info.identity_digest,
|
||||
dir_purpose,
|
||||
ROUTER_PURPOSE_GENERAL,
|
||||
router_purpose,
|
||||
0, resource, NULL, 0);
|
||||
} else
|
||||
log_notice(LD_DIR, "Ignoring directory request, since no bridge "
|
||||
"nodes are available yet.");
|
||||
return;
|
||||
} else if (directconn) {
|
||||
} else if (!get_via_tor) {
|
||||
if (prefer_authority) {
|
||||
/* only ask authdirservers, and don't ask myself */
|
||||
rs = router_pick_trusteddirserver(type, 1, 1,
|
||||
@ -270,10 +277,10 @@ directory_get_from_dirserver(uint8_t dir_purpose, const char *resource,
|
||||
rs = router_pick_trusteddirserver(type, 1, 1,
|
||||
retry_if_no_servers);
|
||||
if (!rs)
|
||||
directconn = 0; /* last resort: try routing it via Tor */
|
||||
get_via_tor = 1; /* last resort: try routing it via Tor */
|
||||
}
|
||||
}
|
||||
} else { /* !directconn */
|
||||
} else { /* get_via_tor */
|
||||
/* Never use fascistfirewall; we're going via Tor. */
|
||||
if (dir_purpose == DIR_PURPOSE_FETCH_RENDDESC) {
|
||||
/* only ask hidserv authorities, any of them will do */
|
||||
@ -291,15 +298,15 @@ directory_get_from_dirserver(uint8_t dir_purpose, const char *resource,
|
||||
|
||||
if (rs)
|
||||
directory_initiate_command_routerstatus(rs, dir_purpose,
|
||||
ROUTER_PURPOSE_GENERAL,
|
||||
!directconn,
|
||||
router_purpose,
|
||||
get_via_tor,
|
||||
resource, NULL, 0);
|
||||
else {
|
||||
log_notice(LD_DIR,
|
||||
"While fetching directory info, "
|
||||
"no running dirservers known. Will try again later. "
|
||||
"(purpose %d)", dir_purpose);
|
||||
if (!purpose_needs_anonymity(dir_purpose)) {
|
||||
if (!purpose_needs_anonymity(dir_purpose, router_purpose)) {
|
||||
/* remember we tried them all and failed. */
|
||||
directory_all_unreachable(time(NULL));
|
||||
}
|
||||
@ -387,8 +394,8 @@ connection_dir_request_failed(dir_connection_t *conn)
|
||||
conn->_base.purpose == DIR_PURPOSE_FETCH_RUNNING_LIST) {
|
||||
log_info(LD_DIR, "Giving up on directory server at '%s:%d'; retrying",
|
||||
conn->_base.address, conn->_base.port);
|
||||
directory_get_from_dirserver(conn->_base.purpose, NULL,
|
||||
0 /* don't retry_if_no_servers */);
|
||||
directory_get_from_dirserver(conn->_base.purpose, conn->router_purpose,
|
||||
NULL, 0 /* don't retry_if_no_servers */);
|
||||
} else if (conn->_base.purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS) {
|
||||
log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
|
||||
conn->_base.address);
|
||||
@ -422,8 +429,8 @@ connection_dir_download_networkstatus_failed(dir_connection_t *conn,
|
||||
smartlist_t *trusted_dirs = router_get_trusted_dir_servers();
|
||||
SMARTLIST_FOREACH(trusted_dirs, trusted_dir_server_t *, ds,
|
||||
++ds->n_networkstatus_failures);
|
||||
directory_get_from_dirserver(conn->_base.purpose, "all.z",
|
||||
0 /* don't retry_if_no_servers */);
|
||||
directory_get_from_dirserver(conn->_base.purpose, conn->router_purpose,
|
||||
"all.z", 0 /* don't retry_if_no_servers */);
|
||||
} else if (!strcmpstart(conn->requested_resource, "fp/")) {
|
||||
/* We were trying to download by fingerprint; mark them all as having
|
||||
* failed, and possibly retry them later.*/
|
||||
@ -1699,7 +1706,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
|
||||
/* try to get a new one now */
|
||||
if (!already_fetching_directory(DIR_PURPOSE_FETCH_DIR) &&
|
||||
!should_delay_dir_fetches(options))
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 1);
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR,
|
||||
ROUTER_PURPOSE_GENERAL, NULL, 1);
|
||||
tor_free(url);
|
||||
return 0;
|
||||
}
|
||||
@ -1750,7 +1758,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
|
||||
/* try to get a new one now */
|
||||
if (!already_fetching_directory(DIR_PURPOSE_FETCH_RUNNING_LIST) &&
|
||||
!should_delay_dir_fetches(options))
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_RUNNING_LIST, NULL, 1);
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_RUNNING_LIST,
|
||||
ROUTER_PURPOSE_GENERAL, NULL, 1);
|
||||
tor_free(url);
|
||||
return 0;
|
||||
}
|
||||
|
@ -939,7 +939,8 @@ run_scheduled_events(time_t now)
|
||||
* our dirport. not simply if we configured one. -RD */
|
||||
if (any_trusted_dir_is_v1_authority() &&
|
||||
!should_delay_dir_fetches(options))
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 1);
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR,
|
||||
ROUTER_PURPOSE_GENERAL, NULL, 1);
|
||||
}
|
||||
/** How often do we (as a cache) fetch a new V1 directory? */
|
||||
#define V1_DIR_FETCH_PERIOD (6*60*60)
|
||||
@ -949,7 +950,8 @@ run_scheduled_events(time_t now)
|
||||
/* Caches need to fetch running_routers; directory clients don't. */
|
||||
if (options->DirPort && time_to_fetch_running_routers < now) {
|
||||
if (!authdir_mode_v1(options) && !should_delay_dir_fetches(options)) {
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_RUNNING_LIST, NULL, 1);
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_RUNNING_LIST,
|
||||
ROUTER_PURPOSE_GENERAL, NULL, 1);
|
||||
}
|
||||
/** How often do we (as a cache) fetch a new V1 runningrouters document? */
|
||||
#define V1_RUNNINGROUTERS_FETCH_PERIOD (30*60)
|
||||
|
@ -2670,10 +2670,11 @@ int assign_to_cpuworker(connection_t *cpuworker, uint8_t question_type,
|
||||
/********************************* directory.c ***************************/
|
||||
|
||||
char *authority_type_to_string(authority_type_t auth);
|
||||
void directory_post_to_dirservers(uint8_t purpose, authority_type_t type,
|
||||
const char *payload,
|
||||
void directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
|
||||
authority_type_t type, const char *payload,
|
||||
size_t payload_len, size_t extrainfo_len);
|
||||
void directory_get_from_dirserver(uint8_t dir_purpose, const char *resource,
|
||||
void directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
|
||||
const char *resource,
|
||||
int retry_if_no_servers);
|
||||
void directory_initiate_command_routerstatus(routerstatus_t *status,
|
||||
uint8_t dir_purpose,
|
||||
|
@ -261,7 +261,8 @@ rend_client_refetch_renddesc(const char *query)
|
||||
"already in progress.", escaped_safe_str(query));
|
||||
} else {
|
||||
/* not one already; initiate a dir rend desc lookup */
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_RENDDESC, query, 1);
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_RENDDESC,
|
||||
ROUTER_PURPOSE_GENERAL, query, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -948,6 +948,7 @@ upload_service_descriptor(rend_service_t *service, int version)
|
||||
|
||||
/* Post it to the dirservers */
|
||||
directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_RENDDESC,
|
||||
ROUTER_PURPOSE_GENERAL,
|
||||
HIDSERV_AUTHORITY, desc, desc_len, 0);
|
||||
tor_free(desc);
|
||||
|
||||
|
@ -909,8 +909,11 @@ router_upload_dir_desc_to_dirservers(int force)
|
||||
}
|
||||
msg[desc_len+extra_len] = 0;
|
||||
|
||||
directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_DIR, auth,
|
||||
msg, desc_len, extra_len);
|
||||
directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_DIR,
|
||||
(auth & BRIDGE_AUTHORITY) ?
|
||||
ROUTER_PURPOSE_BRIDGE :
|
||||
ROUTER_PURPOSE_GENERAL,
|
||||
auth, msg, desc_len, extra_len);
|
||||
tor_free(msg);
|
||||
}
|
||||
|
||||
|
@ -3416,7 +3416,8 @@ update_networkstatus_cache_downloads(time_t now)
|
||||
/* (Check whether we're currently fetching network-status objects.) */
|
||||
if (!connection_get_by_type_purpose(CONN_TYPE_DIR,
|
||||
DIR_PURPOSE_FETCH_NETWORKSTATUS))
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS,"all.z",1);
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS,
|
||||
ROUTER_PURPOSE_GENERAL, "all.z",1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3541,7 +3542,8 @@ update_networkstatus_client_downloads(time_t now)
|
||||
*cp++ = '+';
|
||||
});
|
||||
memcpy(cp, ".z", 3);
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS, resource, 1);
|
||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS,
|
||||
ROUTER_PURPOSE_GENERAL, resource, 1);
|
||||
tor_free(resource);
|
||||
smartlist_free(missing);
|
||||
}
|
||||
@ -4469,13 +4471,13 @@ initiate_descriptor_downloads(routerstatus_t *source,
|
||||
0, /* not private */
|
||||
resource, NULL, 0);
|
||||
} else {
|
||||
directory_get_from_dirserver(purpose, resource, 1);
|
||||
directory_get_from_dirserver(purpose, ROUTER_PURPOSE_GENERAL, resource, 1);
|
||||
}
|
||||
tor_free(resource);
|
||||
}
|
||||
|
||||
/** Clients don't download any descriptor this recent, since it will probably
|
||||
* not have propageted to enough caches. */
|
||||
* not have propagated to enough caches. */
|
||||
#define ESTIMATED_PROPAGATION_TIME (10*60)
|
||||
|
||||
/** Return 0 if this routerstatus is obsolete, too new, isn't
|
||||
|
Loading…
Reference in New Issue
Block a user