circuitmux.c 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000
  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. /*
  106. * Double-linked ring of circuits with queued cells waiting for room to
  107. * free up on this connection's outbuf. Every time we pull cells from
  108. * a circuit, we advance this pointer to the next circuit in the ring.
  109. */
  110. struct circuit_t *active_circuits_head, *active_circuits_tail;
  111. /** List of queued destroy cells */
  112. cell_queue_t destroy_cell_queue;
  113. /** Boolean: True iff the last cell to circuitmux_get_first_active_circuit
  114. * returned the destroy queue. Used to force alternation between
  115. * destroy/non-destroy cells.
  116. *
  117. * XXXX There is no reason to think that alternating is a particularly good
  118. * approach -- it's just designed to prevent destroys from starving other
  119. * cells completely.
  120. */
  121. unsigned int last_cell_was_destroy : 1;
  122. /** Destroy counter: increment this when a destroy gets queued, decrement
  123. * when we unqueue it, so we can test to make sure they don't starve.
  124. */
  125. int64_t destroy_ctr;
  126. /*
  127. * Circuitmux policy; if this is non-NULL, it can override the built-
  128. * in round-robin active circuits behavior. This is how EWMA works in
  129. * the new circuitmux_t world.
  130. */
  131. const circuitmux_policy_t *policy;
  132. /* Policy-specific data */
  133. circuitmux_policy_data_t *policy_data;
  134. };
  135. /*
  136. * This struct holds whatever we want to store per attached circuit on a
  137. * circuitmux_t; right now, just the count of queued cells and the direction.
  138. */
  139. struct circuit_muxinfo_s {
  140. /* Count of cells on this circuit at last update */
  141. unsigned int cell_count;
  142. /* Direction of flow */
  143. cell_direction_t direction;
  144. /* Policy-specific data */
  145. circuitmux_policy_circ_data_t *policy_data;
  146. /* Mark bit for consistency checker */
  147. unsigned int mark:1;
  148. };
  149. /*
  150. * A map from channel ID and circuit ID to a circuit_muxinfo_t for that
  151. * circuit.
  152. */
  153. struct chanid_circid_muxinfo_t {
  154. HT_ENTRY(chanid_circid_muxinfo_t) node;
  155. uint64_t chan_id;
  156. circid_t circ_id;
  157. circuit_muxinfo_t muxinfo;
  158. };
  159. /*
  160. * Internal-use #defines
  161. */
  162. #ifdef CMUX_PARANOIA
  163. #define circuitmux_assert_okay_paranoid(cmux) \
  164. circuitmux_assert_okay(cmux)
  165. #else
  166. #define circuitmux_assert_okay_paranoid(cmux)
  167. #endif /* defined(CMUX_PARANOIA) */
  168. /*
  169. * Static function declarations
  170. */
  171. static inline int
  172. chanid_circid_entries_eq(chanid_circid_muxinfo_t *a,
  173. chanid_circid_muxinfo_t *b);
  174. static inline unsigned int
  175. chanid_circid_entry_hash(chanid_circid_muxinfo_t *a);
  176. static chanid_circid_muxinfo_t *
  177. circuitmux_find_map_entry(circuitmux_t *cmux, circuit_t *circ);
  178. static void
  179. circuitmux_make_circuit_active(circuitmux_t *cmux, circuit_t *circ,
  180. cell_direction_t direction);
  181. static void
  182. circuitmux_make_circuit_inactive(circuitmux_t *cmux, circuit_t *circ,
  183. cell_direction_t direction);
  184. static inline void
  185. circuitmux_move_active_circ_to_tail(circuitmux_t *cmux, circuit_t *circ,
  186. cell_direction_t direction);
  187. static inline circuit_t **
  188. circuitmux_next_active_circ_p(circuitmux_t *cmux, circuit_t *circ);
  189. static inline circuit_t **
  190. circuitmux_prev_active_circ_p(circuitmux_t *cmux, circuit_t *circ);
  191. static void circuitmux_assert_okay_pass_one(circuitmux_t *cmux);
  192. static void circuitmux_assert_okay_pass_two(circuitmux_t *cmux);
  193. static void circuitmux_assert_okay_pass_three(circuitmux_t *cmux);
  194. /* Static global variables */
  195. /** Count the destroy balance to debug destroy queue logic */
  196. static int64_t global_destroy_ctr = 0;
  197. /* Function definitions */
  198. /**
  199. * Linked list helpers
  200. */
  201. /**
  202. * Move an active circuit to the tail of the cmux's active circuits list;
  203. * used by circuitmux_notify_xmit_cells().
  204. */
  205. static inline void
  206. circuitmux_move_active_circ_to_tail(circuitmux_t *cmux, circuit_t *circ,
  207. cell_direction_t direction)
  208. {
  209. circuit_t **next_p = NULL, **prev_p = NULL;
  210. circuit_t **next_prev = NULL, **prev_next = NULL;
  211. circuit_t **tail_next = NULL;
  212. or_circuit_t *or_circ = NULL;
  213. tor_assert(cmux);
  214. tor_assert(circ);
  215. circuitmux_assert_okay_paranoid(cmux);
  216. /* Figure out our next_p and prev_p for this cmux/direction */
  217. if (direction) {
  218. if (direction == CELL_DIRECTION_OUT) {
  219. tor_assert(circ->n_mux == cmux);
  220. next_p = &(circ->next_active_on_n_chan);
  221. prev_p = &(circ->prev_active_on_n_chan);
  222. } else {
  223. or_circ = TO_OR_CIRCUIT(circ);
  224. tor_assert(or_circ->p_mux == cmux);
  225. next_p = &(or_circ->next_active_on_p_chan);
  226. prev_p = &(or_circ->prev_active_on_p_chan);
  227. }
  228. } else {
  229. if (circ->n_mux == cmux) {
  230. next_p = &(circ->next_active_on_n_chan);
  231. prev_p = &(circ->prev_active_on_n_chan);
  232. } else {
  233. or_circ = TO_OR_CIRCUIT(circ);
  234. tor_assert(or_circ->p_mux == cmux);
  235. next_p = &(or_circ->next_active_on_p_chan);
  236. prev_p = &(or_circ->prev_active_on_p_chan);
  237. }
  238. }
  239. tor_assert(next_p);
  240. tor_assert(prev_p);
  241. /* Check if this really is an active circuit */
  242. if ((*next_p == NULL && *prev_p == NULL) &&
  243. !(circ == cmux->active_circuits_head ||
  244. circ == cmux->active_circuits_tail)) {
  245. /* Not active, no-op */
  246. return;
  247. }
  248. /* Check if this is already the tail */
  249. if (circ == cmux->active_circuits_tail) return;
  250. /* Okay, we have to move it; figure out next_prev and prev_next */
  251. if (*next_p) next_prev = circuitmux_prev_active_circ_p(cmux, *next_p);
  252. if (*prev_p) prev_next = circuitmux_next_active_circ_p(cmux, *prev_p);
  253. /* Adjust the previous node's next pointer, if any */
  254. if (prev_next) *prev_next = *next_p;
  255. /* Otherwise, we were the head */
  256. else cmux->active_circuits_head = *next_p;
  257. /* Adjust the next node's previous pointer, if any */
  258. if (next_prev) *next_prev = *prev_p;
  259. /* We're out of the list; now re-attach at the tail */
  260. /* Adjust our next and prev pointers */
  261. *next_p = NULL;
  262. *prev_p = cmux->active_circuits_tail;
  263. /* Set the next pointer of the tail, or the head if none */
  264. if (cmux->active_circuits_tail) {
  265. tail_next = circuitmux_next_active_circ_p(cmux,
  266. cmux->active_circuits_tail);
  267. *tail_next = circ;
  268. } else {
  269. cmux->active_circuits_head = circ;
  270. }
  271. /* Set the tail to this circuit */
  272. cmux->active_circuits_tail = circ;
  273. circuitmux_assert_okay_paranoid(cmux);
  274. }
  275. static inline circuit_t **
  276. circuitmux_next_active_circ_p(circuitmux_t *cmux, circuit_t *circ)
  277. {
  278. tor_assert(cmux);
  279. tor_assert(circ);
  280. if (circ->n_mux == cmux) return &(circ->next_active_on_n_chan);
  281. else {
  282. tor_assert(TO_OR_CIRCUIT(circ)->p_mux == cmux);
  283. return &(TO_OR_CIRCUIT(circ)->next_active_on_p_chan);
  284. }
  285. }
  286. static inline circuit_t **
  287. circuitmux_prev_active_circ_p(circuitmux_t *cmux, circuit_t *circ)
  288. {
  289. tor_assert(cmux);
  290. tor_assert(circ);
  291. if (circ->n_mux == cmux) return &(circ->prev_active_on_n_chan);
  292. else {
  293. tor_assert(TO_OR_CIRCUIT(circ)->p_mux == cmux);
  294. return &(TO_OR_CIRCUIT(circ)->prev_active_on_p_chan);
  295. }
  296. }
  297. /**
  298. * Helper for chanid_circid_cell_count_map_t hash table: compare the channel
  299. * ID and circuit ID for a and b, and return less than, equal to, or greater
  300. * than zero appropriately.
  301. */
  302. static inline int
  303. chanid_circid_entries_eq(chanid_circid_muxinfo_t *a,
  304. chanid_circid_muxinfo_t *b)
  305. {
  306. return a->chan_id == b->chan_id && a->circ_id == b->circ_id;
  307. }
  308. /**
  309. * Helper: return a hash based on circuit ID and channel ID in a.
  310. */
  311. static inline unsigned int
  312. chanid_circid_entry_hash(chanid_circid_muxinfo_t *a)
  313. {
  314. return (((unsigned int)(a->circ_id) << 8) ^
  315. ((unsigned int)((a->chan_id >> 32) & 0xffffffff)) ^
  316. ((unsigned int)(a->chan_id & 0xffffffff)));
  317. }
  318. /* Declare the struct chanid_circid_muxinfo_map type */
  319. HT_HEAD(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t);
  320. /* Emit a bunch of hash table stuff */
  321. HT_PROTOTYPE(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node,
  322. chanid_circid_entry_hash, chanid_circid_entries_eq)
  323. HT_GENERATE2(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node,
  324. chanid_circid_entry_hash, chanid_circid_entries_eq, 0.6,
  325. tor_reallocarray_, tor_free_)
  326. /*
  327. * Circuitmux alloc/free functions
  328. */
  329. /**
  330. * Allocate a new circuitmux_t
  331. */
  332. circuitmux_t *
  333. circuitmux_alloc(void)
  334. {
  335. circuitmux_t *rv = NULL;
  336. rv = tor_malloc_zero(sizeof(*rv));
  337. rv->chanid_circid_map = tor_malloc_zero(sizeof(*( rv->chanid_circid_map)));
  338. HT_INIT(chanid_circid_muxinfo_map, rv->chanid_circid_map);
  339. cell_queue_init(&rv->destroy_cell_queue);
  340. return rv;
  341. }
  342. /**
  343. * Detach all circuits from a circuitmux (use before circuitmux_free())
  344. *
  345. * If <b>detached_out</b> is non-NULL, add every detached circuit_t to
  346. * detached_out.
  347. */
  348. void
  349. circuitmux_detach_all_circuits(circuitmux_t *cmux, smartlist_t *detached_out)
  350. {
  351. chanid_circid_muxinfo_t **i = NULL, *to_remove;
  352. channel_t *chan = NULL;
  353. circuit_t *circ = NULL;
  354. tor_assert(cmux);
  355. /*
  356. * Don't circuitmux_assert_okay_paranoid() here; this gets called when
  357. * channels are being freed and have already been unregistered, so
  358. * the channel ID lookups it does will fail.
  359. */
  360. i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
  361. while (i) {
  362. to_remove = *i;
  363. if (! to_remove) {
  364. log_warn(LD_BUG, "Somehow, an HT iterator gave us a NULL pointer.");
  365. break;
  366. } else {
  367. /* Find a channel and circuit */
  368. chan = channel_find_by_global_id(to_remove->chan_id);
  369. if (chan) {
  370. circ =
  371. circuit_get_by_circid_channel_even_if_marked(to_remove->circ_id,
  372. chan);
  373. if (circ) {
  374. /* Clear the circuit's mux for this direction */
  375. if (to_remove->muxinfo.direction == CELL_DIRECTION_OUT) {
  376. /*
  377. * Update active_circuits et al.; this does policy notifies, so
  378. * comes before freeing policy data
  379. */
  380. if (to_remove->muxinfo.cell_count > 0) {
  381. circuitmux_make_circuit_inactive(cmux, circ, CELL_DIRECTION_OUT);
  382. }
  383. /* Clear n_mux */
  384. circ->n_mux = NULL;
  385. if (detached_out)
  386. smartlist_add(detached_out, circ);
  387. } else if (circ->magic == OR_CIRCUIT_MAGIC) {
  388. /*
  389. * Update active_circuits et al.; this does policy notifies, so
  390. * comes before freeing policy data
  391. */
  392. if (to_remove->muxinfo.cell_count > 0) {
  393. circuitmux_make_circuit_inactive(cmux, circ, CELL_DIRECTION_IN);
  394. }
  395. /*
  396. * It has a sensible p_chan and direction == CELL_DIRECTION_IN,
  397. * so clear p_mux.
  398. */
  399. TO_OR_CIRCUIT(circ)->p_mux = NULL;
  400. if (detached_out)
  401. smartlist_add(detached_out, circ);
  402. } else {
  403. /* Complain and move on */
  404. log_warn(LD_CIRC,
  405. "Circuit %u/channel " U64_FORMAT " had direction == "
  406. "CELL_DIRECTION_IN, but isn't an or_circuit_t",
  407. (unsigned)to_remove->circ_id,
  408. U64_PRINTF_ARG(to_remove->chan_id));
  409. }
  410. /* Free policy-specific data if we have it */
  411. if (to_remove->muxinfo.policy_data) {
  412. /*
  413. * If we have policy data, assert that we have the means to
  414. * free it
  415. */
  416. tor_assert(cmux->policy);
  417. tor_assert(cmux->policy->free_circ_data);
  418. /* Call free_circ_data() */
  419. cmux->policy->free_circ_data(cmux,
  420. cmux->policy_data,
  421. circ,
  422. to_remove->muxinfo.policy_data);
  423. to_remove->muxinfo.policy_data = NULL;
  424. }
  425. } else {
  426. /* Complain and move on */
  427. log_warn(LD_CIRC,
  428. "Couldn't find circuit %u (for channel " U64_FORMAT ")",
  429. (unsigned)to_remove->circ_id,
  430. U64_PRINTF_ARG(to_remove->chan_id));
  431. }
  432. } else {
  433. /* Complain and move on */
  434. log_warn(LD_CIRC,
  435. "Couldn't find channel " U64_FORMAT " (for circuit id %u)",
  436. U64_PRINTF_ARG(to_remove->chan_id),
  437. (unsigned)to_remove->circ_id);
  438. }
  439. /* Assert that we don't have un-freed policy data for this circuit */
  440. tor_assert(to_remove->muxinfo.policy_data == NULL);
  441. }
  442. i = HT_NEXT_RMV(chanid_circid_muxinfo_map, cmux->chanid_circid_map, i);
  443. /* Free it */
  444. tor_free(to_remove);
  445. }
  446. cmux->n_circuits = 0;
  447. cmux->n_active_circuits = 0;
  448. cmux->n_cells = 0;
  449. }
  450. /** Reclaim all circuit IDs currently marked as unusable on <b>chan</b> because
  451. * of pending destroy cells in <b>cmux</b>.
  452. *
  453. * This function must be called AFTER circuits are unlinked from the (channel,
  454. * circuid-id) map with circuit_unlink_all_from_channel(), but before calling
  455. * circuitmux_free().
  456. */
  457. void
  458. circuitmux_mark_destroyed_circids_usable(circuitmux_t *cmux, channel_t *chan)
  459. {
  460. packed_cell_t *cell;
  461. int n_bad = 0;
  462. TOR_SIMPLEQ_FOREACH(cell, &cmux->destroy_cell_queue.head, next) {
  463. circid_t circid = 0;
  464. if (packed_cell_is_destroy(chan, cell, &circid)) {
  465. channel_mark_circid_usable(chan, circid);
  466. } else {
  467. ++n_bad;
  468. }
  469. }
  470. if (n_bad)
  471. log_warn(LD_BUG, "%d cell(s) on destroy queue did not look like a "
  472. "DESTROY cell.", n_bad);
  473. }
  474. /**
  475. * Free a circuitmux_t; the circuits must be detached first with
  476. * circuitmux_detach_all_circuits().
  477. */
  478. void
  479. circuitmux_free_(circuitmux_t *cmux)
  480. {
  481. if (!cmux) return;
  482. tor_assert(cmux->n_circuits == 0);
  483. tor_assert(cmux->n_active_circuits == 0);
  484. /*
  485. * Free policy-specific data if we have any; we don't
  486. * need to do circuitmux_set_policy(cmux, NULL) to cover
  487. * the circuits because they would have been handled in
  488. * circuitmux_detach_all_circuits() before this was
  489. * called.
  490. */
  491. if (cmux->policy && cmux->policy->free_cmux_data) {
  492. if (cmux->policy_data) {
  493. cmux->policy->free_cmux_data(cmux, cmux->policy_data);
  494. cmux->policy_data = NULL;
  495. }
  496. } else tor_assert(cmux->policy_data == NULL);
  497. if (cmux->chanid_circid_map) {
  498. HT_CLEAR(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
  499. tor_free(cmux->chanid_circid_map);
  500. }
  501. /*
  502. * We're throwing away some destroys; log the counter and
  503. * adjust the global counter by the queue size.
  504. */
  505. if (cmux->destroy_cell_queue.n > 0) {
  506. cmux->destroy_ctr -= cmux->destroy_cell_queue.n;
  507. global_destroy_ctr -= cmux->destroy_cell_queue.n;
  508. log_debug(LD_CIRC,
  509. "Freeing cmux at %p with %u queued destroys; the last cmux "
  510. "destroy balance was "I64_FORMAT", global is "I64_FORMAT,
  511. cmux, cmux->destroy_cell_queue.n,
  512. I64_PRINTF_ARG(cmux->destroy_ctr),
  513. I64_PRINTF_ARG(global_destroy_ctr));
  514. } else {
  515. log_debug(LD_CIRC,
  516. "Freeing cmux at %p with no queued destroys, the cmux destroy "
  517. "balance was "I64_FORMAT", global is "I64_FORMAT,
  518. cmux,
  519. I64_PRINTF_ARG(cmux->destroy_ctr),
  520. I64_PRINTF_ARG(global_destroy_ctr));
  521. }
  522. cell_queue_clear(&cmux->destroy_cell_queue);
  523. tor_free(cmux);
  524. }
  525. /*
  526. * Circuitmux policy control functions
  527. */
  528. /**
  529. * Remove any policy installed on cmux; all policy data will be freed and
  530. * cmux behavior will revert to the built-in round-robin active_circuits
  531. * mechanism.
  532. */
  533. void
  534. circuitmux_clear_policy(circuitmux_t *cmux)
  535. {
  536. tor_assert(cmux);
  537. /* Internally, this is just setting policy to NULL */
  538. if (cmux->policy) {
  539. circuitmux_set_policy(cmux, NULL);
  540. }
  541. }
  542. /**
  543. * Return the policy currently installed on a circuitmux_t
  544. */
  545. MOCK_IMPL(const circuitmux_policy_t *,
  546. circuitmux_get_policy, (circuitmux_t *cmux))
  547. {
  548. tor_assert(cmux);
  549. return cmux->policy;
  550. }
  551. /**
  552. * Set policy; allocate for new policy, detach all circuits from old policy
  553. * if any, attach them to new policy, and free old policy data.
  554. */
  555. void
  556. circuitmux_set_policy(circuitmux_t *cmux,
  557. const circuitmux_policy_t *pol)
  558. {
  559. const circuitmux_policy_t *old_pol = NULL, *new_pol = NULL;
  560. circuitmux_policy_data_t *old_pol_data = NULL, *new_pol_data = NULL;
  561. chanid_circid_muxinfo_t **i = NULL;
  562. channel_t *chan = NULL;
  563. uint64_t last_chan_id_searched = 0;
  564. circuit_t *circ = NULL;
  565. tor_assert(cmux);
  566. /* Set up variables */
  567. old_pol = cmux->policy;
  568. old_pol_data = cmux->policy_data;
  569. new_pol = pol;
  570. /* Check if this is the trivial case */
  571. if (old_pol == new_pol) return;
  572. /* Allocate data for new policy, if any */
  573. if (new_pol && new_pol->alloc_cmux_data) {
  574. /*
  575. * If alloc_cmux_data is not null, then we expect to get some policy
  576. * data. Assert that we also have free_cmux_data so we can free it
  577. * when the time comes, and allocate it.
  578. */
  579. tor_assert(new_pol->free_cmux_data);
  580. new_pol_data = new_pol->alloc_cmux_data(cmux);
  581. tor_assert(new_pol_data);
  582. }
  583. /* Install new policy and new policy data on cmux */
  584. cmux->policy = new_pol;
  585. cmux->policy_data = new_pol_data;
  586. /* Iterate over all circuits, attaching/detaching each one */
  587. i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
  588. while (i) {
  589. /* Assert that this entry isn't NULL */
  590. tor_assert(*i);
  591. /*
  592. * Get the channel; since normal case is all circuits on the mux share a
  593. * channel, we cache last_chan_id_searched
  594. */
  595. if (!chan || last_chan_id_searched != (*i)->chan_id) {
  596. chan = channel_find_by_global_id((*i)->chan_id);
  597. last_chan_id_searched = (*i)->chan_id;
  598. }
  599. tor_assert(chan);
  600. /* Get the circuit */
  601. circ = circuit_get_by_circid_channel_even_if_marked((*i)->circ_id, chan);
  602. tor_assert(circ);
  603. /* Need to tell old policy it becomes inactive (i.e., it is active) ? */
  604. if (old_pol && old_pol->notify_circ_inactive &&
  605. (*i)->muxinfo.cell_count > 0) {
  606. old_pol->notify_circ_inactive(cmux, old_pol_data, circ,
  607. (*i)->muxinfo.policy_data);
  608. }
  609. /* Need to free old policy data? */
  610. if ((*i)->muxinfo.policy_data) {
  611. /* Assert that we have the means to free it if we have policy data */
  612. tor_assert(old_pol);
  613. tor_assert(old_pol->free_circ_data);
  614. /* Free it */
  615. old_pol->free_circ_data(cmux, old_pol_data, circ,
  616. (*i)->muxinfo.policy_data);
  617. (*i)->muxinfo.policy_data = NULL;
  618. }
  619. /* Need to allocate new policy data? */
  620. if (new_pol && new_pol->alloc_circ_data) {
  621. /*
  622. * If alloc_circ_data is not null, we expect to get some per-circuit
  623. * policy data. Assert that we also have free_circ_data so we can
  624. * free it when the time comes, and allocate it.
  625. */
  626. tor_assert(new_pol->free_circ_data);
  627. (*i)->muxinfo.policy_data =
  628. new_pol->alloc_circ_data(cmux, new_pol_data, circ,
  629. (*i)->muxinfo.direction,
  630. (*i)->muxinfo.cell_count);
  631. }
  632. /* Need to make active on new policy? */
  633. if (new_pol && new_pol->notify_circ_active &&
  634. (*i)->muxinfo.cell_count > 0) {
  635. new_pol->notify_circ_active(cmux, new_pol_data, circ,
  636. (*i)->muxinfo.policy_data);
  637. }
  638. /* Advance to next circuit map entry */
  639. i = HT_NEXT(chanid_circid_muxinfo_map, cmux->chanid_circid_map, i);
  640. }
  641. /* Free data for old policy, if any */
  642. if (old_pol_data) {
  643. /*
  644. * If we had old policy data, we should have an old policy and a free
  645. * function for it.
  646. */
  647. tor_assert(old_pol);
  648. tor_assert(old_pol->free_cmux_data);
  649. old_pol->free_cmux_data(cmux, old_pol_data);
  650. old_pol_data = NULL;
  651. }
  652. }
  653. /*
  654. * Circuitmux/circuit attachment status inquiry functions
  655. */
  656. /**
  657. * Query the direction of an attached circuit
  658. */
  659. cell_direction_t
  660. circuitmux_attached_circuit_direction(circuitmux_t *cmux, circuit_t *circ)
  661. {
  662. chanid_circid_muxinfo_t *hashent = NULL;
  663. /* Try to find a map entry */
  664. hashent = circuitmux_find_map_entry(cmux, circ);
  665. /*
  666. * This function should only be called on attached circuits; assert that
  667. * we had a map entry.
  668. */
  669. tor_assert(hashent);
  670. /* Return the direction from the map entry */
  671. return hashent->muxinfo.direction;
  672. }
  673. /**
  674. * Find an entry in the cmux's map for this circuit or return NULL if there
  675. * is none.
  676. */
  677. static chanid_circid_muxinfo_t *
  678. circuitmux_find_map_entry(circuitmux_t *cmux, circuit_t *circ)
  679. {
  680. chanid_circid_muxinfo_t search, *hashent = NULL;
  681. /* Sanity-check parameters */
  682. tor_assert(cmux);
  683. tor_assert(cmux->chanid_circid_map);
  684. tor_assert(circ);
  685. /* Check if we have n_chan */
  686. if (circ->n_chan) {
  687. /* Okay, let's see if it's attached for n_chan/n_circ_id */
  688. search.chan_id = circ->n_chan->global_identifier;
  689. search.circ_id = circ->n_circ_id;
  690. /* Query */
  691. hashent = HT_FIND(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
  692. &search);
  693. }
  694. /* Found something? */
  695. if (hashent) {
  696. /*
  697. * Assert that the direction makes sense for a hashent we found by
  698. * n_chan/n_circ_id before we return it.
  699. */
  700. tor_assert(hashent->muxinfo.direction == CELL_DIRECTION_OUT);
  701. } else {
  702. /* Not there, have we got a p_chan/p_circ_id to try? */
  703. if (circ->magic == OR_CIRCUIT_MAGIC) {
  704. search.circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
  705. /* Check for p_chan */
  706. if (TO_OR_CIRCUIT(circ)->p_chan) {
  707. search.chan_id = TO_OR_CIRCUIT(circ)->p_chan->global_identifier;
  708. /* Okay, search for that */
  709. hashent = HT_FIND(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
  710. &search);
  711. /* Find anything? */
  712. if (hashent) {
  713. /* Assert that the direction makes sense before we return it */
  714. tor_assert(hashent->muxinfo.direction == CELL_DIRECTION_IN);
  715. }
  716. }
  717. }
  718. }
  719. /* Okay, hashent is it if it was there */
  720. return hashent;
  721. }
  722. /**
  723. * Query whether a circuit is attached to a circuitmux
  724. */
  725. int
  726. circuitmux_is_circuit_attached(circuitmux_t *cmux, circuit_t *circ)
  727. {
  728. chanid_circid_muxinfo_t *hashent = NULL;
  729. /* Look if it's in the circuit map */
  730. hashent = circuitmux_find_map_entry(cmux, circ);
  731. return (hashent != NULL);
  732. }
  733. /**
  734. * Query whether a circuit is active on a circuitmux
  735. */
  736. int
  737. circuitmux_is_circuit_active(circuitmux_t *cmux, circuit_t *circ)
  738. {
  739. chanid_circid_muxinfo_t *hashent = NULL;
  740. int is_active = 0;
  741. tor_assert(cmux);
  742. tor_assert(circ);
  743. /* Look if it's in the circuit map */
  744. hashent = circuitmux_find_map_entry(cmux, circ);
  745. if (hashent) {
  746. /* Check the number of cells on this circuit */
  747. is_active = (hashent->muxinfo.cell_count > 0);
  748. }
  749. /* else not attached, so not active */
  750. return is_active;
  751. }
  752. /**
  753. * Query number of available cells for a circuit on a circuitmux
  754. */
  755. unsigned int
  756. circuitmux_num_cells_for_circuit(circuitmux_t *cmux, circuit_t *circ)
  757. {
  758. chanid_circid_muxinfo_t *hashent = NULL;
  759. unsigned int n_cells = 0;
  760. tor_assert(cmux);
  761. tor_assert(circ);
  762. /* Look if it's in the circuit map */
  763. hashent = circuitmux_find_map_entry(cmux, circ);
  764. if (hashent) {
  765. /* Just get the cell count for this circuit */
  766. n_cells = hashent->muxinfo.cell_count;
  767. }
  768. /* else not attached, so 0 cells */
  769. return n_cells;
  770. }
  771. /**
  772. * Query total number of available cells on a circuitmux
  773. */
  774. MOCK_IMPL(unsigned int,
  775. circuitmux_num_cells, (circuitmux_t *cmux))
  776. {
  777. tor_assert(cmux);
  778. return cmux->n_cells + cmux->destroy_cell_queue.n;
  779. }
  780. /**
  781. * Query total number of circuits active on a circuitmux
  782. */
  783. unsigned int
  784. circuitmux_num_active_circuits(circuitmux_t *cmux)
  785. {
  786. tor_assert(cmux);
  787. return cmux->n_active_circuits;
  788. }
  789. /**
  790. * Query total number of circuits attached to a circuitmux
  791. */
  792. unsigned int
  793. circuitmux_num_circuits(circuitmux_t *cmux)
  794. {
  795. tor_assert(cmux);
  796. return cmux->n_circuits;
  797. }
  798. /*
  799. * Functions for circuit code to call to update circuit status
  800. */
  801. /**
  802. * Attach a circuit to a circuitmux, for the specified direction.
  803. */
  804. MOCK_IMPL(void,
  805. circuitmux_attach_circuit,(circuitmux_t *cmux, circuit_t *circ,
  806. cell_direction_t direction))
  807. {
  808. channel_t *chan = NULL;
  809. uint64_t channel_id;
  810. circid_t circ_id;
  811. chanid_circid_muxinfo_t search, *hashent = NULL;
  812. unsigned int cell_count;
  813. tor_assert(cmux);
  814. tor_assert(circ);
  815. tor_assert(direction == CELL_DIRECTION_IN ||
  816. direction == CELL_DIRECTION_OUT);
  817. circuitmux_assert_okay_paranoid(cmux);
  818. /*
  819. * Figure out which channel we're using, and get the circuit's current
  820. * cell count and circuit ID; assert that the circuit is not already
  821. * attached to another mux.
  822. */
  823. if (direction == CELL_DIRECTION_OUT) {
  824. /* It's n_chan */
  825. chan = circ->n_chan;
  826. cell_count = circ->n_chan_cells.n;
  827. circ_id = circ->n_circ_id;
  828. } else {
  829. /* We want p_chan */
  830. chan = TO_OR_CIRCUIT(circ)->p_chan;
  831. cell_count = TO_OR_CIRCUIT(circ)->p_chan_cells.n;
  832. circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
  833. }
  834. /* Assert that we did get a channel */
  835. tor_assert(chan);
  836. /* Assert that the circuit ID is sensible */
  837. tor_assert(circ_id != 0);
  838. /* Get the channel ID */
  839. channel_id = chan->global_identifier;
  840. /* See if we already have this one */
  841. search.chan_id = channel_id;
  842. search.circ_id = circ_id;
  843. hashent = HT_FIND(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
  844. &search);
  845. if (hashent) {
  846. /*
  847. * This circuit was already attached to this cmux; make sure the
  848. * directions match and update the cell count and active circuit count.
  849. */
  850. log_info(LD_CIRC,
  851. "Circuit %u on channel " U64_FORMAT " was already attached to "
  852. "cmux %p (trying to attach to %p)",
  853. (unsigned)circ_id, U64_PRINTF_ARG(channel_id),
  854. ((direction == CELL_DIRECTION_OUT) ?
  855. circ->n_mux : TO_OR_CIRCUIT(circ)->p_mux),
  856. cmux);
  857. /*
  858. * The mux pointer on this circuit and the direction in result should
  859. * match; otherwise assert.
  860. */
  861. if (direction == CELL_DIRECTION_OUT) tor_assert(circ->n_mux == cmux);
  862. else tor_assert(TO_OR_CIRCUIT(circ)->p_mux == cmux);
  863. tor_assert(hashent->muxinfo.direction == direction);
  864. /*
  865. * Looks okay; just update the cell count and active circuits if we must
  866. */
  867. if (hashent->muxinfo.cell_count > 0 && cell_count == 0) {
  868. --(cmux->n_active_circuits);
  869. circuitmux_make_circuit_inactive(cmux, circ, direction);
  870. } else if (hashent->muxinfo.cell_count == 0 && cell_count > 0) {
  871. ++(cmux->n_active_circuits);
  872. circuitmux_make_circuit_active(cmux, circ, direction);
  873. }
  874. cmux->n_cells -= hashent->muxinfo.cell_count;
  875. cmux->n_cells += cell_count;
  876. hashent->muxinfo.cell_count = cell_count;
  877. } else {
  878. /*
  879. * New circuit; add an entry and update the circuit/active circuit
  880. * counts.
  881. */
  882. log_debug(LD_CIRC,
  883. "Attaching circuit %u on channel " U64_FORMAT " to cmux %p",
  884. (unsigned)circ_id, U64_PRINTF_ARG(channel_id), cmux);
  885. /*
  886. * Assert that the circuit doesn't already have a mux for this
  887. * direction.
  888. */
  889. if (direction == CELL_DIRECTION_OUT) tor_assert(circ->n_mux == NULL);
  890. else tor_assert(TO_OR_CIRCUIT(circ)->p_mux == NULL);
  891. /* Insert it in the map */
  892. hashent = tor_malloc_zero(sizeof(*hashent));
  893. hashent->chan_id = channel_id;
  894. hashent->circ_id = circ_id;
  895. hashent->muxinfo.cell_count = cell_count;
  896. hashent->muxinfo.direction = direction;
  897. /* Allocate policy specific circuit data if we need it */
  898. if (cmux->policy && cmux->policy->alloc_circ_data) {
  899. /* Assert that we have the means to free policy-specific data */
  900. tor_assert(cmux->policy->free_circ_data);
  901. /* Allocate it */
  902. hashent->muxinfo.policy_data =
  903. cmux->policy->alloc_circ_data(cmux,
  904. cmux->policy_data,
  905. circ,
  906. direction,
  907. cell_count);
  908. /* If we wanted policy data, it's an error not to get any */
  909. tor_assert(hashent->muxinfo.policy_data);
  910. }
  911. HT_INSERT(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
  912. hashent);
  913. /* Set the circuit's mux for this direction */
  914. if (direction == CELL_DIRECTION_OUT) circ->n_mux = cmux;
  915. else TO_OR_CIRCUIT(circ)->p_mux = cmux;
  916. /* Make sure the next/prev pointers are NULL */
  917. if (direction == CELL_DIRECTION_OUT) {
  918. circ->next_active_on_n_chan = NULL;
  919. circ->prev_active_on_n_chan = NULL;
  920. } else {
  921. TO_OR_CIRCUIT(circ)->next_active_on_p_chan = NULL;
  922. TO_OR_CIRCUIT(circ)->prev_active_on_p_chan = NULL;
  923. }
  924. /* Update counters */
  925. ++(cmux->n_circuits);
  926. if (cell_count > 0) {
  927. ++(cmux->n_active_circuits);
  928. circuitmux_make_circuit_active(cmux, circ, direction);
  929. }
  930. cmux->n_cells += cell_count;
  931. }
  932. circuitmux_assert_okay_paranoid(cmux);
  933. }
  934. /**
  935. * Detach a circuit from a circuitmux and update all counters as needed;
  936. * no-op if not attached.
  937. */
  938. MOCK_IMPL(void,
  939. circuitmux_detach_circuit,(circuitmux_t *cmux, circuit_t *circ))
  940. {
  941. chanid_circid_muxinfo_t search, *hashent = NULL;
  942. /*
  943. * Use this to keep track of whether we found it for n_chan or
  944. * p_chan for consistency checking.
  945. *
  946. * The 0 initializer is not a valid cell_direction_t value.
  947. * We assert that it has been replaced with a valid value before it is used.
  948. */
  949. cell_direction_t last_searched_direction = 0;
  950. tor_assert(cmux);
  951. tor_assert(cmux->chanid_circid_map);
  952. tor_assert(circ);
  953. circuitmux_assert_okay_paranoid(cmux);
  954. /* See if we have it for n_chan/n_circ_id */
  955. if (circ->n_chan) {
  956. search.chan_id = circ->n_chan->global_identifier;
  957. search.circ_id = circ->n_circ_id;
  958. hashent = HT_FIND(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
  959. &search);
  960. last_searched_direction = CELL_DIRECTION_OUT;
  961. }
  962. /* Got one? If not, see if it's an or_circuit_t and try p_chan/p_circ_id */
  963. if (!hashent) {
  964. if (circ->magic == OR_CIRCUIT_MAGIC) {
  965. search.circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
  966. if (TO_OR_CIRCUIT(circ)->p_chan) {
  967. search.chan_id = TO_OR_CIRCUIT(circ)->p_chan->global_identifier;
  968. hashent = HT_FIND(chanid_circid_muxinfo_map,
  969. cmux->chanid_circid_map,
  970. &search);
  971. last_searched_direction = CELL_DIRECTION_IN;
  972. }
  973. }
  974. }
  975. tor_assert(last_searched_direction == CELL_DIRECTION_OUT
  976. || last_searched_direction == CELL_DIRECTION_IN);
  977. /*
  978. * If hashent isn't NULL, we have a circuit to detach; don't remove it from
  979. * the map until later of circuitmux_make_circuit_inactive() breaks.
  980. */
  981. if (hashent) {
  982. /* Update counters */
  983. --(cmux->n_circuits);
  984. if (hashent->muxinfo.cell_count > 0) {
  985. --(cmux->n_active_circuits);
  986. /* This does policy notifies, so comes before freeing policy data */
  987. circuitmux_make_circuit_inactive(cmux, circ, last_searched_direction);
  988. }
  989. cmux->n_cells -= hashent->muxinfo.cell_count;
  990. /* Free policy-specific data if we have it */
  991. if (hashent->muxinfo.policy_data) {
  992. /* If we have policy data, assert that we have the means to free it */
  993. tor_assert(cmux->policy);
  994. tor_assert(cmux->policy->free_circ_data);
  995. /* Call free_circ_data() */
  996. cmux->policy->free_circ_data(cmux,
  997. cmux->policy_data,
  998. circ,
  999. hashent->muxinfo.policy_data);
  1000. hashent->muxinfo.policy_data = NULL;
  1001. }
  1002. /* Consistency check: the direction must match the direction searched */
  1003. tor_assert(last_searched_direction == hashent->muxinfo.direction);
  1004. /* Clear the circuit's mux for this direction */
  1005. if (last_searched_direction == CELL_DIRECTION_OUT) circ->n_mux = NULL;
  1006. else TO_OR_CIRCUIT(circ)->p_mux = NULL;
  1007. /* Now remove it from the map */
  1008. HT_REMOVE(chanid_circid_muxinfo_map, cmux->chanid_circid_map, hashent);
  1009. /* Free the hash entry */
  1010. tor_free(hashent);
  1011. }
  1012. circuitmux_assert_okay_paranoid(cmux);
  1013. }
  1014. /**
  1015. * Make a circuit active; update active list and policy-specific info, but
  1016. * we don't mess with the counters or hash table here.
  1017. */
  1018. static void
  1019. circuitmux_make_circuit_active(circuitmux_t *cmux, circuit_t *circ,
  1020. cell_direction_t direction)
  1021. {
  1022. circuit_t **next_active = NULL, **prev_active = NULL, **next_prev = NULL;
  1023. circuitmux_t *circuit_cmux = NULL;
  1024. chanid_circid_muxinfo_t *hashent = NULL;
  1025. channel_t *chan = NULL;
  1026. circid_t circ_id;
  1027. int already_active;
  1028. tor_assert(cmux);
  1029. tor_assert(circ);
  1030. tor_assert(direction == CELL_DIRECTION_OUT ||
  1031. direction == CELL_DIRECTION_IN);
  1032. /*
  1033. * Don't circuitmux_assert_okay_paranoid(cmux) here because the cell count
  1034. * already got changed and we have to update the list for it to be consistent
  1035. * again.
  1036. */
  1037. /* Get the right set of active list links for this direction */
  1038. if (direction == CELL_DIRECTION_OUT) {
  1039. next_active = &(circ->next_active_on_n_chan);
  1040. prev_active = &(circ->prev_active_on_n_chan);
  1041. circuit_cmux = circ->n_mux;
  1042. chan = circ->n_chan;
  1043. circ_id = circ->n_circ_id;
  1044. } else {
  1045. next_active = &(TO_OR_CIRCUIT(circ)->next_active_on_p_chan);
  1046. prev_active = &(TO_OR_CIRCUIT(circ)->prev_active_on_p_chan);
  1047. circuit_cmux = TO_OR_CIRCUIT(circ)->p_mux;
  1048. chan = TO_OR_CIRCUIT(circ)->p_chan;
  1049. circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
  1050. }
  1051. /* Assert that it is attached to this mux and a channel */
  1052. tor_assert(cmux == circuit_cmux);
  1053. tor_assert(chan != NULL);
  1054. /*
  1055. * Check if the circuit really was inactive; if it's active, at least one
  1056. * of the next_active and prev_active pointers will not be NULL, or this
  1057. * circuit will be either the head or tail of the list for this cmux.
  1058. */
  1059. already_active = (*prev_active != NULL || *next_active != NULL ||
  1060. cmux->active_circuits_head == circ ||
  1061. cmux->active_circuits_tail == circ);
  1062. /* If we're already active, log a warning and finish */
  1063. if (already_active) {
  1064. log_warn(LD_CIRC,
  1065. "Circuit %u on channel " U64_FORMAT " was already active",
  1066. (unsigned)circ_id, U64_PRINTF_ARG(chan->global_identifier));
  1067. return;
  1068. }
  1069. /*
  1070. * This is going at the head of the list; if the old head is not NULL,
  1071. * then its prev pointer should point to this.
  1072. */
  1073. *next_active = cmux->active_circuits_head; /* Next is old head */
  1074. *prev_active = NULL; /* Prev is NULL (this will be the head) */
  1075. if (cmux->active_circuits_head) {
  1076. /* The list had an old head; update its prev pointer */
  1077. next_prev =
  1078. circuitmux_prev_active_circ_p(cmux, cmux->active_circuits_head);
  1079. tor_assert(next_prev);
  1080. *next_prev = circ;
  1081. } else {
  1082. /* The list was empty; this becomes the tail as well */
  1083. cmux->active_circuits_tail = circ;
  1084. }
  1085. /* This becomes the new head of the list */
  1086. cmux->active_circuits_head = circ;
  1087. /* Policy-specific notification */
  1088. if (cmux->policy &&
  1089. cmux->policy->notify_circ_active) {
  1090. /* Okay, we need to check the circuit for policy data now */
  1091. hashent = circuitmux_find_map_entry(cmux, circ);
  1092. /* We should have found something */
  1093. tor_assert(hashent);
  1094. /* Notify */
  1095. cmux->policy->notify_circ_active(cmux, cmux->policy_data,
  1096. circ, hashent->muxinfo.policy_data);
  1097. }
  1098. circuitmux_assert_okay_paranoid(cmux);
  1099. }
  1100. /**
  1101. * Make a circuit inactive; update active list and policy-specific info, but
  1102. * we don't mess with the counters or hash table here.
  1103. */
  1104. static void
  1105. circuitmux_make_circuit_inactive(circuitmux_t *cmux, circuit_t *circ,
  1106. cell_direction_t direction)
  1107. {
  1108. circuit_t **next_active = NULL, **prev_active = NULL;
  1109. circuit_t **next_prev = NULL, **prev_next = NULL;
  1110. circuitmux_t *circuit_cmux = NULL;
  1111. chanid_circid_muxinfo_t *hashent = NULL;
  1112. channel_t *chan = NULL;
  1113. circid_t circ_id;
  1114. int already_inactive;
  1115. tor_assert(cmux);
  1116. tor_assert(circ);
  1117. tor_assert(direction == CELL_DIRECTION_OUT ||
  1118. direction == CELL_DIRECTION_IN);
  1119. /*
  1120. * Don't circuitmux_assert_okay_paranoid(cmux) here because the cell count
  1121. * already got changed and we have to update the list for it to be consistent
  1122. * again.
  1123. */
  1124. /* Get the right set of active list links for this direction */
  1125. if (direction == CELL_DIRECTION_OUT) {
  1126. next_active = &(circ->next_active_on_n_chan);
  1127. prev_active = &(circ->prev_active_on_n_chan);
  1128. circuit_cmux = circ->n_mux;
  1129. chan = circ->n_chan;
  1130. circ_id = circ->n_circ_id;
  1131. } else {
  1132. next_active = &(TO_OR_CIRCUIT(circ)->next_active_on_p_chan);
  1133. prev_active = &(TO_OR_CIRCUIT(circ)->prev_active_on_p_chan);
  1134. circuit_cmux = TO_OR_CIRCUIT(circ)->p_mux;
  1135. chan = TO_OR_CIRCUIT(circ)->p_chan;
  1136. circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
  1137. }
  1138. /* Assert that it is attached to this mux and a channel */
  1139. tor_assert(cmux == circuit_cmux);
  1140. tor_assert(chan != NULL);
  1141. /*
  1142. * Check if the circuit really was active; if it's inactive, the
  1143. * next_active and prev_active pointers will be NULL and this circuit
  1144. * will not be the head or tail of the list for this cmux.
  1145. */
  1146. already_inactive = (*prev_active == NULL && *next_active == NULL &&
  1147. cmux->active_circuits_head != circ &&
  1148. cmux->active_circuits_tail != circ);
  1149. /* If we're already inactive, log a warning and finish */
  1150. if (already_inactive) {
  1151. log_warn(LD_CIRC,
  1152. "Circuit %d on channel " U64_FORMAT " was already inactive",
  1153. (unsigned)circ_id, U64_PRINTF_ARG(chan->global_identifier));
  1154. return;
  1155. }
  1156. /* Remove from the list; first get next_prev and prev_next */
  1157. if (*next_active) {
  1158. /*
  1159. * If there's a next circuit, its previous circuit becomes this
  1160. * circuit's previous circuit.
  1161. */
  1162. next_prev = circuitmux_prev_active_circ_p(cmux, *next_active);
  1163. } else {
  1164. /* Else, the tail becomes this circuit's previous circuit */
  1165. next_prev = &(cmux->active_circuits_tail);
  1166. }
  1167. /* Got next_prev, now prev_next */
  1168. if (*prev_active) {
  1169. /*
  1170. * If there's a previous circuit, its next circuit becomes this circuit's
  1171. * next circuit.
  1172. */
  1173. prev_next = circuitmux_next_active_circ_p(cmux, *prev_active);
  1174. } else {
  1175. /* Else, the head becomes this circuit's next circuit */
  1176. prev_next = &(cmux->active_circuits_head);
  1177. }
  1178. /* Assert that we got sensible values for the next/prev pointers */
  1179. tor_assert(next_prev != NULL);
  1180. tor_assert(prev_next != NULL);
  1181. /* Update the next/prev pointers - this removes circ from the list */
  1182. *next_prev = *prev_active;
  1183. *prev_next = *next_active;
  1184. /* Now null out prev_active/next_active */
  1185. *prev_active = NULL;
  1186. *next_active = NULL;
  1187. /* Policy-specific notification */
  1188. if (cmux->policy &&
  1189. cmux->policy->notify_circ_inactive) {
  1190. /* Okay, we need to check the circuit for policy data now */
  1191. hashent = circuitmux_find_map_entry(cmux, circ);
  1192. /* We should have found something */
  1193. tor_assert(hashent);
  1194. /* Notify */
  1195. cmux->policy->notify_circ_inactive(cmux, cmux->policy_data,
  1196. circ, hashent->muxinfo.policy_data);
  1197. }
  1198. circuitmux_assert_okay_paranoid(cmux);
  1199. }
  1200. /**
  1201. * Clear the cell counter for a circuit on a circuitmux
  1202. */
  1203. void
  1204. circuitmux_clear_num_cells(circuitmux_t *cmux, circuit_t *circ)
  1205. {
  1206. /* This is the same as setting the cell count to zero */
  1207. circuitmux_set_num_cells(cmux, circ, 0);
  1208. }
  1209. /**
  1210. * Set the cell counter for a circuit on a circuitmux
  1211. */
  1212. void
  1213. circuitmux_set_num_cells(circuitmux_t *cmux, circuit_t *circ,
  1214. unsigned int n_cells)
  1215. {
  1216. chanid_circid_muxinfo_t *hashent = NULL;
  1217. tor_assert(cmux);
  1218. tor_assert(circ);
  1219. circuitmux_assert_okay_paranoid(cmux);
  1220. /* Search for this circuit's entry */
  1221. hashent = circuitmux_find_map_entry(cmux, circ);
  1222. /* Assert that we found one */
  1223. tor_assert(hashent);
  1224. /* Update cmux cell counter */
  1225. cmux->n_cells -= hashent->muxinfo.cell_count;
  1226. cmux->n_cells += n_cells;
  1227. /* Do we need to notify a cmux policy? */
  1228. if (cmux->policy && cmux->policy->notify_set_n_cells) {
  1229. /* Call notify_set_n_cells */
  1230. cmux->policy->notify_set_n_cells(cmux,
  1231. cmux->policy_data,
  1232. circ,
  1233. hashent->muxinfo.policy_data,
  1234. n_cells);
  1235. }
  1236. /*
  1237. * Update cmux active circuit counter: is the old cell count > 0 and the
  1238. * new cell count == 0 ?
  1239. */
  1240. if (hashent->muxinfo.cell_count > 0 && n_cells == 0) {
  1241. --(cmux->n_active_circuits);
  1242. hashent->muxinfo.cell_count = n_cells;
  1243. circuitmux_make_circuit_inactive(cmux, circ, hashent->muxinfo.direction);
  1244. /* Is the old cell count == 0 and the new cell count > 0 ? */
  1245. } else if (hashent->muxinfo.cell_count == 0 && n_cells > 0) {
  1246. ++(cmux->n_active_circuits);
  1247. hashent->muxinfo.cell_count = n_cells;
  1248. circuitmux_make_circuit_active(cmux, circ, hashent->muxinfo.direction);
  1249. } else {
  1250. /*
  1251. * Update the entry cell count like this so we can put a
  1252. * circuitmux_assert_okay_paranoid inside make_circuit_(in)active() too.
  1253. */
  1254. hashent->muxinfo.cell_count = n_cells;
  1255. }
  1256. circuitmux_assert_okay_paranoid(cmux);
  1257. }
  1258. /*
  1259. * Functions for channel code to call to get a circuit to transmit from or
  1260. * notify that cells have been transmitted.
  1261. */
  1262. /**
  1263. * Pick a circuit to send from, using the active circuits list or a
  1264. * circuitmux policy if one is available. This is called from channel.c.
  1265. *
  1266. * If we would rather send a destroy cell, return NULL and set
  1267. * *<b>destroy_queue_out</b> to the destroy queue.
  1268. *
  1269. * If we have nothing to send, set *<b>destroy_queue_out</b> to NULL and
  1270. * return NULL.
  1271. */
  1272. circuit_t *
  1273. circuitmux_get_first_active_circuit(circuitmux_t *cmux,
  1274. cell_queue_t **destroy_queue_out)
  1275. {
  1276. circuit_t *circ = NULL;
  1277. tor_assert(cmux);
  1278. tor_assert(destroy_queue_out);
  1279. *destroy_queue_out = NULL;
  1280. if (cmux->destroy_cell_queue.n &&
  1281. (!cmux->last_cell_was_destroy || cmux->n_active_circuits == 0)) {
  1282. /* We have destroy cells to send, and either we just sent a relay cell,
  1283. * or we have no relay cells to send. */
  1284. /* XXXX We should let the cmux policy have some say in this eventually. */
  1285. /* XXXX Alternating is not a terribly brilliant approach here. */
  1286. *destroy_queue_out = &cmux->destroy_cell_queue;
  1287. cmux->last_cell_was_destroy = 1;
  1288. } else if (cmux->n_active_circuits > 0) {
  1289. /* We also must have a cell available for this to be the case */
  1290. tor_assert(cmux->n_cells > 0);
  1291. /* Do we have a policy-provided circuit selector? */
  1292. if (cmux->policy && cmux->policy->pick_active_circuit) {
  1293. circ = cmux->policy->pick_active_circuit(cmux, cmux->policy_data);
  1294. }
  1295. /* Fall back on the head of the active circuits list */
  1296. if (!circ) {
  1297. tor_assert(cmux->active_circuits_head);
  1298. circ = cmux->active_circuits_head;
  1299. }
  1300. cmux->last_cell_was_destroy = 0;
  1301. } else {
  1302. tor_assert(cmux->n_cells == 0);
  1303. tor_assert(cmux->destroy_cell_queue.n == 0);
  1304. }
  1305. return circ;
  1306. }
  1307. /**
  1308. * Notify the circuitmux that cells have been sent on a circuit; this
  1309. * is called from channel.c.
  1310. */
  1311. void
  1312. circuitmux_notify_xmit_cells(circuitmux_t *cmux, circuit_t *circ,
  1313. unsigned int n_cells)
  1314. {
  1315. chanid_circid_muxinfo_t *hashent = NULL;
  1316. int becomes_inactive = 0;
  1317. tor_assert(cmux);
  1318. tor_assert(circ);
  1319. circuitmux_assert_okay_paranoid(cmux);
  1320. if (n_cells == 0) return;
  1321. /*
  1322. * To handle this, we have to:
  1323. *
  1324. * 1.) Adjust the circuit's cell counter in the cmux hash table
  1325. * 2.) Move the circuit to the tail of the active_circuits linked list
  1326. * for this cmux, or make the circuit inactive if the cell count
  1327. * went to zero.
  1328. * 3.) Call cmux->policy->notify_xmit_cells(), if any
  1329. */
  1330. /* Find the hash entry */
  1331. hashent = circuitmux_find_map_entry(cmux, circ);
  1332. /* Assert that we found one */
  1333. tor_assert(hashent);
  1334. /* Adjust the cell counter and assert that we had that many cells to send */
  1335. tor_assert(n_cells <= hashent->muxinfo.cell_count);
  1336. hashent->muxinfo.cell_count -= n_cells;
  1337. /* Do we need to make the circuit inactive? */
  1338. if (hashent->muxinfo.cell_count == 0) becomes_inactive = 1;
  1339. /* Adjust the mux cell counter */
  1340. cmux->n_cells -= n_cells;
  1341. /* If we aren't making it inactive later, move it to the tail of the list */
  1342. if (!becomes_inactive) {
  1343. circuitmux_move_active_circ_to_tail(cmux, circ,
  1344. hashent->muxinfo.direction);
  1345. }
  1346. /*
  1347. * We call notify_xmit_cells() before making the circuit inactive if needed,
  1348. * so the policy can always count on this coming in on an active circuit.
  1349. */
  1350. if (cmux->policy && cmux->policy->notify_xmit_cells) {
  1351. cmux->policy->notify_xmit_cells(cmux, cmux->policy_data, circ,
  1352. hashent->muxinfo.policy_data,
  1353. n_cells);
  1354. }
  1355. /*
  1356. * Now make the circuit inactive if needed; this will call the policy's
  1357. * notify_circ_inactive() if present.
  1358. */
  1359. if (becomes_inactive) {
  1360. --(cmux->n_active_circuits);
  1361. circuitmux_make_circuit_inactive(cmux, circ, hashent->muxinfo.direction);
  1362. }
  1363. circuitmux_assert_okay_paranoid(cmux);
  1364. }
  1365. /**
  1366. * Notify the circuitmux that a destroy was sent, so we can update
  1367. * the counter.
  1368. */
  1369. void
  1370. circuitmux_notify_xmit_destroy(circuitmux_t *cmux)
  1371. {
  1372. tor_assert(cmux);
  1373. --(cmux->destroy_ctr);
  1374. --(global_destroy_ctr);
  1375. log_debug(LD_CIRC,
  1376. "Cmux at %p sent a destroy, cmux counter is now "I64_FORMAT", "
  1377. "global counter is now "I64_FORMAT,
  1378. cmux,
  1379. I64_PRINTF_ARG(cmux->destroy_ctr),
  1380. I64_PRINTF_ARG(global_destroy_ctr));
  1381. }
  1382. /*
  1383. * Circuitmux consistency checking assertions
  1384. */
  1385. /**
  1386. * Check that circuitmux data structures are consistent and fail with an
  1387. * assert if not.
  1388. */
  1389. void
  1390. circuitmux_assert_okay(circuitmux_t *cmux)
  1391. {
  1392. tor_assert(cmux);
  1393. /*
  1394. * Pass 1: iterate the hash table; for each entry:
  1395. * a) Check that the circuit has this cmux for n_mux or p_mux
  1396. * b) If the cell_count is > 0, set the mark bit; otherwise clear it
  1397. * c) Also check activeness (cell_count > 0 should be active)
  1398. * d) Count the number of circuits, active circuits and queued cells
  1399. * and at the end check that they match the counters in the cmux.
  1400. *
  1401. * Pass 2: iterate the active circuits list; for each entry,
  1402. * make sure the circuit is attached to this mux and appears
  1403. * in the hash table. Make sure the mark bit is 1, and clear
  1404. * it in the hash table entry. Consistency-check the linked
  1405. * list pointers.
  1406. *
  1407. * Pass 3: iterate the hash table again; assert if any active circuits
  1408. * (mark bit set to 1) are discovered that weren't cleared in pass 2
  1409. * (don't appear in the linked list).
  1410. */
  1411. circuitmux_assert_okay_pass_one(cmux);
  1412. circuitmux_assert_okay_pass_two(cmux);
  1413. circuitmux_assert_okay_pass_three(cmux);
  1414. }
  1415. /**
  1416. * Do the first pass of circuitmux_assert_okay(); see the comment in that
  1417. * function.
  1418. */
  1419. static void
  1420. circuitmux_assert_okay_pass_one(circuitmux_t *cmux)
  1421. {
  1422. chanid_circid_muxinfo_t **i = NULL;
  1423. uint64_t chan_id;
  1424. channel_t *chan;
  1425. circid_t circ_id;
  1426. circuit_t *circ;
  1427. or_circuit_t *or_circ;
  1428. circuit_t **next_p, **prev_p;
  1429. unsigned int n_circuits, n_active_circuits, n_cells;
  1430. tor_assert(cmux);
  1431. tor_assert(cmux->chanid_circid_map);
  1432. /* Reset the counters */
  1433. n_circuits = n_active_circuits = n_cells = 0;
  1434. /* Start iterating the hash table */
  1435. i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
  1436. while (i) {
  1437. /* Assert that the hash table entry isn't null */
  1438. tor_assert(*i);
  1439. /* Get the channel and circuit id */
  1440. chan_id = (*i)->chan_id;
  1441. circ_id = (*i)->circ_id;
  1442. /* Find the channel and circuit, assert that they exist */
  1443. chan = channel_find_by_global_id(chan_id);
  1444. tor_assert(chan);
  1445. circ = circuit_get_by_circid_channel_even_if_marked(circ_id, chan);
  1446. tor_assert(circ);
  1447. /* Assert that we know which direction this is going */
  1448. tor_assert((*i)->muxinfo.direction == CELL_DIRECTION_OUT ||
  1449. (*i)->muxinfo.direction == CELL_DIRECTION_IN);
  1450. if ((*i)->muxinfo.direction == CELL_DIRECTION_OUT) {
  1451. /* We should be n_mux on this circuit */
  1452. tor_assert(cmux == circ->n_mux);
  1453. tor_assert(chan == circ->n_chan);
  1454. /* Get next and prev for next test */
  1455. next_p = &(circ->next_active_on_n_chan);
  1456. prev_p = &(circ->prev_active_on_n_chan);
  1457. } else {
  1458. /* This should be an or_circuit_t and we should be p_mux */
  1459. or_circ = TO_OR_CIRCUIT(circ);
  1460. tor_assert(cmux == or_circ->p_mux);
  1461. tor_assert(chan == or_circ->p_chan);
  1462. /* Get next and prev for next test */
  1463. next_p = &(or_circ->next_active_on_p_chan);
  1464. prev_p = &(or_circ->prev_active_on_p_chan);
  1465. }
  1466. /*
  1467. * Should this circuit be active? I.e., does the mux know about > 0
  1468. * cells on it?
  1469. */
  1470. const int circ_is_active = ((*i)->muxinfo.cell_count > 0);
  1471. /* It should be in the linked list iff it's active */
  1472. if (circ_is_active) {
  1473. /* Either we have a next link or we are the tail */
  1474. tor_assert(*next_p || (circ == cmux->active_circuits_tail));
  1475. /* Either we have a prev link or we are the head */
  1476. tor_assert(*prev_p || (circ == cmux->active_circuits_head));
  1477. /* Increment the active circuits counter */
  1478. ++n_active_circuits;
  1479. } else {
  1480. /* Shouldn't be in list, so no next or prev link */
  1481. tor_assert(!(*next_p));
  1482. tor_assert(!(*prev_p));
  1483. /* And can't be head or tail */
  1484. tor_assert(circ != cmux->active_circuits_head);
  1485. tor_assert(circ != cmux->active_circuits_tail);
  1486. }
  1487. /* Increment the circuits counter */
  1488. ++n_circuits;
  1489. /* Adjust the cell counter */
  1490. n_cells += (*i)->muxinfo.cell_count;
  1491. /* Set the mark bit to circ_is_active */
  1492. (*i)->muxinfo.mark = circ_is_active;
  1493. /* Advance to the next entry */
  1494. i = HT_NEXT(chanid_circid_muxinfo_map, cmux->chanid_circid_map, i);
  1495. }
  1496. /* Now check the counters */
  1497. tor_assert(n_cells == cmux->n_cells);
  1498. tor_assert(n_circuits == cmux->n_circuits);
  1499. tor_assert(n_active_circuits == cmux->n_active_circuits);
  1500. }
  1501. /**
  1502. * Do the second pass of circuitmux_assert_okay(); see the comment in that
  1503. * function.
  1504. */
  1505. static void
  1506. circuitmux_assert_okay_pass_two(circuitmux_t *cmux)
  1507. {
  1508. circuit_t *curr_circ, *prev_circ = NULL, *next_circ;
  1509. or_circuit_t *curr_or_circ;
  1510. uint64_t curr_chan_id;
  1511. circid_t curr_circ_id;
  1512. circuit_t **next_p, **prev_p;
  1513. channel_t *chan;
  1514. unsigned int n_active_circuits = 0;
  1515. chanid_circid_muxinfo_t search, *hashent = NULL;
  1516. tor_assert(cmux);
  1517. tor_assert(cmux->chanid_circid_map);
  1518. /*
  1519. * Walk the linked list of active circuits in cmux; keep track of the
  1520. * previous circuit seen for consistency checking purposes. Count them
  1521. * to make sure the number in the linked list matches
  1522. * cmux->n_active_circuits.
  1523. */
  1524. curr_circ = cmux->active_circuits_head;
  1525. while (curr_circ) {
  1526. /* Reset some things */
  1527. chan = NULL;
  1528. curr_or_circ = NULL;
  1529. next_circ = NULL;
  1530. next_p = prev_p = NULL;
  1531. cell_direction_t direction;
  1532. /* Figure out if this is n_mux or p_mux */
  1533. if (cmux == curr_circ->n_mux) {
  1534. /* Get next_p and prev_p */
  1535. next_p = &(curr_circ->next_active_on_n_chan);
  1536. prev_p = &(curr_circ->prev_active_on_n_chan);
  1537. /* Get the channel */
  1538. chan = curr_circ->n_chan;
  1539. /* Get the circuit id */
  1540. curr_circ_id = curr_circ->n_circ_id;
  1541. /* Remember the direction */
  1542. direction = CELL_DIRECTION_OUT;
  1543. } else {
  1544. /* We must be p_mux and this must be an or_circuit_t */
  1545. curr_or_circ = TO_OR_CIRCUIT(curr_circ);
  1546. tor_assert(cmux == curr_or_circ->p_mux);
  1547. /* Get next_p and prev_p */
  1548. next_p = &(curr_or_circ->next_active_on_p_chan);
  1549. prev_p = &(curr_or_circ->prev_active_on_p_chan);
  1550. /* Get the channel */
  1551. chan = curr_or_circ->p_chan;
  1552. /* Get the circuit id */
  1553. curr_circ_id = curr_or_circ->p_circ_id;
  1554. /* Remember the direction */
  1555. direction = CELL_DIRECTION_IN;
  1556. }
  1557. /* Assert that we got a channel and get the channel ID */
  1558. tor_assert(chan);
  1559. curr_chan_id = chan->global_identifier;
  1560. /* Assert that prev_p points to last circuit we saw */
  1561. tor_assert(*prev_p == prev_circ);
  1562. /* If that's NULL, assert that we are the head */
  1563. if (!(*prev_p)) tor_assert(curr_circ == cmux->active_circuits_head);
  1564. /* Get the next circuit */
  1565. next_circ = *next_p;
  1566. /* If it's NULL, assert that we are the tail */
  1567. if (!(*next_p)) tor_assert(curr_circ == cmux->active_circuits_tail);
  1568. /* Now find the hash table entry for this circuit */
  1569. search.chan_id = curr_chan_id;
  1570. search.circ_id = curr_circ_id;
  1571. hashent = HT_FIND(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
  1572. &search);
  1573. /* Assert that we have one */
  1574. tor_assert(hashent);
  1575. /* Assert that the direction matches */
  1576. tor_assert(direction == hashent->muxinfo.direction);
  1577. /* Assert that the hash entry got marked in pass one */
  1578. tor_assert(hashent->muxinfo.mark);
  1579. /* Clear the mark */
  1580. hashent->muxinfo.mark = 0;
  1581. /* Increment the counter */
  1582. ++n_active_circuits;
  1583. /* Advance to the next active circuit and update prev_circ */
  1584. prev_circ = curr_circ;
  1585. curr_circ = next_circ;
  1586. }
  1587. /* Assert that the counter matches the cmux */
  1588. tor_assert(n_active_circuits == cmux->n_active_circuits);
  1589. }
  1590. /**
  1591. * Do the third pass of circuitmux_assert_okay(); see the comment in that
  1592. * function.
  1593. */
  1594. static void
  1595. circuitmux_assert_okay_pass_three(circuitmux_t *cmux)
  1596. {
  1597. chanid_circid_muxinfo_t **i = NULL;
  1598. tor_assert(cmux);
  1599. tor_assert(cmux->chanid_circid_map);
  1600. /* Start iterating the hash table */
  1601. i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
  1602. /* Advance through each entry */
  1603. while (i) {
  1604. /* Assert that it isn't null */
  1605. tor_assert(*i);
  1606. /*
  1607. * Assert that this entry is not marked - i.e., that either we didn't
  1608. * think it should be active in pass one or we saw it in the active
  1609. * circuits linked list.
  1610. */
  1611. tor_assert(!((*i)->muxinfo.mark));
  1612. /* Advance to the next entry */
  1613. i = HT_NEXT(chanid_circid_muxinfo_map, cmux->chanid_circid_map, i);
  1614. }
  1615. }
  1616. /*DOCDOC */
  1617. void
  1618. circuitmux_append_destroy_cell(channel_t *chan,
  1619. circuitmux_t *cmux,
  1620. circid_t circ_id,
  1621. uint8_t reason)
  1622. {
  1623. cell_t cell;
  1624. memset(&cell, 0, sizeof(cell_t));
  1625. cell.circ_id = circ_id;
  1626. cell.command = CELL_DESTROY;
  1627. cell.payload[0] = (uint8_t) reason;
  1628. cell_queue_append_packed_copy(NULL, &cmux->destroy_cell_queue, 0, &cell,
  1629. chan->wide_circ_ids, 0);
  1630. /* Destroy entering the queue, update counters */
  1631. ++(cmux->destroy_ctr);
  1632. ++global_destroy_ctr;
  1633. log_debug(LD_CIRC,
  1634. "Cmux at %p queued a destroy for circ %u, cmux counter is now "
  1635. I64_FORMAT", global counter is now "I64_FORMAT,
  1636. cmux, circ_id,
  1637. I64_PRINTF_ARG(cmux->destroy_ctr),
  1638. I64_PRINTF_ARG(global_destroy_ctr));
  1639. /* XXXX Duplicate code from append_cell_to_circuit_queue */
  1640. if (!channel_has_queued_writes(chan)) {
  1641. /* There is no data at all waiting to be sent on the outbuf. Add a
  1642. * cell, so that we can notice when it gets flushed, flushed_some can
  1643. * get called, and we can start putting more data onto the buffer then.
  1644. */
  1645. log_debug(LD_GENERAL, "Primed a buffer.");
  1646. channel_flush_from_first_active_circuit(chan, 1);
  1647. }
  1648. }
  1649. /*DOCDOC; for debugging 12184. This runs slowly. */
  1650. int64_t
  1651. circuitmux_count_queued_destroy_cells(const channel_t *chan,
  1652. const circuitmux_t *cmux)
  1653. {
  1654. int64_t n_destroy_cells = cmux->destroy_ctr;
  1655. int64_t destroy_queue_size = cmux->destroy_cell_queue.n;
  1656. int64_t manual_total = 0;
  1657. int64_t manual_total_in_map = 0;
  1658. packed_cell_t *cell;
  1659. TOR_SIMPLEQ_FOREACH(cell, &cmux->destroy_cell_queue.head, next) {
  1660. circid_t id;
  1661. ++manual_total;
  1662. id = packed_cell_get_circid(cell, chan->wide_circ_ids);
  1663. if (circuit_id_in_use_on_channel(id, (channel_t*)chan))
  1664. ++manual_total_in_map;
  1665. }
  1666. if (n_destroy_cells != destroy_queue_size ||
  1667. n_destroy_cells != manual_total ||
  1668. n_destroy_cells != manual_total_in_map) {
  1669. log_warn(LD_BUG, " Discrepancy in counts for queued destroy cells on "
  1670. "circuitmux. n="I64_FORMAT". queue_size="I64_FORMAT". "
  1671. "manual_total="I64_FORMAT". manual_total_in_map="I64_FORMAT".",
  1672. I64_PRINTF_ARG(n_destroy_cells),
  1673. I64_PRINTF_ARG(destroy_queue_size),
  1674. I64_PRINTF_ARG(manual_total),
  1675. I64_PRINTF_ARG(manual_total_in_map));
  1676. }
  1677. return n_destroy_cells;
  1678. }
  1679. /**
  1680. * Compare cmuxes to see which is more preferred; return < 0 if
  1681. * cmux_1 has higher priority (i.e., cmux_1 < cmux_2 in the scheduler's
  1682. * sort order), > 0 if cmux_2 has higher priority, or 0 if they are
  1683. * equally preferred.
  1684. *
  1685. * If the cmuxes have different cmux policies or the policy does not
  1686. * support the cmp_cmux method, return 0.
  1687. */
  1688. MOCK_IMPL(int,
  1689. circuitmux_compare_muxes, (circuitmux_t *cmux_1, circuitmux_t *cmux_2))
  1690. {
  1691. const circuitmux_policy_t *policy;
  1692. tor_assert(cmux_1);
  1693. tor_assert(cmux_2);
  1694. if (cmux_1 == cmux_2) {
  1695. /* Equivalent because they're the same cmux */
  1696. return 0;
  1697. }
  1698. if (cmux_1->policy && cmux_2->policy) {
  1699. if (cmux_1->policy == cmux_2->policy) {
  1700. policy = cmux_1->policy;
  1701. if (policy->cmp_cmux) {
  1702. /* Okay, we can compare! */
  1703. return policy->cmp_cmux(cmux_1, cmux_1->policy_data,
  1704. cmux_2, cmux_2->policy_data);
  1705. } else {
  1706. /*
  1707. * Equivalent because the policy doesn't know how to compare between
  1708. * muxes.
  1709. */
  1710. return 0;
  1711. }
  1712. } else {
  1713. /* Equivalent because they have different policies */
  1714. return 0;
  1715. }
  1716. } else {
  1717. /* Equivalent because one or both are missing a policy */
  1718. return 0;
  1719. }
  1720. }