Forráskód Böngészése

Merge remote branch 'origin/maint-0.2.2'

Resolved trivial one-line conflicts.

Conflicts:
	src/or/dirserv.c
	src/or/rephist.c
Nick Mathewson 13 éve
szülő
commit
f9bb3ced51
6 módosított fájl, 90 hozzáadás és 24 törlés
  1. 13 0
      changes/bug1035
  2. 6 7
      doc/HACKING
  3. 0 3
      src/or/connection_or.c
  4. 13 6
      src/or/dirserv.c
  5. 56 7
      src/or/rephist.c
  6. 2 1
      src/or/rephist.h

+ 13 - 0
changes/bug1035

@@ -0,0 +1,13 @@
+  o Minor features (authorities)
+    - Take altered router IP addresses and ORPorts into account when
+      determining router stability.  Previously, if a router changed
+      its IP or ORPort, the authorities would not treat it as having
+      any downtime for the purposes of stability calculation, whereas
+      clients would experience downtime since the change could take a
+      while to propagate to them.  Resolves issue 1035.
+  o Minor bugfixes (authorities)
+    - Try to be more robust to hops back in time when calculating
+      router stability.  Previously, if a run of uptime or downtime
+      appeared to be negative, the calculation could give incorrect
+      results.  Bugfix on 0.2.0.6-alpha.
+

+ 6 - 7
doc/HACKING

@@ -5,17 +5,17 @@ Getting started
 ---------------
 ---------------
 
 
 For full information on how Tor is supposed to work, look at the files in
 For full information on how Tor is supposed to work, look at the files in
-doc/spec/ .
+https://gitweb.torproject.org/torspec.git/tree
 
 
 For an explanation of how to change Tor's design to work differently, look at
 For an explanation of how to change Tor's design to work differently, look at
-doc/spec/proposals/001-process.txt .
+https://gitweb.torproject.org/torspec.git/blob_plain/HEAD:/proposals/001-process.txt
 
 
 For the latest version of the code, get a copy of git, and
 For the latest version of the code, get a copy of git, and
 
 
    git clone git://git.torproject.org/git/tor .
    git clone git://git.torproject.org/git/tor .
 
 
-We talk about Tor on the or-talk mailing list.  Design proposals and
-discussion belong on the or-dev mailing list.  We hang around on
+We talk about Tor on the tor-talk mailing list.  Design proposals and
+discussion belong on the tor-dev mailing list.  We hang around on
 irc.oftc.net, with general discussion happening on #tor and development
 irc.oftc.net, with general discussion happening on #tor and development
 happening on #tor-dev.
 happening on #tor-dev.
 
 
@@ -65,8 +65,8 @@ If at all possible, try to create this file in the same commit where
 you are making the change.  Please give it a distinctive name that no
 you are making the change.  Please give it a distinctive name that no
 other branch will use for the lifetime of your change.
 other branch will use for the lifetime of your change.
 
 
-When Roger goes to make a release, he will concatenate all the entries
-in changes to make a draft changelog, and clear the directory.  He'll
+When we go to make a release, we will concatenate all the entries
+in changes to make a draft changelog, and clear the directory. We'll
 then edit the draft changelog into a nice readable format.
 then edit the draft changelog into a nice readable format.
 
 
 What needs a changes file?::
 What needs a changes file?::
@@ -405,4 +405,3 @@ function should mention that it does that something in the documentation.  If
 you rely on a function doing something beyond what is in its documentation,
 you rely on a function doing something beyond what is in its documentation,
 then you should watch out, or it might do something else later.
 then you should watch out, or it might do something else later.
 
 
-

+ 0 - 3
src/or/connection_or.c

@@ -1237,9 +1237,6 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
       as_advertised = 0;
       as_advertised = 0;
     }
     }
     if (authdir_mode_tests_reachability(options)) {
     if (authdir_mode_tests_reachability(options)) {
-      /* We initiated this connection to address:port.  Drop all routers
-       * with the same address:port and a different key.
-       */
       dirserv_orconn_tls_done(conn->_base.address, conn->_base.port,
       dirserv_orconn_tls_done(conn->_base.address, conn->_base.port,
                               digest_rcvd_out, as_advertised);
                               digest_rcvd_out, as_advertised);
     }
     }

+ 13 - 6
src/or/dirserv.c

@@ -3143,20 +3143,27 @@ dirserv_orconn_tls_done(const char *address,
   tor_assert(address);
   tor_assert(address);
   tor_assert(digest_rcvd);
   tor_assert(digest_rcvd);
 
 
-  SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
+  /* XXX023 Doing a loop like this is stupid.  We should just look up the
+   * router by digest_rcvd, and see if address, orport, and as_advertised
+   * match up. -NM */
+  SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, ri) {
     if (!strcasecmp(address, ri->address) && or_port == ri->or_port &&
     if (!strcasecmp(address, ri->address) && or_port == ri->or_port &&
         as_advertised &&
         as_advertised &&
         !memcmp(ri->cache_info.identity_digest, digest_rcvd, DIGEST_LEN)) {
         !memcmp(ri->cache_info.identity_digest, digest_rcvd, DIGEST_LEN)) {
       /* correct digest. mark this router reachable! */
       /* correct digest. mark this router reachable! */
       if (!bridge_auth || ri->purpose == ROUTER_PURPOSE_BRIDGE) {
       if (!bridge_auth || ri->purpose == ROUTER_PURPOSE_BRIDGE) {
-        log_info(LD_DIRSERV, "Found router %s to be reachable. Yay.",
-                 ri->nickname);
-        rep_hist_note_router_reachable(digest_rcvd, now);
+        tor_addr_t addr, *addrp=NULL;
+        log_info(LD_DIRSERV, "Found router %s to be reachable at %s:%d. Yay.",
+                 ri->nickname, address, ri->or_port );
+        if (tor_addr_from_str(&addr, ri->address) != -1)
+          addrp = &addr;
+        else
+          log_warn(LD_BUG, "Couldn't parse IP address \"%s\"", ri->address);
+        rep_hist_note_router_reachable(digest_rcvd, addrp, or_port, now);
         ri->last_reachable = now;
         ri->last_reachable = now;
       }
       }
     }
     }
-  });
-
+  } SMARTLIST_FOREACH_END(ri);
   /* FFFF Maybe we should reinstate the code that dumps routers with the same
   /* FFFF Maybe we should reinstate the code that dumps routers with the same
    * addr/port but with nonmatching keys, but instead of dumping, we should
    * addr/port but with nonmatching keys, but instead of dumping, we should
    * skip testing. */
    * skip testing. */

+ 56 - 7
src/or/rephist.c

@@ -14,6 +14,7 @@
 #include "circuitlist.h"
 #include "circuitlist.h"
 #include "circuituse.h"
 #include "circuituse.h"
 #include "config.h"
 #include "config.h"
+#include "networkstatus.h"
 #include "nodelist.h"
 #include "nodelist.h"
 #include "rephist.h"
 #include "rephist.h"
 #include "router.h"
 #include "router.h"
@@ -74,6 +75,13 @@ typedef struct or_history_t {
   /** If nonzero, we have been unable to connect since this time. */
   /** If nonzero, we have been unable to connect since this time. */
   time_t down_since;
   time_t down_since;
 
 
+  /** The address at which we most recently connected to this OR
+   * successfully. */
+  tor_addr_t last_reached_addr;
+
+  /** The port at which we most recently connected to this OR successfully */
+  uint16_t last_reached_port;
+
   /* === For MTBF tracking: */
   /* === For MTBF tracking: */
   /** Weighted sum total of all times that this router has been online.
   /** Weighted sum total of all times that this router has been online.
    */
    */
@@ -120,6 +128,7 @@ get_or_history(const char* id)
     rephist_total_num++;
     rephist_total_num++;
     hist->link_history_map = digestmap_new();
     hist->link_history_map = digestmap_new();
     hist->since = hist->changed = time(NULL);
     hist->since = hist->changed = time(NULL);
+    tor_addr_make_unspec(&hist->last_reached_addr);
     digestmap_set(history_map, id, hist);
     digestmap_set(history_map, id, hist);
   }
   }
   return hist;
   return hist;
@@ -290,13 +299,20 @@ rep_hist_note_connection_died(const char* id, time_t when)
 /** We have just decided that this router with identity digest <b>id</b> is
 /** We have just decided that this router with identity digest <b>id</b> is
  * reachable, meaning we will give it a "Running" flag for the next while. */
  * reachable, meaning we will give it a "Running" flag for the next while. */
 void
 void
-rep_hist_note_router_reachable(const char *id, time_t when)
+rep_hist_note_router_reachable(const char *id, const tor_addr_t *at_addr,
+                               const uint16_t at_port, time_t when)
 {
 {
   or_history_t *hist = get_or_history(id);
   or_history_t *hist = get_or_history(id);
   int was_in_run = 1;
   int was_in_run = 1;
   char tbuf[ISO_TIME_LEN+1];
   char tbuf[ISO_TIME_LEN+1];
+  int addr_changed, port_changed;
 
 
   tor_assert(hist);
   tor_assert(hist);
+  tor_assert((!at_addr && !at_port) || (at_addr && at_port));
+
+  addr_changed = at_addr &&
+    tor_addr_compare(at_addr, &hist->last_reached_addr, CMP_EXACT) != 0;
+  port_changed = at_port && at_port != hist->last_reached_port;
 
 
   if (!started_tracking_stability)
   if (!started_tracking_stability)
     started_tracking_stability = time(NULL);
     started_tracking_stability = time(NULL);
@@ -316,6 +332,27 @@ rep_hist_note_router_reachable(const char *id, time_t when)
     down_length = when - hist->start_of_downtime;
     down_length = when - hist->start_of_downtime;
     hist->total_weighted_time += down_length;
     hist->total_weighted_time += down_length;
     hist->start_of_downtime = 0;
     hist->start_of_downtime = 0;
+  } else if (addr_changed || port_changed) {
+    /* If we're reachable, but the address changed, treat this as some
+     * downtime. */
+    int penalty = get_options()->TestingTorNetwork ? 240 : 3600;
+    networkstatus_t *ns;
+
+    if ((ns = networkstatus_get_latest_consensus())) {
+      int fresh_interval = (int)(ns->fresh_until - ns->valid_after);
+      int live_interval = (int)(ns->valid_until - ns->valid_after);
+      /* on average, a descriptor addr change takes .5 intervals to make it
+       * into a consensus, and half a liveness period to make it to
+       * clients. */
+      penalty = (int)(fresh_interval + live_interval) / 2;
+    }
+    format_local_iso_time(tbuf, hist->start_of_run);
+    log_info(LD_HIST,"Router %s still seems Running, but its address appears "
+             "to have changed since the last time it was reachable.  I'm "
+             "going to treat it as having been down for %d seconds",
+             hex_str(id, DIGEST_LEN), penalty);
+    rep_hist_note_router_unreachable(id, when-penalty);
+    rep_hist_note_router_reachable(id, NULL, 0, when);
   } else {
   } else {
     format_local_iso_time(tbuf, hist->start_of_run);
     format_local_iso_time(tbuf, hist->start_of_run);
     if (was_in_run)
     if (was_in_run)
@@ -325,6 +362,10 @@ rep_hist_note_router_reachable(const char *id, time_t when)
       log_info(LD_HIST,"Router %s is now Running; it was previously untracked",
       log_info(LD_HIST,"Router %s is now Running; it was previously untracked",
                hex_str(id, DIGEST_LEN));
                hex_str(id, DIGEST_LEN));
   }
   }
+  if (at_addr)
+    tor_addr_copy(&hist->last_reached_addr, at_addr);
+  if (at_port)
+    hist->last_reached_port = at_port;
 }
 }
 
 
 /** We have just decided that this router is unreachable, meaning
 /** We have just decided that this router is unreachable, meaning
@@ -345,12 +386,20 @@ rep_hist_note_router_unreachable(const char *id, time_t when)
     long run_length = when - hist->start_of_run;
     long run_length = when - hist->start_of_run;
     format_local_iso_time(tbuf, hist->start_of_run);
     format_local_iso_time(tbuf, hist->start_of_run);
 
 
-    hist->weighted_run_length += run_length;
     hist->total_run_weights += 1.0;
     hist->total_run_weights += 1.0;
     hist->start_of_run = 0;
     hist->start_of_run = 0;
-    hist->weighted_uptime += run_length;
-    hist->total_weighted_time += run_length;
+    if (run_length < 0) {
+      unsigned long penalty = -run_length;
+#define SUBTRACT_CLAMPED(var, penalty) \
+      do { (var) = (var) < (penalty) ? 0 : (var) - (penalty); } while (0)
 
 
+      SUBTRACT_CLAMPED(hist->weighted_run_length, penalty);
+      SUBTRACT_CLAMPED(hist->weighted_uptime, penalty);
+    } else {
+      hist->weighted_run_length += run_length;
+      hist->weighted_uptime += run_length;
+      hist->total_weighted_time += run_length;
+    }
     was_running = 1;
     was_running = 1;
     log_info(LD_HIST, "Router %s is now non-Running: it had previously been "
     log_info(LD_HIST, "Router %s is now non-Running: it had previously been "
              "Running since %s.  Its total weighted uptime is %lu/%lu.",
              "Running since %s.  Its total weighted uptime is %lu/%lu.",
@@ -423,7 +472,7 @@ rep_hist_downrate_old_runs(time_t now)
 static double
 static double
 get_stability(or_history_t *hist, time_t when)
 get_stability(or_history_t *hist, time_t when)
 {
 {
-  unsigned long total = hist->weighted_run_length;
+  long total = hist->weighted_run_length;
   double total_weights = hist->total_run_weights;
   double total_weights = hist->total_run_weights;
 
 
   if (hist->start_of_run) {
   if (hist->start_of_run) {
@@ -459,8 +508,8 @@ get_total_weighted_time(or_history_t *hist, time_t when)
 static double
 static double
 get_weighted_fractional_uptime(or_history_t *hist, time_t when)
 get_weighted_fractional_uptime(or_history_t *hist, time_t when)
 {
 {
-  unsigned long total = hist->total_weighted_time;
-  unsigned long up = hist->weighted_uptime;
+  long total = hist->total_weighted_time;
+  long up = hist->weighted_uptime;
 
 
   if (hist->start_of_run) {
   if (hist->start_of_run) {
     long run_length = (when - hist->start_of_run);
     long run_length = (when - hist->start_of_run);

+ 2 - 1
src/or/rephist.h

@@ -33,7 +33,8 @@ void rep_hist_update_state(or_state_t *state);
 int rep_hist_load_state(or_state_t *state, char **err);
 int rep_hist_load_state(or_state_t *state, char **err);
 void rep_history_clean(time_t before);
 void rep_history_clean(time_t before);
 
 
-void rep_hist_note_router_reachable(const char *id, time_t when);
+void rep_hist_note_router_reachable(const char *id, const tor_addr_t *at_addr,
+                                    uint16_t at_port, time_t when);
 void rep_hist_note_router_unreachable(const char *id, time_t when);
 void rep_hist_note_router_unreachable(const char *id, time_t when);
 int rep_hist_record_mtbf_data(time_t now, int missing_means_down);
 int rep_hist_record_mtbf_data(time_t now, int missing_means_down);
 int rep_hist_load_mtbf_data(time_t now);
 int rep_hist_load_mtbf_data(time_t now);