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