[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r12368: If bridge users set UpdateBridgesFromAuthority, but the dige (in tor/trunk: . src/or)
Author: arma
Date: 2007-11-03 20:15:42 -0400 (Sat, 03 Nov 2007)
New Revision: 12368
Modified:
tor/trunk/ChangeLog
tor/trunk/src/or/circuitbuild.c
tor/trunk/src/or/directory.c
tor/trunk/src/or/or.h
Log:
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.
Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog 2007-11-04 00:15:17 UTC (rev 12367)
+++ tor/trunk/ChangeLog 2007-11-04 00:15:42 UTC (rev 12368)
@@ -50,6 +50,13 @@
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.
Modified: tor/trunk/src/or/circuitbuild.c
===================================================================
--- tor/trunk/src/or/circuitbuild.c 2007-11-04 00:15:17 UTC (rev 12367)
+++ tor/trunk/src/or/circuitbuild.c 2007-11-04 00:15:42 UTC (rev 12368)
@@ -2825,20 +2825,6 @@
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.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 @@
"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
Modified: tor/trunk/src/or/directory.c
===================================================================
--- tor/trunk/src/or/directory.c 2007-11-04 00:15:17 UTC (rev 12367)
+++ tor/trunk/src/or/directory.c 2007-11-04 00:15:42 UTC (rev 12368)
@@ -52,6 +52,7 @@
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_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 @@
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 @@
* 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 @@
});
/* 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
Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h 2007-11-04 00:15:17 UTC (rev 12367)
+++ tor/trunk/src/or/or.h 2007-11-04 00:15:42 UTC (rev 12368)
@@ -2425,6 +2425,7 @@
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);