[or-cvs] Finish implementing config"s EntryNodes and StrictEntryNode...

arma at seul.org arma at seul.org
Sat Dec 31 06:32:59 UTC 2005


Update of /home/or/cvsroot/tor/src/or
In directory moria:/tmp/cvs-serv20810

Modified Files:
	circuitbuild.c config.c or.h routerlist.c 
Log Message:
Finish implementing config's EntryNodes and StrictEntryNodes option.
The logging is way verbose for now.


Index: circuitbuild.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/circuitbuild.c,v
retrieving revision 1.197
retrieving revision 1.198
diff -u -p -d -r1.197 -r1.198
--- circuitbuild.c	28 Dec 2005 09:07:31 -0000	1.197
+++ circuitbuild.c	31 Dec 2005 06:32:57 -0000	1.198
@@ -109,7 +109,7 @@ circuit_list_path(circuit_t *circ, int v
 
   if (verbose) {
     const char *nickname = build_state_get_exit_nickname(circ->build_state);
-    tor_snprintf(buf, sizeof(buf)-1, "%s%s circ (length %d%s%s):",
+    tor_snprintf(buf, sizeof(buf), "%s%s circ (length %d%s%s):",
                  circ->build_state->is_internal ? "internal" : "exit",
                  circ->build_state->need_uptime ? " (high-uptime)" : "",
                  circ->build_state->desired_path_len,
@@ -1115,14 +1115,10 @@ choose_good_exit_server_general(routerli
   int n_connections;
   int best_support = -1;
   int n_best_support=0;
-  smartlist_t *sl, *preferredexits, *preferredentries, *excludedexits;
+  smartlist_t *sl, *preferredexits, *excludedexits;
   routerinfo_t *router;
   or_options_t *options = get_options();
 
-//XXX
-  preferredentries = smartlist_create();
-  add_nickname_list_to_smartlist(preferredentries,options->EntryNodes,1,1);
-
   get_connection_array(&carray, &n_connections);
 
   /* Count how many connections are waiting for a circuit to be built.
@@ -1176,13 +1172,6 @@ choose_good_exit_server_general(routerli
 //             router->nickname, i);
       continue; /* skip routers that reject all */
     }
-    if (smartlist_len(preferredentries)==1 &&
-        router == (routerinfo_t*)smartlist_get(preferredentries, 0)) {
-      n_supported[i] = -1;
-//      log_fn(LOG_DEBUG, "Skipping node %s (index %d) -- it's our only "
-//             "preferred entry node.", router->nickname, i);
-      continue;
-    }
     n_supported[i] = 0;
     for (j = 0; j < n_connections; ++j) { /* iterate over connections */
       if (!ap_stream_wants_exit_attention(carray[j]))
@@ -1213,10 +1202,10 @@ choose_good_exit_server_general(routerli
        n_best_support, best_support, n_pending_connections);
 
   preferredexits = smartlist_create();
-  add_nickname_list_to_smartlist(preferredexits,options->ExitNodes,1,1);
+  add_nickname_list_to_smartlist(preferredexits,options->ExitNodes,1,1,1);
 
   excludedexits = smartlist_create();
-  add_nickname_list_to_smartlist(excludedexits,options->ExcludeNodes,0,1);
+  add_nickname_list_to_smartlist(excludedexits,options->ExcludeNodes,0,0,1);
 
   sl = smartlist_create();
 
@@ -1277,7 +1266,6 @@ choose_good_exit_server_general(routerli
   }
 
   smartlist_free(preferredexits);
-  smartlist_free(preferredentries);
   smartlist_free(excludedexits);
   smartlist_free(sl);
   tor_free(n_supported);
@@ -1741,7 +1729,7 @@ num_live_entry_nodes(void)
 /** Return 1 if <b>digest</b> matches the identity of any node
  * in the entry_nodes list. Else return 0. */
 static INLINE int
-is_an_entry(char *digest)
+is_an_entry_node(char *digest)
 {
   SMARTLIST_FOREACH(entry_nodes, entry_node_t *, entry,
                     if(!memcmp(digest, entry->identity, DIGEST_LEN))
@@ -1750,22 +1738,47 @@ is_an_entry(char *digest)
   return 0;
 }
 
+static void
+log_entry_nodes(int severity)
+{
+  smartlist_t *elements = smartlist_create();
+  char buf[1024];
+  char *s;
+
+  SMARTLIST_FOREACH(entry_nodes, entry_node_t *, e,
+    {
+      tor_snprintf(buf, sizeof(buf), "%s (%s%s%s)",
+                   e->nickname,
+                   e->down_since ? "down " : "up ",
+                   e->unlisted_since ? "unlisted " : "listed ",
+                   e->made_contact ? "made-contact" : "never-contacted");
+      smartlist_add(elements, tor_strdup(buf));
+    });
+
+  s = smartlist_join_strings(elements, ",", 0, NULL);
+  SMARTLIST_FOREACH(elements, char*, cp, tor_free(cp));
+  smartlist_free(elements);
+  log_fn(severity,LD_CIRC,"%s",s);
+  tor_free(s);
+}
+
 #define NUM_ENTRY_PICK_TRIES 100
 
 /** Add a new (preferably stable and fast) entry to our
  * entry_nodes list. Return a pointer to the router if we succeed,
- * or NULL if we can't find any more suitable entries. If
- * <b>tries_left</b> is <= 1, that means you should fail.
+ * or NULL if we can't find any more suitable entries.
  *
- * [not implemented yet]
- * If <b>chosen</b> is defined, use that one, and put it at
- * the *beginning* of our entry_nodes list. Else, put the one
- * we pick at the end of the list. */
+ * If <b>chosen</b> is defined, use that one, and if it's not
+ * already in our entry_nodes list, put it at the *beginning*.
+ * Else, put the one we pick at the end of the list. */
 static routerinfo_t *
-add_an_entry(routerinfo_t *chosen, int tries_left)
+add_an_entry_node(routerinfo_t *chosen)
 {
   routerinfo_t *router;
   entry_node_t *entry;
+  int tries_left = NUM_ENTRY_PICK_TRIES;
+
+again:
   if (--tries_left <= 0) {
     warn(LD_CIRC, "Tried finding a new entry, but failed. Bad news. XXX.");
     return NULL;
@@ -1777,14 +1790,21 @@ add_an_entry(routerinfo_t *chosen, int t
   if (!router)
     return NULL;
   /* make sure it's not already an entry */
-  if (is_an_entry(router->cache_info.identity_digest))
-    return chosen ? NULL : add_an_entry(NULL, tries_left); /* recurse */
+  if (is_an_entry_node(router->cache_info.identity_digest)) {
+    if (chosen)
+      return NULL;
+    goto again;
+  }
   entry = tor_malloc_zero(sizeof(entry_node_t));
   /* XXXX Downgrade this to info before release. NM */
   notice(LD_CIRC, "Chose '%s' as new entry node.", router->nickname);
   strlcpy(entry->nickname, router->nickname, sizeof(entry->nickname));
   memcpy(entry->identity, router->cache_info.identity_digest, DIGEST_LEN);
-  smartlist_add(entry_nodes, entry);
+  if (chosen)
+    smartlist_insert(entry_nodes, 0, entry);
+  else
+    smartlist_add(entry_nodes, entry);
+  log_entry_nodes(LOG_NOTICE);
   return router;
 }
 
@@ -1796,13 +1816,10 @@ pick_entry_nodes(void)
   or_options_t *options = get_options();
   int changed = 0;
 
-  if (!entry_nodes)
-    entry_nodes = smartlist_create();
-
-  /* XXX this is where we prepend options->EntryNodes? */
+  tor_assert(entry_nodes);
 
   while (num_live_entry_nodes() < options->NumEntryNodes) {
-    if (!add_an_entry(NULL, NUM_ENTRY_PICK_TRIES))
+    if (!add_an_entry_node(NULL))
       break;
     changed = 1;
   }
@@ -1862,6 +1879,7 @@ remove_dead_entries(void)
            entry->nickname, dbuf, why, tbuf);
       tor_free(entry);
       smartlist_del_keeporder(entry_nodes, i);
+      log_entry_nodes(LOG_NOTICE);
       changed = 1;
     } else
       ++i;
@@ -1941,6 +1959,7 @@ entry_nodes_set_status_from_directory(vo
   if (changed) {
     log_fn(severity, LD_CIRC, "    (%d/%d entries are usable/new)",
            num_live_entry_nodes(), smartlist_len(entry_nodes));
+    log_entry_nodes(severity);
     entry_nodes_changed();
   }
 }
@@ -1987,6 +2006,7 @@ entry_node_set_status(const char *digest
                    "Connected to new entry node '%s'. Marking earlier "
                    "entries up. %d/%d entries usable/new.", entry->nickname,
                    num_live_entry_nodes(), smartlist_len(entry_nodes));
+            log_entry_nodes(LOG_NOTICE);
             changed = 1;
           }
           if (entry->down_since) {
@@ -1996,6 +2016,7 @@ entry_node_set_status(const char *digest
                    "%d/%d entry nodes usable/new.", entry->nickname,
                    num_live_entry_nodes(), smartlist_len(entry_nodes));
             entry->down_since = 0;
+            log_entry_nodes(LOG_NOTICE);
             changed = 1;
           }
         } else {
@@ -2007,6 +2028,7 @@ entry_node_set_status(const char *digest
                    num_live_entry_nodes()-1, smartlist_len(entry_nodes)-1);
             tor_free(entry);
             smartlist_del_keeporder(entry_nodes, entry_sl_idx);
+            log_entry_nodes(LOG_NOTICE);
             changed = 1;
           } else if (!entry->down_since) {
             entry->down_since = time(NULL);
@@ -2014,6 +2036,7 @@ entry_node_set_status(const char *digest
                  " %d/%d entry nodes usable/new.",
                  entry->nickname,
                  num_live_entry_nodes(), smartlist_len(entry_nodes));
+            log_entry_nodes(LOG_NOTICE);
             changed = 1;
           }
         }
@@ -2025,20 +2048,78 @@ entry_node_set_status(const char *digest
   return refuse_conn ? -1 : 0;
 }
 
+/** When we try to choose an entry node, should we parse and add
+ * config's EntryNodes first? */
+static int should_add_entry_nodes = 0;
+
+void
+entry_nodes_should_be_added(void)
+{
+  notice(LD_CIRC, "New EntryNodes config option detected. Will use.");
+  should_add_entry_nodes = 1;
+}
+
+void
+entry_nodes_prepend_from_config(void)
+{
+  int missed_some = 0;
+  int idx;
+  or_options_t *options = get_options();
+  smartlist_t *routers = smartlist_create();
+
+  tor_assert(entry_nodes);
+
+  add_nickname_list_to_smartlist(routers, options->EntryNodes,
+                                 0, 1, 1);
+
+  /* take a moment first to notice whether we got them all */
+  if (options->EntryNodes) {
+    notice(LD_CIRC,"Adding configured EntryNodes '%s'.",
+           options->EntryNodes);
+    smartlist_t *tmp = smartlist_create();
+    smartlist_split_string(tmp, options->EntryNodes, ",",
+                           SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+    missed_some = smartlist_len(routers) != smartlist_len(tmp);
+    SMARTLIST_FOREACH(tmp, char *, nick, tor_free(nick));
+    smartlist_free(tmp);
+  }
+
+  for (idx = smartlist_len(routers)-1 ; idx >= 0; idx--) {
+    /* pick off the last one, turn it into a router, prepend it
+     * to our entry_nodes list. If we can't find it, set missed_some
+     * to 1. */
+    routerinfo_t *r = smartlist_get(routers, idx);
+    add_an_entry_node(r);
+  }
+
+  if (!missed_some)
+    should_add_entry_nodes = 0; /* whew, we're done */
+
+  smartlist_free(routers);
+}
+
 /** Pick a live (up and listed) entry node from entry_nodes, and
  * make sure not to pick this circuit's exit. */
 static routerinfo_t *
 choose_random_entry(cpath_build_state_t *state)
 {
+  or_options_t *options = get_options();
   smartlist_t *live_entry_nodes = smartlist_create();
   routerinfo_t *chosen_exit = build_state_get_exit_router(state);
-  routerinfo_t *r;
+  routerinfo_t *r = NULL;
   int need_uptime = state->need_uptime;
   int need_capacity = state->need_capacity;
 
+  if (!entry_nodes)
+    entry_nodes = smartlist_create();
+
+  if (should_add_entry_nodes)
+    entry_nodes_prepend_from_config();
+
   if (! entry_nodes ||
-      smartlist_len(entry_nodes) < get_options()->NumEntryNodes)
-    pick_entry_nodes();
+      smartlist_len(entry_nodes) < options->NumEntryNodes)
+    if (!options->StrictEntryNodes)
+      pick_entry_nodes();
 
  retry:
   smartlist_clear(live_entry_nodes);
@@ -2047,7 +2128,7 @@ choose_random_entry(cpath_build_state_t 
       r = entry_is_live(entry, need_uptime, need_capacity);
       if (r && r != chosen_exit) {
         smartlist_add(live_entry_nodes, r);
-        if (smartlist_len(live_entry_nodes) >= get_options()->NumEntryNodes)
+        if (smartlist_len(live_entry_nodes) >= options->NumEntryNodes)
           break; /* we have enough */
       }
     });
@@ -2061,19 +2142,20 @@ choose_random_entry(cpath_build_state_t 
       need_uptime = 0; /* try without that requirement */
       goto retry;
     }
-    /* still no? try adding a new entry then */
-    r = add_an_entry(NULL, NUM_ENTRY_PICK_TRIES);
-    if (r) {
-      smartlist_add(live_entry_nodes, r);
-      entry_nodes_changed();
-    } else {
-      if (need_capacity) {
+    if (!options->StrictEntryNodes) {
+      /* still no? try adding a new entry then */
+      r = add_an_entry_node(NULL);
+      if (r) {
+        smartlist_add(live_entry_nodes, r);
+        entry_nodes_changed();
+      }
+    }
+    if (!r && need_capacity) {
         /* still no? last attempt, try without requiring capacity */
         need_capacity = 0;
         goto retry;
-      }
-      /* live_entry_nodes will be empty below. Oh well, we tried. */
     }
+    /* live_entry_nodes will be empty below. Oh well, we tried. */
   }
 
   r = smartlist_choose(live_entry_nodes);

Index: config.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/config.c,v
retrieving revision 1.470
retrieving revision 1.471
diff -u -p -d -r1.470 -r1.471
--- config.c	28 Dec 2005 09:07:31 -0000	1.470
+++ config.c	31 Dec 2005 06:32:57 -0000	1.471
@@ -701,6 +701,11 @@ options_act(or_options_t *old_options)
     }
   }
 
+  /* Check if we need to parse and add the EntryNodes config option. */
+  if (!old_options ||
+      !opt_streq(old_options->EntryNodes, options->EntryNodes))
+    entry_nodes_should_be_added();
+
   /* Since our options changed, we might need to regenerate and upload our
    * server descriptor.
    */

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.768
retrieving revision 1.769
diff -u -p -d -r1.768 -r1.769
--- or.h	28 Dec 2005 09:07:31 -0000	1.768
+++ or.h	31 Dec 2005 06:32:57 -0000	1.769
@@ -1469,8 +1469,10 @@ void extend_info_free(extend_info_t *inf
 routerinfo_t *build_state_get_exit_router(cpath_build_state_t *state);
 const char *build_state_get_exit_nickname(cpath_build_state_t *state);
 
-int entry_node_set_status(const char *digest, int succeeded);
 void entry_nodes_set_status_from_directory(void);
+int entry_node_set_status(const char *digest, int succeeded);
+void entry_nodes_should_be_added(void);
+void entry_nodes_prepend_from_config(void);
 void entry_nodes_update_state(or_state_t *state);
 int entry_nodes_parse_state(or_state_t *state, int set, const char **err);
 int entry_nodes_getinfo(const char *question, char **answer);
@@ -2235,6 +2237,7 @@ trusted_dir_server_t *router_get_trusted
 int all_trusted_directory_servers_down(void);
 void routerlist_add_family(smartlist_t *sl, routerinfo_t *router);
 void add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
+                                    int must_be_running,
                                     int warn_if_down, int warn_if_unnamed);
 routerinfo_t *routerlist_find_my_routerinfo(void);
 int exit_policy_implicitly_allows_local_networks(addr_policy_t *policy,

Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerlist.c,v
retrieving revision 1.410
retrieving revision 1.411
diff -u -p -d -r1.410 -r1.411
--- routerlist.c	30 Dec 2005 04:46:43 -0000	1.410
+++ routerlist.c	31 Dec 2005 06:32:57 -0000	1.411
@@ -559,7 +559,7 @@ routerlist_add_family(smartlist_t *sl, r
   /* If the user declared any families locally, honor those too. */
   for (cl = get_options()->NodeFamilies; cl; cl = cl->next) {
     if (router_nickname_is_in_list(router, cl->value)) {
-      add_nickname_list_to_smartlist(sl, cl->value, 1, 1);
+      add_nickname_list_to_smartlist(sl, cl->value, 0, 1, 1);
     }
   }
 }
@@ -570,6 +570,7 @@ routerlist_add_family(smartlist_t *sl, r
  */
 void
 add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
+                               int must_be_running,
                                int warn_if_down, int warn_if_unnamed)
 {
   routerinfo_t *router;
@@ -590,13 +591,13 @@ add_nickname_list_to_smartlist(smartlist
   SMARTLIST_FOREACH(nickname_list, const char *, nick, {
     int warned;
     if (!is_legal_nickname_or_hexdigest(nick)) {
-      warn(LD_CONFIG, "Nickname %s is misformed; skipping", nick);
+      warn(LD_CONFIG, "Nickname '%s' is misformed; skipping", nick);
       continue;
     }
     router = router_get_by_nickname(nick, warn_if_unnamed);
     warned = smartlist_string_isin(warned_nicknames, nick);
     if (router) {
-      if (router->is_running) {
+      if (!must_be_running || router->is_running) {
         smartlist_add(sl,router);
         if (warned)
           smartlist_string_remove(warned_nicknames, nick);
@@ -811,12 +812,12 @@ router_choose_random_node(const char *pr
   routerinfo_t *choice;
 
   excludednodes = smartlist_create();
-  add_nickname_list_to_smartlist(excludednodes,excluded,0,1);
+  add_nickname_list_to_smartlist(excludednodes,excluded,0,0,1);
 
   /* Try the preferred nodes first. Ignore need_uptime and need_capacity,
    * since the user explicitly asked for these nodes. */
   sl = smartlist_create();
-  add_nickname_list_to_smartlist(sl,preferred,1,1);
+  add_nickname_list_to_smartlist(sl,preferred,1,1,1);
   smartlist_subtract(sl,excludednodes);
   if (excludedsmartlist)
     smartlist_subtract(sl,excludedsmartlist);



More information about the tor-commits mailing list