circuitmux.h (8141B)
1 /* * Copyright (c) 2012-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 /** 5 * \file circuitmux.h 6 * \brief Header file for circuitmux.c 7 **/ 8 9 #ifndef TOR_CIRCUITMUX_H 10 #define TOR_CIRCUITMUX_H 11 12 #include "core/or/or.h" 13 #include "lib/testsupport/testsupport.h" 14 15 typedef struct circuitmux_policy_t circuitmux_policy_t; 16 typedef struct circuitmux_policy_data_t circuitmux_policy_data_t; 17 typedef struct circuitmux_policy_circ_data_t circuitmux_policy_circ_data_t; 18 19 struct circuitmux_policy_t { 20 /* Allocate cmux-wide policy-specific data */ 21 circuitmux_policy_data_t * (*alloc_cmux_data)(circuitmux_t *cmux); 22 /* Free cmux-wide policy-specific data */ 23 void (*free_cmux_data)(circuitmux_t *cmux, 24 circuitmux_policy_data_t *pol_data); 25 /* Allocate circuit policy-specific data for a newly attached circuit */ 26 circuitmux_policy_circ_data_t * 27 (*alloc_circ_data)(circuitmux_t *cmux, 28 circuitmux_policy_data_t *pol_data, 29 circuit_t *circ, 30 cell_direction_t direction, 31 unsigned int cell_count); 32 /* Free circuit policy-specific data */ 33 void (*free_circ_data)(circuitmux_t *cmux, 34 circuitmux_policy_data_t *pol_data, 35 circuit_t *circ, 36 circuitmux_policy_circ_data_t *pol_circ_data); 37 /* Notify that a circuit has become active/inactive */ 38 void (*notify_circ_active)(circuitmux_t *cmux, 39 circuitmux_policy_data_t *pol_data, 40 circuit_t *circ, 41 circuitmux_policy_circ_data_t *pol_circ_data); 42 void (*notify_circ_inactive)(circuitmux_t *cmux, 43 circuitmux_policy_data_t *pol_data, 44 circuit_t *circ, 45 circuitmux_policy_circ_data_t *pol_circ_data); 46 /* Notify of arriving/transmitted cells on a circuit */ 47 void (*notify_set_n_cells)(circuitmux_t *cmux, 48 circuitmux_policy_data_t *pol_data, 49 circuit_t *circ, 50 circuitmux_policy_circ_data_t *pol_circ_data, 51 unsigned int n_cells); 52 void (*notify_xmit_cells)(circuitmux_t *cmux, 53 circuitmux_policy_data_t *pol_data, 54 circuit_t *circ, 55 circuitmux_policy_circ_data_t *pol_circ_data, 56 unsigned int n_cells); 57 /* Choose a circuit */ 58 circuit_t * (*pick_active_circuit)(circuitmux_t *cmux, 59 circuitmux_policy_data_t *pol_data); 60 /* Optional: channel comparator for use by the scheduler */ 61 int (*cmp_cmux)(circuitmux_t *cmux_1, circuitmux_policy_data_t *pol_data_1, 62 circuitmux_t *cmux_2, circuitmux_policy_data_t *pol_data_2); 63 }; 64 65 /* 66 * Circuitmux policy implementations can subclass this to store circuitmux- 67 * wide data; it just has the magic number in the base struct. 68 */ 69 70 struct circuitmux_policy_data_t { 71 uint32_t magic; 72 }; 73 74 /* 75 * Circuitmux policy implementations can subclass this to store circuit- 76 * specific data; it just has the magic number in the base struct. 77 */ 78 79 struct circuitmux_policy_circ_data_t { 80 uint32_t magic; 81 }; 82 83 /* 84 * Upcast #defines for the above types 85 */ 86 87 /** 88 * Convert a circuitmux_policy_data_t subtype to a circuitmux_policy_data_t. 89 */ 90 91 #define TO_CMUX_POL_DATA(x) (&((x)->base_)) 92 93 /** 94 * Convert a circuitmux_policy_circ_data_t subtype to a 95 * circuitmux_policy_circ_data_t. 96 */ 97 98 #define TO_CMUX_POL_CIRC_DATA(x) (&((x)->base_)) 99 100 /* Consistency check */ 101 void circuitmux_assert_okay(circuitmux_t *cmux); 102 103 /* Create/destroy */ 104 circuitmux_t * circuitmux_alloc(void); 105 void circuitmux_detach_all_circuits(circuitmux_t *cmux, 106 smartlist_t *detached_out); 107 void circuitmux_free_(circuitmux_t *cmux); 108 #define circuitmux_free(cmux) \ 109 FREE_AND_NULL(circuitmux_t, circuitmux_free_, (cmux)) 110 111 /* Policy control */ 112 void circuitmux_clear_policy(circuitmux_t *cmux); 113 MOCK_DECL(const circuitmux_policy_t *, 114 circuitmux_get_policy, (circuitmux_t *cmux)); 115 void circuitmux_set_policy(circuitmux_t *cmux, 116 const circuitmux_policy_t *pol); 117 118 /* Status inquiries */ 119 cell_direction_t circuitmux_attached_circuit_direction( 120 circuitmux_t *cmux, 121 circuit_t *circ); 122 int circuitmux_is_circuit_attached(circuitmux_t *cmux, circuit_t *circ); 123 int circuitmux_is_circuit_active(circuitmux_t *cmux, circuit_t *circ); 124 unsigned int circuitmux_num_cells_for_circuit(circuitmux_t *cmux, 125 circuit_t *circ); 126 MOCK_DECL(unsigned int, circuitmux_num_cells, (circuitmux_t *cmux)); 127 unsigned int circuitmux_num_circuits(circuitmux_t *cmux); 128 unsigned int circuitmux_num_active_circuits(circuitmux_t *cmux); 129 130 /* Debugging interface - slow. */ 131 int64_t circuitmux_count_queued_destroy_cells(const channel_t *chan, 132 const circuitmux_t *cmux); 133 134 /* Channel interface */ 135 circuit_t * circuitmux_get_first_active_circuit(circuitmux_t *cmux, 136 destroy_cell_queue_t **destroy_queue_out); 137 void circuitmux_notify_xmit_cells(circuitmux_t *cmux, circuit_t *circ, 138 unsigned int n_cells); 139 void circuitmux_notify_xmit_destroy(circuitmux_t *cmux); 140 141 /* Circuit interface */ 142 MOCK_DECL(void, circuitmux_attach_circuit, (circuitmux_t *cmux, 143 circuit_t *circ, 144 cell_direction_t direction)); 145 MOCK_DECL(void, circuitmux_detach_circuit, 146 (circuitmux_t *cmux, circuit_t *circ)); 147 void circuitmux_clear_num_cells(circuitmux_t *cmux, circuit_t *circ); 148 void circuitmux_set_num_cells(circuitmux_t *cmux, circuit_t *circ, 149 unsigned int n_cells); 150 151 void circuitmux_append_destroy_cell(channel_t *chan, 152 circuitmux_t *cmux, circid_t circ_id, 153 uint8_t reason); 154 void circuitmux_mark_destroyed_circids_usable(circuitmux_t *cmux, 155 channel_t *chan); 156 157 /* Optional interchannel comparisons for scheduling */ 158 MOCK_DECL(int, circuitmux_compare_muxes, 159 (circuitmux_t *cmux_1, circuitmux_t *cmux_2)); 160 161 #ifdef CIRCUITMUX_PRIVATE 162 163 #include "core/or/destroy_cell_queue_st.h" 164 165 /* 166 * Map of muxinfos for circuitmux_t to use; struct is defined below (name 167 * of struct must match HT_HEAD line). 168 */ 169 typedef HT_HEAD(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t) 170 chanid_circid_muxinfo_map_t; 171 172 /* 173 * Structures for circuitmux.c 174 */ 175 176 struct circuitmux_t { 177 /* Keep count of attached, active circuits */ 178 unsigned int n_circuits, n_active_circuits; 179 180 /* Total number of queued cells on all circuits */ 181 unsigned int n_cells; 182 183 /* 184 * Map from (channel ID, circuit ID) pairs to circuit_muxinfo_t 185 */ 186 chanid_circid_muxinfo_map_t *chanid_circid_map; 187 188 /** List of queued destroy cells */ 189 destroy_cell_queue_t destroy_cell_queue; 190 /** Boolean: True iff the last cell to circuitmux_get_first_active_circuit 191 * returned the destroy queue. Used to force alternation between 192 * destroy/non-destroy cells. 193 * 194 * XXXX There is no reason to think that alternating is a particularly good 195 * approach -- it's just designed to prevent destroys from starving other 196 * cells completely. 197 */ 198 unsigned int last_cell_was_destroy : 1; 199 /** Destroy counter: increment this when a destroy gets queued, decrement 200 * when we unqueue it, so we can test to make sure they don't starve. 201 */ 202 int64_t destroy_ctr; 203 204 /* 205 * Circuitmux policy; if this is non-NULL, it can override the built- 206 * in round-robin active circuits behavior. This is how EWMA works in 207 * the new circuitmux_t world. 208 */ 209 const circuitmux_policy_t *policy; 210 211 /* Policy-specific data */ 212 circuitmux_policy_data_t *policy_data; 213 }; 214 215 #endif /* defined(CIRCUITMUX_PRIVATE) */ 216 217 #endif /* !defined(TOR_CIRCUITMUX_H) */