[or-cvs] r10548: more building blocks towards being able to fetch bridge desc (tor/trunk/src/or)

arma at seul.org arma at seul.org
Sun Jun 10 07:34:21 UTC 2007


Author: arma
Date: 2007-06-10 03:34:21 -0400 (Sun, 10 Jun 2007)
New Revision: 10548

Modified:
   tor/trunk/src/or/circuitbuild.c
   tor/trunk/src/or/config.c
   tor/trunk/src/or/directory.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/router.c
   tor/trunk/src/or/routerlist.c
Log:
more building blocks towards being able to fetch bridge descriptors


Modified: tor/trunk/src/or/circuitbuild.c
===================================================================
--- tor/trunk/src/or/circuitbuild.c	2007-06-10 00:30:14 UTC (rev 10547)
+++ tor/trunk/src/or/circuitbuild.c	2007-06-10 07:34:21 UTC (rev 10548)
@@ -2622,3 +2622,79 @@
   return 0;
 }
 
+typedef struct {
+  uint32_t addr;
+  uint16_t port;
+  char identity[DIGEST_LEN];
+} bridge_info_t;
+
+/** A list of known bridges. */
+static smartlist_t *bridge_list = NULL;
+
+/** Initialize the bridge list to empty, creating it if needed. */
+void
+clear_bridge_list(void)
+{
+  if (!bridge_list)
+    bridge_list = smartlist_create();
+  SMARTLIST_FOREACH(bridge_list, bridge_info_t *, b, tor_free(b));
+  smartlist_clear(bridge_list);
+}
+
+/** Remember a new bridge at <b>addr</b>:<b>port</b>. If <b>digest</b>
+ * is set, it tells us the identity key too. */
+void
+bridge_add_from_config(uint32_t addr, uint16_t port, char *digest)
+{
+  bridge_info_t *b = tor_malloc_zero(sizeof(bridge_info_t));
+  b->addr = addr;
+  b->port = port;
+  if (digest)
+    memcpy(b->identity, digest, DIGEST_LEN);
+  if (!bridge_list)
+    bridge_list = smartlist_create();
+  smartlist_add(bridge_list, b);
+}
+
+/** 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. */
+void
+learn_bridge_descriptors(void)
+{
+  char address_buf[INET_NTOA_BUF_LEN+1];
+  struct in_addr in;
+  or_options_t *options = get_options();
+  int num_bridge_auths = get_n_authorities(BRIDGE_AUTHORITY);
+
+  if (!bridge_list)
+    return;
+
+  SMARTLIST_FOREACH(bridge_list, bridge_info_t *, bridge,
+    {
+      if (router_get_by_digest(bridge->identity))
+        continue; /* we've already got one. great. */
+      in.s_addr = htonl(bridge->addr);
+      tor_inet_ntoa(&in, address_buf, sizeof(address_buf));
+
+      if (tor_digest_is_zero(bridge->identity) ||
+          !options->UpdateBridgesFromAuthority ||
+          !num_bridge_auths) {
+        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", NULL, 0);
+        }
+      } else {
+        /* we have a digest and we want to ask an authority. */
+        // XXX
+      }
+    });
+}
+

Modified: tor/trunk/src/or/config.c
===================================================================
--- tor/trunk/src/or/config.c	2007-06-10 00:30:14 UTC (rev 10547)
+++ tor/trunk/src/or/config.c	2007-06-10 07:34:21 UTC (rev 10548)
@@ -263,6 +263,7 @@
   VAR("TransListenAddress",  LINELIST, TransListenAddress,   NULL),
   VAR("TransPort",           UINT,     TransPort,            "0"),
   VAR("TunnelDirConns",      BOOL,     TunnelDirConns,       "0"),
+  VAR("UpdateBridgesFromAuthority",BOOL,UpdateBridgesFromAuthority,"0"),
   VAR("UseBridges",          BOOL,     UseBridges,           "0"),
   VAR("UseEntryGuards",      BOOL,     UseEntryGuards,       "1"),
   VAR("User",                STRING,   User,                 NULL),
@@ -952,6 +953,7 @@
     add_default_trusted_dirservers();
   }
 
+  clear_bridge_list();
   if (options->Bridges) {
     for (cl = options->Bridges; cl; cl = cl->next) {
       if (parse_bridge_line(cl->value, 0)<0) {
@@ -3606,7 +3608,7 @@
     log_debug(LD_DIR, "Bridge at %s:%d (%s)", address,
               (int)port,
               fingerprint ? fingerprint : "no key listed");
-//    bridge_add_from_config(addr, port, fingerprint ? digest : NULL);
+    bridge_add_from_config(addr, port, fingerprint ? digest : NULL);
   }
 
   r = 0;

Modified: tor/trunk/src/or/directory.c
===================================================================
--- tor/trunk/src/or/directory.c	2007-06-10 00:30:14 UTC (rev 10547)
+++ tor/trunk/src/or/directory.c	2007-06-10 07:34:21 UTC (rev 10548)
@@ -177,7 +177,9 @@
       }
       post_via_tor = purpose_needs_anonymity(purpose) ||
               !fascist_firewall_allows_address_dir(ds->addr, ds->dir_port);
-      directory_initiate_command_routerstatus(rs, purpose, post_via_tor,
+      directory_initiate_command_routerstatus(rs, purpose,
+                                              ROUTER_PURPOSE_GENERAL,
+                                              post_via_tor,
                                               NULL, payload, upload_len);
     });
   if (!found) {
@@ -194,18 +196,18 @@
  * down, mark them up and try again.
  */
 void
-directory_get_from_dirserver(uint8_t purpose, const char *resource,
+directory_get_from_dirserver(uint8_t dir_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(purpose);
+  int directconn = !purpose_needs_anonymity(dir_purpose);
   authority_type_t type;
 
   /* FFFF we could break this switch into its own function, and call
    * it elsewhere in directory.c. -RD */
-  switch (purpose) {
+  switch (dir_purpose) {
     case DIR_PURPOSE_FETCH_EXTRAINFO:
       type = EXTRAINFO_CACHE | V2_AUTHORITY;
       break;
@@ -221,7 +223,7 @@
       type = HIDSERV_AUTHORITY;
       break;
     default:
-      log_warn(LD_BUG, "Unexpected purpose %d", (int)purpose);
+      log_warn(LD_BUG, "Unexpected purpose %d", (int)dir_purpose);
       return;
   }
 
@@ -240,13 +242,13 @@
                                         retry_if_no_servers);
       if (!rs) {
         const char *which;
-        if (purpose == DIR_PURPOSE_FETCH_DIR)
+        if (dir_purpose == DIR_PURPOSE_FETCH_DIR)
           which = "directory";
-        else if (purpose == DIR_PURPOSE_FETCH_RUNNING_LIST)
+        else if (dir_purpose == DIR_PURPOSE_FETCH_RUNNING_LIST)
           which = "status list";
-        else if (purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS)
+        else if (dir_purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS)
           which = "network status";
-        else // if (purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS)
+        else // if (dir_purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS)
           which = "server descriptors";
         log_info(LD_DIR,
                  "No router found for %s; falling back to dirserver list",
@@ -260,7 +262,7 @@
   }
   if (!directconn) {
     /* Never use fascistfirewall; we're going via Tor. */
-    if (purpose == DIR_PURPOSE_FETCH_RENDDESC) {
+    if (dir_purpose == DIR_PURPOSE_FETCH_RENDDESC) {
       /* only ask hidserv authorities, any of them will do */
       rs = router_pick_trusteddirserver(HIDSERV_AUTHORITY, 0, 0,
                                         retry_if_no_servers);
@@ -275,24 +277,29 @@
   }
 
   if (rs)
-    directory_initiate_command_routerstatus(rs, purpose, !directconn,
+    directory_initiate_command_routerstatus(rs, dir_purpose,
+                                            ROUTER_PURPOSE_GENERAL,
+                                            !directconn,
                                             resource, NULL, 0);
   else {
     log_notice(LD_DIR,
                "While fetching directory info, "
                "no running dirservers known. Will try again later. "
-               "(purpose %d)", purpose);
-    if (!purpose_needs_anonymity(purpose)) {
+               "(purpose %d)", dir_purpose);
+    if (!purpose_needs_anonymity(dir_purpose)) {
       /* remember we tried them all and failed. */
       directory_all_unreachable(time(NULL));
     }
   }
 }
 
-/** Launch a new connection to the directory server <b>status</b> to upload or
- * download a server or rendezvous descriptor. <b>purpose</b> determines what
+/** Launch a new connection to the directory server <b>status</b> to
+ * upload or download a server or rendezvous
+ * descriptor. <b>dir_purpose</b> determines what
  * kind of directory connection we're launching, and must be one of
- * DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC}.
+ * DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC}. <b>router_purpose</b>
+ * specifies the descriptor purposes we have in mind (currently only
+ * used for FETCH_DIR).
  *
  * When uploading, <b>payload</b> and <b>payload_len</b> determine the content
  * of the HTTP post.  Otherwise, <b>payload</b> should be NULL.
@@ -302,7 +309,8 @@
  */
 void
 directory_initiate_command_routerstatus(routerstatus_t *status,
-                                        uint8_t purpose,
+                                        uint8_t dir_purpose,
+                                        uint8_t router_purpose,
                                         int anonymized_connection,
                                         const char *resource,
                                         const char *payload,
@@ -323,7 +331,8 @@
                              status->or_port, status->dir_port,
                              status->version_supports_begindir,
                              status->identity_digest,
-                             purpose, anonymized_connection, resource,
+                             dir_purpose, router_purpose,
+                             anonymized_connection, resource,
                              payload, payload_len);
 }
 
@@ -441,8 +450,8 @@
 void
 directory_initiate_command(const char *address, uint32_t addr,
                            uint16_t or_port, uint16_t dir_port,
-                           int supports_begindir,
-                           const char *digest, uint8_t purpose,
+                           int supports_begindir, const char *digest,
+                           uint8_t dir_purpose, uint8_t router_purpose,
                            int anonymized_connection, const char *resource,
                            const char *payload, size_t payload_len)
 {
@@ -460,7 +469,7 @@
   log_debug(LD_DIR, "anonymized %d, want_to_tunnel %d.",
             anonymized_connection, want_to_tunnel);
 
-  switch (purpose) {
+  switch (dir_purpose) {
     case DIR_PURPOSE_FETCH_DIR:
       log_debug(LD_DIR,"initiating directory fetch");
       break;
@@ -498,7 +507,8 @@
   conn->_base.address = tor_strdup(address);
   memcpy(conn->identity_digest, digest, DIGEST_LEN);
 
-  conn->_base.purpose = purpose;
+  conn->_base.purpose = dir_purpose;
+  conn->router_purpose = router_purpose;
 
   /* give it an initial state */
   conn->_base.state = DIR_CONN_STATE_CONNECTING;
@@ -524,7 +534,7 @@
         /* fall through */
       case 0:
         /* queue the command on the outbuf */
-        directory_send_command(conn, purpose, 1, resource,
+        directory_send_command(conn, dir_purpose, 1, resource,
                                payload, payload_len);
         connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
         /* writable indicates finish, readable indicates broken link,
@@ -557,7 +567,7 @@
     }
     conn->_base.state = DIR_CONN_STATE_CLIENT_SENDING;
     /* queue the command on the outbuf */
-    directory_send_command(conn, purpose, 0, resource,
+    directory_send_command(conn, dir_purpose, 0, resource,
                            payload, payload_len);
     connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
     connection_start_reading(TO_CONN(linked_conn));
@@ -1256,7 +1266,8 @@
       if (was_ei) {
         router_load_extrainfo_from_string(body, NULL, SAVED_NOWHERE, which);
       } else {
-        router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which);
+        router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which,
+                                        conn->router_purpose);
         directory_info_has_arrived(now, 0);
       }
     }

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-06-10 00:30:14 UTC (rev 10547)
+++ tor/trunk/src/or/or.h	2007-06-10 07:34:21 UTC (rev 10548)
@@ -934,6 +934,9 @@
     DIR_SPOOL_EXTRA_BY_DIGEST, DIR_SPOOL_EXTRA_BY_FP,
     DIR_SPOOL_CACHED_DIR, DIR_SPOOL_NETWORKSTATUS
   } dir_spool_src : 3;
+  /** If we're fetching descriptors, what router purpose shall we assign
+   * to them? */
+  uint8_t router_purpose;
   /** List of fingerprints for networkstatuses or desriptors to be spooled. */
   smartlist_t *fingerprint_stack;
   /** A cached_dir_t object that we're currently spooling out */
@@ -1850,6 +1853,10 @@
   int UseBridges; /**< Boolean: should we start all circuits with a bridge? */
   config_line_t *Bridges; /**< List of bootstrap bridge addresses. */
 
+  /** Boolean: if we know the bridge's digest, should we get new
+   * descriptors from the bridge authorities or from the bridge itself? */
+  int UpdateBridgesFromAuthority;
+
   int AvoidDiskWrites; /**< Boolean: should we never cache things to disk?
                         * Not used yet. */
   int ClientOnly; /**< Boolean: should we never evolve into a server role? */
@@ -2210,6 +2217,10 @@
                                 const char *question, char **answer);
 void entry_guards_free_all(void);
 
+void clear_bridge_list(void);
+void bridge_add_from_config(uint32_t addr, uint16_t port, char *digest);
+void learn_bridge_descriptors(void);
+
 /********************************* circuitlist.c ***********************/
 
 circuit_t * _circuit_get_global_list(void);
@@ -2640,10 +2651,11 @@
 void directory_post_to_dirservers(uint8_t purpose, authority_type_t type,
                                   const char *payload,
                                   size_t payload_len, size_t extrainfo_len);
-void directory_get_from_dirserver(uint8_t purpose, const char *resource,
+void directory_get_from_dirserver(uint8_t dir_purpose, const char *resource,
                                   int retry_if_no_servers);
 void directory_initiate_command_routerstatus(routerstatus_t *status,
-                                             uint8_t purpose,
+                                             uint8_t dir_purpose,
+                                             uint8_t router_purpose,
                                              int anonymized_connection,
                                              const char *resource,
                                              const char *payload,
@@ -2659,8 +2671,8 @@
 void connection_dir_request_failed(dir_connection_t *conn);
 void directory_initiate_command(const char *address, uint32_t addr,
                                 uint16_t or_port, uint16_t dir_port,
-                                int supports_begindir,
-                                const char *digest, uint8_t purpose,
+                                int supports_begindir, const char *digest,
+                                uint8_t dir_purpose, uint8_t router_purpose,
                                 int anonymized_connection,
                                 const char *resource,
                                 const char *payload, size_t payload_len);
@@ -3202,6 +3214,7 @@
 } trusted_dir_server_t;
 
 int router_reload_router_list(void);
+int get_n_authorities(authority_type_t type);
 int router_reload_networkstatus(void);
 smartlist_t *router_get_trusted_dir_servers(void);
 routerstatus_t *router_pick_directory_server(int requireother,
@@ -3274,7 +3287,8 @@
                               const char **msg);
 void router_load_routers_from_string(const char *s, const char *eos,
                                      saved_location_t saved_location,
-                                     smartlist_t *requested_fingerprints);
+                                     smartlist_t *requested_fingerprints,
+                                     uint8_t purpose);
 void router_load_extrainfo_from_string(const char *s, const char *eos,
                                        saved_location_t saved_location,
                                        smartlist_t *requested_fps);

Modified: tor/trunk/src/or/router.c
===================================================================
--- tor/trunk/src/or/router.c	2007-06-10 00:30:14 UTC (rev 10547)
+++ tor/trunk/src/or/router.c	2007-06-10 07:34:21 UTC (rev 10548)
@@ -614,6 +614,7 @@
                                me->or_port, me->dir_port,
                                0, me->cache_info.identity_digest,
                                DIR_PURPOSE_FETCH_SERVERDESC,
+                               ROUTER_PURPOSE_GENERAL,
                                1, "authority", NULL, 0);
 
     control_event_server_status(LOG_NOTICE,

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2007-06-10 00:30:14 UTC (rev 10547)
+++ tor/trunk/src/or/routerlist.c	2007-06-10 07:34:21 UTC (rev 10548)
@@ -109,7 +109,7 @@
 
 /** Return the number of directory authorities whose type matches some bit set
  * in <b>type</b>  */
-static INLINE int
+INLINE int
 get_n_authorities(authority_type_t type)
 {
   int n = 0;
@@ -549,7 +549,8 @@
     else
       router_load_routers_from_string((*mmap_ptr)->data,
                                       (*mmap_ptr)->data+(*mmap_ptr)->size,
-                                      SAVED_IN_CACHE, NULL);
+                                      SAVED_IN_CACHE, NULL,
+                                      ROUTER_PURPOSE_GENERAL);
   }
 
   tor_snprintf(fname, fname_len, "%s"PATH_SEPARATOR"%s.new",
@@ -560,7 +561,8 @@
     if (extrainfo)
       router_load_extrainfo_from_string(contents, NULL,SAVED_IN_JOURNAL, NULL);
     else
-      router_load_routers_from_string(contents, NULL, SAVED_IN_JOURNAL, NULL);
+      router_load_routers_from_string(contents, NULL, SAVED_IN_JOURNAL, NULL,
+                                      ROUTER_PURPOSE_GENERAL);
     stats->journal_len = (size_t) st.st_size;
     tor_free(contents);
   }
@@ -2788,7 +2790,8 @@
 void
 router_load_routers_from_string(const char *s, const char *eos,
                                 saved_location_t saved_location,
-                                smartlist_t *requested_fingerprints)
+                                smartlist_t *requested_fingerprints,
+                                uint8_t purpose)
 {
   smartlist_t *routers = smartlist_create(), *changed = smartlist_create();
   char fp[HEX_DIGEST_LEN+1];
@@ -2821,6 +2824,10 @@
       }
     }
 
+    ri->purpose = purpose;
+    if (purpose != ROUTER_PURPOSE_GENERAL)
+      ri->cache_info.do_not_cache = 1;
+
     if (router_add_to_routerlist(ri, &msg, from_cache, !from_cache) >= 0)
       smartlist_add(changed, ri);
   });
@@ -3340,6 +3347,10 @@
          if (connection_get_by_type_addr_port_purpose(
                 CONN_TYPE_DIR, ds->addr, ds->dir_port,
                 DIR_PURPOSE_FETCH_NETWORKSTATUS)) {
+           /* XXX020 the above dir_port won't be accurate if we're
+            * doing a tunneled conn. In that case it should be or_port.
+            * How to guess from here? Maybe make the function less general
+            * and have it know that it's looking for dir conns. -RD */
            /* We are already fetching this one. */
            continue;
          }
@@ -3348,6 +3359,7 @@
          strlcat(resource, ".z", sizeof(resource));
          directory_initiate_command_routerstatus(
                &ds->fake_status.status, DIR_PURPOSE_FETCH_NETWORKSTATUS,
+               ROUTER_PURPOSE_GENERAL,
                0, /* Not private */
                resource,
                NULL, 0 /* No payload. */);
@@ -4365,6 +4377,7 @@
   if (source) {
     /* We know which authority we want. */
     directory_initiate_command_routerstatus(source, purpose,
+                                            ROUTER_PURPOSE_GENERAL,
                                             0, /* not private */
                                             resource, NULL, 0);
   } else {



More information about the tor-commits mailing list