Commit 57ffca88 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

r8826@totoro: nickm | 2006-10-01 17:58:45 -0400

 Disprefer exit nodes for entry, middle positions (fixes bug 200).  Also, switch to using a uint64_t to hold "total bandwidth for all nodes" under consideration; crypt_rand_int would have died at 2GB/s network capacity.


svn:r8571
parent 219ad639
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@ Changes in version 0.1.2.2-alpha - 2006-10-??
      and including the function name only seems to confuse users.
    - Fix CIRC controller events so that controllers can learn the identity
      digests of non-Named servers used in circuit paths. (Fixes bug 336.)
    - Avoid choosing Exit nodes for entry or middle hops when the bandwidth
      available in non-Exit nodes is much higher then the bandwidth available
      in Exit nodes. (Fixes bug 200.)

  o Security Fixes, minor:
    - If a client asked for a server by name, and we didn't have a
@@ -93,6 +96,8 @@ Changes in version 0.1.2.2-alpha - 2006-10-??
      With the old code, if a guard was unreachable by us but listed as
      running, it would clog our guard list forever.
    - Make eventdns give strings for DNS errors, not just error numbers.
    - Be prepared in case we ever have a network with  more than 2GB per
      second total advertised capacity.

  o Documentation
    - Documented (and renamed) ServerDNSSearchDomains and
+4 −6
Original line number Diff line number Diff line
@@ -35,12 +35,10 @@ x - If the client's clock is too far in the past, it will drop (or
      D The right thing here is to revamp our node selection implementation.
        (Deferred until oprofile says this matters.)
    o make it configurable, so people can turn it on or off.
N - Add script to grep for identical log msgs.
N - Bug 200: disprefer exit nodes for entry, middle.
    - If less than 1/3 support port X, only use as exit.
    - If 2/3 support port X, weight exits 1/2; weight non-exits 1.
    - (Exit fraction - 1/3):Non-exit fraction
    - (e - 1/3)/(1-e)
  o Add script to grep for identical log msgs.
  o Bug 200: disprefer exit nodes for entry, middle.
    o Specify
    o Implement
  o Bug 303: block exit from circuits created with create-fast
    o Specify and document
    o Implement
+18 −9
Original line number Diff line number Diff line
@@ -157,15 +157,24 @@ of their choices.
       below)
     - XXXX Choosing the length

   For circuits that are not "fast", when choosing among multiple
   candidates for a path element, we choose randomly. For "fast" circuits,
   we choose
   a given router with probability proportional to its advertised bandwidth
   [the smaller of the 'rate' and 'observed' arguments to the "bandwidth"
   element in its descriptor].  If a router's advertised bandwidth is greater
   than MAX_BELIEVEABLE_BANDWIDTH (1.5 MB/sec), we clip to that value.

   (XXXX We should do something to shift traffic away from exit nodes.)
   For circuits that do not need to be not "fast", when choosing among
   multiple candidates for a path element, we choose randomly.

   For "fast" circuits, we a given router as an exit with probability
   proportional to its advertised bandwidth [the smaller of the 'rate' and
   'observed' arguments to the "bandwidth" element in its descriptor].  If a
   router's advertised bandwidth is greater than MAX_BELIEVEABLE_BANDWIDTH
   (1.5 MB/sec), we clip to that value.

   For non-exit positions on "fast" circuits, we pick routers as above, but
   we weight the clipped advertised bandwidth of Exit-flagged nodes depending
   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.
   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.

   Additionally, we may be building circuits with one or more requests in
   mind.  Each kind of request puts certain constraints on paths:
+6 −6
Original line number Diff line number Diff line
@@ -1199,7 +1199,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
    smartlist_subtract(sl,excludedexits);
    if (options->StrictExitNodes || smartlist_overlap(sl,preferredexits))
      smartlist_intersect(sl,preferredexits);
    router = routerlist_sl_choose_by_bandwidth(sl);
    router = routerlist_sl_choose_by_bandwidth(sl, 1);
  } else {
    /* Either there are no pending connections, or no routers even seem to
     * possibly support any of them.  Choose a router at random that satisfies
@@ -1238,7 +1238,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
        smartlist_intersect(sl,preferredexits);
        /* XXX sometimes the above results in null, when the requested
         * exit node is down. we should pick it anyway. */
      router = routerlist_sl_choose_by_bandwidth(sl);
      router = routerlist_sl_choose_by_bandwidth(sl, 1);
      if (router)
        break;
    }
@@ -1282,14 +1282,14 @@ choose_good_exit_server(uint8_t purpose, routerlist_t *dir,
      if (is_internal) /* pick it like a middle hop */
        return router_choose_random_node(NULL, get_options()->ExcludeNodes,
               NULL, need_uptime, need_capacity, 0,
               get_options()->_AllowInvalid & ALLOW_INVALID_MIDDLE, 0);
               get_options()->_AllowInvalid & ALLOW_INVALID_MIDDLE, 0, 0);
      else
        return choose_good_exit_server_general(dir,need_uptime,need_capacity);
    case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
      return router_choose_random_node(
               options->RendNodes, options->RendExcludeNodes,
               NULL, need_uptime, need_capacity, 0,
               options->_AllowInvalid & ALLOW_INVALID_RENDEZVOUS, 0);
               options->_AllowInvalid & ALLOW_INVALID_RENDEZVOUS, 0, 0);
  }
  log_warn(LD_BUG,"Bug: unhandled purpose %d", purpose);
  tor_fragile_assert();
@@ -1508,7 +1508,7 @@ choose_good_middle_server(uint8_t purpose,
  choice = router_choose_random_node(preferred,
           options->ExcludeNodes, excluded,
           state->need_uptime, state->need_capacity, 0,
           options->_AllowInvalid & ALLOW_INVALID_MIDDLE, 0);
           options->_AllowInvalid & ALLOW_INVALID_MIDDLE, 0, 0);
  if (preferred)
    tor_free(preferred);
  smartlist_free(excluded);
@@ -1571,7 +1571,7 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state)
           excluded, state ? state->need_uptime : 0,
           state ? state->need_capacity : 0,
           state ? 0 : 1,
           options->_AllowInvalid & ALLOW_INVALID_ENTRY, 0);
           options->_AllowInvalid & ALLOW_INVALID_ENTRY, 0, 0);
  smartlist_free(excluded);
  return choice;
}
+5 −2
Original line number Diff line number Diff line
@@ -918,6 +918,7 @@ typedef struct {
  unsigned int is_fast:1; /** Do we think this is a fast OR? */
  unsigned int is_stable:1; /** Do we think this is a stable OR? */
  unsigned int is_possible_guard:1; /**< Do we think this is an OK guard? */
  unsigned int is_exit:1; /**< Do we think this is an OK exit? */

/** Tor can use this desc for circuit-building. */
#define ROUTER_PURPOSE_GENERAL 0
@@ -2562,13 +2563,15 @@ routerinfo_t *router_find_exact_exit_enclave(const char *address,
int router_is_unreliable(routerinfo_t *router, int need_uptime,
                         int need_capacity, int need_guard);
uint32_t router_get_advertised_bandwidth(routerinfo_t *router);
routerinfo_t *routerlist_sl_choose_by_bandwidth(smartlist_t *sl);
routerinfo_t *routerlist_sl_choose_by_bandwidth(smartlist_t *sl, int for_exit);

routerinfo_t *router_choose_random_node(const char *preferred,
                                        const char *excluded,
                                        smartlist_t *excludedsmartlist,
                                        int need_uptime, int need_bandwidth,
                                        int need_guard,
                                        int allow_invalid, int strict);
                                        int allow_invalid, int strict,
                                        int weight_for_exit);
routerinfo_t *router_get_by_nickname(const char *nickname,
                                     int warn_if_unnamed);
routerinfo_t *router_get_by_hexdigest(const char *hexdigest);
Loading