summaryrefslogtreecommitdiff
path: root/src/or/connection.c
diff options
context:
space:
mode:
authorAndrea Shepard <andrea@torproject.org>2016-07-01 21:05:13 +0000
committerAndrea Shepard <andrea@torproject.org>2016-08-20 01:43:51 +0000
commit709f2cbf58c0acc4c84035dadc6be4846b5d3f3e (patch)
treed0542fbf97f20ab65f9a552e5176fccc59dc39b2 /src/or/connection.c
parentd502efbd47abebea4f92ea55c4566f130c90ce0e (diff)
downloadtor-709f2cbf58c0acc4c84035dadc6be4846b5d3f3e.tar.gz
tor-709f2cbf58c0acc4c84035dadc6be4846b5d3f3e.zip
Implement OOS comparator
Diffstat (limited to 'src/or/connection.c')
-rw-r--r--src/or/connection.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/src/or/connection.c b/src/or/connection.c
index 18b8a7e62e..9c80d97e4d 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -4500,6 +4500,53 @@ connection_reached_eof(connection_t *conn)
}
}
+/** Comparator for the two-orconn case in OOS victim sort */
+static int
+oos_victim_comparator_for_orconns(or_connection_t *a, or_connection_t *b)
+{
+ int a_circs, b_circs;
+ /* Fewer circuits == higher priority for OOS kill, sort earlier */
+
+ a_circs = connection_or_get_num_circuits(a);
+ b_circs = connection_or_get_num_circuits(b);
+
+ if (a_circs < b_circs) return -1;
+ else if (b_circs > a_circs) return 1;
+ else return 0;
+}
+
+/** Sort comparator for OOS victims; better targets sort before worse
+ * ones. */
+static int
+oos_victim_comparator(const void **a_v, const void **b_v)
+{
+ connection_t *a = NULL, *b = NULL;
+
+ /* Get connection pointers out */
+
+ a = (connection_t *)(*a_v);
+ b = (connection_t *)(*b_v);
+
+ tor_assert(a != NULL);
+ tor_assert(b != NULL);
+
+ /*
+ * We always prefer orconns as victims currently; we won't even see
+ * these non-orconn cases, but if we do, sort them after orconns.
+ */
+ if (a->type == CONN_TYPE_OR && b->type == CONN_TYPE_OR) {
+ return oos_victim_comparator_for_orconns(TO_OR_CONN(a), TO_OR_CONN(b));
+ } else {
+ /*
+ * One isn't an orconn; if one is, it goes first. We currently have no
+ * opinions about cases where neither is an orconn.
+ */
+ if (a->type == CONN_TYPE_OR) return -1;
+ else if (b->type == CONN_TYPE_OR) return 1;
+ else return 0;
+ }
+}
+
/** Pick n victim connections for the OOS handler and return them in a
* smartlist.
*/
@@ -4574,7 +4621,8 @@ pick_oos_victims(int n)
/* Did we find more eligible targets than we want to kill? */
if (smartlist_len(eligible) > n) {
- /* TODO sort */
+ /* Sort the list in order of target preference */
+ smartlist_sort(eligible, oos_victim_comparator);
/* Pick first n as victims */
victims = smartlist_new();
for (i = 0; i < n; ++i) {