| 
					
				 | 
			
			
				@@ -9,6 +9,33 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "or.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "circuitmux.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Private typedefs for circuitmux.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Map of muxinfos for circuitmux_t to use; struct is defined below (name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * of struct must match HT_HEAD line). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+typedef struct chanid_circid_muxinfo_map chanid_circid_muxinfo_map_t; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Hash table entry (yeah, calling it chanid_circid_muxinfo_s seems to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * break the hash table code). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+typedef struct chanid_circid_muxinfo_t chanid_circid_muxinfo_t; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Anything the mux wants to store per-circuit in the map; right now just 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * a count of queued cells. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+typedef struct circuit_muxinfo_s circuit_muxinfo_t; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Structures for circuitmux.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * A circuitmux is a collection of circuits; it tracks which subset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * of the attached circuits are 'active' (i.e., have cells available 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -40,6 +67,14 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 struct circuitmux_s { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Keep count of attached, active circuits */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  unsigned int n_circuits, n_active_circuits; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * Map from (channel ID, circuit ID) pairs to circuit_muxinfo_t 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  chanid_circid_muxinfo_map_t *chanid_circid_map; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    * Double-linked ring of circuits with queued cells waiting for room to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    * free up on this connection's outbuf.  Every time we pull cells from 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -62,6 +97,113 @@ struct circuitmux_s { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    * The tick on which the cell_ewma_ts in active_circuit_pqueue last had 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    * their ewma values rescaled. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  unsigned active_circuit_pqueue_last_recalibrated; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  unsigned int active_circuit_pqueue_last_recalibrated; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * This struct holds whatever we want to store per attached circuit on a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * circuitmux_t; right now, just the count of queued cells. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct circuit_muxinfo_s { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  unsigned int cell_count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * A map from channel ID and circuit ID to a circuit_muxinfo_t for that 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * circuit. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct chanid_circid_muxinfo_t { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  HT_ENTRY(chanid_circid_muxinfo_t) node; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  uint64_t chan_id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  circid_t circ_id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  circuit_muxinfo_t muxinfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Static function declarations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static INLINE int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+chanid_circid_entries_eq(chanid_circid_muxinfo_t *a, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                         chanid_circid_muxinfo_t *b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static INLINE unsigned int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+chanid_circid_entry_hash(chanid_circid_muxinfo_t *a); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* Function definitions */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Helper for chanid_circid_cell_count_map_t hash table: compare the channel 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * ID and circuit ID for a and b, and return less than, equal to, or greater 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * than zero appropriately. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static INLINE int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+chanid_circid_entries_eq(chanid_circid_muxinfo_t *a, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                         chanid_circid_muxinfo_t *b) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return a->chan_id == b->chan_id && a->circ_id == b->circ_id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Helper: return a hash based on circuit ID and channel ID in a. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static INLINE unsigned int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+chanid_circid_entry_hash(chanid_circid_muxinfo_t *a) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return (((unsigned int)(a->circ_id) << 8) ^ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ((unsigned int)((a->chan_id >> 32) & 0xffffffff)) ^ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ((unsigned int)(a->chan_id & 0xffffffff))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* Declare the struct chanid_circid_muxinfo_map type */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+HT_HEAD(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* Emit a bunch of hash table stuff */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+HT_PROTOTYPE(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             chanid_circid_entry_hash, chanid_circid_entries_eq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+HT_GENERATE(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            chanid_circid_entry_hash, chanid_circid_entries_eq, 0.6, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            malloc, realloc, free); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Allocate a new circuitmux_t 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+circuitmux_t * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+circuitmux_alloc(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  circuitmux_t *rv = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  rv = tor_malloc_zero(sizeof(*rv)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  rv->chanid_circid_map = tor_malloc_zero(sizeof(*( rv->chanid_circid_map))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  HT_INIT(chanid_circid_muxinfo_map, rv->chanid_circid_map); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return rv; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Free a circuitmux_t; the circuits must be detached first with 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * circuitmux_detach_all_circuits(). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+circuitmux_free(circuitmux_t *cmux) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!cmux) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_assert(cmux->n_circuits == 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_assert(cmux->n_active_circuits == 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  smartlist_free(cmux->active_circuit_pqueue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (cmux->chanid_circid_map) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    HT_CLEAR(chanid_circid_muxinfo_map, cmux->chanid_circid_map); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tor_free(cmux->chanid_circid_map); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tor_free(cmux); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 |