[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] Rename connection_get_by_identity_digest to reflect that it...
Update of /home/or/cvsroot/tor/src/or
In directory moria:/tmp/cvs-serv15245/src/or
Modified Files:
circuitbuild.c connection.c connection_or.c dirserv.c or.h
relay.c router.c routerlist.c
Log Message:
Rename connection_get_by_identity_digest to reflect that it is OR-only. Make it use a hashtable instead of a linear search.
Index: circuitbuild.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/circuitbuild.c,v
retrieving revision 1.163
retrieving revision 1.164
diff -u -d -r1.163 -r1.164
--- circuitbuild.c 24 Nov 2005 06:44:13 -0000 1.163
+++ circuitbuild.c 30 Nov 2005 03:01:16 -0000 1.164
@@ -342,7 +342,7 @@
/* imprint the circuit with its future n_conn->id */
memcpy(circ->n_conn_id_digest, firsthop->extend_info->identity_digest,
DIGEST_LEN);
- n_conn = connection_get_by_identity_digest(
+ n_conn = connection_or_get_by_identity_digest(
firsthop->extend_info->identity_digest);
if (!n_conn || n_conn->state != OR_CONN_STATE_OPEN ||
(n_conn->is_obsolete &&
@@ -637,7 +637,7 @@
onionskin = cell->payload+RELAY_HEADER_SIZE+4+2;
id_digest = cell->payload+RELAY_HEADER_SIZE+4+2+ONIONSKIN_CHALLENGE_LEN;
- n_conn = connection_get_by_identity_digest(id_digest);
+ n_conn = connection_or_get_by_identity_digest(id_digest);
if (!n_conn || n_conn->state != OR_CONN_STATE_OPEN ||
(n_conn->is_obsolete &&
Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection.c,v
retrieving revision 1.422
retrieving revision 1.423
diff -u -d -r1.422 -r1.423
--- connection.c 26 Nov 2005 01:43:57 -0000 1.422
+++ connection.c 30 Nov 2005 03:01:16 -0000 1.423
@@ -237,6 +237,10 @@
tor_close_socket(conn->s);
}
+ if (conn->type == CONN_TYPE_OR && !tor_digest_is_zero(conn->identity_digest)) {
+ connection_or_remove_from_identity_map(conn);
+ }
+
memset(conn, 0xAA, sizeof(connection_t)); /* poison memory */
tor_free(conn);
}
@@ -1570,47 +1574,6 @@
return NULL;
}
-/** Return the best connection of type OR with the
- * digest <b>digest</b> that we have, or NULL if we have none.
- *
- * 1) Don't return it if it's marked for close.
- * 2) If there are any open conns, ignore non-open conns.
- * 3) If there are any non-obsolete conns, ignore obsolete conns.
- * 4) Then if there are any non-empty conns, ignore empty conns.
- * 5) Of the remaining conns, prefer newer conns.
- */
-connection_t *
-connection_get_by_identity_digest(const char *digest)
-{
- int i, n, newer;
- connection_t *conn, *best=NULL;
- connection_t **carray;
-
- get_connection_array(&carray,&n);
- for (i=0;i<n;i++) {
- conn = carray[i];
- if (conn->marked_for_close ||
- conn->type != CONN_TYPE_OR ||
- memcmp(conn->identity_digest, digest, DIGEST_LEN))
- continue;
- if (!best) {
- best = conn; /* whatever it is, it's better than nothing. */
- continue;
- }
- if (best->state == OR_CONN_STATE_OPEN &&
- conn->state != OR_CONN_STATE_OPEN)
- continue; /* avoid non-open conns if we can */
- newer = best->timestamp_created < conn->timestamp_created;
- if (conn->is_obsolete && (!best->is_obsolete || !newer))
- continue; /* we have something, and it's better than this. */
- if (best->n_circuits && !conn->n_circuits)
- continue; /* prefer conns with circuits on them */
- if (newer)
- best = conn; /* lastly, prefer newer conns */
- }
- return best;
-}
-
/** Return the connection with id <b>id</b> if it is not already
* marked for close.
*/
Index: connection_or.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection_or.c,v
retrieving revision 1.197
retrieving revision 1.198
diff -u -d -r1.197 -r1.198
--- connection_or.c 19 Nov 2005 06:57:44 -0000 1.197
+++ connection_or.c 30 Nov 2005 03:01:16 -0000 1.198
@@ -22,6 +22,71 @@
/**************************************************************/
+/** Map from identity digest of connected OR or desired OR to a connection_t
+ * with that identity digest. If there is more than one such connection_t,
+ * they form a linked list, with next_with_same_id as the next pointer.*/
+static digestmap_t *orconn_identity_map = NULL;
+
+/** If conn is listed in orconn_identity_map, remove it, and clear
+ * conn->identity_digest. */
+void
+connection_or_remove_from_identity_map(connection_t *conn)
+{
+ connection_t *tmp;
+ tor_assert(conn);
+ tor_assert(conn->type == CONN_TYPE_OR);
+ if (!orconn_identity_map)
+ return;
+ tmp = digestmap_get(orconn_identity_map, conn->identity_digest);
+ if (!tmp)
+ return;
+ if (conn == tmp) {
+ if (conn->next_with_same_id)
+ digestmap_set(orconn_identity_map, conn->identity_digest,
+ conn->next_with_same_id);
+ else
+ digestmap_remove(orconn_identity_map, conn->identity_digest);
+ } else {
+ while (tmp->next_with_same_id) {
+ if (tmp->next_with_same_id == conn) {
+ tmp->next_with_same_id = conn->next_with_same_id;
+ break;
+ }
+ tmp = tmp->next_with_same_id;
+ }
+ }
+ memset(conn->identity_digest, 0, DIGEST_LEN);
+ conn->next_with_same_id = NULL;
+}
+
+/** Change conn->identity_digest to digest, and add conn into
+ * orconn_digest_map. */
+static void
+connection_or_set_identity_digest(connection_t *conn, const char *digest)
+{
+ connection_t *tmp;
+ tor_assert(conn);
+ tor_assert(conn->type == CONN_TYPE_OR);
+ tor_assert(digest);
+
+ if (!orconn_identity_map)
+ orconn_identity_map = digestmap_new();
+ if (!memcmp(conn->identity_digest, digest, DIGEST_LEN))
+ return;
+ if (tor_digest_is_zero(conn->identity_digest))
+ connection_or_remove_from_identity_map(conn);
+
+ memcpy(conn->identity_digest, digest, DIGEST_LEN);
+ tmp = digestmap_set(orconn_identity_map, digest, conn);
+ conn->next_with_same_id = tmp;
+
+ /* Checking code; remove once I'm sure this works. XXXX*/
+ for (; tmp; tmp = tmp->next_with_same_id) {
+ tor_assert(!memcmp(tmp->identity_digest, digest, DIGEST_LEN));
+ tor_assert(tmp != conn);
+ }
+}
+
/** Pack the cell_t host-order structure <b>src</b> into network-order
* in the buffer <b>dest</b>. See tor-spec.txt for details about the
* wire format.
@@ -227,7 +292,7 @@
conn->port = router->or_port;
conn->receiver_bucket = conn->bandwidth = (int)options->BandwidthBurst;
conn->identity_pkey = crypto_pk_dup_key(router->identity_pkey);
- crypto_pk_get_digest(conn->identity_pkey, conn->identity_digest);
+ connection_or_set_identity_digest(conn, router->cache_info.identity_digest);
conn->nickname = tor_strdup(router->nickname);
tor_free(conn->address);
conn->address = tor_strdup(router->address);
@@ -252,7 +317,7 @@
conn->port = port;
/* This next part isn't really right, but it's good enough for now. */
conn->receiver_bucket = conn->bandwidth = (int)options->BandwidthBurst;
- memcpy(conn->identity_digest, id_digest, DIGEST_LEN);
+ connection_or_set_identity_digest(conn, id_digest);
/* If we're an authoritative directory server, we may know a
* nickname for this router. */
n = dirserv_get_nickname_by_digest(id_digest);
@@ -268,6 +333,50 @@
conn->address = tor_dup_addr(addr);
}
+/** Return the best connection of type OR with the
+ * digest <b>digest</b> that we have, or NULL if we have none.
+ *
+ * 1) Don't return it if it's marked for close.
+ * 2) If there are any open conns, ignore non-open conns.
+ * 3) If there are any non-obsolete conns, ignore obsolete conns.
+ * 4) Then if there are any non-empty conns, ignore empty conns.
+ * 5) Of the remaining conns, prefer newer conns.
+ */
+connection_t *
+connection_or_get_by_identity_digest(const char *digest)
+{
+ int newer;
+ connection_t *conn, *best=NULL;
+
+ if (!orconn_identity_map)
+ return NULL;
+
+ conn = digestmap_get(orconn_identity_map, digest);
+
+ for (; conn; conn = conn->next_with_same_id) {
+ tor_assert(conn->magic == CONNECTION_MAGIC);
+ tor_assert(conn->type == CONN_TYPE_OR);
+ tor_assert(!memcmp(conn->identity_digest, digest, DIGEST_LEN));
+ if (conn->marked_for_close)
+ continue;
+ if (!best) {
+ best = conn; /* whatever it is, it's better than nothing. */
+ continue;
+ }
+ if (best->state == OR_CONN_STATE_OPEN &&
+ conn->state != OR_CONN_STATE_OPEN)
+ continue; /* avoid non-open conns if we can */
+ newer = best->timestamp_created < conn->timestamp_created;
+ if (conn->is_obsolete && (!best->is_obsolete || !newer))
+ continue; /* we have something, and it's better than this. */
+ if (best->n_circuits && !conn->n_circuits)
+ continue; /* prefer conns with circuits on them */
+ if (newer)
+ best = conn; /* lastly, prefer newer conns */
+ }
+ return best;
+}
+
/** "update an OR connection nickname on the fly"
* Actually, nobody calls this. Should we remove it? */
void
@@ -419,8 +528,6 @@
return 0;
}
-static char ZERO_DIGEST[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
-
/** Return 1 if we initiated this connection, or 0 if it started
* out as an incoming connection.
*
@@ -431,10 +538,9 @@
int
connection_or_nonopen_was_started_here(connection_t *conn)
{
- tor_assert(sizeof(ZERO_DIGEST) == DIGEST_LEN);
tor_assert(conn->type == CONN_TYPE_OR);
- if (!memcmp(ZERO_DIGEST, conn->identity_digest, DIGEST_LEN))
+ if (tor_digest_is_zero(conn->identity_digest))
return 0;
else
return 1;
@@ -560,7 +666,7 @@
if (!connection_or_nonopen_was_started_here(conn)) {
#if 0
connection_t *c;
- if ((c=connection_get_by_identity_digest(digest_rcvd))) {
+ if ((c=connection_or_get_by_identity_digest(digest_rcvd))) {
debug(LD_OR,"Router '%s' is already connected on fd %d. Dropping fd %d.",
c->nickname, c->s, conn->s);
return -1;
Index: dirserv.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/dirserv.c,v
retrieving revision 1.271
retrieving revision 1.272
diff -u -d -r1.271 -r1.272
--- dirserv.c 29 Nov 2005 17:17:02 -0000 1.271
+++ dirserv.c 30 Nov 2005 03:01:16 -0000 1.272
@@ -622,7 +622,7 @@
connection_t *conn;
if (router_is_me(router) && !we_are_hibernating())
return 1;
- conn = connection_get_by_identity_digest(router->cache_info.identity_digest);
+ conn = connection_or_get_by_identity_digest(router->cache_info.identity_digest);
if (conn && conn->state == OR_CONN_STATE_OPEN)
return get_options()->AssumeReachable ||
now < router->last_reachable + REACHABLE_TIMEOUT;
@@ -638,7 +638,7 @@
connection_t *conn;
if (router->is_hibernating)
return 0;
- conn = connection_get_by_identity_digest(router->cache_info.identity_digest);
+ conn = connection_or_get_by_identity_digest(router->cache_info.identity_digest);
if (conn && conn->state == OR_CONN_STATE_OPEN &&
now >= router->last_reachable + 2*REACHABLE_TIMEOUT &&
router->testing_since &&
Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.743
retrieving revision 1.744
diff -u -d -r1.743 -r1.744
--- or.h 26 Nov 2005 09:27:36 -0000 1.743
+++ or.h 30 Nov 2005 03:01:16 -0000 1.744
@@ -665,6 +665,8 @@
* we use? */
int n_circuits; /**< How many circuits use this connection as p_conn or
* n_conn ? */
+ struct connection_t *next_with_same_id; /**< Next connection with same
+ * identity digest as this one. */
/* Used only by DIR and AP connections: */
char rend_query[REND_SERVICE_ID_LEN+1]; /**< What rendezvous service are we
@@ -1570,7 +1572,6 @@
void connection_write_to_buf(const char *string, size_t len, connection_t *conn);
connection_t *connection_or_exact_get_by_addr_port(uint32_t addr, uint16_t port);
-connection_t *connection_get_by_identity_digest(const char *digest);
connection_t *connection_get_by_global_id(uint32_t id);
connection_t *connection_get_by_type(int type);
@@ -1660,6 +1661,9 @@
/********************************* connection_or.c ***************************/
+void connection_or_remove_from_identity_map(connection_t *conn);
+connection_t *connection_or_get_by_identity_digest(const char *digest);
+
int connection_or_reached_eof(connection_t *conn);
int connection_or_process_inbuf(connection_t *conn);
int connection_or_finished_flushing(connection_t *conn);
Index: relay.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/relay.c,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -d -r1.89 -r1.90
--- relay.c 17 Nov 2005 03:40:20 -0000 1.89
+++ relay.c 30 Nov 2005 03:01:16 -0000 1.90
@@ -325,6 +325,7 @@
if (!conn) {
/* XXXX RD This is a bug, right? */
warn(LD_BUG,"incoming relay cell has p_conn==NULL. Dropping.");
+ assert_circuit_ok(circ);
return 0; /* just drop it */
}
relay_set_digest(circ->p_digest, cell);
Index: router.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/router.c,v
retrieving revision 1.231
retrieving revision 1.232
diff -u -d -r1.231 -r1.232
--- router.c 19 Nov 2005 06:57:44 -0000 1.231
+++ router.c 30 Nov 2005 03:01:16 -0000 1.232
@@ -623,7 +623,7 @@
if (!clique_mode(options) && !router_is_clique_mode(router))
continue;
if (force ||
- !connection_get_by_identity_digest(router->cache_info.identity_digest)) {
+ !connection_or_get_by_identity_digest(router->cache_info.identity_digest)) {
debug(LD_OR,"%sconnecting to %s at %s:%u.",
clique_mode(options) ? "(forced) " : "",
router->nickname, router->address, router->or_port);
Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerlist.c,v
retrieving revision 1.382
retrieving revision 1.383
diff -u -d -r1.382 -r1.383
--- routerlist.c 28 Nov 2005 16:29:27 -0000 1.382
+++ routerlist.c 30 Nov 2005 03:01:16 -0000 1.383
@@ -1538,7 +1538,7 @@
* make new ones with the new key.
*/
connection_t *conn;
- while ((conn = connection_get_by_identity_digest(
+ while ((conn = connection_or_get_by_identity_digest(
old_router->cache_info.identity_digest))) {
// And LD_OR? XXXXNM
info(LD_DIR,"Closing conn to router '%s'; there is now a named router with that name.",