Browse Source

Implement OOS comparator

Andrea Shepard 7 years ago
parent
commit
709f2cbf58
1 changed files with 49 additions and 1 deletions
  1. 49 1
      src/or/connection.c

+ 49 - 1
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) {