mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 05:03:43 +01:00
If bridge users set UpdateBridgesFromAuthority, but the digest
they ask for is a 404 from the bridge authority, they now fall back to trying the bridge directly. svn:r12368
This commit is contained in:
parent
8cc70addd7
commit
e9af56cf2f
@ -50,6 +50,13 @@ Changes in version 0.2.0.10-alpha - 2007-11-0?
|
||||
fix for bug 535.
|
||||
- Make the "not enough dir info yet" message better.
|
||||
|
||||
o Minor features (bridges):
|
||||
- If bridge users set UpdateBridgesFromAuthority, but the digest
|
||||
they ask for is a 404 from the bridge authority, they now fall
|
||||
back to trying the bridge directly.
|
||||
- Bridges now use begin_dir to publish their server descriptor to
|
||||
the bridge authority, even when they haven't set TunnelDirConns.
|
||||
|
||||
o Minor features (controller):
|
||||
- When reporting clock skew, and we only have a lower bound on
|
||||
the amount of skew, amount anyway, marked as a lower bound.
|
||||
|
@ -2825,20 +2825,6 @@ clear_bridge_list(void)
|
||||
smartlist_clear(bridge_list);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/** Return 1 if <b>digest</b> is one of our known bridges. */
|
||||
int
|
||||
identity_digest_is_a_bridge(const char *digest)
|
||||
{
|
||||
SMARTLIST_FOREACH(bridge_list, bridge_info_t *, bridge,
|
||||
{
|
||||
if (!memcmp(bridge->identity, digest, DIGEST_LEN))
|
||||
return 1;
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Return a bridge pointer if <b>ri</b> is one of our known bridges
|
||||
* (either by comparing keys if possible, else by comparing addr/port).
|
||||
* Else return NULL. */
|
||||
@ -2902,6 +2888,52 @@ bridge_fetch_status_arrived(bridge_info_t *bridge, time_t now)
|
||||
bridge->fetch_status.n_download_failures = 0;
|
||||
}
|
||||
|
||||
/** If <b>digest</b> is one of our known bridges, return it. */
|
||||
static bridge_info_t *
|
||||
find_bridge_by_digest(char *digest)
|
||||
{
|
||||
SMARTLIST_FOREACH(bridge_list, bridge_info_t *, bridge,
|
||||
{
|
||||
if (!memcmp(bridge->identity, digest, DIGEST_LEN))
|
||||
return bridge;
|
||||
});
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** We need to ask <b>bridge</b> for its server descriptor. <b>address</b>
|
||||
* is a helpful string describing this bridge. */
|
||||
static void
|
||||
launch_direct_bridge_descriptor_fetch(char *address, bridge_info_t *bridge)
|
||||
{
|
||||
if (connection_get_by_type_addr_port_purpose(
|
||||
CONN_TYPE_DIR, bridge->addr, bridge->port,
|
||||
DIR_PURPOSE_FETCH_SERVERDESC))
|
||||
return; /* it's already on the way */
|
||||
directory_initiate_command(address, bridge->addr,
|
||||
bridge->port, 0,
|
||||
1, bridge->identity,
|
||||
DIR_PURPOSE_FETCH_SERVERDESC,
|
||||
ROUTER_PURPOSE_BRIDGE,
|
||||
0, "authority.z", NULL, 0, 0);
|
||||
}
|
||||
|
||||
/** Fetching the bridge descriptor from the bridge authority returned a
|
||||
* "not found". Fall back to trying a direct fetch. */
|
||||
void
|
||||
retry_bridge_descriptor_fetch_directly(char *digest)
|
||||
{
|
||||
bridge_info_t *bridge = find_bridge_by_digest(digest);
|
||||
char address_buf[INET_NTOA_BUF_LEN+1];
|
||||
struct in_addr in;
|
||||
|
||||
if (!bridge)
|
||||
return; /* not found? oh well. */
|
||||
|
||||
in.s_addr = htonl(bridge->addr);
|
||||
tor_inet_ntoa(&in, address_buf, sizeof(address_buf));
|
||||
launch_direct_bridge_descriptor_fetch(address_buf, bridge);
|
||||
}
|
||||
|
||||
/** For each bridge in our list for which we don't currently have a
|
||||
* descriptor, fetch a new copy of its descriptor -- either directly
|
||||
* from the bridge or via a bridge authority. */
|
||||
@ -2941,21 +2973,15 @@ fetch_bridge_descriptors(time_t now)
|
||||
"firewall policy. %s.", address_buf, bridge->port,
|
||||
num_bridge_auths ? "Asking bridge authority instead" :
|
||||
"Skipping");
|
||||
ask_bridge_directly = 0;
|
||||
if (num_bridge_auths)
|
||||
ask_bridge_directly = 0;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ask_bridge_directly) {
|
||||
if (!connection_get_by_type_addr_port_purpose(
|
||||
CONN_TYPE_DIR, bridge->addr, bridge->port,
|
||||
DIR_PURPOSE_FETCH_SERVERDESC)) {
|
||||
/* we need to ask the bridge itself for its descriptor. */
|
||||
directory_initiate_command(address_buf, bridge->addr,
|
||||
bridge->port, 0,
|
||||
1, bridge->identity,
|
||||
DIR_PURPOSE_FETCH_SERVERDESC,
|
||||
ROUTER_PURPOSE_BRIDGE,
|
||||
0, "authority.z", NULL, 0, 0);
|
||||
}
|
||||
/* we need to ask the bridge itself for its descriptor. */
|
||||
launch_direct_bridge_descriptor_fetch(address_buf, bridge);
|
||||
} else {
|
||||
/* We have a digest and we want to ask an authority. We could
|
||||
* combine all the requests into one, but that may give more
|
||||
|
@ -52,6 +52,7 @@ static void dir_networkstatus_download_failed(smartlist_t *failed,
|
||||
int status_code);
|
||||
static void dir_routerdesc_download_failed(smartlist_t *failed,
|
||||
int status_code,
|
||||
int router_purpose,
|
||||
int was_extrainfo,
|
||||
int was_descriptor_digests);
|
||||
static void note_request(const char *key, size_t bytes);
|
||||
@ -1582,6 +1583,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
|
||||
connection_dir_download_routerdesc_failed(conn);
|
||||
} else {
|
||||
dir_routerdesc_download_failed(which, status_code,
|
||||
conn->router_purpose,
|
||||
was_ei, descriptor_digests);
|
||||
SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
|
||||
smartlist_free(which);
|
||||
@ -1621,6 +1623,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
|
||||
conn->_base.address, (int)conn->_base.port);
|
||||
if (smartlist_len(which)) {
|
||||
dir_routerdesc_download_failed(which, status_code,
|
||||
conn->router_purpose,
|
||||
was_ei, descriptor_digests);
|
||||
}
|
||||
SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
|
||||
@ -2968,16 +2971,26 @@ download_status_reset(download_status_t *dls)
|
||||
* either as descriptor digests or as identity digests based on
|
||||
* <b>was_descriptor_digests</b>).
|
||||
*/
|
||||
void
|
||||
static void
|
||||
dir_routerdesc_download_failed(smartlist_t *failed, int status_code,
|
||||
int router_purpose,
|
||||
int was_extrainfo, int was_descriptor_digests)
|
||||
{
|
||||
char digest[DIGEST_LEN];
|
||||
time_t now = time(NULL);
|
||||
or_options_t *options = get_options();
|
||||
int server = server_mode(options) && dirserver_mode(options);
|
||||
if (!was_descriptor_digests)
|
||||
return; /* FFFF should implement this someday */
|
||||
if (!was_descriptor_digests) {
|
||||
if (router_purpose == ROUTER_PURPOSE_BRIDGE) {
|
||||
tor_assert(!was_extrainfo); /* not supported yet */
|
||||
SMARTLIST_FOREACH(failed, const char *, cp,
|
||||
{
|
||||
base16_decode(digest, DIGEST_LEN, cp, strlen(cp));
|
||||
retry_bridge_descriptor_fetch_directly(digest);
|
||||
});
|
||||
}
|
||||
return; /* FFFF should implement for other-than-router-purpose someday */
|
||||
}
|
||||
SMARTLIST_FOREACH(failed, const char *, cp,
|
||||
{
|
||||
download_status_t *dls = NULL;
|
||||
@ -2996,7 +3009,7 @@ dir_routerdesc_download_failed(smartlist_t *failed, int status_code,
|
||||
});
|
||||
|
||||
/* No need to relaunch descriptor downloads here: we already do it
|
||||
* every 10 seconds (DESCRIPTOR_RETRY_INTERVAL) in main.c. */
|
||||
* every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
|
||||
}
|
||||
|
||||
/** Given a directory <b>resource</b> request, containing zero
|
||||
|
@ -2425,6 +2425,7 @@ int getinfo_helper_entry_guards(control_connection_t *conn,
|
||||
void clear_bridge_list(void);
|
||||
int routerinfo_is_a_configured_bridge(routerinfo_t *ri);
|
||||
void bridge_add_from_config(uint32_t addr, uint16_t port, char *digest);
|
||||
void retry_bridge_descriptor_fetch_directly(char *digest);
|
||||
void fetch_bridge_descriptors(time_t now);
|
||||
void learned_bridge_descriptor(routerinfo_t *ri);
|
||||
int any_bridge_descriptors_known(void);
|
||||
|
Loading…
Reference in New Issue
Block a user