Browse Source

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


svn:r10956

Nick Mathewson 18 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:
   o Performance improvements:
     - Be more aggressive with freeing buffer RAM or putting it on the
     - Be more aggressive with freeing buffer RAM or putting it on the
       free lists.
       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):
   o Performance improvements (win32):
     - Use Critical Sections rather than Mutexes for synchronizing threads
     - 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
    on the fraction of bandwidth available from non-Exit nodes.  Call the
    total clipped advertised bandwidth for Exit nodes under consideration E,
    total clipped advertised bandwidth for Exit nodes under consideration E,
    and the total clipped advertised bandwidth for non-Exit nodes under
    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) ==
    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
    (2E - N)/(2E + N).  This ensures that bandwidth is evenly distributed over
    nodes in 3-hop paths.
    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;
   double exit_weight;
   int n_unknown = 0;
   int n_unknown = 0;
   bitarray_t *exit_bits;
   bitarray_t *exit_bits;
+  int include_exits = 1;
 
 
   /* First count the total bandwidth weight, and make a list
   /* First count the total bandwidth weight, and make a list
    * of each value.  <0 means "unknown; no routerinfo."  We use the
    * 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. */
     /* If we're choosing an exit node, exit bandwidth counts fully. */
     exit_weight = 1.0;
     exit_weight = 1.0;
     total_bw = total_exit_bw + total_nonexit_bw;
     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 {
   } else {
-    /* If we're choosing a relay and exits aren't outnumbered use the formula
+    double all_bw = U64_TO_DBL(total_exit_bw+total_nonexit_bw);
-     * from path-spec. */
+    double exit_bw = U64_TO_DBL(total_exit_bw);
-    uint64_t leftover = (total_exit_bw - total_nonexit_bw / 2);
+    /*
-    exit_weight = U64_TO_DBL(leftover) /
+     * For detailed derivation of this formula, see
-      U64_TO_DBL(leftover + total_nonexit_bw);
+     *   http://archives.seul.org/or/dev/Jul-2007/msg00056.html
-#if 0
+     */
-    total_bw =  total_nonexit_bw +
+    exit_weight = 1.0 - all_bw/(3.0*exit_bw);
-      DBL_TO_U64(exit_weight * U64_TO_DBL(total_exit_bw));
+    if (exit_weight <= 0.0) {
-#endif
+      include_exits = 0;
-    total_bw = 0;
+      exit_weight = 0.0;
-    for (i=0; i < (unsigned)smartlist_len(sl); i++) {
+      total_bw = total_nonexit_bw;
-      is_exit = bitarray_is_set(exit_bits, i);
+    } else {
-      if (is_exit)
+      total_bw = 0;
-        total_bw += ((uint64_t)(bandwidths[i] * exit_weight));
+      for (i=0; i < (unsigned)smartlist_len(sl); i++) {
-      else
+        is_exit = bitarray_is_set(exit_bits, i);
-        total_bw += bandwidths[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;
   tmp = 0;
   for (i=0; i < (unsigned)smartlist_len(sl); i++) {
   for (i=0; i < (unsigned)smartlist_len(sl); i++) {
     is_exit = bitarray_is_set(exit_bits, i);
     is_exit = bitarray_is_set(exit_bits, i);
-    if (is_exit)
+    if (is_exit) {
-      tmp += ((uint64_t)(bandwidths[i] * exit_weight));
+      if (include_exits)
-    else
+        tmp += ((uint64_t)(bandwidths[i] * exit_weight));
+    } else
       tmp += bandwidths[i];
       tmp += bandwidths[i];
     if (tmp >= rand_bw)
     if (tmp >= rand_bw)
       break;
       break;