1 /* * Copyright (c) 2012-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
6 * \brief Header file for circuitmux.c
9 #ifndef TOR_CIRCUITMUX_H
10 #define TOR_CIRCUITMUX_H
12 #include "core/or/or.h"
13 #include "lib/testsupport/testsupport.h"
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
;
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
,
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
,
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
,
41 circuitmux_policy_circ_data_t
*pol_circ_data
);
42 void (*notify_circ_inactive
)(circuitmux_t
*cmux
,
43 circuitmux_policy_data_t
*pol_data
,
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
,
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
,
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
);
66 * Circuitmux policy implementations can subclass this to store circuitmux-
67 * wide data; it just has the magic number in the base struct.
70 struct circuitmux_policy_data_t
{
75 * Circuitmux policy implementations can subclass this to store circuit-
76 * specific data; it just has the magic number in the base struct.
79 struct circuitmux_policy_circ_data_t
{
84 * Upcast #defines for the above types
88 * Convert a circuitmux_policy_data_t subtype to a circuitmux_policy_data_t.
91 #define TO_CMUX_POL_DATA(x) (&((x)->base_))
94 * Convert a circuitmux_policy_circ_data_t subtype to a
95 * circuitmux_policy_circ_data_t.
98 #define TO_CMUX_POL_CIRC_DATA(x) (&((x)->base_))
100 /* Consistency check */
101 void circuitmux_assert_okay(circuitmux_t
*cmux
);
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))
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
);
118 /* Status inquiries */
119 cell_direction_t
circuitmux_attached_circuit_direction(
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
,
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
);
130 /* Debugging interface - slow. */
131 int64_t circuitmux_count_queued_destroy_cells(const channel_t
*chan
,
132 const circuitmux_t
*cmux
);
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
);
141 /* Circuit interface */
142 MOCK_DECL(void, circuitmux_attach_circuit
, (circuitmux_t
*cmux
,
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
);
151 void circuitmux_append_destroy_cell(channel_t
*chan
,
152 circuitmux_t
*cmux
, circid_t circ_id
,
154 void circuitmux_mark_destroyed_circids_usable(circuitmux_t
*cmux
,
157 /* Optional interchannel comparisons for scheduling */
158 MOCK_DECL(int, circuitmux_compare_muxes
,
159 (circuitmux_t
*cmux_1
, circuitmux_t
*cmux_2
));
161 #ifdef CIRCUITMUX_PRIVATE
163 #include "core/or/destroy_cell_queue_st.h"
166 * Map of muxinfos for circuitmux_t to use; struct is defined below (name
167 * of struct must match HT_HEAD line).
169 typedef HT_HEAD(chanid_circid_muxinfo_map
, chanid_circid_muxinfo_t
)
170 chanid_circid_muxinfo_map_t
;
173 * Structures for circuitmux.c
176 struct circuitmux_t
{
177 /* Keep count of attached, active circuits */
178 unsigned int n_circuits
, n_active_circuits
;
180 /* Total number of queued cells on all circuits */
181 unsigned int n_cells
;
184 * Map from (channel ID, circuit ID) pairs to circuit_muxinfo_t
186 chanid_circid_muxinfo_map_t
*chanid_circid_map
;
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.
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
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.
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.
209 const circuitmux_policy_t
*policy
;
211 /* Policy-specific data */
212 circuitmux_policy_data_t
*policy_data
;
215 #endif /* defined(CIRCUITMUX_PRIVATE) */
217 #endif /* !defined(TOR_CIRCUITMUX_H) */