aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changes/bufferevent_compilation5
-rw-r--r--changes/bug838711
-rw-r--r--changes/further-12184-diagnostic2
-rw-r--r--configure.ac2
-rw-r--r--src/or/circuitbuild.c2
-rw-r--r--src/or/circuituse.c36
-rw-r--r--src/or/circuituse.h1
-rw-r--r--src/or/connection.c60
-rw-r--r--[-rwxr-xr-x]src/or/control.c0
-rw-r--r--src/or/main.c5
-rw-r--r--[-rwxr-xr-x]src/or/router.c0
11 files changed, 87 insertions, 37 deletions
diff --git a/changes/bufferevent_compilation b/changes/bufferevent_compilation
new file mode 100644
index 0000000000..0690e65297
--- /dev/null
+++ b/changes/bufferevent_compilation
@@ -0,0 +1,5 @@
+ o Minor bugfixes:
+ - Fix compilation when building with bufferevents enabled. (This
+ configuration is still not expected to work, however.)
+ Fixes bugs 12438, 12474; bugfixes on 0.2.5.1-alpha. Patches
+ from Anthony G. Basile.
diff --git a/changes/bug8387 b/changes/bug8387
new file mode 100644
index 0000000000..2ec0487bf8
--- /dev/null
+++ b/changes/bug8387
@@ -0,0 +1,11 @@
+ o Major bugfixes (client):
+
+ - Perform circuit cleanup operations even when circuit
+ construction operations are disabled (because the network is
+ disabled, or because there isn't enough directory information).
+ Previously, when we were not building predictive circuits, we
+ were not closing expired circuits either.
+
+ Fixes bug 8387; bugfix on 0.1.1.11-alpha. This bug became visible
+ in 0.2.4.10-alpha when we became more strict about when we have
+ "enough directory information to build circuits".
diff --git a/changes/further-12184-diagnostic b/changes/further-12184-diagnostic
new file mode 100644
index 0000000000..89e9f4612f
--- /dev/null
+++ b/changes/further-12184-diagnostic
@@ -0,0 +1,2 @@
+ o Minor features (diagnostic):
+ - Slightly enhance the diagnostic message for bug 12184.
diff --git a/configure.ac b/configure.ac
index e858d0c0c1..414c72a42c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -432,7 +432,7 @@ AC_CHECK_MEMBERS([struct event.min_heap_idx], , ,
[#include <event.h>
])
-AC_CHECK_HEADERS(event2/event.h event2/dns.h)
+AC_CHECK_HEADERS(event2/event.h event2/dns.h event2/bufferevent_ssl.h)
LIBS="$save_LIBS"
LDFLAGS="$save_LDFLAGS"
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index e743a25f48..283afee31f 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -183,6 +183,8 @@ get_unique_circ_id_by_chan(channel_t *chan)
if (0)
circuitmux_assert_okay(chan->cmux);
+ channel_dump_statistics(chan, LOG_WARN);
+
return 0;
}
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 221afea912..714754a672 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -783,6 +783,10 @@ circuit_expire_building(void)
}
}
+/** For debugging #8387: track when we last called
+ * circuit_expire_old_circuits_clientside. */
+static time_t last_expired_clientside_circuits = 0;
+
/**
* As a diagnostic for bug 8387, log information about how many one-hop
* circuits we have around that have been there for at least <b>age</b>
@@ -894,6 +898,10 @@ circuit_log_ancient_one_hop_circuits(int age)
}
} SMARTLIST_FOREACH_END(ocirc);
+ log_notice(LD_HEARTBEAT, "It has been %ld seconds since I last called "
+ "circuit_expire_old_circuits_clientside().",
+ (long)(now - last_expired_clientside_circuits));
+
done:
smartlist_free(log_these);
}
@@ -1089,7 +1097,6 @@ circuit_predict_and_launch_new(void)
void
circuit_build_needed_circs(time_t now)
{
- static time_t time_to_new_circuit = 0;
const or_options_t *options = get_options();
/* launch a new circ for any pending streams that need one */
@@ -1098,14 +1105,34 @@ circuit_build_needed_circs(time_t now)
/* make sure any hidden services have enough intro points */
rend_services_introduce();
- if (time_to_new_circuit < now) {
+ circuit_expire_old_circs_as_needed(now);
+
+ if (!options->DisablePredictedCircuits)
+ circuit_predict_and_launch_new();
+}
+
+/**
+ * Called once a second either directly or from
+ * circuit_build_needed_circs(). As appropriate (once per NewCircuitPeriod)
+ * resets failure counts and expires old circuits.
+ */
+void
+circuit_expire_old_circs_as_needed(time_t now)
+{
+ static time_t time_to_expire_and_reset = 0;
+
+ if (time_to_expire_and_reset < now) {
circuit_reset_failure_count(1);
- time_to_new_circuit = now + options->NewCircuitPeriod;
+ time_to_expire_and_reset = now + get_options()->NewCircuitPeriod;
if (proxy_mode(get_options()))
addressmap_clean(now);
circuit_expire_old_circuits_clientside();
#if 0 /* disable for now, until predict-and-launch-new can cull leftovers */
+
+ /* If we ever re-enable, this has to move into
+ * circuit_build_needed_circs */
+
circ = circuit_get_youngest_clean_open(CIRCUIT_PURPOSE_C_GENERAL);
if (get_options()->RunTesting &&
circ &&
@@ -1115,8 +1142,6 @@ circuit_build_needed_circs(time_t now)
}
#endif
}
- if (!options->DisablePredictedCircuits)
- circuit_predict_and_launch_new();
}
/** If the stream <b>conn</b> is a member of any of the linked
@@ -1203,6 +1228,7 @@ circuit_expire_old_circuits_clientside(void)
tor_gettimeofday(&now);
cutoff = now;
+ last_expired_clientside_circuits = now.tv_sec;
if (! circuit_build_times_disabled() &&
circuit_build_times_needs_circuits(get_circuit_build_times())) {
diff --git a/src/or/circuituse.h b/src/or/circuituse.h
index f228a67585..4c5977bee0 100644
--- a/src/or/circuituse.h
+++ b/src/or/circuituse.h
@@ -22,6 +22,7 @@ int circuit_conforms_to_options(const origin_circuit_t *circ,
const or_options_t *options);
#endif
void circuit_build_needed_circs(time_t now);
+void circuit_expire_old_circs_as_needed(time_t now);
void circuit_detach_stream(circuit_t *circ, edge_connection_t *conn);
void circuit_expire_old_circuits_serverside(time_t now);
diff --git a/src/or/connection.c b/src/or/connection.c
index 0b03092f7f..4788bdf950 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -2650,14 +2650,6 @@ record_num_bytes_transferred(connection_t *conn,
}
#endif
-#ifndef USE_BUFFEREVENTS
-/** Last time at which the global or relay buckets were emptied in msec
- * since midnight. */
-static uint32_t global_relayed_read_emptied = 0,
- global_relayed_write_emptied = 0,
- global_read_emptied = 0,
- global_write_emptied = 0;
-
/** Helper: convert given <b>tvnow</b> time value to milliseconds since
* midnight. */
static uint32_t
@@ -2667,6 +2659,28 @@ msec_since_midnight(const struct timeval *tvnow)
((uint32_t)tvnow->tv_usec / (uint32_t)1000L));
}
+/** Helper: return the time in milliseconds since <b>last_empty_time</b>
+ * when a bucket ran empty that previously had <b>tokens_before</b> tokens
+ * now has <b>tokens_after</b> tokens after refilling at timestamp
+ * <b>tvnow</b>, capped at <b>milliseconds_elapsed</b> milliseconds since
+ * last refilling that bucket. Return 0 if the bucket has not been empty
+ * since the last refill or has not been refilled. */
+uint32_t
+bucket_millis_empty(int tokens_before, uint32_t last_empty_time,
+ int tokens_after, int milliseconds_elapsed,
+ const struct timeval *tvnow)
+{
+ uint32_t result = 0, refilled;
+ if (tokens_before <= 0 && tokens_after > tokens_before) {
+ refilled = msec_since_midnight(tvnow);
+ result = (uint32_t)((refilled + 86400L * 1000L - last_empty_time) %
+ (86400L * 1000L));
+ if (result > (uint32_t)milliseconds_elapsed)
+ result = (uint32_t)milliseconds_elapsed;
+ }
+ return result;
+}
+
/** Check if a bucket which had <b>tokens_before</b> tokens and which got
* <b>tokens_removed</b> tokens removed at timestamp <b>tvnow</b> has run
* out of tokens, and if so, note the milliseconds since midnight in
@@ -2680,6 +2694,14 @@ connection_buckets_note_empty_ts(uint32_t *timestamp_var,
*timestamp_var = msec_since_midnight(tvnow);
}
+#ifndef USE_BUFFEREVENTS
+/** Last time at which the global or relay buckets were emptied in msec
+ * since midnight. */
+static uint32_t global_relayed_read_emptied = 0,
+ global_relayed_write_emptied = 0,
+ global_read_emptied = 0,
+ global_write_emptied = 0;
+
/** We just read <b>num_read</b> and wrote <b>num_written</b> bytes
* onto <b>conn</b>. Decrement buckets appropriately. */
static void
@@ -2838,28 +2860,6 @@ connection_bucket_refill_helper(int *bucket, int rate, int burst,
}
}
-/** Helper: return the time in milliseconds since <b>last_empty_time</b>
- * when a bucket ran empty that previously had <b>tokens_before</b> tokens
- * now has <b>tokens_after</b> tokens after refilling at timestamp
- * <b>tvnow</b>, capped at <b>milliseconds_elapsed</b> milliseconds since
- * last refilling that bucket. Return 0 if the bucket has not been empty
- * since the last refill or has not been refilled. */
-uint32_t
-bucket_millis_empty(int tokens_before, uint32_t last_empty_time,
- int tokens_after, int milliseconds_elapsed,
- const struct timeval *tvnow)
-{
- uint32_t result = 0, refilled;
- if (tokens_before <= 0 && tokens_after > tokens_before) {
- refilled = msec_since_midnight(tvnow);
- result = (uint32_t)((refilled + 86400L * 1000L - last_empty_time) %
- (86400L * 1000L));
- if (result > (uint32_t)milliseconds_elapsed)
- result = (uint32_t)milliseconds_elapsed;
- }
- return result;
-}
-
/** Time has passed; increment buckets appropriately. */
void
connection_bucket_refill(int milliseconds_elapsed, time_t now)
diff --git a/src/or/control.c b/src/or/control.c
index 21504e685e..21504e685e 100755..100644
--- a/src/or/control.c
+++ b/src/or/control.c
diff --git a/src/or/main.c b/src/or/main.c
index 8ba4fef1fd..b4b2faef15 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1512,8 +1512,11 @@ run_scheduled_events(time_t now)
* and we make a new circ if there are no clean circuits.
*/
have_dir_info = router_have_minimum_dir_info();
- if (have_dir_info && !net_is_disabled())
+ if (have_dir_info && !net_is_disabled()) {
circuit_build_needed_circs(now);
+ } else {
+ circuit_expire_old_circs_as_needed(now);
+ }
/* every 10 seconds, but not at the same second as other such events */
if (now % 10 == 5)
diff --git a/src/or/router.c b/src/or/router.c
index 4fcd4a5b89..4fcd4a5b89 100755..100644
--- a/src/or/router.c
+++ b/src/or/router.c