summaryrefslogtreecommitdiff
path: root/src/or/connection.c
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2005-11-19 06:57:44 +0000
committerRoger Dingledine <arma@torproject.org>2005-11-19 06:57:44 +0000
commit7aae63994f7d8b42ff7b9b4809eb2f1213372148 (patch)
treec8794fc5446a4012ff83ee805d3e5627e61cc374 /src/or/connection.c
parent700c370a3b9f30495983301883d678ef90bb1621 (diff)
downloadtor-7aae63994f7d8b42ff7b9b4809eb2f1213372148.tar.gz
tor-7aae63994f7d8b42ff7b9b4809eb2f1213372148.zip
Recover better from TCP connections to Tor servers that are broken but
don't tell you (it happens!); and rotate TLS connections once a week. 1) If an OR conn becomes more than a week old, make it obsolete. 2) If it's obsolete and empty, kill it. 3) When an OR makes a second connection to you, allow it. 4) If we want to send a new create cell, but the best conn we've got is obsolete, and the router is 0.1.1.9-alpha-cvs or later, ask for a new conn instead. 5) When we time out on circuit building on the first hop, make that connection obsolete. svn:r5429
Diffstat (limited to 'src/or/connection.c')
-rw-r--r--src/or/connection.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/src/or/connection.c b/src/or/connection.c
index b38f0daff7..88cbd9a676 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -1547,8 +1547,8 @@ connection_or_exact_get_by_addr_port(uint32_t addr, uint16_t port)
return best;
}
-/** Return a connection with give type, address, port, and purpose or NULL if
- * no such connection exists. */
+/** Return a connection with given type, address, port, and purpose;
+ * or NULL if no such connection exists. */
connection_t *
connection_get_by_type_addr_port_purpose(int type, uint32_t addr, uint16_t port,
int purpose)
@@ -1570,22 +1570,42 @@ connection_get_by_type_addr_port_purpose(int type, uint32_t addr, uint16_t port,
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 type)
+connection_get_by_identity_digest(const char *digest)
{
- int i, n;
+ 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->type != type)
+ if (conn->marked_for_close ||
+ memcmp(conn->identity_digest, digest, DIGEST_LEN))
continue;
- if (!memcmp(conn->identity_digest, digest, DIGEST_LEN) &&
- !conn->marked_for_close &&
- (!best || best->timestamp_created < conn->timestamp_created))
- best = conn;
+ 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 (circuit_get_by_conn(best) && !circuit_get_by_conn(conn))
+ continue; /* prefer conns with circuits on them */
+ if (newer)
+ best = conn; /* lastly, prefer newer conns */
}
return best;
}