Allocate and free circuit-specific policy data in the right places

This commit is contained in:
Andrea Shepard
2012-09-27 12:00:21 -07:00
parent 851734d324
commit 930e3d611a
+56 -2
View File
@@ -260,7 +260,10 @@ circuitmux_detach_all_circuits(circuitmux_t *cmux)
if (to_remove->muxinfo.direction == CELL_DIRECTION_OUT) {
/* Clear n_mux */
circ->n_mux = NULL;
/* Update active_circuits et al. */
/*
* Update active_circuits et al.; this does policy notifies, so
* comes before freeing policy data
*/
circuitmux_make_circuit_inactive(cmux, circ, CELL_DIRECTION_OUT);
} else if (circ->magic == OR_CIRCUIT_MAGIC) {
/*
@@ -268,7 +271,10 @@ circuitmux_detach_all_circuits(circuitmux_t *cmux)
* so clear p_mux.
*/
TO_OR_CIRCUIT(circ)->p_mux = NULL;
/* Update active_circuits et al. */
/*
* Update active_circuits et al.; this does policy notifies, so
* comes before freeing policy data
*/
circuitmux_make_circuit_inactive(cmux, circ, CELL_DIRECTION_IN);
} else {
/* Complain and move on */
@@ -278,6 +284,24 @@ circuitmux_detach_all_circuits(circuitmux_t *cmux)
to_remove->circ_id,
U64_PRINTF_ARG(to_remove->chan_id));
}
/* Free policy-specific data if we have it */
if (to_remove->muxinfo.policy_data) {
/*
* If we have policy data, assert that we have the means to
* free it
*/
tor_assert(cmux->policy);
tor_assert(cmux->policy_data);
tor_assert(cmux->policy->free_circ_data);
/* Call free_circ_data() */
cmux->policy->free_circ_data(cmux,
cmux->policy_data,
circ,
to_remove->muxinfo.policy_data);
to_remove->muxinfo.policy_data = NULL;
}
} else {
/* Complain and move on */
log_warn(LD_CIRC,
@@ -293,6 +317,9 @@ circuitmux_detach_all_circuits(circuitmux_t *cmux)
to_remove->circ_id);
}
/* Assert that we don't have un-freed policy data for this circuit */
tor_assert(to_remove->muxinfo.policy_data == NULL);
/* Free it */
tor_free(to_remove);
}
@@ -620,6 +647,18 @@ circuitmux_attach_circuit(circuitmux_t *cmux, circuit_t *circ,
hashent->circ_id = circ_id;
hashent->muxinfo.cell_count = cell_count;
hashent->muxinfo.direction = direction;
/* Allocate policy specific circuit data if we need it */
if (cmux->policy && cmux->policy_data &&
cmux->policy->alloc_circ_data) {
hashent->muxinfo.policy_data =
cmux->policy->alloc_circ_data(cmux,
cmux->policy_data,
circ,
direction,
cell_count);
/* If we wanted policy data, it's an error not to get any */
tor_assert(hashent->muxinfo.policy_data);
}
HT_INSERT(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
hashent);
@@ -693,10 +732,25 @@ circuitmux_detach_circuit(circuitmux_t *cmux, circuit_t *circ)
--(cmux->n_circuits);
if (hashent->muxinfo.cell_count > 0) {
--(cmux->n_active_circuits);
/* This does policy notifies, so comes before freeing policy data */
circuitmux_make_circuit_inactive(cmux, circ, last_searched_direction);
}
cmux->n_cells -= hashent->muxinfo.cell_count;
/* Free policy-specific data if we have it */
if (hashent->muxinfo.policy_data) {
/* If we have policy data, assert that we have the means to free it */
tor_assert(cmux->policy);
tor_assert(cmux->policy_data);
tor_assert(cmux->policy->free_circ_data);
/* Call free_circ_data() */
cmux->policy->free_circ_data(cmux,
cmux->policy_data,
circ,
hashent->muxinfo.policy_data);
hashent->muxinfo.policy_data = NULL;
}
/* Consistency check: the direction must match the direction searched */
tor_assert(last_searched_direction == hashent->muxinfo.direction);
/* Clear the circuit's mux for this direction */