Tor  0.4.5.0-alpha-dev
circuitlist.c
Go to the documentation of this file.
1 /* Copyright 2001 Matej Pfajfar.
2  * Copyright (c) 2001-2004, Roger Dingledine.
3  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4  * Copyright (c) 2007-2020, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
7 /**
8  * \file circuitlist.c
9  *
10  * \brief Manage global structures that list and index circuits, and
11  * look up circuits within them.
12  *
13  * One of the most frequent operations in Tor occurs every time that
14  * a relay cell arrives on a channel. When that happens, we need to
15  * find which circuit it is associated with, based on the channel and the
16  * circuit ID in the relay cell.
17  *
18  * To handle that, we maintain a global list of circuits, and a hashtable
19  * mapping [channel,circID] pairs to circuits. Circuits are added to and
20  * removed from this mapping using circuit_set_p_circid_chan() and
21  * circuit_set_n_circid_chan(). To look up a circuit from this map, most
22  * callers should use circuit_get_by_circid_channel(), though
23  * circuit_get_by_circid_channel_even_if_marked() is appropriate under some
24  * circumstances.
25  *
26  * We also need to allow for the possibility that we have blocked use of a
27  * circuit ID (because we are waiting to send a DESTROY cell), but the
28  * circuit is not there any more. For that case, we allow placeholder
29  * entries in the table, using channel_mark_circid_unusable().
30  *
31  * To efficiently handle a channel that has just opened, we also maintain a
32  * list of the circuits waiting for channels, so we can attach them as
33  * needed without iterating through the whole list of circuits, using
34  * circuit_get_all_pending_on_channel().
35  *
36  * In this module, we also handle the list of circuits that have been
37  * marked for close elsewhere, and close them as needed. (We use this
38  * "mark now, close later" pattern here and elsewhere to avoid
39  * unpredictable recursion if we closed every circuit immediately upon
40  * realizing it needed to close.) See circuit_mark_for_close() for the
41  * mark function, and circuit_close_all_marked() for the close function.
42  *
43  * For hidden services, we need to be able to look up introduction point
44  * circuits and rendezvous circuits by cookie, key, etc. These are
45  * currently handled with linear searches in
46  * circuit_get_ready_rend_circuit_by_rend_data(),
47  * circuit_get_next_by_pk_and_purpose(), and with hash lookups in
48  * circuit_get_rendezvous() and circuit_get_intro_point().
49  *
50  * This module is also the entry point for our out-of-memory handler
51  * logic, which was originally circuit-focused.
52  **/
53 #define CIRCUITLIST_PRIVATE
54 #define OCIRC_EVENT_PRIVATE
55 #include "lib/cc/torint.h" /* TOR_PRIuSZ */
56 
57 #include "core/or/or.h"
58 #include "core/or/channel.h"
59 #include "core/or/channeltls.h"
60 #include "feature/client/circpathbias.h"
61 #include "core/or/circuitbuild.h"
62 #include "core/or/circuitlist.h"
63 #include "core/or/circuituse.h"
64 #include "core/or/circuitstats.h"
65 #include "core/or/circuitpadding.h"
66 #include "core/or/crypt_path.h"
67 #include "core/or/extendinfo.h"
68 #include "core/or/trace_probes_circuit.h"
70 #include "app/config/config.h"
72 #include "core/or/connection_or.h"
79 #include "core/mainloop/mainloop.h"
80 #include "feature/hs/hs_circuit.h"
82 #include "feature/hs/hs_ident.h"
87 #include "core/crypto/onion_fast.h"
88 #include "core/or/policies.h"
89 #include "core/or/relay.h"
94 #include "feature/stats/bwhist.h"
95 #include "feature/stats/rephist.h"
98 #include "core/or/channelpadding.h"
99 #include "lib/compress/compress.h"
103 #include "lib/buf/buffers.h"
104 
105 #include "core/or/ocirc_event.h"
106 
107 #include "ht.h"
108 
113 #include "core/or/half_edge_st.h"
114 #include "core/or/extend_info_st.h"
115 #include "core/or/or_circuit_st.h"
117 
118 /********* START VARIABLES **********/
119 
120 /** A global list of all circuits at this hop. */
122 
123 /** A global list of all origin circuits. Every element of this is also
124  * an element of global_circuitlist. */
126 
127 /** A list of all the circuits in CIRCUIT_STATE_CHAN_WAIT. */
129 
130 /** List of all the (origin) circuits whose state is
131  * CIRCUIT_STATE_GUARD_WAIT. */
133 
134 /** A list of all the circuits that have been marked with
135  * circuit_mark_for_close and which are waiting for circuit_about_to_free. */
137 
138 static void cpath_ref_decref(crypt_path_reference_t *cpath_ref);
139 static void circuit_about_to_free_atexit(circuit_t *circ);
140 static void circuit_about_to_free(circuit_t *circ);
141 
142 /**
143  * A cached value of the current state of the origin circuit list. Has the
144  * value 1 if we saw any opened circuits recently (since the last call to
145  * circuit_any_opened_circuits(), which gets called around once a second by
146  * circuit_expire_building). 0 otherwise.
147  */
149 
150 /********* END VARIABLES ************/
151 
152 /* Implement circuit handle helpers. */
153 HANDLE_IMPL(circuit, circuit_t,)
154 
155 or_circuit_t *
157 {
158  tor_assert(x->magic == OR_CIRCUIT_MAGIC);
159  return DOWNCAST(or_circuit_t, x);
160 }
161 const or_circuit_t *
162 CONST_TO_OR_CIRCUIT(const circuit_t *x)
163 {
165  return DOWNCAST(or_circuit_t, x);
166 }
169 {
171  return DOWNCAST(origin_circuit_t, x);
172 }
173 const origin_circuit_t *
174 CONST_TO_ORIGIN_CIRCUIT(const circuit_t *x)
175 {
177  return DOWNCAST(origin_circuit_t, x);
178 }
179 
180 /** A map from channel and circuit ID to circuit. (Lookup performance is
181  * very important here, since we need to do it every time a cell arrives.) */
183  HT_ENTRY(chan_circid_circuit_map_t) node;
184  channel_t *chan;
185  circid_t circ_id;
186  circuit_t *circuit;
187  /* For debugging 12184: when was this placeholder item added? */
188  time_t made_placeholder_at;
190 
191 /** Helper for hash tables: compare the channel and circuit ID for a and
192  * b, and return less than, equal to, or greater than zero appropriately.
193  */
194 static inline int
197 {
198  return a->chan == b->chan && a->circ_id == b->circ_id;
199 }
200 
201 /** Helper: return a hash based on circuit ID and the pointer value of
202  * chan in <b>a</b>. */
203 static inline unsigned int
205 {
206  /* Try to squeze the siphash input into 8 bytes to save any extra siphash
207  * rounds. This hash function is in the critical path. */
208  uintptr_t chan = (uintptr_t) (void*) a->chan;
209  uint32_t array[2];
210  array[0] = a->circ_id;
211  /* The low bits of the channel pointer are uninteresting, since the channel
212  * is a pretty big structure. */
213  array[1] = (uint32_t) (chan >> 6);
214  return (unsigned) siphash24g(array, sizeof(array));
215 }
216 
217 /** Map from [chan,circid] to circuit. */
218 static HT_HEAD(chan_circid_map, chan_circid_circuit_map_t)
219  chan_circid_map = HT_INITIALIZER();
220 HT_PROTOTYPE(chan_circid_map, chan_circid_circuit_map_t, node,
222 HT_GENERATE2(chan_circid_map, chan_circid_circuit_map_t, node,
225 
226 /** The most recently returned entry from circuit_get_by_circid_chan;
227  * used to improve performance when many cells arrive in a row from the
228  * same circuit.
229  */
230 static chan_circid_circuit_map_t *_last_circid_chan_ent = NULL;
231 
232 /** Implementation helper for circuit_set_{p,n}_circid_channel: A circuit ID
233  * and/or channel for circ has just changed from <b>old_chan, old_id</b>
234  * to <b>chan, id</b>. Adjust the chan,circid map as appropriate, removing
235  * the old entry (if any) and adding a new one. */
236 static void
237 circuit_set_circid_chan_helper(circuit_t *circ, int direction,
238  circid_t id,
239  channel_t *chan)
240 {
243  channel_t *old_chan, **chan_ptr;
244  circid_t old_id, *circid_ptr;
245  int make_active, attached = 0;
246 
247  if (direction == CELL_DIRECTION_OUT) {
248  chan_ptr = &circ->n_chan;
249  circid_ptr = &circ->n_circ_id;
250  make_active = circ->n_chan_cells.n > 0;
251  } else {
252  or_circuit_t *c = TO_OR_CIRCUIT(circ);
253  chan_ptr = &c->p_chan;
254  circid_ptr = &c->p_circ_id;
255  make_active = c->p_chan_cells.n > 0;
256  }
257  old_chan = *chan_ptr;
258  old_id = *circid_ptr;
259 
260  if (id == old_id && chan == old_chan)
261  return;
262 
263  if (_last_circid_chan_ent &&
264  ((old_id == _last_circid_chan_ent->circ_id &&
265  old_chan == _last_circid_chan_ent->chan) ||
266  (id == _last_circid_chan_ent->circ_id &&
267  chan == _last_circid_chan_ent->chan))) {
268  _last_circid_chan_ent = NULL;
269  }
270 
271  if (old_chan) {
272  /*
273  * If we're changing channels or ID and had an old channel and a non
274  * zero old ID and weren't marked for close (i.e., we should have been
275  * attached), detach the circuit. ID changes require this because
276  * circuitmux hashes on (channel_id, circuit_id).
277  */
278  if (old_id != 0 && (old_chan != chan || old_id != id) &&
279  !(circ->marked_for_close)) {
280  tor_assert(old_chan->cmux);
281  circuitmux_detach_circuit(old_chan->cmux, circ);
282  }
283 
284  /* we may need to remove it from the conn-circid map */
285  search.circ_id = old_id;
286  search.chan = old_chan;
287  found = HT_REMOVE(chan_circid_map, &chan_circid_map, &search);
288  if (found) {
289  tor_free(found);
290  if (direction == CELL_DIRECTION_OUT) {
291  /* One fewer circuits use old_chan as n_chan */
292  --(old_chan->num_n_circuits);
293  } else {
294  /* One fewer circuits use old_chan as p_chan */
295  --(old_chan->num_p_circuits);
296  }
297  }
298  }
299 
300  /* Change the values only after we have possibly made the circuit inactive
301  * on the previous chan. */
302  *chan_ptr = chan;
303  *circid_ptr = id;
304 
305  if (chan == NULL)
306  return;
307 
308  /* now add the new one to the conn-circid map */
309  search.circ_id = id;
310  search.chan = chan;
311  found = HT_FIND(chan_circid_map, &chan_circid_map, &search);
312  if (found) {
313  found->circuit = circ;
314  found->made_placeholder_at = 0;
315  } else {
316  found = tor_malloc_zero(sizeof(chan_circid_circuit_map_t));
317  found->circ_id = id;
318  found->chan = chan;
319  found->circuit = circ;
320  HT_INSERT(chan_circid_map, &chan_circid_map, found);
321  }
322 
323  /*
324  * Attach to the circuitmux if we're changing channels or IDs and
325  * have a new channel and ID to use and the circuit is not marked for
326  * close.
327  */
328  if (chan && id != 0 && (old_chan != chan || old_id != id) &&
329  !(circ->marked_for_close)) {
330  tor_assert(chan->cmux);
331  circuitmux_attach_circuit(chan->cmux, circ, direction);
332  attached = 1;
333  }
334 
335  /*
336  * This is a no-op if we have no cells, but if we do it marks us active to
337  * the circuitmux
338  */
339  if (make_active && attached)
340  update_circuit_on_cmux(circ, direction);
341 
342  /* Adjust circuit counts on new channel */
343  if (direction == CELL_DIRECTION_OUT) {
344  ++chan->num_n_circuits;
345  } else {
346  ++chan->num_p_circuits;
347  }
348 }
349 
350 /** Mark that circuit id <b>id</b> shouldn't be used on channel <b>chan</b>,
351  * even if there is no circuit on the channel. We use this to keep the
352  * circuit id from getting re-used while we have queued but not yet sent
353  * a destroy cell. */
354 void
356 {
359 
360  /* See if there's an entry there. That wouldn't be good. */
361  memset(&search, 0, sizeof(search));
362  search.chan = chan;
363  search.circ_id = id;
364  ent = HT_FIND(chan_circid_map, &chan_circid_map, &search);
365 
366  if (ent && ent->circuit) {
367  /* we have a problem. */
368  log_warn(LD_BUG, "Tried to mark %u unusable on %p, but there was already "
369  "a circuit there.", (unsigned)id, chan);
370  } else if (ent) {
371  /* It's already marked. */
372  if (!ent->made_placeholder_at)
373  ent->made_placeholder_at = approx_time();
374  } else {
375  ent = tor_malloc_zero(sizeof(chan_circid_circuit_map_t));
376  ent->chan = chan;
377  ent->circ_id = id;
378  /* leave circuit at NULL. */
379  ent->made_placeholder_at = approx_time();
380  HT_INSERT(chan_circid_map, &chan_circid_map, ent);
381  }
382 }
383 
384 /** Mark that a circuit id <b>id</b> can be used again on <b>chan</b>.
385  * We use this to re-enable the circuit ID after we've sent a destroy cell.
386  */
387 void
389 {
392 
393  /* See if there's an entry there. That wouldn't be good. */
394  memset(&search, 0, sizeof(search));
395  search.chan = chan;
396  search.circ_id = id;
397  ent = HT_REMOVE(chan_circid_map, &chan_circid_map, &search);
398  if (ent && ent->circuit) {
399  log_warn(LD_BUG, "Tried to mark %u usable on %p, but there was already "
400  "a circuit there.", (unsigned)id, chan);
401  return;
402  }
403  if (_last_circid_chan_ent == ent)
404  _last_circid_chan_ent = NULL;
405  tor_free(ent);
406 }
407 
408 /** Called to indicate that a DESTROY is pending on <b>chan</b> with
409  * circuit ID <b>id</b>, but hasn't been sent yet. */
410 void
412 {
414  if (circ) {
415  if (circ->n_chan == chan && circ->n_circ_id == id) {
416  circ->n_delete_pending = 1;
417  } else {
418  or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
419  if (orcirc->p_chan == chan && orcirc->p_circ_id == id) {
420  circ->p_delete_pending = 1;
421  }
422  }
423  return;
424  }
426 }
427 
428 /** Called to indicate that a DESTROY is no longer pending on <b>chan</b> with
429  * circuit ID <b>id</b> -- typically, because it has been sent. */
430 MOCK_IMPL(void,
432 {
434  if (circ) {
435  if (circ->n_chan == chan && circ->n_circ_id == id) {
436  circ->n_delete_pending = 0;
437  } else {
438  or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
439  if (orcirc->p_chan == chan && orcirc->p_circ_id == id) {
440  circ->p_delete_pending = 0;
441  }
442  }
443  /* XXXX this shouldn't happen; log a bug here. */
444  return;
445  }
446  channel_mark_circid_usable(chan, id);
447 }
448 
449 /** Set the p_conn field of a circuit <b>circ</b>, along
450  * with the corresponding circuit ID, and add the circuit as appropriate
451  * to the (chan,id)->circuit map. */
452 void
454  channel_t *chan)
455 {
456  circuit_t *circ = TO_CIRCUIT(or_circ);
457  channel_t *old_chan = or_circ->p_chan;
458  circid_t old_id = or_circ->p_circ_id;
459 
460  circuit_set_circid_chan_helper(circ, CELL_DIRECTION_IN, id, chan);
461 
462  if (chan) {
464  }
465 
466  if (circ->p_delete_pending && old_chan) {
467  channel_mark_circid_unusable(old_chan, old_id);
468  circ->p_delete_pending = 0;
469  }
470 }
471 
472 /** Set the n_conn field of a circuit <b>circ</b>, along
473  * with the corresponding circuit ID, and add the circuit as appropriate
474  * to the (chan,id)->circuit map. */
475 void
477  channel_t *chan)
478 {
479  channel_t *old_chan = circ->n_chan;
480  circid_t old_id = circ->n_circ_id;
481 
482  circuit_set_circid_chan_helper(circ, CELL_DIRECTION_OUT, id, chan);
483 
484  if (chan) {
486  }
487 
488  if (circ->n_delete_pending && old_chan) {
489  channel_mark_circid_unusable(old_chan, old_id);
490  circ->n_delete_pending = 0;
491  }
492 }
493 
494 /**
495  * Helper function to publish a message about events on an origin circuit
496  *
497  * Publishes a message to subscribers of origin circuit events, and
498  * sends the control event.
499  **/
500 int
502  int reason_code)
503 {
504  ocirc_cevent_msg_t *msg = tor_malloc(sizeof(*msg));
505 
506  tor_assert(circ);
507 
508  msg->gid = circ->global_identifier;
509  msg->evtype = tp;
510  msg->reason = reason_code;
511  msg->onehop = circ->build_state->onehop_tunnel;
512 
513  ocirc_cevent_publish(msg);
514  return control_event_circuit_status(circ, tp, reason_code);
515 }
516 
517 /**
518  * Helper function to publish a state change message
519  *
520  * circuit_set_state() calls this to notify subscribers about a change
521  * of the state of an origin circuit. @a circ must be an origin
522  * circuit.
523  **/
524 static void
526 {
527  ocirc_state_msg_t *msg = tor_malloc(sizeof(*msg));
528  const origin_circuit_t *ocirc;
529 
531  ocirc = CONST_TO_ORIGIN_CIRCUIT(circ);
532  /* Only inbound OR circuits can be in this state, not origin circuits. */
534 
535  msg->gid = ocirc->global_identifier;
536  msg->state = circ->state;
537  msg->onehop = ocirc->build_state->onehop_tunnel;
538 
539  ocirc_state_publish(msg);
540 }
541 
542 /** Change the state of <b>circ</b> to <b>state</b>, adding it to or removing
543  * it from lists as appropriate. */
544 void
545 circuit_set_state(circuit_t *circ, uint8_t state)
546 {
547  tor_assert(circ);
548  if (state == circ->state)
549  return;
550  if (PREDICT_UNLIKELY(!circuits_pending_chans))
552  if (PREDICT_UNLIKELY(!circuits_pending_other_guards))
554  if (circ->state == CIRCUIT_STATE_CHAN_WAIT) {
555  /* remove from waiting-circuit list. */
557  }
558  if (state == CIRCUIT_STATE_CHAN_WAIT) {
559  /* add to waiting-circuit list. */
561  }
562  if (circ->state == CIRCUIT_STATE_GUARD_WAIT) {
564  }
565  if (state == CIRCUIT_STATE_GUARD_WAIT) {
567  }
568  if (state == CIRCUIT_STATE_GUARD_WAIT || state == CIRCUIT_STATE_OPEN)
570 
571  tor_trace(TR_SUBSYS(circuit), TR_EV(change_state), circ, circ->state, state);
572  circ->state = state;
573  if (CIRCUIT_IS_ORIGIN(circ))
574  circuit_state_publish(circ);
575 }
576 
577 /** Append to <b>out</b> all circuits in state CHAN_WAIT waiting for
578  * the given connection. */
579 void
581 {
582  tor_assert(out);
583  tor_assert(chan);
584 
586  return;
587 
589  if (circ->marked_for_close)
590  continue;
591  if (!circ->n_hop)
592  continue;
595  /* Look at addr/port. This is an unkeyed connection. */
596  if (!channel_matches_extend_info(chan, circ->n_hop))
597  continue;
598  } else {
599  /* We expected a key. See if it's the right one. */
600  if (tor_memneq(chan->identity_digest,
602  continue;
603  }
604  smartlist_add(out, circ);
605  } SMARTLIST_FOREACH_END(circ);
606 }
607 
608 /** Return the number of circuits in state CHAN_WAIT, waiting for the given
609  * channel. */
610 int
612 {
613  int cnt;
614  smartlist_t *sl = smartlist_new();
615 
616  tor_assert(chan);
617 
619  cnt = smartlist_len(sl);
620  smartlist_free(sl);
621  log_debug(LD_CIRC,"or_conn to %s, %d pending circs",
622  channel_describe_peer(chan),
623  cnt);
624  return cnt;
625 }
626 
627 /** Remove <b>origin_circ</b> from the global list of origin circuits.
628  * Called when we are freeing a circuit.
629  */
630 static void
632 {
633  int origin_idx = origin_circ->global_origin_circuit_list_idx;
634  if (origin_idx < 0)
635  return;
636  origin_circuit_t *c2;
637  tor_assert(origin_idx <= smartlist_len(global_origin_circuit_list));
638  c2 = smartlist_get(global_origin_circuit_list, origin_idx);
639  tor_assert(origin_circ == c2);
641  if (origin_idx < smartlist_len(global_origin_circuit_list)) {
642  origin_circuit_t *replacement =
643  smartlist_get(global_origin_circuit_list, origin_idx);
644  replacement->global_origin_circuit_list_idx = origin_idx;
645  }
646  origin_circ->global_origin_circuit_list_idx = -1;
647 }
648 
649 /** Add <b>origin_circ</b> to the global list of origin circuits. Called
650  * when creating the circuit. */
651 static void
653 {
654  tor_assert(origin_circ->global_origin_circuit_list_idx == -1);
656  smartlist_add(lst, origin_circ);
657  origin_circ->global_origin_circuit_list_idx = smartlist_len(lst) - 1;
658 }
659 
660 /** Detach from the global circuit list, and deallocate, all
661  * circuits that have been marked for close.
662  */
663 void
665 {
666  if (circuits_pending_close == NULL)
667  return;
668 
672 
673  /* Remove it from the circuit list. */
674  int idx = circ->global_circuitlist_idx;
675  smartlist_del(lst, idx);
676  if (idx < smartlist_len(lst)) {
677  circuit_t *replacement = smartlist_get(lst, idx);
678  replacement->global_circuitlist_idx = idx;
679  }
680  circ->global_circuitlist_idx = -1;
681 
682  /* Remove it from the origin circuit list, if appropriate. */
683  if (CIRCUIT_IS_ORIGIN(circ)) {
685  }
686 
687  circuit_about_to_free(circ);
688  circuit_free(circ);
689  } SMARTLIST_FOREACH_END(circ);
690 
692 }
693 
694 /** Return a pointer to the global list of circuits. */
697 {
698  if (NULL == global_circuitlist)
700  return global_circuitlist;
701 }
702 
703 /** Return a pointer to the global list of origin circuits. */
704 smartlist_t *
706 {
707  if (NULL == global_origin_circuit_list)
710 }
711 
712 /**
713  * Return true if we have any opened general-purpose 3 hop
714  * origin circuits.
715  *
716  * The result from this function is cached for use by
717  * circuit_any_opened_circuits_cached().
718  */
719 int
721 {
723  const origin_circuit_t *, next_circ) {
724  if (!TO_CIRCUIT(next_circ)->marked_for_close &&
725  next_circ->has_opened &&
726  TO_CIRCUIT(next_circ)->state == CIRCUIT_STATE_OPEN &&
727  TO_CIRCUIT(next_circ)->purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT &&
728  next_circ->build_state &&
729  next_circ->build_state->desired_path_len == DEFAULT_ROUTE_LEN) {
731  return 1;
732  }
733  } SMARTLIST_FOREACH_END(next_circ);
734 
736  return 0;
737 }
738 
739 /**
740  * Cache the "any circuits opened" state, as specified in param
741  * circuits_are_opened. This is a helper function to update
742  * the circuit opened status whenever we happen to look at the
743  * circuit list.
744  */
745 void
746 circuit_cache_opened_circuit_state(int circuits_are_opened)
747 {
748  any_opened_circs_cached_val = circuits_are_opened;
749 }
750 
751 /**
752  * Return true if there were any opened circuits since the last call to
753  * circuit_any_opened_circuits(), or since circuit_expire_building() last
754  * ran (it runs roughly once per second).
755  */
756 int
758 {
760 }
761 
762 /** Function to make circ->state human-readable */
763 const char *
765 {
766  static char buf[64];
767  switch (state) {
768  case CIRCUIT_STATE_BUILDING: return "doing handshakes";
769  case CIRCUIT_STATE_ONIONSKIN_PENDING: return "processing the onion";
770  case CIRCUIT_STATE_CHAN_WAIT: return "connecting to server";
771  case CIRCUIT_STATE_GUARD_WAIT: return "waiting to see how other "
772  "guards perform";
773  case CIRCUIT_STATE_OPEN: return "open";
774  default:
775  log_warn(LD_BUG, "Unknown circuit state %d", state);
776  tor_snprintf(buf, sizeof(buf), "unknown state [%d]", state);
777  return buf;
778  }
779 }
780 
781 /** Map a circuit purpose to a string suitable to be displayed to a
782  * controller. */
783 const char *
785 {
786  static char buf[32];
787  switch (purpose) {
788  case CIRCUIT_PURPOSE_OR:
792  return "SERVER"; /* A controller should never see these, actually. */
793 
795  return "GENERAL";
796 
798  return "HS_CLIENT_HSDIR";
799 
803  return "HS_CLIENT_INTRO";
804 
809  return "HS_CLIENT_REND";
810 
812  return "HS_SERVICE_HSDIR";
813 
816  return "HS_SERVICE_INTRO";
817 
820  return "HS_SERVICE_REND";
821 
823  return "TESTING";
825  return "MEASURE_TIMEOUT";
827  return "CONTROLLER";
829  return "PATH_BIAS_TESTING";
831  return "HS_VANGUARDS";
833  return "CIRCUIT_PADDING";
834 
835  default:
836  tor_snprintf(buf, sizeof(buf), "UNKNOWN_%d", (int)purpose);
837  return buf;
838  }
839 }
840 
841 /** Return a string specifying the state of the hidden-service circuit
842  * purpose <b>purpose</b>, or NULL if <b>purpose</b> is not a
843  * hidden-service-related circuit purpose. */
844 const char *
846 {
847  switch (purpose)
848  {
849  default:
851  "Unrecognized circuit purpose: %d",
852  (int)purpose);
854  FALLTHROUGH;
855 
856  case CIRCUIT_PURPOSE_OR:
864  return NULL;
865 
867  return "OR_HSSI_ESTABLISHED";
869  return "OR_HSCR_ESTABLISHED";
871  return "OR_HS_R_JOINED";
872 
875  return "HSCI_CONNECTING";
877  return "HSCI_INTRO_SENT";
879  return "HSCI_DONE";
880 
882  return "HSCR_CONNECTING";
884  return "HSCR_ESTABLISHED_IDLE";
886  return "HSCR_ESTABLISHED_WAITING";
888  return "HSCR_JOINED";
889 
892  return "HSSI_CONNECTING";
894  return "HSSI_ESTABLISHED";
895 
897  return "HSSR_CONNECTING";
899  return "HSSR_JOINED";
900  }
901 }
902 
903 /** Return a human-readable string for the circuit purpose <b>purpose</b>. */
904 const char *
906 {
907  static char buf[32];
908 
909  switch (purpose)
910  {
911  case CIRCUIT_PURPOSE_OR:
912  return "Circuit at relay";
914  return "Acting as intro point";
916  return "Acting as rendezvous (pending)";
918  return "Acting as rendezvous (established)";
920  return "General-purpose client";
922  return "Hidden service client: Connecting to intro point";
924  return "Hidden service client: Waiting for ack from intro point";
926  return "Hidden service client: Received ack from intro point";
928  return "Hidden service client: Establishing rendezvous point";
930  return "Hidden service client: Pending rendezvous point";
932  return "Hidden service client: Pending rendezvous point (ack received)";
934  return "Hidden service client: Active rendezvous point";
936  return "Hidden service client: Fetching HS descriptor";
937 
939  return "Measuring circuit timeout";
940 
942  return "Hidden service: Establishing introduction point";
944  return "Hidden service: Introduction point";
946  return "Hidden service: Connecting to rendezvous point";
948  return "Hidden service: Active rendezvous point";
950  return "Hidden service: Uploading HS descriptor";
951 
953  return "Testing circuit";
954 
956  return "Circuit made by controller";
957 
959  return "Path-bias testing circuit";
960 
962  return "Hidden service: Pre-built vanguard circuit";
963 
965  return "Circuit kept open for padding";
966 
967  default:
968  tor_snprintf(buf, sizeof(buf), "UNKNOWN_%d", (int)purpose);
969  return buf;
970  }
971 }
972 
973 /** Pick a reasonable package_window to start out for our circuits.
974  * Originally this was hard-coded at 1000, but now the consensus votes
975  * on the answer. See proposal 168. */
976 int32_t
978 {
979  int32_t num = networkstatus_get_param(NULL, "circwindow", CIRCWINDOW_START,
980  CIRCWINDOW_START_MIN,
981  CIRCWINDOW_START_MAX);
982  /* If the consensus tells us a negative number, we'd assert. */
983  if (num < 0)
984  num = CIRCWINDOW_START;
985  return num;
986 }
987 
988 /** Initialize the common elements in a circuit_t, and add it to the global
989  * list. */
990 static void
992 {
994 
995  // Gets reset when we send CREATE_FAST.
996  // circuit_expire_building() expects these to be equal
997  // until the orconn is built.
998  circ->timestamp_began = circ->timestamp_created;
999 
1003  cell_queue_init(&circ->n_chan_cells);
1004 
1006  circ->global_circuitlist_idx = smartlist_len(circuit_get_global_list()) - 1;
1007 }
1008 
1009 /** If we haven't yet decided on a good timeout value for circuit
1010  * building, we close idle circuits aggressively so we can get more
1011  * data points. These are the default, min, and max consensus values */
1012 #define DFLT_IDLE_TIMEOUT_WHILE_LEARNING (3*60)
1013 #define MIN_IDLE_TIMEOUT_WHILE_LEARNING (10)
1014 #define MAX_IDLE_TIMEOUT_WHILE_LEARNING (1000*60)
1015 
1016 /** Allocate space for a new circuit, initializing with <b>p_circ_id</b>
1017  * and <b>p_conn</b>. Add it to the global circuit list.
1018  */
1021 {
1022  origin_circuit_t *circ;
1023  /* never zero, since a global ID of 0 is treated specially by the
1024  * controller */
1025  static uint32_t n_circuits_allocated = 1;
1026 
1027  circ = tor_malloc_zero(sizeof(origin_circuit_t));
1028  circ->base_.magic = ORIGIN_CIRCUIT_MAGIC;
1029 
1030  circ->next_stream_id = crypto_rand_int(1<<16);
1031  circ->global_identifier = n_circuits_allocated++;
1034 
1036 
1037  /* Add to origin-list. */
1038  circ->global_origin_circuit_list_idx = -1;
1040 
1041  circuit_build_times_update_last_circ(get_circuit_build_times_mutable());
1042 
1045  /* Circuits should be shorter lived if we need more of them
1046  * for learning a good build timeout */
1047  circ->circuit_idle_timeout =
1048  networkstatus_get_param(NULL, "cbtlearntimeout",
1050  MIN_IDLE_TIMEOUT_WHILE_LEARNING,
1051  MAX_IDLE_TIMEOUT_WHILE_LEARNING);
1052  } else {
1053  // This should always be larger than the current port prediction time
1054  // remaining, or else we'll end up with the case where a circuit times out
1055  // and another one is built, effectively doubling the timeout window.
1056  //
1057  // We also randomize it by up to 5% more (ie 5% of 0 to 3600 seconds,
1058  // depending on how much circuit prediction time is remaining) so that
1059  // we don't close a bunch of unused circuits all at the same time.
1060  int prediction_time_remaining =
1062  circ->circuit_idle_timeout = prediction_time_remaining+1+
1063  crypto_rand_int(1+prediction_time_remaining/20);
1064 
1065  if (circ->circuit_idle_timeout <= 0) {
1066  log_warn(LD_BUG,
1067  "Circuit chose a negative idle timeout of %d based on "
1068  "%d seconds of predictive building remaining.",
1069  circ->circuit_idle_timeout,
1070  prediction_time_remaining);
1071  circ->circuit_idle_timeout =
1072  networkstatus_get_param(NULL, "cbtlearntimeout",
1074  MIN_IDLE_TIMEOUT_WHILE_LEARNING,
1075  MAX_IDLE_TIMEOUT_WHILE_LEARNING);
1076  }
1077 
1078  log_info(LD_CIRC,
1079  "Circuit %"PRIu32" chose an idle timeout of %d based on "
1080  "%d seconds of predictive building remaining.",
1081  (circ->global_identifier),
1082  circ->circuit_idle_timeout,
1083  prediction_time_remaining);
1084  }
1085 
1086  tor_trace(TR_SUBSYS(circuit), TR_EV(new_origin), circ);
1087  return circ;
1088 }
1089 
1090 /** Allocate a new or_circuit_t, connected to <b>p_chan</b> as
1091  * <b>p_circ_id</b>. If <b>p_chan</b> is NULL, the circuit is unattached. */
1092 or_circuit_t *
1093 or_circuit_new(circid_t p_circ_id, channel_t *p_chan)
1094 {
1095  /* CircIDs */
1096  or_circuit_t *circ;
1097 
1098  circ = tor_malloc_zero(sizeof(or_circuit_t));
1099  circ->base_.magic = OR_CIRCUIT_MAGIC;
1100 
1101  if (p_chan)
1102  circuit_set_p_circid_chan(circ, p_circ_id, p_chan);
1103 
1105  cell_queue_init(&circ->p_chan_cells);
1106 
1108 
1109  tor_trace(TR_SUBSYS(circuit), TR_EV(new_or), circ);
1110  return circ;
1111 }
1112 
1113 /** Free all storage held in circ->testing_cell_stats */
1114 void
1116 {
1117  if (!circ || !circ->testing_cell_stats)
1118  return;
1120  ent, tor_free(ent));
1121  smartlist_free(circ->testing_cell_stats);
1122  circ->testing_cell_stats = NULL;
1123 }
1124 
1125 /** Deallocate space associated with circ.
1126  */
1127 STATIC void
1129 {
1130  circid_t n_circ_id = 0;
1131  void *mem;
1132  size_t memlen;
1133  int should_free = 1;
1134  if (!circ)
1135  return;
1136 
1137  /* We keep a copy of this so we can log its value before it gets unset. */
1138  n_circ_id = circ->n_circ_id;
1139 
1141 
1142  /* Cleanup circuit from anything HS v3 related. We also do this when the
1143  * circuit is closed. This is to avoid any code path that free registered
1144  * circuits without closing them before. This needs to be done before the
1145  * hs identifier is freed. */
1147 
1148  if (CIRCUIT_IS_ORIGIN(circ)) {
1149  origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
1150  mem = ocirc;
1151  memlen = sizeof(origin_circuit_t);
1153 
1155 
1156  if (ocirc->half_streams) {
1158  half_conn) {
1159  half_edge_free(half_conn);
1160  } SMARTLIST_FOREACH_END(half_conn);
1161  smartlist_free(ocirc->half_streams);
1162  }
1163 
1164  if (ocirc->build_state) {
1165  extend_info_free(ocirc->build_state->chosen_exit);
1168  }
1169  tor_free(ocirc->build_state);
1170 
1171  /* Cancel before freeing, if we haven't already succeeded or failed. */
1172  if (ocirc->guard_state) {
1174  }
1175  circuit_guard_state_free(ocirc->guard_state);
1176 
1177  circuit_clear_cpath(ocirc);
1178 
1179  crypto_pk_free(ocirc->intro_key);
1180  rend_data_free(ocirc->rend_data);
1181 
1182  /* Finally, free the identifier of the circuit and nullify it so multiple
1183  * cleanup will work. */
1184  hs_ident_circuit_free(ocirc->hs_ident);
1185  ocirc->hs_ident = NULL;
1186 
1187  tor_free(ocirc->dest_address);
1188  if (ocirc->socks_username) {
1189  memwipe(ocirc->socks_username, 0x12, ocirc->socks_username_len);
1190  tor_free(ocirc->socks_username);
1191  }
1192  if (ocirc->socks_password) {
1193  memwipe(ocirc->socks_password, 0x06, ocirc->socks_password_len);
1194  tor_free(ocirc->socks_password);
1195  }
1196  addr_policy_list_free(ocirc->prepend_policy);
1197  } else {
1198  or_circuit_t *ocirc = TO_OR_CIRCUIT(circ);
1199  /* Remember cell statistics for this circuit before deallocating. */
1200  if (get_options()->CellStatistics)
1201  rep_hist_buffer_stats_add_circ(circ, time(NULL));
1202  mem = ocirc;
1203  memlen = sizeof(or_circuit_t);
1204  tor_assert(circ->magic == OR_CIRCUIT_MAGIC);
1205 
1206  should_free = (ocirc->workqueue_entry == NULL);
1207 
1208  relay_crypto_clear(&ocirc->crypto);
1209 
1210  if (ocirc->rend_splice) {
1211  or_circuit_t *other = ocirc->rend_splice;
1212  tor_assert(other->base_.magic == OR_CIRCUIT_MAGIC);
1213  other->rend_splice = NULL;
1214  }
1215 
1216  /* remove from map. */
1217  circuit_set_p_circid_chan(ocirc, 0, NULL);
1218 
1219  /* Clear cell queue _after_ removing it from the map. Otherwise our
1220  * "active" checks will be violated. */
1221  cell_queue_clear(&ocirc->p_chan_cells);
1222  }
1223 
1224  extend_info_free(circ->n_hop);
1226 
1227  if (circ->global_circuitlist_idx != -1) {
1228  int idx = circ->global_circuitlist_idx;
1229  circuit_t *c2 = smartlist_get(global_circuitlist, idx);
1230  tor_assert(c2 == circ);
1232  if (idx < smartlist_len(global_circuitlist)) {
1233  c2 = smartlist_get(global_circuitlist, idx);
1234  c2->global_circuitlist_idx = idx;
1235  }
1236  }
1237 
1238  /* Remove from map. */
1239  circuit_set_n_circid_chan(circ, 0, NULL);
1240 
1241  /* Clear cell queue _after_ removing it from the map. Otherwise our
1242  * "active" checks will be violated. */
1244 
1245  /* Cleanup possible SENDME state. */
1246  if (circ->sendme_last_digests) {
1247  SMARTLIST_FOREACH(circ->sendme_last_digests, uint8_t *, d, tor_free(d));
1248  smartlist_free(circ->sendme_last_digests);
1249  }
1250 
1251  log_info(LD_CIRC, "Circuit %u (id: %" PRIu32 ") has been freed.",
1252  n_circ_id,
1253  CIRCUIT_IS_ORIGIN(circ) ?
1254  TO_ORIGIN_CIRCUIT(circ)->global_identifier : 0);
1255 
1256  /* Free any circuit padding structures */
1258 
1259  /* Clear all dangling handle references. */
1260  circuit_handles_clear(circ);
1261 
1262  /* Tracepoint. Data within the circuit object is recorded so do this before
1263  * the actual memory free. */
1264  tor_trace(TR_SUBSYS(circuit), TR_EV(free), circ);
1265 
1266  if (should_free) {
1267  memwipe(mem, 0xAA, memlen); /* poison memory */
1268  tor_free(mem);
1269  } else {
1270  /* If we made it here, this is an or_circuit_t that still has a pending
1271  * cpuworker request which we weren't able to cancel. Instead, set up
1272  * the magic value so that when the reply comes back, we'll know to discard
1273  * the reply and free this structure.
1274  */
1275  memwipe(mem, 0xAA, memlen);
1276  circ->magic = DEAD_CIRCUIT_MAGIC;
1277  }
1278 }
1279 
1280 /** Deallocate the linked list circ-><b>cpath</b>, and remove the cpath from
1281  * <b>circ</b>. */
1282 void
1284 {
1285  crypt_path_t *victim, *head, *cpath;
1286 
1287  head = cpath = circ->cpath;
1288 
1289  if (!cpath)
1290  return;
1291 
1292  /* it's a circular list, so we have to notice when we've
1293  * gone through it once. */
1294  while (cpath->next && cpath->next != head) {
1295  victim = cpath;
1296  cpath = victim->next;
1297  cpath_free(victim);
1298  }
1299 
1300  cpath_free(cpath);
1301 
1302  circ->cpath = NULL;
1303 }
1304 
1305 /** Release all storage held by circuits. */
1306 void
1308 {
1310 
1311  SMARTLIST_FOREACH_BEGIN(lst, circuit_t *, tmp) {
1312  if (! CIRCUIT_IS_ORIGIN(tmp)) {
1313  or_circuit_t *or_circ = TO_OR_CIRCUIT(tmp);
1314  while (or_circ->resolving_streams) {
1315  edge_connection_t *next_conn;
1316  next_conn = or_circ->resolving_streams->next_stream;
1318  or_circ->resolving_streams = next_conn;
1319  }
1320  }
1321  tmp->global_circuitlist_idx = -1;
1323  circuit_free(tmp);
1324  SMARTLIST_DEL_CURRENT(lst, tmp);
1325  } SMARTLIST_FOREACH_END(tmp);
1326 
1327  smartlist_free(lst);
1328  global_circuitlist = NULL;
1329 
1330  smartlist_free(global_origin_circuit_list);
1332 
1333  smartlist_free(circuits_pending_chans);
1334  circuits_pending_chans = NULL;
1335 
1336  smartlist_free(circuits_pending_close);
1337  circuits_pending_close = NULL;
1338 
1339  smartlist_free(circuits_pending_other_guards);
1341 
1342  {
1343  chan_circid_circuit_map_t **elt, **next, *c;
1344  for (elt = HT_START(chan_circid_map, &chan_circid_map);
1345  elt;
1346  elt = next) {
1347  c = *elt;
1348  next = HT_NEXT_RMV(chan_circid_map, &chan_circid_map, elt);
1349 
1350  tor_assert(c->circuit == NULL);
1351  tor_free(c);
1352  }
1353  }
1354  HT_CLEAR(chan_circid_map, &chan_circid_map);
1355 }
1356 
1357 /** Release a crypt_path_reference_t*, which may be NULL. */
1358 static void
1360 {
1361  if (cpath_ref != NULL) {
1362  if (--(cpath_ref->refcount) == 0) {
1363  cpath_free(cpath_ref->cpath);
1364  tor_free(cpath_ref);
1365  }
1366  }
1367 }
1368 
1369 /** A helper function for circuit_dump_by_conn() below. Log a bunch
1370  * of information about circuit <b>circ</b>.
1371  */
1372 static void
1374  circuit_t *circ,
1375  int conn_array_index,
1376  const char *type,
1377  circid_t this_circid,
1378  circid_t other_circid)
1379 {
1380  tor_log(severity, LD_CIRC, "Conn %d has %s circuit: circID %u "
1381  "(other side %u), state %d (%s), born %ld:",
1382  conn_array_index, type, (unsigned)this_circid, (unsigned)other_circid,
1383  circ->state, circuit_state_to_string(circ->state),
1384  (long)circ->timestamp_began.tv_sec);
1385  if (CIRCUIT_IS_ORIGIN(circ)) { /* circ starts at this node */
1386  circuit_log_path(severity, LD_CIRC, TO_ORIGIN_CIRCUIT(circ));
1387  }
1388 }
1389 
1390 /** Log, at severity <b>severity</b>, information about each circuit
1391  * that is connected to <b>conn</b>.
1392  */
1393 void
1395 {
1396  edge_connection_t *tmpconn;
1397 
1399  circid_t n_circ_id = circ->n_circ_id, p_circ_id = 0;
1400 
1401  if (circ->marked_for_close) {
1402  continue;
1403  }
1404 
1405  if (!CIRCUIT_IS_ORIGIN(circ)) {
1406  p_circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
1407  }
1408 
1409  if (CIRCUIT_IS_ORIGIN(circ)) {
1410  for (tmpconn=TO_ORIGIN_CIRCUIT(circ)->p_streams; tmpconn;
1411  tmpconn=tmpconn->next_stream) {
1412  if (TO_CONN(tmpconn) == conn) {
1413  circuit_dump_conn_details(severity, circ, conn->conn_array_index,
1414  "App-ward", p_circ_id, n_circ_id);
1415  }
1416  }
1417  }
1418 
1419  if (! CIRCUIT_IS_ORIGIN(circ)) {
1420  for (tmpconn=TO_OR_CIRCUIT(circ)->n_streams; tmpconn;
1421  tmpconn=tmpconn->next_stream) {
1422  if (TO_CONN(tmpconn) == conn) {
1423  circuit_dump_conn_details(severity, circ, conn->conn_array_index,
1424  "Exit-ward", n_circ_id, p_circ_id);
1425  }
1426  }
1427  }
1428  }
1429  SMARTLIST_FOREACH_END(circ);
1430 }
1431 
1432 /** Return the circuit whose global ID is <b>id</b>, or NULL if no
1433  * such circuit exists. */
1436 {
1438  if (CIRCUIT_IS_ORIGIN(circ) &&
1439  TO_ORIGIN_CIRCUIT(circ)->global_identifier == id) {
1440  if (circ->marked_for_close)
1441  return NULL;
1442  else
1443  return TO_ORIGIN_CIRCUIT(circ);
1444  }
1445  }
1446  SMARTLIST_FOREACH_END(circ);
1447  return NULL;
1448 }
1449 
1450 /** Return a circ such that:
1451  * - circ->n_circ_id or circ->p_circ_id is equal to <b>circ_id</b>, and
1452  * - circ is attached to <b>chan</b>, either as p_chan or n_chan.
1453  * Return NULL if no such circuit exists.
1454  *
1455  * If <b>found_entry_out</b> is provided, set it to true if we have a
1456  * placeholder entry for circid/chan, and leave it unset otherwise.
1457  */
1458 static inline circuit_t *
1460  int *found_entry_out)
1461 {
1464 
1465  if (_last_circid_chan_ent &&
1466  circ_id == _last_circid_chan_ent->circ_id &&
1467  chan == _last_circid_chan_ent->chan) {
1468  found = _last_circid_chan_ent;
1469  } else {
1470  search.circ_id = circ_id;
1471  search.chan = chan;
1472  found = HT_FIND(chan_circid_map, &chan_circid_map, &search);
1473  _last_circid_chan_ent = found;
1474  }
1475  if (found && found->circuit) {
1476  log_debug(LD_CIRC,
1477  "circuit_get_by_circid_channel_impl() returning circuit %p for"
1478  " circ_id %u, channel ID %"PRIu64 " (%p)",
1479  found->circuit, (unsigned)circ_id,
1480  (chan->global_identifier), chan);
1481  if (found_entry_out)
1482  *found_entry_out = 1;
1483  return found->circuit;
1484  }
1485 
1486  log_debug(LD_CIRC,
1487  "circuit_get_by_circid_channel_impl() found %s for"
1488  " circ_id %u, channel ID %"PRIu64 " (%p)",
1489  found ? "placeholder" : "nothing",
1490  (unsigned)circ_id,
1491  (chan->global_identifier), chan);
1492 
1493  if (found_entry_out)
1494  *found_entry_out = found ? 1 : 0;
1495 
1496  return NULL;
1497  /* The rest of this checks for bugs. Disabled by default. */
1498  /* We comment it out because coverity complains otherwise.
1499  {
1500  circuit_t *circ;
1501  TOR_LIST_FOREACH(circ, &global_circuitlist, head) {
1502  if (! CIRCUIT_IS_ORIGIN(circ)) {
1503  or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
1504  if (or_circ->p_chan == chan && or_circ->p_circ_id == circ_id) {
1505  log_warn(LD_BUG,
1506  "circuit matches p_chan, but not in hash table (Bug!)");
1507  return circ;
1508  }
1509  }
1510  if (circ->n_chan == chan && circ->n_circ_id == circ_id) {
1511  log_warn(LD_BUG,
1512  "circuit matches n_chan, but not in hash table (Bug!)");
1513  return circ;
1514  }
1515  }
1516  return NULL;
1517  } */
1518 }
1519 
1520 /** Return a circ such that:
1521  * - circ->n_circ_id or circ->p_circ_id is equal to <b>circ_id</b>, and
1522  * - circ is attached to <b>chan</b>, either as p_chan or n_chan.
1523  * - circ is not marked for close.
1524  * Return NULL if no such circuit exists.
1525  */
1526 circuit_t *
1528 {
1529  circuit_t *circ = circuit_get_by_circid_channel_impl(circ_id, chan, NULL);
1530  if (!circ || circ->marked_for_close)
1531  return NULL;
1532  else
1533  return circ;
1534 }
1535 
1536 /** Return a circ such that:
1537  * - circ->n_circ_id or circ->p_circ_id is equal to <b>circ_id</b>, and
1538  * - circ is attached to <b>chan</b>, either as p_chan or n_chan.
1539  * Return NULL if no such circuit exists.
1540  */
1541 circuit_t *
1543  channel_t *chan)
1544 {
1545  return circuit_get_by_circid_channel_impl(circ_id, chan, NULL);
1546 }
1547 
1548 /** Return true iff the circuit ID <b>circ_id</b> is currently used by a
1549  * circuit, marked or not, on <b>chan</b>, or if the circ ID is reserved until
1550  * a queued destroy cell can be sent.
1551  *
1552  * (Return 1 if the circuit is present, marked or not; Return 2
1553  * if the circuit ID is pending a destroy.)
1554  **/
1555 int
1557 {
1558  int found = 0;
1559  if (circuit_get_by_circid_channel_impl(circ_id, chan, &found) != NULL)
1560  return 1;
1561  if (found)
1562  return 2;
1563  return 0;
1564 }
1565 
1566 /** Helper for debugging 12184. Returns the time since which 'circ_id' has
1567  * been marked unusable on 'chan'. */
1568 time_t
1570 {
1573 
1574  memset(&search, 0, sizeof(search));
1575  search.circ_id = circ_id;
1576  search.chan = chan;
1577 
1578  found = HT_FIND(chan_circid_map, &chan_circid_map, &search);
1579 
1580  if (! found || found->circuit)
1581  return 0;
1582 
1583  return found->made_placeholder_at;
1584 }
1585 
1586 /** Return the circuit that a given edge connection is using. */
1587 circuit_t *
1589 {
1590  circuit_t *circ;
1591 
1592  circ = conn->on_circuit;
1593  tor_assert(!circ ||
1594  (CIRCUIT_IS_ORIGIN(circ) ? circ->magic == ORIGIN_CIRCUIT_MAGIC
1595  : circ->magic == OR_CIRCUIT_MAGIC));
1596 
1597  return circ;
1598 }
1599 
1600 /** For each circuit that has <b>chan</b> as n_chan or p_chan, unlink the
1601  * circuit from the chan,circid map, and mark it for close if it hasn't
1602  * been marked already.
1603  */
1604 void
1606 {
1607  smartlist_t *detached = smartlist_new();
1608 
1609 /* #define DEBUG_CIRCUIT_UNLINK_ALL */
1610 
1611  channel_unlink_all_circuits(chan, detached);
1612 
1613 #ifdef DEBUG_CIRCUIT_UNLINK_ALL
1614  {
1615  smartlist_t *detached_2 = smartlist_new();
1616  int mismatch = 0, badlen = 0;
1617 
1619  if (circ->n_chan == chan ||
1620  (!CIRCUIT_IS_ORIGIN(circ) &&
1621  TO_OR_CIRCUIT(circ)->p_chan == chan)) {
1622  smartlist_add(detached_2, circ);
1623  }
1624  }
1625  SMARTLIST_FOREACH_END(circ);
1626 
1627  if (smartlist_len(detached) != smartlist_len(detached_2)) {
1628  log_warn(LD_BUG, "List of detached circuits had the wrong length! "
1629  "(got %d, should have gotten %d)",
1630  (int)smartlist_len(detached),
1631  (int)smartlist_len(detached_2));
1632  badlen = 1;
1633  }
1634  smartlist_sort_pointers(detached);
1635  smartlist_sort_pointers(detached_2);
1636 
1637  SMARTLIST_FOREACH(detached, circuit_t *, c,
1638  if (c != smartlist_get(detached_2, c_sl_idx))
1639  mismatch = 1;
1640  );
1641 
1642  if (mismatch)
1643  log_warn(LD_BUG, "Mismatch in list of detached circuits.");
1644 
1645  if (badlen || mismatch) {
1646  smartlist_free(detached);
1647  detached = detached_2;
1648  } else {
1649  log_notice(LD_CIRC, "List of %d circuits was as expected.",
1650  (int)smartlist_len(detached));
1651  smartlist_free(detached_2);
1652  }
1653  }
1654 #endif /* defined(DEBUG_CIRCUIT_UNLINK_ALL) */
1655 
1656  SMARTLIST_FOREACH_BEGIN(detached, circuit_t *, circ) {
1657  int mark = 0;
1658  if (circ->n_chan == chan) {
1659 
1660  circuit_set_n_circid_chan(circ, 0, NULL);
1661  mark = 1;
1662 
1663  /* If we didn't request this closure, pass the remote
1664  * bit to mark_for_close. */
1665  if (chan->reason_for_closing != CHANNEL_CLOSE_REQUESTED)
1666  reason |= END_CIRC_REASON_FLAG_REMOTE;
1667  }
1668  if (! CIRCUIT_IS_ORIGIN(circ)) {
1669  or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
1670  if (or_circ->p_chan == chan) {
1671  circuit_set_p_circid_chan(or_circ, 0, NULL);
1672  mark = 1;
1673  }
1674  }
1675  if (!mark) {
1676  log_warn(LD_BUG, "Circuit on detached list which I had no reason "
1677  "to mark");
1678  continue;
1679  }
1680  if (!circ->marked_for_close)
1681  circuit_mark_for_close(circ, reason);
1682  } SMARTLIST_FOREACH_END(circ);
1683 
1684  smartlist_free(detached);
1685 }
1686 
1687 /** Return a circ such that
1688  * - circ->rend_data->onion_address is equal to
1689  * <b>rend_data</b>->onion_address,
1690  * - circ->rend_data->rend_cookie is equal to
1691  * <b>rend_data</b>->rend_cookie, and
1692  * - circ->purpose is equal to CIRCUIT_PURPOSE_C_REND_READY.
1693  *
1694  * Return NULL if no such circuit exists.
1695  */
1698 {
1700  if (!circ->marked_for_close &&
1702  origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
1703  if (ocirc->rend_data == NULL) {
1704  continue;
1705  }
1707  rend_data_get_address(ocirc->rend_data)) &&
1709  rend_data->rend_cookie,
1710  REND_COOKIE_LEN))
1711  return ocirc;
1712  }
1713  }
1714  SMARTLIST_FOREACH_END(circ);
1715  return NULL;
1716 }
1717 
1718 /** Return the first introduction circuit originating from the global circuit
1719  * list after <b>start</b> or at the start of the list if <b>start</b> is
1720  * NULL. Return NULL if no circuit is found.
1721  *
1722  * If <b>want_client_circ</b> is true, then we are looking for client-side
1723  * introduction circuits: A client introduction point circuit has a purpose of
1724  * either CIRCUIT_PURPOSE_C_INTRODUCING, CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT
1725  * or CIRCUIT_PURPOSE_C_INTRODUCE_ACKED. This does not return a circuit marked
1726  * for close, but it returns circuits regardless of their circuit state.
1727  *
1728  * If <b>want_client_circ</b> is false, then we are looking for service-side
1729  * introduction circuits: A service introduction point circuit has a purpose of
1730  * either CIRCUIT_PURPOSE_S_ESTABLISH_INTRO or CIRCUIT_PURPOSE_S_INTRO. This
1731  * does not return circuits marked for close, or in any state other than open.
1732  */
1735  bool want_client_circ)
1736 {
1737  int idx = 0;
1739 
1740  if (start) {
1741  idx = TO_CIRCUIT(start)->global_circuitlist_idx + 1;
1742  }
1743 
1744  for ( ; idx < smartlist_len(lst); ++idx) {
1745  circuit_t *circ = smartlist_get(lst, idx);
1746 
1747  /* Ignore a marked for close circuit or if the state is not open. */
1748  if (circ->marked_for_close) {
1749  continue;
1750  }
1751 
1752  /* Depending on whether we are looking for client or service circs, skip
1753  * circuits with other purposes. */
1754  if (want_client_circ) {
1755  if (circ->purpose != CIRCUIT_PURPOSE_C_INTRODUCING &&
1758  continue;
1759  }
1760  } else { /* we are looking for service-side circs */
1761  if (circ->state != CIRCUIT_STATE_OPEN) {
1762  continue;
1763  }
1765  circ->purpose != CIRCUIT_PURPOSE_S_INTRO) {
1766  continue;
1767  }
1768  }
1769 
1770  /* The purposes we are looking for are only for origin circuits so the
1771  * following is valid. */
1772  return TO_ORIGIN_CIRCUIT(circ);
1773  }
1774  /* Not found. */
1775  return NULL;
1776 }
1777 
1778 /** Return the first service rendezvous circuit originating from the global
1779  * circuit list after <b>start</b> or at the start of the list if <b>start</b>
1780  * is NULL. Return NULL if no circuit is found.
1781  *
1782  * A service rendezvous point circuit has a purpose of either
1783  * CIRCUIT_PURPOSE_S_CONNECT_REND or CIRCUIT_PURPOSE_S_REND_JOINED. This does
1784  * not return a circuit marked for close and its state must be open. */
1787 {
1788  int idx = 0;
1790 
1791  if (start) {
1792  idx = TO_CIRCUIT(start)->global_circuitlist_idx + 1;
1793  }
1794 
1795  for ( ; idx < smartlist_len(lst); ++idx) {
1796  circuit_t *circ = smartlist_get(lst, idx);
1797 
1798  /* Ignore a marked for close circuit or purpose not matching a service
1799  * intro point or if the state is not open. */
1800  if (circ->marked_for_close || circ->state != CIRCUIT_STATE_OPEN ||
1803  continue;
1804  }
1805  /* The purposes we are looking for are only for origin circuits so the
1806  * following is valid. */
1807  return TO_ORIGIN_CIRCUIT(circ);
1808  }
1809  /* Not found. */
1810  return NULL;
1811 }
1812 
1813 /** Return the first circuit originating here in global_circuitlist after
1814  * <b>start</b> whose purpose is <b>purpose</b>, and where <b>digest</b> (if
1815  * set) matches the private key digest of the rend data associated with the
1816  * circuit. Return NULL if no circuit is found. If <b>start</b> is NULL,
1817  * begin at the start of the list.
1818  */
1821  const uint8_t *digest, uint8_t purpose)
1822 {
1823  int idx;
1826  if (start == NULL)
1827  idx = 0;
1828  else
1829  idx = TO_CIRCUIT(start)->global_circuitlist_idx + 1;
1830 
1831  for ( ; idx < smartlist_len(lst); ++idx) {
1832  circuit_t *circ = smartlist_get(lst, idx);
1833  origin_circuit_t *ocirc;
1834 
1835  if (circ->marked_for_close)
1836  continue;
1837  if (circ->purpose != purpose)
1838  continue;
1839  /* At this point we should be able to get a valid origin circuit because
1840  * the origin purpose we are looking for matches this circuit. */
1841  if (BUG(!CIRCUIT_PURPOSE_IS_ORIGIN(circ->purpose))) {
1842  break;
1843  }
1844  ocirc = TO_ORIGIN_CIRCUIT(circ);
1845  if (!digest)
1846  return ocirc;
1847  if (rend_circuit_pk_digest_eq(ocirc, digest)) {
1848  return ocirc;
1849  }
1850  }
1851  return NULL;
1852 }
1853 
1854 /** We might cannibalize this circuit: Return true if its last hop can be used
1855  * as a v3 rendezvous point. */
1856 static int
1858 {
1859  if (!circ->build_state) {
1860  return 0;
1861  }
1862 
1863  extend_info_t *chosen_exit = circ->build_state->chosen_exit;
1864  if (BUG(!chosen_exit)) {
1865  return 0;
1866  }
1867 
1868  const node_t *rp_node = node_get_by_id(chosen_exit->identity_digest);
1869  if (rp_node) {
1870  if (node_supports_v3_rendezvous_point(rp_node)) {
1871  return 1;
1872  }
1873  }
1874 
1875  return 0;
1876 }
1877 
1878 /** We are trying to create a circuit of purpose <b>purpose</b> and we are
1879  * looking for cannibalizable circuits. Return the circuit purpose we would be
1880  * willing to cannibalize. */
1881 static uint8_t
1883 {
1884  if (circuit_should_use_vanguards(purpose)) {
1885  /* If we are using vanguards, then we should only cannibalize vanguard
1886  * circuits so that we get the same path construction logic. */
1888  } else {
1889  /* If no vanguards are used just get a general circuit! */
1891  }
1892 }
1893 
1894 /** Return a circuit that is open, is CIRCUIT_PURPOSE_C_GENERAL,
1895  * has a timestamp_dirty value of 0, has flags matching the CIRCLAUNCH_*
1896  * flags in <b>flags</b>, and if info is defined, does not already use info
1897  * as any of its hops; or NULL if no circuit fits this description.
1898  *
1899  * The <b>purpose</b> argument refers to the purpose of the circuit we want to
1900  * create, not the purpose of the circuit we want to cannibalize.
1901  *
1902  * If !CIRCLAUNCH_NEED_UPTIME, prefer returning non-uptime circuits.
1903  *
1904  * To "cannibalize" a circuit means to extend it an extra hop, and use it
1905  * for some other purpose than we had originally intended. We do this when
1906  * we want to perform some low-bandwidth task at a specific relay, and we
1907  * would like the circuit to complete as soon as possible. (If we were going
1908  * to use a lot of bandwidth, we wouldn't want a circuit with an extra hop.
1909  * If we didn't care about circuit completion latency, we would just build
1910  * a new circuit.)
1911  */
1913 circuit_find_to_cannibalize(uint8_t purpose_to_produce, extend_info_t *info,
1914  int flags)
1915 {
1916  origin_circuit_t *best=NULL;
1917  int need_uptime = (flags & CIRCLAUNCH_NEED_UPTIME) != 0;
1918  int need_capacity = (flags & CIRCLAUNCH_NEED_CAPACITY) != 0;
1919  int internal = (flags & CIRCLAUNCH_IS_INTERNAL) != 0;
1920  const or_options_t *options = get_options();
1921  /* We want the circuit we are trying to cannibalize to have this purpose */
1922  int purpose_to_search_for;
1923 
1924  /* Make sure we're not trying to create a onehop circ by
1925  * cannibalization. */
1927 
1928  purpose_to_search_for = get_circuit_purpose_needed_to_cannibalize(
1929  purpose_to_produce);
1930 
1931  tor_assert_nonfatal(purpose_to_search_for == CIRCUIT_PURPOSE_C_GENERAL ||
1932  purpose_to_search_for == CIRCUIT_PURPOSE_HS_VANGUARDS);
1933 
1934  log_debug(LD_CIRC,
1935  "Hunting for a circ to cannibalize: purpose %d, uptime %d, "
1936  "capacity %d, internal %d",
1937  purpose_to_produce, need_uptime, need_capacity, internal);
1938 
1940  if (CIRCUIT_IS_ORIGIN(circ_) &&
1941  circ_->state == CIRCUIT_STATE_OPEN &&
1942  !circ_->marked_for_close &&
1943  circ_->purpose == purpose_to_search_for &&
1944  !circ_->timestamp_dirty) {
1945  origin_circuit_t *circ = TO_ORIGIN_CIRCUIT(circ_);
1946 
1947  /* Only cannibalize from reasonable length circuits. If we
1948  * want C_GENERAL, then only choose 3 hop circs. If we want
1949  * HS_VANGUARDS, only choose 4 hop circs.
1950  */
1951  if (circ->build_state->desired_path_len !=
1952  route_len_for_purpose(purpose_to_search_for, NULL)) {
1953  goto next;
1954  }
1955 
1956  /* Ignore any circuits for which we can't use the Guard. It is possible
1957  * that the Guard was removed from the sampled set after the circuit
1958  * was created, so avoid using it. */
1959  if (!entry_guard_could_succeed(circ->guard_state)) {
1960  goto next;
1961  }
1962 
1963  if ((!need_uptime || circ->build_state->need_uptime) &&
1964  (!need_capacity || circ->build_state->need_capacity) &&
1965  (internal == circ->build_state->is_internal) &&
1966  !circ->unusable_for_new_conns &&
1968  !circ->build_state->onehop_tunnel &&
1969  !circ->isolation_values_set) {
1970  if (info) {
1971  /* need to make sure we don't duplicate hops */
1972  crypt_path_t *hop = circ->cpath;
1973  const node_t *ri1 = node_get_by_id(info->identity_digest);
1974  do {
1975  const node_t *ri2;
1977  info->identity_digest, DIGEST_LEN))
1978  goto next;
1979  if (ri1 &&
1981  && nodes_in_same_family(ri1, ri2))
1982  goto next;
1983  hop=hop->next;
1984  } while (hop!=circ->cpath);
1985  }
1986  if (options->ExcludeNodes) {
1987  /* Make sure no existing nodes in the circuit are excluded for
1988  * general use. (This may be possible if StrictNodes is 0, and we
1989  * thought we needed to use an otherwise excluded node for, say, a
1990  * directory operation.) */
1991  crypt_path_t *hop = circ->cpath;
1992  do {
1994  hop->extend_info))
1995  goto next;
1996  hop = hop->next;
1997  } while (hop != circ->cpath);
1998  }
1999 
2000  if ((flags & CIRCLAUNCH_IS_V3_RP) &&
2002  log_debug(LD_GENERAL, "Skipping uncannibalizable circuit for v3 "
2003  "rendezvous point.");
2004  goto next;
2005  }
2006 
2007  if (!best || (best->build_state->need_uptime && !need_uptime))
2008  best = circ;
2009  next: ;
2010  }
2011  }
2012  }
2013  SMARTLIST_FOREACH_END(circ_);
2014  return best;
2015 }
2016 
2017 /**
2018  * Check whether any of the origin circuits that are waiting to see if
2019  * their guard is good enough to use can be upgraded to "ready". If so,
2020  * return a new smartlist containing them. Otherwise return NULL.
2021  */
2022 smartlist_t *
2024 {
2025  /* Only if some circuit is actually waiting on an upgrade should we
2026  * run the algorithm. */
2028  smartlist_len(circuits_pending_other_guards)==0)
2029  return NULL;
2030  /* Only if we have some origin circuits should we run the algorithm. */
2032  return NULL;
2033 
2034  /* Okay; we can pass our circuit list to entrynodes.c.*/
2035  smartlist_t *result = smartlist_new();
2036  int circuits_upgraded = entry_guards_upgrade_waiting_circuits(
2039  result);
2040  if (circuits_upgraded && smartlist_len(result)) {
2041  return result;
2042  } else {
2043  smartlist_free(result);
2044  return NULL;
2045  }
2046 }
2047 
2048 /** Return the number of hops in circuit's path. If circ has no entries,
2049  * or is NULL, returns 0. */
2050 int
2052 {
2053  int n = 0;
2054  if (circ && circ->cpath) {
2055  crypt_path_t *cpath, *cpath_next = NULL;
2056  for (cpath = circ->cpath; cpath_next != circ->cpath; cpath = cpath_next) {
2057  cpath_next = cpath->next;
2058  ++n;
2059  }
2060  }
2061  return n;
2062 }
2063 
2064 /** Return the number of opened hops in circuit's path.
2065  * If circ has no entries, or is NULL, returns 0. */
2066 int
2068 {
2069  int n = 0;
2070  if (circ && circ->cpath) {
2071  crypt_path_t *cpath, *cpath_next = NULL;
2072  for (cpath = circ->cpath;
2073  cpath->state == CPATH_STATE_OPEN
2074  && cpath_next != circ->cpath;
2075  cpath = cpath_next) {
2076  cpath_next = cpath->next;
2077  ++n;
2078  }
2079  }
2080  return n;
2081 }
2082 
2083 /** Return the <b>hopnum</b>th hop in <b>circ</b>->cpath, or NULL if there
2084  * aren't that many hops in the list. <b>hopnum</b> starts at 1.
2085  * Returns NULL if <b>hopnum</b> is 0 or negative. */
2086 crypt_path_t *
2088 {
2089  if (circ && circ->cpath && hopnum > 0) {
2090  crypt_path_t *cpath, *cpath_next = NULL;
2091  for (cpath = circ->cpath; cpath_next != circ->cpath; cpath = cpath_next) {
2092  cpath_next = cpath->next;
2093  if (--hopnum <= 0)
2094  return cpath;
2095  }
2096  }
2097  return NULL;
2098 }
2099 
2100 /** Go through the circuitlist; mark-for-close each circuit that starts
2101  * at us but has not yet been used. */
2102 void
2104 {
2106  if (CIRCUIT_IS_ORIGIN(circ) &&
2107  !circ->marked_for_close &&
2108  !circ->timestamp_dirty)
2109  circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
2110  }
2111  SMARTLIST_FOREACH_END(circ);
2112 }
2113 
2114 /** Go through the circuitlist; for each circuit that starts at us
2115  * and is dirty, frob its timestamp_dirty so we won't use it for any
2116  * new streams.
2117  *
2118  * This is useful for letting the user change pseudonyms, so new
2119  * streams will not be linkable to old streams.
2120  */
2121 void
2123 {
2125  if (CIRCUIT_IS_ORIGIN(circ) &&
2126  !circ->marked_for_close &&
2127  circ->timestamp_dirty) {
2129  }
2130  }
2131  SMARTLIST_FOREACH_END(circ);
2132 }
2133 
2134 /**
2135  * Report any queued cells on or_circuits as written in our bandwidth
2136  * totals, for the specified channel direction.
2137  *
2138  * When we close a circuit or clear its cell queues, we've read
2139  * data and recorded those bytes in our read statistics, but we're
2140  * not going to write it. This discrepancy can be used by an adversary
2141  * to infer information from our public relay statistics and perform
2142  * attacks such as guard discovery.
2143  *
2144  * This function is in the critical path of circuit_mark_for_close().
2145  * It must be (and is) O(1)!
2146  *
2147  * See https://bugs.torproject.org/tpo/core/tor/23512
2148  */
2149 void
2152 {
2153  uint64_t cells;
2154  uint64_t cell_size;
2155  uint64_t written_sync;
2156  const channel_t *chan = NULL;
2157  const or_circuit_t *or_circ;
2158 
2159  if (!CIRCUIT_IS_ORCIRC(c))
2160  return;
2161 
2162  or_circ = CONST_TO_OR_CIRCUIT(c);
2163 
2164  if (dir == CIRCUIT_N_CHAN) {
2165  chan = c->n_chan;
2166  cells = c->n_chan_cells.n;
2167  } else {
2168  chan = or_circ->p_chan;
2169  cells = or_circ->p_chan_cells.n;
2170  }
2171 
2172  /* If we still know the chan, determine real cell size. Otherwise,
2173  * assume it's a wide circid channel */
2174  if (chan)
2175  cell_size = get_cell_network_size(chan->wide_circ_ids);
2176  else
2177  cell_size = CELL_MAX_NETWORK_SIZE;
2178 
2179  /* If we know the channel, find out if it's IPv6. */
2180  tor_addr_t remote_addr;
2181  bool is_ipv6 = chan &&
2182  channel_get_addr_if_possible(chan, &remote_addr) &&
2183  tor_addr_family(&remote_addr) == AF_INET6;
2184 
2185  /* The missing written bytes are the cell counts times their cell
2186  * size plus TLS per cell overhead */
2187  written_sync = cells*(cell_size+TLS_PER_CELL_OVERHEAD);
2188 
2189  /* Report the missing bytes as written, to avoid asymmetry.
2190  * We must use time() for consistency with rephist, even though on
2191  * some very old rare platforms, approx_time() may be faster. */
2192  bwhist_note_bytes_written(written_sync, time(NULL), is_ipv6);
2193 }
2194 
2195 /** Mark <b>circ</b> to be closed next time we call
2196  * circuit_close_all_marked(). Do any cleanup needed:
2197  * - If state is onionskin_pending, remove circ from the onion_pending
2198  * list.
2199  * - If circ isn't open yet: call circuit_build_failed() if we're
2200  * the origin.
2201  * - If purpose is C_INTRODUCE_ACK_WAIT, report the intro point
2202  * failure we just had to the hidden service client module.
2203  * - If purpose is C_INTRODUCING and <b>reason</b> isn't TIMEOUT,
2204  * report to the hidden service client module that the intro point
2205  * we just tried may be unreachable.
2206  * - Send appropriate destroys and edge_destroys for conns and
2207  * streams attached to circ.
2208  * - If circ->rend_splice is set (we are the midpoint of a joined
2209  * rendezvous stream), then mark the other circuit to close as well.
2210  */
2211 MOCK_IMPL(void,
2212 circuit_mark_for_close_, (circuit_t *circ, int reason, int line,
2213  const char *file))
2214 {
2215  int orig_reason = reason; /* Passed to the controller */
2216  assert_circuit_ok(circ);
2217  tor_assert(line);
2218  tor_assert(file);
2219 
2220  /* Check whether the circuitpadding subsystem wants to block this close */
2221  if (circpad_marked_circuit_for_padding(circ, reason)) {
2222  return;
2223  }
2224 
2225  if (circ->marked_for_close) {
2226  log_warn(LD_BUG,
2227  "Duplicate call to circuit_mark_for_close at %s:%d"
2228  " (first at %s:%d)", file, line,
2230  return;
2231  }
2232  if (reason == END_CIRC_AT_ORIGIN) {
2233  if (!CIRCUIT_IS_ORIGIN(circ)) {
2234  log_warn(LD_BUG, "Specified 'at-origin' non-reason for ending circuit, "
2235  "but circuit was not at origin. (called %s:%d, purpose=%d)",
2236  file, line, circ->purpose);
2237  }
2238  reason = END_CIRC_REASON_NONE;
2239  }
2240 
2241  if (CIRCUIT_IS_ORIGIN(circ)) {
2242  if (pathbias_check_close(TO_ORIGIN_CIRCUIT(circ), reason) == -1) {
2243  /* Don't close it yet, we need to test it first */
2244  return;
2245  }
2246 
2247  /* We don't send reasons when closing circuits at the origin. */
2248  reason = END_CIRC_REASON_NONE;
2249  }
2250 
2251  circuit_synchronize_written_or_bandwidth(circ, CIRCUIT_N_CHAN);
2252  circuit_synchronize_written_or_bandwidth(circ, CIRCUIT_P_CHAN);
2253 
2254  if (reason & END_CIRC_REASON_FLAG_REMOTE)
2255  reason &= ~END_CIRC_REASON_FLAG_REMOTE;
2256 
2257  if (reason < END_CIRC_REASON_MIN_ || reason > END_CIRC_REASON_MAX_) {
2258  if (!(orig_reason & END_CIRC_REASON_FLAG_REMOTE))
2259  log_warn(LD_BUG, "Reason %d out of range at %s:%d", reason, file, line);
2260  reason = END_CIRC_REASON_NONE;
2261  }
2262 
2263  circ->marked_for_close = line;
2264  circ->marked_for_close_file = file;
2265  circ->marked_for_close_reason = reason;
2266  circ->marked_for_close_orig_reason = orig_reason;
2267 
2268  if (!CIRCUIT_IS_ORIGIN(circ)) {
2269  or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
2270  if (or_circ->rend_splice) {
2271  if (!or_circ->rend_splice->base_.marked_for_close) {
2272  /* do this after marking this circuit, to avoid infinite recursion. */
2273  circuit_mark_for_close(TO_CIRCUIT(or_circ->rend_splice), reason);
2274  }
2275  or_circ->rend_splice = NULL;
2276  }
2277  }
2278 
2279  /* Notify the HS subsystem that this circuit is closing. */
2281 
2282  if (circuits_pending_close == NULL)
2284 
2287 
2288  log_info(LD_GENERAL, "Circuit %u (id: %" PRIu32 ") marked for close at "
2289  "%s:%d (orig reason: %d, new reason: %d)",
2290  circ->n_circ_id,
2291  CIRCUIT_IS_ORIGIN(circ) ?
2292  TO_ORIGIN_CIRCUIT(circ)->global_identifier : 0,
2293  file, line, orig_reason, reason);
2294  tor_trace(TR_SUBSYS(circuit), TR_EV(mark_for_close), circ);
2295 }
2296 
2297 /** Called immediately before freeing a marked circuit <b>circ</b> from
2298  * circuit_free_all() while shutting down Tor; this is a safe-at-shutdown
2299  * version of circuit_about_to_free(). It's important that it at least
2300  * do circuitmux_detach_circuit() when appropriate.
2301  */
2302 static void
2304 {
2305 
2306  if (circ->n_chan) {
2307  circuit_clear_cell_queue(circ, circ->n_chan);
2308  circuitmux_detach_circuit(circ->n_chan->cmux, circ);
2309  circuit_set_n_circid_chan(circ, 0, NULL);
2310  }
2311 
2312  if (! CIRCUIT_IS_ORIGIN(circ)) {
2313  or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
2314 
2315  if (or_circ->p_chan) {
2316  circuit_clear_cell_queue(circ, or_circ->p_chan);
2317  circuitmux_detach_circuit(or_circ->p_chan->cmux, circ);
2318  circuit_set_p_circid_chan(or_circ, 0, NULL);
2319  }
2320  }
2321 }
2322 
2323 /** Called immediately before freeing a marked circuit <b>circ</b>.
2324  * Disconnects the circuit from other data structures, launches events
2325  * as appropriate, and performs other housekeeping.
2326  */
2327 static void
2329 {
2330 
2331  int reason = circ->marked_for_close_reason;
2332  int orig_reason = circ->marked_for_close_orig_reason;
2333 
2334  if (circ->state == CIRCUIT_STATE_ONIONSKIN_PENDING) {
2336  }
2337  /* If the circuit ever became OPEN, we sent it to the reputation history
2338  * module then. If it isn't OPEN, we send it there now to remember which
2339  * links worked and which didn't.
2340  */
2341  if (circ->state != CIRCUIT_STATE_OPEN &&
2342  circ->state != CIRCUIT_STATE_GUARD_WAIT) {
2343  if (CIRCUIT_IS_ORIGIN(circ)) {
2344  origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
2345  circuit_build_failed(ocirc); /* take actions if necessary */
2346  }
2347  }
2348  if (circ->state == CIRCUIT_STATE_CHAN_WAIT) {
2351  }
2354  }
2355  if (CIRCUIT_IS_ORIGIN(circ)) {
2357  (circ->state == CIRCUIT_STATE_OPEN ||
2358  circ->state == CIRCUIT_STATE_GUARD_WAIT) ?
2359  CIRC_EVENT_CLOSED:CIRC_EVENT_FAILED,
2360  orig_reason);
2361  }
2362 
2363  if (circ->n_chan) {
2364  circuit_clear_cell_queue(circ, circ->n_chan);
2365  /* Only send destroy if the channel isn't closing anyway */
2366  if (!CHANNEL_CONDEMNED(circ->n_chan)) {
2367  channel_send_destroy(circ->n_circ_id, circ->n_chan, reason);
2368  }
2369  circuitmux_detach_circuit(circ->n_chan->cmux, circ);
2370  circuit_set_n_circid_chan(circ, 0, NULL);
2371  }
2372 
2373  if (! CIRCUIT_IS_ORIGIN(circ)) {
2374  or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
2375  edge_connection_t *conn;
2376  for (conn=or_circ->n_streams; conn; conn=conn->next_stream)
2377  connection_edge_destroy(or_circ->p_circ_id, conn);
2378  or_circ->n_streams = NULL;
2379 
2380  while (or_circ->resolving_streams) {
2381  conn = or_circ->resolving_streams;
2382  or_circ->resolving_streams = conn->next_stream;
2383  if (!conn->base_.marked_for_close) {
2384  /* The client will see a DESTROY, and infer that the connections
2385  * are closing because the circuit is getting torn down. No need
2386  * to send an end cell. */
2387  conn->edge_has_sent_end = 1;
2388  conn->end_reason = END_STREAM_REASON_DESTROY;
2390  connection_mark_for_close(TO_CONN(conn));
2391  }
2392  conn->on_circuit = NULL;
2393  }
2394 
2395  if (or_circ->p_chan) {
2396  circuit_clear_cell_queue(circ, or_circ->p_chan);
2397  /* Only send destroy if the channel isn't closing anyway */
2398  if (!CHANNEL_CONDEMNED(or_circ->p_chan)) {
2399  channel_send_destroy(or_circ->p_circ_id, or_circ->p_chan, reason);
2400  }
2401  circuitmux_detach_circuit(or_circ->p_chan->cmux, circ);
2402  circuit_set_p_circid_chan(or_circ, 0, NULL);
2403  }
2404  } else {
2405  origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
2406  edge_connection_t *conn;
2407  for (conn=ocirc->p_streams; conn; conn=conn->next_stream)
2408  connection_edge_destroy(circ->n_circ_id, conn);
2409  ocirc->p_streams = NULL;
2410  }
2411 }
2412 
2413 /** Given a marked circuit <b>circ</b>, aggressively free its cell queues to
2414  * recover memory. */
2415 static void
2417 {
2418  if (!circ->marked_for_close) {
2419  log_warn(LD_BUG, "Called on non-marked circuit");
2420  return;
2421  }
2423  if (! CIRCUIT_IS_ORIGIN(circ)) {
2424  or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
2425  cell_queue_clear(&orcirc->p_chan_cells);
2426  }
2427 }
2428 
2429 static size_t
2430 single_conn_free_bytes(connection_t *conn)
2431 {
2432  size_t result = 0;
2433  if (conn->inbuf) {
2434  result += buf_allocation(conn->inbuf);
2435  buf_clear(conn->inbuf);
2436  }
2437  if (conn->outbuf) {
2438  result += buf_allocation(conn->outbuf);
2439  buf_clear(conn->outbuf);
2440  }
2441  if (conn->type == CONN_TYPE_DIR) {
2442  dir_connection_t *dir_conn = TO_DIR_CONN(conn);
2443  if (dir_conn->compress_state) {
2444  result += tor_compress_state_size(dir_conn->compress_state);
2445  tor_compress_free(dir_conn->compress_state);
2446  dir_conn->compress_state = NULL;
2447  }
2448  }
2449  return result;
2450 }
2451 
2452 /** Aggressively free buffer contents on all the buffers of all streams in the
2453  * list starting at <b>stream</b>. Return the number of bytes recovered. */
2454 static size_t
2456 {
2457  size_t result = 0;
2458  for ( ; stream; stream = stream->next_stream) {
2459  connection_t *conn = TO_CONN(stream);
2460  result += single_conn_free_bytes(conn);
2461  if (conn->linked_conn) {
2462  result += single_conn_free_bytes(conn->linked_conn);
2463  }
2464  }
2465  return result;
2466 }
2467 
2468 /** Aggressively free buffer contents on all the buffers of all streams on
2469  * circuit <b>c</b>. Return the number of bytes recovered. */
2470 static size_t
2472 {
2473  if (CIRCUIT_IS_ORIGIN(c)) {
2475  } else {
2476  return marked_circuit_streams_free_bytes(TO_OR_CIRCUIT(c)->n_streams);
2477  }
2478 }
2479 
2480 /** Return the number of cells used by the circuit <b>c</b>'s cell queues. */
2481 STATIC size_t
2483 {
2484  size_t n = c->n_chan_cells.n;
2485  if (! CIRCUIT_IS_ORIGIN(c)) {
2486  circuit_t *cc = (circuit_t *) c;
2487  n += TO_OR_CIRCUIT(cc)->p_chan_cells.n;
2488  }
2489  return n;
2490 }
2491 
2492 /** Return the number of bytes allocated for <b>c</b>'s half-open streams. */
2493 static size_t
2495 {
2496  if (! CIRCUIT_IS_ORIGIN(c)) {
2497  return 0;
2498  }
2499  const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(c);
2500  if (ocirc->half_streams)
2501  return smartlist_len(ocirc->half_streams) * sizeof(half_edge_t);
2502  else
2503  return 0;
2504 }
2505 
2506 /**
2507  * Return the age of the oldest cell queued on <b>c</b>, in timestamp units.
2508  * Return 0 if there are no cells queued on c. Requires that <b>now</b> be
2509  * the current coarse timestamp.
2510  *
2511  * This function will return incorrect results if the oldest cell queued on
2512  * the circuit is older than about 2**32 msec (about 49 days) old.
2513  */
2514 STATIC uint32_t
2516 {
2517  uint32_t age = 0;
2518  packed_cell_t *cell;
2519 
2520  if (NULL != (cell = TOR_SIMPLEQ_FIRST(&c->n_chan_cells.head)))
2521  age = now - cell->inserted_timestamp;
2522 
2523  if (! CIRCUIT_IS_ORIGIN(c)) {
2524  const or_circuit_t *orcirc = CONST_TO_OR_CIRCUIT(c);
2525  if (NULL != (cell = TOR_SIMPLEQ_FIRST(&orcirc->p_chan_cells.head))) {
2526  uint32_t age2 = now - cell->inserted_timestamp;
2527  if (age2 > age)
2528  return age2;
2529  }
2530  }
2531  return age;
2532 }
2533 
2534 /** Return the age of the oldest buffer chunk on <b>conn</b>, where age is
2535  * taken in timestamp units before the time <b>now</b>. If the connection has
2536  * no data, treat it as having age zero.
2537  **/
2538 static uint32_t
2539 conn_get_buffer_age(const connection_t *conn, uint32_t now_ts)
2540 {
2541  uint32_t age = 0, age2;
2542  if (conn->outbuf) {
2543  age2 = buf_get_oldest_chunk_timestamp(conn->outbuf, now_ts);
2544  if (age2 > age)
2545  age = age2;
2546  }
2547  if (conn->inbuf) {
2548  age2 = buf_get_oldest_chunk_timestamp(conn->inbuf, now_ts);
2549  if (age2 > age)
2550  age = age2;
2551  }
2552  return age;
2553 }
2554 
2555 /** Return the age in timestamp units of the oldest buffer chunk on any stream
2556  * in the linked list <b>stream</b>, where age is taken in timestamp units
2557  * before the timestamp <b>now</b>. */
2558 static uint32_t
2560 {
2561  uint32_t age = 0, age2;
2562  for (; stream; stream = stream->next_stream) {
2563  const connection_t *conn = TO_CONN(stream);
2564  age2 = conn_get_buffer_age(conn, now);
2565  if (age2 > age)
2566  age = age2;
2567  if (conn->linked_conn) {
2568  age2 = conn_get_buffer_age(conn->linked_conn, now);
2569  if (age2 > age)
2570  age = age2;
2571  }
2572  }
2573  return age;
2574 }
2575 
2576 /** Return the age in timestamp units of the oldest buffer chunk on any stream
2577  * attached to the circuit <b>c</b>, where age is taken before the timestamp
2578  * <b>now</b>. */
2579 STATIC uint32_t
2581 {
2582  if (CIRCUIT_IS_ORIGIN(c)) {
2584  CONST_TO_ORIGIN_CIRCUIT(c)->p_streams, now);
2585  } else {
2587  CONST_TO_OR_CIRCUIT(c)->n_streams, now);
2588  }
2589 }
2590 
2591 /** Return the age of the oldest cell or stream buffer chunk on the circuit
2592  * <b>c</b>, where age is taken in timestamp units before the timestamp
2593  * <b>now</b> */
2594 STATIC uint32_t
2596 {
2597  uint32_t cell_age = circuit_max_queued_cell_age(c, now);
2598  uint32_t data_age = circuit_max_queued_data_age(c, now);
2599  if (cell_age > data_age)
2600  return cell_age;
2601  else
2602  return data_age;
2603 }
2604 
2605 /** Helper to sort a list of circuit_t by age of oldest item, in descending
2606  * order. */
2607 static int
2608 circuits_compare_by_oldest_queued_item_(const void **a_, const void **b_)
2609 {
2610  const circuit_t *a = *a_;
2611  const circuit_t *b = *b_;
2612  uint32_t age_a = a->age_tmp;
2613  uint32_t age_b = b->age_tmp;
2614 
2615  if (age_a < age_b)
2616  return 1;
2617  else if (age_a == age_b)
2618  return 0;
2619  else
2620  return -1;
2621 }
2622 
2623 static uint32_t now_ts_for_buf_cmp;
2624 
2625 /** Helper to sort a list of circuit_t by age of oldest item, in descending
2626  * order. */
2627 static int
2628 conns_compare_by_buffer_age_(const void **a_, const void **b_)
2629 {
2630  const connection_t *a = *a_;
2631  const connection_t *b = *b_;
2632  time_t age_a = conn_get_buffer_age(a, now_ts_for_buf_cmp);
2633  time_t age_b = conn_get_buffer_age(b, now_ts_for_buf_cmp);
2634 
2635  if (age_a < age_b)
2636  return 1;
2637  else if (age_a == age_b)
2638  return 0;
2639  else
2640  return -1;
2641 }
2642 
2643 #define FRACTION_OF_DATA_TO_RETAIN_ON_OOM 0.90
2644 
2645 /** We're out of memory for cells, having allocated <b>current_allocation</b>
2646  * bytes' worth. Kill the 'worst' circuits until we're under
2647  * FRACTION_OF_DATA_TO_RETAIN_ON_OOM of our maximum usage. */
2648 void
2649 circuits_handle_oom(size_t current_allocation)
2650 {
2651  smartlist_t *circlist;
2653  int conn_idx;
2654  size_t mem_to_recover;
2655  size_t mem_recovered=0;
2656  int n_circuits_killed=0;
2657  int n_dirconns_killed=0;
2658  uint32_t now_ts;
2659  log_notice(LD_GENERAL, "We're low on memory (cell queues total alloc:"
2660  " %"TOR_PRIuSZ" buffer total alloc: %" TOR_PRIuSZ ","
2661  " tor compress total alloc: %" TOR_PRIuSZ
2662  " (zlib: %" TOR_PRIuSZ ", zstd: %" TOR_PRIuSZ ","
2663  " lzma: %" TOR_PRIuSZ "),"
2664  " rendezvous cache total alloc: %" TOR_PRIuSZ "). Killing"
2665  " circuits withover-long queues. (This behavior is controlled by"
2666  " MaxMemInQueues.)",
2667  cell_queues_get_total_allocation(),
2668  buf_get_total_allocation(),
2673  rend_cache_get_total_allocation());
2674 
2675  {
2676  size_t mem_target = (size_t)(get_options()->MaxMemInQueues *
2677  FRACTION_OF_DATA_TO_RETAIN_ON_OOM);
2678  if (current_allocation <= mem_target)
2679  return;
2680  mem_to_recover = current_allocation - mem_target;
2681  }
2682 
2683  now_ts = monotime_coarse_get_stamp();
2684 
2685  circlist = circuit_get_global_list();
2686  SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) {
2687  circ->age_tmp = circuit_max_queued_item_age(circ, now_ts);
2688  } SMARTLIST_FOREACH_END(circ);
2689 
2690  /* This is O(n log n); there are faster algorithms we could use instead.
2691  * Let's hope this doesn't happen enough to be in the critical path. */
2693 
2694  /* Fix up the indices before we run into trouble */
2695  SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) {
2696  circ->global_circuitlist_idx = circ_sl_idx;
2697  } SMARTLIST_FOREACH_END(circ);
2698 
2699  /* Now sort the connection array ... */
2700  now_ts_for_buf_cmp = now_ts;
2702  now_ts_for_buf_cmp = 0;
2703 
2704  /* Fix up the connection array to its new order. */
2706  conn->conn_array_index = conn_sl_idx;
2707  } SMARTLIST_FOREACH_END(conn);
2708 
2709  /* Okay, now the worst circuits and connections are at the front of their
2710  * respective lists. Let's mark them, and reclaim their storage
2711  * aggressively. */
2712  conn_idx = 0;
2713  SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) {
2714  size_t n;
2715  size_t freed;
2716 
2717  /* Free storage in any non-linked directory connections that have buffered
2718  * data older than this circuit. */
2719  while (conn_idx < smartlist_len(connection_array)) {
2720  connection_t *conn = smartlist_get(connection_array, conn_idx);
2721  uint32_t conn_age = conn_get_buffer_age(conn, now_ts);
2722  if (conn_age < circ->age_tmp) {
2723  break;
2724  }
2725  if (conn->type == CONN_TYPE_DIR && conn->linked_conn == NULL) {
2726  if (!conn->marked_for_close)
2727  connection_mark_for_close(conn);
2728  mem_recovered += single_conn_free_bytes(conn);
2729 
2730  ++n_dirconns_killed;
2731 
2732  if (mem_recovered >= mem_to_recover)
2733  goto done_recovering_mem;
2734  }
2735  ++conn_idx;
2736  }
2737 
2738  /* Now, kill the circuit. */
2739  n = n_cells_in_circ_queues(circ);
2740  const size_t half_stream_alloc = circuit_alloc_in_half_streams(circ);
2741  if (! circ->marked_for_close) {
2742  circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT);
2743  }
2745  freed = marked_circuit_free_stream_bytes(circ);
2746 
2747  ++n_circuits_killed;
2748 
2749  mem_recovered += n * packed_cell_mem_cost();
2750  mem_recovered += half_stream_alloc;
2751  mem_recovered += freed;
2752 
2753  if (mem_recovered >= mem_to_recover)
2754  goto done_recovering_mem;
2755  } SMARTLIST_FOREACH_END(circ);
2756 
2757  done_recovering_mem:
2758 
2759  log_notice(LD_GENERAL, "Removed %"TOR_PRIuSZ" bytes by killing %d circuits; "
2760  "%d circuits remain alive. Also killed %d non-linked directory "
2761  "connections.",
2762  mem_recovered,
2763  n_circuits_killed,
2764  smartlist_len(circlist) - n_circuits_killed,
2765  n_dirconns_killed);
2766 }
2767 
2768 /** Verify that circuit <b>c</b> has all of its invariants
2769  * correct. Trigger an assert if anything is invalid.
2770  */
2771 MOCK_IMPL(void,
2773 {
2774  edge_connection_t *conn;
2775  const or_circuit_t *or_circ = NULL;
2776  const origin_circuit_t *origin_circ = NULL;
2777 
2778  tor_assert(c);
2780  tor_assert(c->purpose >= CIRCUIT_PURPOSE_MIN_ &&
2781  c->purpose <= CIRCUIT_PURPOSE_MAX_);
2782 
2783  if (CIRCUIT_IS_ORIGIN(c))
2784  origin_circ = CONST_TO_ORIGIN_CIRCUIT(c);
2785  else
2786  or_circ = CONST_TO_OR_CIRCUIT(c);
2787 
2788  if (c->n_chan) {
2789  tor_assert(!c->n_hop);
2790 
2791  if (c->n_circ_id) {
2792  /* We use the _impl variant here to make sure we don't fail on marked
2793  * circuits, which would not be returned by the regular function. */
2795  c->n_chan, NULL);
2796  tor_assert(c == c2);
2797  }
2798  }
2799  if (or_circ && or_circ->p_chan) {
2800  if (or_circ->p_circ_id) {
2801  /* ibid */
2802  circuit_t *c2 =
2804  or_circ->p_chan, NULL);
2805  tor_assert(c == c2);
2806  }
2807  }
2808  if (or_circ)
2809  for (conn = or_circ->n_streams; conn; conn = conn->next_stream)
2810  tor_assert(conn->base_.type == CONN_TYPE_EXIT);
2811 
2812  tor_assert(c->deliver_window >= 0);
2813  tor_assert(c->package_window >= 0);
2814  if (c->state == CIRCUIT_STATE_OPEN ||
2817  if (or_circ) {
2818  relay_crypto_assert_ok(&or_circ->crypto);
2819  }
2820  }
2821  if (c->state == CIRCUIT_STATE_CHAN_WAIT && !c->marked_for_close) {
2824  } else {
2827  }
2828  if (origin_circ && origin_circ->cpath) {
2829  cpath_assert_ok(origin_circ->cpath);
2830  }
2832  tor_assert(or_circ);
2833  if (!c->marked_for_close) {
2834  tor_assert(or_circ->rend_splice);
2835  tor_assert(or_circ->rend_splice->rend_splice == or_circ);
2836  }
2837  tor_assert(or_circ->rend_splice != or_circ);
2838  } else {
2839  tor_assert(!or_circ || !or_circ->rend_splice);
2840  }
2841 }
log_fn
#define log_fn(severity, domain, args,...)
Definition: log.h:287
crypt_path_reference_t
Definition: crypt_path_reference_st.h:19
CELL_MAX_NETWORK_SIZE
#define CELL_MAX_NETWORK_SIZE
Definition: or.h:580
circuit_unlink_all_from_channel
void circuit_unlink_all_from_channel(channel_t *chan, int reason)
Definition: circuitlist.c:1605
channel_note_destroy_not_pending
void channel_note_destroy_not_pending(channel_t *chan, circid_t id)
Definition: circuitlist.c:431
DOWNCAST
#define DOWNCAST(to, ptr)
Definition: or.h:109
tor_zstd_get_total_allocation
size_t tor_zstd_get_total_allocation(void)
Definition: compress_zstd.c:500
circuit_get_by_circid_channel
circuit_t * circuit_get_by_circid_channel(circid_t circ_id, channel_t *chan)
Definition: circuitlist.c:1527
tor_free
#define tor_free(p)
Definition: malloc.h:52
half_edge_t
Definition: half_edge_st.h:22
get_circuit_build_times_mutable
circuit_build_times_t * get_circuit_build_times_mutable(void)
Definition: circuitstats.c:86
circuit_remove_from_origin_circuit_list
static void circuit_remove_from_origin_circuit_list(origin_circuit_t *origin_circ)
Definition: circuitlist.c:631
circuits_compare_by_oldest_queued_item_
static int circuits_compare_by_oldest_queued_item_(const void **a_, const void **b_)
Definition: circuitlist.c:2608
connection_edge.h
Header file for connection_edge.c.
testing_cell_stats_entry_t
Definition: or.h:937
origin_circuit_t::half_streams
smartlist_t * half_streams
Definition: origin_circuit_st.h:88
tor_free_
void tor_free_(void *mem)
Definition: malloc.c:227
tor_addr_family
static sa_family_t tor_addr_family(const tor_addr_t *a)
Definition: address.h:187
CIRCUIT_PURPOSE_REND_ESTABLISHED
#define CIRCUIT_PURPOSE_REND_ESTABLISHED
Definition: circuitlist.h:47
CIRCUIT_PURPOSE_IS_ORIGIN
#define CIRCUIT_PURPOSE_IS_ORIGIN(p)
Definition: circuitlist.h:139
ORIGIN_CIRCUIT_MAGIC
#define ORIGIN_CIRCUIT_MAGIC
Definition: circuit_st.h:30
channel_t::identity_digest
char identity_digest[DIGEST_LEN]
Definition: channel.h:378
CIRCUIT_STATE_OPEN
#define CIRCUIT_STATE_OPEN
Definition: circuitlist.h:32
circuit_t::purpose
uint8_t purpose
Definition: circuit_st.h:111
circuit_t::marked_for_close
uint16_t marked_for_close
Definition: circuit_st.h:189
circuit_t::timestamp_dirty
time_t timestamp_dirty
Definition: circuit_st.h:187
crypt_path_reference_st.h
reference-counting structure for crypt_path_t
compress.h
Headers for compress.c.
circuit_max_queued_data_age
STATIC uint32_t circuit_max_queued_data_age(const circuit_t *c, uint32_t now)
Definition: circuitlist.c:2580
hs_ident.h
Header file containing circuit and connection identifier data for the whole HS subsytem.
memwipe
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:55
packed_cell_mem_cost
size_t packed_cell_mem_cost(void)
Definition: relay.c:2678
tor_addr_t
Definition: address.h:69
CIRCUIT_PURPOSE_C_GENERAL
#define CIRCUIT_PURPOSE_C_GENERAL
Definition: circuitlist.h:72
circuit_get_next_intro_circ
origin_circuit_t * circuit_get_next_intro_circ(const origin_circuit_t *start, bool want_client_circ)
Definition: circuitlist.c:1734
approx_time
time_t approx_time(void)
Definition: approx_time.c:32
circuit_t::n_chan_create_cell
struct create_cell_t * n_chan_create_cell
Definition: circuit_st.h:153
origin_circuit_t::prepend_policy
smartlist_t * prepend_policy
Definition: origin_circuit_st.h:293
MOCK_IMPL
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
edge_connection_t::edge_has_sent_end
unsigned int edge_has_sent_end
Definition: edge_connection_st.h:67
circuit_get_global_list
smartlist_t * circuit_get_global_list(void)
Definition: circuitlist.c:696
CIRCUIT_PURPOSE_INTRO_POINT
#define CIRCUIT_PURPOSE_INTRO_POINT
Definition: circuitlist.h:42
origin_circuit_t::isolation_values_set
unsigned int isolation_values_set
Definition: origin_circuit_st.h:247
marked_circuit_free_cells
static void marked_circuit_free_cells(circuit_t *circ)
Definition: circuitlist.c:2416
any_opened_circs_cached_val
static int any_opened_circs_cached_val
Definition: circuitlist.c:148
routerset_contains_extendinfo
int routerset_contains_extendinfo(const routerset_t *set, const extend_info_t *ei)
Definition: routerset.c:307
CIRCLAUNCH_NEED_CAPACITY
#define CIRCLAUNCH_NEED_CAPACITY
Definition: circuituse.h:43
tor_assert
#define tor_assert(expr)
Definition: util_bug.h:102
ocirc_cevent_msg_t::reason
int reason
Definition: ocirc_event.h:60
ocirc_state_msg_t::gid
uint32_t gid
Definition: ocirc_event.h:29
CONN_TYPE_DIR
#define CONN_TYPE_DIR
Definition: connection.h:55
LD_BUG
#define LD_BUG
Definition: log.h:86
circuit_alloc_in_half_streams
static size_t circuit_alloc_in_half_streams(const circuit_t *c)
Definition: circuitlist.c:2494
circuit_set_p_circid_chan
void circuit_set_p_circid_chan(or_circuit_t *or_circ, circid_t id, channel_t *chan)
Definition: circuitlist.c:453
cpath_build_state_st.h
Circuit-build-stse structure.
ocirc_state_msg_t
Definition: ocirc_event.h:28
DEFAULT_ROUTE_LEN
#define DEFAULT_ROUTE_LEN
Definition: or.h:1019
CIRCUIT_PURPOSE_PATH_BIAS_TESTING
#define CIRCUIT_PURPOSE_PATH_BIAS_TESTING
Definition: circuitlist.h:122
circuituse.h
Header file for circuituse.c.
tor_compress_state_size
size_t tor_compress_state_size(const tor_compress_state_t *state)
Definition: compress.c:639
channel.h
Header file for channel.c.
bwhist.h
Header for feature/stats/bwhist.c.
MAX_RELAY_EARLY_CELLS_PER_CIRCUIT
#define MAX_RELAY_EARLY_CELLS_PER_CIRCUIT
Definition: or.h:954
compress_lzma.h
Header for compress_lzma.c.
bwhist_note_bytes_written
void bwhist_note_bytes_written(uint64_t num_bytes, time_t when, bool ipv6)
Definition: bwhist.c:164
LD_GENERAL
#define LD_GENERAL
Definition: log.h:62
origin_circuit_t::next_stream_id
streamid_t next_stream_id
Definition: origin_circuit_st.h:231
control_event_circuit_status
int control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, int reason_code)
Definition: control_events.c:631
tor_fragile_assert
#define tor_fragile_assert()
Definition: util_bug.h:259
crypt_path_t::state
uint8_t state
Definition: crypt_path_st.h:68
circuit_clear_cpath
void circuit_clear_cpath(origin_circuit_t *circ)
Definition: circuitlist.c:1283
circuit_get_by_circid_channel_even_if_marked
circuit_t * circuit_get_by_circid_channel_even_if_marked(circid_t circ_id, channel_t *chan)
Definition: circuitlist.c:1542
cpath_build_state_t::is_internal
unsigned int is_internal
Definition: cpath_build_state_st.h:26
tor_reallocarray_
void * tor_reallocarray_(void *ptr, size_t sz1, size_t sz2)
Definition: malloc.c:146
route_len_for_purpose
int route_len_for_purpose(uint8_t purpose, extend_info_t *exit_ei)
Definition: circuitbuild.c:1341
node_get_by_id
const node_t * node_get_by_id(const char *identity_digest)
Definition: nodelist.c:223
smartlist_add
void smartlist_add(smartlist_t *sl, void *element)
Definition: smartlist_core.c:117
conns_compare_by_buffer_age_
static int conns_compare_by_buffer_age_(const void **a_, const void **b_)
Definition: circuitlist.c:2628
entry_guard_cancel
void entry_guard_cancel(circuit_guard_state_t **guard_state_p)
Definition: entrynodes.c:2513
get_guard_selection_info
guard_selection_t * get_guard_selection_info(void)
Definition: entrynodes.c:307
circuit_get_next_by_pk_and_purpose
origin_circuit_t * circuit_get_next_by_pk_and_purpose(origin_circuit_t *start, const uint8_t *digest, uint8_t purpose)
Definition: circuitlist.c:1820
CIRCUIT_PURPOSE_C_REND_JOINED
#define CIRCUIT_PURPOSE_C_REND_JOINED
Definition: circuitlist.h:90
CIRCUIT_STATE_ONIONSKIN_PENDING
#define CIRCUIT_STATE_ONIONSKIN_PENDING
Definition: circuitlist.h:23
circuit_t::testing_cell_stats
smartlist_t * testing_cell_stats
Definition: circuit_st.h:212
torint.h
Integer definitions used throughout Tor.
END_CIRC_REASON_FLAG_REMOTE
#define END_CIRC_REASON_FLAG_REMOTE
Definition: or.h:329
circuit_free_
STATIC void circuit_free_(circuit_t *circ)
Definition: circuitlist.c:1128
circuit_t::marked_for_close_reason
int marked_for_close_reason
Definition: circuit_st.h:197
circuit_t::n_chan
channel_t * n_chan
Definition: circuit_st.h:69
circuits_handle_oom
void circuits_handle_oom(size_t current_allocation)
Definition: circuitlist.c:2649
circuit_t::marked_for_close_file
const char * marked_for_close_file
Definition: circuit_st.h:192
edge_connection_t::end_reason
uint16_t end_reason
Definition: edge_connection_st.h:54
circuit_dump_conn_details
static void circuit_dump_conn_details(int severity, circuit_t *circ, int conn_array_index, const char *type, circid_t this_circid, circid_t other_circid)
Definition: circuitlist.c:1373
smartlist_new
smartlist_t * smartlist_new(void)
Definition: smartlist_core.c:26
crypt_path.h
Header file for crypt_path.c.
circuit_state_publish
static void circuit_state_publish(const circuit_t *circ)
Definition: circuitlist.c:525
circuit_dump_by_conn
void circuit_dump_by_conn(connection_t *conn, int severity)
Definition: circuitlist.c:1394
tor_snprintf
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition: printf.c:27
CIRCUIT_IS_ORIGIN
#define CIRCUIT_IS_ORIGIN(c)
Definition: circuitlist.h:146
channel_t::reason_for_closing
enum channel_t::@0 reason_for_closing
crypt_path_t
Definition: crypt_path_st.h:47
onion_queue.h
Header file for onion_queue.c.
marked_circuit_free_stream_bytes
static size_t marked_circuit_free_stream_bytes(circuit_t *c)
Definition: circuitlist.c:2471
circuit_channel_direction_t
circuit_channel_direction_t
Definition: or.h:495
circuitpadding.h
Header file for circuitpadding.c.
CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT
#define CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT
Definition: circuitlist.h:78
SMARTLIST_FOREACH
#define SMARTLIST_FOREACH(sl, type, var, cmd)
Definition: smartlist_foreach.h:112
crypto_rand_int
int crypto_rand_int(unsigned int max)
Definition: crypto_rand_numeric.c:52
circuit_t::global_circuitlist_idx
int global_circuitlist_idx
Definition: circuit_st.h:207
channel_t::cmux
circuitmux_t * cmux
Definition: channel.h:397
cell_queue_init
void cell_queue_init(cell_queue_t *queue)
Definition: relay.c:2577
or_circuit_t::p_chan_cells
cell_queue_t p_chan_cells
Definition: or_circuit_st.h:35
networkstatus.h
Header file for networkstatus.c.
origin_circuit_t::global_identifier
uint32_t global_identifier
Definition: origin_circuit_st.h:240
onion_fast.h
Header file for onion_fast.c.
END_CIRC_AT_ORIGIN
#define END_CIRC_AT_ORIGIN
Definition: or.h:306
circuit_get_streams_max_data_age
static uint32_t circuit_get_streams_max_data_age(const edge_connection_t *stream, uint32_t now)
Definition: circuitlist.c:2559
CIRCUIT_PURPOSE_REND_POINT_WAITING
#define CIRCUIT_PURPOSE_REND_POINT_WAITING
Definition: circuitlist.h:45
circuit_max_queued_item_age
STATIC uint32_t circuit_max_queued_item_age(const circuit_t *c, uint32_t now)
Definition: circuitlist.c:2595
CIRCUIT_PURPOSE_C_ESTABLISH_REND
#define CIRCUIT_PURPOSE_C_ESTABLISH_REND
Definition: circuitlist.h:83
CIRCUIT_PURPOSE_S_HSDIR_POST
#define CIRCUIT_PURPOSE_S_HSDIR_POST
Definition: circuitlist.h:114
rep_hist_buffer_stats_add_circ
void rep_hist_buffer_stats_add_circ(circuit_t *circ, time_t end_of_interval)
Definition: rephist.c:1290
tor_memeq
int tor_memeq(const void *a, const void *b, size_t sz)
Definition: di_ops.c:107
cell_queue_t::n
int n
Definition: cell_queue_st.h:31
CIRCUIT_PURPOSE_OR
#define CIRCUIT_PURPOSE_OR
Definition: circuitlist.h:39
crypto_util.h
Common functions for cryptographic routines.
CIRCUIT_PURPOSE_CONTROLLER
#define CIRCUIT_PURPOSE_CONTROLLER
Definition: circuitlist.h:120
circuit_can_be_cannibalized_for_v3_rp
static int circuit_can_be_cannibalized_for_v3_rp(const origin_circuit_t *circ)
Definition: circuitlist.c:1857
LD_CIRC
#define LD_CIRC
Definition: log.h:82
circuit_status_event_t
circuit_status_event_t
Definition: ocirc_event.h:19
global_origin_circuit_list
static smartlist_t * global_origin_circuit_list
Definition: circuitlist.c:125
predicted_ports_prediction_time_remaining
int predicted_ports_prediction_time_remaining(time_t now)
Definition: predict_ports.c:54
channel_mark_circid_usable
void channel_mark_circid_usable(channel_t *chan, circid_t id)
Definition: circuitlist.c:388
or_circuit_t::p_chan
channel_t * p_chan
Definition: or_circuit_st.h:37
hs_circ_cleanup_on_free
void hs_circ_cleanup_on_free(circuit_t *circ)
Definition: hs_circuit.c:1327
CELL_DIRECTION_OUT
@ CELL_DIRECTION_OUT
Definition: or.h:485
circuitlist.h
Header file for circuitlist.c.
mainloop.h
Header file for mainloop.c.
OR_CIRCUIT_MAGIC
#define OR_CIRCUIT_MAGIC
Definition: circuit_st.h:32
circuit_log_path
void circuit_log_path(int severity, unsigned int domain, origin_circuit_t *circ)
Definition: circuitbuild.c:352
DIGEST_LEN
#define DIGEST_LEN
Definition: digest_sizes.h:20
HT_HEAD
static HT_HEAD(HT_PROTOTYPE(chan_circid_map, HT_PROTOTYPE(chan_circid_circuit_map_t)
Definition: circuitlist.c:218
cpath_assert_ok
void cpath_assert_ok(const crypt_path_t *cp)
Definition: crypt_path.c:84
rend_cmp_service_ids
int rend_cmp_service_ids(const char *one, const char *two)
Definition: rendcommon.c:49
circuit_t::marked_for_close_orig_reason
int marked_for_close_orig_reason
Definition: circuit_st.h:201
TR_SUBSYS
#define TR_SUBSYS(name)
Definition: events.h:45
channel_describe_peer
const char * channel_describe_peer(channel_t *chan)
Definition: channel.c:2804
cpath_free
void cpath_free(crypt_path_t *victim)
Definition: crypt_path.c:163
circuit_find_to_cannibalize
origin_circuit_t * circuit_find_to_cannibalize(uint8_t purpose_to_produce, extend_info_t *info, int flags)
Definition: circuitlist.c:1913
cpath_build_state_t::chosen_exit
extend_info_t * chosen_exit
Definition: cpath_build_state_st.h:20
packed_cell_t
Definition: cell_queue_st.h:18
half_edge_st.h
Half-open connection structure.
or_circuit_t::resolving_streams
edge_connection_t * resolving_streams
Definition: or_circuit_st.h:42
channel_mark_circid_unusable
void channel_mark_circid_unusable(channel_t *chan, circid_t id)
Definition: circuitlist.c:355
init_circuit_base
static void init_circuit_base(circuit_t *circ)
Definition: circuitlist.c:991
crypt_path_reference_t::refcount
unsigned int refcount
Definition: crypt_path_reference_st.h:21
circpad_marked_circuit_for_padding
int circpad_marked_circuit_for_padding(circuit_t *circ, int reason)
Definition: circuitpadding.c:174
conn_get_buffer_age
static uint32_t conn_get_buffer_age(const connection_t *conn, uint32_t now_ts)
Definition: circuitlist.c:2539
or_circuit_t::remaining_relay_early_cells
unsigned int remaining_relay_early_cells
Definition: or_circuit_st.h:57
circuit_t::deliver_window
int deliver_window
Definition: circuit_st.h:121
circuit_cache_opened_circuit_state
void circuit_cache_opened_circuit_state(int circuits_are_opened)
Definition: circuitlist.c:746
connection_t::outbuf
struct buf_t * outbuf
Definition: connection_st.h:102
tor_memneq
#define tor_memneq(a, b, sz)
Definition: di_ops.h:21
circuit_t::age_tmp
uint32_t age_tmp
Definition: circuit_st.h:150
entrynodes.h
Header file for circuitbuild.c.
circuit_get_by_global_id
origin_circuit_t * circuit_get_by_global_id(uint32_t id)
Definition: circuitlist.c:1435
circuitmux_detach_circuit
void circuitmux_detach_circuit(circuitmux_t *cmux, circuit_t *circ)
Definition: circuitmux.c:851
get_circuit_purpose_needed_to_cannibalize
static uint8_t get_circuit_purpose_needed_to_cannibalize(uint8_t purpose)
Definition: circuitlist.c:1882
entry_guards_upgrade_waiting_circuits
int entry_guards_upgrade_waiting_circuits(guard_selection_t *gs, const smartlist_t *all_circuits_in, smartlist_t *newly_complete_out)
Definition: entrynodes.c:2638
node_t
Definition: node_st.h:34
origin_circuit_t
Definition: origin_circuit_st.h:79
mainloop_schedule_postloop_cleanup
void mainloop_schedule_postloop_cleanup(void)
Definition: mainloop.c:1634
circuit_any_opened_circuits
int circuit_any_opened_circuits(void)
Definition: circuitlist.c:720
chan_circid_circuit_map_t
Definition: circuitlist.c:182
circuit_get_global_origin_circuit_list
smartlist_t * circuit_get_global_origin_circuit_list(void)
Definition: circuitlist.c:705
global_circuitlist
static smartlist_t * global_circuitlist
Definition: circuitlist.c:121
CIRCUIT_IS_ORCIRC
#define CIRCUIT_IS_ORCIRC(c)
Definition: circuitlist.h:153
crypto_dh.h
Headers for crypto_dh.c.
CIRCUIT_PURPOSE_C_CIRCUIT_PADDING
#define CIRCUIT_PURPOSE_C_CIRCUIT_PADDING
Definition: circuitlist.h:97
CIRCLAUNCH_ONEHOP_TUNNEL
#define CIRCLAUNCH_ONEHOP_TUNNEL
Definition: circuituse.h:39
cpath_build_state_t::onehop_tunnel
unsigned int onehop_tunnel
Definition: cpath_build_state_st.h:32
marked_circuit_streams_free_bytes
static size_t marked_circuit_streams_free_bytes(edge_connection_t *stream)
Definition: circuitlist.c:2455
directory.h
Header file for directory.c.
tor_digest_is_zero
int tor_digest_is_zero(const char *digest)
Definition: util_string.c:96
ocirc_state_msg_t::state
int state
Definition: ocirc_event.h:30
CIRCUIT_PURPOSE_HS_VANGUARDS
#define CIRCUIT_PURPOSE_HS_VANGUARDS
Definition: circuitlist.h:130
or_options_t::ExcludeNodes
struct routerset_t * ExcludeNodes
Definition: or_options_st.h:102
REND_COOKIE_LEN
#define REND_COOKIE_LEN
Definition: or.h:400
origin_circuit_t::circuit_idle_timeout
int circuit_idle_timeout
Definition: origin_circuit_st.h:299
or_circuit_t::n_streams
edge_connection_t * n_streams
Definition: or_circuit_st.h:39
circuit_add_to_origin_circuit_list
static void circuit_add_to_origin_circuit_list(origin_circuit_t *origin_circ)
Definition: circuitlist.c:652
connection_t::inbuf
struct buf_t * inbuf
Definition: connection_st.h:101
CIRCUIT_STATE_CHAN_WAIT
#define CIRCUIT_STATE_CHAN_WAIT
Definition: circuitlist.h:26
circuit_t::sendme_last_digests
smartlist_t * sendme_last_digests
Definition: circuit_st.h:147
circuits_pending_chans
static smartlist_t * circuits_pending_chans
Definition: circuitlist.c:128
smartlist_del
void smartlist_del(smartlist_t *sl, int idx)
Definition: smartlist_core.c:214
circuit_t::timestamp_began
struct timeval timestamp_began
Definition: circuit_st.h:165
CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT
#define CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT
Definition: circuitlist.h:95
get_connection_array
smartlist_t * get_connection_array(void)
Definition: mainloop.c:453
nodes_in_same_family
int nodes_in_same_family(const node_t *node1, const node_t *node2)
Definition: nodelist.c:2114
circuit_about_to_free_atexit
static void circuit_about_to_free_atexit(circuit_t *circ)
Definition: circuitlist.c:2303
connection_t::marked_for_close
uint16_t marked_for_close
Definition: connection_st.h:149
connection_t::conn_array_index
int conn_array_index
Definition: connection_st.h:97
circuit_t
Definition: circuit_st.h:61
nodelist.h
Header file for nodelist.c.
routerlist.h
Header file for routerlist.c.
routerset.h
Header file for routerset.c.
ocirc_cevent_msg_t::evtype
int evtype
Definition: ocirc_event.h:59
compress_zstd.h
Header for compress_zstd.c.
circuit_purpose_to_controller_string
const char * circuit_purpose_to_controller_string(uint8_t purpose)
Definition: circuitlist.c:784
circpad_circuit_free_all_machineinfos
void circpad_circuit_free_all_machineinfos(circuit_t *circ)
Definition: circuitpadding.c:304
predict_ports.h
Header file for predict_ports.c.
or_circuit_t::rend_splice
struct or_circuit_t * rend_splice
Definition: or_circuit_st.h:50
ocirc_cevent_msg_t::gid
uint32_t gid
Definition: ocirc_event.h:58
get_circuit_build_times
const circuit_build_times_t * get_circuit_build_times(void)
Definition: circuitstats.c:79
tor_gettimeofday
void tor_gettimeofday(struct timeval *timeval)
Definition: tor_gettimeofday.c:42
or_circuit_new
or_circuit_t * or_circuit_new(circid_t p_circ_id, channel_t *p_chan)
Definition: circuitlist.c:1093
circuitstats.h
Header file for circuitstats.c.
circuit_t::timestamp_created
struct timeval timestamp_created
Definition: circuit_st.h:168
circuit_purpose_to_controller_hs_state_string
const char * circuit_purpose_to_controller_hs_state_string(uint8_t purpose)
Definition: circuitlist.c:845
circuits_pending_other_guards
static smartlist_t * circuits_pending_other_guards
Definition: circuitlist.c:132
extendinfo.h
Header for core/or/extendinfo.c.
buffers.h
Header file for buffers.c.
DEAD_CIRCUIT_MAGIC
#define DEAD_CIRCUIT_MAGIC
Definition: circuit_st.h:36
circuit_t::package_window
int package_window
Definition: circuit_st.h:116
channel_t
Definition: channel.h:181
rend_data_t::rend_cookie
char rend_cookie[REND_COOKIE_LEN]
Definition: or.h:428
circuit_t::p_delete_pending
unsigned int p_delete_pending
Definition: circuit_st.h:98
connection_t
Definition: connection_st.h:45
entry_guard_could_succeed
int entry_guard_could_succeed(const circuit_guard_state_t *guard_state)
Definition: entrynodes.c:3575
connection_t::type
unsigned int type
Definition: connection_st.h:50
circuit_t::n_circ_id
circid_t n_circ_id
Definition: circuit_st.h:78
smartlist_sort_pointers
void smartlist_sort_pointers(smartlist_t *sl)
Definition: smartlist.c:594
ocirc_cevent_msg_t
Definition: ocirc_event.h:57
CIRCWINDOW_START
#define CIRCWINDOW_START
Definition: or.h:502
origin_circuit_t::guard_state
struct circuit_guard_state_t * guard_state
Definition: origin_circuit_st.h:141
crypto_rand.h
Common functions for using (pseudo-)random number generators.
connection_free_
void connection_free_(connection_t *conn)
Definition: connection.c:950
relay_crypto_assert_ok
void relay_crypto_assert_ok(const relay_crypto_t *crypto)
Definition: relay_crypto.c:367
edge_connection_t::on_circuit
struct circuit_t * on_circuit
Definition: edge_connection_st.h:30
control_events.h
Header file for control_events.c.
circuit_synchronize_written_or_bandwidth
void circuit_synchronize_written_or_bandwidth(const circuit_t *c, circuit_channel_direction_t dir)
Definition: circuitlist.c:2150
get_options
const or_options_t * get_options(void)
Definition: config.c:928
DFLT_IDLE_TIMEOUT_WHILE_LEARNING
#define DFLT_IDLE_TIMEOUT_WHILE_LEARNING
Definition: circuitlist.c:1012
compress_zlib.h
Header for compress_zlib.c.
origin_circuit_t::build_state
cpath_build_state_t * build_state
Definition: origin_circuit_st.h:123
circuit_count_pending_on_channel
int circuit_count_pending_on_channel(channel_t *chan)
Definition: circuitlist.c:611
channel_note_destroy_pending
void channel_note_destroy_pending(channel_t *chan, circid_t id)
Definition: circuitlist.c:411
connection_array
STATIC smartlist_t * connection_array
Definition: mainloop.c:166
circuitbuild.h
Header file for circuitbuild.c.
CIRCUIT_PURPOSE_S_REND_JOINED
#define CIRCUIT_PURPOSE_S_REND_JOINED
Definition: circuitlist.h:112
origin_circuit_t::remaining_relay_early_cells
unsigned int remaining_relay_early_cells
Definition: origin_circuit_st.h:149
circuit_any_opened_circuits_cached
int circuit_any_opened_circuits_cached(void)
Definition: circuitlist.c:757
smartlist_clear
void smartlist_clear(smartlist_t *sl)
Definition: smartlist_core.c:50
CIRCLAUNCH_IS_INTERNAL
#define CIRCLAUNCH_IS_INTERNAL
Definition: circuituse.h:46
circuit_t::n_delete_pending
unsigned int n_delete_pending
Definition: circuit_st.h:101
extend_info_st.h
Extend-info structure.
circuit_id_in_use_on_channel
int circuit_id_in_use_on_channel(circid_t circ_id, channel_t *chan)
Definition: circuitlist.c:1556
CIRCUIT_PURPOSE_C_INTRODUCE_ACKED
#define CIRCUIT_PURPOSE_C_INTRODUCE_ACKED
Definition: circuitlist.h:81
buf_allocation
size_t buf_allocation(const buf_t *buf)
Definition: buffers.c:401
circuit_t::n_chan_cells
cell_queue_t n_chan_cells
Definition: circuit_st.h:81
edge_connection_st.h
Edge-connection structure.
CIRCLAUNCH_NEED_UPTIME
#define CIRCLAUNCH_NEED_UPTIME
Definition: circuituse.h:41
pathbias_check_close
int pathbias_check_close(origin_circuit_t *ocirc, int reason)
Definition: circpathbias.c:1015
origin_circuit_t::cpath
crypt_path_t * cpath
Definition: origin_circuit_st.h:129
channel_unlink_all_circuits
void channel_unlink_all_circuits(channel_t *chan, smartlist_t *circuits_out)
Definition: relay.c:2801
circuit_find_circuits_to_upgrade_from_guard_wait
smartlist_t * circuit_find_circuits_to_upgrade_from_guard_wait(void)
Definition: circuitlist.c:2023
cpath_build_state_t::need_capacity
unsigned int need_capacity
Definition: cpath_build_state_st.h:24
circuit_build_times_needs_circuits
int circuit_build_times_needs_circuits(const circuit_build_times_t *cbt)
Definition: circuitstats.c:1384
CIRCUIT_PURPOSE_C_HSDIR_GET
#define CIRCUIT_PURPOSE_C_HSDIR_GET
Definition: circuitlist.h:92
cpath_ref_decref
static void cpath_ref_decref(crypt_path_reference_t *cpath_ref)
Definition: circuitlist.c:1359
TO_ORIGIN_CIRCUIT
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:168
relay.h
Header file for relay.c.
CIRCUIT_PURPOSE_C_REND_READY
#define CIRCUIT_PURPOSE_C_REND_READY
Definition: circuitlist.h:85
circuit_get_cpath_opened_len
int circuit_get_cpath_opened_len(const origin_circuit_t *circ)
Definition: circuitlist.c:2067
connection.h
Header file for connection.c.
connection_t::linked_conn
struct connection_t * linked_conn
Definition: connection_st.h:168
channeltls.h
Header file for channeltls.c.
circuit_about_to_free
static void circuit_about_to_free(circuit_t *circ)
Definition: circuitlist.c:2328
onion_pending_remove
void onion_pending_remove(or_circuit_t *circ)
Definition: onion_queue.c:310
assert_circuit_ok
void assert_circuit_ok(const circuit_t *c)
Definition: circuitlist.c:2772
extend_info_t::identity_digest
char identity_digest[DIGEST_LEN]
Definition: extend_info_st.h:31
cell_queue_clear
void cell_queue_clear(cell_queue_t *queue)
Definition: relay.c:2585
circuit_mark_all_unused_circs
void circuit_mark_all_unused_circs(void)
Definition: circuitlist.c:2103
or_options_t::MaxMemInQueues
uint64_t MaxMemInQueues
Definition: or_options_st.h:179
CIRCUIT_PURPOSE_S_CONNECT_REND
#define CIRCUIT_PURPOSE_S_CONNECT_REND
Definition: circuitlist.h:109
cpath_build_state_t::need_uptime
unsigned int need_uptime
Definition: cpath_build_state_st.h:22
circuit_set_n_circid_chan
void circuit_set_n_circid_chan(circuit_t *circ, circid_t id, channel_t *chan)
Definition: circuitlist.c:476
buf_get_oldest_chunk_timestamp
uint32_t buf_get_oldest_chunk_timestamp(const buf_t *buf, uint32_t now)
Definition: buffers.c:506
circuit_build_failed
void circuit_build_failed(origin_circuit_t *circ)
Definition: circuituse.c:1785
circuit_close_all_marked
void circuit_close_all_marked(void)
Definition: circuitlist.c:664
monotime_coarse_get_stamp
uint32_t monotime_coarse_get_stamp(void)
Definition: compat_time.c:844
CONN_TYPE_EXIT
#define CONN_TYPE_EXIT
Definition: connection.h:46
circuit_reset_sendme_randomness
void circuit_reset_sendme_randomness(circuit_t *circ)
Definition: relay.c:2062
circuit_should_use_vanguards
int circuit_should_use_vanguards(uint8_t purpose)
Definition: circuituse.c:2044
CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
Definition: circuitlist.h:103
node_supports_v3_rendezvous_point
bool node_supports_v3_rendezvous_point(const node_t *node)
Definition: nodelist.c:1190
CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED
#define CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED
Definition: circuitlist.h:88
circuit_get_by_circid_channel_impl
static circuit_t * circuit_get_by_circid_channel_impl(circid_t circ_id, channel_t *chan, int *found_entry_out)
Definition: circuitlist.c:1459
origin_circuit_t::rend_data
rend_data_t * rend_data
Definition: origin_circuit_st.h:132
crypt_path_t::extend_info
extend_info_t * extend_info
Definition: crypt_path_st.h:61
circuit_get_ready_rend_circ_by_rend_data
origin_circuit_t * circuit_get_ready_rend_circ_by_rend_data(const rend_data_t *rend_data)
Definition: circuitlist.c:1697
CIRCUIT_PURPOSE_S_INTRO
#define CIRCUIT_PURPOSE_S_INTRO
Definition: circuitlist.h:106
SMARTLIST_FOREACH_BEGIN
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
Definition: smartlist_foreach.h:78
circuit_id_when_marked_unusable_on_channel
time_t circuit_id_when_marked_unusable_on_channel(circid_t circ_id, channel_t *chan)
Definition: circuitlist.c:1569
relay_crypto.h
Header for relay_crypto.c.
SMARTLIST_DEL_CURRENT
#define SMARTLIST_DEL_CURRENT(sl, var)
Definition: smartlist_foreach.h:120
circuitmux_attach_circuit
void circuitmux_attach_circuit(circuitmux_t *cmux, circuit_t *circ, cell_direction_t direction)
Definition: circuitmux.c:730
CIRCUIT_PURPOSE_TESTING
#define CIRCUIT_PURPOSE_TESTING
Definition: circuitlist.h:118
circuit_mark_all_dirty_circs_as_unusable
void circuit_mark_all_dirty_circs_as_unusable(void)
Definition: circuitlist.c:2122
dir_connection_st.h
Client/server directory connection structure.
onion_crypto.h
Header file for onion_crypto.c.
LOG_WARN
#define LOG_WARN
Definition: log.h:53
CIRCLAUNCH_IS_V3_RP
#define CIRCLAUNCH_IS_V3_RP
Definition: circuituse.h:49
edge_connection_t
Definition: edge_connection_st.h:21
buf_clear
void buf_clear(buf_t *buf)
Definition: buffers.c:381
channel_matches_extend_info
int channel_matches_extend_info(channel_t *chan, extend_info_t *extend_info)
Definition: channel.c:3259
rend_data_t
Definition: or.h:419
n_cells_in_circ_queues
STATIC size_t n_cells_in_circ_queues(const circuit_t *c)
Definition: circuitlist.c:2482
or_circuit_t::workqueue_entry
struct workqueue_entry_t * workqueue_entry
Definition: or_circuit_st.h:30
policies.h
Header file for policies.c.
TO_DIR_CONN
dir_connection_t * TO_DIR_CONN(connection_t *c)
Definition: directory.c:89
HT_PROTOTYPE
HT_PROTOTYPE(hs_circuitmap_ht, circuit_t, hs_circuitmap_node, hs_circuit_hash_token, hs_circuits_have_same_token)
crypt_path_t::next
struct crypt_path_t * next
Definition: crypt_path_st.h:72
hs_circuitmap.h
Header file for hs_circuitmap.c.
or_circuit_t
Definition: or_circuit_st.h:21
or_circuit_t::p_circ_id
circid_t p_circ_id
Definition: or_circuit_st.h:33
rend_data_get_address
const char * rend_data_get_address(const rend_data_t *rend_data)
Definition: hs_common.c:529
circuit_set_state
void circuit_set_state(circuit_t *circ, uint8_t state)
Definition: circuitlist.c:545
config.h
Header file for config.c.
ocirc_cevent_msg_t::onehop
bool onehop
Definition: ocirc_event.h:61
tor_compress_get_total_allocation
size_t tor_compress_get_total_allocation(void)
Definition: compress.c:458
cpath_build_state_t::desired_path_len
int desired_path_len
Definition: cpath_build_state_st.h:18
crypt_path_reference_t::cpath
crypt_path_t * cpath
Definition: crypt_path_reference_st.h:24
circuit_state_to_string
const char * circuit_state_to_string(int state)
Definition: circuitlist.c:764
circuit_free_all
void circuit_free_all(void)
Definition: circuitlist.c:1307
smartlist_contains
int smartlist_contains(const smartlist_t *sl, const void *element)
Definition: smartlist_core.c:201
origin_circuit_t::global_origin_circuit_list_idx
int global_origin_circuit_list_idx
Definition: origin_circuit_st.h:145
channel_t::global_identifier
uint64_t global_identifier
Definition: channel.h:197
tor_log
void tor_log(int severity, log_domain_mask_t domain, const char *format,...)
Definition: log.c:628
circuit_get_next_service_rp_circ
origin_circuit_t * circuit_get_next_service_rp_circ(origin_circuit_t *start)
Definition: circuitlist.c:1786
mark_circuit_unusable_for_new_conns
void mark_circuit_unusable_for_new_conns(origin_circuit_t *circ)
Definition: circuituse.c:3163
origin_circuit_t::hs_ident
struct hs_ident_circuit_t * hs_ident
Definition: origin_circuit_st.h:136
CIRCUIT_STATE_GUARD_WAIT
#define CIRCUIT_STATE_GUARD_WAIT
Definition: circuitlist.h:30
circuit_get_cpath_len
int circuit_get_cpath_len(origin_circuit_t *circ)
Definition: circuitlist.c:2051
channel_t::timestamp_last_had_circuits
time_t timestamp_last_had_circuits
Definition: channel.h:448
origin_circuit_t::p_streams
edge_connection_t * p_streams
Definition: origin_circuit_st.h:84
channel_t::num_n_circuits
unsigned int num_n_circuits
Definition: channel.h:410
TO_CIRCUIT
#define TO_CIRCUIT(x)
Definition: or.h:965
circuit_mark_for_close_
void circuit_mark_for_close_(circuit_t *circ, int reason, int line, const char *file)
Definition: circuitlist.c:2213
edge_connection_t::next_stream
struct edge_connection_t * next_stream
Definition: edge_connection_st.h:24
or_options_t
Definition: or_options_st.h:45
circuit_t::n_hop
extend_info_t * n_hop
Definition: circuit_st.h:87
TO_CONN
#define TO_CONN(c)
Definition: or.h:736
STATIC
#define STATIC
Definition: testsupport.h:32
channel_get_addr_if_possible
int channel_get_addr_if_possible(const channel_t *chan, tor_addr_t *addr_out)
Definition: channel.c:2824
relay_crypto_clear
void relay_crypto_clear(relay_crypto_t *crypto)
Definition: relay_crypto.c:265
cpath_build_state_t::pending_final_cpath
crypt_path_t * pending_final_cpath
Definition: cpath_build_state_st.h:34
dir_connection_t
Definition: dir_connection_st.h:21
dir_connection_t::compress_state
struct tor_compress_state_t * compress_state
Definition: dir_connection_st.h:43
hs_circuit.h
Header file containing circuit data for the whole HS subsytem.
tor_zlib_get_total_allocation
size_t tor_zlib_get_total_allocation(void)
Definition: compress_zlib.c:294
or_circuit_t::crypto
relay_crypto_t crypto
Definition: or_circuit_st.h:46
hs_circ_cleanup_on_close
void hs_circ_cleanup_on_close(circuit_t *circ)
Definition: hs_circuit.c:1307
networkstatus_get_param
int32_t networkstatus_get_param(const networkstatus_t *ns, const char *param_name, int32_t default_val, int32_t min_val, int32_t max_val)
Definition: networkstatus.c:2495
smartlist_sort
void smartlist_sort(smartlist_t *sl, int(*compare)(const void **a, const void **b))
Definition: smartlist.c:334
connection_edge_destroy
int connection_edge_destroy(circid_t circ_id, edge_connection_t *conn)
Definition: connection_edge.c:410
channel_send_destroy
int channel_send_destroy(circid_t circ_id, channel_t *chan, int reason)
Definition: channel.c:2031
TO_OR_CIRCUIT
or_circuit_t * TO_OR_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:156
CIRCUIT_STATE_BUILDING
#define CIRCUIT_STATE_BUILDING
Definition: circuitlist.h:21
origin_circuit_st.h
Origin circuit structure.
tor_lzma_get_total_allocation
size_t tor_lzma_get_total_allocation(void)
Definition: compress_lzma.c:352
circuit_get_by_edge_conn
circuit_t * circuit_get_by_edge_conn(edge_connection_t *conn)
Definition: circuitlist.c:1588
smartlist_t
Definition: smartlist_core.h:26
smartlist_remove
void smartlist_remove(smartlist_t *sl, const void *element)
Definition: smartlist_core.c:151
ocirc_state_msg_t::onehop
bool onehop
Definition: ocirc_event.h:31
circuit_clear_testing_cell_stats
void circuit_clear_testing_cell_stats(circuit_t *circ)
Definition: circuitlist.c:1115
origin_circuit_new
origin_circuit_t * origin_circuit_new(void)
Definition: circuitlist.c:1020
rendclient.h
Header file for rendclient.c.
circuit_t::state
uint8_t state
Definition: circuit_st.h:110
circuit_initial_package_window
int32_t circuit_initial_package_window(void)
Definition: circuitlist.c:977
circuit_build_times_disabled
int circuit_build_times_disabled(const or_options_t *options)
Definition: circuitstats.c:118
CELL_DIRECTION_IN
@ CELL_DIRECTION_IN
Definition: or.h:484
rendcommon.h
Header file for rendcommon.c.
circuit_get_all_pending_on_channel
void circuit_get_all_pending_on_channel(smartlist_t *out, channel_t *chan)
Definition: circuitlist.c:580
rephist.h
Header file for rephist.c.
CIRCUIT_PURPOSE_C_INTRODUCING
#define CIRCUIT_PURPOSE_C_INTRODUCING
Definition: circuitlist.h:75
ocirc_event.h
Header file for ocirc_event.c.
circuit_t::magic
uint32_t magic
Definition: circuit_st.h:62
connection_or.h
Header file for connection_or.c.
END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED
#define END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED
Definition: or.h:280
packed_cell_t::inserted_timestamp
uint32_t inserted_timestamp
Definition: cell_queue_st.h:22
cpath_build_state_t::service_pending_final_cpath_ref
crypt_path_reference_t * service_pending_final_cpath_ref
Definition: cpath_build_state_st.h:37
circuit_max_queued_cell_age
STATIC uint32_t circuit_max_queued_cell_age(const circuit_t *c, uint32_t now)
Definition: circuitlist.c:2515
circuits_pending_close
static smartlist_t * circuits_pending_close
Definition: circuitlist.c:136
extend_info_t
Definition: extend_info_st.h:27
circuit_purpose_to_string
const char * circuit_purpose_to_string(uint8_t purpose)
Definition: circuitlist.c:905
circid_t
uint32_t circid_t
Definition: or.h:609
chan_circid_entries_eq_
static int chan_circid_entries_eq_(chan_circid_circuit_map_t *a, chan_circid_circuit_map_t *b)
Definition: circuitlist.c:195
chan_circid_entry_hash_
static unsigned int chan_circid_entry_hash_(chan_circid_circuit_map_t *a)
Definition: circuitlist.c:204
or.h
Master header file for Tor-specific functionality.
circuit_event_status
int circuit_event_status(origin_circuit_t *circ, circuit_status_event_t tp, int reason_code)
Definition: circuitlist.c:501
circuit_clear_cell_queue
void circuit_clear_cell_queue(circuit_t *circ, channel_t *chan)
Definition: relay.c:3232
circuit_get_cpath_hop
crypt_path_t * circuit_get_cpath_hop(origin_circuit_t *circ, int hopnum)
Definition: circuitlist.c:2087