diff options
-rw-r--r-- | changes/bufferevent_compilation | 5 | ||||
-rw-r--r-- | changes/bug8387 | 11 | ||||
-rw-r--r-- | changes/further-12184-diagnostic | 2 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/or/circuitbuild.c | 2 | ||||
-rw-r--r-- | src/or/circuituse.c | 36 | ||||
-rw-r--r-- | src/or/circuituse.h | 1 | ||||
-rw-r--r-- | src/or/connection.c | 60 | ||||
-rw-r--r--[-rwxr-xr-x] | src/or/control.c | 0 | ||||
-rw-r--r-- | src/or/main.c | 5 | ||||
-rw-r--r--[-rwxr-xr-x] | src/or/router.c | 0 |
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 |