[tor-commits] [tor/master] Implement circuitmux policy basic notifications mechanism

andrea at torproject.org andrea at torproject.org
Thu Oct 11 02:05:23 UTC 2012


commit 851734d3245dfd56be02f6f4a78a3b776f4ebedc
Author: Andrea Shepard <andrea at torproject.org>
Date:   Thu Sep 27 11:38:27 2012 -0700

    Implement circuitmux policy basic notifications mechanism
---
 src/or/circuitmux.c |   59 +++++++++++++++++++++++++++++++++++++-------------
 src/or/circuitmux.h |   57 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+), 16 deletions(-)

diff --git a/src/or/circuitmux.c b/src/or/circuitmux.c
index 77bb568..860ba64 100644
--- a/src/or/circuitmux.c
+++ b/src/or/circuitmux.c
@@ -88,21 +88,14 @@ struct circuitmux_s {
   struct circuit_t *active_circuits_head, *active_circuits_tail;
 
   /*
-   * Priority queue of cell_ewma_t for circuits with queued cells waiting
-   * for room to free up on this connection's outbuf.  Kept in heap order
-   * according to EWMA.
-   *
-   * This is redundant with active_circuits; if we ever decide only to use
-   * the cell_ewma algorithm for choosing circuits, we can remove
-   * active_circuits.
+   * Circuitmux policy; if this is non-NULL, it can override the built-
+   * in round-robin active circuits behavior.  This is how EWMA works in
+   * the new circuitmux_t world.
    */
-  smartlist_t *active_circuit_pqueue;
+  const circuitmux_policy_t *policy;
 
-  /*
-   * The tick on which the cell_ewma_ts in active_circuit_pqueue last had
-   * their ewma values rescaled.
-   */
-  unsigned int active_circuit_pqueue_last_recalibrated;
+  /* Policy-specific data */
+  circuitmux_policy_data_t *policy_data;
 };
 
 /*
@@ -115,6 +108,8 @@ struct circuit_muxinfo_s {
   unsigned int cell_count;
   /* Direction of flow */
   cell_direction_t direction;
+  /* Policy-specific data */
+  circuitmux_policy_circ_data_t *policy_data;
 };
 
 /*
@@ -321,7 +316,13 @@ circuitmux_free(circuitmux_t *cmux)
   tor_assert(cmux->n_circuits == 0);
   tor_assert(cmux->n_active_circuits == 0);
 
-  smartlist_free(cmux->active_circuit_pqueue);
+  /* Free policy-specific data if we have any */
+  if (cmux->policy && cmux->policy->free_cmux_data) {
+    if (cmux->policy_data) {
+      cmux->policy->free_cmux_data(cmux, cmux->policy_data);
+      cmux->policy_data = NULL;
+    }
+  } else tor_assert(cmux->policy_data == NULL);
 
   if (cmux->chanid_circid_map) {
     HT_CLEAR(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
@@ -718,6 +719,7 @@ circuitmux_make_circuit_active(circuitmux_t *cmux, circuit_t *circ,
 {
   circuit_t **next_active = NULL, **prev_active = NULL, **next_prev = NULL;
   circuitmux_t *circuit_cmux = NULL;
+  chanid_circid_muxinfo_t *hashent = NULL;
   channel_t *chan = NULL;
   circid_t circ_id;
   int already_active;
@@ -782,7 +784,19 @@ circuitmux_make_circuit_active(circuitmux_t *cmux, circuit_t *circ,
   /* This becomes the new head of the list */
   cmux->active_circuits_head = circ;
 
-  /* TODO policy-specific notifications */
+  /* Policy-specific notification */
+  if (cmux->policy &&
+      cmux->policy->notify_circ_active &&
+      cmux->policy_data) {
+    /* Okay, we need to check the circuit for policy data now */
+    hashent = circuitmux_find_map_entry(cmux, circ);
+    /* We should have found something */
+    tor_assert(hashent);
+    /* Check for policy data for the circuit and notify */
+    if (hashent->muxinfo.policy_data)
+      cmux->policy->notify_circ_active(cmux, cmux->policy_data,
+                                       circ, hashent->muxinfo.policy_data);
+  }
 }
 
 /**
@@ -797,6 +811,7 @@ circuitmux_make_circuit_inactive(circuitmux_t *cmux, circuit_t *circ,
   circuit_t **next_active = NULL, **prev_active = NULL;
   circuit_t **next_prev = NULL, **prev_next = NULL;
   circuitmux_t *circuit_cmux = NULL;
+  chanid_circid_muxinfo_t *hashent = NULL;
   channel_t *chan = NULL;
   circid_t circ_id;
   int already_inactive;
@@ -878,7 +893,19 @@ circuitmux_make_circuit_inactive(circuitmux_t *cmux, circuit_t *circ,
   *prev_active = NULL;
   *next_active = NULL;
 
-  /* TODO policy-specific notifications */
+  /* Policy-specific notification */
+  if (cmux->policy &&
+      cmux->policy->notify_circ_inactive &&
+      cmux->policy_data) {
+    /* Okay, we need to check the circuit for policy data now */
+    hashent = circuitmux_find_map_entry(cmux, circ);
+    /* We should have found something */
+    tor_assert(hashent);
+    /* Check for policy data for the circuit and notify */
+    if (hashent->muxinfo.policy_data)
+      cmux->policy->notify_circ_inactive(cmux, cmux->policy_data,
+                                         circ, hashent->muxinfo.policy_data);
+  }
 }
 
 /**
diff --git a/src/or/circuitmux.h b/src/or/circuitmux.h
index ade544f..e344b6e 100644
--- a/src/or/circuitmux.h
+++ b/src/or/circuitmux.h
@@ -11,6 +11,57 @@
 
 #include "or.h"
 
+typedef struct circuitmux_policy_s circuitmux_policy_t;
+typedef struct circuitmux_policy_data_s circuitmux_policy_data_t;
+typedef struct circuitmux_policy_circ_data_s circuitmux_policy_circ_data_t;
+
+struct circuitmux_policy_s {
+  /* Allocate cmux-wide policy-specific data */
+  circuitmux_policy_data_t * (*alloc_cmux_data)(circuitmux_t *cmux);
+  /* Free cmux-wide policy-specific data */
+  void (*free_cmux_data)(circuitmux_t *cmux,
+                         circuitmux_policy_data_t *pol_data);
+  /* Allocate circuit policy-specific data for a newly attached circuit */
+  circuitmux_policy_circ_data_t *
+    (*alloc_circ_data)(circuitmux_t *cmux,
+                       circuitmux_policy_data_t *pol_data,
+                       circuit_t *circ,
+                       cell_direction_t direction,
+                       unsigned int cell_count);
+  /* Free circuit policy-specific data */
+  void (*free_circ_data)(circuitmux_t *cmux,
+                         circuitmux_policy_data_t *pol_data,
+                         circuit_t *circ,
+                         circuitmux_policy_circ_data_t *pol_circ_data);
+  /* Notify that a circuit has become active/inactive */
+  void (*notify_circ_active)(circuitmux_t *cmux,
+                             circuitmux_policy_data_t *pol_data,
+                             circuit_t *circ,
+                             circuitmux_policy_circ_data_t *pol_circ_data);
+  void (*notify_circ_inactive)(circuitmux_t *cmux,
+                               circuitmux_policy_data_t *pol_data,
+                               circuit_t *circ,
+                               circuitmux_policy_circ_data_t *pol_circ_data);
+};
+
+/*
+ * Circuitmux policy implementations can subclass this to store circuitmux-
+ * wide data; it just has the magic number in the base struct.
+ */
+
+struct circuitmux_policy_data_s {
+  uint32_t magic;
+};
+
+/*
+ * Circuitmux policy implementations can subclass this to store circuit-
+ * specific data; it just has the magic number in the base struct.
+ */
+
+struct circuitmux_policy_circ_data_s {
+  uint32_t magic;
+};
+
 /* Consistency check */
 void circuitmux_assert_okay(circuitmux_t *cmux);
 
@@ -19,6 +70,12 @@ circuitmux_t * circuitmux_alloc(void);
 void circuitmux_detach_all_circuits(circuitmux_t *cmux);
 void circuitmux_free(circuitmux_t *cmux);
 
+/* Policy control */
+void circuitmux_clear_policy(circuitmux_t *cmux);
+const circuitmux_policy_t * circuitmux_get_policy(circuitmux_t *cmux);
+void circuitmux_set_policy(circuitmux_t *cmux,
+                           const circuitmux_policy_t *pol);
+
 /* Status inquiries */
 cell_direction_t circuitmux_attached_circuit_direction(
     circuitmux_t *cmux,





More information about the tor-commits mailing list