aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/or/circuitbuild.c30
-rw-r--r--src/or/directory.c77
-rw-r--r--src/or/main.c6
-rw-r--r--src/or/or.h7
-rw-r--r--src/or/rendclient.c3
-rw-r--r--src/or/rendservice.c1
-rw-r--r--src/or/router.c7
-rw-r--r--src/or/routerlist.c10
8 files changed, 84 insertions, 57 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 72c839b23..5cf90bd58 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -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);
}
});
}
diff --git a/src/or/directory.c b/src/or/directory.c
index 7084c163e..2bbd4deab 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -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;
}
diff --git a/src/or/main.c b/src/or/main.c
index 0d0adf700..d4dd8b324 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -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)
diff --git a/src/or/or.h b/src/or/or.h
index 8df54314e..7a1ac3117 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -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,
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index c65aa9513..fef95d1c8 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -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);
}
}
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 937d40b5c..8ec388809 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -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);
diff --git a/src/or/router.c b/src/or/router.c
index 1137881e6..77bcf19b7 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -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);
}
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 92338fa3e..9bb456c3a 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -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