From 709f2cbf58c0acc4c84035dadc6be4846b5d3f3e Mon Sep 17 00:00:00 2001 From: Andrea Shepard Date: Fri, 1 Jul 2016 21:05:13 +0000 Subject: [PATCH] Implement OOS comparator --- src/or/connection.c | 50 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) 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) {