circuitmux.c 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634
  1. /* * Copyright (c) 2012, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file circuitmux.c
  5. * \brief Circuit mux/cell selection abstraction
  6. **/
  7. #include "or.h"
  8. #include "channel.h"
  9. #include "circuitlist.h"
  10. #include "circuitmux.h"
  11. /*
  12. * Private typedefs for circuitmux.c
  13. */
  14. /*
  15. * Map of muxinfos for circuitmux_t to use; struct is defined below (name
  16. * of struct must match HT_HEAD line).
  17. */
  18. typedef struct chanid_circid_muxinfo_map chanid_circid_muxinfo_map_t;
  19. /*
  20. * Hash table entry (yeah, calling it chanid_circid_muxinfo_s seems to
  21. * break the hash table code).
  22. */
  23. typedef struct chanid_circid_muxinfo_t chanid_circid_muxinfo_t;
  24. /*
  25. * Anything the mux wants to store per-circuit in the map; right now just
  26. * a count of queued cells.
  27. */
  28. typedef struct circuit_muxinfo_s circuit_muxinfo_t;
  29. /*
  30. * Structures for circuitmux.c
  31. */
  32. /*
  33. * A circuitmux is a collection of circuits; it tracks which subset
  34. * of the attached circuits are 'active' (i.e., have cells available
  35. * to transmit) and how many cells on each. It expoes three distinct
  36. * interfaces to other components:
  37. *
  38. * To channels, which each have a circuitmux_t, the supported operations
  39. * are:
  40. *
  41. * circuitmux_flush_cells():
  42. *
  43. * Retrieve a cell from one of the active circuits, chosen according to
  44. * the circuitmux_t's cell selection policy.
  45. *
  46. * circuitmux_unlink_all():
  47. *
  48. * The channel is closing down, all circuits must be detached.
  49. *
  50. * To circuits, the exposed operations are:
  51. *
  52. * TODO
  53. *
  54. * To circuit selection policies, the exposed operations are:
  55. *
  56. * TODO
  57. *
  58. * General status inquiries?
  59. *
  60. */
  61. struct circuitmux_s {
  62. /* Keep count of attached, active circuits */
  63. unsigned int n_circuits, n_active_circuits;
  64. /* Total number of queued cells on all circuits */
  65. unsigned int n_cells;
  66. /*
  67. * Map from (channel ID, circuit ID) pairs to circuit_muxinfo_t
  68. */
  69. chanid_circid_muxinfo_map_t *chanid_circid_map;
  70. /*
  71. * Double-linked ring of circuits with queued cells waiting for room to
  72. * free up on this connection's outbuf. Every time we pull cells from
  73. * a circuit, we advance this pointer to the next circuit in the ring.
  74. */
  75. struct circuit_t *active_circuits_head, *active_circuits_tail;
  76. /*
  77. * Circuitmux policy; if this is non-NULL, it can override the built-
  78. * in round-robin active circuits behavior. This is how EWMA works in
  79. * the new circuitmux_t world.
  80. */
  81. const circuitmux_policy_t *policy;
  82. /* Policy-specific data */
  83. circuitmux_policy_data_t *policy_data;
  84. };
  85. /*
  86. * This struct holds whatever we want to store per attached circuit on a
  87. * circuitmux_t; right now, just the count of queued cells and the direction.
  88. */
  89. struct circuit_muxinfo_s {
  90. /* Count of cells on this circuit at last update */
  91. unsigned int cell_count;
  92. /* Direction of flow */
  93. cell_direction_t direction;
  94. /* Policy-specific data */
  95. circuitmux_policy_circ_data_t *policy_data;
  96. /* Mark bit for consistency checker */
  97. unsigned int mark:1;
  98. };
  99. /*
  100. * A map from channel ID and circuit ID to a circuit_muxinfo_t for that
  101. * circuit.
  102. */
  103. struct chanid_circid_muxinfo_t {
  104. HT_ENTRY(chanid_circid_muxinfo_t) node;
  105. uint64_t chan_id;
  106. circid_t circ_id;
  107. circuit_muxinfo_t muxinfo;
  108. };
  109. /*
  110. * Static function declarations
  111. */
  112. static INLINE int
  113. chanid_circid_entries_eq(chanid_circid_muxinfo_t *a,
  114. chanid_circid_muxinfo_t *b);
  115. static INLINE unsigned int
  116. chanid_circid_entry_hash(chanid_circid_muxinfo_t *a);
  117. static chanid_circid_muxinfo_t *
  118. circuitmux_find_map_entry(circuitmux_t *cmux, circuit_t *circ);
  119. static void
  120. circuitmux_make_circuit_active(circuitmux_t *cmux, circuit_t *circ,
  121. cell_direction_t direction);
  122. static void
  123. circuitmux_make_circuit_inactive(circuitmux_t *cmux, circuit_t *circ,
  124. cell_direction_t direction);
  125. static INLINE void
  126. circuitmux_move_active_circ_to_tail(circuitmux_t *cmux, circuit_t *circ,
  127. cell_direction_t direction);
  128. static INLINE circuit_t **
  129. circuitmux_next_active_circ_p(circuitmux_t *cmux, circuit_t *circ);
  130. static INLINE circuit_t **
  131. circuitmux_prev_active_circ_p(circuitmux_t *cmux, circuit_t *circ);
  132. static void circuitmux_assert_okay_pass_one(circuitmux_t *cmux);
  133. static void circuitmux_assert_okay_pass_two(circuitmux_t *cmux);
  134. static void circuitmux_assert_okay_pass_three(circuitmux_t *cmux);
  135. /* Function definitions */
  136. /**
  137. * Linked list helpers
  138. */
  139. /**
  140. * Move an active circuit to the tail of the cmux's active circuits list;
  141. * used by circuitmux_notify_xmit_cells().
  142. */
  143. static INLINE void
  144. circuitmux_move_active_circ_to_tail(circuitmux_t *cmux, circuit_t *circ,
  145. cell_direction_t direction)
  146. {
  147. circuit_t **next_p = NULL, **prev_p = NULL;
  148. circuit_t **next_prev = NULL, **prev_next = NULL;
  149. or_circuit_t *or_circ = NULL;
  150. tor_assert(cmux);
  151. tor_assert(circ);
  152. /* Figure out our next_p and prev_p for this cmux/direction */
  153. if (direction) {
  154. if (direction == CELL_DIRECTION_OUT) {
  155. tor_assert(circ->n_mux == cmux);
  156. next_p = &(circ->next_active_on_n_chan);
  157. prev_p = &(circ->prev_active_on_n_chan);
  158. } else {
  159. or_circ = TO_OR_CIRCUIT(circ);
  160. tor_assert(or_circ->p_mux == cmux);
  161. next_p = &(or_circ->next_active_on_p_chan);
  162. prev_p = &(or_circ->prev_active_on_p_chan);
  163. }
  164. } else {
  165. if (circ->n_mux == cmux) {
  166. next_p = &(circ->next_active_on_n_chan);
  167. prev_p = &(circ->prev_active_on_n_chan);
  168. direction = CELL_DIRECTION_OUT;
  169. } else {
  170. or_circ = TO_OR_CIRCUIT(circ);
  171. tor_assert(or_circ->p_mux == cmux);
  172. next_p = &(or_circ->next_active_on_p_chan);
  173. prev_p = &(or_circ->prev_active_on_p_chan);
  174. direction = CELL_DIRECTION_IN;
  175. }
  176. }
  177. tor_assert(next_p);
  178. tor_assert(prev_p);
  179. /* Check if this really is an active circuit */
  180. if ((*next_p == NULL && *prev_p == NULL) &&
  181. !(circ == cmux->active_circuits_head ||
  182. circ == cmux->active_circuits_tail)) {
  183. /* Not active, no-op */
  184. return;
  185. }
  186. /* Check if this is already the tail */
  187. if (circ == cmux->active_circuits_tail) return;
  188. /* Okay, we have to move it; figure out next_prev and prev_next */
  189. if (*next_p) next_prev = circuitmux_prev_active_circ_p(cmux, *next_p);
  190. if (*prev_p) prev_next = circuitmux_next_active_circ_p(cmux, *prev_p);
  191. /* Adjust the previous node's next pointer, if any */
  192. if (prev_next) *prev_next = *next_p;
  193. /* Otherwise, we were the head */
  194. else cmux->active_circuits_head = *next_p;
  195. /* Adjust the next node's previous pointer, if any */
  196. if (next_prev) *next_prev = *prev_p;
  197. /* Adjust our next and prev pointers */
  198. *next_p = NULL;
  199. *prev_p = cmux->active_circuits_tail;
  200. /* Set the tail to this circuit */
  201. cmux->active_circuits_tail = circ;
  202. }
  203. static INLINE circuit_t **
  204. circuitmux_next_active_circ_p(circuitmux_t *cmux, circuit_t *circ)
  205. {
  206. tor_assert(cmux);
  207. tor_assert(circ);
  208. if (circ->n_mux == cmux) return &(circ->next_active_on_n_chan);
  209. else {
  210. tor_assert(TO_OR_CIRCUIT(circ)->p_mux == cmux);
  211. return &(TO_OR_CIRCUIT(circ)->next_active_on_p_chan);
  212. }
  213. }
  214. static INLINE circuit_t **
  215. circuitmux_prev_active_circ_p(circuitmux_t *cmux, circuit_t *circ)
  216. {
  217. tor_assert(cmux);
  218. tor_assert(circ);
  219. if (circ->n_mux == cmux) return &(circ->prev_active_on_n_chan);
  220. else {
  221. tor_assert(TO_OR_CIRCUIT(circ)->p_mux == cmux);
  222. return &(TO_OR_CIRCUIT(circ)->prev_active_on_p_chan);
  223. }
  224. }
  225. /**
  226. * Helper for chanid_circid_cell_count_map_t hash table: compare the channel
  227. * ID and circuit ID for a and b, and return less than, equal to, or greater
  228. * than zero appropriately.
  229. */
  230. static INLINE int
  231. chanid_circid_entries_eq(chanid_circid_muxinfo_t *a,
  232. chanid_circid_muxinfo_t *b)
  233. {
  234. return a->chan_id == b->chan_id && a->circ_id == b->circ_id;
  235. }
  236. /**
  237. * Helper: return a hash based on circuit ID and channel ID in a.
  238. */
  239. static INLINE unsigned int
  240. chanid_circid_entry_hash(chanid_circid_muxinfo_t *a)
  241. {
  242. return (((unsigned int)(a->circ_id) << 8) ^
  243. ((unsigned int)((a->chan_id >> 32) & 0xffffffff)) ^
  244. ((unsigned int)(a->chan_id & 0xffffffff)));
  245. }
  246. /* Declare the struct chanid_circid_muxinfo_map type */
  247. HT_HEAD(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t);
  248. /* Emit a bunch of hash table stuff */
  249. HT_PROTOTYPE(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node,
  250. chanid_circid_entry_hash, chanid_circid_entries_eq);
  251. HT_GENERATE(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node,
  252. chanid_circid_entry_hash, chanid_circid_entries_eq, 0.6,
  253. malloc, realloc, free);
  254. /*
  255. * Circuitmux alloc/free functions
  256. */
  257. /**
  258. * Allocate a new circuitmux_t
  259. */
  260. circuitmux_t *
  261. circuitmux_alloc(void)
  262. {
  263. circuitmux_t *rv = NULL;
  264. rv = tor_malloc_zero(sizeof(*rv));
  265. rv->chanid_circid_map = tor_malloc_zero(sizeof(*( rv->chanid_circid_map)));
  266. HT_INIT(chanid_circid_muxinfo_map, rv->chanid_circid_map);
  267. return rv;
  268. }
  269. /**
  270. * Detach all circuits from a circuitmux (use before circuitmux_free())
  271. */
  272. void
  273. circuitmux_detach_all_circuits(circuitmux_t *cmux)
  274. {
  275. chanid_circid_muxinfo_t **i = NULL, *to_remove;
  276. channel_t *chan = NULL;
  277. circuit_t *circ = NULL;
  278. tor_assert(cmux);
  279. i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
  280. while (i) {
  281. to_remove = *i;
  282. i = HT_NEXT_RMV(chanid_circid_muxinfo_map, cmux->chanid_circid_map, i);
  283. if (to_remove) {
  284. /* Find a channel and circuit */
  285. chan = channel_find_by_global_id(to_remove->chan_id);
  286. if (chan) {
  287. circ = circuit_get_by_circid_channel(to_remove->circ_id, chan);
  288. if (circ) {
  289. /* Clear the circuit's mux for this direction */
  290. if (to_remove->muxinfo.direction == CELL_DIRECTION_OUT) {
  291. /* Clear n_mux */
  292. circ->n_mux = NULL;
  293. /*
  294. * Update active_circuits et al.; this does policy notifies, so
  295. * comes before freeing policy data
  296. */
  297. circuitmux_make_circuit_inactive(cmux, circ, CELL_DIRECTION_OUT);
  298. } else if (circ->magic == OR_CIRCUIT_MAGIC) {
  299. /*
  300. * It has a sensible p_chan and direction == CELL_DIRECTION_IN,
  301. * so clear p_mux.
  302. */
  303. TO_OR_CIRCUIT(circ)->p_mux = NULL;
  304. /*
  305. * Update active_circuits et al.; this does policy notifies, so
  306. * comes before freeing policy data
  307. */
  308. circuitmux_make_circuit_inactive(cmux, circ, CELL_DIRECTION_IN);
  309. } else {
  310. /* Complain and move on */
  311. log_warn(LD_CIRC,
  312. "Circuit %d/channel " U64_FORMAT " had direction == "
  313. "CELL_DIRECTION_IN, but isn't an or_circuit_t",
  314. to_remove->circ_id,
  315. U64_PRINTF_ARG(to_remove->chan_id));
  316. }
  317. /* Free policy-specific data if we have it */
  318. if (to_remove->muxinfo.policy_data) {
  319. /*
  320. * If we have policy data, assert that we have the means to
  321. * free it
  322. */
  323. tor_assert(cmux->policy);
  324. tor_assert(cmux->policy->free_circ_data);
  325. /* Call free_circ_data() */
  326. cmux->policy->free_circ_data(cmux,
  327. cmux->policy_data,
  328. circ,
  329. to_remove->muxinfo.policy_data);
  330. to_remove->muxinfo.policy_data = NULL;
  331. }
  332. } else {
  333. /* Complain and move on */
  334. log_warn(LD_CIRC,
  335. "Couldn't find circuit %d (for channel " U64_FORMAT ")",
  336. to_remove->circ_id,
  337. U64_PRINTF_ARG(to_remove->chan_id));
  338. }
  339. } else {
  340. /* Complain and move on */
  341. log_warn(LD_CIRC,
  342. "Couldn't find channel " U64_FORMAT " (for circuit id %d)",
  343. U64_PRINTF_ARG(to_remove->chan_id),
  344. to_remove->circ_id);
  345. }
  346. /* Assert that we don't have un-freed policy data for this circuit */
  347. tor_assert(to_remove->muxinfo.policy_data == NULL);
  348. /* Free it */
  349. tor_free(to_remove);
  350. }
  351. }
  352. cmux->n_circuits = 0;
  353. cmux->n_active_circuits = 0;
  354. cmux->n_cells = 0;
  355. }
  356. /**
  357. * Free a circuitmux_t; the circuits must be detached first with
  358. * circuitmux_detach_all_circuits().
  359. */
  360. void
  361. circuitmux_free(circuitmux_t *cmux)
  362. {
  363. if (!cmux) return;
  364. tor_assert(cmux->n_circuits == 0);
  365. tor_assert(cmux->n_active_circuits == 0);
  366. /*
  367. * Free policy-specific data if we have any; we don't
  368. * need to do circuitmux_set_policy(cmux, NULL) to cover
  369. * the circuits because they would have been handled in
  370. * circuitmux_detach_all_circuits() before this was
  371. * called.
  372. */
  373. if (cmux->policy && cmux->policy->free_cmux_data) {
  374. if (cmux->policy_data) {
  375. cmux->policy->free_cmux_data(cmux, cmux->policy_data);
  376. cmux->policy_data = NULL;
  377. }
  378. } else tor_assert(cmux->policy_data == NULL);
  379. if (cmux->chanid_circid_map) {
  380. HT_CLEAR(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
  381. tor_free(cmux->chanid_circid_map);
  382. }
  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. if (cmux->policy) {
  399. circuitmux_set_policy(cmux, NULL);
  400. }
  401. }
  402. /**
  403. * Return the policy currently installed on a circuitmux_t
  404. */
  405. const circuitmux_policy_t *
  406. circuitmux_get_policy(circuitmux_t *cmux)
  407. {
  408. tor_assert(cmux);
  409. return cmux->policy;
  410. }
  411. /**
  412. * Set policy; allocate for new policy, detach all circuits from old policy
  413. * if any, attach them to new policy, and free old policy data.
  414. */
  415. void
  416. circuitmux_set_policy(circuitmux_t *cmux,
  417. const circuitmux_policy_t *pol)
  418. {
  419. const circuitmux_policy_t *old_pol = NULL, *new_pol = NULL;
  420. circuitmux_policy_data_t *old_pol_data = NULL, *new_pol_data = NULL;
  421. chanid_circid_muxinfo_t **i = NULL;
  422. channel_t *chan = NULL;
  423. uint64_t last_chan_id_searched = 0;
  424. circuit_t *circ = NULL;
  425. tor_assert(cmux);
  426. /* Set up variables */
  427. old_pol = cmux->policy;
  428. old_pol_data = cmux->policy_data;
  429. new_pol = pol;
  430. /* Check if this is the trivial case */
  431. if (old_pol == new_pol) return;
  432. /* Allocate data for new policy, if any */
  433. if (new_pol && new_pol->alloc_cmux_data) {
  434. /*
  435. * If alloc_cmux_data is not null, then we expect to get some policy
  436. * data. Assert that we also have free_cmux_data so we can free it
  437. * when the time comes, and allocate it.
  438. */
  439. tor_assert(new_pol->free_cmux_data);
  440. new_pol_data = new_pol->alloc_cmux_data(cmux);
  441. tor_assert(new_pol_data);
  442. }
  443. /* Install new policy and new policy data on cmux */
  444. cmux->policy = new_pol;
  445. cmux->policy_data = new_pol_data;
  446. /* Iterate over all circuits, attaching/detaching each one */
  447. i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
  448. while (i) {
  449. /* Assert that this entry isn't NULL */
  450. tor_assert(*i);
  451. /*
  452. * Get the channel; since normal case is all circuits on the mux share a
  453. * channel, we cache last_chan_id_searched
  454. */
  455. if (!chan || last_chan_id_searched != (*i)->chan_id) {
  456. chan = channel_find_by_global_id((*i)->chan_id);
  457. last_chan_id_searched = (*i)->chan_id;
  458. }
  459. tor_assert(chan);
  460. /* Get the circuit */
  461. circ = circuit_get_by_circid_channel((*i)->circ_id, chan);
  462. tor_assert(circ);
  463. /* Need to tell old policy it becomes inactive (i.e., it is active) ? */
  464. if (old_pol && old_pol->notify_circ_inactive &&
  465. (*i)->muxinfo.cell_count > 0) {
  466. old_pol->notify_circ_inactive(cmux, old_pol_data, circ,
  467. (*i)->muxinfo.policy_data);
  468. }
  469. /* Need to free old policy data? */
  470. if ((*i)->muxinfo.policy_data) {
  471. /* Assert that we have the means to free it if we have policy data */
  472. tor_assert(old_pol);
  473. tor_assert(old_pol->free_circ_data);
  474. /* Free it */
  475. old_pol->free_circ_data(cmux, old_pol_data, circ,
  476. (*i)->muxinfo.policy_data);
  477. (*i)->muxinfo.policy_data = NULL;
  478. }
  479. /* Need to allocate new policy data? */
  480. if (new_pol && new_pol->alloc_circ_data) {
  481. /*
  482. * If alloc_circ_data is not null, we expect to get some per-circuit
  483. * policy data. Assert that we also have free_circ_data so we can
  484. * free it when the time comes, and allocate it.
  485. */
  486. tor_assert(new_pol->free_circ_data);
  487. (*i)->muxinfo.policy_data =
  488. new_pol->alloc_circ_data(cmux, new_pol_data, circ,
  489. (*i)->muxinfo.direction,
  490. (*i)->muxinfo.cell_count);
  491. }
  492. /* Need to make active on new policy? */
  493. if (new_pol && new_pol->notify_circ_active &&
  494. (*i)->muxinfo.cell_count > 0) {
  495. new_pol->notify_circ_active(cmux, new_pol_data, circ,
  496. (*i)->muxinfo.policy_data);
  497. }
  498. /* Advance to next circuit map entry */
  499. i = HT_NEXT(chanid_circid_muxinfo_map, cmux->chanid_circid_map, i);
  500. }
  501. /* Free data for old policy, if any */
  502. if (old_pol_data) {
  503. /*
  504. * If we had old policy data, we should have an old policy and a free
  505. * function for it.
  506. */
  507. tor_assert(old_pol);
  508. tor_assert(old_pol->free_cmux_data);
  509. old_pol->free_cmux_data(cmux, old_pol_data);
  510. old_pol_data = NULL;
  511. }
  512. }
  513. /*
  514. * Circuitmux/circuit attachment status inquiry functions
  515. */
  516. /**
  517. * Query the direction of an attached circuit
  518. */
  519. cell_direction_t
  520. circuitmux_attached_circuit_direction(circuitmux_t *cmux, circuit_t *circ)
  521. {
  522. chanid_circid_muxinfo_t *hashent = NULL;
  523. /* Try to find a map entry */
  524. hashent = circuitmux_find_map_entry(cmux, circ);
  525. /*
  526. * This function should only be called on attached circuits; assert that
  527. * we had a map entry.
  528. */
  529. tor_assert(hashent);
  530. /* Return the direction from the map entry */
  531. return hashent->muxinfo.direction;
  532. }
  533. /**
  534. * Find an entry in the cmux's map for this circuit or return NULL if there
  535. * is none.
  536. */
  537. static chanid_circid_muxinfo_t *
  538. circuitmux_find_map_entry(circuitmux_t *cmux, circuit_t *circ)
  539. {
  540. chanid_circid_muxinfo_t search, *hashent = NULL;
  541. /* Sanity-check parameters */
  542. tor_assert(cmux);
  543. tor_assert(cmux->chanid_circid_map);
  544. tor_assert(circ);
  545. tor_assert(circ->n_chan);
  546. /* Okay, let's see if it's attached for n_chan/n_circ_id */
  547. search.chan_id = circ->n_chan->global_identifier;
  548. search.circ_id = circ->n_circ_id;
  549. /* Query */
  550. hashent = HT_FIND(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
  551. &search);
  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. unsigned int
  633. circuitmux_num_cells(circuitmux_t *cmux)
  634. {
  635. tor_assert(cmux);
  636. return cmux->n_cells;
  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. 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. 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, direction);
  727. } else if (hashent->muxinfo.cell_count == 0 && cell_count > 0) {
  728. ++(cmux->n_active_circuits);
  729. circuitmux_make_circuit_active(cmux, circ, direction);
  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. 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 && 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. /* Make sure the next/prev pointers are NULL */
  774. if (direction == CELL_DIRECTION_OUT) {
  775. circ->next_active_on_n_chan = NULL;
  776. circ->prev_active_on_n_chan = NULL;
  777. } else {
  778. TO_OR_CIRCUIT(circ)->next_active_on_p_chan = NULL;
  779. TO_OR_CIRCUIT(circ)->prev_active_on_p_chan = NULL;
  780. }
  781. /* Update counters */
  782. ++(cmux->n_circuits);
  783. if (cell_count > 0) {
  784. ++(cmux->n_active_circuits);
  785. circuitmux_make_circuit_active(cmux, circ, direction);
  786. }
  787. cmux->n_cells += cell_count;
  788. }
  789. }
  790. /**
  791. * Detach a circuit from a circuitmux and update all counters as needed;
  792. * no-op if not attached.
  793. */
  794. void
  795. circuitmux_detach_circuit(circuitmux_t *cmux, circuit_t *circ)
  796. {
  797. chanid_circid_muxinfo_t search, *hashent = NULL;
  798. /*
  799. * Use this to keep track of whether we found it for n_chan or
  800. * p_chan for consistency checking.
  801. */
  802. cell_direction_t last_searched_direction;
  803. tor_assert(cmux);
  804. tor_assert(cmux->chanid_circid_map);
  805. tor_assert(circ);
  806. tor_assert(circ->n_chan);
  807. /* See if we have it for n_chan/n_circ_id */
  808. search.chan_id = circ->n_chan->global_identifier;
  809. search.circ_id = circ->n_circ_id;
  810. hashent = HT_REMOVE(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
  811. &search);
  812. last_searched_direction = CELL_DIRECTION_OUT;
  813. /* Got one? If not, see if it's an or_circuit_t and try p_chan/p_circ_id */
  814. if (!hashent) {
  815. if (circ->magic == OR_CIRCUIT_MAGIC) {
  816. search.circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
  817. if (TO_OR_CIRCUIT(circ)->p_chan) {
  818. search.chan_id = TO_OR_CIRCUIT(circ)->p_chan->global_identifier;
  819. hashent = HT_REMOVE(chanid_circid_muxinfo_map,
  820. cmux->chanid_circid_map,
  821. &search);
  822. last_searched_direction = CELL_DIRECTION_IN;
  823. }
  824. }
  825. }
  826. /* If hashent isn't NULL, we just removed it from the map */
  827. if (hashent) {
  828. /* Update counters */
  829. --(cmux->n_circuits);
  830. if (hashent->muxinfo.cell_count > 0) {
  831. --(cmux->n_active_circuits);
  832. /* This does policy notifies, so comes before freeing policy data */
  833. circuitmux_make_circuit_inactive(cmux, circ, last_searched_direction);
  834. }
  835. cmux->n_cells -= hashent->muxinfo.cell_count;
  836. /* Free policy-specific data if we have it */
  837. if (hashent->muxinfo.policy_data) {
  838. /* If we have policy data, assert that we have the means to free it */
  839. tor_assert(cmux->policy);
  840. tor_assert(cmux->policy->free_circ_data);
  841. /* Call free_circ_data() */
  842. cmux->policy->free_circ_data(cmux,
  843. cmux->policy_data,
  844. circ,
  845. hashent->muxinfo.policy_data);
  846. hashent->muxinfo.policy_data = NULL;
  847. }
  848. /* Consistency check: the direction must match the direction searched */
  849. tor_assert(last_searched_direction == hashent->muxinfo.direction);
  850. /* Clear the circuit's mux for this direction */
  851. if (last_searched_direction == CELL_DIRECTION_OUT) circ->n_mux = NULL;
  852. else TO_OR_CIRCUIT(circ)->p_mux = NULL;
  853. /* Free the hash entry */
  854. tor_free(hashent);
  855. }
  856. }
  857. /**
  858. * Make a circuit active; update active list and policy-specific info, but
  859. * we don't mess with the counters or hash table here.
  860. */
  861. static void
  862. circuitmux_make_circuit_active(circuitmux_t *cmux, circuit_t *circ,
  863. cell_direction_t direction)
  864. {
  865. circuit_t **next_active = NULL, **prev_active = NULL, **next_prev = NULL;
  866. circuitmux_t *circuit_cmux = NULL;
  867. chanid_circid_muxinfo_t *hashent = NULL;
  868. channel_t *chan = NULL;
  869. circid_t circ_id;
  870. int already_active;
  871. tor_assert(cmux);
  872. tor_assert(circ);
  873. tor_assert(direction == CELL_DIRECTION_OUT ||
  874. direction == CELL_DIRECTION_IN);
  875. /* Get the right set of active list links for this direction */
  876. if (direction == CELL_DIRECTION_OUT) {
  877. next_active = &(circ->next_active_on_n_chan);
  878. prev_active = &(circ->prev_active_on_n_chan);
  879. circuit_cmux = circ->n_mux;
  880. chan = circ->n_chan;
  881. circ_id = circ->n_circ_id;
  882. } else {
  883. next_active = &(TO_OR_CIRCUIT(circ)->next_active_on_p_chan);
  884. prev_active = &(TO_OR_CIRCUIT(circ)->prev_active_on_p_chan);
  885. circuit_cmux = TO_OR_CIRCUIT(circ)->p_mux;
  886. chan = TO_OR_CIRCUIT(circ)->p_chan;
  887. circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
  888. }
  889. /* Assert that it is attached to this mux and a channel */
  890. tor_assert(cmux == circuit_cmux);
  891. tor_assert(chan != NULL);
  892. /*
  893. * Check if the circuit really was inactive; if it's active, at least one
  894. * of the next_active and prev_active pointers will not be NULL, or this
  895. * circuit will be either the head or tail of the list for this cmux.
  896. */
  897. already_active = (*prev_active != NULL || *next_active != NULL ||
  898. cmux->active_circuits_head == circ ||
  899. cmux->active_circuits_tail == circ);
  900. /* If we're already active, log a warning and finish */
  901. if (already_active) {
  902. log_warn(LD_CIRC,
  903. "Circuit %d on channel " U64_FORMAT " was already active",
  904. circ_id, U64_PRINTF_ARG(chan->global_identifier));
  905. return;
  906. }
  907. /*
  908. * This is going at the head of the list; if the old head is not NULL,
  909. * then its prev pointer should point to this.
  910. */
  911. *next_active = cmux->active_circuits_head; /* Next is old head */
  912. *prev_active = NULL; /* Prev is NULL (this will be the head) */
  913. if (cmux->active_circuits_head) {
  914. /* The list had an old head; update its prev pointer */
  915. next_prev =
  916. circuitmux_prev_active_circ_p(cmux, cmux->active_circuits_head);
  917. tor_assert(next_prev);
  918. *next_prev = circ;
  919. } else {
  920. /* The list was empty; this becomes the tail as well */
  921. cmux->active_circuits_tail = circ;
  922. }
  923. /* This becomes the new head of the list */
  924. cmux->active_circuits_head = circ;
  925. /* Policy-specific notification */
  926. if (cmux->policy &&
  927. cmux->policy->notify_circ_active) {
  928. /* Okay, we need to check the circuit for policy data now */
  929. hashent = circuitmux_find_map_entry(cmux, circ);
  930. /* We should have found something */
  931. tor_assert(hashent);
  932. /* Notify */
  933. cmux->policy->notify_circ_active(cmux, cmux->policy_data,
  934. circ, hashent->muxinfo.policy_data);
  935. }
  936. }
  937. /**
  938. * Make a circuit inactive; update active list and policy-specific info, but
  939. * we don't mess with the counters or hash table here.
  940. */
  941. static void
  942. circuitmux_make_circuit_inactive(circuitmux_t *cmux, circuit_t *circ,
  943. cell_direction_t direction)
  944. {
  945. circuit_t **next_active = NULL, **prev_active = NULL;
  946. circuit_t **next_prev = NULL, **prev_next = NULL;
  947. circuitmux_t *circuit_cmux = NULL;
  948. chanid_circid_muxinfo_t *hashent = NULL;
  949. channel_t *chan = NULL;
  950. circid_t circ_id;
  951. int already_inactive;
  952. tor_assert(cmux);
  953. tor_assert(circ);
  954. tor_assert(direction == CELL_DIRECTION_OUT ||
  955. direction == CELL_DIRECTION_IN);
  956. /* Get the right set of active list links for this direction */
  957. if (direction == CELL_DIRECTION_OUT) {
  958. next_active = &(circ->next_active_on_n_chan);
  959. prev_active = &(circ->prev_active_on_n_chan);
  960. circuit_cmux = circ->n_mux;
  961. chan = circ->n_chan;
  962. circ_id = circ->n_circ_id;
  963. } else {
  964. next_active = &(TO_OR_CIRCUIT(circ)->next_active_on_p_chan);
  965. prev_active = &(TO_OR_CIRCUIT(circ)->prev_active_on_p_chan);
  966. circuit_cmux = TO_OR_CIRCUIT(circ)->p_mux;
  967. chan = TO_OR_CIRCUIT(circ)->p_chan;
  968. circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
  969. }
  970. /* Assert that it is attached to this mux and a channel */
  971. tor_assert(cmux == circuit_cmux);
  972. tor_assert(chan != NULL);
  973. /*
  974. * Check if the circuit really was active; if it's inactive, the
  975. * next_active and prev_active pointers will be NULL and this circuit
  976. * will not be the head or tail of the list for this cmux.
  977. */
  978. already_inactive = (*prev_active == NULL && *next_active == NULL &&
  979. cmux->active_circuits_head != circ &&
  980. cmux->active_circuits_tail != circ);
  981. /* If we're already inactive, log a warning and finish */
  982. if (already_inactive) {
  983. log_warn(LD_CIRC,
  984. "Circuit %d on channel " U64_FORMAT " was already inactive",
  985. circ_id, U64_PRINTF_ARG(chan->global_identifier));
  986. return;
  987. }
  988. /* Remove from the list; first get next_prev and prev_next */
  989. if (*next_active) {
  990. /*
  991. * If there's a next circuit, its previous circuit becomes this
  992. * circuit's previous circuit.
  993. */
  994. next_prev = circuitmux_prev_active_circ_p(cmux, *next_active);
  995. } else {
  996. /* Else, the tail becomes this circuit's previous circuit */
  997. next_prev = &(cmux->active_circuits_tail);
  998. }
  999. /* Got next_prev, now prev_next */
  1000. if (*prev_active) {
  1001. /*
  1002. * If there's a previous circuit, its next circuit becomes this circuit's
  1003. * next circuit.
  1004. */
  1005. prev_next = circuitmux_next_active_circ_p(cmux, *prev_active);
  1006. } else {
  1007. /* Else, the head becomes this circuit's next circuit */
  1008. prev_next = &(cmux->active_circuits_head);
  1009. }
  1010. /* Assert that we got sensible values for the next/prev pointers */
  1011. tor_assert(next_prev != NULL);
  1012. tor_assert(prev_next != NULL);
  1013. /* Update the next/prev pointers - this removes circ from the list */
  1014. *next_prev = *prev_active;
  1015. *prev_next = *next_active;
  1016. /* Now null out prev_active/next_active */
  1017. *prev_active = NULL;
  1018. *next_active = NULL;
  1019. /* Policy-specific notification */
  1020. if (cmux->policy &&
  1021. cmux->policy->notify_circ_inactive) {
  1022. /* Okay, we need to check the circuit for policy data now */
  1023. hashent = circuitmux_find_map_entry(cmux, circ);
  1024. /* We should have found something */
  1025. tor_assert(hashent);
  1026. /* Notify */
  1027. cmux->policy->notify_circ_inactive(cmux, cmux->policy_data,
  1028. circ, hashent->muxinfo.policy_data);
  1029. }
  1030. }
  1031. /**
  1032. * Clear the cell counter for a circuit on a circuitmux
  1033. */
  1034. void
  1035. circuitmux_clear_num_cells(circuitmux_t *cmux, circuit_t *circ)
  1036. {
  1037. /* This is the same as setting the cell count to zero */
  1038. circuitmux_set_num_cells(cmux, circ, 0);
  1039. }
  1040. /**
  1041. * Set the cell counter for a circuit on a circuitmux
  1042. */
  1043. void
  1044. circuitmux_set_num_cells(circuitmux_t *cmux, circuit_t *circ,
  1045. unsigned int n_cells)
  1046. {
  1047. chanid_circid_muxinfo_t *hashent = NULL;
  1048. tor_assert(cmux);
  1049. tor_assert(circ);
  1050. /* Search for this circuit's entry */
  1051. hashent = circuitmux_find_map_entry(cmux, circ);
  1052. /* Assert that we found one */
  1053. tor_assert(hashent);
  1054. /* Update cmux cell counter */
  1055. cmux->n_cells -= hashent->muxinfo.cell_count;
  1056. cmux->n_cells += n_cells;
  1057. /* Do we need to notify a cmux policy? */
  1058. if (cmux->policy && cmux->policy->notify_set_n_cells) {
  1059. /* Call notify_set_n_cells */
  1060. cmux->policy->notify_set_n_cells(cmux,
  1061. cmux->policy_data,
  1062. circ,
  1063. hashent->muxinfo.policy_data,
  1064. n_cells);
  1065. }
  1066. /*
  1067. * Update cmux active circuit counter: is the old cell count > 0 and the
  1068. * new cell count == 0 ?
  1069. */
  1070. if (hashent->muxinfo.cell_count > 0 && n_cells == 0) {
  1071. --(cmux->n_active_circuits);
  1072. circuitmux_make_circuit_inactive(cmux, circ, hashent->muxinfo.direction);
  1073. /* Is the old cell count == 0 and the new cell count > 0 ? */
  1074. } else if (hashent->muxinfo.cell_count == 0 && n_cells > 0) {
  1075. ++(cmux->n_active_circuits);
  1076. circuitmux_make_circuit_active(cmux, circ, hashent->muxinfo.direction);
  1077. }
  1078. /* Update hash entry cell counter */
  1079. hashent->muxinfo.cell_count = n_cells;
  1080. }
  1081. /*
  1082. * Functions for channel code to call to get a circuit to transmit from or
  1083. * notify that cells have been transmitted.
  1084. */
  1085. /**
  1086. * Pick a circuit to send from, using the active circuits list or a
  1087. * circuitmux policy if one is available. This is called from channel.c.
  1088. */
  1089. circuit_t *
  1090. circuitmux_get_first_active_circuit(circuitmux_t *cmux)
  1091. {
  1092. circuit_t *circ = NULL;
  1093. tor_assert(cmux);
  1094. if (cmux->n_active_circuits > 0) {
  1095. /* We also must have a cell available for this to be the case */
  1096. tor_assert(cmux->n_cells > 0);
  1097. /* Do we have a policy-provided circuit selector? */
  1098. if (cmux->policy && cmux->policy->pick_active_circuit) {
  1099. circ = cmux->policy->pick_active_circuit(cmux, cmux->policy_data);
  1100. }
  1101. /* Fall back on the head of the active circuits list */
  1102. if (!circ) {
  1103. tor_assert(cmux->active_circuits_head);
  1104. circ = cmux->active_circuits_head;
  1105. }
  1106. } else tor_assert(cmux->n_cells == 0);
  1107. return circ;
  1108. }
  1109. /**
  1110. * Notify the circuitmux that cells have been sent on a circuit; this
  1111. * is called from channel.c.
  1112. */
  1113. void
  1114. circuitmux_notify_xmit_cells(circuitmux_t *cmux, circuit_t *circ,
  1115. unsigned int n_cells)
  1116. {
  1117. chanid_circid_muxinfo_t *hashent = NULL;
  1118. int becomes_inactive = 0;
  1119. tor_assert(cmux);
  1120. tor_assert(circ);
  1121. if (n_cells == 0) return;
  1122. /*
  1123. * To handle this, we have to:
  1124. *
  1125. * 1.) Adjust the circuit's cell counter in the cmux hash table
  1126. * 2.) Move the circuit to the tail of the active_circuits linked list
  1127. * for this cmux, or make the circuit inactive if the cell count
  1128. * went to zero.
  1129. * 3.) Call cmux->policy->notify_xmit_cells(), if any
  1130. */
  1131. /* Find the hash entry */
  1132. hashent = circuitmux_find_map_entry(cmux, circ);
  1133. /* Assert that we found one */
  1134. tor_assert(hashent);
  1135. /* Adjust the cell counter and assert that we had that many cells to send */
  1136. tor_assert(n_cells <= hashent->muxinfo.cell_count);
  1137. hashent->muxinfo.cell_count -= n_cells;
  1138. /* Do we need to make the circuit inactive? */
  1139. if (hashent->muxinfo.cell_count == 0) becomes_inactive = 1;
  1140. /* If we aren't making it inactive later, move it to the tail of the list */
  1141. if (!becomes_inactive) {
  1142. circuitmux_move_active_circ_to_tail(cmux, circ,
  1143. hashent->muxinfo.direction);
  1144. }
  1145. /*
  1146. * We call notify_xmit_cells() before making the circuit inactive if needed,
  1147. * so the policy can always count on this coming in on an active circuit.
  1148. */
  1149. if (cmux->policy && cmux->policy->notify_xmit_cells) {
  1150. cmux->policy->notify_xmit_cells(cmux, cmux->policy_data, circ,
  1151. hashent->muxinfo.policy_data,
  1152. n_cells);
  1153. }
  1154. /*
  1155. * Now make the circuit inactive if needed; this will call the policy's
  1156. * notify_circ_inactive() if present.
  1157. */
  1158. if (becomes_inactive) {
  1159. --(cmux->n_active_circuits);
  1160. circuitmux_make_circuit_inactive(cmux, circ, hashent->muxinfo.direction);
  1161. }
  1162. }
  1163. /*
  1164. * Circuitmux consistency checking assertions
  1165. */
  1166. /**
  1167. * Check that circuitmux data structures are consistent and fail with an
  1168. * assert if not.
  1169. */
  1170. void
  1171. circuitmux_assert_okay(circuitmux_t *cmux)
  1172. {
  1173. tor_assert(cmux);
  1174. /*
  1175. * Pass 1: iterate the hash table; for each entry:
  1176. * a) Check that the circuit has this cmux for n_mux or p_mux
  1177. * b) If the cell_count is > 0, set the mark bit; otherwise clear it
  1178. * c) Also check activeness (cell_count > 0 should be active)
  1179. * d) Count the number of circuits, active circuits and queued cells
  1180. * and at the end check that they match the counters in the cmux.
  1181. *
  1182. * Pass 2: iterate the active circuits list; for each entry,
  1183. * make sure the circuit is attached to this mux and appears
  1184. * in the hash table. Make sure the mark bit is 1, and clear
  1185. * it in the hash table entry. Consistency-check the linked
  1186. * list pointers.
  1187. *
  1188. * Pass 3: iterate the hash table again; assert if any active circuits
  1189. * (mark bit set to 1) are discovered that weren't cleared in pass 2
  1190. * (don't appear in the linked list).
  1191. */
  1192. circuitmux_assert_okay_pass_one(cmux);
  1193. circuitmux_assert_okay_pass_two(cmux);
  1194. circuitmux_assert_okay_pass_three(cmux);
  1195. }
  1196. /**
  1197. * Do the first pass of circuitmux_assert_okay(); see the comment in that
  1198. * function.
  1199. */
  1200. static void
  1201. circuitmux_assert_okay_pass_one(circuitmux_t *cmux)
  1202. {
  1203. chanid_circid_muxinfo_t **i = NULL;
  1204. uint64_t chan_id;
  1205. channel_t *chan;
  1206. circid_t circ_id;
  1207. circuit_t *circ;
  1208. or_circuit_t *or_circ;
  1209. unsigned int circ_is_active;
  1210. circuit_t **next_p, **prev_p;
  1211. unsigned int n_circuits, n_active_circuits, n_cells;
  1212. tor_assert(cmux);
  1213. tor_assert(cmux->chanid_circid_map);
  1214. /* Reset the counters */
  1215. n_circuits = n_active_circuits = n_cells = 0;
  1216. /* Start iterating the hash table */
  1217. i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
  1218. while (i) {
  1219. /* Assert that the hash table entry isn't null */
  1220. tor_assert(*i);
  1221. /* Get the channel and circuit id */
  1222. chan_id = (*i)->chan_id;
  1223. circ_id = (*i)->circ_id;
  1224. /* Find the channel and circuit, assert that they exist */
  1225. chan = channel_find_by_global_id(chan_id);
  1226. tor_assert(chan);
  1227. circ = circuit_get_by_circid_channel(circ_id, chan);
  1228. tor_assert(circ);
  1229. /* Clear the circ_is_active bit to start */
  1230. circ_is_active = 0;
  1231. /* Assert that we know which direction this is going */
  1232. tor_assert((*i)->muxinfo.direction == CELL_DIRECTION_OUT ||
  1233. (*i)->muxinfo.direction == CELL_DIRECTION_IN);
  1234. if ((*i)->muxinfo.direction == CELL_DIRECTION_OUT) {
  1235. /* We should be n_mux on this circuit */
  1236. tor_assert(cmux == circ->n_mux);
  1237. tor_assert(chan == circ->n_chan);
  1238. /* Get next and prev for next test */
  1239. next_p = &(circ->next_active_on_n_chan);
  1240. prev_p = &(circ->prev_active_on_n_chan);
  1241. } else {
  1242. /* This should be an or_circuit_t and we should be p_mux */
  1243. or_circ = TO_OR_CIRCUIT(circ);
  1244. tor_assert(cmux == or_circ->p_mux);
  1245. tor_assert(chan == or_circ->p_chan);
  1246. /* Get next and prev for next test */
  1247. next_p = &(or_circ->next_active_on_p_chan);
  1248. prev_p = &(or_circ->prev_active_on_p_chan);
  1249. }
  1250. /*
  1251. * Should this circuit be active? I.e., does the mux know about > 0
  1252. * cells on it?
  1253. */
  1254. circ_is_active = ((*i)->muxinfo.cell_count > 0);
  1255. /* It should be in the linked list iff it's active */
  1256. if (circ_is_active) {
  1257. /* Either we have a next link or we are the tail */
  1258. tor_assert(*next_p || (circ == cmux->active_circuits_tail));
  1259. /* Either we have a prev link or we are the head */
  1260. tor_assert(*prev_p || (circ == cmux->active_circuits_head));
  1261. /* Increment the active circuits counter */
  1262. ++n_active_circuits;
  1263. } else {
  1264. /* Shouldn't be in list, so no next or prev link */
  1265. tor_assert(!(*next_p));
  1266. tor_assert(!(*prev_p));
  1267. /* And can't be head or tail */
  1268. tor_assert(circ != cmux->active_circuits_head);
  1269. tor_assert(circ != cmux->active_circuits_tail);
  1270. }
  1271. /* Increment the circuits counter */
  1272. ++n_circuits;
  1273. /* Adjust the cell counter */
  1274. n_cells += (*i)->muxinfo.cell_count;
  1275. /* Set the mark bit to circ_is_active */
  1276. (*i)->muxinfo.mark = circ_is_active;
  1277. /* Advance to the next entry */
  1278. i = HT_NEXT(chanid_circid_muxinfo_map, cmux->chanid_circid_map, i);
  1279. }
  1280. /* Now check the counters */
  1281. tor_assert(n_cells == cmux->n_cells);
  1282. tor_assert(n_circuits == cmux->n_circuits);
  1283. tor_assert(n_active_circuits == cmux->n_active_circuits);
  1284. }
  1285. /**
  1286. * Do the second pass of circuitmux_assert_okay(); see the comment in that
  1287. * function.
  1288. */
  1289. static void
  1290. circuitmux_assert_okay_pass_two(circuitmux_t *cmux)
  1291. {
  1292. circuit_t *curr_circ, *prev_circ = NULL, *next_circ;
  1293. or_circuit_t *curr_or_circ;
  1294. uint64_t curr_chan_id;
  1295. circid_t curr_circ_id;
  1296. circuit_t **next_p, **prev_p;
  1297. channel_t *chan;
  1298. unsigned int n_active_circuits = 0;
  1299. cell_direction_t direction;
  1300. chanid_circid_muxinfo_t search, *hashent = NULL;
  1301. tor_assert(cmux);
  1302. tor_assert(cmux->chanid_circid_map);
  1303. /*
  1304. * Walk the linked list of active circuits in cmux; keep track of the
  1305. * previous circuit seen for consistency checking purposes. Count them
  1306. * to make sure the number in the linked list matches
  1307. * cmux->n_active_circuits.
  1308. */
  1309. curr_circ = cmux->active_circuits_head;
  1310. while (curr_circ) {
  1311. /* Reset some things */
  1312. chan = NULL;
  1313. curr_or_circ = NULL;
  1314. next_circ = NULL;
  1315. next_p = prev_p = NULL;
  1316. direction = 0;
  1317. /* Figure out if this is n_mux or p_mux */
  1318. if (cmux == curr_circ->n_mux) {
  1319. /* Get next_p and prev_p */
  1320. next_p = &(curr_circ->next_active_on_n_chan);
  1321. prev_p = &(curr_circ->prev_active_on_n_chan);
  1322. /* Get the channel */
  1323. chan = curr_circ->n_chan;
  1324. /* Get the circuit id */
  1325. curr_circ_id = curr_circ->n_circ_id;
  1326. /* Remember the direction */
  1327. direction = CELL_DIRECTION_OUT;
  1328. } else {
  1329. /* We must be p_mux and this must be an or_circuit_t */
  1330. curr_or_circ = TO_OR_CIRCUIT(curr_circ);
  1331. tor_assert(cmux == curr_or_circ->p_mux);
  1332. /* Get next_p and prev_p */
  1333. next_p = &(curr_or_circ->next_active_on_p_chan);
  1334. prev_p = &(curr_or_circ->prev_active_on_p_chan);
  1335. /* Get the channel */
  1336. chan = curr_or_circ->p_chan;
  1337. /* Get the circuit id */
  1338. curr_circ_id = curr_or_circ->p_circ_id;
  1339. /* Remember the direction */
  1340. direction = CELL_DIRECTION_IN;
  1341. }
  1342. /* Assert that we got a channel and get the channel ID */
  1343. tor_assert(chan);
  1344. curr_chan_id = chan->global_identifier;
  1345. /* Assert that prev_p points to last circuit we saw */
  1346. tor_assert(*prev_p == prev_circ);
  1347. /* If that's NULL, assert that we are the head */
  1348. if (!(*prev_p)) tor_assert(curr_circ == cmux->active_circuits_head);
  1349. /* Get the next circuit */
  1350. next_circ = *next_p;
  1351. /* If it's NULL, assert that we are the tail */
  1352. if (!(*next_p)) tor_assert(curr_circ == cmux->active_circuits_tail);
  1353. /* Now find the hash table entry for this circuit */
  1354. search.chan_id = curr_chan_id;
  1355. search.circ_id = curr_circ_id;
  1356. hashent = HT_FIND(chanid_circid_muxinfo_map, cmux->chanid_circid_map,
  1357. &search);
  1358. /* Assert that we have one */
  1359. tor_assert(hashent);
  1360. /* Assert that the direction matches */
  1361. tor_assert(direction == hashent->muxinfo.direction);
  1362. /* Assert that the hash entry got marked in pass one */
  1363. tor_assert(hashent->muxinfo.mark);
  1364. /* Clear the mark */
  1365. hashent->muxinfo.mark = 0;
  1366. /* Increment the counter */
  1367. ++n_active_circuits;
  1368. /* Advance to the next active circuit and update prev_circ */
  1369. prev_circ = curr_circ;
  1370. curr_circ = next_circ;
  1371. }
  1372. /* Assert that the counter matches the cmux */
  1373. tor_assert(n_active_circuits == cmux->n_active_circuits);
  1374. }
  1375. /**
  1376. * Do the third pass of circuitmux_assert_okay(); see the comment in that
  1377. * function.
  1378. */
  1379. static void
  1380. circuitmux_assert_okay_pass_three(circuitmux_t *cmux)
  1381. {
  1382. chanid_circid_muxinfo_t **i = NULL;
  1383. tor_assert(cmux);
  1384. tor_assert(cmux->chanid_circid_map);
  1385. /* Start iterating the hash table */
  1386. i = HT_START(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
  1387. /* Advance through each entry */
  1388. while (i) {
  1389. /* Assert that it isn't null */
  1390. tor_assert(*i);
  1391. /*
  1392. * Assert that this entry is not marked - i.e., that either we didn't
  1393. * think it should be active in pass one or we saw it in the active
  1394. * circuits linked list.
  1395. */
  1396. tor_assert(!((*i)->muxinfo.mark));
  1397. /* Advance to the next entry */
  1398. i = HT_NEXT(chanid_circid_muxinfo_map, cmux->chanid_circid_map, i);
  1399. }
  1400. }