|
@@ -1951,3 +1951,51 @@ circuitmux_count_queued_destroy_cells(const channel_t *chan,
|
|
|
return n_destroy_cells;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Compare cmuxes to see which is more preferred; return < 0 if
|
|
|
+ * cmux_1 has higher priority (i.e., cmux_1 < cmux_2 in the scheduler's
|
|
|
+ * sort order), > 0 if cmux_2 has higher priority, or 0 if they are
|
|
|
+ * equally preferred.
|
|
|
+ *
|
|
|
+ * If the cmuxes have different cmux policies or the policy does not
|
|
|
+ * support the cmp_cmux method, return 0.
|
|
|
+ */
|
|
|
+
|
|
|
+int
|
|
|
+circuitmux_compare_muxes(circuitmux_t *cmux_1, circuitmux_t *cmux_2)
|
|
|
+{
|
|
|
+ const circuitmux_policy_t *policy;
|
|
|
+
|
|
|
+ tor_assert(cmux_1);
|
|
|
+ tor_assert(cmux_2);
|
|
|
+
|
|
|
+ if (cmux_1 == cmux_2) {
|
|
|
+ /* Equivalent because they're the same cmux */
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cmux_1->policy && cmux_2->policy) {
|
|
|
+ if (cmux_1->policy == cmux_2->policy) {
|
|
|
+ policy = cmux_1->policy;
|
|
|
+
|
|
|
+ if (policy->cmp_cmux) {
|
|
|
+ /* Okay, we can compare! */
|
|
|
+ return policy->cmp_cmux(cmux_1, cmux_1->policy_data,
|
|
|
+ cmux_2, cmux_2->policy_data);
|
|
|
+ } else {
|
|
|
+ /*
|
|
|
+ * Equivalent because the policy doesn't know how to compare between
|
|
|
+ * muxes.
|
|
|
+ */
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ /* Equivalent because they have different policies */
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ /* Equivalent because one or both are missing a policy */
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|