tor  0.4.1.0-alpha-dev
Data Structures | Typedefs | Functions | Variables
circuitmux.c File Reference
#include "core/or/or.h"
#include "core/or/channel.h"
#include "core/or/circuitlist.h"
#include "core/or/circuitmux.h"
#include "core/or/relay.h"
#include "core/or/cell_queue_st.h"
#include "core/or/destroy_cell_queue_st.h"
#include "core/or/or_circuit_st.h"

Go to the source code of this file.

Data Structures

struct  circuitmux_s
 
struct  circuit_muxinfo_s
 
struct  chanid_circid_muxinfo_t
 

Typedefs

typedef struct chanid_circid_muxinfo_map chanid_circid_muxinfo_map_t
 
typedef struct chanid_circid_muxinfo_t chanid_circid_muxinfo_t
 
typedef struct circuit_muxinfo_s circuit_muxinfo_t
 

Functions

static int chanid_circid_entries_eq (chanid_circid_muxinfo_t *a, chanid_circid_muxinfo_t *b)
 
static unsigned int chanid_circid_entry_hash (chanid_circid_muxinfo_t *a)
 
static chanid_circid_muxinfo_tcircuitmux_find_map_entry (circuitmux_t *cmux, circuit_t *circ)
 
static void circuitmux_make_circuit_active (circuitmux_t *cmux, circuit_t *circ)
 
static void circuitmux_make_circuit_inactive (circuitmux_t *cmux, circuit_t *circ)
 
 HT_HEAD (chanid_circid_muxinfo_map, chanid_circid_muxinfo_t)
 
 HT_PROTOTYPE (HT_GENERATE2(chanid_circid_muxinfo_map, HT_GENERATE2(chanid_circid_muxinfo_t, HT_GENERATE2(node, HT_GENERATE2(chanid_circid_entry_hash, HT_GENERATE2(chanid_circid_entries_eq)
 
void circuitmux_detach_all_circuits (circuitmux_t *cmux, smartlist_t *detached_out)
 
void circuitmux_mark_destroyed_circids_usable (circuitmux_t *cmux, channel_t *chan)
 
void circuitmux_free_ (circuitmux_t *cmux)
 
void circuitmux_clear_policy (circuitmux_t *cmux)
 
 MOCK_IMPL (const circuitmux_policy_t *, circuitmux_get_policy,(circuitmux_t *cmux))
 
void circuitmux_set_policy (circuitmux_t *cmux, const circuitmux_policy_t *pol)
 
cell_direction_t circuitmux_attached_circuit_direction (circuitmux_t *cmux, circuit_t *circ)
 
int circuitmux_is_circuit_attached (circuitmux_t *cmux, circuit_t *circ)
 
int circuitmux_is_circuit_active (circuitmux_t *cmux, circuit_t *circ)
 
unsigned int circuitmux_num_cells_for_circuit (circuitmux_t *cmux, circuit_t *circ)
 
 MOCK_IMPL (unsigned int, circuitmux_num_cells,(circuitmux_t *cmux))
 
unsigned int circuitmux_num_active_circuits (circuitmux_t *cmux)
 
unsigned int circuitmux_num_circuits (circuitmux_t *cmux)
 
 MOCK_IMPL (void, circuitmux_attach_circuit,(circuitmux_t *cmux, circuit_t *circ, cell_direction_t direction))
 
 MOCK_IMPL (void, circuitmux_detach_circuit,(circuitmux_t *cmux, circuit_t *circ))
 
void circuitmux_clear_num_cells (circuitmux_t *cmux, circuit_t *circ)
 
void circuitmux_set_num_cells (circuitmux_t *cmux, circuit_t *circ, unsigned int n_cells)
 
circuit_tcircuitmux_get_first_active_circuit (circuitmux_t *cmux, destroy_cell_queue_t **destroy_queue_out)
 
void circuitmux_notify_xmit_cells (circuitmux_t *cmux, circuit_t *circ, unsigned int n_cells)
 
void circuitmux_notify_xmit_destroy (circuitmux_t *cmux)
 
void circuitmux_append_destroy_cell (channel_t *chan, circuitmux_t *cmux, circid_t circ_id, uint8_t reason)
 
int64_t circuitmux_count_queued_destroy_cells (const channel_t *chan, const circuitmux_t *cmux)
 
 MOCK_IMPL (int, circuitmux_compare_muxes,(circuitmux_t *cmux_1, circuitmux_t *cmux_2))
 

Variables

static int64_t global_destroy_ctr = 0
 

Detailed Description

Circuit mux/cell selection abstraction.

A circuitmux is responsible for MUltipleXing all of the circuits that are writing on a single channel. It keeps track of which of these circuits has something to write (aka, "active" circuits), and which one should write next. A circuitmux corresponds 1:1 with a channel.

There can be different implementations of the circuitmux's rules (which decide which circuit is next to write).

A circuitmux exposes three distinct interfaces to other components:

To channels, which each have a circuitmux_t, the supported operations (invoked from relay.c) are:

circuitmux_get_first_active_circuit():

Pick one of the circuitmux's active circuits to send cells from.

circuitmux_notify_xmit_cells():

Notify the circuitmux that cells have been sent on a circuit.

To circuits, the exposed operations are:

circuitmux_attach_circuit():

Attach a circuit to the circuitmux; this will allocate any policy- specific data wanted for this circuit and add it to the active circuits list if it has queued cells.

circuitmux_detach_circuit():

Detach a circuit from the circuitmux, freeing associated structures.

circuitmux_clear_num_cells():

Clear the circuitmux's cell counter for this circuit.

circuitmux_set_num_cells():

Set the circuitmux's cell counter for this circuit. One of circuitmuc_clear_num_cells() or circuitmux_set_num_cells() MUST be called when the number of cells queued on a circuit changes.

See circuitmux.h for the circuitmux_policy_t data structure, which contains a table of function pointers implementing a circuit selection policy, and circuitmux_ewma.c for an example of a circuitmux policy. Circuitmux policies can be manipulated with:

circuitmux_get_policy():

Return the current policy for a circuitmux_t, if any.

circuitmux_clear_policy():

Remove a policy installed on a circuitmux_t, freeing all associated data. The circuitmux will revert to the built-in round-robin behavior.

circuitmux_set_policy():

Install a policy on a circuitmux_t; the appropriate callbacks will be made to attach all existing circuits to the new policy.

Definition in file circuitmux.c.

Function Documentation

◆ chanid_circid_entries_eq()

static int chanid_circid_entries_eq ( chanid_circid_muxinfo_t a,
chanid_circid_muxinfo_t b 
)
inlinestatic

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.

Definition at line 206 of file circuitmux.c.

◆ chanid_circid_entry_hash()

static unsigned int chanid_circid_entry_hash ( chanid_circid_muxinfo_t a)
inlinestatic

Helper: return a hash based on circuit ID and channel ID in a.

Definition at line 217 of file circuitmux.c.

◆ circuitmux_attached_circuit_direction()

cell_direction_t circuitmux_attached_circuit_direction ( circuitmux_t cmux,
circuit_t circ 
)

Query the direction of an attached circuit

Definition at line 598 of file circuitmux.c.

References circuitmux_find_map_entry(), and tor_assert().

◆ circuitmux_clear_num_cells()

void circuitmux_clear_num_cells ( circuitmux_t cmux,
circuit_t circ 
)

Clear the cell counter for a circuit on a circuitmux

Definition at line 1034 of file circuitmux.c.

References circuitmux_set_num_cells().

◆ circuitmux_clear_policy()

void circuitmux_clear_policy ( circuitmux_t cmux)

Remove any policy installed on cmux; all policy data will be freed and cmux behavior will revert to the built-in round-robin active_circuits mechanism.

Definition at line 451 of file circuitmux.c.

References circuitmux_set_policy(), and tor_assert().

◆ circuitmux_detach_all_circuits()

void circuitmux_detach_all_circuits ( circuitmux_t cmux,
smartlist_t detached_out 
)

Detach all circuits from a circuitmux (use before circuitmux_free())

If detached_out is non-NULL, add every detached circuit_t to detached_out.

Definition at line 263 of file circuitmux.c.

References tor_assert().

Referenced by channel_unlink_all_circuits().

◆ circuitmux_find_map_entry()

static chanid_circid_muxinfo_t * circuitmux_find_map_entry ( circuitmux_t cmux,
circuit_t circ 
)
static

◆ circuitmux_free_()

void circuitmux_free_ ( circuitmux_t cmux)

Free a circuitmux_t; the circuits must be detached first with circuitmux_detach_all_circuits().

Definition at line 387 of file circuitmux.c.

References circuitmux_s::destroy_cell_queue, circuitmux_s::destroy_ctr, global_destroy_ctr, destroy_cell_queue_t::n, tor_assert(), and tor_free.

◆ circuitmux_get_first_active_circuit()

circuit_t* circuitmux_get_first_active_circuit ( circuitmux_t cmux,
destroy_cell_queue_t **  destroy_queue_out 
)

Pick a circuit to send from, using the active circuits list or a circuitmux policy if one is available. This is called from channel.c.

If we would rather send a destroy cell, return NULL and set *destroy_queue_out to the destroy queue.

If we have nothing to send, set *destroy_queue_out to NULL and return NULL.

Definition at line 1107 of file circuitmux.c.

References circuitmux_s::destroy_cell_queue, circuitmux_s::last_cell_was_destroy, destroy_cell_queue_t::n, and tor_assert().

Referenced by MOCK_IMPL().

◆ circuitmux_is_circuit_active()

int circuitmux_is_circuit_active ( circuitmux_t cmux,
circuit_t circ 
)

Query whether a circuit is active on a circuitmux

Definition at line 691 of file circuitmux.c.

References circuitmux_find_map_entry(), and tor_assert().

◆ circuitmux_is_circuit_attached()

int circuitmux_is_circuit_attached ( circuitmux_t cmux,
circuit_t circ 
)

Query whether a circuit is attached to a circuitmux

Definition at line 676 of file circuitmux.c.

References circuitmux_find_map_entry().

Referenced by circuit_clear_cell_queue(), and update_circuit_on_cmux_().

◆ circuitmux_make_circuit_active()

static void circuitmux_make_circuit_active ( circuitmux_t cmux,
circuit_t circ 
)
static

Make a circuit active; update active list and policy-specific info, but we don't mess with the counters or hash table here.

Definition at line 987 of file circuitmux.c.

References circuitmux_find_map_entry(), and tor_assert().

Referenced by circuitmux_set_num_cells().

◆ circuitmux_make_circuit_inactive()

static void circuitmux_make_circuit_inactive ( circuitmux_t cmux,
circuit_t circ 
)
static

Make a circuit inactive; update active list and policy-specific info, but we don't mess with the counters or hash table here.

Definition at line 1011 of file circuitmux.c.

References circuitmux_find_map_entry(), and tor_assert().

Referenced by circuitmux_notify_xmit_cells(), circuitmux_set_num_cells(), and MOCK_IMPL().

◆ circuitmux_mark_destroyed_circids_usable()

void circuitmux_mark_destroyed_circids_usable ( circuitmux_t cmux,
channel_t chan 
)

Reclaim all circuit IDs currently marked as unusable on chan because of pending destroy cells in cmux.

This function must be called AFTER circuits are unlinked from the (channel, circuid-id) map with circuit_unlink_all_from_channel(), but before calling circuitmux_free().

Definition at line 373 of file circuitmux.c.

References channel_mark_circid_usable(), and circuitmux_s::destroy_cell_queue.

◆ circuitmux_notify_xmit_cells()

void circuitmux_notify_xmit_cells ( circuitmux_t cmux,
circuit_t circ,
unsigned int  n_cells 
)

Notify the circuitmux that cells have been sent on a circuit; this is called from channel.c.

Definition at line 1150 of file circuitmux.c.

References circuitmux_find_map_entry(), circuitmux_make_circuit_inactive(), and tor_assert().

◆ circuitmux_notify_xmit_destroy()

void circuitmux_notify_xmit_destroy ( circuitmux_t cmux)

Notify the circuitmux that a destroy was sent, so we can update the counter.

Definition at line 1210 of file circuitmux.c.

References circuitmux_s::destroy_ctr, global_destroy_ctr, and tor_assert().

Referenced by MOCK_IMPL().

◆ circuitmux_num_active_circuits()

unsigned int circuitmux_num_active_circuits ( circuitmux_t cmux)

Query total number of circuits active on a circuitmux

Definition at line 751 of file circuitmux.c.

References tor_assert().

◆ circuitmux_num_cells_for_circuit()

unsigned int circuitmux_num_cells_for_circuit ( circuitmux_t cmux,
circuit_t circ 
)

Query number of available cells for a circuit on a circuitmux

Definition at line 715 of file circuitmux.c.

References circuitmux_find_map_entry(), and tor_assert().

◆ circuitmux_num_circuits()

unsigned int circuitmux_num_circuits ( circuitmux_t cmux)

Query total number of circuits attached to a circuitmux

Definition at line 763 of file circuitmux.c.

References tor_assert().

◆ circuitmux_set_num_cells()

void circuitmux_set_num_cells ( circuitmux_t cmux,
circuit_t circ,
unsigned int  n_cells 
)

Set the cell counter for a circuit on a circuitmux

Definition at line 1045 of file circuitmux.c.

References circuitmux_find_map_entry(), circuitmux_make_circuit_active(), circuitmux_make_circuit_inactive(), and tor_assert().

Referenced by circuitmux_clear_num_cells().

◆ circuitmux_set_policy()

void circuitmux_set_policy ( circuitmux_t cmux,
const circuitmux_policy_t pol 
)

Set policy; allocate for new policy, detach all circuits from old policy if any, attach them to new policy, and free old policy data.

Definition at line 477 of file circuitmux.c.

References channel_find_by_global_id(), circuit_get_by_circid_channel_even_if_marked(), and tor_assert().

Referenced by circuitmux_clear_policy().

◆ HT_PROTOTYPE()

HT_PROTOTYPE ( HT_GENERATE2(  chanid_circid_muxinfo_map,
HT_GENERATE2(  chanid_circid_muxinfo_t,
HT_GENERATE2(  node,
HT_GENERATE2(  chanid_circid_entry_hash,
HT_GENERATE2(  chanid_circid_entries_eq 
)

Allocate a new circuitmux_t

Definition at line 228 of file circuitmux.c.

◆ MOCK_IMPL() [1/5]

MOCK_IMPL ( const circuitmux_policy_t ,
circuitmux_get_policy  ,
(circuitmux_t *cmux)   
)

Return the policy currently installed on a circuitmux_t

Definition at line 463 of file circuitmux.c.

References tor_assert().

◆ MOCK_IMPL() [2/5]

MOCK_IMPL ( unsigned  int,
circuitmux_num_cells  ,
(circuitmux_t *cmux)   
)

Query total number of available cells on a circuitmux

Definition at line 738 of file circuitmux.c.

References circuitmux_s::destroy_cell_queue, destroy_cell_queue_t::n, and tor_assert().

◆ MOCK_IMPL() [3/5]

MOCK_IMPL ( void  ,
circuitmux_attach_circuit  ,
(circuitmux_t *cmux, circuit_t *circ, cell_direction_t direction)   
)

◆ MOCK_IMPL() [4/5]

MOCK_IMPL ( void  ,
circuitmux_detach_circuit  ,
(circuitmux_t *cmux, circuit_t *circ)   
)

Detach a circuit from a circuitmux and update all counters as needed; no-op if not attached.

Definition at line 900 of file circuitmux.c.

References CELL_DIRECTION_IN, CELL_DIRECTION_OUT, circuitmux_make_circuit_inactive(), channel_s::global_identifier, circuit_t::magic, circuit_t::n_chan, circuit_t::n_circ_id, or_circuit_t::p_chan, or_circuit_t::p_circ_id, TO_OR_CIRCUIT(), tor_assert(), and tor_free.

◆ MOCK_IMPL() [5/5]

MOCK_IMPL ( int  ,
circuitmux_compare_muxes  ,
(circuitmux_t *cmux_1, circuitmux_t *cmux_2)   
)

Compare cmuxes to see which is more preferred; return < 0 if cmux_1 has higher priority (i.e., cmux_1 < cmux_2 in the scheduler's sort order), > 0 if cmux_2 has higher priority, or 0 if they are equally preferred.

If the cmuxes have different cmux policies or the policy does not support the cmp_cmux method, return 0.

Definition at line 1300 of file circuitmux.c.

References tor_assert().

Variable Documentation

◆ global_destroy_ctr

int64_t global_destroy_ctr = 0
static

Count the destroy balance to debug destroy queue logic

Definition at line 195 of file circuitmux.c.

Referenced by circuitmux_free_(), and circuitmux_notify_xmit_destroy().