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