tor  master
Data Structures | Typedefs | Functions
circuitmux.c File Reference

Circuit mux/cell selection abstraction. More...

#include "or.h"
#include "channel.h"
#include "circuitlist.h"
#include "circuitmux.h"
#include "relay.h"
Include dependency graph for circuitmux.c:

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

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

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.

Function Documentation

◆ circuitmux_attached_circuit_direction()

cell_direction_t circuitmux_attached_circuit_direction ( circuitmux_t cmux,
circuit_t circ 
)

Query the direction of an attached circuit

◆ 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

Here is the call graph for this function:

◆ 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.

Here is the call graph for this function:

◆ 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.

Here is the caller graph for this function:

◆ circuitmux_free_()

void circuitmux_free_ ( circuitmux_t cmux)

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

◆ 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.

Here is the caller graph for this function:

◆ circuitmux_is_circuit_active()

int circuitmux_is_circuit_active ( circuitmux_t cmux,
circuit_t circ 
)

Query whether a circuit is active on a circuitmux

◆ circuitmux_is_circuit_attached()

int circuitmux_is_circuit_attached ( circuitmux_t cmux,
circuit_t circ 
)

Query whether a circuit is attached to a circuitmux

◆ 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().

Here is the call graph for this function:

◆ 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.

◆ 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.

◆ circuitmux_num_active_circuits()

unsigned int circuitmux_num_active_circuits ( circuitmux_t cmux)

Query total number of circuits active on a circuitmux

◆ 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

◆ circuitmux_num_circuits()

unsigned int circuitmux_num_circuits ( circuitmux_t cmux)

Query total number of circuits attached to a circuitmux

◆ 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

Here is the caller graph for this function:

◆ 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.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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

◆ 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

◆ MOCK_IMPL() [2/5]

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

Query total number of available cells on a circuitmux

◆ MOCK_IMPL() [3/5]

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

Attach a circuit to a circuitmux, for the specified 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.

◆ 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.