circuitmux_ewma.h (4178B)
1 /* * Copyright (c) 2012-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 /** 5 * \file circuitmux_ewma.h 6 * \brief Header file for circuitmux_ewma.c 7 **/ 8 9 #ifndef TOR_CIRCUITMUX_EWMA_H 10 #define TOR_CIRCUITMUX_EWMA_H 11 12 #include "core/or/or.h" 13 #include "core/or/circuitmux.h" 14 15 /* The public EWMA policy callbacks object. */ 16 extern circuitmux_policy_t ewma_policy; 17 18 /* Externally visible EWMA functions */ 19 void cmux_ewma_set_options(const or_options_t *options, 20 const networkstatus_t *consensus); 21 22 void circuitmux_ewma_free_all(void); 23 24 #ifdef CIRCUITMUX_EWMA_PRIVATE 25 26 /*** EWMA structures ***/ 27 28 typedef struct cell_ewma_t cell_ewma_t; 29 typedef struct ewma_policy_data_t ewma_policy_data_t; 30 typedef struct ewma_policy_circ_data_t ewma_policy_circ_data_t; 31 32 /** 33 * The cell_ewma_t structure keeps track of how many cells a circuit has 34 * transferred recently. It keeps an EWMA (exponentially weighted moving 35 * average) of the number of cells flushed from the circuit queue onto a 36 * connection in channel_flush_from_first_active_circuit(). 37 */ 38 39 struct cell_ewma_t { 40 /** The last 'tick' at which we recalibrated cell_count. 41 * 42 * A cell sent at exactly the start of this tick has weight 1.0. Cells sent 43 * since the start of this tick have weight greater than 1.0; ones sent 44 * earlier have less weight. */ 45 unsigned int last_adjusted_tick; 46 /** The EWMA of the cell count. */ 47 double cell_count; 48 /** True iff this is the cell count for a circuit's previous 49 * channel. */ 50 unsigned int is_for_p_chan : 1; 51 /** The position of the circuit within the OR connection's priority 52 * queue. */ 53 int heap_index; 54 }; 55 56 struct ewma_policy_data_t { 57 circuitmux_policy_data_t base_; 58 59 /** 60 * Priority queue of cell_ewma_t for circuits with queued cells waiting 61 * for room to free up on the channel that owns this circuitmux. Kept 62 * in heap order according to EWMA. This was formerly in channel_t, and 63 * in or_connection_t before that. 64 */ 65 smartlist_t *active_circuit_pqueue; 66 67 /** 68 * The tick on which the cell_ewma_ts in active_circuit_pqueue last had 69 * their ewma values rescaled. This was formerly in channel_t, and in 70 * or_connection_t before that. 71 */ 72 unsigned int active_circuit_pqueue_last_recalibrated; 73 }; 74 75 struct ewma_policy_circ_data_t { 76 circuitmux_policy_circ_data_t base_; 77 78 /** 79 * The EWMA count for the number of cells flushed from this circuit 80 * onto this circuitmux. Used to determine which circuit to flush 81 * from next. This was formerly in circuit_t and or_circuit_t. 82 */ 83 cell_ewma_t cell_ewma; 84 85 /** 86 * Pointer back to the circuit_t this is for; since we're separating 87 * out circuit selection policy like this, we can't attach cell_ewma_t 88 * to the circuit_t any more, so we can't use SUBTYPE_P directly to a 89 * circuit_t like before; instead get it here. 90 */ 91 circuit_t *circ; 92 }; 93 94 #define EWMA_POL_DATA_MAGIC 0x2fd8b16aU 95 #define EWMA_POL_CIRC_DATA_MAGIC 0x761e7747U 96 97 /*** Downcasts for the above types ***/ 98 99 /** 100 * Downcast a circuitmux_policy_data_t to an ewma_policy_data_t and assert 101 * if the cast is impossible. 102 */ 103 104 static inline ewma_policy_data_t * 105 TO_EWMA_POL_DATA(circuitmux_policy_data_t *pol) 106 { 107 if (!pol) return NULL; 108 else { 109 tor_assertf(pol->magic == EWMA_POL_DATA_MAGIC, 110 "Mismatch: %"PRIu32" != %"PRIu32, 111 pol->magic, EWMA_POL_DATA_MAGIC); 112 return DOWNCAST(ewma_policy_data_t, pol); 113 } 114 } 115 116 /** 117 * Downcast a circuitmux_policy_circ_data_t to an ewma_policy_circ_data_t 118 * and assert if the cast is impossible. 119 */ 120 121 static inline ewma_policy_circ_data_t * 122 TO_EWMA_POL_CIRC_DATA(circuitmux_policy_circ_data_t *pol) 123 { 124 if (!pol) return NULL; 125 else { 126 tor_assertf(pol->magic == EWMA_POL_CIRC_DATA_MAGIC, 127 "Mismatch: %"PRIu32" != %"PRIu32, 128 pol->magic, EWMA_POL_CIRC_DATA_MAGIC); 129 return DOWNCAST(ewma_policy_circ_data_t, pol); 130 } 131 } 132 133 STATIC unsigned cell_ewma_get_current_tick_and_fraction(double *remainder_out); 134 STATIC void cell_ewma_initialize_ticks(void); 135 136 #endif /* defined(CIRCUITMUX_EWMA_PRIVATE) */ 137 138 #endif /* !defined(TOR_CIRCUITMUX_EWMA_H) */