summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2007-06-15 06:01:04 +0000
committerRoger Dingledine <arma@torproject.org>2007-06-15 06:01:04 +0000
commit2cd293dc8f447d9b96590c92d2ef00458c3996a2 (patch)
treee154736479ba230f7ee09deb8ba5ffa04d59cdad
parent6a2f045163e7583fd41318cd8f0e4d321c937fee (diff)
downloadtor-2cd293dc8f447d9b96590c92d2ef00458c3996a2.tar.gz
tor-2cd293dc8f447d9b96590c92d2ef00458c3996a2.zip
now we can specify a bridge without specifying its key,
and we will still connect to it and use it. getting closer! svn:r10609
-rw-r--r--src/or/circuitbuild.c35
-rw-r--r--src/or/circuitlist.c17
-rw-r--r--src/or/connection_or.c11
-rw-r--r--src/or/or.h2
-rw-r--r--src/or/routerlist.c2
5 files changed, 57 insertions, 10 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index f505ae03fe..3f8515542e 100644
--- a/src/or/circuitbuild.c
+++ b/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. */
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 4b455e958f..b668d298c6 100644
--- a/src/or/circuitlist.c
+++ b/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);
});
}
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 817f491349..6b4c9e663f 100644
--- a/src/or/connection_or.c
+++ b/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);
diff --git a/src/or/or.h b/src/or/or.h
index 75a6a3783c..784f56cec8 100644
--- a/src/or/or.h
+++ b/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);
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index d7f56058fb..5981d22954 100644
--- a/src/or/routerlist.c
+++ b/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,