tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

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) */