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

[or-cvs] r10292: Make connection_array into a smartlist. (in tor/trunk: . src/or)



Author: nickm
Date: 2007-05-22 11:49:14 -0400 (Tue, 22 May 2007)
New Revision: 10292

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/src/or/circuitbuild.c
   tor/trunk/src/or/connection.c
   tor/trunk/src/or/connection_edge.c
   tor/trunk/src/or/connection_or.c
   tor/trunk/src/or/control.c
   tor/trunk/src/or/cpuworker.c
   tor/trunk/src/or/directory.c
   tor/trunk/src/or/main.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/rendclient.c
   tor/trunk/src/or/routerlist.c
Log:
 r12853@catbus:  nickm | 2007-05-22 11:36:54 -0400
 Make connection_array into a smartlist.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r12853] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2007-05-22 15:48:46 UTC (rev 10291)
+++ tor/trunk/ChangeLog	2007-05-22 15:49:14 UTC (rev 10292)
@@ -76,6 +76,7 @@
       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
       the last-detected version if we're building from a .tar.gz.
+      Use this version consistently in log messages.
 
   o Minor features (logging):
     - Always prepend "Bug: " to any log message about a bug.
@@ -181,6 +182,9 @@
     - Make dns_resolve() handle attaching connections to circuits
       properly, so the caller doesn't have to.
     - 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

Modified: tor/trunk/src/or/circuitbuild.c
===================================================================
--- tor/trunk/src/or/circuitbuild.c	2007-05-22 15:48:46 UTC (rev 10291)
+++ tor/trunk/src/or/circuitbuild.c	2007-05-22 15:49:14 UTC (rev 10292)
@@ -1145,25 +1145,25 @@
                                 int need_capacity)
 {
   int *n_supported;
-  int i, j;
+  int i;
   int n_pending_connections = 0;
-  connection_t **carray;
-  int n_connections;
+  smartlist_t *connections;
   int best_support = -1;
   int n_best_support=0;
   smartlist_t *sl, *preferredexits, *excludedexits;
   routerinfo_t *router;
   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.
    * 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;
-  }
+  });
 //  log_fn(LOG_DEBUG, "Choosing exit node; %d connections are pending",
 //         n_pending_connections);
   /* Now we count, for each of the routers in the directory, how many
@@ -1204,10 +1204,12 @@
       continue; /* skip routers that reject all */
     }
     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 */
-      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];
 //        log_fn(LOG_DEBUG,"%s is supported. n_supported[%d] now %d.",
 //               router->nickname, i, n_supported[i]);
@@ -1215,7 +1217,7 @@
 //        log_fn(LOG_DEBUG,"%s (index %d) would reject this stream.",
 //               router->nickname, i);
       }
-    } /* End looping over connections. */
+    }); /* End looping over connections. */
     if (n_supported[i] > best_support) {
       /* If this router is better than previous ones, remember its index
        * and goodness, and start counting how many routers are this good. */

Modified: tor/trunk/src/or/connection.c
===================================================================
--- tor/trunk/src/or/connection.c	2007-05-22 15:48:46 UTC (rev 10291)
+++ tor/trunk/src/or/connection.c	2007-05-22 15:49:14 UTC (rev 10292)
@@ -385,21 +385,19 @@
 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. */
-  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();
 
   /* Unlink everything from the 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) {
     SMARTLIST_FOREACH(outgoing_addrs, void*, addr, tor_free(addr));
@@ -583,15 +581,13 @@
 void
 connection_expire_held_open(void)
 {
-  connection_t **carray, *conn;
-  int n, i;
   time_t now;
+  smartlist_t *conns = get_connection_array();
 
   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
      * for 15 seconds...
      */
@@ -613,7 +609,7 @@
         conn->hold_open_until_flushed = 0;
       }
     }
-  }
+  });
 }
 
 /** Bind a new non-blocking socket listening to
@@ -995,12 +991,11 @@
                 smartlist_t *new_conns,
                 int never_open_conns)
 {
-  smartlist_t *launch = smartlist_create();
+  smartlist_t *launch = smartlist_create(), *conns;
   int free_launch_elts = 1;
+  int r;
   config_line_t *c;
-  int n_conn, i;
   connection_t *conn;
-  connection_t **carray;
   config_line_t *line;
 
   if (cfg && port_option) {
@@ -1020,9 +1015,9 @@
                     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)
       continue;
     if (force) {
@@ -1069,17 +1064,17 @@
       if (free_launch_elts)
         config_free_lines(line);
     }
-  }
+  });
 
   /* Now open all the listeners that are configured but not opened. */
-  i = 0;
+  r = 0;
   if (!never_open_conns) {
     SMARTLIST_FOREACH(launch, config_line_t *, cfg_line,
       {
         conn = connection_create_listener(cfg_line->value,
                                           (uint16_t) port_option, type);
         if (!conn) {
-          i = -1;
+          r = -1;
         } else {
           if (new_conns)
             smartlist_add(new_conns, conn);
@@ -1093,7 +1088,7 @@
   }
   smartlist_free(launch);
 
-  return i;
+  return r;
 }
 
 /** (Re)launch listeners for each port you should have open.  If
@@ -1416,10 +1411,8 @@
 void
 connection_bucket_refill(int seconds_elapsed)
 {
-  int i, n;
-  connection_t *conn;
-  connection_t **carray;
   or_options_t *options = get_options();
+  smartlist_t *conns = get_connection_array();
   int relayrate, relayburst;
 
   if (options->RelayBandwidthRate) {
@@ -1452,10 +1445,8 @@
                                   "global_relayed_write_bucket");
 
   /* 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)) {
       or_connection_t *or_conn = TO_OR_CONN(conn);
       if (connection_read_bucket_should_increase(or_conn)) {
@@ -1491,7 +1482,7 @@
       conn->write_blocked_on_bw = 0;
       connection_start_writing(conn);
     }
-  }
+  });
 }
 
 /** Is the receiver bucket for connection <b>conn</b> low enough that we
@@ -2057,21 +2048,18 @@
 or_connection_t *
 connection_or_exact_get_by_addr_port(uint32_t addr, uint16_t port)
 {
-  int i, n;
-  connection_t *conn;
   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 &&
         conn->addr == addr &&
         conn->port == port &&
         !conn->marked_for_close &&
         (!best || best->_base.timestamp_created < conn->timestamp_created))
       best = TO_OR_CONN(conn);
-  }
+  });
   return best;
 }
 
@@ -2082,20 +2070,16 @@
                                          uint32_t addr, uint16_t port,
                                          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 &&
         conn->addr == addr &&
         conn->port == port &&
         conn->purpose == purpose &&
         !conn->marked_for_close)
       return conn;
-  }
+  });
   return NULL;
 }
 
@@ -2105,20 +2089,16 @@
 edge_connection_t *
 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->marked_for_close)
         return TO_EDGE_CONN(conn);
       else
         return NULL;
     }
-  }
+  });
   return NULL;
 }
 
@@ -2127,16 +2107,12 @@
 connection_t *
 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)
       return conn;
-  }
+  });
   return NULL;
 }
 
@@ -2146,16 +2122,12 @@
 connection_t *
 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)
       return conn;
-  }
+  });
   return NULL;
 }
 
@@ -2166,17 +2138,14 @@
 connection_t *
 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 (!best || conn->timestamp_lastwritten < best->timestamp_lastwritten)
         best = conn;
-  }
+  });
   return best;
 }
 
@@ -2188,16 +2157,13 @@
 connection_get_by_type_state_rendquery(int type, int state,
                                        const char *rendquery)
 {
-  int i, n;
-  connection_t *conn;
-  connection_t **carray;
+  smartlist_t *conns = get_connection_array();
 
   tor_assert(type == CONN_TYPE_DIR ||
              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 &&
         !conn->marked_for_close &&
         (!state || state == conn->state)) {
@@ -2208,7 +2174,7 @@
               !rend_cmp_service_ids(rendquery, TO_EDGE_CONN(conn)->rend_query))
         return conn;
     }
-  }
+  });
   return NULL;
 }
 
@@ -2217,18 +2183,14 @@
 connection_t *
 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 &&
         !conn->marked_for_close &&
         (purpose == conn->purpose))
       return conn;
-  }
+  });
   return NULL;
 }
 
@@ -2511,17 +2473,15 @@
   int n_conns_by_type[_CONN_TYPE_MAX+1];
   uint64_t total_alloc = 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(alloc_by_type, 0, sizeof(alloc_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;
     ++n_conns_by_type[tp];
     if (c->inbuf) {
@@ -2532,7 +2492,7 @@
       used_by_type[tp] += buf_datalen(c->outbuf);
       alloc_by_type[tp] += buf_capacity(c->outbuf);
     }
-  }
+  });
   for (i=0; i <= _CONN_TYPE_MAX; ++i) {
     total_used += used_by_type[i];
     total_alloc += alloc_by_type[i];
@@ -2540,7 +2500,8 @@
 
   log(severity, LD_GENERAL,
      "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) {
     if (!n_conns_by_type[i])
       continue;

Modified: tor/trunk/src/or/connection_edge.c
===================================================================
--- tor/trunk/src/or/connection_edge.c	2007-05-22 15:48:46 UTC (rev 10291)
+++ tor/trunk/src/or/connection_edge.c	2007-05-22 15:49:14 UTC (rev 10292)
@@ -343,22 +343,20 @@
 void
 connection_ap_expire_beginning(void)
 {
-  connection_t **carray;
   edge_connection_t *conn;
   circuit_t *circ;
-  int n, i;
   time_t now = time(NULL);
   or_options_t *options = get_options();
   int severity;
   int cutoff;
   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;
-    conn = TO_EDGE_CONN(carray[i]);
+    conn = TO_EDGE_CONN(c);
     /* if it's an internal bridge connection, don't yell its status. */
     severity = (!conn->_base.addr && !conn->_base.port)
       ? LOG_INFO : LOG_NOTICE;
@@ -431,7 +429,7 @@
                                        END_STREAM_REASON_TIMEOUT)<0) {
       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,
@@ -440,15 +438,10 @@
 void
 connection_ap_attach_pending(void)
 {
-  connection_t **carray;
-  connection_t *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 ||
         conn->type != CONN_TYPE_AP ||
         conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
@@ -457,7 +450,7 @@
     if (connection_ap_handshake_attach_circuit(edge_conn) < 0) {
       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
@@ -467,16 +460,12 @@
 void
 circuit_discard_optional_exit_enclaves(extend_info_t *info)
 {
-  connection_t **carray;
-  connection_t *conn;
   edge_connection_t *edge_conn;
   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 ||
         conn->type != CONN_TYPE_AP ||
         !conn->chosen_exit_optional)
@@ -492,7 +481,7 @@
       conn->chosen_exit_optional = 0;
       tor_free(edge_conn->chosen_exit_name); /* clears it */
     }
-  }
+  });
 }
 
 /** The AP connection <b>conn</b> has just failed while attaching or

Modified: tor/trunk/src/or/connection_or.c
===================================================================
--- tor/trunk/src/or/connection_or.c	2007-05-22 15:48:46 UTC (rev 10291)
+++ tor/trunk/src/or/connection_or.c	2007-05-22 15:49:14 UTC (rev 10292)
@@ -65,18 +65,15 @@
 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) {
       or_connection_t *or_conn = TO_OR_CONN(conn);
       memset(or_conn->identity_digest, 0, DIGEST_LEN);
       or_conn->next_with_same_id = NULL;
     }
-  }
+  });
 
   if (orconn_identity_map) {
     digestmap_free(orconn_identity_map, NULL);

Modified: tor/trunk/src/or/control.c
===================================================================
--- tor/trunk/src/or/control.c	2007-05-22 15:48:46 UTC (rev 10291)
+++ tor/trunk/src/or/control.c	2007-05-22 15:49:14 UTC (rev 10292)
@@ -175,25 +175,24 @@
 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;
   old_mask = global_event_mask1short;
   old_mask |= global_event_mask1long;
 
   global_event_mask1short = 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)
         global_event_mask1long |= conn->event_mask;
       else
         global_event_mask1short |= conn->event_mask;
     }
-  }
+  });
 
   new_mask = global_event_mask1short;
   new_mask |= global_event_mask1long;
@@ -206,12 +205,13 @@
    * fields. */
   if (! (old_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 @@
 send_control_event_string(uint16_t event, event_format_t which,
                           const char *msg)
 {
-  connection_t **conns;
-  int n_conns, i;
-
+  smartlist_t *conns = get_connection_array();
   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 (!(which & LONG_NAMES))
           continue;
@@ -501,7 +499,7 @@
           connection_handle_write(TO_CONN(control_conn), 1);
       }
     }
-  }
+  });
 }
 
 /** Helper for send_control1_event and send_control1_event_extended:
@@ -1361,24 +1359,23 @@
     SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
     smartlist_free(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();
-    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;
       edge_connection_t *conn;
       char *s;
       size_t slen;
       circuit_t *circ;
       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;
-      conn = TO_EDGE_CONN(conns[i]);
+      conn = TO_EDGE_CONN(base_conn);
       switch (conn->_base.state)
         {
         case AP_CONN_STATE_CONTROLLER_WAIT:
@@ -1413,24 +1410,23 @@
                          (unsigned long)origin_circ->global_identifier : 0ul,
                    buf);
       smartlist_add(status, s);
-    }
+    });
     *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
     SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
     smartlist_free(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();
-    get_connection_array(&conns, &n_conns);
-    for (i=0; i < n_conns; ++i) {
+    SMARTLIST_FOREACH(conns, connection_t *, base_conn,
+    {
       const char *state;
       char *s;
       char name[128];
       size_t slen;
       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;
-      conn = TO_OR_CONN(conns[i]);
+      conn = TO_OR_CONN(base_conn);
       if (conn->_base.state == OR_CONN_STATE_OPEN)
         state = "CONNECTED";
       else if (conn->nickname)
@@ -1443,7 +1439,7 @@
       s = tor_malloc(slen+1);
       tor_snprintf(s, slen, "%s %s", name, state);
       smartlist_add(status, s);
-    }
+    });
     *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
     SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
     smartlist_free(status);
@@ -2846,28 +2842,26 @@
 int
 control_event_stream_bandwidth_used(void)
 {
-  connection_t **carray;
-  edge_connection_t *conn;
-  int n, i;
-
   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;
-        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;
 
         send_control_event(EVENT_STREAM_BANDWIDTH_USED, ALL_NAMES,
                             "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;

Modified: tor/trunk/src/or/cpuworker.c
===================================================================
--- tor/trunk/src/or/cpuworker.c	2007-05-22 15:48:46 UTC (rev 10291)
+++ tor/trunk/src/or/cpuworker.c	2007-05-22 15:49:14 UTC (rev 10292)
@@ -412,14 +412,10 @@
 static void
 cull_wedged_cpuworkers(void)
 {
-  connection_t **carray;
-  connection_t *conn;
-  int n_conns, i;
   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 &&
         conn->type == CONN_TYPE_CPUWORKER &&
         conn->state == CPUWORKER_STATE_BUSY_ONION &&
@@ -430,7 +426,7 @@
       num_cpuworkers--;
       connection_mark_for_close(conn);
     }
-  }
+  });
 }
 
 /** If cpuworker is defined, assert that he's idle, and use him. Else,

Modified: tor/trunk/src/or/directory.c
===================================================================
--- tor/trunk/src/or/directory.c	2007-05-22 15:48:46 UTC (rev 10291)
+++ tor/trunk/src/or/directory.c	2007-05-22 15:49:14 UTC (rev 10292)
@@ -1532,19 +1532,15 @@
 static int
 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 &&
         conn->purpose == purpose &&
         !conn->marked_for_close &&
         !router_digest_is_me(TO_DIR_CONN(conn)->identity_digest))
       return 1;
-  }
+  });
   return 0;
 }
 

Modified: tor/trunk/src/or/main.c
===================================================================
--- tor/trunk/src/or/main.c	2007-05-22 15:48:46 UTC (rev 10291)
+++ tor/trunk/src/or/main.c	2007-05-22 15:49:14 UTC (rev 10292)
@@ -67,10 +67,8 @@
 /** Is there a signewnym request we're currently waiting to handle? */
 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
  * and removed from connection_array. */
 static smartlist_t *closeable_connection_lst = NULL;
@@ -79,8 +77,6 @@
 /** DOCDOC */
 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
  * entry to inform the user that Tor is working. */
 int has_completed_circuit=0;
@@ -164,13 +160,8 @@
   tor_assert(conn->s >= 0 || conn->linked);
 
   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->write_event = tor_malloc_zero(sizeof(struct event));
@@ -179,10 +170,9 @@
   event_set(conn->write_event, conn->s, EV_WRITE|EV_PERSIST,
             conn_write_callback, conn);
 
-  n_conns++;
-
   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;
 }
@@ -195,25 +185,26 @@
 connection_remove(connection_t *conn)
 {
   int current_index;
+  connection_t *tmp;
 
   tor_assert(conn);
-  tor_assert(n_conns>0);
 
   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);
   current_index = conn->conn_array_index;
   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;
   }
 
   /* 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;
 }
@@ -274,23 +265,17 @@
 int
 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>
  * to the length of the array. <b>*array</b> and <b>*n</b> must not
  * 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
@@ -549,7 +534,7 @@
   connection_t *conn;
   int retval;
 
-  conn = connection_array[i];
+  conn = smartlist_get(connection_array, i);
   if (!conn->marked_for_close)
     return 0; /* nothing to see here, move along */
   assert_connection_ok(conn, time(NULL));
@@ -687,7 +672,7 @@
 run_connection_housekeeping(int i, time_t now)
 {
   cell_t cell;
-  connection_t *conn = connection_array[i];
+  connection_t *conn = smartlist_get(connection_array, i);
   or_options_t *options = get_options();
   or_connection_t *or_conn;
 
@@ -1015,17 +1000,16 @@
     circuit_build_needed_circs(now);
 
   /** 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);
   }
   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();
     buf_shrink_freelists();
     time_to_shrink_memory = now + MEM_SHRINK_INTERVAL;
@@ -1535,15 +1519,14 @@
 static void
 dumpstats(int severity)
 {
-  int i;
-  connection_t *conn;
   time_t now = time(NULL);
   time_t elapsed;
 
   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,
         "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),
@@ -1568,7 +1551,7 @@
     }
     circuit_dump_by_conn(conn, severity); /* dump info about all the circuits
                                            * using this conn */
-  }
+  });
   log(severity, LD_NET,
       "Cells processed: "U64_FORMAT" padding\n"
       "                 "U64_FORMAT" create\n"
@@ -1686,6 +1669,8 @@
 {
   char buf[256];
   time_of_process_start = time(NULL);
+  if (!connection_array)
+    connection_array = smartlist_create();
   if (!closeable_connection_lst)
     closeable_connection_lst = smartlist_create();
   if (!active_linked_connection_lst)

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-05-22 15:48:46 UTC (rev 10291)
+++ tor/trunk/src/or/or.h	2007-05-22 15:49:14 UTC (rev 10292)
@@ -2676,7 +2676,7 @@
 void add_connection_to_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);
 int connection_is_reading(connection_t *conn);

Modified: tor/trunk/src/or/rendclient.c
===================================================================
--- tor/trunk/src/or/rendclient.c	2007-05-22 15:48:46 UTC (rev 10291)
+++ tor/trunk/src/or/rendclient.c	2007-05-22 15:49:14 UTC (rev 10292)
@@ -433,17 +433,15 @@
   edge_connection_t *conn;
   rend_cache_entry_t *entry;
   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;
-    conn = TO_EDGE_CONN(carray[i]);
+    conn = TO_EDGE_CONN(_conn);
     if (rend_cmp_service_ids(query, conn->rend_query))
       continue;
     assert_connection_ok(TO_CONN(conn), now);
@@ -470,7 +468,7 @@
                  "unavailable (try again later).", safe_str(query));
       connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
     }
-  }
+  });
 }
 
 /** Return a newly allocated extend_info_t* for a randomly chosen introduction

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2007-05-22 15:48:46 UTC (rev 10291)
+++ tor/trunk/src/or/routerlist.c	2007-05-22 15:49:14 UTC (rev 10292)
@@ -4169,17 +4169,15 @@
 {
   const char *prefix = "d/";
   size_t p_len = strlen(prefix);
-  int i, n_conns;
-  connection_t **carray;
   smartlist_t *tmp = smartlist_create();
   int purpose =
     extrainfo ? DIR_PURPOSE_FETCH_EXTRAINFO : DIR_PURPOSE_FETCH_SERVERDESC;
+  smartlist_t *conns = get_connection_array();
 
   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 &&
         conn->purpose == purpose &&
         !conn->marked_for_close) {
@@ -4188,7 +4186,7 @@
         dir_split_resource_into_fingerprints(resource + p_len,
                                              tmp, NULL, 1, 0);
     }
-  }
+  });
   SMARTLIST_FOREACH(tmp, char *, d,
                     {
                       digestmap_set(result, d, (void*)1);