Преглед изворни кода

Merge remote-tracking branch 'origin/maint-0.2.5'

Nick Mathewson пре 10 година
родитељ
комит
7591ce64fb

+ 5 - 0
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.

+ 11 - 0
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".

+ 2 - 0
changes/further-12184-diagnostic

@@ -0,0 +1,2 @@
+  o Minor features (diagnostic):
+    - Slightly enhance the diagnostic message for bug 12184.

+ 1 - 1
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"

+ 2 - 0
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;
     }
 

+ 31 - 5
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())) {

+ 1 - 0
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);

+ 30 - 30
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)

+ 0 - 0
src/or/control.c


+ 4 - 1
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)

+ 0 - 0
src/or/router.c