[or-cvs] Refactor routerlist access slightly: always use router_get_...

Nick Mathewson nickm at seul.org
Tue Oct 18 17:43:56 UTC 2005


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

Modified Files:
	circuitbuild.c control.c dirserv.c or.h router.c routerlist.c 
Log Message:
Refactor routerlist access slightly: always use router_get_by_routerlist(); change its interface; add modifier functions to add/remove elements from the current routerlist (so we can add indices).

Index: circuitbuild.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/circuitbuild.c,v
retrieving revision 1.152
retrieving revision 1.153
diff -u -d -r1.152 -r1.153
--- circuitbuild.c	17 Oct 2005 08:41:58 -0000	1.152
+++ circuitbuild.c	18 Oct 2005 17:43:54 -0000	1.153
@@ -1254,14 +1254,9 @@
 onion_pick_cpath_exit(circuit_t *circ, extend_info_t *exit)
 {
   cpath_build_state_t *state = circ->build_state;
-  routerlist_t *rl;
+  routerlist_t *rl = router_get_routerlist();
   int r;
 
-  router_get_routerlist(&rl);
-  if (!rl) {
-    log_fn(LOG_WARN,"router_get_routerlist returned empty list; closing circ.");
-    return -1;
-  }
   r = new_route_len(get_options()->PathlenCoinWeight, circ->purpose,
                     exit, rl->routers);
   if (r < 1) /* must be at least 1 */
@@ -1439,13 +1434,9 @@
   }
   if (firewall_is_fascist()) {
     /* exclude all ORs that listen on the wrong port */
-    routerlist_t *rl;
+    routerlist_t *rl = router_get_routerlist();
     int i;
 
-    router_get_routerlist(&rl);
-    if (!rl)
-      return NULL;
-
     for (i=0; i < smartlist_len(rl->routers); i++) {
       r = smartlist_get(rl->routers, i);
       if (!fascist_firewall_allows_address(r->addr,r->or_port))
@@ -1745,9 +1736,7 @@
   if (! helper_nodes)
     return;
 
-  router_get_routerlist(&routers);
-  if (! routers)
-    return;
+  routers = router_get_routerlist();
 
   now = time(NULL);
 

Index: control.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/control.c,v
retrieving revision 1.141
retrieving revision 1.142
diff -u -d -r1.141 -r1.142
--- control.c	18 Oct 2005 16:45:43 -0000	1.141
+++ control.c	18 Oct 2005 17:43:54 -0000	1.142
@@ -1261,8 +1261,7 @@
     *answer = dirserver_getinfo_unregistered(question +
                                              strlen("unregistered-servers-"));
   } else if (!strcmp(question, "network-status")) {
-    routerlist_t *routerlist;
-    router_get_routerlist(&routerlist);
+    routerlist_t *routerlist = router_get_routerlist();
     if (!routerlist || !routerlist->routers ||
         list_server_status(routerlist->routers, answer) < 0) {
       return -1;

Index: dirserv.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/dirserv.c,v
retrieving revision 1.255
retrieving revision 1.256
diff -u -d -r1.255 -r1.256
--- dirserv.c	18 Oct 2005 17:09:57 -0000	1.255
+++ dirserv.c	18 Oct 2005 17:43:54 -0000	1.256
@@ -333,16 +333,6 @@
  *    Descriptor list
  */
 
-static smartlist_t *
-get_descriptor_list(void)
-{
-  routerlist_t *routerlist;
-  router_get_routerlist(&routerlist);
-  if (!routerlist)
-    return NULL;
-  return routerlist->routers;
-}
-
 /** Return -1 if <b>ri</b> has a private or otherwise bad address,
  * unless we're configured to not care. Return 0 if all ok. */
 static int
@@ -487,21 +477,18 @@
 {
   int i;
   int changed = 0;
-  smartlist_t *descriptor_list = get_descriptor_list();
-
-  if (!descriptor_list)
-    return;
+  routerlist_t *rl = router_get_routerlist();
 
-  for (i = 0; i < smartlist_len(descriptor_list); ++i) {
+  for (i = 0; i < smartlist_len(rl->routers); ++i) {
     const char *msg;
-    routerinfo_t *ent = smartlist_get(descriptor_list, i);
+    routerinfo_t *ent = smartlist_get(rl->routers, i);
     router_status_t r = dirserv_router_get_status(ent, &msg);
     switch (r) {
       case FP_REJECT:
         log(LOG_INFO, "Router '%s' is now rejected: %s",
             ent->nickname, msg?msg:"");
+        routerlist_remove(rl, ent, i--);
         routerinfo_free(ent);
-        smartlist_del(descriptor_list, i--);
         changed = 1;
         break;
       case FP_NAMED:
@@ -539,21 +526,15 @@
 char *
 dirserver_getinfo_unregistered(const char *question)
 {
-  int i;
   router_status_t r;
   smartlist_t *answerlist;
   char buf[1024];
   char *answer;
-  routerinfo_t *ent;
   int min_bw = atoi(question);
-  smartlist_t *descriptor_list = get_descriptor_list();
-
-  if (!descriptor_list)
-    return tor_strdup("");
+  routerlist_t *rl = router_get_routerlist();
 
   answerlist = smartlist_create();
-  for (i = 0; i < smartlist_len(descriptor_list); ++i) {
-    ent = smartlist_get(descriptor_list, i);
+  SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ent, {
     r = dirserv_router_get_status(ent, NULL);
     if (ent->bandwidthcapacity >= (size_t)min_bw &&
         ent->bandwidthrate >= (size_t)min_bw &&
@@ -565,7 +546,7 @@
                    ent->platform ? ent->platform : "");
       smartlist_add(answerlist, tor_strdup(buf));
     }
-  }
+  });
   answer = smartlist_join_strings(answerlist, "\r\n", 0, NULL);
   SMARTLIST_FOREACH(answerlist, char *, cp, tor_free(cp));
   smartlist_free(answerlist);
@@ -754,15 +735,12 @@
   char *buf = NULL;
   size_t buf_len;
   size_t identity_pkey_len;
-  smartlist_t *descriptor_list = get_descriptor_list();
+  routerlist_t *rl = router_get_routerlist();
 
   tor_assert(dir_out);
   *dir_out = NULL;
 
-  if (!descriptor_list)
-    return -1;
-
-  if (list_server_status(descriptor_list, &router_status))
+  if (list_server_status(rl->routers, &router_status))
     return -1;
 
   if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,
@@ -778,7 +756,7 @@
 
   buf_len = 2048+strlen(recommended_versions)+
     strlen(router_status);
-  SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
+  SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri,
                     buf_len += ri->signed_descriptor_len+1);
   buf = tor_malloc(buf_len);
   /* We'll be comparing against buf_len throughout the rest of the
@@ -800,7 +778,7 @@
   tor_free(identity_pkey);
 
   cp = buf + strlen(buf);
-  SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
+  SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri,
     {
       if (cp+ri->signed_descriptor_len+1 >= buf+buf_len)
         goto truncated;
@@ -1067,9 +1045,9 @@
   crypto_pk_env_t *private_key = get_identity_key();
   char *identity_pkey; /* Identity key, DER64-encoded. */
   size_t identity_pkey_len;
-  smartlist_t *descriptor_list = get_descriptor_list();
+  routerlist_t *rl = router_get_routerlist();
 
-  if (list_server_status(descriptor_list, &router_status)) {
+  if (list_server_status(rl->routers, &router_status)) {
     goto err;
   }
   if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,
@@ -1178,17 +1156,12 @@
   struct in_addr in;
   uint32_t addr;
   crypto_pk_env_t *private_key = get_identity_key();
-  smartlist_t *descriptor_list = get_descriptor_list();
+  routerlist_t *rl = router_get_routerlist();
   time_t now = time(NULL);
   int naming = options->NamingAuthoritativeDir;
   int versioning = options->VersioningAuthoritativeDir;
   const char *contact;
 
-  if (!descriptor_list) {
-    log_fn(LOG_WARN, "Couldn't get router list.");
-    goto done;
-  }
-
   if (resolve_my_address(options, &addr, &hostname)<0) {
     log_fn(LOG_WARN, "Couldn't resolve my hostname");
     goto done;
@@ -1217,7 +1190,7 @@
     contact = "(none)";
 
   len = 2048+strlen(client_versions)+strlen(server_versions)+identity_pkey_len*2;
-  len += (RS_ENTRY_LEN)*smartlist_len(descriptor_list) ;
+  len += (RS_ENTRY_LEN)*smartlist_len(rl->routers);
 
   status = tor_malloc(len);
   tor_snprintf(status, len,
@@ -1242,7 +1215,7 @@
   outp = status + strlen(status);
   endp = status + len;
 
-  SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri, {
+  SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
       int f_exit = router_is_general_exit(ri);
       int f_stable = !router_is_unreliable(ri, 1, 0);
       int f_fast = !router_is_unreliable(ri, 0, 1);
@@ -1345,9 +1318,10 @@
                                     the_v2_networkstatus_is_dirty,
                                     generate_v2_networkstatus,
                                     "network status list", 0);
-      log_fn(LOG_WARN, "Unable to generate an authoritative network status.");
       if (d)
         smartlist_add(result, d);
+      else
+        log_fn(LOG_WARN,"Unable to generate an authoritative network status.");
     }
   } else if (!strcmp(key, "all")) {
     strmap_iter_t *iter = strmap_iter_init(cached_v2_networkstatus);
@@ -1403,16 +1377,11 @@
 dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
   const char **msg)
 {
-  smartlist_t *complete_list = get_descriptor_list();
   *msg = NULL;
 
-  if (!complete_list) {
-    *msg = "No server descriptors available";
-    return -1;
-  }
-
   if (!strcmp(key, "/tor/server/all")) {
-    smartlist_add_all(descs_out, complete_list);
+    routerlist_t *rl = router_get_routerlist();
+    smartlist_add_all(descs_out, rl->routers);
   } else if (!strcmp(key, "/tor/server/authority")) {
     routerinfo_t *ri = router_get_my_routerinfo();
     if (ri)
@@ -1475,18 +1444,15 @@
                         int as_advertised)
 {
   int i;
-  smartlist_t *descriptor_list = get_descriptor_list();
+  routerlist_t *rl = router_get_routerlist();
   tor_assert(address);
   tor_assert(digest_rcvd);
   tor_assert(nickname_rcvd);
 
-  if (!descriptor_list)
-    return;
-
   // XXXXNM We should really have a better solution here than dropping
   // XXXXNM whole routers; otherwise, they come back way too easily.
-  for (i = 0; i < smartlist_len(descriptor_list); ++i) {
-    routerinfo_t *ri = smartlist_get(descriptor_list, i);
+  for (i = 0; i < smartlist_len(rl->routers); ++i) {
+    routerinfo_t *ri = smartlist_get(rl->routers, i);
     int drop = 0;
     if (strcasecmp(address, ri->address) || or_port != ri->or_port)
       continue;
@@ -1503,8 +1469,8 @@
       }
     }
     if (drop) {
+      routerlist_remove(rl, ri, i--);
       routerinfo_free(ri);
-      smartlist_del(descriptor_list, i--);
       directory_set_dirty();
     } else { /* correct nickname and digest. mark this router reachable! */
       log_fn(LOG_INFO,"Found router %s to be reachable. Yay.", ri->nickname);

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.719
retrieving revision 1.720
diff -u -d -r1.719 -r1.720
--- or.h	18 Oct 2005 17:09:57 -0000	1.719
+++ or.h	18 Oct 2005 17:43:54 -0000	1.720
@@ -2135,9 +2135,10 @@
 routerinfo_t *router_get_by_digest(const char *digest);
 routerinfo_t *router_get_by_descriptor_digest(const char *digest);
 int router_digest_is_trusted_dir(const char *digest);
-void router_get_routerlist(routerlist_t **prouterlist);
+routerlist_t *router_get_routerlist(void);
 void routerlist_reset_warnings(void);
 void routerlist_free(routerlist_t *routerlist);
+void routerlist_remove(routerlist_t *rl, routerinfo_t *ri, int idx);
 void routerinfo_free(routerinfo_t *router);
 void routerstatus_free(routerstatus_t *routerstatus);
 void networkstatus_free(networkstatus_t *networkstatus);

Index: router.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/router.c,v
retrieving revision 1.222
retrieving revision 1.223
diff -u -d -r1.222 -r1.223
--- router.c	17 Oct 2005 16:21:42 -0000	1.222
+++ router.c	18 Oct 2005 17:43:54 -0000	1.223
@@ -610,18 +610,13 @@
 void
 router_retry_connections(int force)
 {
-  int i;
   time_t now = time(NULL);
-  routerinfo_t *router;
-  routerlist_t *rl;
+  routerlist_t *rl = router_get_routerlist();
   or_options_t *options = get_options();
 
   tor_assert(server_mode(options));
 
-  router_get_routerlist(&rl);
-  if (!rl) return;
-  for (i=0;i < smartlist_len(rl->routers);i++) {
-    router = smartlist_get(rl->routers, i);
+  SMARTLIST_FOREACH(rl->routers, routerinfo_t *, router, {
     if (router_is_me(router))
       continue;
     if (!clique_mode(options) && !router_is_clique_mode(router))
@@ -637,7 +632,7 @@
         router->testing_since = now;
       connection_or_connect(router->addr, router->or_port, router->identity_digest);
     }
-  }
+  });
 }
 
 /** Return true iff this OR should try to keep connections open to all

Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerlist.c,v
retrieving revision 1.341
retrieving revision 1.342
diff -u -d -r1.341 -r1.342
--- routerlist.c	14 Oct 2005 04:56:20 -0000	1.341
+++ routerlist.c	18 Oct 2005 17:43:54 -0000	1.342
@@ -255,8 +255,7 @@
   int j;
 
   if (!routerlist) {
-    routerlist = tor_malloc_zero(sizeof(routerlist_t));
-    routerlist->routers = smartlist_create();
+    router_get_routerlist();
   }
 
   router_journal_len = router_store_len = 0;
@@ -1024,11 +1023,15 @@
   return NULL;
 }
 
-/** Set *<b>prouterlist</b> to the current list of all known routers. */
-void
-router_get_routerlist(routerlist_t **prouterlist)
+/** Return the current list of all known routers. */
+routerlist_t *
+router_get_routerlist(void)
 {
-  *prouterlist = routerlist;
+  if (!routerlist) {
+    routerlist = tor_malloc_zero(sizeof(routerlist_t));
+    routerlist->routers = smartlist_create();
+  }
+  return routerlist;
 }
 
 /** Free all storage held by <b>router</b>. */
@@ -1101,6 +1104,35 @@
   tor_free(rl);
 }
 
+/** Insert an item <b>ri</b> into the routerlist <b>rl</b>, updating indices
+ * as needed. */
+static void
+routerlist_insert(routerlist_t *rl, routerinfo_t *ri)
+{
+  smartlist_add(rl->routers, ri);
+}
+
+/** Remove an item <b>ri</b> into the routerlist <b>rl</b>, updating indices
+ * as needed. If <b>idx</b> is nonnegative and smartlist_get(rl-&gt;routers,
+ * idx) == ri, we don't need to do a linear search over the list to decide
+ * which to remove.  We fill the gap rl-&gt;routers with a later element in
+ * the list, if any exists. */
+void
+routerlist_remove(routerlist_t *rl, routerinfo_t *ri, int idx)
+{
+  if (idx < 0 || smartlist_get(rl->routers, idx) != ri) {
+    idx = -1;
+    SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
+                      if (r == ri) {
+                        idx = r_sl_idx;
+                        break;
+                      });
+    if (idx < 0)
+      return;
+  }
+  smartlist_del(rl->routers, idx);
+}
+
 /** Free all memory held by the rouerlist module */
 void
 routerlist_free_all(void)
@@ -1333,8 +1365,8 @@
                  old_router->nickname);
           connection_mark_for_close(conn);
         }
+        routerlist_remove(routerlist, old_router, i--);
         routerinfo_free(old_router);
-        smartlist_del_keeporder(routerlist->routers, i--);
       } else if (old_router->is_named) {
         /* Can't replace a verified router with an unverified one. */
         log_fn(LOG_DEBUG, "Skipping unverified entry for verified router '%s'",
@@ -1347,7 +1379,7 @@
   }
   /* We haven't seen a router with this name before.  Add it to the end of
    * the list. */
-  smartlist_add(routerlist->routers, router);
+  routerlist_insert(routerlist, router);
   if (!from_cache)
     router_append_to_journal(router->signed_descriptor,
                              router->signed_descriptor_len);
@@ -1373,8 +1405,8 @@
     if (router->published_on <= cutoff) {
       /* Too old.  Remove it. */
       log_fn(LOG_INFO,"Forgetting obsolete routerinfo for router '%s'", router->nickname);
+      routerlist_remove(routerlist, router, i--);
       routerinfo_free(router);
-      smartlist_del(routerlist->routers, i--);
     }
   }
 }



More information about the tor-commits mailing list