circuitmux.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360
  1. /* * Copyright (c) 2012-2017, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file circuitmux.c
  5. * \brief Circuit mux/cell selection abstraction
  6. *
  7. * A circuitmux is responsible for <b>MU</b>ltiple<b>X</b>ing all of the
  8. * circuits that are writing on a single channel. It keeps track of which of
  9. * these circuits has something to write (aka, "active" circuits), and which
  10. * one should write next. A circuitmux corresponds 1:1 with a channel.
  11. *
  12. * There can be different implementations of the circuitmux's rules (which
  13. * decide which circuit is next to write).
  14. *
  15. * A circuitmux exposes three distinct
  16. * interfaces to other components:
  17. *
  18. * To channels, which each have a circuitmux_t, the supported operations
  19. * (invoked from relay.c) are:
  20. *
  21. * circuitmux_get_first_active_circuit():
  22. *
  23. * Pick one of the circuitmux's active circuits to send cells from.
  24. *
  25. * circuitmux_notify_xmit_cells():
  26. *
  27. * Notify the circuitmux that cells have been sent on a circuit.
  28. *
  29. * To circuits, the exposed operations are:
  30. *
  31. * circuitmux_attach_circuit():
  32. *
  33. * Attach a circuit to the circuitmux; this will allocate any policy-
  34. * specific data wanted for this circuit and add it to the active
  35. * circuits list if it has queued cells.
  36. *
  37. * circuitmux_detach_circuit():
  38. *
  39. * Detach a circuit from the circuitmux, freeing associated structures.
  40. *
  41. * circuitmux_clear_num_cells():
  42. *
  43. * Clear the circuitmux's cell counter for this circuit.
  44. *
  45. * circuitmux_set_num_cells():
  46. *
  47. * Set the circuitmux's cell counter for this circuit. One of
  48. * circuitmuc_clear_num_cells() or circuitmux_set_num_cells() MUST be
  49. * called when the number of cells queued on a circuit changes.
  50. *
  51. * See circuitmux.h for the circuitmux_policy_t data structure, which contains
  52. * a table of function pointers implementing a circuit selection policy, and
  53. * circuitmux_ewma.c for an example of a circuitmux policy. Circuitmux
  54. * policies can be manipulated with:
  55. *
  56. * circuitmux_get_policy():
  57. *
  58. * Return the current policy for a circuitmux_t, if any.
  59. *
  60. * circuitmux_clear_policy():
  61. *
  62. * Remove a policy installed on a circuitmux_t, freeing all associated
  63. * data. The circuitmux will revert to the built-in round-robin behavior.
  64. *
  65. * circuitmux_set_policy():
  66. *
  67. * Install a policy on a circuitmux_t; the appropriate callbacks will be
  68. * made to attach all existing circuits to the new policy.
  69. **/
  70. #include "or.h"
  71. #include "channel.h"
  72. #include "circuitlist.h"
  73. #include "circuitmux.h"
  74. #include "relay.h"
  75. /*
  76. * Private typedefs for circuitmux.c
  77. */
  78. /*
  79. * Map of muxinfos for circuitmux_t to use; struct is defined below (name
  80. * of struct must match HT_HEAD line).
  81. */
  82. typedef struct chanid_circid_muxinfo_map chanid_circid_muxinfo_map_t;
  83. /*
  84. * Hash table entry (yeah, calling it chanid_circid_muxinfo_s seems to
  85. * break the hash table code).
  86. */
  87. typedef struct chanid_circid_muxinfo_t chanid_circid_muxinfo_t;
  88. /*
  89. * Anything the mux wants to store per-circuit in the map; right now just
  90. * a count of queued cells.
  91. */
  92. typedef struct circuit_muxinfo_s circuit_muxinfo_t;
  93. /*
  94. * Structures for circuitmux.c
  95. */
  96. struct circuitmux_s {
  97. /* Keep count of attached, active circuits */
  98. unsigned int n_circuits, n_active_circuits;
  99. /* Total number of queued cells on all circuits */
  100. unsigned int n_cells;
  101. /*
  102. * Map from (channel ID, circuit ID) pairs to circuit_muxinfo_t
  103. */
  104. chanid_circid_muxinfo_map_t *chanid_circid_map;
  105. /** List of queued destroy cells */
  106. destroy_cell_queue_t destroy_cell_queue;
  107. /** Boolean: True iff the last cell to circuitmux_get_first_active_circuit
  108. * returned the destroy queue. Used to force alternation between
  109. * destroy/non-destroy cells.
  110. *
  111. * XXXX There is no reason to think that alternating is a particularly good
  112. * approach -- it's just designed to prevent destroys from starving other
  113. * cells completely.
  114. */
  115. unsigned int last_cell_was_destroy : 1;
  116. /** Destroy counter: increment this when a destroy gets queued, decrement
  117. * when we unqueue it, so we can test to make sure they don't starve.
  118. */
  119. int64_t destroy_ctr;
  120. /*
  121. * Circuitmux policy; if this is non-NULL, it can override the built-
  122. * in round-robin active circuits behavior. This is how EWMA works in
  123. * the new circuitmux_t world.
  124. */
  125. const circuitmux_policy_t *policy;
  126. /* Policy-specific data */
  127. circuitmux_policy_data_t *policy_data;
  128. };
  129. /*
  130. * This struct holds whatever we want to store per attached circuit on a
  131. * circuitmux_t; right now, just the count of queued cells and the direction.
  132. */
  133. struct circuit_muxinfo_s {
  134. /* Count of cells on this circuit at last update */
  135. unsigned int cell_count;
  136. /* Direction of flow */
  137. cell_direction_t direction;
  138. /* Policy-specific data */
  139. circuitmux_policy_circ_data_t *policy_data;
  140. /* Mark bit for consistency checker */
  141. unsigned int mark:1;
  142. };
  143. /*
  144. * A map from channel ID and circuit ID to a circuit_muxinfo_t for that
  145. * circuit.
  146. */
  147. struct chanid_circid_muxinfo_t {
  148. HT_ENTRY(chanid_circid_muxinfo_t) node;
  149. uint64_t chan_id;
  150. circid_t circ_id;
  151. circuit_muxinfo_t muxinfo;
  152. };
  153. /*
  154. * Static function declarations
  155. */
  156. static inline int
  157. chanid_circid_entries_eq(chanid_circid_muxinfo_t *a,
  158. chanid_circid_muxinfo_t *b);
  159. static inline unsigned int
  160. chanid_circid_entry_hash(chanid_circid_muxinfo_t *a);
  161. static chanid_circid_muxinfo_t *
  162. circuitmux_find_map_entry(circuitmux_t *cmux, circuit_t *circ);
  163. static void
  164. circuitmux_make_circuit_active(circuitmux_t *cmux, circuit_t *circ);
  165. static void
  166. circuitmux_make_circuit_inactive(circuitmux_t *cmux, circuit_t *circ);
  167. /* Static global variables */
  168. /** Count the destroy balance to debug destroy queue logic */
  169. static int64_t global_destroy_ctr = 0;
  170. /* Function definitions */
  171. /**
  172. * Helper for chanid_circid_cell_count_map_t hash table: compare the channel
  173. * ID and circuit ID for a and b, and return less than, equal to, or greater
  174. * than zero appropriately.
  175. */
  176. static inline int
  177. chanid_circid_entries_eq(chanid_circid_muxinfo_t *a,
  178. chanid_circid_muxinfo_t *b)
  179. {
  180. return a->chan_id == b->chan_id && a->circ_id == b->circ_id;
  181. }
  182. /**
  183. * Helper: return a hash based on circuit ID and channel ID in a.
  184. */
  185. static inline unsigned int
  186. chanid_circid_entry_hash(chanid_circid_muxinfo_t *a)
  187. {
  188. return (((unsigned int)(a->circ_id) << 8) ^
  189. ((unsigned int)((a->chan_id >> 32) & 0xffffffff)) ^
  190. ((unsigned int)(a->chan_id & 0xffffffff)));
  191. }
  192. /* Declare the struct chanid_circid_muxinfo_map type */
  193. HT_HEAD(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t);
  194. /* Emit a bunch of hash table stuff */
  195. HT_PROTOTYPE(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node,
  196. chanid_circid_entry_hash, chanid_circid_entries_eq)
  197. HT_GENERATE2(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node,
  198. chanid_circid_entry_hash, chanid_circid_entries_eq, 0.6,
  199. tor_reallocarray_, tor_free_)
  200. /*
  201. * Circuitmux alloc/free functions
  202. */
  203. /**
  204. * Allocate a new circuitmux_t
  205. */
  206. circuitmux_t *
  207. circuitmux_alloc(void)
  208. {
  209. circuitmux_t *rv = NULL;
  210. rv = tor_malloc_zero(sizeof(*rv));
  211. rv->chanid_circid_map = tor_malloc_zero(sizeof(*( rv->chanid_circid_map)));
  212. HT_INIT(chanid_circid_muxinfo_map, rv->chanid_circid_map);
  213. destroy_cell_queue_init(&rv->destroy_cell_queue);
  214. return rv;
  215. }
  216. /**
  217. * Detach all circuits from a circuitmux (use before circuitmux_free())
  218. *
  219. * If <b>detached_out</b> is non-NULL, add every detached circuit_t to
  220. * detached_out.
  221. */
  222. void
  223. circuitmux_detach_all_circuits(circuitmux_t *cmux, smartlist_t *detached_out)
  224. {
  225. chanid_circid_muxinfo_t **i = NULL, *to_remove;
  226. channel_t *chan = NULL;
  227. circuit_t *circ = NULL;
  228. tor_assert(cmux);
  229. i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
  230. while (i) {
  231. to_remove = *i;
  232. if (! to_remove) {
  233. log_warn(LD_BUG, "Somehow, an HT iterator gave us a NULL pointer.");
  234. break;
  235. } else {
  236. /* Find a channel and circuit */
  237. chan = channel_find_by_global_id(to_remove->chan_id);
  238. if (chan) {
  239. circ =
  240. circuit_get_by_circid_channel_even_if_marked(to_remove->circ_id,
  241. chan);
  242. if (circ) {
  243. /* Clear the circuit's mux for this direction */
  244. if (to_remove->muxinfo.direction == CELL_DIRECTION_OUT) {
  245. /*
  246. * Update active_circuits et al.; this does policy notifies, so
  247. * comes before freeing policy data
  248. */
  249. if (to_remove->muxinfo.cell_count > 0) {
  250. circuitmux_make_circuit_inactive(cmux, circ);
  251. }
  252. /* Clear n_mux */
  253. circ->n_mux = NULL;
  254. if (detached_out)
  255. smartlist_add(detached_out, circ);
  256. } else if (circ->magic == OR_CIRCUIT_MAGIC) {
  257. /*
  258. * Update active_circuits et al.; this does policy notifies, so
  259. * comes before freeing policy data
  260. */
  261. if (to_remove->muxinfo.cell_count > 0) {
  262. circuitmux_make_circuit_inactive(cmux, circ);
  263. }
  264. /*
  265. * It has a sensible p_chan and direction == CELL_DIRECTION_IN,
  266. * so clear p_mux.
  267. */
  268. TO_OR_CIRCUIT(circ)->p_mux = NULL;
  269. if (detached_out)
  270. smartlist_add(detached_out, circ);
  271. } else {
  272. /* Complain and move on */
  273. log_warn(LD_CIRC,
  274. "Circuit %u/channel " U64_FORMAT " had direction == "
  275. "CELL_DIRECTION_IN, but isn't an or_circuit_t",
  276. (unsigned)to_remove->circ_id,
  277. U64_PRINTF_ARG(to_remove->chan_id));
  278. }
  279. /* Free policy-specific data if we have it */
  280. if (to_remove->muxinfo.policy_data) {
  281. /*
  282. * If we have policy data, assert that we have the means to
  283. * free it
  284. */
  285. tor_assert(cmux->policy);
  286. tor_assert(cmux->policy->free_circ_data);
  287. /* Call free_circ_data() */
  288. cmux->policy->free_circ_data(cmux,
  289. cmux->policy_data,
  290. circ,
  291. to_remove->muxinfo.policy_data);
  292. to_remove->muxinfo.policy_data = NULL;
  293. }
  294. } else {
  295. /* Complain and move on */
  296. log_warn(LD_CIRC,
  297. "Couldn't find circuit %u (for channel " U64_FORMAT ")",
  298. (unsigned)to_remove->circ_id,
  299. U64_PRINTF_ARG(to_remove->chan_id));
  300. }
  301. } else {
  302. /* Complain and move on */
  303. log_warn(LD_CIRC,
  304. "Couldn't find channel " U64_FORMAT " (for circuit id %u)",
  305. U64_PRINTF_ARG(to_remove->chan_id),
  306. (unsigned)to_remove->circ_id);
  307. }
  308. /* Assert that we don't have un-freed policy data for this circuit */
  309. tor_assert(to_remove->muxinfo.policy_data == NULL);
  310. }
  311. i = HT_NEXT_RMV(chanid_circid_muxinfo_map, cmux->chanid_circid_map, i);
  312. /* Free it */
  313. tor_free(to_remove);
  314. }
  315. cmux->n_circuits = 0;
  316. cmux->n_active_circuits = 0;
  317. cmux->n_cells = 0;
  318. }
  319. /** Reclaim all circuit IDs currently marked as unusable on <b>chan</b> because
  320. * of pending destroy cells in <b>cmux</b>.
  321. *
  322. * This function must be called AFTER circuits are unlinked from the (channel,
  323. * circuid-id) map with circuit_unlink_all_from_channel(), but before calling
  324. * circuitmux_free().
  325. */
  326. void
  327. circuitmux_mark_destroyed_circids_usable(circuitmux_t *cmux, channel_t *chan)
  328. {
  329. destroy_cell_t *cell;
  330. TOR_SIMPLEQ_FOREACH(cell, &cmux->destroy_cell_queue.head, next) {
  331. channel_mark_circid_usable(chan, cell->circid);
  332. }
  333. }
  334. /**
  335. * Free a circuitmux_t; the circuits must be detached first with
  336. * circuitmux_detach_all_circuits().
  337. */
  338. void
  339. circuitmux_free_(circuitmux_t *cmux)
  340. {
  341. if (!cmux) return;
  342. tor_assert(cmux->n_circuits == 0);
  343. tor_assert(cmux->n_active_circuits == 0);
  344. /*
  345. * Free policy-specific data if we have any; we don't
  346. * need to do circuitmux_set_policy(cmux, NULL) to cover
  347. * the circuits because they would have been handled in
  348. * circuitmux_detach_all_circuits() before this was
  349. * called.
  350. */
  351. if (cmux->policy && cmux->policy->free_cmux_data) {
  352. if (cmux->policy_data) {
  353. cmux->policy->free_cmux_data(cmux, cmux->policy_data);
  354. cmux->policy_data = NULL;
  355. }
  356. } else tor_assert(cmux->policy_data == NULL);
  357. if (cmux->chanid_circid_map) {
  358. HT_CLEAR(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
  359. tor_free(cmux->chanid_circid_map);
  360. }
  361. /*
  362. * We're throwing away some destroys; log the counter and
  363. * adjust the global counter by the queue size.
  364. */
  365. if (cmux->destroy_cell_queue.n > 0) {
  366. cmux->destroy_ctr -= cmux->destroy_cell_queue.n;
  367. global_destroy_ctr -= cmux->destroy_cell_queue.n;
  368. log_debug(LD_CIRC,
  369. "Freeing cmux at %p with %u queued destroys; the last cmux "
  370. "destroy balance was "I64_FORMAT", global is "I64_FORMAT,
  371. cmux, cmux->destroy_cell_queue.n,
  372. I64_PRINTF_ARG(cmux->destroy_ctr),
  373. I64_PRINTF_ARG(global_destroy_ctr));
  374. } else {
  375. log_debug(LD_CIRC,
  376. "Freeing cmux at %p with no queued destroys, the cmux destroy "
  377. "balance was "I64_FORMAT", global is "I64_FORMAT,
  378. cmux,
  379. I64_PRINTF_ARG(cmux->destroy_ctr),
  380. I64_PRINTF_ARG(global_destroy_ctr));
  381. }
  382. destroy_cell_queue_clear(&cmux->destroy_cell_queue);
  383. tor_free(cmux);
  384. }
  385. /*
  386. * Circuitmux policy control functions
  387. */
  388. /**
  389. * Remove any policy installed on cmux; all policy data will be freed and
  390. * cmux behavior will revert to the built-in round-robin active_circuits
  391. * mechanism.
  392. */
  393. void
  394. circuitmux_clear_policy(circuitmux_t *cmux)
  395. {
  396. tor_assert(cmux);
  397. /* Internally, this is just setting policy to NULL */
  398. circuitmux_set_policy(cmux, NULL);
  399. }
  400. /**
  401. * Return the policy currently installed on a circuitmux_t
  402. */
  403. MOCK_IMPL(const circuitmux_policy_t *,
  404. circuitmux_get_policy, (circuitmux_t *cmux))
  405. {
  406. tor_assert(cmux);
  407. return cmux->policy;
  408. }
  409. /**
  410. * Set policy; allocate for new policy, detach all circuits from old policy
  411. * if any, attach them to new policy, and free old policy data.
  412. */
  413. void
  414. circuitmux_set_policy(circuitmux_t *cmux,
  415. const circuitmux_policy_t *pol)
  416. {
  417. const circuitmux_policy_t *old_pol = NULL, *new_pol = NULL;
  418. circuitmux_policy_data_t *old_pol_data = NULL, *new_pol_data = NULL;
  419. chanid_circid_muxinfo_t **i = NULL;
  420. channel_t *chan = NULL;
  421. uint64_t last_chan_id_searched = 0;
  422. circuit_t *circ = NULL;
  423. tor_assert(cmux);
  424. /* Set up variables */
  425. old_pol = cmux->policy;
  426. old_pol_data = cmux->policy_data;
  427. new_pol = pol;
  428. /* Check if this is the trivial case */
  429. if (old_pol == new_pol) return;
  430. /* Allocate data for new policy, if any */
  431. if (new_pol && new_pol->alloc_cmux_data) {
  432. /*
  433. * If alloc_cmux_data is not null, then we expect to get some policy
  434. * data. Assert that we also have free_cmux_data so we can free it
  435. * when the time comes, and allocate it.
  436. */
  437. tor_assert(new_pol->free_cmux_data);
  438. new_pol_data = new_pol->alloc_cmux_data(cmux);
  439. tor_assert(new_pol_data);
  440. }
  441. /* Install new policy and new policy data on cmux */
  442. cmux->policy = new_pol;
  443. cmux->policy_data = new_pol_data;
  444. /* Iterate over all circuits, attaching/detaching each one */
  445. i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
  446. while (i) {
  447. /* Assert that this entry isn't NULL */
  448. tor_assert(*i);
  449. /*
  450. * Get the channel; since normal case is all circuits on the mux share a
  451. * channel, we cache last_chan_id_searched
  452. */
  453. if (!chan || last_chan_id_searched != (*i)->chan_id) {
  454. chan = channel_find_by_global_id((*i)->chan_id);
  455. last_chan_id_searched = (*i)->chan_id;
  456. }
  457. tor_assert(chan);
  458. /* Get the circuit */
  459. circ = circuit_get_by_circid_channel_even_if_marked((*i)->circ_id, chan);
  460. tor_assert(circ);
  461. /* Need to tell old policy it becomes inactive (i.e., it is active) ? */
  462. if (old_pol && old_pol->notify_circ_inactive &&
  463. (*i)->muxinfo.cell_count > 0) {
  464. old_pol->notify_circ_inactive(cmux, old_pol_data, circ,
  465. (*i)->muxinfo.policy_data);
  466. }
  467. /* Need to free old policy data? */
  468. if ((*i)->muxinfo.policy_data) {
  469. /* Assert that we have the means to free it if we have policy data */
  470. tor_assert(old_pol);
  471. tor_assert(old_pol->free_circ_data);
  472. /* Free it */
  473. old_pol->free_circ_data(cmux, old_pol_data, circ,
  474. (*i)->muxinfo.policy_data);
  475. (*i)->muxinfo.policy_data = NULL;
  476. }
  477. /* Need to allocate new policy data? */
  478. if (new_pol && new_pol->alloc_circ_data) {
  479. /*
  480. * If alloc_circ_data is not null, we expect to get some per-circuit
  481. * policy data. Assert that we also have free_circ_data so we can
  482. * free it when the time comes, and allocate it.
  483. */
  484. tor_assert(new_pol->free_circ_data);
  485. (*i)->muxinfo.policy_data =
  486. new_pol->alloc_circ_data(cmux, new_pol_data, circ,
  487. (*i)->muxinfo.direction,
  488. (*i)->muxinfo.cell_count);
  489. }
  490. /* Need to make active on new policy? */
  491. if (new_pol && new_pol->notify_circ_active &&
  492. (*i)->muxinfo.cell_count > 0) {
  493. new_pol->notify_circ_active(cmux, new_pol_data, circ,
  494. (*i)->muxinfo.policy_data);
  495. }
  496. /* Advance to next circuit map entry */
  497. i = HT_NEXT(chanid_circid_muxinfo_map, cmux->chanid_circid_map, i);
  498. }
  499. /* Free data for old policy, if any */
  500. if (old_pol_data) {
  501. /*
  502. * If we had old policy data, we should have an old policy and a free
  503. * function for it.
  504. */
  505. tor_assert(old_pol);
  506. tor_assert(old_pol->free_cmux_data);
  507. old_pol->free_cmux_data(cmux, old_pol_data);
  508. old_pol_data = NULL;
  509. }
  510. }
  511. /*
  512. * Circuitmux/circuit attachment status inquiry functions
  513. */
  514. /**
  515. * Query the direction of an attached circuit
  516. */
  517. cell_direction_t
  518. circuitmux_attached_circuit_direction(circuitmux_t *cmux, circuit_t *circ)
  519. {
  520. chanid_circid_muxinfo_t *hashent = NULL;
  521. /* Try to find a map entry */
  522. hashent = circuitmux_find_map_entry(cmux, circ);
  523. /*
  524. * This function should only be called on attached circuits; assert that
  525. * we had a map entry.
  526. */
  527. tor_assert(hashent);
  528. /* Return the direction from the map entry */
  529. return hashent->muxinfo.direction;
  530. }
  531. /**
  532. * Find an entry in the cmux's map for this circuit or return NULL if there
  533. * is none.
  534. */
  535. static chanid_circid_muxinfo_t *
  536. circuitmux_find_map_entry(circuitmux_t *cmux, circuit_t *circ)
  537. {
  538. chanid_circid_muxinfo_t search, *hashent = NULL;
  539. /* Sanity-check parameters */
  540. tor_assert(cmux);
  541. tor_assert(cmux->chanid_circid_map);
  542. tor_assert(circ);
  543. /* Check if we have n_chan */
  544. if (circ->n_chan) {
  545. /* Okay, let's see if it's attached for n_chan/n_circ_id */
  546. search.chan_id = circ->n_chan->global_identifier;
  547. search.circ_id = circ->n_circ_id;
  548. /* Query */
  549. hashent = HT_FIND(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
  550. &search);
  551. }
  552. /* Found something? */
  553. if (hashent) {
  554. /*
  555. * Assert that the direction makes sense for a hashent we found by
  556. * n_chan/n_circ_id before we return it.
  557. */
  558. tor_assert(hashent->muxinfo.direction == CELL_DIRECTION_OUT);
  559. } else {
  560. /* Not there, have we got a p_chan/p_circ_id to try? */
  561. if (circ->magic == OR_CIRCUIT_MAGIC) {
  562. search.circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
  563. /* Check for p_chan */
  564. if (TO_OR_CIRCUIT(circ)->p_chan) {
  565. search.chan_id = TO_OR_CIRCUIT(circ)->p_chan->global_identifier;
  566. /* Okay, search for that */
  567. hashent = HT_FIND(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
  568. &search);
  569. /* Find anything? */
  570. if (hashent) {
  571. /* Assert that the direction makes sense before we return it */
  572. tor_assert(hashent->muxinfo.direction == CELL_DIRECTION_IN);
  573. }
  574. }
  575. }
  576. }
  577. /* Okay, hashent is it if it was there */
  578. return hashent;
  579. }
  580. /**
  581. * Query whether a circuit is attached to a circuitmux
  582. */
  583. int
  584. circuitmux_is_circuit_attached(circuitmux_t *cmux, circuit_t *circ)
  585. {
  586. chanid_circid_muxinfo_t *hashent = NULL;
  587. /* Look if it's in the circuit map */
  588. hashent = circuitmux_find_map_entry(cmux, circ);
  589. return (hashent != NULL);
  590. }
  591. /**
  592. * Query whether a circuit is active on a circuitmux
  593. */
  594. int
  595. circuitmux_is_circuit_active(circuitmux_t *cmux, circuit_t *circ)
  596. {
  597. chanid_circid_muxinfo_t *hashent = NULL;
  598. int is_active = 0;
  599. tor_assert(cmux);
  600. tor_assert(circ);
  601. /* Look if it's in the circuit map */
  602. hashent = circuitmux_find_map_entry(cmux, circ);
  603. if (hashent) {
  604. /* Check the number of cells on this circuit */
  605. is_active = (hashent->muxinfo.cell_count > 0);
  606. }
  607. /* else not attached, so not active */
  608. return is_active;
  609. }
  610. /**
  611. * Query number of available cells for a circuit on a circuitmux
  612. */
  613. unsigned int
  614. circuitmux_num_cells_for_circuit(circuitmux_t *cmux, circuit_t *circ)
  615. {
  616. chanid_circid_muxinfo_t *hashent = NULL;
  617. unsigned int n_cells = 0;
  618. tor_assert(cmux);
  619. tor_assert(circ);
  620. /* Look if it's in the circuit map */
  621. hashent = circuitmux_find_map_entry(cmux, circ);
  622. if (hashent) {
  623. /* Just get the cell count for this circuit */
  624. n_cells = hashent->muxinfo.cell_count;
  625. }
  626. /* else not attached, so 0 cells */
  627. return n_cells;
  628. }
  629. /**
  630. * Query total number of available cells on a circuitmux
  631. */
  632. MOCK_IMPL(unsigned int,
  633. circuitmux_num_cells, (circuitmux_t *cmux))
  634. {
  635. tor_assert(cmux);
  636. return cmux->n_cells + cmux->destroy_cell_queue.n;
  637. }
  638. /**
  639. * Query total number of circuits active on a circuitmux
  640. */
  641. unsigned int
  642. circuitmux_num_active_circuits(circuitmux_t *cmux)
  643. {
  644. tor_assert(cmux);
  645. return cmux->n_active_circuits;
  646. }
  647. /**
  648. * Query total number of circuits attached to a circuitmux
  649. */
  650. unsigned int
  651. circuitmux_num_circuits(circuitmux_t *cmux)
  652. {
  653. tor_assert(cmux);
  654. return cmux->n_circuits;
  655. }
  656. /*
  657. * Functions for circuit code to call to update circuit status
  658. */
  659. /**
  660. * Attach a circuit to a circuitmux, for the specified direction.
  661. */
  662. MOCK_IMPL(void,
  663. circuitmux_attach_circuit,(circuitmux_t *cmux, circuit_t *circ,
  664. cell_direction_t direction))
  665. {
  666. channel_t *chan = NULL;
  667. uint64_t channel_id;
  668. circid_t circ_id;
  669. chanid_circid_muxinfo_t search, *hashent = NULL;
  670. unsigned int cell_count;
  671. tor_assert(cmux);
  672. tor_assert(circ);
  673. tor_assert(direction == CELL_DIRECTION_IN ||
  674. direction == CELL_DIRECTION_OUT);
  675. /*
  676. * Figure out which channel we're using, and get the circuit's current
  677. * cell count and circuit ID; assert that the circuit is not already
  678. * attached to another mux.
  679. */
  680. if (direction == CELL_DIRECTION_OUT) {
  681. /* It's n_chan */
  682. chan = circ->n_chan;
  683. cell_count = circ->n_chan_cells.n;
  684. circ_id = circ->n_circ_id;
  685. } else {
  686. /* We want p_chan */
  687. chan = TO_OR_CIRCUIT(circ)->p_chan;
  688. cell_count = TO_OR_CIRCUIT(circ)->p_chan_cells.n;
  689. circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
  690. }
  691. /* Assert that we did get a channel */
  692. tor_assert(chan);
  693. /* Assert that the circuit ID is sensible */
  694. tor_assert(circ_id != 0);
  695. /* Get the channel ID */
  696. channel_id = chan->global_identifier;
  697. /* See if we already have this one */
  698. search.chan_id = channel_id;
  699. search.circ_id = circ_id;
  700. hashent = HT_FIND(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
  701. &search);
  702. if (hashent) {
  703. /*
  704. * This circuit was already attached to this cmux; make sure the
  705. * directions match and update the cell count and active circuit count.
  706. */
  707. log_info(LD_CIRC,
  708. "Circuit %u on channel " U64_FORMAT " was already attached to "
  709. "cmux %p (trying to attach to %p)",
  710. (unsigned)circ_id, U64_PRINTF_ARG(channel_id),
  711. ((direction == CELL_DIRECTION_OUT) ?
  712. circ->n_mux : TO_OR_CIRCUIT(circ)->p_mux),
  713. cmux);
  714. /*
  715. * The mux pointer on this circuit and the direction in result should
  716. * match; otherwise assert.
  717. */
  718. if (direction == CELL_DIRECTION_OUT) tor_assert(circ->n_mux == cmux);
  719. else tor_assert(TO_OR_CIRCUIT(circ)->p_mux == cmux);
  720. tor_assert(hashent->muxinfo.direction == direction);
  721. /*
  722. * Looks okay; just update the cell count and active circuits if we must
  723. */
  724. if (hashent->muxinfo.cell_count > 0 && cell_count == 0) {
  725. --(cmux->n_active_circuits);
  726. circuitmux_make_circuit_inactive(cmux, circ);
  727. } else if (hashent->muxinfo.cell_count == 0 && cell_count > 0) {
  728. ++(cmux->n_active_circuits);
  729. circuitmux_make_circuit_active(cmux, circ);
  730. }
  731. cmux->n_cells -= hashent->muxinfo.cell_count;
  732. cmux->n_cells += cell_count;
  733. hashent->muxinfo.cell_count = cell_count;
  734. } else {
  735. /*
  736. * New circuit; add an entry and update the circuit/active circuit
  737. * counts.
  738. */
  739. log_debug(LD_CIRC,
  740. "Attaching circuit %u on channel " U64_FORMAT " to cmux %p",
  741. (unsigned)circ_id, U64_PRINTF_ARG(channel_id), cmux);
  742. /*
  743. * Assert that the circuit doesn't already have a mux for this
  744. * direction.
  745. */
  746. if (direction == CELL_DIRECTION_OUT) tor_assert(circ->n_mux == NULL);
  747. else tor_assert(TO_OR_CIRCUIT(circ)->p_mux == NULL);
  748. /* Insert it in the map */
  749. hashent = tor_malloc_zero(sizeof(*hashent));
  750. hashent->chan_id = channel_id;
  751. hashent->circ_id = circ_id;
  752. hashent->muxinfo.cell_count = cell_count;
  753. hashent->muxinfo.direction = direction;
  754. /* Allocate policy specific circuit data if we need it */
  755. if (cmux->policy->alloc_circ_data) {
  756. /* Assert that we have the means to free policy-specific data */
  757. tor_assert(cmux->policy->free_circ_data);
  758. /* Allocate it */
  759. hashent->muxinfo.policy_data =
  760. cmux->policy->alloc_circ_data(cmux,
  761. cmux->policy_data,
  762. circ,
  763. direction,
  764. cell_count);
  765. /* If we wanted policy data, it's an error not to get any */
  766. tor_assert(hashent->muxinfo.policy_data);
  767. }
  768. HT_INSERT(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
  769. hashent);
  770. /* Set the circuit's mux for this direction */
  771. if (direction == CELL_DIRECTION_OUT) circ->n_mux = cmux;
  772. else TO_OR_CIRCUIT(circ)->p_mux = cmux;
  773. /* Update counters */
  774. ++(cmux->n_circuits);
  775. if (cell_count > 0) {
  776. ++(cmux->n_active_circuits);
  777. circuitmux_make_circuit_active(cmux, circ);
  778. }
  779. cmux->n_cells += cell_count;
  780. }
  781. }
  782. /**
  783. * Detach a circuit from a circuitmux and update all counters as needed;
  784. * no-op if not attached.
  785. */
  786. MOCK_IMPL(void,
  787. circuitmux_detach_circuit,(circuitmux_t *cmux, circuit_t *circ))
  788. {
  789. chanid_circid_muxinfo_t search, *hashent = NULL;
  790. /*
  791. * Use this to keep track of whether we found it for n_chan or
  792. * p_chan for consistency checking.
  793. *
  794. * The 0 initializer is not a valid cell_direction_t value.
  795. * We assert that it has been replaced with a valid value before it is used.
  796. */
  797. cell_direction_t last_searched_direction = 0;
  798. tor_assert(cmux);
  799. tor_assert(cmux->chanid_circid_map);
  800. tor_assert(circ);
  801. /* See if we have it for n_chan/n_circ_id */
  802. if (circ->n_chan) {
  803. search.chan_id = circ->n_chan->global_identifier;
  804. search.circ_id = circ->n_circ_id;
  805. hashent = HT_FIND(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
  806. &search);
  807. last_searched_direction = CELL_DIRECTION_OUT;
  808. }
  809. /* Got one? If not, see if it's an or_circuit_t and try p_chan/p_circ_id */
  810. if (!hashent) {
  811. if (circ->magic == OR_CIRCUIT_MAGIC) {
  812. search.circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
  813. if (TO_OR_CIRCUIT(circ)->p_chan) {
  814. search.chan_id = TO_OR_CIRCUIT(circ)->p_chan->global_identifier;
  815. hashent = HT_FIND(chanid_circid_muxinfo_map,
  816. cmux->chanid_circid_map,
  817. &search);
  818. last_searched_direction = CELL_DIRECTION_IN;
  819. }
  820. }
  821. }
  822. tor_assert(last_searched_direction == CELL_DIRECTION_OUT
  823. || last_searched_direction == CELL_DIRECTION_IN);
  824. /*
  825. * If hashent isn't NULL, we have a circuit to detach; don't remove it from
  826. * the map until later of circuitmux_make_circuit_inactive() breaks.
  827. */
  828. if (hashent) {
  829. /* Update counters */
  830. --(cmux->n_circuits);
  831. if (hashent->muxinfo.cell_count > 0) {
  832. --(cmux->n_active_circuits);
  833. /* This does policy notifies, so comes before freeing policy data */
  834. circuitmux_make_circuit_inactive(cmux, circ);
  835. }
  836. cmux->n_cells -= hashent->muxinfo.cell_count;
  837. /* Free policy-specific data if we have it */
  838. if (hashent->muxinfo.policy_data) {
  839. /* If we have policy data, assert that we have the means to free it */
  840. tor_assert(cmux->policy);
  841. tor_assert(cmux->policy->free_circ_data);
  842. /* Call free_circ_data() */
  843. cmux->policy->free_circ_data(cmux,
  844. cmux->policy_data,
  845. circ,
  846. hashent->muxinfo.policy_data);
  847. hashent->muxinfo.policy_data = NULL;
  848. }
  849. /* Consistency check: the direction must match the direction searched */
  850. tor_assert(last_searched_direction == hashent->muxinfo.direction);
  851. /* Clear the circuit's mux for this direction */
  852. if (last_searched_direction == CELL_DIRECTION_OUT) circ->n_mux = NULL;
  853. else TO_OR_CIRCUIT(circ)->p_mux = NULL;
  854. /* Now remove it from the map */
  855. HT_REMOVE(chanid_circid_muxinfo_map, cmux->chanid_circid_map, hashent);
  856. /* Free the hash entry */
  857. tor_free(hashent);
  858. }
  859. }
  860. /**
  861. * Make a circuit active; update active list and policy-specific info, but
  862. * we don't mess with the counters or hash table here.
  863. */
  864. static void
  865. circuitmux_make_circuit_active(circuitmux_t *cmux, circuit_t *circ)
  866. {
  867. tor_assert(cmux);
  868. tor_assert(cmux->policy);
  869. tor_assert(circ);
  870. /* Policy-specific notification */
  871. if (cmux->policy->notify_circ_active) {
  872. /* Okay, we need to check the circuit for policy data now */
  873. chanid_circid_muxinfo_t *hashent = circuitmux_find_map_entry(cmux, circ);
  874. /* We should have found something */
  875. tor_assert(hashent);
  876. /* Notify */
  877. cmux->policy->notify_circ_active(cmux, cmux->policy_data,
  878. circ, hashent->muxinfo.policy_data);
  879. }
  880. }
  881. /**
  882. * Make a circuit inactive; update active list and policy-specific info, but
  883. * we don't mess with the counters or hash table here.
  884. */
  885. static void
  886. circuitmux_make_circuit_inactive(circuitmux_t *cmux, circuit_t *circ)
  887. {
  888. tor_assert(cmux);
  889. tor_assert(cmux->policy);
  890. tor_assert(circ);
  891. /* Policy-specific notification */
  892. if (cmux->policy->notify_circ_inactive) {
  893. /* Okay, we need to check the circuit for policy data now */
  894. chanid_circid_muxinfo_t *hashent = circuitmux_find_map_entry(cmux, circ);
  895. /* We should have found something */
  896. tor_assert(hashent);
  897. /* Notify */
  898. cmux->policy->notify_circ_inactive(cmux, cmux->policy_data,
  899. circ, hashent->muxinfo.policy_data);
  900. }
  901. }
  902. /**
  903. * Clear the cell counter for a circuit on a circuitmux
  904. */
  905. void
  906. circuitmux_clear_num_cells(circuitmux_t *cmux, circuit_t *circ)
  907. {
  908. /* This is the same as setting the cell count to zero */
  909. circuitmux_set_num_cells(cmux, circ, 0);
  910. }
  911. /**
  912. * Set the cell counter for a circuit on a circuitmux
  913. */
  914. void
  915. circuitmux_set_num_cells(circuitmux_t *cmux, circuit_t *circ,
  916. unsigned int n_cells)
  917. {
  918. chanid_circid_muxinfo_t *hashent = NULL;
  919. tor_assert(cmux);
  920. tor_assert(circ);
  921. /* Search for this circuit's entry */
  922. hashent = circuitmux_find_map_entry(cmux, circ);
  923. /* Assert that we found one */
  924. tor_assert(hashent);
  925. /* Update cmux cell counter */
  926. cmux->n_cells -= hashent->muxinfo.cell_count;
  927. cmux->n_cells += n_cells;
  928. /* Do we need to notify a cmux policy? */
  929. if (cmux->policy->notify_set_n_cells) {
  930. /* Call notify_set_n_cells */
  931. cmux->policy->notify_set_n_cells(cmux,
  932. cmux->policy_data,
  933. circ,
  934. hashent->muxinfo.policy_data,
  935. n_cells);
  936. }
  937. /*
  938. * Update cmux active circuit counter: is the old cell count > 0 and the
  939. * new cell count == 0 ?
  940. */
  941. if (hashent->muxinfo.cell_count > 0 && n_cells == 0) {
  942. --(cmux->n_active_circuits);
  943. hashent->muxinfo.cell_count = n_cells;
  944. circuitmux_make_circuit_inactive(cmux, circ);
  945. /* Is the old cell count == 0 and the new cell count > 0 ? */
  946. } else if (hashent->muxinfo.cell_count == 0 && n_cells > 0) {
  947. ++(cmux->n_active_circuits);
  948. hashent->muxinfo.cell_count = n_cells;
  949. circuitmux_make_circuit_active(cmux, circ);
  950. } else {
  951. hashent->muxinfo.cell_count = n_cells;
  952. }
  953. }
  954. /*
  955. * Functions for channel code to call to get a circuit to transmit from or
  956. * notify that cells have been transmitted.
  957. */
  958. /**
  959. * Pick a circuit to send from, using the active circuits list or a
  960. * circuitmux policy if one is available. This is called from channel.c.
  961. *
  962. * If we would rather send a destroy cell, return NULL and set
  963. * *<b>destroy_queue_out</b> to the destroy queue.
  964. *
  965. * If we have nothing to send, set *<b>destroy_queue_out</b> to NULL and
  966. * return NULL.
  967. */
  968. circuit_t *
  969. circuitmux_get_first_active_circuit(circuitmux_t *cmux,
  970. destroy_cell_queue_t **destroy_queue_out)
  971. {
  972. circuit_t *circ = NULL;
  973. tor_assert(cmux);
  974. tor_assert(cmux->policy);
  975. /* This callback is mandatory. */
  976. tor_assert(cmux->policy->pick_active_circuit);
  977. tor_assert(destroy_queue_out);
  978. *destroy_queue_out = NULL;
  979. if (cmux->destroy_cell_queue.n &&
  980. (!cmux->last_cell_was_destroy || cmux->n_active_circuits == 0)) {
  981. /* We have destroy cells to send, and either we just sent a relay cell,
  982. * or we have no relay cells to send. */
  983. /* XXXX We should let the cmux policy have some say in this eventually. */
  984. /* XXXX Alternating is not a terribly brilliant approach here. */
  985. *destroy_queue_out = &cmux->destroy_cell_queue;
  986. cmux->last_cell_was_destroy = 1;
  987. } else if (cmux->n_active_circuits > 0) {
  988. /* We also must have a cell available for this to be the case */
  989. tor_assert(cmux->n_cells > 0);
  990. /* Do we have a policy-provided circuit selector? */
  991. circ = cmux->policy->pick_active_circuit(cmux, cmux->policy_data);
  992. cmux->last_cell_was_destroy = 0;
  993. } else {
  994. tor_assert(cmux->n_cells == 0);
  995. tor_assert(cmux->destroy_cell_queue.n == 0);
  996. }
  997. return circ;
  998. }
  999. /**
  1000. * Notify the circuitmux that cells have been sent on a circuit; this
  1001. * is called from channel.c.
  1002. */
  1003. void
  1004. circuitmux_notify_xmit_cells(circuitmux_t *cmux, circuit_t *circ,
  1005. unsigned int n_cells)
  1006. {
  1007. chanid_circid_muxinfo_t *hashent = NULL;
  1008. int becomes_inactive = 0;
  1009. tor_assert(cmux);
  1010. tor_assert(circ);
  1011. if (n_cells == 0) return;
  1012. /*
  1013. * To handle this, we have to:
  1014. *
  1015. * 1.) Adjust the circuit's cell counter in the cmux hash table
  1016. * 2.) Move the circuit to the tail of the active_circuits linked list
  1017. * for this cmux, or make the circuit inactive if the cell count
  1018. * went to zero.
  1019. * 3.) Call cmux->policy->notify_xmit_cells(), if any
  1020. */
  1021. /* Find the hash entry */
  1022. hashent = circuitmux_find_map_entry(cmux, circ);
  1023. /* Assert that we found one */
  1024. tor_assert(hashent);
  1025. /* Adjust the cell counter and assert that we had that many cells to send */
  1026. tor_assert(n_cells <= hashent->muxinfo.cell_count);
  1027. hashent->muxinfo.cell_count -= n_cells;
  1028. /* Do we need to make the circuit inactive? */
  1029. if (hashent->muxinfo.cell_count == 0) becomes_inactive = 1;
  1030. /* Adjust the mux cell counter */
  1031. cmux->n_cells -= n_cells;
  1032. /*
  1033. * We call notify_xmit_cells() before making the circuit inactive if needed,
  1034. * so the policy can always count on this coming in on an active circuit.
  1035. */
  1036. if (cmux->policy->notify_xmit_cells) {
  1037. cmux->policy->notify_xmit_cells(cmux, cmux->policy_data, circ,
  1038. hashent->muxinfo.policy_data,
  1039. n_cells);
  1040. }
  1041. /*
  1042. * Now make the circuit inactive if needed; this will call the policy's
  1043. * notify_circ_inactive() if present.
  1044. */
  1045. if (becomes_inactive) {
  1046. --(cmux->n_active_circuits);
  1047. circuitmux_make_circuit_inactive(cmux, circ);
  1048. }
  1049. }
  1050. /**
  1051. * Notify the circuitmux that a destroy was sent, so we can update
  1052. * the counter.
  1053. */
  1054. void
  1055. circuitmux_notify_xmit_destroy(circuitmux_t *cmux)
  1056. {
  1057. tor_assert(cmux);
  1058. --(cmux->destroy_ctr);
  1059. --(global_destroy_ctr);
  1060. log_debug(LD_CIRC,
  1061. "Cmux at %p sent a destroy, cmux counter is now "I64_FORMAT", "
  1062. "global counter is now "I64_FORMAT,
  1063. cmux,
  1064. I64_PRINTF_ARG(cmux->destroy_ctr),
  1065. I64_PRINTF_ARG(global_destroy_ctr));
  1066. }
  1067. /*DOCDOC */
  1068. void
  1069. circuitmux_append_destroy_cell(channel_t *chan,
  1070. circuitmux_t *cmux,
  1071. circid_t circ_id,
  1072. uint8_t reason)
  1073. {
  1074. destroy_cell_queue_append(&cmux->destroy_cell_queue, circ_id, reason);
  1075. /* Destroy entering the queue, update counters */
  1076. ++(cmux->destroy_ctr);
  1077. ++global_destroy_ctr;
  1078. log_debug(LD_CIRC,
  1079. "Cmux at %p queued a destroy for circ %u, cmux counter is now "
  1080. I64_FORMAT", global counter is now "I64_FORMAT,
  1081. cmux, circ_id,
  1082. I64_PRINTF_ARG(cmux->destroy_ctr),
  1083. I64_PRINTF_ARG(global_destroy_ctr));
  1084. /* XXXX Duplicate code from append_cell_to_circuit_queue */
  1085. if (!channel_has_queued_writes(chan)) {
  1086. /* There is no data at all waiting to be sent on the outbuf. Add a
  1087. * cell, so that we can notice when it gets flushed, flushed_some can
  1088. * get called, and we can start putting more data onto the buffer then.
  1089. */
  1090. log_debug(LD_GENERAL, "Primed a buffer.");
  1091. channel_flush_from_first_active_circuit(chan, 1);
  1092. }
  1093. }
  1094. /*DOCDOC; for debugging 12184. This runs slowly. */
  1095. int64_t
  1096. circuitmux_count_queued_destroy_cells(const channel_t *chan,
  1097. const circuitmux_t *cmux)
  1098. {
  1099. int64_t n_destroy_cells = cmux->destroy_ctr;
  1100. int64_t destroy_queue_size = cmux->destroy_cell_queue.n;
  1101. int64_t manual_total = 0;
  1102. int64_t manual_total_in_map = 0;
  1103. destroy_cell_t *cell;
  1104. TOR_SIMPLEQ_FOREACH(cell, &cmux->destroy_cell_queue.head, next) {
  1105. circid_t id;
  1106. ++manual_total;
  1107. id = cell->circid;
  1108. if (circuit_id_in_use_on_channel(id, (channel_t*)chan))
  1109. ++manual_total_in_map;
  1110. }
  1111. if (n_destroy_cells != destroy_queue_size ||
  1112. n_destroy_cells != manual_total ||
  1113. n_destroy_cells != manual_total_in_map) {
  1114. log_warn(LD_BUG, " Discrepancy in counts for queued destroy cells on "
  1115. "circuitmux. n="I64_FORMAT". queue_size="I64_FORMAT". "
  1116. "manual_total="I64_FORMAT". manual_total_in_map="I64_FORMAT".",
  1117. I64_PRINTF_ARG(n_destroy_cells),
  1118. I64_PRINTF_ARG(destroy_queue_size),
  1119. I64_PRINTF_ARG(manual_total),
  1120. I64_PRINTF_ARG(manual_total_in_map));
  1121. }
  1122. return n_destroy_cells;
  1123. }
  1124. /**
  1125. * Compare cmuxes to see which is more preferred; return < 0 if
  1126. * cmux_1 has higher priority (i.e., cmux_1 < cmux_2 in the scheduler's
  1127. * sort order), > 0 if cmux_2 has higher priority, or 0 if they are
  1128. * equally preferred.
  1129. *
  1130. * If the cmuxes have different cmux policies or the policy does not
  1131. * support the cmp_cmux method, return 0.
  1132. */
  1133. MOCK_IMPL(int,
  1134. circuitmux_compare_muxes, (circuitmux_t *cmux_1, circuitmux_t *cmux_2))
  1135. {
  1136. const circuitmux_policy_t *policy;
  1137. tor_assert(cmux_1);
  1138. tor_assert(cmux_2);
  1139. if (cmux_1 == cmux_2) {
  1140. /* Equivalent because they're the same cmux */
  1141. return 0;
  1142. }
  1143. if (cmux_1->policy && cmux_2->policy) {
  1144. if (cmux_1->policy == cmux_2->policy) {
  1145. policy = cmux_1->policy;
  1146. if (policy->cmp_cmux) {
  1147. /* Okay, we can compare! */
  1148. return policy->cmp_cmux(cmux_1, cmux_1->policy_data,
  1149. cmux_2, cmux_2->policy_data);
  1150. } else {
  1151. /*
  1152. * Equivalent because the policy doesn't know how to compare between
  1153. * muxes.
  1154. */
  1155. return 0;
  1156. }
  1157. } else {
  1158. /* Equivalent because they have different policies */
  1159. return 0;
  1160. }
  1161. } else {
  1162. /* Equivalent because one or both are missing a policy */
  1163. return 0;
  1164. }
  1165. }