Browse Source

r13959@catbus: nickm | 2007-07-28 18:09:56 -0400
Use the correct formula to calculate exit weights.


svn:r10956

Nick Mathewson 17 years ago
parent
commit
76a408941c
3 changed files with 33 additions and 25 deletions
  1. 3 0
      ChangeLog
  2. 5 1
      doc/spec/path-spec.txt
  3. 25 24
      src/or/routerlist.c

+ 3 - 0
ChangeLog

@@ -43,6 +43,9 @@ Changes in version 0.2.0.3-alpha - 2007-??-??
   o Performance improvements:
     - Be more aggressive with freeing buffer RAM or putting it on the
       free lists.
+    - If exit bandwidth ever exceeds one third of total bandwidth, then
+      use the correct formula to weight exit nodes when choosing paths.
+      (Based on patch from Mike Perry.)
 
   o Performance improvements (win32):
     - Use Critical Sections rather than Mutexes for synchronizing threads

+ 5 - 1
doc/spec/path-spec.txt

@@ -189,7 +189,11 @@ of their choices.
    on the fraction of bandwidth available from non-Exit nodes.  Call the
    total clipped advertised bandwidth for Exit nodes under consideration E,
    and the total clipped advertised bandwidth for non-Exit nodes under
-   consideration N.  If E<N/2, we do not consider Exit-flagged nodes.
+   and the total clipped advertised bandwidth for all nodes under
+   consideration T.  If E<T/3, we do not consider Exit-flagged nodes.
+   Otherwise, we weight their bandwidth with the factor 1-T/(3E). This
+   ensures that bandwidth is evenly distributed over nodes in 3-hop paths.
+
    Otherwise, we weight their bandwidth with the factor (E-N/2)/(N+E-N/2) ==
    (2E - N)/(2E + N).  This ensures that bandwidth is evenly distributed over
    nodes in 3-hop paths.

+ 25 - 24
src/or/routerlist.c

@@ -1240,6 +1240,7 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, int for_exit, int statuses)
   double exit_weight;
   int n_unknown = 0;
   bitarray_t *exit_bits;
+  int include_exits = 1;
 
   /* First count the total bandwidth weight, and make a list
    * of each value.  <0 means "unknown; no routerinfo."  We use the
@@ -1325,28 +1326,27 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, int for_exit, int statuses)
     /* If we're choosing an exit node, exit bandwidth counts fully. */
     exit_weight = 1.0;
     total_bw = total_exit_bw + total_nonexit_bw;
-  } else if (total_exit_bw < total_nonexit_bw / 2) {
-    /* If we're choosing a relay and exits are greatly outnumbered, ignore
-     * them. */
-    exit_weight = 0.0;
-    total_bw = total_nonexit_bw;
   } else {
-    /* If we're choosing a relay and exits aren't outnumbered use the formula
-     * from path-spec. */
-    uint64_t leftover = (total_exit_bw - total_nonexit_bw / 2);
-    exit_weight = U64_TO_DBL(leftover) /
-      U64_TO_DBL(leftover + total_nonexit_bw);
-#if 0
-    total_bw =  total_nonexit_bw +
-      DBL_TO_U64(exit_weight * U64_TO_DBL(total_exit_bw));
-#endif
-    total_bw = 0;
-    for (i=0; i < (unsigned)smartlist_len(sl); i++) {
-      is_exit = bitarray_is_set(exit_bits, i);
-      if (is_exit)
-        total_bw += ((uint64_t)(bandwidths[i] * exit_weight));
-      else
-        total_bw += bandwidths[i];
+    double all_bw = U64_TO_DBL(total_exit_bw+total_nonexit_bw);
+    double exit_bw = U64_TO_DBL(total_exit_bw);
+    /*
+     * For detailed derivation of this formula, see
+     *   http://archives.seul.org/or/dev/Jul-2007/msg00056.html
+     */
+    exit_weight = 1.0 - all_bw/(3.0*exit_bw);
+    if (exit_weight <= 0.0) {
+      include_exits = 0;
+      exit_weight = 0.0;
+      total_bw = total_nonexit_bw;
+    } else {
+      total_bw = 0;
+      for (i=0; i < (unsigned)smartlist_len(sl); i++) {
+        is_exit = bitarray_is_set(exit_bits, i);
+        if (is_exit)
+          total_bw += ((uint64_t)(bandwidths[i] * exit_weight));
+        else
+          total_bw += bandwidths[i];
+      }
     }
   }
   /*
@@ -1364,9 +1364,10 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, int for_exit, int statuses)
   tmp = 0;
   for (i=0; i < (unsigned)smartlist_len(sl); i++) {
     is_exit = bitarray_is_set(exit_bits, i);
-    if (is_exit)
-      tmp += ((uint64_t)(bandwidths[i] * exit_weight));
-    else
+    if (is_exit) {
+      if (include_exits)
+        tmp += ((uint64_t)(bandwidths[i] * exit_weight));
+    } else
       tmp += bandwidths[i];
     if (tmp >= rand_bw)
       break;