[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);