diff options
author | Andrea Shepard <andrea@torproject.org> | 2016-06-30 14:54:58 +0000 |
---|---|---|
committer | Andrea Shepard <andrea@torproject.org> | 2016-08-20 01:43:51 +0000 |
commit | d502efbd47abebea4f92ea55c4566f130c90ce0e (patch) | |
tree | 7cd0cfa3da24298bbbfa8b34c1b380b4e3220dd5 /src/or/connection.c | |
parent | e9464737af4b31e0aba29eb5581a5faf80647800 (diff) | |
download | tor-d502efbd47abebea4f92ea55c4566f130c90ce0e.tar.gz tor-d502efbd47abebea4f92ea55c4566f130c90ce0e.zip |
Implement pick_oos_victims() except for sort step
Diffstat (limited to 'src/or/connection.c')
-rw-r--r-- | src/or/connection.c | 83 |
1 files changed, 79 insertions, 4 deletions
diff --git a/src/or/connection.c b/src/or/connection.c index e164fae15c..18b8a7e62e 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -4506,13 +4506,88 @@ connection_reached_eof(connection_t *conn) static smartlist_t * pick_oos_victims(int n) { - smartlist_t *conns = NULL; + smartlist_t *eligible = NULL, *victims = NULL; + smartlist_t *conns; + int conn_counts_by_type[CONN_TYPE_MAX_ + 1], i; + + /* + * Big damn assumption (someone improve this someday!): + * + * Socket exhaustion normally happens on high-volume relays, and so + * most of the connections involved are orconns. We should pick victims + * by assembling a list of all orconns, and sorting them in order of + * how much 'damage' by some metric we'd be doing by dropping them. + * + * If we move on from orconns, we should probably think about incoming + * directory connections next, or exit connections. Things we should + * probably never kill are controller connections and listeners. + * + * This function will count how many connections of different types + * exist and log it for purposes of gathering data on typical OOS + * situations to guide future improvements. + */ + + /* First, get the connection array */ + conns = get_connection_array(); + /* + * Iterate it and pick out eligible connection types, and log some stats + * along the way. + */ + eligible = smartlist_new(); + memset(conn_counts_by_type, 0, sizeof(conn_counts_by_type)); + SMARTLIST_FOREACH_BEGIN(conns, connection_t *, c) { + /* Bump the counter */ + tor_assert(c->type <= CONN_TYPE_MAX_); + ++(conn_counts_by_type[c->type]); + + /* Skip anything we would count as moribund */ + if (c->conn_array_index < 0 || + c->marked_for_close) { + continue; + } + + switch (c->type) { + case CONN_TYPE_OR: + /* We've got an orconn, it's eligible to be OOSed */ + smartlist_add(eligible, c); + break; + default: + /* We don't know what to do with it, ignore it */ + break; + } + } SMARTLIST_FOREACH_END(c); - (void)n; + /* Log some stats */ + if (smartlist_len(conns) > 0) { + /* At least one counter must be non-zero */ + log_info(LD_NET, "Some stats on conn types seen during OOS follow"); + for (i = CONN_TYPE_MIN_; i <= CONN_TYPE_MAX_; ++i) { + /* Did we see any? */ + if (conn_counts_by_type[i] > 0) { + log_info(LD_NET, "%s: %d conns", + conn_type_to_string(i), + conn_counts_by_type[i]); + } + } + log_info(LD_NET, "Done with OOS conn type stats"); + } - /* TODO */ + /* Did we find more eligible targets than we want to kill? */ + if (smartlist_len(eligible) > n) { + /* TODO sort */ + /* Pick first n as victims */ + victims = smartlist_new(); + for (i = 0; i < n; ++i) { + smartlist_add(victims, smartlist_get(eligible, i)); + } + /* Free the original list */ + smartlist_free(eligible); + } else { + /* No, we can just call them all victims */ + victims = eligible; + } - return conns; + return victims; } /** Kill a list of connections for the OOS handler. */ |