Browse Source

now we can specify a bridge without specifying its key,
and we will still connect to it and use it. getting closer!


svn:r10609

Roger Dingledine 17 years ago
parent
commit
2cd293dc8f
5 changed files with 57 additions and 10 deletions
  1. 32 3
      src/or/circuitbuild.c
  2. 12 5
      src/or/circuitlist.c
  3. 11 0
      src/or/connection_or.c
  4. 1 1
      src/or/or.h
  5. 1 1
      src/or/routerlist.c

+ 32 - 3
src/or/circuitbuild.c

@@ -413,13 +413,23 @@ circuit_n_conn_done(or_connection_t *or_conn, int status)
 
   SMARTLIST_FOREACH(pending_circs, circuit_t *, circ,
     {
-      /* This check is redundant wrt get_all_pending_on_or_conn, but I'm
+      /* These checks are redundant wrt get_all_pending_on_or_conn, but I'm
        * leaving them in in case it's possible for the status of a circuit to
        * change as we're going down the list. */
       if (circ->marked_for_close || circ->n_conn ||
-          circ->state != CIRCUIT_STATE_OR_WAIT ||
-          memcmp(or_conn->identity_digest, circ->n_conn_id_digest, DIGEST_LEN))
+          circ->state != CIRCUIT_STATE_OR_WAIT)
         continue;
+      if (tor_digest_is_zero(circ->n_conn_id_digest)) {
+        /* Look at addr/port. This is an unkeyed connection. */
+        if (circ->n_addr != or_conn->_base.addr ||
+            circ->n_port != or_conn->_base.port)
+          continue;
+      } else {
+        /* We expected a key. See if it's the right one. */
+        if (memcmp(or_conn->identity_digest,
+                   circ->n_conn_id_digest, DIGEST_LEN))
+          continue;
+      }
       if (!status) { /* or_conn failed; close circ */
         log_info(LD_CIRC,"or_conn failed. Closing circ.");
         circuit_mark_for_close(circ, END_CIRC_REASON_OR_CONN_CLOSED);
@@ -2670,6 +2680,7 @@ 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)
@@ -2681,6 +2692,24 @@ identity_digest_is_a_bridge(const char *digest)
     });
   return 0;
 }
+#endif
+
+/** Return 1 if <b>ri</b> is one of our known bridges (either by
+ * comparing keys if possible, else by comparing addr/port). */
+int
+routerinfo_is_a_bridge(routerinfo_t *ri)
+{
+  SMARTLIST_FOREACH(bridge_list, bridge_info_t *, bridge,
+    {
+      if (tor_digest_is_zero(bridge->identity) &&
+          bridge->addr == ri->addr && bridge->port == ri->or_port)
+        return 1;
+      if (!memcmp(bridge->identity, ri->cache_info.identity_digest,
+                  DIGEST_LEN))
+        return 1;
+    });
+  return 0;
+}
 
 /** Remember a new bridge at <b>addr</b>:<b>port</b>. If <b>digest</b>
  * is set, it tells us the identity key too. */

+ 12 - 5
src/or/circuitlist.c

@@ -218,7 +218,7 @@ circuit_add(circuit_t *circ)
   }
 }
 
-/** Append to <b>out</b> the number of circuits in state OR_WAIT, waiting for
+/** Append to <b>out</b> all circuits in state OR_WAIT waiting for
  * the given connection. */
 void
 circuit_get_all_pending_on_or_conn(smartlist_t *out, or_connection_t *or_conn)
@@ -234,11 +234,18 @@ circuit_get_all_pending_on_or_conn(smartlist_t *out, or_connection_t *or_conn)
     if (circ->marked_for_close)
       continue;
     tor_assert(circ->state == CIRCUIT_STATE_OR_WAIT);
-    if (!circ->n_conn &&
-        !memcmp(or_conn->identity_digest, circ->n_conn_id_digest,
-                DIGEST_LEN)) {
-      smartlist_add(out, circ);
+    if (tor_digest_is_zero(circ->n_conn_id_digest)) {
+      /* Look at addr/port. This is an unkeyed connection. */
+      if (circ->n_addr != or_conn->_base.addr ||
+          circ->n_port != or_conn->_base.port)
+        continue;
+    } else {
+      /* We expected a key. See if it's the right one. */
+      if (memcmp(or_conn->identity_digest,
+                 circ->n_conn_id_digest, DIGEST_LEN))
+        continue;
     }
+    smartlist_add(out, circ);
   });
 }
 

+ 11 - 0
src/or/connection_or.c

@@ -655,6 +655,17 @@ connection_or_check_valid_handshake(or_connection_t *conn, int started_here,
     conn->circ_id_type = CIRC_ID_TYPE_NEITHER;
   }
 
+  if (started_here && tor_digest_is_zero(conn->identity_digest)) {
+    memcpy(conn->identity_digest, digest_rcvd, DIGEST_LEN);
+    conn->nickname = tor_malloc(HEX_DIGEST_LEN+2);
+    conn->nickname[0] = '$';
+    base16_encode(conn->nickname+1, HEX_DIGEST_LEN+1,
+                  conn->identity_digest, DIGEST_LEN);
+    log_info(LD_OR, "Connected to router %s at %s:%d without knowing "
+                    "its key. Hoping for the best.",
+                    conn->nickname, conn->_base.address, conn->_base.port);
+  }
+
   if (started_here) {
     int as_advertised = 1;
     tor_assert(has_cert);

+ 1 - 1
src/or/or.h

@@ -2223,7 +2223,7 @@ int getinfo_helper_entry_guards(control_connection_t *conn,
 void entry_guards_free_all(void);
 
 void clear_bridge_list(void);
-int identity_digest_is_a_bridge(const char *digest);
+int routerinfo_is_a_bridge(routerinfo_t *ri);
 void bridge_add_from_config(uint32_t addr, uint16_t port, char *digest);
 void fetch_bridge_descriptors(void);
 void learned_bridge_descriptor(routerinfo_t *ri);

+ 1 - 1
src/or/routerlist.c

@@ -2388,7 +2388,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
      * we are receiving in response to a fetch. */
 
     if (!signed_desc_digest_is_recognized(&router->cache_info) &&
-        !identity_digest_is_a_bridge(router->cache_info.identity_digest)) {
+        !routerinfo_is_a_bridge(router)) {
       /* We asked for it, so some networkstatus must have listed it when we
        * did.  Save it if we're a cache in case somebody else asks for it. */
       log_info(LD_DIR,