mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 20:33:31 +01:00
Implement circuitmux_clear_policy(), circuitmux_get_policy() and circuitmux_set_policy() in circuitmux.c
This commit is contained in:
parent
eade7a37cd
commit
86d9d85dfc
@ -343,7 +343,13 @@ circuitmux_free(circuitmux_t *cmux)
|
|||||||
tor_assert(cmux->n_circuits == 0);
|
tor_assert(cmux->n_circuits == 0);
|
||||||
tor_assert(cmux->n_active_circuits == 0);
|
tor_assert(cmux->n_active_circuits == 0);
|
||||||
|
|
||||||
/* Free policy-specific data if we have any */
|
/*
|
||||||
|
* Free policy-specific data if we have any; we don't
|
||||||
|
* need to do circuitmux_set_policy(cmux, NULL) to cover
|
||||||
|
* the circuits because they would have been handled in
|
||||||
|
* circuitmux_detach_all_circuits() before this was
|
||||||
|
* called.
|
||||||
|
*/
|
||||||
if (cmux->policy && cmux->policy->free_cmux_data) {
|
if (cmux->policy && cmux->policy->free_cmux_data) {
|
||||||
if (cmux->policy_data) {
|
if (cmux->policy_data) {
|
||||||
cmux->policy->free_cmux_data(cmux, cmux->policy_data);
|
cmux->policy->free_cmux_data(cmux, cmux->policy_data);
|
||||||
@ -359,6 +365,157 @@ circuitmux_free(circuitmux_t *cmux)
|
|||||||
tor_free(cmux);
|
tor_free(cmux);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Circuitmux policy control functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
circuitmux_clear_policy(circuitmux_t *cmux)
|
||||||
|
{
|
||||||
|
tor_assert(cmux);
|
||||||
|
|
||||||
|
/* Internally, this is just setting policy to NULL */
|
||||||
|
if (cmux->policy) {
|
||||||
|
circuitmux_set_policy(cmux, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the policy currently installed on a circuitmux_t
|
||||||
|
*/
|
||||||
|
|
||||||
|
const circuitmux_policy_t *
|
||||||
|
circuitmux_get_policy(circuitmux_t *cmux)
|
||||||
|
{
|
||||||
|
tor_assert(cmux);
|
||||||
|
|
||||||
|
return cmux->policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set policy; allocate for new policy, detach all circuits from old policy
|
||||||
|
* if any, attach them to new policy, and free old policy data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
circuitmux_set_policy(circuitmux_t *cmux,
|
||||||
|
const circuitmux_policy_t *pol)
|
||||||
|
{
|
||||||
|
const circuitmux_policy_t *old_pol = NULL, *new_pol = NULL;
|
||||||
|
circuitmux_policy_data_t *old_pol_data = NULL, *new_pol_data = NULL;
|
||||||
|
chanid_circid_muxinfo_t **i = NULL;
|
||||||
|
channel_t *chan = NULL;
|
||||||
|
uint64_t last_chan_id_searched = 0;
|
||||||
|
circuit_t *circ = NULL;
|
||||||
|
|
||||||
|
tor_assert(cmux);
|
||||||
|
|
||||||
|
/* Set up variables */
|
||||||
|
old_pol = cmux->policy;
|
||||||
|
old_pol_data = cmux->policy_data;
|
||||||
|
new_pol = pol;
|
||||||
|
|
||||||
|
/* Check if this is the trivial case */
|
||||||
|
if (old_pol == new_pol) return;
|
||||||
|
|
||||||
|
/* Allocate data for new policy, if any */
|
||||||
|
if (new_pol && new_pol->alloc_cmux_data) {
|
||||||
|
/*
|
||||||
|
* If alloc_cmux_data is not null, then we expect to get some policy
|
||||||
|
* data. Assert that we also have free_cmux_data so we can free it
|
||||||
|
* when the time comes, and allocate it.
|
||||||
|
*/
|
||||||
|
tor_assert(new_pol->free_cmux_data);
|
||||||
|
new_pol_data = new_pol->alloc_cmux_data(cmux);
|
||||||
|
tor_assert(new_pol_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Install new policy and new policy data on cmux */
|
||||||
|
cmux->policy = new_pol;
|
||||||
|
cmux->policy_data = new_pol_data;
|
||||||
|
|
||||||
|
/* Iterate over all circuits, attaching/detaching each one */
|
||||||
|
i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
|
||||||
|
while (i) {
|
||||||
|
/* Assert that this entry isn't NULL */
|
||||||
|
tor_assert(*i);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the channel; since normal case is all circuits on the mux share a
|
||||||
|
* channel, we cache last_chan_id_searched
|
||||||
|
*/
|
||||||
|
if (!chan || last_chan_id_searched != (*i)->chan_id) {
|
||||||
|
chan = channel_find_by_global_id((*i)->chan_id);
|
||||||
|
last_chan_id_searched = (*i)->chan_id;
|
||||||
|
}
|
||||||
|
tor_assert(chan);
|
||||||
|
|
||||||
|
/* Get the circuit */
|
||||||
|
circ = circuit_get_by_circid_channel((*i)->circ_id, chan);
|
||||||
|
tor_assert(circ);
|
||||||
|
|
||||||
|
/* Need to tell old policy it becomes inactive (i.e., it is active) ? */
|
||||||
|
if (old_pol && old_pol->notify_circ_inactive &&
|
||||||
|
(*i)->muxinfo.cell_count > 0) {
|
||||||
|
old_pol->notify_circ_inactive(cmux, old_pol_data, circ,
|
||||||
|
(*i)->muxinfo.policy_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need to free old policy data? */
|
||||||
|
if ((*i)->muxinfo.policy_data) {
|
||||||
|
/* Assert that we have the means to free it if we have policy data */
|
||||||
|
tor_assert(old_pol);
|
||||||
|
tor_assert(old_pol->free_circ_data);
|
||||||
|
/* Free it */
|
||||||
|
old_pol->free_circ_data(cmux, old_pol_data, circ,
|
||||||
|
(*i)->muxinfo.policy_data);
|
||||||
|
(*i)->muxinfo.policy_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need to allocate new policy data? */
|
||||||
|
if (new_pol && new_pol->alloc_circ_data) {
|
||||||
|
/*
|
||||||
|
* If alloc_circ_data is not null, we expect to get some per-circuit
|
||||||
|
* policy data. Assert that we also have free_circ_data so we can
|
||||||
|
* free it when the time comes, and allocate it.
|
||||||
|
*/
|
||||||
|
tor_assert(new_pol->free_circ_data);
|
||||||
|
(*i)->muxinfo.policy_data =
|
||||||
|
new_pol->alloc_circ_data(cmux, new_pol_data, circ,
|
||||||
|
(*i)->muxinfo.direction,
|
||||||
|
(*i)->muxinfo.cell_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need to make active on new policy? */
|
||||||
|
if (new_pol && new_pol->notify_circ_active &&
|
||||||
|
(*i)->muxinfo.cell_count > 0) {
|
||||||
|
new_pol->notify_circ_active(cmux, new_pol_data, circ,
|
||||||
|
(*i)->muxinfo.policy_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance to next circuit map entry */
|
||||||
|
i = HT_NEXT(chanid_circid_muxinfo_map, cmux->chanid_circid_map, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free data for old policy, if any */
|
||||||
|
if (old_pol_data) {
|
||||||
|
/*
|
||||||
|
* If we had old policy data, we should have an old policy and a free
|
||||||
|
* function for it.
|
||||||
|
*/
|
||||||
|
tor_assert(old_pol);
|
||||||
|
tor_assert(old_pol->free_cmux_data);
|
||||||
|
old_pol->free_cmux_data(cmux, old_pol_data);
|
||||||
|
old_pol_data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Circuitmux/circuit attachment status inquiry functions
|
* Circuitmux/circuit attachment status inquiry functions
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user