aboutsummaryrefslogtreecommitdiff
path: root/src/or/rephist.c
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2004-12-05 07:10:08 +0000
committerRoger Dingledine <arma@torproject.org>2004-12-05 07:10:08 +0000
commitef6c9d18e799e5b02505ba73bbf36bfe92ce5a8b (patch)
tree24e864902bc7196fb3e2ca1a39fc7463c2582d1c /src/or/rephist.c
parent32e74d352500dc228a1de5d5bc97e219897ef09b (diff)
downloadtor-ef6c9d18e799e5b02505ba73bbf36bfe92ce5a8b.tar
tor-ef6c9d18e799e5b02505ba73bbf36bfe92ce5a8b.tar.gz
New circuit building strategy: keep a list of ports that we've used in the past 6 hours, and always try to have 2 circuits open or on the way
that will handle each such port. (We can extend this to include addresses if exit policies shift to require that.) Seed us with port 80 so web browsers won't complain that Tor is "slow to start up". This was necessary because our old circuit building strategy just involved counting circuits, and as time went by we would build up a big pile of circuits that had peculiar exit policies (e.g. only exit to 9001-9100) which would take up space in the circuit pile but never get used. Fix router_compare_addr_to_addr_policy: it was not treating a port of * as always matching, so we were picking reject *:* nodes as exit nodes too. If you haven't used a clean circuit in an hour, throw it away, just to be on the safe side. This means after 6 hours a totally unused Tor client will have no circuits open. svn:r3078
Diffstat (limited to 'src/or/rephist.c')
-rw-r--r--src/or/rephist.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 2f1c976f0..3095ad46a 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -11,6 +11,7 @@ const char rephist_c_id[] = "$Id$";
#include "or.h"
static void bw_arrays_init(void);
+static void predicted_ports_init(void);
/** History of an OR-\>OR link. */
typedef struct link_history_t {
@@ -133,6 +134,7 @@ void rep_hist_init(void)
{
history_map = strmap_new();
bw_arrays_init();
+ predicted_ports_init();
}
/** Remember that an attempt to connect to the OR with identity digest
@@ -617,3 +619,78 @@ rep_hist_get_bandwidth_lines(void)
return buf;
}
+/** A list of port numbers that have been used recently. */
+static smartlist_t *predicted_ports_list=NULL;
+/** The corresponding most recently used time for each port. */
+static smartlist_t *predicted_ports_times=NULL;
+
+static void add_predicted_port(uint16_t port, time_t now) {
+ uint16_t *tmp_port = tor_malloc(sizeof(uint16_t));
+ time_t *tmp_time = tor_malloc(sizeof(time_t));
+ *tmp_port = port;
+ *tmp_time = now;
+ smartlist_add(predicted_ports_list, tmp_port);
+ smartlist_add(predicted_ports_times, tmp_time);
+}
+
+static void predicted_ports_init(void) {
+ predicted_ports_list = smartlist_create();
+ predicted_ports_times = smartlist_create();
+ add_predicted_port(80, time(NULL)); /* add one to kickstart us */
+}
+
+/** Remember that <b>port</b> has been asked for as of time <b>now</b>.
+ * This is used for predicting what sorts of streams we'll make in the
+ * future and making circuits to anticipate that.
+ */
+void rep_hist_note_used_port(uint16_t port, time_t now) {
+ int i;
+ uint16_t *tmp_port;
+ time_t *tmp_time;
+
+ tor_assert(predicted_ports_list);
+ tor_assert(predicted_ports_times);
+
+ if(!port) /* record nothing */
+ return;
+
+ for (i = 0; i < smartlist_len(predicted_ports_list); ++i) {
+ tmp_port = smartlist_get(predicted_ports_list, i);
+ tmp_time = smartlist_get(predicted_ports_times, i);
+ if (*tmp_port == port) {
+ *tmp_time = now;
+ return;
+ }
+ }
+ /* it's not there yet; we need to add it */
+ add_predicted_port(port, now);
+}
+
+#define PREFERRED_PORTS_RELEVANCE_TIME (6*3600) /* 6 hours */
+
+/** Allocate and return a string of space-separated port numbers that
+ * are likely to be asked for in the near future.
+ */
+char *rep_hist_get_predicted_ports(time_t now) {
+ int i;
+ uint16_t *tmp_port;
+ time_t *tmp_time;
+
+ tor_assert(predicted_ports_list);
+ tor_assert(predicted_ports_times);
+
+ /* clean out obsolete entries */
+ for (i = 0; i < smartlist_len(predicted_ports_list); ++i) {
+ tmp_time = smartlist_get(predicted_ports_times, i);
+ if (*tmp_time + PREFERRED_PORTS_RELEVANCE_TIME < now) {
+ tmp_port = smartlist_get(predicted_ports_list, i);
+ smartlist_del(predicted_ports_list, i);
+ smartlist_del(predicted_ports_times, i);
+ tor_free(tmp_port);
+ tor_free(tmp_time);
+ i--;
+ }
+ }
+ return smartlist_join_strings(predicted_ports_list, " ", 0, NULL);
+}
+