Browse Source

Merge remote-tracking branch 'public/bug2003_nm'

Nick Mathewson 12 years ago
parent
commit
1ec22eac4b
4 changed files with 54 additions and 20 deletions
  1. 8 0
      changes/bug2003
  2. 19 19
      src/or/hibernate.c
  3. 22 0
      src/or/hibernate.h
  4. 5 1
      src/test/test_dir.c

+ 8 - 0
changes/bug2003

@@ -0,0 +1,8 @@
+  o Major bugfixes:
+    - Don't update the AccountingSoftLimitHitAt state file entry whenever
+      tor gets started. This prevents a wrong average bandwidth estimate,
+      which would cause relays to always start a new accounting interval at
+      the earliest possible moment. Fixes bug 2003; bugfix on 0.2.2.7-alpha.
+      Reported by BryonEldridge, who also helped immensely in tracking this
+      bug down. Thanks!
+

+ 19 - 19
src/or/hibernate.c

@@ -21,6 +21,7 @@ hibernating, phase 2:
   - close all OR/AP/exit conns)
 */
 
+#define HIBERNATE_PRIVATE
 #include "or.h"
 #include "config.h"
 #include "connection.h"
@@ -29,26 +30,11 @@ hibernating, phase 2:
 #include "main.h"
 #include "router.h"
 
-/** Possible values of hibernate_state */
-typedef enum {
-  /** We are running normally. */
-  HIBERNATE_STATE_LIVE=1,
-  /** We're trying to shut down cleanly, and we'll kill all active connections
-   * at shutdown_time. */
-  HIBERNATE_STATE_EXITING=2,
-  /** We're running low on allocated bandwidth for this period, so we won't
-   * accept any new connections. */
-  HIBERNATE_STATE_LOWBANDWIDTH=3,
-  /** We are hibernating, and we won't wake up till there's more bandwidth to
-   * use. */
-  HIBERNATE_STATE_DORMANT=4
-} hibernate_state_t;
-
 extern long stats_n_seconds_working; /* published uptime */
 
 /** Are we currently awake, asleep, running out of bandwidth, or shutting
  * down? */
-static hibernate_state_t hibernate_state = HIBERNATE_STATE_LIVE;
+static hibernate_state_t hibernate_state = HIBERNATE_STATE_INITIAL;
 /** If are hibernating, when do we plan to wake up? Set to 0 if we
  * aren't hibernating. */
 static time_t hibernate_end_time = 0;
@@ -804,10 +790,12 @@ static void
 hibernate_end(hibernate_state_t new_state)
 {
   tor_assert(hibernate_state == HIBERNATE_STATE_LOWBANDWIDTH ||
-             hibernate_state == HIBERNATE_STATE_DORMANT);
+             hibernate_state == HIBERNATE_STATE_DORMANT ||
+             hibernate_state == HIBERNATE_STATE_INITIAL);
 
   /* listeners will be relaunched in run_scheduled_events() in main.c */
-  log_notice(LD_ACCT,"Hibernation period ended. Resuming normal activity.");
+  if (hibernate_state != HIBERNATE_STATE_INITIAL)
+    log_notice(LD_ACCT,"Hibernation period ended. Resuming normal activity.");
 
   hibernate_state = new_state;
   hibernate_end_time = 0; /* no longer hibernating */
@@ -939,7 +927,8 @@ consider_hibernation(time_t now)
 
   /* Else, we aren't hibernating. See if it's time to start hibernating, or to
    * go dormant. */
-  if (hibernate_state == HIBERNATE_STATE_LIVE) {
+  if (hibernate_state == HIBERNATE_STATE_LIVE ||
+      hibernate_state == HIBERNATE_STATE_INITIAL) {
     if (hibernate_soft_limit_reached()) {
       log_notice(LD_ACCT,
                  "Bandwidth soft limit reached; commencing hibernation. "
@@ -951,6 +940,8 @@ consider_hibernation(time_t now)
                  "Commencing hibernation. We will wake up at %s local time.",
                  buf);
       hibernate_go_dormant(now);
+    } else if (hibernate_state == HIBERNATE_STATE_INITIAL) {
+      hibernate_end(HIBERNATE_STATE_LIVE);
     }
   }
 
@@ -1017,3 +1008,12 @@ getinfo_helper_accounting(control_connection_t *conn,
   return 0;
 }
 
+/**
+ * Manually change the hibernation state.  Private; used only by the unit
+ * tests.
+ */
+void
+hibernate_set_state_for_testing_(hibernate_state_t newstate)
+{
+  hibernate_state = newstate;
+}

+ 22 - 0
src/or/hibernate.h

@@ -25,5 +25,27 @@ int getinfo_helper_accounting(control_connection_t *conn,
                               const char *question, char **answer,
                               const char **errmsg);
 
+#ifdef HIBERNATE_PRIVATE
+/** Possible values of hibernate_state */
+typedef enum {
+  /** We are running normally. */
+  HIBERNATE_STATE_LIVE=1,
+  /** We're trying to shut down cleanly, and we'll kill all active connections
+   * at shutdown_time. */
+  HIBERNATE_STATE_EXITING=2,
+  /** We're running low on allocated bandwidth for this period, so we won't
+   * accept any new connections. */
+  HIBERNATE_STATE_LOWBANDWIDTH=3,
+  /** We are hibernating, and we won't wake up till there's more bandwidth to
+   * use. */
+  HIBERNATE_STATE_DORMANT=4,
+  /** We start out in state default, which means we havent decided which state
+   * we're in. */
+  HIBERNATE_STATE_INITIAL=5
+} hibernate_state_t;
+
+void hibernate_set_state_for_testing_(hibernate_state_t newstate);
+#endif
+
 #endif
 

+ 5 - 1
src/test/test_dir.c

@@ -7,10 +7,12 @@
 #define DIRSERV_PRIVATE
 #define DIRVOTE_PRIVATE
 #define ROUTER_PRIVATE
+#define HIBERNATE_PRIVATE
 #include "or.h"
 #include "directory.h"
 #include "dirserv.h"
 #include "dirvote.h"
+#include "hibernate.h"
 #include "networkstatus.h"
 #include "router.h"
 #include "routerlist.h"
@@ -85,6 +87,8 @@ test_dir_formats(void)
 
   test_assert(pk1 && pk2 && pk3);
 
+  hibernate_set_state_for_testing_(HIBERNATE_STATE_LIVE);
+
   get_platform_str(platform, sizeof(platform));
   r1 = tor_malloc_zero(sizeof(routerinfo_t));
   r1->address = tor_strdup("18.244.0.1");
@@ -1303,7 +1307,7 @@ test_dir_v3_networkstatus(void)
 }
 
 #define DIR_LEGACY(name)                                                   \
-  { #name, legacy_test_helper, 0, &legacy_setup, test_dir_ ## name }
+  { #name, legacy_test_helper, TT_FORK, &legacy_setup, test_dir_ ## name }
 
 #define DIR(name)                               \
   { #name, test_dir_##name, 0, NULL, NULL }