[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] [tor/master 02/15] Try to make most routerinfo_t interfaces const



Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Wed, 29 Sep 2010 00:38:32 -0400
Subject: Try to make most routerinfo_t interfaces const
Commit: d84d20cbb2c8ca8d248378ce21f0d3969f9b5ef8

---
 src/or/circuitbuild.c    |  100 +++++++++++++++----------------
 src/or/circuitbuild.h    |   12 ++--
 src/or/circuitlist.c     |    4 +-
 src/or/circuituse.c      |   13 ++--
 src/or/circuituse.h      |    2 +-
 src/or/command.c         |    2 +-
 src/or/connection_edge.c |   10 ++--
 src/or/connection_edge.h |    3 +-
 src/or/connection_or.c   |    4 +-
 src/or/control.c         |   34 ++++++-----
 src/or/directory.c       |    8 +-
 src/or/dirserv.c         |   44 +++++++-------
 src/or/dirserv.h         |    4 +-
 src/or/dns.c             |    2 +-
 src/or/main.c            |    4 +-
 src/or/networkstatus.c   |    2 +-
 src/or/policies.c        |    2 +-
 src/or/policies.h        |    2 +-
 src/or/relay.c           |    5 +-
 src/or/rendclient.c      |    2 +-
 src/or/rendservice.c     |    8 +-
 src/or/rephist.c         |    4 +-
 src/or/router.c          |   19 +++---
 src/or/router.h          |    4 +-
 src/or/routerlist.c      |  146 ++++++++++++++++++++++++---------------------
 src/or/routerlist.h      |   45 ++++++++-------
 26 files changed, 251 insertions(+), 234 deletions(-)

diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 473b28e..c8e9508 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -1401,7 +1401,7 @@ circuit_list_path_impl(origin_circuit_t *circ, int verbose, int verbose_names)
 
   hop = circ->cpath;
   do {
-    routerinfo_t *ri;
+    const routerinfo_t *ri;
     routerstatus_t *rs;
     char *elt;
     const char *id;
@@ -1500,13 +1500,13 @@ void
 circuit_rep_hist_note_result(origin_circuit_t *circ)
 {
   crypt_path_t *hop;
-  char *prev_digest = NULL;
-  routerinfo_t *router;
+  const char *prev_digest = NULL;
+  const routerinfo_t *router;
   hop = circ->cpath;
   if (!hop) /* circuit hasn't started building yet. */
     return;
   if (server_mode(get_options())) {
-    routerinfo_t *me = router_get_my_routerinfo();
+    const routerinfo_t *me = router_get_my_routerinfo();
     if (!me)
       return;
     prev_digest = me->cache_info.identity_digest;
@@ -1794,7 +1794,7 @@ int
 inform_testing_reachability(void)
 {
   char dirbuf[128];
-  routerinfo_t *me = router_get_my_routerinfo();
+  const routerinfo_t *me = router_get_my_routerinfo();
   if (!me)
     return 0;
   control_event_server_status(LOG_NOTICE,
@@ -1866,7 +1866,7 @@ int
 circuit_send_next_onion_skin(origin_circuit_t *circ)
 {
   crypt_path_t *hop;
-  routerinfo_t *router;
+  const routerinfo_t *router;
   char payload[2+4+DIGEST_LEN+ONIONSKIN_CHALLENGE_LEN];
   char *onionskin;
   size_t payload_len;
@@ -2479,7 +2479,7 @@ circuit_all_predicted_ports_handled(time_t now, int *need_uptime,
  * <b>needed_ports</b>, else return 0.
  */
 static int
-router_handles_some_port(routerinfo_t *router, smartlist_t *needed_ports)
+router_handles_some_port(const routerinfo_t *router, smartlist_t *needed_ports)
 {
   int i;
   uint16_t port;
@@ -2523,7 +2523,7 @@ ap_stream_wants_exit_attention(connection_t *conn)
  *
  * Return NULL if we can't find any suitable routers.
  */
-static routerinfo_t *
+static const routerinfo_t *
 choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
                                 int need_capacity)
 {
@@ -2533,7 +2533,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
   smartlist_t *connections;
   int best_support = -1;
   int n_best_support=0;
-  routerinfo_t *router;
+  const routerinfo_t *router;
   or_options_t *options = get_options();
 
   connections = get_connection_array();
@@ -2600,8 +2600,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
     }
     n_supported[i] = 0;
     /* iterate over connections */
-    SMARTLIST_FOREACH(connections, connection_t *, conn,
-    {
+    SMARTLIST_FOREACH_BEGIN(connections, connection_t *, conn) {
       if (!ap_stream_wants_exit_attention(conn))
         continue; /* Skip everything but APs in CIRCUIT_WAIT */
       if (connection_ap_can_use_exit(TO_EDGE_CONN(conn), router, 1)) {
@@ -2612,7 +2611,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
 //        log_fn(LOG_DEBUG,"%s (index %d) would reject this stream.",
 //               router->nickname, i);
       }
-    }); /* End looping over connections. */
+    } SMARTLIST_FOREACH_END(conn);
     if (n_pending_connections > 0 && n_supported[i] == 0) {
       /* Leave best_support at -1 if that's where it is, so we can
        * distinguish it later. */
@@ -2688,7 +2687,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
             (attempt || router_handles_some_port(router, needed_ports))) {
 //          log_fn(LOG_DEBUG,"Try %d: '%s' is a possibility.",
 //                 try, router->nickname);
-          smartlist_add(supporting, router);
+          smartlist_add(supporting, (void*)router);
         }
       }
 
@@ -2737,7 +2736,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
  * For client-side rendezvous circuits, choose a random node, weighted
  * toward the preferences in 'options'.
  */
-static routerinfo_t *
+static const routerinfo_t *
 choose_good_exit_server(uint8_t purpose, routerlist_t *dir,
                         int need_uptime, int need_capacity, int is_internal)
 {
@@ -2853,7 +2852,7 @@ onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit)
     log_info(LD_CIRC,"Using requested exit node '%s'", exit->nickname);
     exit = extend_info_dup(exit);
   } else { /* we have to decide one */
-    routerinfo_t *router =
+    const routerinfo_t *router =
       choose_good_exit_server(circ->_base.purpose, rl, state->need_uptime,
                               state->need_capacity, state->is_internal);
     if (!router) {
@@ -2967,14 +2966,14 @@ onion_append_to_cpath(crypt_path_t **head_ptr, crypt_path_t *new_hop)
  * circuit. In particular, make sure we don't pick the exit node or its
  * family, and make sure we don't duplicate any previous nodes or their
  * families. */
-static routerinfo_t *
+static const routerinfo_t *
 choose_good_middle_server(uint8_t purpose,
                           cpath_build_state_t *state,
                           crypt_path_t *head,
                           int cur_len)
 {
   int i;
-  routerinfo_t *r, *choice;
+  const routerinfo_t *r, *choice;
   crypt_path_t *cpath;
   smartlist_t *excluded;
   or_options_t *options = get_options();
@@ -2985,12 +2984,12 @@ choose_good_middle_server(uint8_t purpose,
   log_debug(LD_CIRC, "Contemplating intermediate hop: random choice.");
   excluded = smartlist_create();
   if ((r = build_state_get_exit_router(state))) {
-    smartlist_add(excluded, r);
+    smartlist_add(excluded, (void*) r);
     routerlist_add_family(excluded, r);
   }
   for (i = 0, cpath = head; i < cur_len; ++i, cpath=cpath->next) {
     if ((r = router_get_by_digest(cpath->extend_info->identity_digest))) {
-      smartlist_add(excluded, r);
+      smartlist_add(excluded, (void*)r);
       routerlist_add_family(excluded, r);
     }
   }
@@ -3014,10 +3013,10 @@ choose_good_middle_server(uint8_t purpose,
  * If <b>state</b> is NULL, we're choosing a router to serve as an entry
  * guard, not for any particular circuit.
  */
-static routerinfo_t *
+static const routerinfo_t *
 choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state)
 {
-  routerinfo_t *r, *choice;
+  const routerinfo_t *r, *choice;
   smartlist_t *excluded;
   or_options_t *options = get_options();
   router_crn_flags_t flags = CRN_NEED_GUARD;
@@ -3030,7 +3029,7 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state)
   excluded = smartlist_create();
 
   if (state && (r = build_state_get_exit_router(state))) {
-    smartlist_add(excluded, r);
+    smartlist_add(excluded, (void*)r);
     routerlist_add_family(excluded, r);
   }
   if (firewall_is_fascist_or()) {
@@ -3042,7 +3041,7 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state)
     for (i=0; i < smartlist_len(rl->routers); i++) {
       r = smartlist_get(rl->routers, i);
       if (!fascist_firewall_allows_or(r))
-        smartlist_add(excluded, r);
+        smartlist_add(excluded, (void*)r);
     }
   }
   /* and exclude current entry guards, if applicable */
@@ -3050,7 +3049,7 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state)
     SMARTLIST_FOREACH(entry_guards, entry_guard_t *, entry,
       {
         if ((r = router_get_by_digest(entry->identity))) {
-          smartlist_add(excluded, r);
+          smartlist_add(excluded, (void*)r);
           routerlist_add_family(excluded, r);
         }
       });
@@ -3107,11 +3106,11 @@ onion_extend_cpath(origin_circuit_t *circ)
   if (cur_len == state->desired_path_len - 1) { /* Picking last node */
     info = extend_info_dup(state->chosen_exit);
   } else if (cur_len == 0) { /* picking first node */
-    routerinfo_t *r = choose_good_entry_server(purpose, state);
+    const routerinfo_t *r = choose_good_entry_server(purpose, state);
     if (r)
       info = extend_info_from_router(r);
   } else {
-    routerinfo_t *r =
+    const routerinfo_t *r =
       choose_good_middle_server(purpose, state, circ->cpath, cur_len);
     if (r)
       info = extend_info_from_router(r);
@@ -3173,7 +3172,7 @@ extend_info_alloc(const char *nickname, const char *digest,
 /** Allocate and return a new extend_info_t that can be used to build a
  * circuit to or through the router <b>r</b>. */
 extend_info_t *
-extend_info_from_router(routerinfo_t *r)
+extend_info_from_router(const routerinfo_t *r)
 {
   tor_addr_t addr;
   tor_assert(r);
@@ -3212,7 +3211,7 @@ extend_info_dup(extend_info_t *info)
  * If there is no chosen exit, or if we don't know the routerinfo_t for
  * the chosen exit, return NULL.
  */
-routerinfo_t *
+const routerinfo_t *
 build_state_get_exit_router(cpath_build_state_t *state)
 {
   if (!state || !state->chosen_exit)
@@ -3241,7 +3240,7 @@ build_state_get_exit_nickname(cpath_build_state_t *state)
  */
 /*XXXX take a routerstatus, not a routerinfo. */
 static int
-entry_guard_set_status(entry_guard_t *e, routerinfo_t *ri,
+entry_guard_set_status(entry_guard_t *e, const routerinfo_t *ri,
                        time_t now, or_options_t *options, const char **reason)
 {
   char buf[HEX_DIGEST_LEN+1];
@@ -3317,11 +3316,11 @@ entry_is_time_to_retry(entry_guard_t *e, time_t now)
  *
  * If the answer is no, set *<b>msg</b> to an explanation of why.
  */
-static INLINE routerinfo_t *
+static INLINE const routerinfo_t *
 entry_is_live(entry_guard_t *e, int need_uptime, int need_capacity,
               int assume_reachable, const char **msg)
 {
-  routerinfo_t *r;
+  const routerinfo_t *r;
   or_options_t *options = get_options();
   tor_assert(msg);
 
@@ -3459,10 +3458,10 @@ control_event_guard_deferred(void)
  * If <b>chosen</b> is defined, use that one, and if it's not
  * already in our entry_guards list, put it at the *beginning*.
  * Else, put the one we pick at the end of the list. */
-static routerinfo_t *
+static const routerinfo_t *
 add_an_entry_guard(routerinfo_t *chosen, int reset_status)
 {
-  routerinfo_t *router;
+  const routerinfo_t *router;
   entry_guard_t *entry;
 
   if (chosen) {
@@ -3652,7 +3651,7 @@ entry_guards_compute_status(or_options_t *options, time_t now)
   reasons = digestmap_new();
   SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry)
     {
-      routerinfo_t *r = router_get_by_digest(entry->identity);
+      const routerinfo_t *r = router_get_by_digest(entry->identity);
       const char *reason = NULL;
       if (entry_guard_set_status(entry, r, now, options, &reason))
         changed = 1;
@@ -3673,7 +3672,7 @@ entry_guards_compute_status(or_options_t *options, time_t now)
     SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry) {
       const char *reason = digestmap_get(reasons, entry->identity);
       const char *live_msg = "";
-      routerinfo_t *r = entry_is_live(entry, 0, 1, 0, &live_msg);
+      const routerinfo_t *r = entry_is_live(entry, 0, 1, 0, &live_msg);
       log_info(LD_CIRC, "Summary: Entry '%s' is %s, %s%s%s, and %s%s.",
                entry->nickname,
                entry->unreachable_since ? "unreachable" : "reachable",
@@ -3790,7 +3789,7 @@ entry_guard_register_connect_status(const char *digest, int succeeded,
           break;
         if (e->made_contact) {
           const char *msg;
-          routerinfo_t *r = entry_is_live(e, 0, 1, 1, &msg);
+          const routerinfo_t *r = entry_is_live(e, 0, 1, 1, &msg);
           if (r && e->unreachable_since) {
             refuse_conn = 1;
             e->can_retry = 1;
@@ -3936,20 +3935,21 @@ entry_list_is_totally_static(or_options_t *options)
  * make sure not to pick this circuit's exit or any node in the
  * exit's family. If <b>state</b> is NULL, we're looking for a random
  * guard (likely a bridge). */
-routerinfo_t *
+const routerinfo_t *
 choose_random_entry(cpath_build_state_t *state)
 {
   or_options_t *options = get_options();
   smartlist_t *live_entry_guards = smartlist_create();
   smartlist_t *exit_family = smartlist_create();
-  routerinfo_t *chosen_exit = state?build_state_get_exit_router(state) : NULL;
-  routerinfo_t *r = NULL;
+  const routerinfo_t *chosen_exit =
+    state?build_state_get_exit_router(state) : NULL;
+  const routerinfo_t *r = NULL;
   int need_uptime = state ? state->need_uptime : 0;
   int need_capacity = state ? state->need_capacity : 0;
   int preferred_min, consider_exit_family = 0;
 
   if (chosen_exit) {
-    smartlist_add(exit_family, chosen_exit);
+    smartlist_add(exit_family, (void*) chosen_exit);
     routerlist_add_family(exit_family, chosen_exit);
     consider_exit_family = 1;
   }
@@ -3966,8 +3966,7 @@ choose_random_entry(cpath_build_state_t *state)
 
  retry:
   smartlist_clear(live_entry_guards);
-  SMARTLIST_FOREACH(entry_guards, entry_guard_t *, entry,
-    {
+  SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry) {
       const char *msg;
       r = entry_is_live(entry, need_uptime, need_capacity, 0, &msg);
       if (!r)
@@ -3988,7 +3987,7 @@ choose_random_entry(cpath_build_state_t *state)
                    "No relays from EntryNodes available. Using others.");
         }
       }
-      smartlist_add(live_entry_guards, r);
+      smartlist_add(live_entry_guards, (void*)r);
       if (!entry->made_contact) {
         /* Always start with the first not-yet-contacted entry
          * guard. Otherwise we might add several new ones, pick
@@ -3998,7 +3997,7 @@ choose_random_entry(cpath_build_state_t *state)
       }
       if (smartlist_len(live_entry_guards) >= options->NumEntryGuards)
         break; /* we have enough */
-    });
+  } SMARTLIST_FOREACH_END(entry);
 
   if (entry_list_is_constrained(options)) {
     /* If we prefer the entry nodes we've got, and we have at least
@@ -4308,7 +4307,7 @@ getinfo_helper_entry_guards(control_connection_t *conn,
         char *c = tor_malloc(len);
         const char *status = NULL;
         time_t when = 0;
-        routerinfo_t *ri;
+        const routerinfo_t *ri;
 
         if (!e->made_contact) {
           status = "never-connected";
@@ -4398,7 +4397,7 @@ get_configured_bridge_by_addr_port_digest(tor_addr_t *addr, uint16_t port,
 /** Wrapper around get_configured_bridge_by_addr_port_digest() to look
  * it up via router descriptor <b>ri</b>. */
 static bridge_info_t *
-get_configured_bridge_by_routerinfo(routerinfo_t *ri)
+get_configured_bridge_by_routerinfo(const routerinfo_t *ri)
 {
   tor_addr_t addr;
   tor_addr_from_ipv4h(&addr, ri->addr);
@@ -4408,7 +4407,7 @@ get_configured_bridge_by_routerinfo(routerinfo_t *ri)
 
 /** Return 1 if <b>ri</b> is one of our known bridges, else 0. */
 int
-routerinfo_is_a_configured_bridge(routerinfo_t *ri)
+routerinfo_is_a_configured_bridge(const routerinfo_t *ri)
 {
   return get_configured_bridge_by_routerinfo(ri) ? 1 : 0;
 }
@@ -4635,9 +4634,8 @@ entries_retry_helper(or_options_t *options, int act)
                   ROUTER_PURPOSE_BRIDGE : ROUTER_PURPOSE_GENERAL;
   if (!entry_guards)
     entry_guards = smartlist_create();
-  SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e,
-    {
-      ri = router_get_by_digest(e->identity);
+  SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, e) {
+      ri = router_get_mutable_by_digest(e->identity);
       if (ri && ri->purpose == purpose) {
         any_known = 1;
         if (ri->is_running)
@@ -4657,7 +4655,7 @@ entries_retry_helper(or_options_t *options, int act)
           e->bad_since = 0;
         }
       }
-    });
+  } SMARTLIST_FOREACH_END(e);
   log_debug(LD_DIR, "%d: any_known %d, any_running %d",
             act, any_known, any_running);
   return any_known && !any_running;
diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h
index 888bf9d..59e818d 100644
--- a/src/or/circuitbuild.h
+++ b/src/or/circuitbuild.h
@@ -44,10 +44,10 @@ void onion_append_to_cpath(crypt_path_t **head_ptr, crypt_path_t *new_hop);
 extend_info_t *extend_info_alloc(const char *nickname, const char *digest,
                                  crypto_pk_env_t *onion_key,
                                  const tor_addr_t *addr, uint16_t port);
-extend_info_t *extend_info_from_router(routerinfo_t *r);
+extend_info_t *extend_info_from_router(const routerinfo_t *r);
 extend_info_t *extend_info_dup(extend_info_t *info);
 void extend_info_free(extend_info_t *info);
-routerinfo_t *build_state_get_exit_router(cpath_build_state_t *state);
+const routerinfo_t *build_state_get_exit_router(cpath_build_state_t *state);
 const char *build_state_get_exit_nickname(cpath_build_state_t *state);
 
 void entry_guards_compute_status(or_options_t *options, time_t now);
@@ -55,7 +55,7 @@ int entry_guard_register_connect_status(const char *digest, int succeeded,
                                         int mark_relay_status, time_t now);
 void entry_nodes_should_be_added(void);
 int entry_list_is_constrained(or_options_t *options);
-routerinfo_t *choose_random_entry(cpath_build_state_t *state);
+const routerinfo_t *choose_random_entry(cpath_build_state_t *state);
 int entry_guards_parse_state(or_state_t *state, int set, char **msg);
 void entry_guards_update_state(or_state_t *state);
 int getinfo_helper_entry_guards(control_connection_t *conn,
@@ -63,9 +63,9 @@ int getinfo_helper_entry_guards(control_connection_t *conn,
                                 const char **errmsg);
 
 void clear_bridge_list(void);
-int routerinfo_is_a_configured_bridge(routerinfo_t *ri);
-void
-learned_router_identity(tor_addr_t *addr, uint16_t port, const char *digest);
+int routerinfo_is_a_configured_bridge(const routerinfo_t *ri);
+void learned_router_identity(tor_addr_t *addr, uint16_t port,
+                             const char *digest);
 void bridge_add_from_config(const tor_addr_t *addr, uint16_t port,
                             char *digest);
 void retry_bridge_descriptor_fetch_directly(const char *digest);
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index fb4b69b..96a06c0 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -946,9 +946,9 @@ circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info,
         if (info) {
           /* need to make sure we don't duplicate hops */
           crypt_path_t *hop = circ->cpath;
-          routerinfo_t *ri1 = router_get_by_digest(info->identity_digest);
+          const routerinfo_t *ri1 = router_get_by_digest(info->identity_digest);
           do {
-            routerinfo_t *ri2;
+            const routerinfo_t *ri2;
             if (!memcmp(hop->extend_info->identity_digest,
                         info->identity_digest, DIGEST_LEN))
               goto next;
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 3af0fb6..a2a09be 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -43,7 +43,7 @@ circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn,
                       int need_uptime, int need_internal,
                       time_t now)
 {
-  routerinfo_t *exitrouter;
+  const routerinfo_t *exitrouter;
   cpath_build_state_t *build_state;
   tor_assert(circ);
   tor_assert(conn);
@@ -473,7 +473,7 @@ circuit_stream_is_being_handled(edge_connection_t *conn,
                                 uint16_t port, int min)
 {
   circuit_t *circ;
-  routerinfo_t *exitrouter;
+  const routerinfo_t *exitrouter;
   int num=0;
   time_t now = time(NULL);
   int need_uptime = smartlist_string_num_isin(get_options()->LongLivedPorts,
@@ -1077,7 +1077,7 @@ static int did_circs_fail_last_period = 0;
  * details on arguments. */
 origin_circuit_t *
 circuit_launch_by_router(uint8_t purpose,
-                         routerinfo_t *exit, int flags)
+                         const routerinfo_t *exit, int flags)
 {
   origin_circuit_t *circ;
   extend_info_t *info = NULL;
@@ -1267,7 +1267,8 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
       }
     } else {
       /* XXXX022 Duplicates checks in connection_ap_handshake_attach_circuit */
-      routerinfo_t *router = router_get_by_nickname(conn->chosen_exit_name, 1);
+      const routerinfo_t *router =
+        router_get_by_nickname(conn->chosen_exit_name, 1);
       int opt = conn->chosen_exit_optional;
       if (router && !connection_ap_can_use_exit(conn, router, 0)) {
         log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP,
@@ -1317,7 +1318,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
      */
     if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_GENERAL) {
       if (conn->chosen_exit_name) {
-        routerinfo_t *r;
+        const routerinfo_t *r;
         int opt = conn->chosen_exit_optional;
         r = router_get_by_nickname(conn->chosen_exit_name, 1);
         if (r) {
@@ -1571,7 +1572,7 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn)
     origin_circuit_t *circ=NULL;
 
     if (conn->chosen_exit_name) {
-      routerinfo_t *router = router_get_by_nickname(conn->chosen_exit_name, 1);
+      const routerinfo_t *router = router_get_by_nickname(conn->chosen_exit_name, 1);
       int opt = conn->chosen_exit_optional;
       if (!router && !want_onehop) {
         /* We ran into this warning when trying to extend a circuit to a
diff --git a/src/or/circuituse.h b/src/or/circuituse.h
index 269b6c5..617685e 100644
--- a/src/or/circuituse.h
+++ b/src/or/circuituse.h
@@ -42,7 +42,7 @@ origin_circuit_t *circuit_launch_by_extend_info(uint8_t purpose,
                                                 extend_info_t *info,
                                                 int flags);
 origin_circuit_t *circuit_launch_by_router(uint8_t purpose,
-                                           routerinfo_t *exit, int flags);
+                                           const routerinfo_t *exit, int flags);
 void circuit_reset_failure_count(int timeout);
 int connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn,
                                                   origin_circuit_t *circ,
diff --git a/src/or/command.c b/src/or/command.c
index ea0bbea..6296c47 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -267,7 +267,7 @@ command_process_create_cell(cell_t *cell, or_connection_t *conn)
   }
 
   if (circuit_id_in_use_on_orconn(cell->circ_id, conn)) {
-    routerinfo_t *router = router_get_by_digest(conn->identity_digest);
+    const routerinfo_t *router = router_get_by_digest(conn->identity_digest);
     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
            "Received CREATE cell (circID %d) for known circ. "
            "Dropping (age %d).",
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 9627631..2b9ccc5 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -587,7 +587,7 @@ void
 circuit_discard_optional_exit_enclaves(extend_info_t *info)
 {
   edge_connection_t *edge_conn;
-  routerinfo_t *r1, *r2;
+  const routerinfo_t *r1, *r2;
 
   smartlist_t *conns = get_connection_array();
   SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
@@ -1575,7 +1575,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
         return -1;
       }
     } else {
-      routerinfo_t *r;
+      const routerinfo_t *r;
       conn->chosen_exit_name = tor_strdup(socks->address);
       r = router_get_by_nickname(conn->chosen_exit_name, 1);
       *socks->address = 0;
@@ -1631,7 +1631,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
 
       if (!conn->use_begindir && !conn->chosen_exit_name && !circ) {
         /* see if we can find a suitable enclave exit */
-        routerinfo_t *r =
+        const routerinfo_t *r =
           router_find_exact_exit_enclave(socks->address, socks->port);
         if (r) {
           log_info(LD_APP,
@@ -2896,7 +2896,7 @@ connection_edge_is_rendezvous_stream(edge_connection_t *conn)
  * this relay, return 0.
  */
 int
-connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit,
+connection_ap_can_use_exit(edge_connection_t *conn, const routerinfo_t *exit,
                            int excluded_means_no)
 {
   or_options_t *options = get_options();
@@ -2910,7 +2910,7 @@ connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit,
    * make sure the exit node of the existing circuit matches exactly.
    */
   if (conn->chosen_exit_name) {
-    routerinfo_t *chosen_exit =
+    const routerinfo_t *chosen_exit =
       router_get_by_nickname(conn->chosen_exit_name, 1);
     if (!chosen_exit || memcmp(chosen_exit->cache_info.identity_digest,
                                exit->cache_info.identity_digest, DIGEST_LEN)) {
diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h
index 0f7bf07..24ea327 100644
--- a/src/or/connection_edge.h
+++ b/src/or/connection_edge.h
@@ -47,7 +47,8 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ);
 int connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ);
 void connection_exit_connect(edge_connection_t *conn);
 int connection_edge_is_rendezvous_stream(edge_connection_t *conn);
-int connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit,
+int connection_ap_can_use_exit(edge_connection_t *conn,
+                               const routerinfo_t *exit,
                                int excluded_means_no);
 void connection_ap_expire_beginning(void);
 void connection_ap_attach_pending(void);
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 069c3e1..ee17282 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -438,7 +438,7 @@ connection_or_init_conn_from_address(or_connection_t *conn,
                                      const char *id_digest,
                                      int started_here)
 {
-  routerinfo_t *r = router_get_by_digest(id_digest);
+  const routerinfo_t *r = router_get_by_digest(id_digest);
   connection_or_set_identity_digest(conn, id_digest);
   connection_or_update_token_buckets_helper(conn, 1, get_options());
 
@@ -1491,7 +1491,7 @@ connection_or_send_netinfo(or_connection_t *conn)
 {
   cell_t cell;
   time_t now = time(NULL);
-  routerinfo_t *me;
+  const routerinfo_t *me;
   int len;
   char *out;
 
diff --git a/src/or/control.c b/src/or/control.c
index 37ebfd8..be887f4 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1344,7 +1344,7 @@ getinfo_helper_misc(control_connection_t *conn, const char *question,
   } else if (!strcmp(question, "dir-usage")) {
     *answer = directory_dump_request_log();
   } else if (!strcmp(question, "fingerprint")) {
-    routerinfo_t *me = router_get_my_routerinfo();
+    const routerinfo_t *me = router_get_my_routerinfo();
     if (!me) {
       *errmsg = "No routerdesc known; am I really a server?";
       return -1;
@@ -1366,8 +1366,9 @@ getinfo_helper_misc(control_connection_t *conn, const char *question,
  * NOTE: <b>ri_body</b> is as returned by signed_descriptor_get_body: it might
  * not be NUL-terminated. */
 static char *
-munge_extrainfo_into_routerinfo(const char *ri_body, signed_descriptor_t *ri,
-                                signed_descriptor_t *ei)
+munge_extrainfo_into_routerinfo(const char *ri_body,
+                                const signed_descriptor_t *ri,
+                                const signed_descriptor_t *ei)
 {
   char *out = NULL, *outp;
   int i;
@@ -1412,16 +1413,17 @@ getinfo_helper_dir(control_connection_t *control_conn,
                    const char *question, char **answer,
                    const char **errmsg)
 {
+  const routerinfo_t *ri;
   (void) control_conn;
   if (!strcmpstart(question, "desc/id/")) {
-    routerinfo_t *ri = router_get_by_hexdigest(question+strlen("desc/id/"));
+    ri = router_get_by_hexdigest(question+strlen("desc/id/"));
     if (ri) {
       const char *body = signed_descriptor_get_body(&ri->cache_info);
       if (body)
         *answer = tor_strndup(body, ri->cache_info.signed_descriptor_len);
     }
   } else if (!strcmpstart(question, "desc/name/")) {
-    routerinfo_t *ri = router_get_by_nickname(question+strlen("desc/name/"),1);
+    ri = router_get_by_nickname(question+strlen("desc/name/"),1);
     if (ri) {
       const char *body = signed_descriptor_get_body(&ri->cache_info);
       if (body)
@@ -1431,7 +1433,7 @@ getinfo_helper_dir(control_connection_t *control_conn,
     routerlist_t *routerlist = router_get_routerlist();
     smartlist_t *sl = smartlist_create();
     if (routerlist && routerlist->routers) {
-      SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, ri,
+      SMARTLIST_FOREACH(routerlist->routers, const routerinfo_t *, ri,
       {
         const char *body = signed_descriptor_get_body(&ri->cache_info);
         if (body)
@@ -1447,7 +1449,7 @@ getinfo_helper_dir(control_connection_t *control_conn,
     routerlist_t *routerlist = router_get_routerlist();
     smartlist_t *sl = smartlist_create();
     if (routerlist && routerlist->routers) {
-      SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, ri,
+      SMARTLIST_FOREACH(routerlist->routers, const routerinfo_t *, ri,
       {
         const char *body = signed_descriptor_get_body(&ri->cache_info);
         signed_descriptor_t *ei = extrainfo_get_by_descriptor_digest(
@@ -1465,8 +1467,8 @@ getinfo_helper_dir(control_connection_t *control_conn,
     SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
     smartlist_free(sl);
   } else if (!strcmpstart(question, "desc-annotations/id/")) {
-    routerinfo_t *ri = router_get_by_hexdigest(question+
-                                               strlen("desc-annotations/id/"));
+    ri = router_get_by_hexdigest(question+
+                                 strlen("desc-annotations/id/"));
     if (ri) {
       const char *annotations =
         signed_descriptor_get_annotations(&ri->cache_info);
@@ -2168,12 +2170,12 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
   routers = smartlist_create();
   SMARTLIST_FOREACH(router_nicknames, const char *, n,
   {
-    routerinfo_t *r = router_get_by_nickname(n, 1);
+    const routerinfo_t *r = router_get_by_nickname(n, 1);
     if (!r) {
       connection_printf_to_buf(conn, "552 No such router \"%s\"\r\n", n);
       goto done;
     }
-    smartlist_add(routers, r);
+    smartlist_add(routers, (void*) r);
   });
   if (!smartlist_len(routers)) {
     connection_write_str_to_buf("512 No router names provided\r\n", conn);
@@ -2186,7 +2188,7 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
   }
 
   /* now circ refers to something that is ready to be extended */
-  SMARTLIST_FOREACH(routers, routerinfo_t *, r,
+  SMARTLIST_FOREACH(routers, const routerinfo_t *, r,
   {
     extend_info_t *info = extend_info_from_router(r);
     circuit_append_new_exit(circ, info);
@@ -2338,8 +2340,8 @@ handle_control_attachstream(control_connection_t *conn, uint32_t len,
   }
   /* Is this a single hop circuit? */
   if (circ && (circuit_get_cpath_len(circ)<2 || hop==1)) {
-    routerinfo_t *r = NULL;
-    char* exit_digest;
+    const routerinfo_t *r = NULL;
+    char *exit_digest;
     if (circ->build_state &&
         circ->build_state->chosen_exit &&
         !tor_digest_is_zero(circ->build_state->chosen_exit->identity_digest)) {
@@ -3175,7 +3177,7 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
 static void
 orconn_target_get_name(char *name, size_t len, or_connection_t *conn)
 {
-  routerinfo_t *ri = router_get_by_digest(conn->identity_digest);
+  const routerinfo_t *ri = router_get_by_digest(conn->identity_digest);
   if (ri) {
     tor_assert(len > MAX_VERBOSE_NICKNAME_LEN);
     router_get_verbose_nickname(name, ri);
@@ -3720,7 +3722,7 @@ control_event_guard(const char *nickname, const char *digest,
 
   {
     char buf[MAX_VERBOSE_NICKNAME_LEN+1];
-    routerinfo_t *ri = router_get_by_digest(digest);
+    const routerinfo_t *ri = router_get_by_digest(digest);
     if (ri) {
       router_get_verbose_nickname(buf, ri);
     } else {
diff --git a/src/or/directory.c b/src/or/directory.c
index 657b210..0b40b29 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -219,7 +219,7 @@ dir_conn_purpose_to_string(int purpose)
 int
 router_supports_extrainfo(const char *identity_digest, int is_authority)
 {
-  routerinfo_t *ri = router_get_by_digest(identity_digest);
+  const routerinfo_t *ri = router_get_by_digest(identity_digest);
 
   if (ri) {
     if (ri->caches_extra_info)
@@ -400,7 +400,7 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
        * possible directory question. This won't be true forever. -RD */
       /* It certainly is not true with conditional consensus downloading,
        * so, for now, never assume the server supports that. */
-      routerinfo_t *ri = choose_random_entry(NULL);
+      const routerinfo_t *ri = choose_random_entry(NULL);
       if (ri) {
         tor_addr_t addr;
         tor_addr_from_ipv4h(&addr, ri->addr);
@@ -522,7 +522,7 @@ directory_initiate_command_routerstatus_rend(routerstatus_t *status,
                                              time_t if_modified_since,
                                              const rend_data_t *rend_query)
 {
-  routerinfo_t *router;
+  const routerinfo_t *router;
   char address_buf[INET_NTOA_BUF_LEN+1];
   struct in_addr in;
   const char *address;
@@ -590,7 +590,7 @@ directory_conn_is_self_reachability_test(dir_connection_t *conn)
 {
   if (conn->requested_resource &&
       !strcmpstart(conn->requested_resource,"authority")) {
-    routerinfo_t *me = router_get_my_routerinfo();
+    const routerinfo_t *me = router_get_my_routerinfo();
     if (me &&
         router_digest_is_me(conn->identity_digest) &&
         tor_addr_eq_ipv4h(&conn->_base.addr, me->addr) && /*XXXX prop 118*/
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 75e3e86..148147b 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -74,7 +74,8 @@ dirserv_get_status_impl(const char *fp, const char *nickname,
                         const char *platform, const char *contact,
                         const char **msg, int should_log);
 static void clear_cached_dir(cached_dir_t *d);
-static signed_descriptor_t *get_signed_descriptor_by_fp(const char *fp,
+static const signed_descriptor_t *get_signed_descriptor_by_fp(
+                                                        const char *fp,
                                                         int extrainfo,
                                                         time_t publish_cutoff);
 static int dirserv_add_extrainfo(extrainfo_t *ei, const char **msg);
@@ -707,7 +708,7 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source)
    * from this server.  (We do this here and not in router_add_to_routerlist
    * because we want to be able to accept the newest router descriptor that
    * another authority has, so we all converge on the same one.) */
-  ri_old = router_get_by_digest(ri->cache_info.identity_digest);
+  ri_old = router_get_mutable_by_digest(ri->cache_info.identity_digest);
   if (ri_old && ri_old->cache_info.published_on < ri->cache_info.published_on
       && router_differences_are_cosmetic(ri_old, ri)
       && !router_is_me(ri)) {
@@ -767,7 +768,7 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source)
 static was_router_added_t
 dirserv_add_extrainfo(extrainfo_t *ei, const char **msg)
 {
-  routerinfo_t *ri;
+  const routerinfo_t *ri;
   int r;
   tor_assert(msg);
   *msg = NULL;
@@ -1151,7 +1152,7 @@ dirserv_dump_directory_to_string(char **dir_out,
 int
 directory_fetches_from_authorities(or_options_t *options)
 {
-  routerinfo_t *me;
+  const routerinfo_t *me;
   uint32_t addr;
   int refuseunknown;
   if (options->FetchDirInfoEarly)
@@ -2026,7 +2027,7 @@ routerstatus_format_entry(char *buf, size_t buf_len,
   }
 
   if (format != NS_V2) {
-    routerinfo_t* desc = router_get_by_digest(rs->identity_digest);
+    const routerinfo_t* desc = router_get_by_digest(rs->identity_digest);
     uint32_t bw;
 
     if (format != NS_CONTROL_PORT) {
@@ -2879,7 +2880,7 @@ dirserv_get_networkstatus_v2_fingerprints(smartlist_t *result,
 
   if (!strcmp(key,"authority")) {
     if (authdir_mode_v2(get_options())) {
-      routerinfo_t *me = router_get_my_routerinfo();
+      const routerinfo_t *me = router_get_my_routerinfo();
       if (me)
         smartlist_add(result,
                       tor_memdup(me->cache_info.identity_digest, DIGEST_LEN));
@@ -2965,7 +2966,7 @@ dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
                       smartlist_add(fps_out,
                       tor_memdup(r->cache_info.identity_digest, DIGEST_LEN)));
   } else if (!strcmp(key, "authority")) {
-    routerinfo_t *ri = router_get_my_routerinfo();
+    const routerinfo_t *ri = router_get_my_routerinfo();
     if (ri)
       smartlist_add(fps_out,
                     tor_memdup(ri->cache_info.identity_digest, DIGEST_LEN));
@@ -2985,8 +2986,8 @@ dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
 
   if (for_unencrypted_conn) {
     /* Remove anything that insists it not be sent unencrypted. */
-    SMARTLIST_FOREACH(fps_out, char *, cp, {
-        signed_descriptor_t *sd;
+    SMARTLIST_FOREACH_BEGIN(fps_out, char *, cp) {
+        const signed_descriptor_t *sd;
         if (by_id)
           sd = get_signed_descriptor_by_fp(cp,is_extrainfo,0);
         else if (is_extrainfo)
@@ -2997,7 +2998,7 @@ dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
           tor_free(cp);
           SMARTLIST_DEL_CURRENT(fps_out, cp);
         }
-      });
+    } SMARTLIST_FOREACH_END(cp);
   }
 
   if (!smartlist_len(fps_out)) {
@@ -3036,9 +3037,9 @@ dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
     SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
                       smartlist_add(descs_out, &(r->cache_info)));
   } else if (!strcmp(key, "/tor/server/authority")) {
-    routerinfo_t *ri = router_get_my_routerinfo();
+    const routerinfo_t *ri = router_get_my_routerinfo();
     if (ri)
-      smartlist_add(descs_out, &(ri->cache_info));
+      smartlist_add(descs_out, (void*) &(ri->cache_info));
   } else if (!strcmpstart(key, "/tor/server/d/")) {
     smartlist_t *digests = smartlist_create();
     key += strlen("/tor/server/d/");
@@ -3062,17 +3063,17 @@ dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
        {
          if (router_digest_is_me(d)) {
            /* make sure desc_routerinfo exists */
-           routerinfo_t *ri = router_get_my_routerinfo();
+           const routerinfo_t *ri = router_get_my_routerinfo();
            if (ri)
-             smartlist_add(descs_out, &(ri->cache_info));
+             smartlist_add(descs_out, (void*) &(ri->cache_info));
          } else {
-           routerinfo_t *ri = router_get_by_digest(d);
+           const routerinfo_t *ri = router_get_by_digest(d);
            /* Don't actually serve a descriptor that everyone will think is
             * expired.  This is an (ugly) workaround to keep buggy 0.1.1.10
             * Tors from downloading descriptors that they will throw away.
             */
            if (ri && ri->cache_info.published_on > cutoff)
-             smartlist_add(descs_out, &(ri->cache_info));
+             smartlist_add(descs_out, (void*) &(ri->cache_info));
          }
        });
     SMARTLIST_FOREACH(digests, char *, d, tor_free(d));
@@ -3130,7 +3131,8 @@ dirserv_orconn_tls_done(const char *address,
  * an upload or a download.  Used to decide whether to relaunch reachability
  * testing for the server. */
 int
-dirserv_should_launch_reachability_test(routerinfo_t *ri, routerinfo_t *ri_old)
+dirserv_should_launch_reachability_test(const routerinfo_t *ri,
+                                        const routerinfo_t *ri_old)
 {
   if (!authdir_mode_handles_descs(get_options(), ri->purpose))
     return 0;
@@ -3254,7 +3256,7 @@ dirserv_remove_old_statuses(smartlist_t *fps, time_t cutoff)
  * its extra-info document if <b>extrainfo</b> is true. Return
  * NULL if not found or if the descriptor is older than
  * <b>publish_cutoff</b>. */
-static signed_descriptor_t *
+static const signed_descriptor_t *
 get_signed_descriptor_by_fp(const char *fp, int extrainfo,
                             time_t publish_cutoff)
 {
@@ -3264,7 +3266,7 @@ get_signed_descriptor_by_fp(const char *fp, int extrainfo,
     else
       return &(router_get_my_routerinfo()->cache_info);
   } else {
-    routerinfo_t *ri = router_get_by_digest(fp);
+    const routerinfo_t *ri = router_get_by_digest(fp);
     if (ri &&
         ri->cache_info.published_on > publish_cutoff) {
       if (extrainfo)
@@ -3332,7 +3334,7 @@ dirserv_estimate_data_size(smartlist_t *fps, int is_serverdescs,
   tor_assert(fps);
   if (is_serverdescs) {
     int n = smartlist_len(fps);
-    routerinfo_t *me = router_get_my_routerinfo();
+    const routerinfo_t *me = router_get_my_routerinfo();
     result = (me?me->cache_info.signed_descriptor_len:2048) * n;
     if (compressed)
       result /= 2; /* observed compressibility is between 35 and 55%. */
@@ -3399,7 +3401,7 @@ connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
          connection_get_outbuf_len(TO_CONN(conn)) < DIRSERV_BUFFER_MIN) {
     const char *body;
     char *fp = smartlist_pop_last(conn->fingerprint_stack);
-    signed_descriptor_t *sd = NULL;
+    const signed_descriptor_t *sd = NULL;
     if (by_fp) {
       sd = get_signed_descriptor_by_fp(fp, extra, publish_cutoff);
     } else {
diff --git a/src/or/dirserv.h b/src/or/dirserv.h
index 94e4e81..9be4935 100644
--- a/src/or/dirserv.h
+++ b/src/or/dirserv.h
@@ -99,8 +99,8 @@ void dirserv_orconn_tls_done(const char *address,
                              uint16_t or_port,
                              const char *digest_rcvd,
                              int as_advertised);
-int dirserv_should_launch_reachability_test(routerinfo_t *ri,
-                                            routerinfo_t *ri_old);
+int dirserv_should_launch_reachability_test(const routerinfo_t *ri,
+                                            const routerinfo_t *ri_old);
 void dirserv_single_reachability_test(time_t now, routerinfo_t *router);
 void dirserv_test_reachability(time_t now);
 int authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
diff --git a/src/or/dns.c b/src/or/dns.c
index 4e319b7..83d4791 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -668,7 +668,7 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
   cached_resolve_t *resolve;
   cached_resolve_t search;
   pending_connection_t *pending_connection;
-  routerinfo_t *me;
+  const routerinfo_t *me;
   tor_addr_t addr;
   time_t now = time(NULL);
   uint8_t is_reverse = 0;
diff --git a/src/or/main.c b/src/or/main.c
index 072fd93..4c305ca 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1273,7 +1273,7 @@ run_scheduled_events(time_t now)
         /* If we haven't checked for 12 hours and our bandwidth estimate is
          * low, do another bandwidth test. This is especially important for
          * bridges, since they might go long periods without much use. */
-        routerinfo_t *me = router_get_my_routerinfo();
+        const routerinfo_t *me = router_get_my_routerinfo();
         if (time_to_recheck_bandwidth && me &&
             me->bandwidthcapacity < me->bandwidthrate &&
             me->bandwidthcapacity < 51200) {
@@ -1474,7 +1474,7 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
       (stats_n_seconds_working+seconds_elapsed) /
         TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) {
     /* every 20 minutes, check and complain if necessary */
-    routerinfo_t *me = router_get_my_routerinfo();
+    const routerinfo_t *me = router_get_my_routerinfo();
     if (me && !check_whether_orport_reachable()) {
       log_warn(LD_CONFIG,"Your server (%s:%d) has not managed to confirm that "
                "its ORPort is reachable. Please check your firewalls, ports, "
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index c41bcab..3451a2d 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -2083,7 +2083,7 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
       /* If we _are_ an authority, we should check whether this router
        * is one that will cause us to need a reachability test. */
       routerinfo_t *old_router =
-        router_get_by_digest(router->cache_info.identity_digest);
+        router_get_mutable_by_digest(router->cache_info.identity_digest);
       if (old_router != router) {
         router->needs_retest_if_added =
           dirserv_should_launch_reachability_test(router, old_router);
diff --git a/src/or/policies.c b/src/or/policies.c
index 4fd0904..b4d3595 100644
--- a/src/or/policies.c
+++ b/src/or/policies.c
@@ -261,7 +261,7 @@ fascist_firewall_allows_address_or(const tor_addr_t *addr, uint16_t port)
 /** Return true iff we think our firewall will let us make an OR connection to
  * <b>ri</b>. */
 int
-fascist_firewall_allows_or(routerinfo_t *ri)
+fascist_firewall_allows_or(const routerinfo_t *ri)
 {
   /* XXXX proposal 118 */
   tor_addr_t addr;
diff --git a/src/or/policies.h b/src/or/policies.h
index dd46f4d..4a34745 100644
--- a/src/or/policies.h
+++ b/src/or/policies.h
@@ -19,7 +19,7 @@
 
 int firewall_is_fascist_or(void);
 int fascist_firewall_allows_address_or(const tor_addr_t *addr, uint16_t port);
-int fascist_firewall_allows_or(routerinfo_t *ri);
+int fascist_firewall_allows_or(const routerinfo_t *ri);
 int fascist_firewall_allows_address_dir(const tor_addr_t *addr, uint16_t port);
 int dir_policy_permits_address(const tor_addr_t *addr);
 int socks_policy_permits_address(const tor_addr_t *addr);
diff --git a/src/or/relay.c b/src/or/relay.c
index f9a44cf..48948f0 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -720,11 +720,12 @@ connection_ap_process_end_not_open(
   if (rh->length > 0 && edge_reason_is_retriable(reason) &&
       !connection_edge_is_rendezvous_stream(conn)  /* avoid retry if rend */
       ) {
+    const char *chosen_exit_digest =
+      circ->build_state->chosen_exit->identity_digest;
     log_info(LD_APP,"Address '%s' refused due to '%s'. Considering retrying.",
              safe_str(conn->socks_request->address),
              stream_end_reason_to_string(reason));
-    exitrouter =
-      router_get_by_digest(circ->build_state->chosen_exit->identity_digest);
+    exitrouter = router_get_mutable_by_digest(chosen_exit_digest);
     switch (reason) {
       case END_STREAM_REASON_EXITPOLICY:
         if (rh->length >= 5) {
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index 68abb88..67bd55a 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -738,7 +738,7 @@ rend_client_get_random_intro(const rend_data_t *rend_query)
   int i;
   rend_cache_entry_t *entry;
   rend_intro_point_t *intro;
-  routerinfo_t *router;
+  const routerinfo_t *router;
 
   if (rend_cache_lookup_entry(rend_query->onion_address, -1, &entry) < 1) {
     log_warn(LD_REND,
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index b0d7915..f6769d5 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -1001,7 +1001,7 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request,
   } else {
     char *rp_nickname;
     size_t nickname_field_len;
-    routerinfo_t *router;
+    const routerinfo_t *router;
     int version;
     if (*buf == 1) {
       rp_nickname = buf+1;
@@ -1754,7 +1754,7 @@ void
 rend_services_introduce(void)
 {
   int i,j,r;
-  routerinfo_t *router;
+  const routerinfo_t *router;
   rend_service_t *service;
   rend_intro_point_t *intro;
   int changed, prev_intro_nodes;
@@ -1807,7 +1807,7 @@ rend_services_introduce(void)
         changed = 1;
       }
       if (router)
-        smartlist_add(intro_routers, router);
+        smartlist_add(intro_routers, (void*)router);
     }
 
     /* We have enough intro points, and the intro points we thought we had were
@@ -1848,7 +1848,7 @@ rend_services_introduce(void)
         break;
       }
       changed = 1;
-      smartlist_add(intro_routers, router);
+      smartlist_add(intro_routers, (void*)router);
       intro = tor_malloc_zero(sizeof(rend_intro_point_t));
       intro->extend_info = extend_info_from_router(router);
       intro->intro_key = crypto_new_pk_env();
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 056fc5c..d998e87 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -579,7 +579,7 @@ rep_hist_dump_stats(time_t now, int severity)
   size_t len;
   int ret;
   unsigned long upt, downt;
-  routerinfo_t *r;
+  const routerinfo_t *r;
 
   rep_history_clean(now - get_options()->RephistTrackTime);
 
@@ -871,7 +871,7 @@ rep_hist_get_router_stability_doc(time_t now)
   }
 
   DIGESTMAP_FOREACH(history_map, id, or_history_t *, hist) {
-    routerinfo_t *ri;
+    const routerinfo_t *ri;
     char dbuf[BASE64_DIGEST_LEN+1];
     char header_buf[512];
     char *info;
diff --git a/src/or/router.c b/src/or/router.c
index 8b3a184..dfb2f06 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -773,7 +773,7 @@ decide_to_advertise_dirport(or_options_t *options, uint16_t dir_port)
 void
 consider_testing_reachability(int test_or, int test_dir)
 {
-  routerinfo_t *me = router_get_my_routerinfo();
+  const routerinfo_t *me = router_get_my_routerinfo();
   int orport_reachable = check_whether_orport_reachable();
   tor_addr_t addr;
   if (!me)
@@ -808,7 +808,7 @@ void
 router_orport_found_reachable(void)
 {
   if (!can_reach_or_port) {
-    routerinfo_t *me = router_get_my_routerinfo();
+    const routerinfo_t *me = router_get_my_routerinfo();
     log_notice(LD_OR,"Self-testing indicates your ORPort is reachable from "
                "the outside. Excellent.%s",
                get_options()->_PublishServerDescriptor != NO_AUTHORITY ?
@@ -831,7 +831,7 @@ void
 router_dirport_found_reachable(void)
 {
   if (!can_reach_dir_port) {
-    routerinfo_t *me = router_get_my_routerinfo();
+    const routerinfo_t *me = router_get_my_routerinfo();
     log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable "
                "from the outside. Excellent.");
     can_reach_dir_port = 1;
@@ -1093,7 +1093,7 @@ static int desc_needs_upload = 0;
 void
 router_upload_dir_desc_to_dirservers(int force)
 {
-  routerinfo_t *ri;
+  const routerinfo_t *ri;
   extrainfo_t *ei;
   char *msg;
   size_t desc_len, extra_len = 0, total_len;
@@ -1186,7 +1186,7 @@ router_extrainfo_digest_is_me(const char *digest)
 
 /** A wrapper around router_digest_is_me(). */
 int
-router_is_me(routerinfo_t *router)
+router_is_me(const routerinfo_t *router)
 {
   return router_digest_is_me(router->cache_info.identity_digest);
 }
@@ -1205,7 +1205,7 @@ router_fingerprint_is_me(const char *fp)
 
 /** Return a routerinfo for this OR, rebuilding a fresh one if
  * necessary.  Return NULL on error, or if called on an OP. */
-routerinfo_t *
+const routerinfo_t *
 router_get_my_routerinfo(void)
 {
   if (!server_mode(get_options()))
@@ -1348,9 +1348,8 @@ router_rebuild_descriptor(int force)
     ri->declared_family = smartlist_create();
     smartlist_split_string(family, options->MyFamily, ",",
       SPLIT_SKIP_SPACE|SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
-    SMARTLIST_FOREACH(family, char *, name,
-     {
-       routerinfo_t *member;
+    SMARTLIST_FOREACH_BEGIN(family, char *, name) {
+        const routerinfo_t *member;
        if (!strcasecmp(name, options->Nickname))
          member = ri;
        else
@@ -1386,7 +1385,7 @@ router_rebuild_descriptor(int force)
            smartlist_string_remove(warned_nonexistent_family, name);
        }
        tor_free(name);
-     });
+    } SMARTLIST_FOREACH_END(name);
 
     /* remove duplicates from the list */
     smartlist_sort_strings(ri->declared_family);
diff --git a/src/or/router.h b/src/or/router.h
index c17fc78..13ea6f8 100644
--- a/src/or/router.h
+++ b/src/or/router.h
@@ -62,12 +62,12 @@ void router_new_address_suggestion(const char *suggestion,
                                    const dir_connection_t *d_conn);
 int router_compare_to_my_exit_policy(edge_connection_t *conn);
 int router_my_exit_policy_is_reject_star(void);
-routerinfo_t *router_get_my_routerinfo(void);
+const routerinfo_t *router_get_my_routerinfo(void);
 extrainfo_t *router_get_my_extrainfo(void);
 const char *router_get_my_descriptor(void);
 int router_digest_is_me(const char *digest);
 int router_extrainfo_digest_is_me(const char *digest);
-int router_is_me(routerinfo_t *router);
+int router_is_me(const routerinfo_t *router);
 int router_fingerprint_is_me(const char *fp);
 int router_pick_published_address(or_options_t *options, uint32_t *addr);
 int router_rebuild_descriptor(int force);
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 3c38f9c..d2edead 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -44,12 +44,14 @@ static routerstatus_t *router_pick_directory_server_impl(
 static routerstatus_t *router_pick_trusteddirserver_impl(
                           authority_type_t auth, int flags, int *n_busy_out);
 static void mark_all_trusteddirservers_up(void);
-static int router_nickname_matches(routerinfo_t *router, const char *nickname);
+static int router_nickname_matches(const routerinfo_t *router,
+                                   const char *nickname);
 static void trusted_dir_server_free(trusted_dir_server_t *ds);
 static int signed_desc_digest_is_recognized(signed_descriptor_t *desc);
 static void update_router_have_minimum_dir_info(void);
-static const char *signed_descriptor_get_body_impl(signed_descriptor_t *desc,
-                                                   int with_annotations);
+static const char *signed_descriptor_get_body_impl(
+                                              const signed_descriptor_t *desc,
+                                              int with_annotations);
 static void list_pending_downloads(digestmap_t *result,
                                    int purpose, const char *prefix);
 
@@ -599,7 +601,7 @@ router_should_rebuild_store(desc_store_t *store)
 /** Return the desc_store_t in <b>rl</b> that should be used to store
  * <b>sd</b>. */
 static INLINE desc_store_t *
-desc_get_store(routerlist_t *rl, signed_descriptor_t *sd)
+desc_get_store(routerlist_t *rl, const signed_descriptor_t *sd)
 {
   if (sd->is_extrainfo)
     return &rl->extrainfo_store;
@@ -957,7 +959,7 @@ int
 router_get_my_share_of_directory_requests(double *v2_share_out,
                                           double *v3_share_out)
 {
-  routerinfo_t *me = router_get_my_routerinfo();
+  const routerinfo_t *me = router_get_my_routerinfo();
   routerstatus_t *rs;
   const int pds_flags = PDS_ALLOW_SELF|PDS_IGNORE_FASCISTFIREWALL;
   *v2_share_out = *v3_share_out = 0.0;
@@ -1167,7 +1169,7 @@ router_pick_trusteddirserver_impl(authority_type_t type, int flags,
 {
   smartlist_t *direct, *tunnel;
   smartlist_t *overloaded_direct, *overloaded_tunnel;
-  routerinfo_t *me = router_get_my_routerinfo();
+  const routerinfo_t *me = router_get_my_routerinfo();
   routerstatus_t *result;
   time_t now = time(NULL);
   const int requireother = ! (flags & PDS_ALLOW_SELF);
@@ -1299,7 +1301,7 @@ router_reset_status_download_failures(void)
 
 /** Return true iff router1 and router2 have the same /16 network. */
 static INLINE int
-routers_in_same_network_family(routerinfo_t *r1, routerinfo_t *r2)
+routers_in_same_network_family(const routerinfo_t *r1, const routerinfo_t *r2)
 {
   return (r1->addr & 0xffff0000) == (r2->addr & 0xffff0000);
 }
@@ -1309,7 +1311,7 @@ routers_in_same_network_family(routerinfo_t *r1, routerinfo_t *r2)
  * Add each of them to <b>sl</b>.
  */
 static void
-routerlist_add_network_family(smartlist_t *sl, routerinfo_t *router)
+routerlist_add_network_family(smartlist_t *sl, const routerinfo_t *router)
 {
   SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, r,
   {
@@ -1323,9 +1325,9 @@ routerlist_add_network_family(smartlist_t *sl, routerinfo_t *router)
  * or pick more than one relay from a family for our entry guard list.
  */
 void
-routerlist_add_family(smartlist_t *sl, routerinfo_t *router)
+routerlist_add_family(smartlist_t *sl, const routerinfo_t *router)
 {
-  routerinfo_t *r;
+  const routerinfo_t *r;
   config_line_t *cl;
   or_options_t *options = get_options();
 
@@ -1336,8 +1338,7 @@ routerlist_add_family(smartlist_t *sl, routerinfo_t *router)
   if (router->declared_family) {
     /* Add every r such that router declares familyness with r, and r
      * declares familyhood with router. */
-    SMARTLIST_FOREACH(router->declared_family, const char *, n,
-      {
+    SMARTLIST_FOREACH_BEGIN(router->declared_family, const char *, n) {
         if (!(r = router_get_by_nickname(n, 0)))
           continue;
         if (!r->declared_family)
@@ -1345,9 +1346,9 @@ routerlist_add_family(smartlist_t *sl, routerinfo_t *router)
         SMARTLIST_FOREACH(r->declared_family, const char *, n2,
           {
             if (router_nickname_matches(router, n2))
-              smartlist_add(sl, r);
+              smartlist_add(sl, (void*)r);
           });
-      });
+    } SMARTLIST_FOREACH_END(n);
   }
 
   /* If the user declared any families locally, honor those too. */
@@ -1360,7 +1361,7 @@ routerlist_add_family(smartlist_t *sl, routerinfo_t *router)
 
 /** Return true iff r is named by some nickname in <b>lst</b>. */
 static INLINE int
-router_in_nickname_smartlist(smartlist_t *lst, routerinfo_t *r)
+router_in_nickname_smartlist(smartlist_t *lst, const routerinfo_t *r)
 {
   if (!lst) return 0;
   SMARTLIST_FOREACH(lst, const char *, name,
@@ -1372,7 +1373,7 @@ router_in_nickname_smartlist(smartlist_t *lst, routerinfo_t *r)
 /** Return true iff r1 and r2 are in the same family, but not the same
  * router. */
 int
-routers_in_same_family(routerinfo_t *r1, routerinfo_t *r2)
+routers_in_same_family(const routerinfo_t *r1, const routerinfo_t *r2)
 {
   or_options_t *options = get_options();
   config_line_t *cl;
@@ -1402,7 +1403,7 @@ void
 add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
                                int must_be_running)
 {
-  routerinfo_t *router;
+  const routerinfo_t *router;
   smartlist_t *nickname_list;
   int have_dir_info = router_have_minimum_dir_info();
 
@@ -1417,7 +1418,7 @@ add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
   smartlist_split_string(nickname_list, list, ",",
                          SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
 
-  SMARTLIST_FOREACH(nickname_list, const char *, nick, {
+  SMARTLIST_FOREACH_BEGIN(nickname_list, const char *, nick) {
     int warned;
     if (!is_legal_nickname_or_hexdigest(nick)) {
       log_warn(LD_CONFIG, "Nickname '%s' is misformed; skipping", nick);
@@ -1427,7 +1428,7 @@ add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
     warned = smartlist_string_isin(warned_nicknames, nick);
     if (router) {
       if (!must_be_running || router->is_running) {
-        smartlist_add(sl,router);
+        smartlist_add(sl,(void*)router);
       }
     } else if (!router_get_consensus_status_by_nickname(nick,1)) {
       if (!warned) {
@@ -1436,7 +1437,7 @@ add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
         smartlist_add(warned_nicknames, tor_strdup(nick));
       }
     }
-  });
+  } SMARTLIST_FOREACH_END(nick);
   SMARTLIST_FOREACH(nickname_list, char *, nick, tor_free(nick));
   smartlist_free(nickname_list);
 }
@@ -1446,7 +1447,7 @@ add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
  * return 0.
  */
 int
-router_nickname_is_in_list(routerinfo_t *router, const char *list)
+router_nickname_is_in_list(const routerinfo_t *router, const char *list)
 {
   smartlist_t *nickname_list;
   int v = 0;
@@ -1492,7 +1493,7 @@ router_add_running_routers_to_smartlist(smartlist_t *sl, int allow_invalid,
 
 /** Look through the routerlist until we find a router that has my key.
  Return it. */
-routerinfo_t *
+const routerinfo_t *
 routerlist_find_my_routerinfo(void)
 {
   if (!routerlist)
@@ -1510,7 +1511,7 @@ routerlist_find_my_routerinfo(void)
  * that allows exit to this address:port, or return NULL if there
  * isn't a good one.
  */
-routerinfo_t *
+const routerinfo_t *
 router_find_exact_exit_enclave(const char *address, uint16_t port)
 {
   uint32_t addr;
@@ -1523,7 +1524,7 @@ router_find_exact_exit_enclave(const char *address, uint16_t port)
 
   tor_addr_from_ipv4h(&a, addr);
 
-  SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
+  SMARTLIST_FOREACH(routerlist->routers, const routerinfo_t *, router,
   {
     if (router->addr == addr &&
         router->is_running &&
@@ -1541,7 +1542,7 @@ router_find_exact_exit_enclave(const char *address, uint16_t port)
  * If <b>need_guard</b>, we require that the router is a possible entry guard.
  */
 int
-router_is_unreliable(routerinfo_t *router, int need_uptime,
+router_is_unreliable(const routerinfo_t *router, int need_uptime,
                      int need_capacity, int need_guard)
 {
   if (need_uptime && !router->is_stable)
@@ -1556,7 +1557,7 @@ router_is_unreliable(routerinfo_t *router, int need_uptime,
 /** Return the smaller of the router's configured BandwidthRate
  * and its advertised capacity. */
 uint32_t
-router_get_advertised_bandwidth(routerinfo_t *router)
+router_get_advertised_bandwidth(const routerinfo_t *router)
 {
   if (router->bandwidthcapacity < router->bandwidthrate)
     return router->bandwidthcapacity;
@@ -1570,7 +1571,7 @@ router_get_advertised_bandwidth(routerinfo_t *router)
 /** Return the smaller of the router's configured BandwidthRate
  * and its advertised capacity, capped by max-believe-bw. */
 uint32_t
-router_get_advertised_bandwidth_capped(routerinfo_t *router)
+router_get_advertised_bandwidth_capped(const routerinfo_t *router)
 {
   uint32_t result = router->bandwidthcapacity;
   if (result > router->bandwidthrate)
@@ -1845,8 +1846,8 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, bandwidth_weight_rule_t rule,
                               int statuses)
 {
   unsigned int i;
-  routerinfo_t *router;
-  routerstatus_t *status=NULL;
+  const routerinfo_t *router;
+  const routerstatus_t *status=NULL;
   int32_t *bandwidths;
   int is_exit;
   int is_guard;
@@ -2096,7 +2097,7 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, bandwidth_weight_rule_t rule,
 /** Choose a random element of router list <b>sl</b>, weighted by
  * the advertised bandwidth of each router.
  */
-routerinfo_t *
+const routerinfo_t *
 routerlist_sl_choose_by_bandwidth(smartlist_t *sl,
                                   bandwidth_weight_rule_t rule)
 {
@@ -2139,7 +2140,7 @@ routerstatus_sl_choose_by_bandwidth(smartlist_t *sl,
  * picking an exit node, otherwise we weight bandwidths for picking a relay
  * node (that is, possibly discounting exit nodes).
  */
-routerinfo_t *
+const routerinfo_t *
 router_choose_random_node(smartlist_t *excludedsmartlist,
                           routerset_t *excludedset,
                           router_crn_flags_t flags)
@@ -2152,7 +2153,7 @@ router_choose_random_node(smartlist_t *excludedsmartlist,
 
   smartlist_t *sl=smartlist_create(),
               *excludednodes=smartlist_create();
-  routerinfo_t *choice = NULL, *r;
+  const routerinfo_t *choice = NULL, *r;
   bandwidth_weight_rule_t rule;
 
   tor_assert(!(weight_for_exit && need_guard));
@@ -2170,7 +2171,7 @@ router_choose_random_node(smartlist_t *excludedsmartlist,
   }
 
   if ((r = routerlist_find_my_routerinfo())) {
-    smartlist_add(excludednodes, r);
+    smartlist_add(excludednodes, (void *)r);
     routerlist_add_family(excludednodes, r);
   }
 
@@ -2243,7 +2244,7 @@ hex_digest_matches(const char *hexdigest, const char *identity_digest,
  * optionally prefixed with a single dollar sign).  Return false if
  * <b>hexdigest</b> is malformed, or it doesn't match.  */
 static INLINE int
-router_hex_digest_matches(routerinfo_t *router, const char *hexdigest)
+router_hex_digest_matches(const routerinfo_t *router, const char *hexdigest)
 {
   return hex_digest_matches(hexdigest, router->cache_info.identity_digest,
                             router->nickname, router->is_named);
@@ -2254,7 +2255,7 @@ router_hex_digest_matches(routerinfo_t *router, const char *hexdigest)
  * matches a hexadecimal value stored in <b>nickname</b>.  Return
  * false otherwise. */
 static int
-router_nickname_matches(routerinfo_t *router, const char *nickname)
+router_nickname_matches(const routerinfo_t *router, const char *nickname)
 {
   if (nickname[0]!='$' && !strcasecmp(router->nickname, nickname))
     return 1;
@@ -2265,7 +2266,7 @@ router_nickname_matches(routerinfo_t *router, const char *nickname)
  * nickname or (case-sensitive) hexadecimal key digest is
  * <b>nickname</b>.  Return NULL if no such router is known.
  */
-routerinfo_t *
+const routerinfo_t *
 router_get_by_nickname(const char *nickname, int warn_if_unnamed)
 {
   int maybedigest;
@@ -2376,7 +2377,7 @@ router_get_by_nickname(const char *nickname, int warn_if_unnamed)
 int
 router_digest_version_as_new_as(const char *digest, const char *cutoff)
 {
-  routerinfo_t *router = router_get_by_digest(digest);
+  const routerinfo_t *router = router_get_by_digest(digest);
   if (!router)
     return 1;
   return tor_version_as_new_as(router->platform, cutoff);
@@ -2430,12 +2431,12 @@ hexdigest_to_digest(const char *hexdigest, char *digest)
 
 /** Return the router in our routerlist whose hexadecimal key digest
  * is <b>hexdigest</b>.  Return NULL if no such router is known. */
-routerinfo_t *
+const routerinfo_t *
 router_get_by_hexdigest(const char *hexdigest)
 {
   char digest[DIGEST_LEN];
   size_t len;
-  routerinfo_t *ri;
+  const routerinfo_t *ri;
 
   tor_assert(hexdigest);
   if (!routerlist)
@@ -2464,10 +2465,10 @@ router_get_by_hexdigest(const char *hexdigest)
   return ri;
 }
 
-/** Return the router in our routerlist whose 20-byte key digest
- * is <b>digest</b>.  Return NULL if no such router is known. */
+/** As router_get_by_digest,but return a pointer that you're allowed to
+ * modify */
 routerinfo_t *
-router_get_by_digest(const char *digest)
+router_get_mutable_by_digest(const char *digest)
 {
   tor_assert(digest);
 
@@ -2478,6 +2479,14 @@ router_get_by_digest(const char *digest)
   return rimap_get(routerlist->identity_map, digest);
 }
 
+/** Return the router in our routerlist whose 20-byte key digest
+ * is <b>digest</b>.  Return NULL if no such router is known. */
+const routerinfo_t *
+router_get_by_digest(const char *digest)
+{
+  return router_get_mutable_by_digest(digest);
+}
+
 /** Return the router in our routerlist whose 20-byte descriptor
  * is <b>digest</b>.  Return NULL if no such router is known. */
 signed_descriptor_t *
@@ -2528,7 +2537,7 @@ extrainfo_get_by_descriptor_digest(const char *digest)
  * The caller must not free the string returned.
  */
 static const char *
-signed_descriptor_get_body_impl(signed_descriptor_t *desc,
+signed_descriptor_get_body_impl(const signed_descriptor_t *desc,
                                 int with_annotations)
 {
   const char *r = NULL;
@@ -2577,7 +2586,7 @@ signed_descriptor_get_body_impl(signed_descriptor_t *desc,
  * The caller must not free the string returned.
  */
 const char *
-signed_descriptor_get_body(signed_descriptor_t *desc)
+signed_descriptor_get_body(const signed_descriptor_t *desc)
 {
   return signed_descriptor_get_body_impl(desc, 0);
 }
@@ -2585,7 +2594,7 @@ signed_descriptor_get_body(signed_descriptor_t *desc)
 /** As signed_descriptor_get_body(), but points to the beginning of the
  * annotations section rather than the beginning of the descriptor. */
 const char *
-signed_descriptor_get_annotations(signed_descriptor_t *desc)
+signed_descriptor_get_annotations(const signed_descriptor_t *desc)
 {
   return signed_descriptor_get_body_impl(desc, 1);
 }
@@ -2770,7 +2779,7 @@ routerlist_insert(routerlist_t *rl, routerinfo_t *ri)
   routerinfo_t *ri_old;
   {
     /* XXXX Remove if this slows us down. */
-    routerinfo_t *ri_generated = router_get_my_routerinfo();
+    const routerinfo_t *ri_generated = router_get_my_routerinfo();
     tor_assert(ri_generated != ri);
   }
   tor_assert(ri->cache_info.routerlist_index == -1);
@@ -2852,7 +2861,7 @@ routerlist_insert_old(routerlist_t *rl, routerinfo_t *ri)
 {
   {
     /* XXXX remove this code if it slows us down. */
-    routerinfo_t *ri_generated = router_get_my_routerinfo();
+    const routerinfo_t *ri_generated = router_get_my_routerinfo();
     tor_assert(ri_generated != ri);
   }
   tor_assert(ri->cache_info.routerlist_index == -1);
@@ -3005,7 +3014,7 @@ routerlist_replace(routerlist_t *rl, routerinfo_t *ri_old,
   extrainfo_t *ei_tmp;
   {
     /* XXXX Remove this if it turns out to slow us down. */
-    routerinfo_t *ri_generated = router_get_my_routerinfo();
+    const routerinfo_t *ri_generated = router_get_my_routerinfo();
     tor_assert(ri_generated != ri_new);
   }
   tor_assert(ri_old != ri_new);
@@ -3162,7 +3171,7 @@ router_set_status(const char *digest, int up)
                     if (!memcmp(d->digest, digest, DIGEST_LEN))
                       d->is_running = up);
 
-  router = router_get_by_digest(digest);
+  router = router_get_mutable_by_digest(digest);
   if (router) {
     log_debug(LD_DIR,"Marking router '%s/%s' as %s.",
               router->nickname, router->address, up ? "up" : "down");
@@ -3218,7 +3227,7 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
 
   id_digest = router->cache_info.identity_digest;
 
-  old_router = router_get_by_digest(id_digest);
+  old_router = router_get_mutable_by_digest(id_digest);
 
   /* Make sure that we haven't already got this exact descriptor. */
   if (sdmap_get(routerlist->desc_digest_map,
@@ -3940,7 +3949,7 @@ router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port,
 /** Return true iff <b>router</b> does not permit exit streams.
  */
 int
-router_exit_policy_rejects_all(routerinfo_t *router)
+router_exit_policy_rejects_all(const routerinfo_t *router)
 {
   return router->policy_is_reject_star;
 }
@@ -4524,13 +4533,12 @@ update_consensus_router_descriptor_downloads(time_t now, int is_vote,
 
   map = digestmap_new();
   list_pending_descriptor_downloads(map, 0);
-  SMARTLIST_FOREACH(consensus->routerstatus_list, void *, rsp,
-    {
+  SMARTLIST_FOREACH_BEGIN(consensus->routerstatus_list, void *, rsp) {
       routerstatus_t *rs =
         is_vote ? &(((vote_routerstatus_t *)rsp)->status) : rsp;
       signed_descriptor_t *sd;
       if ((sd = router_get_by_descriptor_digest(rs->descriptor_digest))) {
-        routerinfo_t *ri;
+        const routerinfo_t *ri;
         ++n_have;
         if (!(ri = router_get_by_digest(rs->identity_digest)) ||
             memcmp(ri->cache_info.signed_descriptor_digest,
@@ -4565,7 +4573,8 @@ update_consensus_router_descriptor_downloads(time_t now, int is_vote,
       if (is_vote && source) {
         char time_bufnew[ISO_TIME_LEN+1];
         char time_bufold[ISO_TIME_LEN+1];
-        routerinfo_t *oldrouter = router_get_by_digest(rs->identity_digest);
+        const routerinfo_t *oldrouter;
+        oldrouter = router_get_by_digest(rs->identity_digest);
         format_iso_time(time_bufnew, rs->published_on);
         if (oldrouter)
           format_iso_time(time_bufold, oldrouter->cache_info.published_on);
@@ -4575,7 +4584,7 @@ update_consensus_router_descriptor_downloads(time_t now, int is_vote,
                  source->nickname, oldrouter ? "known" : "unknown");
       }
       smartlist_add(downloadable, rs->descriptor_digest);
-    });
+  } SMARTLIST_FOREACH_END(rsp);
 
   if (!authdir_mode_handles_descs(options, ROUTER_PURPOSE_GENERAL)
       && smartlist_len(no_longer_old)) {
@@ -4950,7 +4959,7 @@ router_reset_descriptor_download_failures(void)
  * would not cause a recent (post 0.1.1.6) dirserver to republish.
  */
 int
-router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2)
+router_differences_are_cosmetic(const routerinfo_t *r1, const routerinfo_t *r2)
 {
   time_t r1pub, r2pub;
   long time_difference;
@@ -4958,7 +4967,7 @@ router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2)
 
   /* r1 should be the one that was published first. */
   if (r1->cache_info.published_on > r2->cache_info.published_on) {
-    routerinfo_t *ri_tmp = r2;
+    const routerinfo_t *ri_tmp = r2;
     r2 = r1;
     r1 = ri_tmp;
   }
@@ -5031,7 +5040,8 @@ router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2)
  * incompatibility (if any).
  **/
 int
-routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei,
+routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri,
+                                       extrainfo_t *ei,
                                        signed_descriptor_t *sd,
                                        const char **msg)
 {
@@ -5039,7 +5049,7 @@ routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei,
   tor_assert(ri);
   tor_assert(ei);
   if (!sd)
-    sd = &ri->cache_info;
+    sd = (signed_descriptor_t*)&ri->cache_info;
 
   if (ei->bad_sig) {
     if (msg) *msg = "Extrainfo signature was bad, or signed with wrong key.";
@@ -5102,7 +5112,7 @@ routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei,
 /** Assert that the internal representation of <b>rl</b> is
  * self-consistent. */
 void
-routerlist_assert_ok(routerlist_t *rl)
+routerlist_assert_ok(const routerlist_t *rl)
 {
   routerinfo_t *r2;
   signed_descriptor_t *sd2;
@@ -5192,7 +5202,7 @@ routerlist_assert_ok(routerlist_t *rl)
  * If <b>router</b> is NULL, it just frees its internal memory and returns.
  */
 const char *
-esc_router_info(routerinfo_t *router)
+esc_router_info(const routerinfo_t *router)
 {
   static char *info=NULL;
   char *esc_contact, *esc_platform;
@@ -5515,7 +5525,7 @@ routerset_contains_extendinfo(const routerset_t *set, const extend_info_t *ei)
 
 /** Return true iff <b>ri</b> is in <b>set</b>. */
 int
-routerset_contains_router(const routerset_t *set, routerinfo_t *ri)
+routerset_contains_router(const routerset_t *set, const routerinfo_t *ri)
 {
   tor_addr_t addr;
   tor_addr_from_ipv4h(&addr, ri->addr);
@@ -5559,10 +5569,10 @@ routerset_get_all_routers(smartlist_t *out, const routerset_t *routerset,
     /* No routers are specified by type; all are given by name or digest.
      * we can do a lookup in O(len(list)). */
     SMARTLIST_FOREACH(routerset->list, const char *, name, {
-        routerinfo_t *router = router_get_by_nickname(name, 1);
+        const routerinfo_t *router = router_get_by_nickname(name, 1);
         if (router) {
           if (!running_only || router->is_running)
-            smartlist_add(out, router);
+            smartlist_add(out, (void*)router);
         }
     });
   } else {
@@ -5573,7 +5583,7 @@ routerset_get_all_routers(smartlist_t *out, const routerset_t *routerset,
         if (running_only && !router->is_running)
           continue;
         if (routerset_contains_router(routerset, router))
-          smartlist_add(out, router);
+          smartlist_add(out, (void*)router);
     });
   }
 }
@@ -5740,7 +5750,7 @@ hid_serv_get_responsible_directories(smartlist_t *responsible_dirs,
 int
 hid_serv_acting_as_directory(void)
 {
-  routerinfo_t *me = router_get_my_routerinfo();
+  const routerinfo_t *me = router_get_my_routerinfo();
   networkstatus_t *c;
   routerstatus_t *rs;
   if (!me)
@@ -5774,7 +5784,7 @@ hid_serv_acting_as_directory(void)
 int
 hid_serv_responsible_for_desc_id(const char *query)
 {
-  routerinfo_t *me;
+  const routerinfo_t *me;
   routerstatus_t *last_rs;
   const char *my_id, *last_id;
   int result;
diff --git a/src/or/routerlist.h b/src/or/routerlist.h
index 804be2a..a805469 100644
--- a/src/or/routerlist.h
+++ b/src/or/routerlist.h
@@ -34,30 +34,30 @@ routerstatus_t *router_pick_trusteddirserver(authority_type_t type, int flags);
 int router_get_my_share_of_directory_requests(double *v2_share_out,
                                               double *v3_share_out);
 void router_reset_status_download_failures(void);
-void routerlist_add_family(smartlist_t *sl, routerinfo_t *router);
-int routers_in_same_family(routerinfo_t *r1, routerinfo_t *r2);
+void routerlist_add_family(smartlist_t *sl, const routerinfo_t *router);
+int routers_in_same_family(const routerinfo_t *r1, const routerinfo_t *r2);
 int routers_have_same_or_addr(const routerinfo_t *r1, const routerinfo_t *r2);
 void add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
                                     int must_be_running);
-int router_nickname_is_in_list(routerinfo_t *router, const char *list);
-routerinfo_t *routerlist_find_my_routerinfo(void);
-routerinfo_t *router_find_exact_exit_enclave(const char *address,
+int router_nickname_is_in_list(const routerinfo_t *router, const char *list);
+const routerinfo_t *routerlist_find_my_routerinfo(void);
+const routerinfo_t *router_find_exact_exit_enclave(const char *address,
                                              uint16_t port);
-int router_is_unreliable(routerinfo_t *router, int need_uptime,
+int router_is_unreliable(const routerinfo_t *router, int need_uptime,
                          int need_capacity, int need_guard);
-uint32_t router_get_advertised_bandwidth(routerinfo_t *router);
-uint32_t router_get_advertised_bandwidth_capped(routerinfo_t *router);
+uint32_t router_get_advertised_bandwidth(const routerinfo_t *router);
+uint32_t router_get_advertised_bandwidth_capped(const routerinfo_t *router);
 
-routerinfo_t *routerlist_sl_choose_by_bandwidth(smartlist_t *sl,
+const routerinfo_t *routerlist_sl_choose_by_bandwidth(smartlist_t *sl,
                                                 bandwidth_weight_rule_t rule);
 routerstatus_t *routerstatus_sl_choose_by_bandwidth(smartlist_t *sl,
                                                 bandwidth_weight_rule_t rule);
 
-routerinfo_t *router_choose_random_node(smartlist_t *excludedsmartlist,
+const routerinfo_t *router_choose_random_node(smartlist_t *excludedsmartlist,
                                         struct routerset_t *excludedset,
                                         router_crn_flags_t flags);
 
-routerinfo_t *router_get_by_nickname(const char *nickname,
+const routerinfo_t *router_get_by_nickname(const char *nickname,
                                      int warn_if_unnamed);
 int router_digest_version_as_new_as(const char *digest, const char *cutoff);
 int router_digest_is_trusted_dir_type(const char *digest,
@@ -67,13 +67,14 @@ int router_digest_is_trusted_dir_type(const char *digest,
 
 int router_addr_is_trusted_dir(uint32_t addr);
 int hexdigest_to_digest(const char *hexdigest, char *digest);
-routerinfo_t *router_get_by_hexdigest(const char *hexdigest);
-routerinfo_t *router_get_by_digest(const char *digest);
+const routerinfo_t *router_get_by_hexdigest(const char *hexdigest);
+const routerinfo_t *router_get_by_digest(const char *digest);
+routerinfo_t *router_get_mutable_by_digest(const char *digest);
 signed_descriptor_t *router_get_by_descriptor_digest(const char *digest);
 signed_descriptor_t *router_get_by_extrainfo_digest(const char *digest);
 signed_descriptor_t *extrainfo_get_by_descriptor_digest(const char *digest);
-const char *signed_descriptor_get_body(signed_descriptor_t *desc);
-const char *signed_descriptor_get_annotations(signed_descriptor_t *desc);
+const char *signed_descriptor_get_body(const signed_descriptor_t *desc);
+const char *signed_descriptor_get_annotations(const signed_descriptor_t *desc);
 routerlist_t *router_get_routerlist(void);
 void routerinfo_free(routerinfo_t *router);
 void extrainfo_free(extrainfo_t *extrainfo);
@@ -134,7 +135,7 @@ void router_load_extrainfo_from_string(const char *s, const char *eos,
 void routerlist_retry_directory_downloads(time_t now);
 int router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port,
                                           int need_uptime);
-int router_exit_policy_rejects_all(routerinfo_t *router);
+int router_exit_policy_rejects_all(const routerinfo_t *router);
 trusted_dir_server_t *add_trusted_dir_server(const char *nickname,
                            const char *address,
                            uint16_t dir_port, uint16_t or_port,
@@ -152,13 +153,15 @@ void router_dir_info_changed(void);
 const char *get_dir_info_status_string(void);
 int count_loading_descriptors_progress(void);
 void router_reset_descriptor_download_failures(void);
-int router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2);
-int routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei,
+int router_differences_are_cosmetic(const routerinfo_t *r1,
+                                    const routerinfo_t *r2);
+int routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri,
+                                           extrainfo_t *ei,
                                            signed_descriptor_t *sd,
                                            const char **msg);
 
-void routerlist_assert_ok(routerlist_t *rl);
-const char *esc_router_info(routerinfo_t *router);
+void routerlist_assert_ok(const routerlist_t *rl);
+const char *esc_router_info(const routerinfo_t *router);
 void routers_sort_by_identity(smartlist_t *routers);
 
 routerset_t *routerset_new(void);
@@ -167,7 +170,7 @@ int routerset_parse(routerset_t *target, const char *s,
 void routerset_union(routerset_t *target, const routerset_t *source);
 int routerset_is_list(const routerset_t *set);
 int routerset_needs_geoip(const routerset_t *set);
-int routerset_contains_router(const routerset_t *set, routerinfo_t *ri);
+int routerset_contains_router(const routerset_t *set, const routerinfo_t *ri);
 int routerset_contains_routerstatus(const routerset_t *set,
                                     routerstatus_t *rs);
 int routerset_contains_extendinfo(const routerset_t *set,
-- 
1.7.1