Browse Source

r12853@catbus: nickm | 2007-05-22 11:36:54 -0400
Make connection_array into a smartlist.


svn:r10292

Nick Mathewson 18 years ago
parent
commit
6975a093e9
12 changed files with 201 additions and 281 deletions
  1. 4 0
      ChangeLog
  2. 13 11
      src/or/circuitbuild.c
  3. 63 102
      src/or/connection.c
  4. 14 25
      src/or/connection_edge.c
  5. 4 7
      src/or/connection_or.c
  6. 49 55
      src/or/control.c
  7. 4 8
      src/or/cpuworker.c
  8. 4 8
      src/or/directory.c
  9. 33 48
      src/or/main.c
  10. 1 1
      src/or/or.h
  11. 8 10
      src/or/rendclient.c
  12. 4 6
      src/or/routerlist.c

+ 4 - 0
ChangeLog

@@ -76,6 +76,7 @@ Changes in version 0.2.0.1-alpha - 2007-??-??
       string: either fetch it directly if we're in an SVN checkout, do
       string: either fetch it directly if we're in an SVN checkout, do
       some magic to guess it if we're in an SVK checkout, or use
       some magic to guess it if we're in an SVK checkout, or use
       the last-detected version if we're building from a .tar.gz.
       the last-detected version if we're building from a .tar.gz.
+      Use this version consistently in log messages.
 
 
   o Minor features (logging):
   o Minor features (logging):
     - Always prepend "Bug: " to any log message about a bug.
     - Always prepend "Bug: " to any log message about a bug.
@@ -181,6 +182,9 @@ Changes in version 0.2.0.1-alpha - 2007-??-??
     - Make dns_resolve() handle attaching connections to circuits
     - Make dns_resolve() handle attaching connections to circuits
       properly, so the caller doesn't have to.
       properly, so the caller doesn't have to.
     - Rename wants_to_read and wants_to_write to read/write_blocked_on_bw.
     - Rename wants_to_read and wants_to_write to read/write_blocked_on_bw.
+    - Keep the connection array as a dynamic smartlist_t, rather than as
+      a fixed-sized array.  This is important, as the number of connections
+      is becoming increasingly decoupled from the number of sockets.
 
 
 
 
 Changes in version 0.1.2.13 - 2007-04-24
 Changes in version 0.1.2.13 - 2007-04-24

+ 13 - 11
src/or/circuitbuild.c

@@ -1145,25 +1145,25 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
                                 int need_capacity)
                                 int need_capacity)
 {
 {
   int *n_supported;
   int *n_supported;
-  int i, j;
+  int i;
   int n_pending_connections = 0;
   int n_pending_connections = 0;
-  connection_t **carray;
-  int n_connections;
+  smartlist_t *connections;
   int best_support = -1;
   int best_support = -1;
   int n_best_support=0;
   int n_best_support=0;
   smartlist_t *sl, *preferredexits, *excludedexits;
   smartlist_t *sl, *preferredexits, *excludedexits;
   routerinfo_t *router;
   routerinfo_t *router;
   or_options_t *options = get_options();
   or_options_t *options = get_options();
 
 
-  get_connection_array(&carray, &n_connections);
+  connections = get_connection_array();
 
 
   /* Count how many connections are waiting for a circuit to be built.
   /* Count how many connections are waiting for a circuit to be built.
    * We use this for log messages now, but in the future we may depend on it.
    * We use this for log messages now, but in the future we may depend on it.
    */
    */
-  for (i = 0; i < n_connections; ++i) {
-    if (ap_stream_wants_exit_attention(carray[i]))
+  SMARTLIST_FOREACH(connections, connection_t *, conn,
+  {
+    if (ap_stream_wants_exit_attention(conn))
       ++n_pending_connections;
       ++n_pending_connections;
-  }
+  });
 //  log_fn(LOG_DEBUG, "Choosing exit node; %d connections are pending",
 //  log_fn(LOG_DEBUG, "Choosing exit node; %d connections are pending",
 //         n_pending_connections);
 //         n_pending_connections);
   /* Now we count, for each of the routers in the directory, how many
   /* Now we count, for each of the routers in the directory, how many
@@ -1204,10 +1204,12 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
       continue; /* skip routers that reject all */
       continue; /* skip routers that reject all */
     }
     }
     n_supported[i] = 0;
     n_supported[i] = 0;
-    for (j = 0; j < n_connections; ++j) { /* iterate over connections */
-      if (!ap_stream_wants_exit_attention(carray[j]))
+    /* iterate over connections */
+    SMARTLIST_FOREACH(connections, connection_t *, conn,
+    {
+      if (!ap_stream_wants_exit_attention(conn))
         continue; /* Skip everything but APs in CIRCUIT_WAIT */
         continue; /* Skip everything but APs in CIRCUIT_WAIT */
-      if (connection_ap_can_use_exit(TO_EDGE_CONN(carray[j]), router)) {
+      if (connection_ap_can_use_exit(TO_EDGE_CONN(conn), router)) {
         ++n_supported[i];
         ++n_supported[i];
 //        log_fn(LOG_DEBUG,"%s is supported. n_supported[%d] now %d.",
 //        log_fn(LOG_DEBUG,"%s is supported. n_supported[%d] now %d.",
 //               router->nickname, i, n_supported[i]);
 //               router->nickname, i, n_supported[i]);
@@ -1215,7 +1217,7 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
 //        log_fn(LOG_DEBUG,"%s (index %d) would reject this stream.",
 //        log_fn(LOG_DEBUG,"%s (index %d) would reject this stream.",
 //               router->nickname, i);
 //               router->nickname, i);
       }
       }
-    } /* End looping over connections. */
+    }); /* End looping over connections. */
     if (n_supported[i] > best_support) {
     if (n_supported[i] > best_support) {
       /* If this router is better than previous ones, remember its index
       /* If this router is better than previous ones, remember its index
        * and goodness, and start counting how many routers are this good. */
        * and goodness, and start counting how many routers are this good. */

+ 63 - 102
src/or/connection.c

@@ -385,21 +385,19 @@ connection_free(connection_t *conn)
 void
 void
 connection_free_all(void)
 connection_free_all(void)
 {
 {
-  int i, n;
-  connection_t **carray;
+  smartlist_t *conns = get_connection_array();
 
 
-  get_connection_array(&carray,&n);
   /* We don't want to log any messages to controllers. */
   /* We don't want to log any messages to controllers. */
-  for (i=0;i<n;i++)
-    if (carray[i]->type == CONN_TYPE_CONTROL)
-      TO_CONTROL_CONN(carray[i])->event_mask = 0;
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+    if (conn->type == CONN_TYPE_CONTROL)
+      TO_CONTROL_CONN(conn)->event_mask = 0);
+
   control_update_global_event_mask();
   control_update_global_event_mask();
 
 
   /* Unlink everything from the identity map. */
   /* Unlink everything from the identity map. */
   connection_or_clear_identity_map();
   connection_or_clear_identity_map();
 
 
-  for (i=0;i<n;i++)
-    _connection_free(carray[i]);
+  SMARTLIST_FOREACH(conns, connection_t *, conn, _connection_free(conn));
 
 
   if (outgoing_addrs) {
   if (outgoing_addrs) {
     SMARTLIST_FOREACH(outgoing_addrs, void*, addr, tor_free(addr));
     SMARTLIST_FOREACH(outgoing_addrs, void*, addr, tor_free(addr));
@@ -583,15 +581,13 @@ _connection_mark_for_close(connection_t *conn, int line, const char *file)
 void
 void
 connection_expire_held_open(void)
 connection_expire_held_open(void)
 {
 {
-  connection_t **carray, *conn;
-  int n, i;
   time_t now;
   time_t now;
+  smartlist_t *conns = get_connection_array();
 
 
   now = time(NULL);
   now = time(NULL);
 
 
-  get_connection_array(&carray, &n);
-  for (i = 0; i < n; ++i) {
-    conn = carray[i];
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     /* If we've been holding the connection open, but we haven't written
     /* If we've been holding the connection open, but we haven't written
      * for 15 seconds...
      * for 15 seconds...
      */
      */
@@ -613,7 +609,7 @@ connection_expire_held_open(void)
         conn->hold_open_until_flushed = 0;
         conn->hold_open_until_flushed = 0;
       }
       }
     }
     }
-  }
+  });
 }
 }
 
 
 /** Bind a new non-blocking socket listening to
 /** Bind a new non-blocking socket listening to
@@ -995,12 +991,11 @@ retry_listeners(int type, config_line_t *cfg,
                 smartlist_t *new_conns,
                 smartlist_t *new_conns,
                 int never_open_conns)
                 int never_open_conns)
 {
 {
-  smartlist_t *launch = smartlist_create();
+  smartlist_t *launch = smartlist_create(), *conns;
   int free_launch_elts = 1;
   int free_launch_elts = 1;
+  int r;
   config_line_t *c;
   config_line_t *c;
-  int n_conn, i;
   connection_t *conn;
   connection_t *conn;
-  connection_t **carray;
   config_line_t *line;
   config_line_t *line;
 
 
   if (cfg && port_option) {
   if (cfg && port_option) {
@@ -1020,9 +1015,9 @@ retry_listeners(int type, config_line_t *cfg,
                     log_fn(LOG_NOTICE, "#%s#%s", l->key, l->value));
                     log_fn(LOG_NOTICE, "#%s#%s", l->key, l->value));
   */
   */
 
 
-  get_connection_array(&carray,&n_conn);
-  for (i=0; i < n_conn; ++i) {
-    conn = carray[i];
+  conns = get_connection_array();
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (conn->type != type || conn->marked_for_close)
     if (conn->type != type || conn->marked_for_close)
       continue;
       continue;
     if (force) {
     if (force) {
@@ -1069,17 +1064,17 @@ retry_listeners(int type, config_line_t *cfg,
       if (free_launch_elts)
       if (free_launch_elts)
         config_free_lines(line);
         config_free_lines(line);
     }
     }
-  }
+  });
 
 
   /* Now open all the listeners that are configured but not opened. */
   /* Now open all the listeners that are configured but not opened. */
-  i = 0;
+  r = 0;
   if (!never_open_conns) {
   if (!never_open_conns) {
     SMARTLIST_FOREACH(launch, config_line_t *, cfg_line,
     SMARTLIST_FOREACH(launch, config_line_t *, cfg_line,
       {
       {
         conn = connection_create_listener(cfg_line->value,
         conn = connection_create_listener(cfg_line->value,
                                           (uint16_t) port_option, type);
                                           (uint16_t) port_option, type);
         if (!conn) {
         if (!conn) {
-          i = -1;
+          r = -1;
         } else {
         } else {
           if (new_conns)
           if (new_conns)
             smartlist_add(new_conns, conn);
             smartlist_add(new_conns, conn);
@@ -1093,7 +1088,7 @@ retry_listeners(int type, config_line_t *cfg,
   }
   }
   smartlist_free(launch);
   smartlist_free(launch);
 
 
-  return i;
+  return r;
 }
 }
 
 
 /** (Re)launch listeners for each port you should have open.  If
 /** (Re)launch listeners for each port you should have open.  If
@@ -1416,10 +1411,8 @@ connection_bucket_refill_helper(int *bucket, int rate, int burst,
 void
 void
 connection_bucket_refill(int seconds_elapsed)
 connection_bucket_refill(int seconds_elapsed)
 {
 {
-  int i, n;
-  connection_t *conn;
-  connection_t **carray;
   or_options_t *options = get_options();
   or_options_t *options = get_options();
+  smartlist_t *conns = get_connection_array();
   int relayrate, relayburst;
   int relayrate, relayburst;
 
 
   if (options->RelayBandwidthRate) {
   if (options->RelayBandwidthRate) {
@@ -1452,10 +1445,8 @@ connection_bucket_refill(int seconds_elapsed)
                                   "global_relayed_write_bucket");
                                   "global_relayed_write_bucket");
 
 
   /* refill the per-connection buckets */
   /* refill the per-connection buckets */
-  get_connection_array(&carray,&n);
-  for (i=0;i<n;i++) {
-    conn = carray[i];
-
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (connection_speaks_cells(conn)) {
     if (connection_speaks_cells(conn)) {
       or_connection_t *or_conn = TO_OR_CONN(conn);
       or_connection_t *or_conn = TO_OR_CONN(conn);
       if (connection_read_bucket_should_increase(or_conn)) {
       if (connection_read_bucket_should_increase(or_conn)) {
@@ -1491,7 +1482,7 @@ connection_bucket_refill(int seconds_elapsed)
       conn->write_blocked_on_bw = 0;
       conn->write_blocked_on_bw = 0;
       connection_start_writing(conn);
       connection_start_writing(conn);
     }
     }
-  }
+  });
 }
 }
 
 
 /** Is the receiver bucket for connection <b>conn</b> low enough that we
 /** Is the receiver bucket for connection <b>conn</b> low enough that we
@@ -2057,21 +2048,18 @@ _connection_write_to_buf_impl(const char *string, size_t len,
 or_connection_t *
 or_connection_t *
 connection_or_exact_get_by_addr_port(uint32_t addr, uint16_t port)
 connection_or_exact_get_by_addr_port(uint32_t addr, uint16_t port)
 {
 {
-  int i, n;
-  connection_t *conn;
   or_connection_t *best=NULL;
   or_connection_t *best=NULL;
-  connection_t **carray;
+  smartlist_t *conns = get_connection_array();
 
 
-  get_connection_array(&carray,&n);
-  for (i=0;i<n;i++) {
-    conn = carray[i];
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (conn->type == CONN_TYPE_OR &&
     if (conn->type == CONN_TYPE_OR &&
         conn->addr == addr &&
         conn->addr == addr &&
         conn->port == port &&
         conn->port == port &&
         !conn->marked_for_close &&
         !conn->marked_for_close &&
         (!best || best->_base.timestamp_created < conn->timestamp_created))
         (!best || best->_base.timestamp_created < conn->timestamp_created))
       best = TO_OR_CONN(conn);
       best = TO_OR_CONN(conn);
-  }
+  });
   return best;
   return best;
 }
 }
 
 
@@ -2082,20 +2070,16 @@ connection_get_by_type_addr_port_purpose(int type,
                                          uint32_t addr, uint16_t port,
                                          uint32_t addr, uint16_t port,
                                          int purpose)
                                          int purpose)
 {
 {
-  int i, n;
-  connection_t *conn;
-  connection_t **carray;
-
-  get_connection_array(&carray,&n);
-  for (i=0;i<n;i++) {
-    conn = carray[i];
+  smartlist_t *conns = get_connection_array();
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (conn->type == type &&
     if (conn->type == type &&
         conn->addr == addr &&
         conn->addr == addr &&
         conn->port == port &&
         conn->port == port &&
         conn->purpose == purpose &&
         conn->purpose == purpose &&
         !conn->marked_for_close)
         !conn->marked_for_close)
       return conn;
       return conn;
-  }
+  });
   return NULL;
   return NULL;
 }
 }
 
 
@@ -2105,20 +2089,16 @@ connection_get_by_type_addr_port_purpose(int type,
 edge_connection_t *
 edge_connection_t *
 connection_get_by_global_id(uint32_t id)
 connection_get_by_global_id(uint32_t id)
 {
 {
-  int i, n;
-  connection_t *conn;
-  connection_t **carray;
-
-  get_connection_array(&carray,&n);
-  for (i=0;i<n;i++) {
-    conn = carray[i];
+  smartlist_t *conns = get_connection_array();
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (CONN_IS_EDGE(conn) && TO_EDGE_CONN(conn)->global_identifier == id) {
     if (CONN_IS_EDGE(conn) && TO_EDGE_CONN(conn)->global_identifier == id) {
       if (!conn->marked_for_close)
       if (!conn->marked_for_close)
         return TO_EDGE_CONN(conn);
         return TO_EDGE_CONN(conn);
       else
       else
         return NULL;
         return NULL;
     }
     }
-  }
+  });
   return NULL;
   return NULL;
 }
 }
 
 
@@ -2127,16 +2107,12 @@ connection_get_by_global_id(uint32_t id)
 connection_t *
 connection_t *
 connection_get_by_type(int type)
 connection_get_by_type(int type)
 {
 {
-  int i, n;
-  connection_t *conn;
-  connection_t **carray;
-
-  get_connection_array(&carray,&n);
-  for (i=0;i<n;i++) {
-    conn = carray[i];
+  smartlist_t *conns = get_connection_array();
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (conn->type == type && !conn->marked_for_close)
     if (conn->type == type && !conn->marked_for_close)
       return conn;
       return conn;
-  }
+  });
   return NULL;
   return NULL;
 }
 }
 
 
@@ -2146,16 +2122,12 @@ connection_get_by_type(int type)
 connection_t *
 connection_t *
 connection_get_by_type_state(int type, int state)
 connection_get_by_type_state(int type, int state)
 {
 {
-  int i, n;
-  connection_t *conn;
-  connection_t **carray;
-
-  get_connection_array(&carray,&n);
-  for (i=0;i<n;i++) {
-    conn = carray[i];
+  smartlist_t *conns = get_connection_array();
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (conn->type == type && conn->state == state && !conn->marked_for_close)
     if (conn->type == type && conn->state == state && !conn->marked_for_close)
       return conn;
       return conn;
-  }
+  });
   return NULL;
   return NULL;
 }
 }
 
 
@@ -2166,17 +2138,14 @@ connection_get_by_type_state(int type, int state)
 connection_t *
 connection_t *
 connection_get_by_type_state_lastwritten(int type, int state)
 connection_get_by_type_state_lastwritten(int type, int state)
 {
 {
-  int i, n;
-  connection_t *conn, *best=NULL;
-  connection_t **carray;
-
-  get_connection_array(&carray,&n);
-  for (i=0;i<n;i++) {
-    conn = carray[i];
+  connection_t *best = NULL;
+  smartlist_t *conns = get_connection_array();
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (conn->type == type && conn->state == state && !conn->marked_for_close)
     if (conn->type == type && conn->state == state && !conn->marked_for_close)
       if (!best || conn->timestamp_lastwritten < best->timestamp_lastwritten)
       if (!best || conn->timestamp_lastwritten < best->timestamp_lastwritten)
         best = conn;
         best = conn;
-  }
+  });
   return best;
   return best;
 }
 }
 
 
@@ -2188,16 +2157,13 @@ connection_t *
 connection_get_by_type_state_rendquery(int type, int state,
 connection_get_by_type_state_rendquery(int type, int state,
                                        const char *rendquery)
                                        const char *rendquery)
 {
 {
-  int i, n;
-  connection_t *conn;
-  connection_t **carray;
+  smartlist_t *conns = get_connection_array();
 
 
   tor_assert(type == CONN_TYPE_DIR ||
   tor_assert(type == CONN_TYPE_DIR ||
              type == CONN_TYPE_AP || type == CONN_TYPE_EXIT);
              type == CONN_TYPE_AP || type == CONN_TYPE_EXIT);
 
 
-  get_connection_array(&carray,&n);
-  for (i=0;i<n;i++) {
-    conn = carray[i];
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (conn->type == type &&
     if (conn->type == type &&
         !conn->marked_for_close &&
         !conn->marked_for_close &&
         (!state || state == conn->state)) {
         (!state || state == conn->state)) {
@@ -2208,7 +2174,7 @@ connection_get_by_type_state_rendquery(int type, int state,
               !rend_cmp_service_ids(rendquery, TO_EDGE_CONN(conn)->rend_query))
               !rend_cmp_service_ids(rendquery, TO_EDGE_CONN(conn)->rend_query))
         return conn;
         return conn;
     }
     }
-  }
+  });
   return NULL;
   return NULL;
 }
 }
 
 
@@ -2217,18 +2183,14 @@ connection_get_by_type_state_rendquery(int type, int state,
 connection_t *
 connection_t *
 connection_get_by_type_purpose(int type, int purpose)
 connection_get_by_type_purpose(int type, int purpose)
 {
 {
-  int i, n;
-  connection_t *conn;
-  connection_t **carray;
-
-  get_connection_array(&carray,&n);
-  for (i=0;i<n;i++) {
-    conn = carray[i];
+  smartlist_t *conns = get_connection_array();
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (conn->type == type &&
     if (conn->type == type &&
         !conn->marked_for_close &&
         !conn->marked_for_close &&
         (purpose == conn->purpose))
         (purpose == conn->purpose))
       return conn;
       return conn;
-  }
+  });
   return NULL;
   return NULL;
 }
 }
 
 
@@ -2511,17 +2473,15 @@ connection_dump_buffer_mem_stats(int severity)
   int n_conns_by_type[_CONN_TYPE_MAX+1];
   int n_conns_by_type[_CONN_TYPE_MAX+1];
   uint64_t total_alloc = 0;
   uint64_t total_alloc = 0;
   uint64_t total_used = 0;
   uint64_t total_used = 0;
-  int i, n;
-  connection_t **carray;
+  int i;
+  smartlist_t *conns = get_connection_array();
 
 
   memset(used_by_type, 0, sizeof(used_by_type));
   memset(used_by_type, 0, sizeof(used_by_type));
   memset(alloc_by_type, 0, sizeof(alloc_by_type));
   memset(alloc_by_type, 0, sizeof(alloc_by_type));
   memset(n_conns_by_type, 0, sizeof(n_conns_by_type));
   memset(n_conns_by_type, 0, sizeof(n_conns_by_type));
 
 
-  get_connection_array(&carray,&n);
-
-  for (i=0; i<n; ++i) {
-    connection_t *c = carray[i];
+  SMARTLIST_FOREACH(conns, connection_t *, c,
+  {
     int tp = c->type;
     int tp = c->type;
     ++n_conns_by_type[tp];
     ++n_conns_by_type[tp];
     if (c->inbuf) {
     if (c->inbuf) {
@@ -2532,7 +2492,7 @@ connection_dump_buffer_mem_stats(int severity)
       used_by_type[tp] += buf_datalen(c->outbuf);
       used_by_type[tp] += buf_datalen(c->outbuf);
       alloc_by_type[tp] += buf_capacity(c->outbuf);
       alloc_by_type[tp] += buf_capacity(c->outbuf);
     }
     }
-  }
+  });
   for (i=0; i <= _CONN_TYPE_MAX; ++i) {
   for (i=0; i <= _CONN_TYPE_MAX; ++i) {
     total_used += used_by_type[i];
     total_used += used_by_type[i];
     total_alloc += alloc_by_type[i];
     total_alloc += alloc_by_type[i];
@@ -2540,7 +2500,8 @@ connection_dump_buffer_mem_stats(int severity)
 
 
   log(severity, LD_GENERAL,
   log(severity, LD_GENERAL,
      "In buffers for %d connections: "U64_FORMAT" used/"U64_FORMAT" allocated",
      "In buffers for %d connections: "U64_FORMAT" used/"U64_FORMAT" allocated",
-      n, U64_PRINTF_ARG(total_used), U64_PRINTF_ARG(total_alloc));
+      smartlist_len(conns),
+      U64_PRINTF_ARG(total_used), U64_PRINTF_ARG(total_alloc));
   for (i=_CONN_TYPE_MIN; i <= _CONN_TYPE_MAX; ++i) {
   for (i=_CONN_TYPE_MIN; i <= _CONN_TYPE_MAX; ++i) {
     if (!n_conns_by_type[i])
     if (!n_conns_by_type[i])
       continue;
       continue;

+ 14 - 25
src/or/connection_edge.c

@@ -343,22 +343,20 @@ compute_retry_timeout(edge_connection_t *conn)
 void
 void
 connection_ap_expire_beginning(void)
 connection_ap_expire_beginning(void)
 {
 {
-  connection_t **carray;
   edge_connection_t *conn;
   edge_connection_t *conn;
   circuit_t *circ;
   circuit_t *circ;
-  int n, i;
   time_t now = time(NULL);
   time_t now = time(NULL);
   or_options_t *options = get_options();
   or_options_t *options = get_options();
   int severity;
   int severity;
   int cutoff;
   int cutoff;
   int seconds_idle;
   int seconds_idle;
+  smartlist_t *conns = get_connection_array();
 
 
-  get_connection_array(&carray, &n);
-
-  for (i = 0; i < n; ++i) {
-    if (carray[i]->type != CONN_TYPE_AP)
+  SMARTLIST_FOREACH(conns, connection_t *, c,
+  {
+    if (c->type != CONN_TYPE_AP)
       continue;
       continue;
-    conn = TO_EDGE_CONN(carray[i]);
+    conn = TO_EDGE_CONN(c);
     /* if it's an internal bridge connection, don't yell its status. */
     /* if it's an internal bridge connection, don't yell its status. */
     severity = (!conn->_base.addr && !conn->_base.port)
     severity = (!conn->_base.addr && !conn->_base.port)
       ? LOG_INFO : LOG_NOTICE;
       ? LOG_INFO : LOG_NOTICE;
@@ -431,7 +429,7 @@ connection_ap_expire_beginning(void)
                                        END_STREAM_REASON_TIMEOUT)<0) {
                                        END_STREAM_REASON_TIMEOUT)<0) {
       connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
       connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
     }
     }
-  } /* end for */
+  }); /* end foreach */
 }
 }
 
 
 /** Tell any AP streams that are waiting for a new circuit to try again,
 /** Tell any AP streams that are waiting for a new circuit to try again,
@@ -440,15 +438,10 @@ connection_ap_expire_beginning(void)
 void
 void
 connection_ap_attach_pending(void)
 connection_ap_attach_pending(void)
 {
 {
-  connection_t **carray;
-  connection_t *conn;
   edge_connection_t *edge_conn;
   edge_connection_t *edge_conn;
-  int n, i;
-
-  get_connection_array(&carray, &n);
-
-  for (i = 0; i < n; ++i) {
-    conn = carray[i];
+  smartlist_t *conns = get_connection_array();
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (conn->marked_for_close ||
     if (conn->marked_for_close ||
         conn->type != CONN_TYPE_AP ||
         conn->type != CONN_TYPE_AP ||
         conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
         conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
@@ -457,7 +450,7 @@ connection_ap_attach_pending(void)
     if (connection_ap_handshake_attach_circuit(edge_conn) < 0) {
     if (connection_ap_handshake_attach_circuit(edge_conn) < 0) {
       connection_mark_unattached_ap(edge_conn, END_STREAM_REASON_CANT_ATTACH);
       connection_mark_unattached_ap(edge_conn, END_STREAM_REASON_CANT_ATTACH);
     }
     }
-  }
+  });
 }
 }
 
 
 /** A circuit failed to finish on its last hop <b>info</b>. If there
 /** A circuit failed to finish on its last hop <b>info</b>. If there
@@ -467,16 +460,12 @@ connection_ap_attach_pending(void)
 void
 void
 circuit_discard_optional_exit_enclaves(extend_info_t *info)
 circuit_discard_optional_exit_enclaves(extend_info_t *info)
 {
 {
-  connection_t **carray;
-  connection_t *conn;
   edge_connection_t *edge_conn;
   edge_connection_t *edge_conn;
   routerinfo_t *r1, *r2;
   routerinfo_t *r1, *r2;
-  int n, i;
-
-  get_connection_array(&carray, &n);
 
 
-  for (i = 0; i < n; ++i) {
-    conn = carray[i];
+  smartlist_t *conns = get_connection_array();
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (conn->marked_for_close ||
     if (conn->marked_for_close ||
         conn->type != CONN_TYPE_AP ||
         conn->type != CONN_TYPE_AP ||
         !conn->chosen_exit_optional)
         !conn->chosen_exit_optional)
@@ -492,7 +481,7 @@ circuit_discard_optional_exit_enclaves(extend_info_t *info)
       conn->chosen_exit_optional = 0;
       conn->chosen_exit_optional = 0;
       tor_free(edge_conn->chosen_exit_name); /* clears it */
       tor_free(edge_conn->chosen_exit_name); /* clears it */
     }
     }
-  }
+  });
 }
 }
 
 
 /** The AP connection <b>conn</b> has just failed while attaching or
 /** The AP connection <b>conn</b> has just failed while attaching or

+ 4 - 7
src/or/connection_or.c

@@ -65,18 +65,15 @@ connection_or_remove_from_identity_map(or_connection_t *conn)
 void
 void
 connection_or_clear_identity_map(void)
 connection_or_clear_identity_map(void)
 {
 {
-  int i, n;
-  connection_t **carray;
-
-  get_connection_array(&carray,&n);
-  for (i = 0; i < n; ++i) {
-    connection_t* conn = carray[i];
+  smartlist_t *conns = get_connection_array();
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (conn->type == CONN_TYPE_OR) {
     if (conn->type == CONN_TYPE_OR) {
       or_connection_t *or_conn = TO_OR_CONN(conn);
       or_connection_t *or_conn = TO_OR_CONN(conn);
       memset(or_conn->identity_digest, 0, DIGEST_LEN);
       memset(or_conn->identity_digest, 0, DIGEST_LEN);
       or_conn->next_with_same_id = NULL;
       or_conn->next_with_same_id = NULL;
     }
     }
-  }
+  });
 
 
   if (orconn_identity_map) {
   if (orconn_identity_map) {
     digestmap_free(orconn_identity_map, NULL);
     digestmap_free(orconn_identity_map, NULL);

+ 49 - 55
src/or/control.c

@@ -175,25 +175,24 @@ log_severity_to_event(int severity)
 void
 void
 control_update_global_event_mask(void)
 control_update_global_event_mask(void)
 {
 {
-  connection_t **conns;
-  int n_conns, i;
+  smartlist_t *conns = get_connection_array();
   event_mask_t old_mask, new_mask;
   event_mask_t old_mask, new_mask;
   old_mask = global_event_mask1short;
   old_mask = global_event_mask1short;
   old_mask |= global_event_mask1long;
   old_mask |= global_event_mask1long;
 
 
   global_event_mask1short = 0;
   global_event_mask1short = 0;
   global_event_mask1long = 0;
   global_event_mask1long = 0;
-  get_connection_array(&conns, &n_conns);
-  for (i = 0; i < n_conns; ++i) {
-    if (conns[i]->type == CONN_TYPE_CONTROL &&
-        STATE_IS_OPEN(conns[i]->state)) {
-      control_connection_t *conn = TO_CONTROL_CONN(conns[i]);
+  SMARTLIST_FOREACH(conns, connection_t *, _conn,
+  {
+    if (_conn->type == CONN_TYPE_CONTROL &&
+        STATE_IS_OPEN(_conn->state)) {
+      control_connection_t *conn = TO_CONTROL_CONN(_conn);
       if (conn->use_long_names)
       if (conn->use_long_names)
         global_event_mask1long |= conn->event_mask;
         global_event_mask1long |= conn->event_mask;
       else
       else
         global_event_mask1short |= conn->event_mask;
         global_event_mask1short |= conn->event_mask;
     }
     }
-  }
+  });
 
 
   new_mask = global_event_mask1short;
   new_mask = global_event_mask1short;
   new_mask |= global_event_mask1long;
   new_mask |= global_event_mask1long;
@@ -206,12 +205,13 @@ control_update_global_event_mask(void)
    * fields. */
    * fields. */
   if (! (old_mask & EVENT_STREAM_BANDWIDTH_USED) &&
   if (! (old_mask & EVENT_STREAM_BANDWIDTH_USED) &&
       (new_mask & EVENT_STREAM_BANDWIDTH_USED)) {
       (new_mask & EVENT_STREAM_BANDWIDTH_USED)) {
-    for (i = 0; i < n_conns; ++i) {
-      if (conns[i]->type == CONN_TYPE_AP) {
-        edge_connection_t *conn = TO_EDGE_CONN(conns[i]);
-        conn->n_written = conn->n_read = 0;
+    SMARTLIST_FOREACH(conns, connection_t *, conn,
+    {
+      if (conn->type == CONN_TYPE_AP) {
+        edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
+        edge_conn->n_written = edge_conn->n_read = 0;
       }
       }
-    }
+    });
   }
   }
 }
 }
 
 
@@ -461,17 +461,15 @@ static void
 send_control_event_string(uint16_t event, event_format_t which,
 send_control_event_string(uint16_t event, event_format_t which,
                           const char *msg)
                           const char *msg)
 {
 {
-  connection_t **conns;
-  int n_conns, i;
-
+  smartlist_t *conns = get_connection_array();
   tor_assert(event >= _EVENT_MIN && event <= _EVENT_MAX);
   tor_assert(event >= _EVENT_MIN && event <= _EVENT_MAX);
 
 
-  get_connection_array(&conns, &n_conns);
-  for (i = 0; i < n_conns; ++i) {
-    if (conns[i]->type == CONN_TYPE_CONTROL &&
-        !conns[i]->marked_for_close &&
-        conns[i]->state == CONTROL_CONN_STATE_OPEN) {
-      control_connection_t *control_conn = TO_CONTROL_CONN(conns[i]);
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
+    if (conn->type == CONN_TYPE_CONTROL &&
+        !conn->marked_for_close &&
+        conn->state == CONTROL_CONN_STATE_OPEN) {
+      control_connection_t *control_conn = TO_CONTROL_CONN(conn);
       if (control_conn->use_long_names) {
       if (control_conn->use_long_names) {
         if (!(which & LONG_NAMES))
         if (!(which & LONG_NAMES))
           continue;
           continue;
@@ -501,7 +499,7 @@ send_control_event_string(uint16_t event, event_format_t which,
           connection_handle_write(TO_CONN(control_conn), 1);
           connection_handle_write(TO_CONN(control_conn), 1);
       }
       }
     }
     }
-  }
+  });
 }
 }
 
 
 /** Helper for send_control1_event and send_control1_event_extended:
 /** Helper for send_control1_event and send_control1_event_extended:
@@ -1361,24 +1359,23 @@ getinfo_helper_events(control_connection_t *control_conn,
     SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
     SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
     smartlist_free(status);
     smartlist_free(status);
   } else if (!strcmp(question, "stream-status")) {
   } else if (!strcmp(question, "stream-status")) {
-    connection_t **conns;
-    int n_conns, i;
-    char buf[256];
+    smartlist_t *conns = get_connection_array();
     smartlist_t *status = smartlist_create();
     smartlist_t *status = smartlist_create();
-    get_connection_array(&conns, &n_conns);
-    for (i=0; i < n_conns; ++i) {
+    char buf[256];
+    SMARTLIST_FOREACH(conns, connection_t *, base_conn,
+    {
       const char *state;
       const char *state;
       edge_connection_t *conn;
       edge_connection_t *conn;
       char *s;
       char *s;
       size_t slen;
       size_t slen;
       circuit_t *circ;
       circuit_t *circ;
       origin_circuit_t *origin_circ = NULL;
       origin_circuit_t *origin_circ = NULL;
-      if (conns[i]->type != CONN_TYPE_AP ||
-          conns[i]->marked_for_close ||
-          conns[i]->state == AP_CONN_STATE_SOCKS_WAIT ||
-          conns[i]->state == AP_CONN_STATE_NATD_WAIT)
+      if (base_conn->type != CONN_TYPE_AP ||
+          base_conn->marked_for_close ||
+          base_conn->state == AP_CONN_STATE_SOCKS_WAIT ||
+          base_conn->state == AP_CONN_STATE_NATD_WAIT)
         continue;
         continue;
-      conn = TO_EDGE_CONN(conns[i]);
+      conn = TO_EDGE_CONN(base_conn);
       switch (conn->_base.state)
       switch (conn->_base.state)
         {
         {
         case AP_CONN_STATE_CONTROLLER_WAIT:
         case AP_CONN_STATE_CONTROLLER_WAIT:
@@ -1413,24 +1410,23 @@ getinfo_helper_events(control_connection_t *control_conn,
                          (unsigned long)origin_circ->global_identifier : 0ul,
                          (unsigned long)origin_circ->global_identifier : 0ul,
                    buf);
                    buf);
       smartlist_add(status, s);
       smartlist_add(status, s);
-    }
+    });
     *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
     *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
     SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
     SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
     smartlist_free(status);
     smartlist_free(status);
   } else if (!strcmp(question, "orconn-status")) {
   } else if (!strcmp(question, "orconn-status")) {
-    connection_t **conns;
-    int n_conns, i;
+    smartlist_t *conns = get_connection_array();
     smartlist_t *status = smartlist_create();
     smartlist_t *status = smartlist_create();
-    get_connection_array(&conns, &n_conns);
-    for (i=0; i < n_conns; ++i) {
+    SMARTLIST_FOREACH(conns, connection_t *, base_conn,
+    {
       const char *state;
       const char *state;
       char *s;
       char *s;
       char name[128];
       char name[128];
       size_t slen;
       size_t slen;
       or_connection_t *conn;
       or_connection_t *conn;
-      if (conns[i]->type != CONN_TYPE_OR || conns[i]->marked_for_close)
+      if (base_conn->type != CONN_TYPE_OR || base_conn->marked_for_close)
         continue;
         continue;
-      conn = TO_OR_CONN(conns[i]);
+      conn = TO_OR_CONN(base_conn);
       if (conn->_base.state == OR_CONN_STATE_OPEN)
       if (conn->_base.state == OR_CONN_STATE_OPEN)
         state = "CONNECTED";
         state = "CONNECTED";
       else if (conn->nickname)
       else if (conn->nickname)
@@ -1443,7 +1439,7 @@ getinfo_helper_events(control_connection_t *control_conn,
       s = tor_malloc(slen+1);
       s = tor_malloc(slen+1);
       tor_snprintf(s, slen, "%s %s", name, state);
       tor_snprintf(s, slen, "%s %s", name, state);
       smartlist_add(status, s);
       smartlist_add(status, s);
-    }
+    });
     *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
     *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
     SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
     SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
     smartlist_free(status);
     smartlist_free(status);
@@ -2846,28 +2842,26 @@ control_event_or_conn_status(or_connection_t *conn, or_conn_status_event_t tp,
 int
 int
 control_event_stream_bandwidth_used(void)
 control_event_stream_bandwidth_used(void)
 {
 {
-  connection_t **carray;
-  edge_connection_t *conn;
-  int n, i;
-
   if (EVENT_IS_INTERESTING(EVENT_STREAM_BANDWIDTH_USED)) {
   if (EVENT_IS_INTERESTING(EVENT_STREAM_BANDWIDTH_USED)) {
-    get_connection_array(&carray, &n);
+    smartlist_t *conns = get_connection_array();
+    edge_connection_t *edge_conn;
 
 
-    for (i = 0; i < n; ++i) {
-        if (carray[i]->type != CONN_TYPE_AP)
+    SMARTLIST_FOREACH(conns, connection_t *, conn,
+    {
+        if (conn->type != CONN_TYPE_AP)
           continue;
           continue;
-        conn = TO_EDGE_CONN(carray[i]);
-        if (!conn->n_read && !conn->n_written)
+        edge_conn = TO_EDGE_CONN(conn);
+        if (!edge_conn->n_read && !edge_conn->n_written)
           continue;
           continue;
 
 
         send_control_event(EVENT_STREAM_BANDWIDTH_USED, ALL_NAMES,
         send_control_event(EVENT_STREAM_BANDWIDTH_USED, ALL_NAMES,
                             "650 STREAM_BW %lu %lu %lu\r\n",
                             "650 STREAM_BW %lu %lu %lu\r\n",
-                            (unsigned long)conn->global_identifier,
-                            (unsigned long)conn->n_read,
-                            (unsigned long)conn->n_written);
+                            (unsigned long)edge_conn->global_identifier,
+                            (unsigned long)edge_conn->n_read,
+                            (unsigned long)edge_conn->n_written);
 
 
-        conn->n_written = conn->n_read = 0;
-    }
+        edge_conn->n_written = edge_conn->n_read = 0;
+    });
   }
   }
 
 
   return 0;
   return 0;

+ 4 - 8
src/or/cpuworker.c

@@ -412,14 +412,10 @@ process_pending_task(connection_t *cpuworker)
 static void
 static void
 cull_wedged_cpuworkers(void)
 cull_wedged_cpuworkers(void)
 {
 {
-  connection_t **carray;
-  connection_t *conn;
-  int n_conns, i;
   time_t now = time(NULL);
   time_t now = time(NULL);
-
-  get_connection_array(&carray, &n_conns);
-  for (i = 0; i < n_conns; ++i) {
-    conn = carray[i];
+  smartlist_t *conns = get_connection_array();
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (!conn->marked_for_close &&
     if (!conn->marked_for_close &&
         conn->type == CONN_TYPE_CPUWORKER &&
         conn->type == CONN_TYPE_CPUWORKER &&
         conn->state == CPUWORKER_STATE_BUSY_ONION &&
         conn->state == CPUWORKER_STATE_BUSY_ONION &&
@@ -430,7 +426,7 @@ cull_wedged_cpuworkers(void)
       num_cpuworkers--;
       num_cpuworkers--;
       connection_mark_for_close(conn);
       connection_mark_for_close(conn);
     }
     }
-  }
+  });
 }
 }
 
 
 /** If cpuworker is defined, assert that he's idle, and use him. Else,
 /** If cpuworker is defined, assert that he's idle, and use him. Else,

+ 4 - 8
src/or/directory.c

@@ -1532,19 +1532,15 @@ write_http_response_header(dir_connection_t *conn, ssize_t length,
 static int
 static int
 already_fetching_directory(int purpose)
 already_fetching_directory(int purpose)
 {
 {
-  int i, n;
-  connection_t *conn;
-  connection_t **carray;
-
-  get_connection_array(&carray,&n);
-  for (i=0;i<n;i++) {
-    conn = carray[i];
+  smartlist_t *conns = get_connection_array();
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (conn->type == CONN_TYPE_DIR &&
     if (conn->type == CONN_TYPE_DIR &&
         conn->purpose == purpose &&
         conn->purpose == purpose &&
         !conn->marked_for_close &&
         !conn->marked_for_close &&
         !router_digest_is_me(TO_DIR_CONN(conn)->identity_digest))
         !router_digest_is_me(TO_DIR_CONN(conn)->identity_digest))
       return 1;
       return 1;
-  }
+  });
   return 0;
   return 0;
 }
 }
 
 

+ 33 - 48
src/or/main.c

@@ -67,10 +67,8 @@ static time_t time_of_last_signewnym = 0;
 /** Is there a signewnym request we're currently waiting to handle? */
 /** Is there a signewnym request we're currently waiting to handle? */
 static int signewnym_is_pending = 0;
 static int signewnym_is_pending = 0;
 
 
-/** Array of all open connections.  The first n_conns elements are valid. */
-/*XXXX020 Should we just use a smartlist here? -NM Sure. -RD */
-static connection_t *connection_array[MAXCONNECTIONS+1] =
-        { NULL };
+/** Smartlist of all open connections. */
+static smartlist_t *connection_array = NULL;
 /** List of connections that have been marked for close and need to be freed
 /** List of connections that have been marked for close and need to be freed
  * and removed from connection_array. */
  * and removed from connection_array. */
 static smartlist_t *closeable_connection_lst = NULL;
 static smartlist_t *closeable_connection_lst = NULL;
@@ -79,8 +77,6 @@ static smartlist_t *active_linked_connection_lst = NULL;
 /** DOCDOC */
 /** DOCDOC */
 static int called_loop_once = 0;
 static int called_loop_once = 0;
 
 
-static int n_conns=0; /**< Number of connections currently active. */
-
 /** We set this to 1 when we've opened a circuit, so we can print a log
 /** We set this to 1 when we've opened a circuit, so we can print a log
  * entry to inform the user that Tor is working. */
  * entry to inform the user that Tor is working. */
 int has_completed_circuit=0;
 int has_completed_circuit=0;
@@ -164,13 +160,8 @@ connection_add(connection_t *conn)
   tor_assert(conn->s >= 0 || conn->linked);
   tor_assert(conn->s >= 0 || conn->linked);
 
 
   tor_assert(conn->conn_array_index == -1); /* can only connection_add once */
   tor_assert(conn->conn_array_index == -1); /* can only connection_add once */
-  if (n_conns >= MAXCONNECTIONS) {
-    log_warn(LD_BUG, "Unable to add a connection; MAXCONNECTIONS is set too "
-             "low.  This is a bug; tell the developers.");
-    return -1;
-  }
-  conn->conn_array_index = n_conns;
-  connection_array[n_conns] = conn;
+  conn->conn_array_index = smartlist_len(connection_array);
+  smartlist_add(connection_array, conn);
 
 
   conn->read_event = tor_malloc_zero(sizeof(struct event));
   conn->read_event = tor_malloc_zero(sizeof(struct event));
   conn->write_event = tor_malloc_zero(sizeof(struct event));
   conn->write_event = tor_malloc_zero(sizeof(struct event));
@@ -179,10 +170,9 @@ connection_add(connection_t *conn)
   event_set(conn->write_event, conn->s, EV_WRITE|EV_PERSIST,
   event_set(conn->write_event, conn->s, EV_WRITE|EV_PERSIST,
             conn_write_callback, conn);
             conn_write_callback, conn);
 
 
-  n_conns++;
-
   log_debug(LD_NET,"new conn type %s, socket %d, n_conns %d.",
   log_debug(LD_NET,"new conn type %s, socket %d, n_conns %d.",
-            conn_type_to_string(conn->type), conn->s, n_conns);
+            conn_type_to_string(conn->type), conn->s,
+            smartlist_len(connection_array));
 
 
   return 0;
   return 0;
 }
 }
@@ -195,25 +185,26 @@ int
 connection_remove(connection_t *conn)
 connection_remove(connection_t *conn)
 {
 {
   int current_index;
   int current_index;
+  connection_t *tmp;
 
 
   tor_assert(conn);
   tor_assert(conn);
-  tor_assert(n_conns>0);
 
 
   log_debug(LD_NET,"removing socket %d (type %s), n_conns now %d",
   log_debug(LD_NET,"removing socket %d (type %s), n_conns now %d",
-            conn->s, conn_type_to_string(conn->type), n_conns-1);
+            conn->s, conn_type_to_string(conn->type),
+            smartlist_len(connection_array));
 
 
   tor_assert(conn->conn_array_index >= 0);
   tor_assert(conn->conn_array_index >= 0);
   current_index = conn->conn_array_index;
   current_index = conn->conn_array_index;
   connection_unregister_events(conn); /* This is redundant, but cheap. */
   connection_unregister_events(conn); /* This is redundant, but cheap. */
-  if (current_index == n_conns-1) { /* this is the end */
-    n_conns--;
+  if (current_index == smartlist_len(connection_array)-1) { /* at the end */
+    smartlist_del(connection_array, current_index);
     return 0;
     return 0;
   }
   }
 
 
   /* replace this one with the one at the end */
   /* replace this one with the one at the end */
-  n_conns--;
-  connection_array[current_index] = connection_array[n_conns];
-  connection_array[current_index]->conn_array_index = current_index;
+  smartlist_del(connection_array, current_index);
+  tmp = smartlist_get(connection_array, current_index);
+  tmp->conn_array_index = current_index;
 
 
   return 0;
   return 0;
 }
 }
@@ -274,23 +265,17 @@ connection_is_on_closeable_list(connection_t *conn)
 int
 int
 connection_in_array(connection_t *conn)
 connection_in_array(connection_t *conn)
 {
 {
-  int i;
-  for (i=0; i<n_conns; ++i) {
-    if (conn==connection_array[i])
-      return 1;
-  }
-  return 0;
+  return smartlist_isin(connection_array, conn);
 }
 }
 
 
 /** Set <b>*array</b> to an array of all connections, and <b>*n</b>
 /** Set <b>*array</b> to an array of all connections, and <b>*n</b>
  * to the length of the array. <b>*array</b> and <b>*n</b> must not
  * to the length of the array. <b>*array</b> and <b>*n</b> must not
  * be modified.
  * be modified.
  */
  */
-void
-get_connection_array(connection_t ***array, int *n)
+smartlist_t *
+get_connection_array(void)
 {
 {
-  *array = connection_array;
-  *n = n_conns;
+  return connection_array;
 }
 }
 
 
 /** Set the event mask on <b>conn</b> to <b>events</b>.  (The event
 /** Set the event mask on <b>conn</b> to <b>events</b>.  (The event
@@ -549,7 +534,7 @@ conn_close_if_marked(int i)
   connection_t *conn;
   connection_t *conn;
   int retval;
   int retval;
 
 
-  conn = connection_array[i];
+  conn = smartlist_get(connection_array, i);
   if (!conn->marked_for_close)
   if (!conn->marked_for_close)
     return 0; /* nothing to see here, move along */
     return 0; /* nothing to see here, move along */
   assert_connection_ok(conn, time(NULL));
   assert_connection_ok(conn, time(NULL));
@@ -687,7 +672,7 @@ static void
 run_connection_housekeeping(int i, time_t now)
 run_connection_housekeeping(int i, time_t now)
 {
 {
   cell_t cell;
   cell_t cell;
-  connection_t *conn = connection_array[i];
+  connection_t *conn = smartlist_get(connection_array, i);
   or_options_t *options = get_options();
   or_options_t *options = get_options();
   or_connection_t *or_conn;
   or_connection_t *or_conn;
 
 
@@ -1015,17 +1000,16 @@ run_scheduled_events(time_t now)
     circuit_build_needed_circs(now);
     circuit_build_needed_circs(now);
 
 
   /** 5. We do housekeeping for each connection... */
   /** 5. We do housekeeping for each connection... */
-  for (i=0;i<n_conns;i++) {
+  for (i=0;i<smartlist_len(connection_array);i++) {
     run_connection_housekeeping(i, now);
     run_connection_housekeeping(i, now);
   }
   }
   if (time_to_shrink_memory < now) {
   if (time_to_shrink_memory < now) {
-    for (i=0;i<n_conns;i++) {
-      connection_t *conn = connection_array[i];
-      if (conn->outbuf)
-        buf_shrink(conn->outbuf);
-      if (conn->inbuf)
-        buf_shrink(conn->inbuf);
-    }
+    SMARTLIST_FOREACH(connection_array, connection_t *, conn, {
+        if (conn->outbuf)
+          buf_shrink(conn->outbuf);
+        if (conn->inbuf)
+          buf_shrink(conn->inbuf);
+      });
     clean_cell_pool();
     clean_cell_pool();
     buf_shrink_freelists();
     buf_shrink_freelists();
     time_to_shrink_memory = now + MEM_SHRINK_INTERVAL;
     time_to_shrink_memory = now + MEM_SHRINK_INTERVAL;
@@ -1535,15 +1519,14 @@ dumpmemusage(int severity)
 static void
 static void
 dumpstats(int severity)
 dumpstats(int severity)
 {
 {
-  int i;
-  connection_t *conn;
   time_t now = time(NULL);
   time_t now = time(NULL);
   time_t elapsed;
   time_t elapsed;
 
 
   log(severity, LD_GENERAL, "Dumping stats:");
   log(severity, LD_GENERAL, "Dumping stats:");
 
 
-  for (i=0;i<n_conns;i++) {
-    conn = connection_array[i];
+  SMARTLIST_FOREACH(connection_array, connection_t *, conn,
+  {
+    int i = conn_sl_idx;
     log(severity, LD_GENERAL,
     log(severity, LD_GENERAL,
         "Conn %d (socket %d) type %d (%s), state %d (%s), created %d secs ago",
         "Conn %d (socket %d) type %d (%s), state %d (%s), created %d secs ago",
         i, conn->s, conn->type, conn_type_to_string(conn->type),
         i, conn->s, conn->type, conn_type_to_string(conn->type),
@@ -1568,7 +1551,7 @@ dumpstats(int severity)
     }
     }
     circuit_dump_by_conn(conn, severity); /* dump info about all the circuits
     circuit_dump_by_conn(conn, severity); /* dump info about all the circuits
                                            * using this conn */
                                            * using this conn */
-  }
+  });
   log(severity, LD_NET,
   log(severity, LD_NET,
       "Cells processed: "U64_FORMAT" padding\n"
       "Cells processed: "U64_FORMAT" padding\n"
       "                 "U64_FORMAT" create\n"
       "                 "U64_FORMAT" create\n"
@@ -1686,6 +1669,8 @@ tor_init(int argc, char *argv[])
 {
 {
   char buf[256];
   char buf[256];
   time_of_process_start = time(NULL);
   time_of_process_start = time(NULL);
+  if (!connection_array)
+    connection_array = smartlist_create();
   if (!closeable_connection_lst)
   if (!closeable_connection_lst)
     closeable_connection_lst = smartlist_create();
     closeable_connection_lst = smartlist_create();
   if (!active_linked_connection_lst)
   if (!active_linked_connection_lst)

+ 1 - 1
src/or/or.h

@@ -2676,7 +2676,7 @@ int connection_in_array(connection_t *conn);
 void add_connection_to_closeable_list(connection_t *conn);
 void add_connection_to_closeable_list(connection_t *conn);
 int connection_is_on_closeable_list(connection_t *conn);
 int connection_is_on_closeable_list(connection_t *conn);
 
 
-void get_connection_array(connection_t ***array, int *n);
+smartlist_t *get_connection_array(void);
 
 
 void connection_watch_events(connection_t *conn, short events);
 void connection_watch_events(connection_t *conn, short events);
 int connection_is_reading(connection_t *conn);
 int connection_is_reading(connection_t *conn);

+ 8 - 10
src/or/rendclient.c

@@ -433,17 +433,15 @@ rend_client_desc_here(const char *query)
   edge_connection_t *conn;
   edge_connection_t *conn;
   rend_cache_entry_t *entry;
   rend_cache_entry_t *entry;
   time_t now = time(NULL);
   time_t now = time(NULL);
-  int i, n_conns;
-  connection_t **carray;
 
 
-  get_connection_array(&carray, &n_conns);
-
-  for (i = 0; i < n_conns; ++i) {
-    if (carray[i]->type != CONN_TYPE_AP ||
-        carray[i]->state != AP_CONN_STATE_RENDDESC_WAIT ||
-        carray[i]->marked_for_close)
+  smartlist_t *conns = get_connection_array();
+  SMARTLIST_FOREACH(conns, connection_t *, _conn,
+  {
+    if (_conn->type != CONN_TYPE_AP ||
+        _conn->state != AP_CONN_STATE_RENDDESC_WAIT ||
+        _conn->marked_for_close)
       continue;
       continue;
-    conn = TO_EDGE_CONN(carray[i]);
+    conn = TO_EDGE_CONN(_conn);
     if (rend_cmp_service_ids(query, conn->rend_query))
     if (rend_cmp_service_ids(query, conn->rend_query))
       continue;
       continue;
     assert_connection_ok(TO_CONN(conn), now);
     assert_connection_ok(TO_CONN(conn), now);
@@ -470,7 +468,7 @@ rend_client_desc_here(const char *query)
                  "unavailable (try again later).", safe_str(query));
                  "unavailable (try again later).", safe_str(query));
       connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
       connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
     }
     }
-  }
+  });
 }
 }
 
 
 /** Return a newly allocated extend_info_t* for a randomly chosen introduction
 /** Return a newly allocated extend_info_t* for a randomly chosen introduction

+ 4 - 6
src/or/routerlist.c

@@ -4169,17 +4169,15 @@ list_pending_descriptor_downloads(digestmap_t *result, int extrainfo)
 {
 {
   const char *prefix = "d/";
   const char *prefix = "d/";
   size_t p_len = strlen(prefix);
   size_t p_len = strlen(prefix);
-  int i, n_conns;
-  connection_t **carray;
   smartlist_t *tmp = smartlist_create();
   smartlist_t *tmp = smartlist_create();
   int purpose =
   int purpose =
     extrainfo ? DIR_PURPOSE_FETCH_EXTRAINFO : DIR_PURPOSE_FETCH_SERVERDESC;
     extrainfo ? DIR_PURPOSE_FETCH_EXTRAINFO : DIR_PURPOSE_FETCH_SERVERDESC;
+  smartlist_t *conns = get_connection_array();
 
 
   tor_assert(result);
   tor_assert(result);
-  get_connection_array(&carray, &n_conns);
 
 
-  for (i = 0; i < n_conns; ++i) {
-    connection_t *conn = carray[i];
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
     if (conn->type == CONN_TYPE_DIR &&
     if (conn->type == CONN_TYPE_DIR &&
         conn->purpose == purpose &&
         conn->purpose == purpose &&
         !conn->marked_for_close) {
         !conn->marked_for_close) {
@@ -4188,7 +4186,7 @@ list_pending_descriptor_downloads(digestmap_t *result, int extrainfo)
         dir_split_resource_into_fingerprints(resource + p_len,
         dir_split_resource_into_fingerprints(resource + p_len,
                                              tmp, NULL, 1, 0);
                                              tmp, NULL, 1, 0);
     }
     }
-  }
+  });
   SMARTLIST_FOREACH(tmp, char *, d,
   SMARTLIST_FOREACH(tmp, char *, d,
                     {
                     {
                       digestmap_set(result, d, (void*)1);
                       digestmap_set(result, d, (void*)1);