Commit 6975a093 authored by Nick Mathewson's avatar Nick Mathewson 🌉
Browse files

r12853@catbus: nickm | 2007-05-22 11:36:54 -0400

 Make connection_array into a smartlist.


svn:r10292
parent e935d73b
......@@ -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
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 @@ Changes in version 0.2.0.1-alpha - 2007-??-??
- 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
......
......@@ -1145,25 +1145,25 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
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 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime,
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 @@ 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. */
}); /* 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. */
......
......@@ -385,21 +385,19 @@ connection_free(connection_t *conn)
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 @@ _connection_mark_for_close(connection_t *conn, int line, const char *file)
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 @@ connection_expire_held_open(void)
conn->hold_open_until_flushed = 0;
}
}
}
});
}
/** Bind a new non-blocking socket listening to
......@@ -995,12 +991,11 @@ retry_listeners(int type, config_line_t *cfg,
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 @@ retry_listeners(int type, config_line_t *cfg,
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 @@ retry_listeners(int type, config_line_t *cfg,
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 @@ retry_listeners(int type, config_line_t *cfg,
}
smartlist_free(launch);
return i;
return r;
}
/** (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
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 @@ connection_bucket_refill(int seconds_elapsed)
"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 @@ connection_bucket_refill(int seconds_elapsed)
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 @@ _connection_write_to_buf_impl(const char *string, size_t len,
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 @@ connection_get_by_type_addr_port_purpose(int type,
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 @@ connection_get_by_type_addr_port_purpose(int type,
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_get_by_global_id(uint32_t id)
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_get_by_type(int type)
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_get_by_type_state(int type, int state)
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_t *
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 @@ connection_get_by_type_state_rendquery(int type, int state,
!rend_cmp_service_ids(rendquery, TO_EDGE_CONN(conn)->rend_query))
return conn;
}
}
});
return NULL;
}
......@@ -2217,18 +2183,14 @@ connection_get_by_type_state_rendquery(int type, int state,
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 @@ connection_dump_buffer_mem_stats(int severity)
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 @@ connection_dump_buffer_mem_stats(int severity)
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 @@ connection_dump_buffer_mem_stats(int severity)
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;
......
......@@ -343,22 +343,20 @@ compute_retry_timeout(edge_connection_t *conn)
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 @@ connection_ap_expire_beginning(void)
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 @@ connection_ap_expire_beginning(void)
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 @@ connection_ap_attach_pending(void)
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 @@ connection_ap_attach_pending(void)
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 @@ circuit_discard_optional_exit_enclaves(extend_info_t *info)
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
......
......@@ -65,18 +65,15 @@ connection_or_remove_from_identity_map(or_connection_t *conn)
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);
......
......@@ -175,25 +175,24 @@ log_severity_to_event(int severity)
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 @@ control_update_global_event_mask(void)
* 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 @@ static void
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);