tor  0.4.2.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-2019, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
53 #define CIRCUITLIST_PRIVATE
54 #define OCIRC_EVENT_PRIVATE
55 #include "lib/cc/torint.h" /* TOR_PRIuSZ */
56 
57 #include "core/or/or.h"
58 #include "core/or/channel.h"
59 #include "core/or/channeltls.h"
60 #include "feature/client/circpathbias.h"
61 #include "core/or/circuitbuild.h"
62 #include "core/or/circuitlist.h"
63 #include "core/or/circuituse.h"
64 #include "core/or/circuitstats.h"
65 #include "core/or/circuitpadding.h"
66 #include "core/or/crypt_path.h"
68 #include "app/config/config.h"
70 #include "core/or/connection_or.h"
77 #include "core/mainloop/mainloop.h"
78 #include "feature/hs/hs_circuit.h"
80 #include "feature/hs/hs_ident.h"
85 #include "core/crypto/onion_fast.h"
86 #include "core/or/policies.h"
87 #include "core/or/relay.h"
88 #include "core/crypto/relay_crypto.h"
91 #include "feature/stats/predict_ports.h"
92 #include "feature/stats/rephist.h"
94 #include "feature/nodelist/routerset.h"
95 #include "core/or/channelpadding.h"
96 #include "lib/compress/compress.h"
100 #include "lib/buf/buffers.h"
101 
102 #define OCIRC_EVENT_PRIVATE
103 #include "core/or/ocirc_event.h"
104 
105 #include "ht.h"
106 
107 #include "core/or/cpath_build_state_st.h"
108 #include "core/or/crypt_path_reference_st.h"
109 #include "feature/dircommon/dir_connection_st.h"
110 #include "core/or/edge_connection_st.h"
111 #include "core/or/half_edge_st.h"
112 #include "core/or/extend_info_st.h"
113 #include "core/or/or_circuit_st.h"
114 #include "core/or/origin_circuit_st.h"
115 
116 /********* START VARIABLES **********/
117 
120 
124 
127 
131 
135 
136 static void cpath_ref_decref(crypt_path_reference_t *cpath_ref);
137 static void circuit_about_to_free_atexit(circuit_t *circ);
138 static void circuit_about_to_free(circuit_t *circ);
139 
147 
148 /********* END VARIABLES ************/
149 
150 or_circuit_t *
152 {
153  tor_assert(x->magic == OR_CIRCUIT_MAGIC);
154  return DOWNCAST(or_circuit_t, x);
155 }
156 const or_circuit_t *
157 CONST_TO_OR_CIRCUIT(const circuit_t *x)
158 {
159  tor_assert(x->magic == OR_CIRCUIT_MAGIC);
160  return DOWNCAST(or_circuit_t, x);
161 }
164 {
165  tor_assert(x->magic == ORIGIN_CIRCUIT_MAGIC);
166  return DOWNCAST(origin_circuit_t, x);
167 }
168 const origin_circuit_t *
169 CONST_TO_ORIGIN_CIRCUIT(const circuit_t *x)
170 {
171  tor_assert(x->magic == ORIGIN_CIRCUIT_MAGIC);
172  return DOWNCAST(origin_circuit_t, x);
173 }
174 
178  HT_ENTRY(chan_circid_circuit_map_t) node;
179  channel_t *chan;
180  circid_t circ_id;
181  circuit_t *circuit;
182  /* For debugging 12184: when was this placeholder item added? */
183  time_t made_placeholder_at;
185 
189 static inline int
192 {
193  return a->chan == b->chan && a->circ_id == b->circ_id;
194 }
195 
198 static inline unsigned int
200 {
201  /* Try to squeze the siphash input into 8 bytes to save any extra siphash
202  * rounds. This hash function is in the critical path. */
203  uintptr_t chan = (uintptr_t) (void*) a->chan;
204  uint32_t array[2];
205  array[0] = a->circ_id;
206  /* The low bits of the channel pointer are uninteresting, since the channel
207  * is a pretty big structure. */
208  array[1] = (uint32_t) (chan >> 6);
209  return (unsigned) siphash24g(array, sizeof(array));
210 }
211 
213 static HT_HEAD(chan_circid_map, chan_circid_circuit_map_t)
214  chan_circid_map = HT_INITIALIZER();
215 HT_PROTOTYPE(chan_circid_map, chan_circid_circuit_map_t, node,
217 HT_GENERATE2(chan_circid_map, chan_circid_circuit_map_t, node,
220 
221 
225 static chan_circid_circuit_map_t *_last_circid_chan_ent = NULL;
226 
231 static void
232 circuit_set_circid_chan_helper(circuit_t *circ, int direction,
233  circid_t id,
234  channel_t *chan)
235 {
238  channel_t *old_chan, **chan_ptr;
239  circid_t old_id, *circid_ptr;
240  int make_active, attached = 0;
241 
242  if (direction == CELL_DIRECTION_OUT) {
243  chan_ptr = &circ->n_chan;
244  circid_ptr = &circ->n_circ_id;
245  make_active = circ->n_chan_cells.n > 0;
246  } else {
247  or_circuit_t *c = TO_OR_CIRCUIT(circ);
248  chan_ptr = &c->p_chan;
249  circid_ptr = &c->p_circ_id;
250  make_active = c->p_chan_cells.n > 0;
251  }
252  old_chan = *chan_ptr;
253  old_id = *circid_ptr;
254 
255  if (id == old_id && chan == old_chan)
256  return;
257 
258  if (_last_circid_chan_ent &&
259  ((old_id == _last_circid_chan_ent->circ_id &&
260  old_chan == _last_circid_chan_ent->chan) ||
261  (id == _last_circid_chan_ent->circ_id &&
262  chan == _last_circid_chan_ent->chan))) {
263  _last_circid_chan_ent = NULL;
264  }
265 
266  if (old_chan) {
267  /*
268  * If we're changing channels or ID and had an old channel and a non
269  * zero old ID and weren't marked for close (i.e., we should have been
270  * attached), detach the circuit. ID changes require this because
271  * circuitmux hashes on (channel_id, circuit_id).
272  */
273  if (old_id != 0 && (old_chan != chan || old_id != id) &&
274  !(circ->marked_for_close)) {
275  tor_assert(old_chan->cmux);
276  circuitmux_detach_circuit(old_chan->cmux, circ);
277  }
278 
279  /* we may need to remove it from the conn-circid map */
280  search.circ_id = old_id;
281  search.chan = old_chan;
282  found = HT_REMOVE(chan_circid_map, &chan_circid_map, &search);
283  if (found) {
284  tor_free(found);
285  if (direction == CELL_DIRECTION_OUT) {
286  /* One fewer circuits use old_chan as n_chan */
287  --(old_chan->num_n_circuits);
288  } else {
289  /* One fewer circuits use old_chan as p_chan */
290  --(old_chan->num_p_circuits);
291  }
292  }
293  }
294 
295  /* Change the values only after we have possibly made the circuit inactive
296  * on the previous chan. */
297  *chan_ptr = chan;
298  *circid_ptr = id;
299 
300  if (chan == NULL)
301  return;
302 
303  /* now add the new one to the conn-circid map */
304  search.circ_id = id;
305  search.chan = chan;
306  found = HT_FIND(chan_circid_map, &chan_circid_map, &search);
307  if (found) {
308  found->circuit = circ;
309  found->made_placeholder_at = 0;
310  } else {
311  found = tor_malloc_zero(sizeof(chan_circid_circuit_map_t));
312  found->circ_id = id;
313  found->chan = chan;
314  found->circuit = circ;
315  HT_INSERT(chan_circid_map, &chan_circid_map, found);
316  }
317 
318  /*
319  * Attach to the circuitmux if we're changing channels or IDs and
320  * have a new channel and ID to use and the circuit is not marked for
321  * close.
322  */
323  if (chan && id != 0 && (old_chan != chan || old_id != id) &&
324  !(circ->marked_for_close)) {
325  tor_assert(chan->cmux);
326  circuitmux_attach_circuit(chan->cmux, circ, direction);
327  attached = 1;
328  }
329 
330  /*
331  * This is a no-op if we have no cells, but if we do it marks us active to
332  * the circuitmux
333  */
334  if (make_active && attached)
335  update_circuit_on_cmux(circ, direction);
336 
337  /* Adjust circuit counts on new channel */
338  if (direction == CELL_DIRECTION_OUT) {
339  ++chan->num_n_circuits;
340  } else {
341  ++chan->num_p_circuits;
342  }
343 }
344 
349 void
351 {
354 
355  /* See if there's an entry there. That wouldn't be good. */
356  memset(&search, 0, sizeof(search));
357  search.chan = chan;
358  search.circ_id = id;
359  ent = HT_FIND(chan_circid_map, &chan_circid_map, &search);
360 
361  if (ent && ent->circuit) {
362  /* we have a problem. */
363  log_warn(LD_BUG, "Tried to mark %u unusable on %p, but there was already "
364  "a circuit there.", (unsigned)id, chan);
365  } else if (ent) {
366  /* It's already marked. */
367  if (!ent->made_placeholder_at)
368  ent->made_placeholder_at = approx_time();
369  } else {
370  ent = tor_malloc_zero(sizeof(chan_circid_circuit_map_t));
371  ent->chan = chan;
372  ent->circ_id = id;
373  /* leave circuit at NULL. */
374  ent->made_placeholder_at = approx_time();
375  HT_INSERT(chan_circid_map, &chan_circid_map, ent);
376  }
377 }
378 
382 void
384 {
387 
388  /* See if there's an entry there. That wouldn't be good. */
389  memset(&search, 0, sizeof(search));
390  search.chan = chan;
391  search.circ_id = id;
392  ent = HT_REMOVE(chan_circid_map, &chan_circid_map, &search);
393  if (ent && ent->circuit) {
394  log_warn(LD_BUG, "Tried to mark %u usable on %p, but there was already "
395  "a circuit there.", (unsigned)id, chan);
396  return;
397  }
398  if (_last_circid_chan_ent == ent)
399  _last_circid_chan_ent = NULL;
400  tor_free(ent);
401 }
402 
405 void
407 {
409  if (circ) {
410  if (circ->n_chan == chan && circ->n_circ_id == id) {
411  circ->n_delete_pending = 1;
412  } else {
413  or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
414  if (orcirc->p_chan == chan && orcirc->p_circ_id == id) {
415  circ->p_delete_pending = 1;
416  }
417  }
418  return;
419  }
421 }
422 
426 channel_note_destroy_not_pending,(channel_t *chan, circid_t id))
427 {
429  if (circ) {
430  if (circ->n_chan == chan && circ->n_circ_id == id) {
431  circ->n_delete_pending = 0;
432  } else {
433  or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
434  if (orcirc->p_chan == chan && orcirc->p_circ_id == id) {
435  circ->p_delete_pending = 0;
436  }
437  }
438  /* XXXX this shouldn't happen; log a bug here. */
439  return;
440  }
441  channel_mark_circid_usable(chan, id);
442 }
443 
447 void
449  channel_t *chan)
450 {
451  circuit_t *circ = TO_CIRCUIT(or_circ);
452  channel_t *old_chan = or_circ->p_chan;
453  circid_t old_id = or_circ->p_circ_id;
454 
455  circuit_set_circid_chan_helper(circ, CELL_DIRECTION_IN, id, chan);
456 
457  if (chan) {
459  }
460 
461  if (circ->p_delete_pending && old_chan) {
462  channel_mark_circid_unusable(old_chan, old_id);
463  circ->p_delete_pending = 0;
464  }
465 }
466 
470 void
472  channel_t *chan)
473 {
474  channel_t *old_chan = circ->n_chan;
475  circid_t old_id = circ->n_circ_id;
476 
477  circuit_set_circid_chan_helper(circ, CELL_DIRECTION_OUT, id, chan);
478 
479  if (chan) {
481  }
482 
483  if (circ->n_delete_pending && old_chan) {
484  channel_mark_circid_unusable(old_chan, old_id);
485  circ->n_delete_pending = 0;
486  }
487 }
488 
495 int
497  int reason_code)
498 {
499  ocirc_cevent_msg_t *msg = tor_malloc(sizeof(*msg));
500 
501  tor_assert(circ);
502 
503  msg->gid = circ->global_identifier;
504  msg->evtype = tp;
505  msg->reason = reason_code;
506  msg->onehop = circ->build_state->onehop_tunnel;
507 
508  ocirc_cevent_publish(msg);
509  return control_event_circuit_status(circ, tp, reason_code);
510 }
511 
519 static void
521 {
522  ocirc_state_msg_t *msg = tor_malloc(sizeof(*msg));
523  const origin_circuit_t *ocirc;
524 
526  ocirc = CONST_TO_ORIGIN_CIRCUIT(circ);
527  /* Only inbound OR circuits can be in this state, not origin circuits. */
529 
530  msg->gid = ocirc->global_identifier;
531  msg->state = circ->state;
532  msg->onehop = ocirc->build_state->onehop_tunnel;
533 
534  ocirc_state_publish(msg);
535 }
536 
539 void
540 circuit_set_state(circuit_t *circ, uint8_t state)
541 {
542  tor_assert(circ);
543  if (state == circ->state)
544  return;
545  if (PREDICT_UNLIKELY(!circuits_pending_chans))
546  circuits_pending_chans = smartlist_new();
547  if (PREDICT_UNLIKELY(!circuits_pending_other_guards))
548  circuits_pending_other_guards = smartlist_new();
549  if (circ->state == CIRCUIT_STATE_CHAN_WAIT) {
550  /* remove from waiting-circuit list. */
552  }
553  if (state == CIRCUIT_STATE_CHAN_WAIT) {
554  /* add to waiting-circuit list. */
556  }
557  if (circ->state == CIRCUIT_STATE_GUARD_WAIT) {
559  }
560  if (state == CIRCUIT_STATE_GUARD_WAIT) {
562  }
563  if (state == CIRCUIT_STATE_GUARD_WAIT || state == CIRCUIT_STATE_OPEN)
565  circ->state = state;
566  if (CIRCUIT_IS_ORIGIN(circ))
567  circuit_state_publish(circ);
568 }
569 
572 void
574 {
575  tor_assert(out);
576  tor_assert(chan);
577 
579  return;
580 
582  if (circ->marked_for_close)
583  continue;
584  if (!circ->n_hop)
585  continue;
588  /* Look at addr/port. This is an unkeyed connection. */
589  if (!channel_matches_extend_info(chan, circ->n_hop))
590  continue;
591  } else {
592  /* We expected a key. See if it's the right one. */
593  if (tor_memneq(chan->identity_digest,
595  continue;
596  }
597  smartlist_add(out, circ);
598  } SMARTLIST_FOREACH_END(circ);
599 }
600 
603 int
605 {
606  int cnt;
607  smartlist_t *sl = smartlist_new();
608 
609  tor_assert(chan);
610 
612  cnt = smartlist_len(sl);
613  smartlist_free(sl);
614  log_debug(LD_CIRC,"or_conn to %s, %d pending circs",
616  cnt);
617  return cnt;
618 }
619 
623 static void
625 {
626  int origin_idx = origin_circ->global_origin_circuit_list_idx;
627  if (origin_idx < 0)
628  return;
629  origin_circuit_t *c2;
630  tor_assert(origin_idx <= smartlist_len(global_origin_circuit_list));
631  c2 = smartlist_get(global_origin_circuit_list, origin_idx);
632  tor_assert(origin_circ == c2);
634  if (origin_idx < smartlist_len(global_origin_circuit_list)) {
635  origin_circuit_t *replacement =
636  smartlist_get(global_origin_circuit_list, origin_idx);
637  replacement->global_origin_circuit_list_idx = origin_idx;
638  }
639  origin_circ->global_origin_circuit_list_idx = -1;
640 }
641 
644 static void
646 {
647  tor_assert(origin_circ->global_origin_circuit_list_idx == -1);
649  smartlist_add(lst, origin_circ);
650  origin_circ->global_origin_circuit_list_idx = smartlist_len(lst) - 1;
651 }
652 
656 void
658 {
659  if (circuits_pending_close == NULL)
660  return;
661 
662  smartlist_t *lst = circuit_get_global_list();
665 
666  /* Remove it from the circuit list. */
667  int idx = circ->global_circuitlist_idx;
668  smartlist_del(lst, idx);
669  if (idx < smartlist_len(lst)) {
670  circuit_t *replacement = smartlist_get(lst, idx);
671  replacement->global_circuitlist_idx = idx;
672  }
673  circ->global_circuitlist_idx = -1;
674 
675  /* Remove it from the origin circuit list, if appropriate. */
676  if (CIRCUIT_IS_ORIGIN(circ)) {
678  }
679 
680  circuit_about_to_free(circ);
681  circuit_free(circ);
682  } SMARTLIST_FOREACH_END(circ);
683 
685 }
686 
689 circuit_get_global_list,(void))
690 {
691  if (NULL == global_circuitlist)
692  global_circuitlist = smartlist_new();
693  return global_circuitlist;
694 }
695 
697 smartlist_t *
699 {
700  if (NULL == global_origin_circuit_list)
701  global_origin_circuit_list = smartlist_new();
703 }
704 
712 int
714 {
716  const origin_circuit_t *, next_circ) {
717  if (!TO_CIRCUIT(next_circ)->marked_for_close &&
718  next_circ->has_opened &&
719  TO_CIRCUIT(next_circ)->state == CIRCUIT_STATE_OPEN &&
720  TO_CIRCUIT(next_circ)->purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT &&
721  next_circ->build_state &&
722  next_circ->build_state->desired_path_len == DEFAULT_ROUTE_LEN) {
724  return 1;
725  }
726  } SMARTLIST_FOREACH_END(next_circ);
727 
729  return 0;
730 }
731 
738 void
739 circuit_cache_opened_circuit_state(int circuits_are_opened)
740 {
741  any_opened_circs_cached_val = circuits_are_opened;
742 }
743 
749 int
751 {
753 }
754 
756 const char *
758 {
759  static char buf[64];
760  switch (state) {
761  case CIRCUIT_STATE_BUILDING: return "doing handshakes";
762  case CIRCUIT_STATE_ONIONSKIN_PENDING: return "processing the onion";
763  case CIRCUIT_STATE_CHAN_WAIT: return "connecting to server";
764  case CIRCUIT_STATE_GUARD_WAIT: return "waiting to see how other "
765  "guards perform";
766  case CIRCUIT_STATE_OPEN: return "open";
767  default:
768  log_warn(LD_BUG, "Unknown circuit state %d", state);
769  tor_snprintf(buf, sizeof(buf), "unknown state [%d]", state);
770  return buf;
771  }
772 }
773 
776 const char *
778 {
779  static char buf[32];
780  switch (purpose) {
781  case CIRCUIT_PURPOSE_OR:
785  return "SERVER"; /* A controller should never see these, actually. */
786 
788  return "GENERAL";
789 
791  return "HS_CLIENT_HSDIR";
792 
796  return "HS_CLIENT_INTRO";
797 
802  return "HS_CLIENT_REND";
803 
805  return "HS_SERVICE_HSDIR";
806 
809  return "HS_SERVICE_INTRO";
810 
813  return "HS_SERVICE_REND";
814 
816  return "TESTING";
818  return "MEASURE_TIMEOUT";
820  return "CONTROLLER";
822  return "PATH_BIAS_TESTING";
824  return "HS_VANGUARDS";
826  return "CIRCUIT_PADDING";
827 
828  default:
829  tor_snprintf(buf, sizeof(buf), "UNKNOWN_%d", (int)purpose);
830  return buf;
831  }
832 }
833 
837 const char *
839 {
840  switch (purpose)
841  {
842  default:
844  "Unrecognized circuit purpose: %d",
845  (int)purpose);
847  /* fall through */
848 
849  case CIRCUIT_PURPOSE_OR:
857  return NULL;
858 
860  return "OR_HSSI_ESTABLISHED";
862  return "OR_HSCR_ESTABLISHED";
864  return "OR_HS_R_JOINED";
865 
868  return "HSCI_CONNECTING";
870  return "HSCI_INTRO_SENT";
872  return "HSCI_DONE";
873 
875  return "HSCR_CONNECTING";
877  return "HSCR_ESTABLISHED_IDLE";
879  return "HSCR_ESTABLISHED_WAITING";
881  return "HSCR_JOINED";
882 
885  return "HSSI_CONNECTING";
887  return "HSSI_ESTABLISHED";
888 
890  return "HSSR_CONNECTING";
892  return "HSSR_JOINED";
893  }
894 }
895 
897 const char *
899 {
900  static char buf[32];
901 
902  switch (purpose)
903  {
904  case CIRCUIT_PURPOSE_OR:
905  return "Circuit at relay";
907  return "Acting as intro point";
909  return "Acting as rendezvous (pending)";
911  return "Acting as rendezvous (established)";
913  return "General-purpose client";
915  return "Hidden service client: Connecting to intro point";
917  return "Hidden service client: Waiting for ack from intro point";
919  return "Hidden service client: Received ack from intro point";
921  return "Hidden service client: Establishing rendezvous point";
923  return "Hidden service client: Pending rendezvous point";
925  return "Hidden service client: Pending rendezvous point (ack received)";
927  return "Hidden service client: Active rendezvous point";
929  return "Hidden service client: Fetching HS descriptor";
930 
932  return "Measuring circuit timeout";
933 
935  return "Hidden service: Establishing introduction point";
937  return "Hidden service: Introduction point";
939  return "Hidden service: Connecting to rendezvous point";
941  return "Hidden service: Active rendezvous point";
943  return "Hidden service: Uploading HS descriptor";
944 
946  return "Testing circuit";
947 
949  return "Circuit made by controller";
950 
952  return "Path-bias testing circuit";
953 
955  return "Hidden service: Pre-built vanguard circuit";
956 
958  return "Circuit kept open for padding";
959 
960  default:
961  tor_snprintf(buf, sizeof(buf), "UNKNOWN_%d", (int)purpose);
962  return buf;
963  }
964 }
965 
969 int32_t
971 {
972  int32_t num = networkstatus_get_param(NULL, "circwindow", CIRCWINDOW_START,
973  CIRCWINDOW_START_MIN,
974  CIRCWINDOW_START_MAX);
975  /* If the consensus tells us a negative number, we'd assert. */
976  if (num < 0)
977  num = CIRCWINDOW_START;
978  return num;
979 }
980 
983 static void
985 {
986  tor_gettimeofday(&circ->timestamp_created);
987 
988  // Gets reset when we send CREATE_FAST.
989  // circuit_expire_building() expects these to be equal
990  // until the orconn is built.
991  circ->timestamp_began = circ->timestamp_created;
992 
997 
998  smartlist_add(circuit_get_global_list(), circ);
999  circ->global_circuitlist_idx = smartlist_len(circuit_get_global_list()) - 1;
1000 }
1001 
1005 #define DFLT_IDLE_TIMEOUT_WHILE_LEARNING (3*60)
1006 #define MIN_IDLE_TIMEOUT_WHILE_LEARNING (10)
1007 #define MAX_IDLE_TIMEOUT_WHILE_LEARNING (1000*60)
1008 
1014 {
1015  origin_circuit_t *circ;
1016  /* never zero, since a global ID of 0 is treated specially by the
1017  * controller */
1018  static uint32_t n_circuits_allocated = 1;
1019 
1020  circ = tor_malloc_zero(sizeof(origin_circuit_t));
1021  circ->base_.magic = ORIGIN_CIRCUIT_MAGIC;
1022 
1023  circ->next_stream_id = crypto_rand_int(1<<16);
1024  circ->global_identifier = n_circuits_allocated++;
1027 
1029 
1030  /* Add to origin-list. */
1031  circ->global_origin_circuit_list_idx = -1;
1033 
1034  circuit_build_times_update_last_circ(get_circuit_build_times_mutable());
1035 
1036  if (! circuit_build_times_disabled(get_options()) &&
1038  /* Circuits should be shorter lived if we need more of them
1039  * for learning a good build timeout */
1040  circ->circuit_idle_timeout =
1041  networkstatus_get_param(NULL, "cbtlearntimeout",
1043  MIN_IDLE_TIMEOUT_WHILE_LEARNING,
1044  MAX_IDLE_TIMEOUT_WHILE_LEARNING);
1045  } else {
1046  // This should always be larger than the current port prediction time
1047  // remaining, or else we'll end up with the case where a circuit times out
1048  // and another one is built, effectively doubling the timeout window.
1049  //
1050  // We also randomize it by up to 5% more (ie 5% of 0 to 3600 seconds,
1051  // depending on how much circuit prediction time is remaining) so that
1052  // we don't close a bunch of unused circuits all at the same time.
1053  int prediction_time_remaining =
1055  circ->circuit_idle_timeout = prediction_time_remaining+1+
1056  crypto_rand_int(1+prediction_time_remaining/20);
1057 
1058  if (circ->circuit_idle_timeout <= 0) {
1059  log_warn(LD_BUG,
1060  "Circuit chose a negative idle timeout of %d based on "
1061  "%d seconds of predictive building remaining.",
1062  circ->circuit_idle_timeout,
1063  prediction_time_remaining);
1064  circ->circuit_idle_timeout =
1065  networkstatus_get_param(NULL, "cbtlearntimeout",
1067  MIN_IDLE_TIMEOUT_WHILE_LEARNING,
1068  MAX_IDLE_TIMEOUT_WHILE_LEARNING);
1069  }
1070 
1071  log_info(LD_CIRC,
1072  "Circuit %"PRIu32" chose an idle timeout of %d based on "
1073  "%d seconds of predictive building remaining.",
1074  (circ->global_identifier),
1075  circ->circuit_idle_timeout,
1076  prediction_time_remaining);
1077  }
1078 
1079  return circ;
1080 }
1081 
1084 or_circuit_t *
1085 or_circuit_new(circid_t p_circ_id, channel_t *p_chan)
1086 {
1087  /* CircIDs */
1088  or_circuit_t *circ;
1089 
1090  circ = tor_malloc_zero(sizeof(or_circuit_t));
1091  circ->base_.magic = OR_CIRCUIT_MAGIC;
1092 
1093  if (p_chan)
1094  circuit_set_p_circid_chan(circ, p_circ_id, p_chan);
1095 
1097  cell_queue_init(&circ->p_chan_cells);
1098 
1100 
1101  return circ;
1102 }
1103 
1105 void
1107 {
1108  if (!circ || !circ->testing_cell_stats)
1109  return;
1111  ent, tor_free(ent));
1112  smartlist_free(circ->testing_cell_stats);
1113  circ->testing_cell_stats = NULL;
1114 }
1115 
1118 STATIC void
1120 {
1121  circid_t n_circ_id = 0;
1122  void *mem;
1123  size_t memlen;
1124  int should_free = 1;
1125  if (!circ)
1126  return;
1127 
1128  /* We keep a copy of this so we can log its value before it gets unset. */
1129  n_circ_id = circ->n_circ_id;
1130 
1132 
1133  /* Cleanup circuit from anything HS v3 related. We also do this when the
1134  * circuit is closed. This is to avoid any code path that free registered
1135  * circuits without closing them before. This needs to be done before the
1136  * hs identifier is freed. */
1137  hs_circ_cleanup(circ);
1138 
1139  if (CIRCUIT_IS_ORIGIN(circ)) {
1140  origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
1141  mem = ocirc;
1142  memlen = sizeof(origin_circuit_t);
1143  tor_assert(circ->magic == ORIGIN_CIRCUIT_MAGIC);
1144 
1146 
1147  if (ocirc->half_streams) {
1149  half_conn) {
1150  half_edge_free(half_conn);
1151  } SMARTLIST_FOREACH_END(half_conn);
1152  smartlist_free(ocirc->half_streams);
1153  }
1154 
1155  if (ocirc->build_state) {
1156  extend_info_free(ocirc->build_state->chosen_exit);
1159  }
1160  tor_free(ocirc->build_state);
1161 
1162  /* Cancel before freeing, if we haven't already succeeded or failed. */
1163  if (ocirc->guard_state) {
1165  }
1166  circuit_guard_state_free(ocirc->guard_state);
1167 
1168  circuit_clear_cpath(ocirc);
1169 
1170  crypto_pk_free(ocirc->intro_key);
1171  rend_data_free(ocirc->rend_data);
1172 
1173  /* Finally, free the identifier of the circuit and nullify it so multiple
1174  * cleanup will work. */
1175  hs_ident_circuit_free(ocirc->hs_ident);
1176  ocirc->hs_ident = NULL;
1177 
1178  tor_free(ocirc->dest_address);
1179  if (ocirc->socks_username) {
1180  memwipe(ocirc->socks_username, 0x12, ocirc->socks_username_len);
1181  tor_free(ocirc->socks_username);
1182  }
1183  if (ocirc->socks_password) {
1184  memwipe(ocirc->socks_password, 0x06, ocirc->socks_password_len);
1185  tor_free(ocirc->socks_password);
1186  }
1187  addr_policy_list_free(ocirc->prepend_policy);
1188  } else {
1189  or_circuit_t *ocirc = TO_OR_CIRCUIT(circ);
1190  /* Remember cell statistics for this circuit before deallocating. */
1191  if (get_options()->CellStatistics)
1192  rep_hist_buffer_stats_add_circ(circ, time(NULL));
1193  mem = ocirc;
1194  memlen = sizeof(or_circuit_t);
1195  tor_assert(circ->magic == OR_CIRCUIT_MAGIC);
1196 
1197  should_free = (ocirc->workqueue_entry == NULL);
1198 
1199  relay_crypto_clear(&ocirc->crypto);
1200 
1201  if (ocirc->rend_splice) {
1202  or_circuit_t *other = ocirc->rend_splice;
1203  tor_assert(other->base_.magic == OR_CIRCUIT_MAGIC);
1204  other->rend_splice = NULL;
1205  }
1206 
1207  /* remove from map. */
1208  circuit_set_p_circid_chan(ocirc, 0, NULL);
1209 
1210  /* Clear cell queue _after_ removing it from the map. Otherwise our
1211  * "active" checks will be violated. */
1212  cell_queue_clear(&ocirc->p_chan_cells);
1213  }
1214 
1215  extend_info_free(circ->n_hop);
1217 
1218  if (circ->global_circuitlist_idx != -1) {
1219  int idx = circ->global_circuitlist_idx;
1220  circuit_t *c2 = smartlist_get(global_circuitlist, idx);
1221  tor_assert(c2 == circ);
1223  if (idx < smartlist_len(global_circuitlist)) {
1224  c2 = smartlist_get(global_circuitlist, idx);
1225  c2->global_circuitlist_idx = idx;
1226  }
1227  }
1228 
1229  /* Remove from map. */
1230  circuit_set_n_circid_chan(circ, 0, NULL);
1231 
1232  /* Clear cell queue _after_ removing it from the map. Otherwise our
1233  * "active" checks will be violated. */
1235 
1236  /* Cleanup possible SENDME state. */
1237  if (circ->sendme_last_digests) {
1238  SMARTLIST_FOREACH(circ->sendme_last_digests, uint8_t *, d, tor_free(d));
1239  smartlist_free(circ->sendme_last_digests);
1240  }
1241 
1242  log_info(LD_CIRC, "Circuit %u (id: %" PRIu32 ") has been freed.",
1243  n_circ_id,
1244  CIRCUIT_IS_ORIGIN(circ) ?
1245  TO_ORIGIN_CIRCUIT(circ)->global_identifier : 0);
1246 
1247  /* Free any circuit padding structures */
1249 
1250  if (should_free) {
1251  memwipe(mem, 0xAA, memlen); /* poison memory */
1252  tor_free(mem);
1253  } else {
1254  /* If we made it here, this is an or_circuit_t that still has a pending
1255  * cpuworker request which we weren't able to cancel. Instead, set up
1256  * the magic value so that when the reply comes back, we'll know to discard
1257  * the reply and free this structure.
1258  */
1259  memwipe(mem, 0xAA, memlen);
1260  circ->magic = DEAD_CIRCUIT_MAGIC;
1261  }
1262 }
1263 
1266 void
1268 {
1269  crypt_path_t *victim, *head, *cpath;
1270 
1271  head = cpath = circ->cpath;
1272 
1273  if (!cpath)
1274  return;
1275 
1276  /* it's a circular list, so we have to notice when we've
1277  * gone through it once. */
1278  while (cpath->next && cpath->next != head) {
1279  victim = cpath;
1280  cpath = victim->next;
1281  cpath_free(victim);
1282  }
1283 
1284  cpath_free(cpath);
1285 
1286  circ->cpath = NULL;
1287 }
1288 
1290 void
1292 {
1293  smartlist_t *lst = circuit_get_global_list();
1294 
1295  SMARTLIST_FOREACH_BEGIN(lst, circuit_t *, tmp) {
1296  if (! CIRCUIT_IS_ORIGIN(tmp)) {
1297  or_circuit_t *or_circ = TO_OR_CIRCUIT(tmp);
1298  while (or_circ->resolving_streams) {
1299  edge_connection_t *next_conn;
1300  next_conn = or_circ->resolving_streams->next_stream;
1301  connection_free_(TO_CONN(or_circ->resolving_streams));
1302  or_circ->resolving_streams = next_conn;
1303  }
1304  }
1305  tmp->global_circuitlist_idx = -1;
1307  circuit_free(tmp);
1308  SMARTLIST_DEL_CURRENT(lst, tmp);
1309  } SMARTLIST_FOREACH_END(tmp);
1310 
1311  smartlist_free(lst);
1312  global_circuitlist = NULL;
1313 
1314  smartlist_free(global_origin_circuit_list);
1316 
1317  smartlist_free(circuits_pending_chans);
1318  circuits_pending_chans = NULL;
1319 
1320  smartlist_free(circuits_pending_close);
1321  circuits_pending_close = NULL;
1322 
1323  smartlist_free(circuits_pending_other_guards);
1325 
1326  {
1327  chan_circid_circuit_map_t **elt, **next, *c;
1328  for (elt = HT_START(chan_circid_map, &chan_circid_map);
1329  elt;
1330  elt = next) {
1331  c = *elt;
1332  next = HT_NEXT_RMV(chan_circid_map, &chan_circid_map, elt);
1333 
1334  tor_assert(c->circuit == NULL);
1335  tor_free(c);
1336  }
1337  }
1338  HT_CLEAR(chan_circid_map, &chan_circid_map);
1339 }
1340 
1342 static void
1344 {
1345  if (cpath_ref != NULL) {
1346  if (--(cpath_ref->refcount) == 0) {
1347  cpath_free(cpath_ref->cpath);
1348  tor_free(cpath_ref);
1349  }
1350  }
1351 }
1352 
1356 static void
1358  circuit_t *circ,
1359  int conn_array_index,
1360  const char *type,
1361  circid_t this_circid,
1362  circid_t other_circid)
1363 {
1364  tor_log(severity, LD_CIRC, "Conn %d has %s circuit: circID %u "
1365  "(other side %u), state %d (%s), born %ld:",
1366  conn_array_index, type, (unsigned)this_circid, (unsigned)other_circid,
1367  circ->state, circuit_state_to_string(circ->state),
1368  (long)circ->timestamp_began.tv_sec);
1369  if (CIRCUIT_IS_ORIGIN(circ)) { /* circ starts at this node */
1370  circuit_log_path(severity, LD_CIRC, TO_ORIGIN_CIRCUIT(circ));
1371  }
1372 }
1373 
1377 void
1379 {
1380  edge_connection_t *tmpconn;
1381 
1382  SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
1383  circid_t n_circ_id = circ->n_circ_id, p_circ_id = 0;
1384 
1385  if (circ->marked_for_close) {
1386  continue;
1387  }
1388 
1389  if (!CIRCUIT_IS_ORIGIN(circ)) {
1390  p_circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
1391  }
1392 
1393  if (CIRCUIT_IS_ORIGIN(circ)) {
1394  for (tmpconn=TO_ORIGIN_CIRCUIT(circ)->p_streams; tmpconn;
1395  tmpconn=tmpconn->next_stream) {
1396  if (TO_CONN(tmpconn) == conn) {
1397  circuit_dump_conn_details(severity, circ, conn->conn_array_index,
1398  "App-ward", p_circ_id, n_circ_id);
1399  }
1400  }
1401  }
1402 
1403  if (! CIRCUIT_IS_ORIGIN(circ)) {
1404  for (tmpconn=TO_OR_CIRCUIT(circ)->n_streams; tmpconn;
1405  tmpconn=tmpconn->next_stream) {
1406  if (TO_CONN(tmpconn) == conn) {
1407  circuit_dump_conn_details(severity, circ, conn->conn_array_index,
1408  "Exit-ward", n_circ_id, p_circ_id);
1409  }
1410  }
1411  }
1412  }
1413  SMARTLIST_FOREACH_END(circ);
1414 }
1415 
1420 {
1421  SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
1422  if (CIRCUIT_IS_ORIGIN(circ) &&
1423  TO_ORIGIN_CIRCUIT(circ)->global_identifier == id) {
1424  if (circ->marked_for_close)
1425  return NULL;
1426  else
1427  return TO_ORIGIN_CIRCUIT(circ);
1428  }
1429  }
1430  SMARTLIST_FOREACH_END(circ);
1431  return NULL;
1432 }
1433 
1442 static inline circuit_t *
1444  int *found_entry_out)
1445 {
1448 
1449  if (_last_circid_chan_ent &&
1450  circ_id == _last_circid_chan_ent->circ_id &&
1451  chan == _last_circid_chan_ent->chan) {
1452  found = _last_circid_chan_ent;
1453  } else {
1454  search.circ_id = circ_id;
1455  search.chan = chan;
1456  found = HT_FIND(chan_circid_map, &chan_circid_map, &search);
1457  _last_circid_chan_ent = found;
1458  }
1459  if (found && found->circuit) {
1460  log_debug(LD_CIRC,
1461  "circuit_get_by_circid_channel_impl() returning circuit %p for"
1462  " circ_id %u, channel ID %"PRIu64 " (%p)",
1463  found->circuit, (unsigned)circ_id,
1464  (chan->global_identifier), chan);
1465  if (found_entry_out)
1466  *found_entry_out = 1;
1467  return found->circuit;
1468  }
1469 
1470  log_debug(LD_CIRC,
1471  "circuit_get_by_circid_channel_impl() found %s for"
1472  " circ_id %u, channel ID %"PRIu64 " (%p)",
1473  found ? "placeholder" : "nothing",
1474  (unsigned)circ_id,
1475  (chan->global_identifier), chan);
1476 
1477  if (found_entry_out)
1478  *found_entry_out = found ? 1 : 0;
1479 
1480  return NULL;
1481  /* The rest of this checks for bugs. Disabled by default. */
1482  /* We comment it out because coverity complains otherwise.
1483  {
1484  circuit_t *circ;
1485  TOR_LIST_FOREACH(circ, &global_circuitlist, head) {
1486  if (! CIRCUIT_IS_ORIGIN(circ)) {
1487  or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
1488  if (or_circ->p_chan == chan && or_circ->p_circ_id == circ_id) {
1489  log_warn(LD_BUG,
1490  "circuit matches p_chan, but not in hash table (Bug!)");
1491  return circ;
1492  }
1493  }
1494  if (circ->n_chan == chan && circ->n_circ_id == circ_id) {
1495  log_warn(LD_BUG,
1496  "circuit matches n_chan, but not in hash table (Bug!)");
1497  return circ;
1498  }
1499  }
1500  return NULL;
1501  } */
1502 }
1503 
1510 circuit_t *
1512 {
1513  circuit_t *circ = circuit_get_by_circid_channel_impl(circ_id, chan, NULL);
1514  if (!circ || circ->marked_for_close)
1515  return NULL;
1516  else
1517  return circ;
1518 }
1519 
1525 circuit_t *
1527  channel_t *chan)
1528 {
1529  return circuit_get_by_circid_channel_impl(circ_id, chan, NULL);
1530 }
1531 
1539 int
1541 {
1542  int found = 0;
1543  if (circuit_get_by_circid_channel_impl(circ_id, chan, &found) != NULL)
1544  return 1;
1545  if (found)
1546  return 2;
1547  return 0;
1548 }
1549 
1552 time_t
1554 {
1557 
1558  memset(&search, 0, sizeof(search));
1559  search.circ_id = circ_id;
1560  search.chan = chan;
1561 
1562  found = HT_FIND(chan_circid_map, &chan_circid_map, &search);
1563 
1564  if (! found || found->circuit)
1565  return 0;
1566 
1567  return found->made_placeholder_at;
1568 }
1569 
1571 circuit_t *
1573 {
1574  circuit_t *circ;
1575 
1576  circ = conn->on_circuit;
1577  tor_assert(!circ ||
1578  (CIRCUIT_IS_ORIGIN(circ) ? circ->magic == ORIGIN_CIRCUIT_MAGIC
1579  : circ->magic == OR_CIRCUIT_MAGIC));
1580 
1581  return circ;
1582 }
1583 
1588 void
1590 {
1591  smartlist_t *detached = smartlist_new();
1592 
1593 /* #define DEBUG_CIRCUIT_UNLINK_ALL */
1594 
1595  channel_unlink_all_circuits(chan, detached);
1596 
1597 #ifdef DEBUG_CIRCUIT_UNLINK_ALL
1598  {
1599  smartlist_t *detached_2 = smartlist_new();
1600  int mismatch = 0, badlen = 0;
1601 
1602  SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
1603  if (circ->n_chan == chan ||
1604  (!CIRCUIT_IS_ORIGIN(circ) &&
1605  TO_OR_CIRCUIT(circ)->p_chan == chan)) {
1606  smartlist_add(detached_2, circ);
1607  }
1608  }
1609  SMARTLIST_FOREACH_END(circ);
1610 
1611  if (smartlist_len(detached) != smartlist_len(detached_2)) {
1612  log_warn(LD_BUG, "List of detached circuits had the wrong length! "
1613  "(got %d, should have gotten %d)",
1614  (int)smartlist_len(detached),
1615  (int)smartlist_len(detached_2));
1616  badlen = 1;
1617  }
1618  smartlist_sort_pointers(detached);
1619  smartlist_sort_pointers(detached_2);
1620 
1621  SMARTLIST_FOREACH(detached, circuit_t *, c,
1622  if (c != smartlist_get(detached_2, c_sl_idx))
1623  mismatch = 1;
1624  );
1625 
1626  if (mismatch)
1627  log_warn(LD_BUG, "Mismatch in list of detached circuits.");
1628 
1629  if (badlen || mismatch) {
1630  smartlist_free(detached);
1631  detached = detached_2;
1632  } else {
1633  log_notice(LD_CIRC, "List of %d circuits was as expected.",
1634  (int)smartlist_len(detached));
1635  smartlist_free(detached_2);
1636  }
1637  }
1638 #endif /* defined(DEBUG_CIRCUIT_UNLINK_ALL) */
1639 
1640  SMARTLIST_FOREACH_BEGIN(detached, circuit_t *, circ) {
1641  int mark = 0;
1642  if (circ->n_chan == chan) {
1643 
1644  circuit_set_n_circid_chan(circ, 0, NULL);
1645  mark = 1;
1646 
1647  /* If we didn't request this closure, pass the remote
1648  * bit to mark_for_close. */
1649  if (chan->reason_for_closing != CHANNEL_CLOSE_REQUESTED)
1650  reason |= END_CIRC_REASON_FLAG_REMOTE;
1651  }
1652  if (! CIRCUIT_IS_ORIGIN(circ)) {
1653  or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
1654  if (or_circ->p_chan == chan) {
1655  circuit_set_p_circid_chan(or_circ, 0, NULL);
1656  mark = 1;
1657  }
1658  }
1659  if (!mark) {
1660  log_warn(LD_BUG, "Circuit on detached list which I had no reason "
1661  "to mark");
1662  continue;
1663  }
1664  if (!circ->marked_for_close)
1665  circuit_mark_for_close(circ, reason);
1666  } SMARTLIST_FOREACH_END(circ);
1667 
1668  smartlist_free(detached);
1669 }
1670 
1682 {
1683  SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
1684  if (!circ->marked_for_close &&
1686  origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
1687  if (ocirc->rend_data == NULL) {
1688  continue;
1689  }
1690  if (!rend_cmp_service_ids(rend_data_get_address(rend_data),
1691  rend_data_get_address(ocirc->rend_data)) &&
1693  rend_data->rend_cookie,
1694  REND_COOKIE_LEN))
1695  return ocirc;
1696  }
1697  }
1698  SMARTLIST_FOREACH_END(circ);
1699  return NULL;
1700 }
1701 
1719  bool want_client_circ)
1720 {
1721  int idx = 0;
1722  smartlist_t *lst = circuit_get_global_list();
1723 
1724  if (start) {
1725  idx = TO_CIRCUIT(start)->global_circuitlist_idx + 1;
1726  }
1727 
1728  for ( ; idx < smartlist_len(lst); ++idx) {
1729  circuit_t *circ = smartlist_get(lst, idx);
1730 
1731  /* Ignore a marked for close circuit or if the state is not open. */
1732  if (circ->marked_for_close) {
1733  continue;
1734  }
1735 
1736  /* Depending on whether we are looking for client or service circs, skip
1737  * circuits with other purposes. */
1738  if (want_client_circ) {
1739  if (circ->purpose != CIRCUIT_PURPOSE_C_INTRODUCING &&
1742  continue;
1743  }
1744  } else { /* we are looking for service-side circs */
1745  if (circ->state != CIRCUIT_STATE_OPEN) {
1746  continue;
1747  }
1749  circ->purpose != CIRCUIT_PURPOSE_S_INTRO) {
1750  continue;
1751  }
1752  }
1753 
1754  /* The purposes we are looking for are only for origin circuits so the
1755  * following is valid. */
1756  return TO_ORIGIN_CIRCUIT(circ);
1757  }
1758  /* Not found. */
1759  return NULL;
1760 }
1761 
1771 {
1772  int idx = 0;
1773  smartlist_t *lst = circuit_get_global_list();
1774 
1775  if (start) {
1776  idx = TO_CIRCUIT(start)->global_circuitlist_idx + 1;
1777  }
1778 
1779  for ( ; idx < smartlist_len(lst); ++idx) {
1780  circuit_t *circ = smartlist_get(lst, idx);
1781 
1782  /* Ignore a marked for close circuit or purpose not matching a service
1783  * intro point or if the state is not open. */
1784  if (circ->marked_for_close || circ->state != CIRCUIT_STATE_OPEN ||
1787  continue;
1788  }
1789  /* The purposes we are looking for are only for origin circuits so the
1790  * following is valid. */
1791  return TO_ORIGIN_CIRCUIT(circ);
1792  }
1793  /* Not found. */
1794  return NULL;
1795 }
1796 
1805  const uint8_t *digest, uint8_t purpose)
1806 {
1807  int idx;
1808  smartlist_t *lst = circuit_get_global_list();
1810  if (start == NULL)
1811  idx = 0;
1812  else
1813  idx = TO_CIRCUIT(start)->global_circuitlist_idx + 1;
1814 
1815  for ( ; idx < smartlist_len(lst); ++idx) {
1816  circuit_t *circ = smartlist_get(lst, idx);
1817  origin_circuit_t *ocirc;
1818 
1819  if (circ->marked_for_close)
1820  continue;
1821  if (circ->purpose != purpose)
1822  continue;
1823  /* At this point we should be able to get a valid origin circuit because
1824  * the origin purpose we are looking for matches this circuit. */
1825  if (BUG(!CIRCUIT_PURPOSE_IS_ORIGIN(circ->purpose))) {
1826  break;
1827  }
1828  ocirc = TO_ORIGIN_CIRCUIT(circ);
1829  if (!digest)
1830  return ocirc;
1831  if (rend_circuit_pk_digest_eq(ocirc, digest)) {
1832  return ocirc;
1833  }
1834  }
1835  return NULL;
1836 }
1837 
1840 static int
1842 {
1843  if (!circ->build_state) {
1844  return 0;
1845  }
1846 
1847  extend_info_t *chosen_exit = circ->build_state->chosen_exit;
1848  if (BUG(!chosen_exit)) {
1849  return 0;
1850  }
1851 
1852  const node_t *rp_node = node_get_by_id(chosen_exit->identity_digest);
1853  if (rp_node) {
1854  if (node_supports_v3_rendezvous_point(rp_node)) {
1855  return 1;
1856  }
1857  }
1858 
1859  return 0;
1860 }
1861 
1865 static uint8_t
1867 {
1868  if (circuit_should_use_vanguards(purpose)) {
1869  /* If we are using vanguards, then we should only cannibalize vanguard
1870  * circuits so that we get the same path construction logic. */
1872  } else {
1873  /* If no vanguards are used just get a general circuit! */
1875  }
1876 }
1877 
1897 circuit_find_to_cannibalize(uint8_t purpose_to_produce, extend_info_t *info,
1898  int flags)
1899 {
1900  origin_circuit_t *best=NULL;
1901  int need_uptime = (flags & CIRCLAUNCH_NEED_UPTIME) != 0;
1902  int need_capacity = (flags & CIRCLAUNCH_NEED_CAPACITY) != 0;
1903  int internal = (flags & CIRCLAUNCH_IS_INTERNAL) != 0;
1904  const or_options_t *options = get_options();
1905  /* We want the circuit we are trying to cannibalize to have this purpose */
1906  int purpose_to_search_for;
1907 
1908  /* Make sure we're not trying to create a onehop circ by
1909  * cannibalization. */
1911 
1912  purpose_to_search_for = get_circuit_purpose_needed_to_cannibalize(
1913  purpose_to_produce);
1914 
1915  tor_assert_nonfatal(purpose_to_search_for == CIRCUIT_PURPOSE_C_GENERAL ||
1916  purpose_to_search_for == CIRCUIT_PURPOSE_HS_VANGUARDS);
1917 
1918  log_debug(LD_CIRC,
1919  "Hunting for a circ to cannibalize: purpose %d, uptime %d, "
1920  "capacity %d, internal %d",
1921  purpose_to_produce, need_uptime, need_capacity, internal);
1922 
1923  SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ_) {
1924  if (CIRCUIT_IS_ORIGIN(circ_) &&
1925  circ_->state == CIRCUIT_STATE_OPEN &&
1926  !circ_->marked_for_close &&
1927  circ_->purpose == purpose_to_search_for &&
1928  !circ_->timestamp_dirty) {
1929  origin_circuit_t *circ = TO_ORIGIN_CIRCUIT(circ_);
1930 
1931  /* Only cannibalize from reasonable length circuits. If we
1932  * want C_GENERAL, then only choose 3 hop circs. If we want
1933  * HS_VANGUARDS, only choose 4 hop circs.
1934  */
1935  if (circ->build_state->desired_path_len !=
1936  route_len_for_purpose(purpose_to_search_for, NULL)) {
1937  goto next;
1938  }
1939 
1940  /* Ignore any circuits for which we can't use the Guard. It is possible
1941  * that the Guard was removed from the samepled set after the circuit
1942  * was created so avoid using it. */
1943  if (!entry_guard_could_succeed(circ->guard_state)) {
1944  goto next;
1945  }
1946 
1947  if ((!need_uptime || circ->build_state->need_uptime) &&
1948  (!need_capacity || circ->build_state->need_capacity) &&
1949  (internal == circ->build_state->is_internal) &&
1950  !circ->unusable_for_new_conns &&
1952  !circ->build_state->onehop_tunnel &&
1953  !circ->isolation_values_set) {
1954  if (info) {
1955  /* need to make sure we don't duplicate hops */
1956  crypt_path_t *hop = circ->cpath;
1957  const node_t *ri1 = node_get_by_id(info->identity_digest);
1958  do {
1959  const node_t *ri2;
1961  info->identity_digest, DIGEST_LEN))
1962  goto next;
1963  if (ri1 &&
1964  (ri2 = node_get_by_id(hop->extend_info->identity_digest))
1965  && nodes_in_same_family(ri1, ri2))
1966  goto next;
1967  hop=hop->next;
1968  } while (hop!=circ->cpath);
1969  }
1970  if (options->ExcludeNodes) {
1971  /* Make sure no existing nodes in the circuit are excluded for
1972  * general use. (This may be possible if StrictNodes is 0, and we
1973  * thought we needed to use an otherwise excluded node for, say, a
1974  * directory operation.) */
1975  crypt_path_t *hop = circ->cpath;
1976  do {
1978  hop->extend_info))
1979  goto next;
1980  hop = hop->next;
1981  } while (hop != circ->cpath);
1982  }
1983 
1984  if ((flags & CIRCLAUNCH_IS_V3_RP) &&
1986  log_debug(LD_GENERAL, "Skipping uncannibalizable circuit for v3 "
1987  "rendezvous point.");
1988  goto next;
1989  }
1990 
1991  if (!best || (best->build_state->need_uptime && !need_uptime))
1992  best = circ;
1993  next: ;
1994  }
1995  }
1996  }
1997  SMARTLIST_FOREACH_END(circ_);
1998  return best;
1999 }
2000 
2006 smartlist_t *
2008 {
2009  /* Only if some circuit is actually waiting on an upgrade should we
2010  * run the algorithm. */
2012  smartlist_len(circuits_pending_other_guards)==0)
2013  return NULL;
2014  /* Only if we have some origin circuits should we run the algorithm. */
2016  return NULL;
2017 
2018  /* Okay; we can pass our circuit list to entrynodes.c.*/
2019  smartlist_t *result = smartlist_new();
2020  int circuits_upgraded = entry_guards_upgrade_waiting_circuits(
2023  result);
2024  if (circuits_upgraded && smartlist_len(result)) {
2025  return result;
2026  } else {
2027  smartlist_free(result);
2028  return NULL;
2029  }
2030 }
2031 
2034 int
2036 {
2037  int n = 0;
2038  if (circ && circ->cpath) {
2039  crypt_path_t *cpath, *cpath_next = NULL;
2040  for (cpath = circ->cpath; cpath_next != circ->cpath; cpath = cpath_next) {
2041  cpath_next = cpath->next;
2042  ++n;
2043  }
2044  }
2045  return n;
2046 }
2047 
2050 int
2052 {
2053  int n = 0;
2054  if (circ && circ->cpath) {
2055  crypt_path_t *cpath, *cpath_next = NULL;
2056  for (cpath = circ->cpath;
2057  cpath->state == CPATH_STATE_OPEN
2058  && cpath_next != circ->cpath;
2059  cpath = cpath_next) {
2060  cpath_next = cpath->next;
2061  ++n;
2062  }
2063  }
2064  return n;
2065 }
2066 
2070 crypt_path_t *
2072 {
2073  if (circ && circ->cpath && hopnum > 0) {
2074  crypt_path_t *cpath, *cpath_next = NULL;
2075  for (cpath = circ->cpath; cpath_next != circ->cpath; cpath = cpath_next) {
2076  cpath_next = cpath->next;
2077  if (--hopnum <= 0)
2078  return cpath;
2079  }
2080  }
2081  return NULL;
2082 }
2083 
2086 void
2088 {
2089  SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
2090  if (CIRCUIT_IS_ORIGIN(circ) &&
2091  !circ->marked_for_close &&
2092  !circ->timestamp_dirty)
2093  circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
2094  }
2095  SMARTLIST_FOREACH_END(circ);
2096 }
2097 
2105 void
2107 {
2108  SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ) {
2109  if (CIRCUIT_IS_ORIGIN(circ) &&
2110  !circ->marked_for_close &&
2111  circ->timestamp_dirty) {
2113  }
2114  }
2115  SMARTLIST_FOREACH_END(circ);
2116 }
2117 
2133 void
2136 {
2137  uint64_t cells;
2138  uint64_t cell_size;
2139  uint64_t written_sync;
2140  const channel_t *chan = NULL;
2141  const or_circuit_t *or_circ;
2142 
2143  if (!CIRCUIT_IS_ORCIRC(c))
2144  return;
2145 
2146  or_circ = CONST_TO_OR_CIRCUIT(c);
2147 
2148  if (dir == CIRCUIT_N_CHAN) {
2149  chan = c->n_chan;
2150  cells = c->n_chan_cells.n;
2151  } else {
2152  chan = or_circ->p_chan;
2153  cells = or_circ->p_chan_cells.n;
2154  }
2155 
2156  /* If we still know the chan, determine real cell size. Otherwise,
2157  * assume it's a wide circid channel */
2158  if (chan)
2159  cell_size = get_cell_network_size(chan->wide_circ_ids);
2160  else
2161  cell_size = CELL_MAX_NETWORK_SIZE;
2162 
2163  /* The missing written bytes are the cell counts times their cell
2164  * size plus TLS per cell overhead */
2165  written_sync = cells*(cell_size+TLS_PER_CELL_OVERHEAD);
2166 
2167  /* Report the missing bytes as written, to avoid asymmetry.
2168  * We must use time() for consistency with rephist, even though on
2169  * some very old rare platforms, approx_time() may be faster. */
2170  rep_hist_note_bytes_written(written_sync, time(NULL));
2171 }
2172 
2190 circuit_mark_for_close_, (circuit_t *circ, int reason, int line,
2191  const char *file))
2192 {
2193  int orig_reason = reason; /* Passed to the controller */
2194  assert_circuit_ok(circ);
2195  tor_assert(line);
2196  tor_assert(file);
2197 
2198  /* Check whether the circuitpadding subsystem wants to block this close */
2199  if (circpad_marked_circuit_for_padding(circ, reason)) {
2200  return;
2201  }
2202 
2203  if (circ->marked_for_close) {
2204  log_warn(LD_BUG,
2205  "Duplicate call to circuit_mark_for_close at %s:%d"
2206  " (first at %s:%d)", file, line,
2208  return;
2209  }
2210  if (reason == END_CIRC_AT_ORIGIN) {
2211  if (!CIRCUIT_IS_ORIGIN(circ)) {
2212  log_warn(LD_BUG, "Specified 'at-origin' non-reason for ending circuit, "
2213  "but circuit was not at origin. (called %s:%d, purpose=%d)",
2214  file, line, circ->purpose);
2215  }
2216  reason = END_CIRC_REASON_NONE;
2217  }
2218 
2219  if (CIRCUIT_IS_ORIGIN(circ)) {
2220  if (pathbias_check_close(TO_ORIGIN_CIRCUIT(circ), reason) == -1) {
2221  /* Don't close it yet, we need to test it first */
2222  return;
2223  }
2224 
2225  /* We don't send reasons when closing circuits at the origin. */
2226  reason = END_CIRC_REASON_NONE;
2227  }
2228 
2229  circuit_synchronize_written_or_bandwidth(circ, CIRCUIT_N_CHAN);
2230  circuit_synchronize_written_or_bandwidth(circ, CIRCUIT_P_CHAN);
2231 
2232  if (reason & END_CIRC_REASON_FLAG_REMOTE)
2233  reason &= ~END_CIRC_REASON_FLAG_REMOTE;
2234 
2235  if (reason < END_CIRC_REASON_MIN_ || reason > END_CIRC_REASON_MAX_) {
2236  if (!(orig_reason & END_CIRC_REASON_FLAG_REMOTE))
2237  log_warn(LD_BUG, "Reason %d out of range at %s:%d", reason, file, line);
2238  reason = END_CIRC_REASON_NONE;
2239  }
2240 
2241  circ->marked_for_close = line;
2242  circ->marked_for_close_file = file;
2243  circ->marked_for_close_reason = reason;
2244  circ->marked_for_close_orig_reason = orig_reason;
2245 
2246  if (!CIRCUIT_IS_ORIGIN(circ)) {
2247  or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
2248  if (or_circ->rend_splice) {
2249  if (!or_circ->rend_splice->base_.marked_for_close) {
2250  /* do this after marking this circuit, to avoid infinite recursion. */
2251  circuit_mark_for_close(TO_CIRCUIT(or_circ->rend_splice), reason);
2252  }
2253  or_circ->rend_splice = NULL;
2254  }
2255  }
2256 
2257  /* Notify the HS subsystem that this circuit is closing. */
2258  hs_circ_cleanup(circ);
2259 
2260  if (circuits_pending_close == NULL)
2261  circuits_pending_close = smartlist_new();
2262 
2265 
2266  log_info(LD_GENERAL, "Circuit %u (id: %" PRIu32 ") marked for close at "
2267  "%s:%d (orig reason: %d, new reason: %d)",
2268  circ->n_circ_id,
2269  CIRCUIT_IS_ORIGIN(circ) ?
2270  TO_ORIGIN_CIRCUIT(circ)->global_identifier : 0,
2271  file, line, orig_reason, reason);
2272 }
2273 
2279 static void
2281 {
2282 
2283  if (circ->n_chan) {
2284  circuit_clear_cell_queue(circ, circ->n_chan);
2285  circuitmux_detach_circuit(circ->n_chan->cmux, circ);
2286  circuit_set_n_circid_chan(circ, 0, NULL);
2287  }
2288 
2289  if (! CIRCUIT_IS_ORIGIN(circ)) {
2290  or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
2291 
2292  if (or_circ->p_chan) {
2293  circuit_clear_cell_queue(circ, or_circ->p_chan);
2294  circuitmux_detach_circuit(or_circ->p_chan->cmux, circ);
2295  circuit_set_p_circid_chan(or_circ, 0, NULL);
2296  }
2297  }
2298 }
2299 
2304 static void
2306 {
2307 
2308  int reason = circ->marked_for_close_reason;
2309  int orig_reason = circ->marked_for_close_orig_reason;
2310 
2311  if (circ->state == CIRCUIT_STATE_ONIONSKIN_PENDING) {
2313  }
2314  /* If the circuit ever became OPEN, we sent it to the reputation history
2315  * module then. If it isn't OPEN, we send it there now to remember which
2316  * links worked and which didn't.
2317  */
2318  if (circ->state != CIRCUIT_STATE_OPEN &&
2319  circ->state != CIRCUIT_STATE_GUARD_WAIT) {
2320  if (CIRCUIT_IS_ORIGIN(circ)) {
2321  origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
2322  circuit_build_failed(ocirc); /* take actions if necessary */
2323  }
2324  }
2325  if (circ->state == CIRCUIT_STATE_CHAN_WAIT) {
2328  }
2331  }
2332  if (CIRCUIT_IS_ORIGIN(circ)) {
2334  (circ->state == CIRCUIT_STATE_OPEN ||
2335  circ->state == CIRCUIT_STATE_GUARD_WAIT) ?
2336  CIRC_EVENT_CLOSED:CIRC_EVENT_FAILED,
2337  orig_reason);
2338  }
2339 
2341  origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
2342  int timed_out = (reason == END_CIRC_REASON_TIMEOUT);
2345  if (orig_reason != END_CIRC_REASON_IP_NOW_REDUNDANT &&
2346  ocirc->rend_data) {
2347  /* treat this like getting a nack from it */
2348  log_info(LD_REND, "Failed intro circ %s to %s (awaiting ack). %s",
2349  safe_str_client(rend_data_get_address(ocirc->rend_data)),
2350  safe_str_client(build_state_get_exit_nickname(ocirc->build_state)),
2351  timed_out ? "Recording timeout." : "Removing from descriptor.");
2353  ocirc->rend_data,
2354  timed_out ?
2355  INTRO_POINT_FAILURE_TIMEOUT :
2356  INTRO_POINT_FAILURE_GENERIC);
2357  }
2358  } else if (circ->purpose == CIRCUIT_PURPOSE_C_INTRODUCING &&
2359  reason != END_CIRC_REASON_TIMEOUT) {
2360  origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
2361  if (ocirc->build_state->chosen_exit && ocirc->rend_data) {
2362  if (orig_reason != END_CIRC_REASON_IP_NOW_REDUNDANT &&
2363  ocirc->rend_data) {
2364  log_info(LD_REND, "Failed intro circ %s to %s "
2365  "(building circuit to intro point). "
2366  "Marking intro point as possibly unreachable.",
2367  safe_str_client(rend_data_get_address(ocirc->rend_data)),
2368  safe_str_client(build_state_get_exit_nickname(
2369  ocirc->build_state)));
2371  ocirc->rend_data,
2372  INTRO_POINT_FAILURE_UNREACHABLE);
2373  }
2374  }
2375  }
2376 
2377  if (circ->n_chan) {
2378  circuit_clear_cell_queue(circ, circ->n_chan);
2379  /* Only send destroy if the channel isn't closing anyway */
2380  if (!CHANNEL_CONDEMNED(circ->n_chan)) {
2381  channel_send_destroy(circ->n_circ_id, circ->n_chan, reason);
2382  }
2383  circuitmux_detach_circuit(circ->n_chan->cmux, circ);
2384  circuit_set_n_circid_chan(circ, 0, NULL);
2385  }
2386 
2387  if (! CIRCUIT_IS_ORIGIN(circ)) {
2388  or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
2389  edge_connection_t *conn;
2390  for (conn=or_circ->n_streams; conn; conn=conn->next_stream)
2391  connection_edge_destroy(or_circ->p_circ_id, conn);
2392  or_circ->n_streams = NULL;
2393 
2394  while (or_circ->resolving_streams) {
2395  conn = or_circ->resolving_streams;
2396  or_circ->resolving_streams = conn->next_stream;
2397  if (!conn->base_.marked_for_close) {
2398  /* The client will see a DESTROY, and infer that the connections
2399  * are closing because the circuit is getting torn down. No need
2400  * to send an end cell. */
2401  conn->edge_has_sent_end = 1;
2402  conn->end_reason = END_STREAM_REASON_DESTROY;
2404  connection_mark_for_close(TO_CONN(conn));
2405  }
2406  conn->on_circuit = NULL;
2407  }
2408 
2409  if (or_circ->p_chan) {
2410  circuit_clear_cell_queue(circ, or_circ->p_chan);
2411  /* Only send destroy if the channel isn't closing anyway */
2412  if (!CHANNEL_CONDEMNED(or_circ->p_chan)) {
2413  channel_send_destroy(or_circ->p_circ_id, or_circ->p_chan, reason);
2414  }
2415  circuitmux_detach_circuit(or_circ->p_chan->cmux, circ);
2416  circuit_set_p_circid_chan(or_circ, 0, NULL);
2417  }
2418  } else {
2419  origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
2420  edge_connection_t *conn;
2421  for (conn=ocirc->p_streams; conn; conn=conn->next_stream)
2422  connection_edge_destroy(circ->n_circ_id, conn);
2423  ocirc->p_streams = NULL;
2424  }
2425 }
2426 
2429 static void
2431 {
2432  if (!circ->marked_for_close) {
2433  log_warn(LD_BUG, "Called on non-marked circuit");
2434  return;
2435  }
2437  if (! CIRCUIT_IS_ORIGIN(circ)) {
2438  or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
2439  cell_queue_clear(&orcirc->p_chan_cells);
2440  }
2441 }
2442 
2443 static size_t
2444 single_conn_free_bytes(connection_t *conn)
2445 {
2446  size_t result = 0;
2447  if (conn->inbuf) {
2448  result += buf_allocation(conn->inbuf);
2449  buf_clear(conn->inbuf);
2450  }
2451  if (conn->outbuf) {
2452  result += buf_allocation(conn->outbuf);
2453  buf_clear(conn->outbuf);
2454  conn->outbuf_flushlen = 0;
2455  }
2456  if (conn->type == CONN_TYPE_DIR) {
2457  dir_connection_t *dir_conn = TO_DIR_CONN(conn);
2458  if (dir_conn->compress_state) {
2459  result += tor_compress_state_size(dir_conn->compress_state);
2460  tor_compress_free(dir_conn->compress_state);
2461  dir_conn->compress_state = NULL;
2462  }
2463  }
2464  return result;
2465 }
2466 
2469 static size_t
2471 {
2472  size_t result = 0;
2473  for ( ; stream; stream = stream->next_stream) {
2474  connection_t *conn = TO_CONN(stream);
2475  result += single_conn_free_bytes(conn);
2476  if (conn->linked_conn) {
2477  result += single_conn_free_bytes(conn->linked_conn);
2478  }
2479  }
2480  return result;
2481 }
2482 
2485 static size_t
2487 {
2488  if (CIRCUIT_IS_ORIGIN(c)) {
2490  } else {
2491  return marked_circuit_streams_free_bytes(TO_OR_CIRCUIT(c)->n_streams);
2492  }
2493 }
2494 
2496 STATIC size_t
2498 {
2499  size_t n = c->n_chan_cells.n;
2500  if (! CIRCUIT_IS_ORIGIN(c)) {
2501  circuit_t *cc = (circuit_t *) c;
2502  n += TO_OR_CIRCUIT(cc)->p_chan_cells.n;
2503  }
2504  return n;
2505 }
2506 
2508 static size_t
2510 {
2511  if (! CIRCUIT_IS_ORIGIN(c)) {
2512  return 0;
2513  }
2514  const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(c);
2515  if (ocirc->half_streams)
2516  return smartlist_len(ocirc->half_streams) * sizeof(half_edge_t);
2517  else
2518  return 0;
2519 }
2520 
2529 STATIC uint32_t
2531 {
2532  uint32_t age = 0;
2533  packed_cell_t *cell;
2534 
2535  if (NULL != (cell = TOR_SIMPLEQ_FIRST(&c->n_chan_cells.head)))
2536  age = now - cell->inserted_timestamp;
2537 
2538  if (! CIRCUIT_IS_ORIGIN(c)) {
2539  const or_circuit_t *orcirc = CONST_TO_OR_CIRCUIT(c);
2540  if (NULL != (cell = TOR_SIMPLEQ_FIRST(&orcirc->p_chan_cells.head))) {
2541  uint32_t age2 = now - cell->inserted_timestamp;
2542  if (age2 > age)
2543  return age2;
2544  }
2545  }
2546  return age;
2547 }
2548 
2553 static uint32_t
2554 conn_get_buffer_age(const connection_t *conn, uint32_t now_ts)
2555 {
2556  uint32_t age = 0, age2;
2557  if (conn->outbuf) {
2558  age2 = buf_get_oldest_chunk_timestamp(conn->outbuf, now_ts);
2559  if (age2 > age)
2560  age = age2;
2561  }
2562  if (conn->inbuf) {
2563  age2 = buf_get_oldest_chunk_timestamp(conn->inbuf, now_ts);
2564  if (age2 > age)
2565  age = age2;
2566  }
2567  return age;
2568 }
2569 
2573 static uint32_t
2575 {
2576  uint32_t age = 0, age2;
2577  for (; stream; stream = stream->next_stream) {
2578  const connection_t *conn = TO_CONN(stream);
2579  age2 = conn_get_buffer_age(conn, now);
2580  if (age2 > age)
2581  age = age2;
2582  if (conn->linked_conn) {
2583  age2 = conn_get_buffer_age(conn->linked_conn, now);
2584  if (age2 > age)
2585  age = age2;
2586  }
2587  }
2588  return age;
2589 }
2590 
2594 STATIC uint32_t
2596 {
2597  if (CIRCUIT_IS_ORIGIN(c)) {
2599  CONST_TO_ORIGIN_CIRCUIT(c)->p_streams, now);
2600  } else {
2602  CONST_TO_OR_CIRCUIT(c)->n_streams, now);
2603  }
2604 }
2605 
2609 STATIC uint32_t
2611 {
2612  uint32_t cell_age = circuit_max_queued_cell_age(c, now);
2613  uint32_t data_age = circuit_max_queued_data_age(c, now);
2614  if (cell_age > data_age)
2615  return cell_age;
2616  else
2617  return data_age;
2618 }
2619 
2622 static int
2623 circuits_compare_by_oldest_queued_item_(const void **a_, const void **b_)
2624 {
2625  const circuit_t *a = *a_;
2626  const circuit_t *b = *b_;
2627  uint32_t age_a = a->age_tmp;
2628  uint32_t age_b = b->age_tmp;
2629 
2630  if (age_a < age_b)
2631  return 1;
2632  else if (age_a == age_b)
2633  return 0;
2634  else
2635  return -1;
2636 }
2637 
2638 static uint32_t now_ts_for_buf_cmp;
2639 
2642 static int
2643 conns_compare_by_buffer_age_(const void **a_, const void **b_)
2644 {
2645  const connection_t *a = *a_;
2646  const connection_t *b = *b_;
2647  time_t age_a = conn_get_buffer_age(a, now_ts_for_buf_cmp);
2648  time_t age_b = conn_get_buffer_age(b, now_ts_for_buf_cmp);
2649 
2650  if (age_a < age_b)
2651  return 1;
2652  else if (age_a == age_b)
2653  return 0;
2654  else
2655  return -1;
2656 }
2657 
2658 #define FRACTION_OF_DATA_TO_RETAIN_ON_OOM 0.90
2659 
2663 void
2664 circuits_handle_oom(size_t current_allocation)
2665 {
2666  smartlist_t *circlist;
2667  smartlist_t *connection_array = get_connection_array();
2668  int conn_idx;
2669  size_t mem_to_recover;
2670  size_t mem_recovered=0;
2671  int n_circuits_killed=0;
2672  int n_dirconns_killed=0;
2673  uint32_t now_ts;
2674  log_notice(LD_GENERAL, "We're low on memory (cell queues total alloc:"
2675  " %"TOR_PRIuSZ" buffer total alloc: %" TOR_PRIuSZ ","
2676  " tor compress total alloc: %" TOR_PRIuSZ
2677  " (zlib: %" TOR_PRIuSZ ", zstd: %" TOR_PRIuSZ ","
2678  " lzma: %" TOR_PRIuSZ "),"
2679  " rendezvous cache total alloc: %" TOR_PRIuSZ "). Killing"
2680  " circuits withover-long queues. (This behavior is controlled by"
2681  " MaxMemInQueues.)",
2682  cell_queues_get_total_allocation(),
2683  buf_get_total_allocation(),
2688  rend_cache_get_total_allocation());
2689 
2690  {
2691  size_t mem_target = (size_t)(get_options()->MaxMemInQueues *
2692  FRACTION_OF_DATA_TO_RETAIN_ON_OOM);
2693  if (current_allocation <= mem_target)
2694  return;
2695  mem_to_recover = current_allocation - mem_target;
2696  }
2697 
2698  now_ts = monotime_coarse_get_stamp();
2699 
2700  circlist = circuit_get_global_list();
2701  SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) {
2702  circ->age_tmp = circuit_max_queued_item_age(circ, now_ts);
2703  } SMARTLIST_FOREACH_END(circ);
2704 
2705  /* This is O(n log n); there are faster algorithms we could use instead.
2706  * Let's hope this doesn't happen enough to be in the critical path. */
2708 
2709  /* Fix up the indices before we run into trouble */
2710  SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) {
2711  circ->global_circuitlist_idx = circ_sl_idx;
2712  } SMARTLIST_FOREACH_END(circ);
2713 
2714  /* Now sort the connection array ... */
2715  now_ts_for_buf_cmp = now_ts;
2717  now_ts_for_buf_cmp = 0;
2718 
2719  /* Fix up the connection array to its new order. */
2721  conn->conn_array_index = conn_sl_idx;
2722  } SMARTLIST_FOREACH_END(conn);
2723 
2724  /* Okay, now the worst circuits and connections are at the front of their
2725  * respective lists. Let's mark them, and reclaim their storage
2726  * aggressively. */
2727  conn_idx = 0;
2728  SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) {
2729  size_t n;
2730  size_t freed;
2731 
2732  /* Free storage in any non-linked directory connections that have buffered
2733  * data older than this circuit. */
2734  while (conn_idx < smartlist_len(connection_array)) {
2735  connection_t *conn = smartlist_get(connection_array, conn_idx);
2736  uint32_t conn_age = conn_get_buffer_age(conn, now_ts);
2737  if (conn_age < circ->age_tmp) {
2738  break;
2739  }
2740  if (conn->type == CONN_TYPE_DIR && conn->linked_conn == NULL) {
2741  if (!conn->marked_for_close)
2742  connection_mark_for_close(conn);
2743  mem_recovered += single_conn_free_bytes(conn);
2744 
2745  ++n_dirconns_killed;
2746 
2747  if (mem_recovered >= mem_to_recover)
2748  goto done_recovering_mem;
2749  }
2750  ++conn_idx;
2751  }
2752 
2753  /* Now, kill the circuit. */
2754  n = n_cells_in_circ_queues(circ);
2755  const size_t half_stream_alloc = circuit_alloc_in_half_streams(circ);
2756  if (! circ->marked_for_close) {
2757  circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT);
2758  }
2760  freed = marked_circuit_free_stream_bytes(circ);
2761 
2762  ++n_circuits_killed;
2763 
2764  mem_recovered += n * packed_cell_mem_cost();
2765  mem_recovered += half_stream_alloc;
2766  mem_recovered += freed;
2767 
2768  if (mem_recovered >= mem_to_recover)
2769  goto done_recovering_mem;
2770  } SMARTLIST_FOREACH_END(circ);
2771 
2772  done_recovering_mem:
2773 
2774  log_notice(LD_GENERAL, "Removed %"TOR_PRIuSZ" bytes by killing %d circuits; "
2775  "%d circuits remain alive. Also killed %d non-linked directory "
2776  "connections.",
2777  mem_recovered,
2778  n_circuits_killed,
2779  smartlist_len(circlist) - n_circuits_killed,
2780  n_dirconns_killed);
2781 }
2782 
2787 assert_circuit_ok,(const circuit_t *c))
2788 {
2789  edge_connection_t *conn;
2790  const or_circuit_t *or_circ = NULL;
2791  const origin_circuit_t *origin_circ = NULL;
2792 
2793  tor_assert(c);
2794  tor_assert(c->magic == ORIGIN_CIRCUIT_MAGIC || c->magic == OR_CIRCUIT_MAGIC);
2795  tor_assert(c->purpose >= CIRCUIT_PURPOSE_MIN_ &&
2796  c->purpose <= CIRCUIT_PURPOSE_MAX_);
2797 
2798  if (CIRCUIT_IS_ORIGIN(c))
2799  origin_circ = CONST_TO_ORIGIN_CIRCUIT(c);
2800  else
2801  or_circ = CONST_TO_OR_CIRCUIT(c);
2802 
2803  if (c->n_chan) {
2804  tor_assert(!c->n_hop);
2805 
2806  if (c->n_circ_id) {
2807  /* We use the _impl variant here to make sure we don't fail on marked
2808  * circuits, which would not be returned by the regular function. */
2810  c->n_chan, NULL);
2811  tor_assert(c == c2);
2812  }
2813  }
2814  if (or_circ && or_circ->p_chan) {
2815  if (or_circ->p_circ_id) {
2816  /* ibid */
2817  circuit_t *c2 =
2819  or_circ->p_chan, NULL);
2820  tor_assert(c == c2);
2821  }
2822  }
2823  if (or_circ)
2824  for (conn = or_circ->n_streams; conn; conn = conn->next_stream)
2825  tor_assert(conn->base_.type == CONN_TYPE_EXIT);
2826 
2827  tor_assert(c->deliver_window >= 0);
2828  tor_assert(c->package_window >= 0);
2829  if (c->state == CIRCUIT_STATE_OPEN ||
2832  if (or_circ) {
2833  relay_crypto_assert_ok(&or_circ->crypto);
2834  }
2835  }
2836  if (c->state == CIRCUIT_STATE_CHAN_WAIT && !c->marked_for_close) {
2839  } else {
2842  }
2843  if (origin_circ && origin_circ->cpath) {
2844  cpath_assert_ok(origin_circ->cpath);
2845  }
2847  tor_assert(or_circ);
2848  if (!c->marked_for_close) {
2849  tor_assert(or_circ->rend_splice);
2850  tor_assert(or_circ->rend_splice->rend_splice == or_circ);
2851  }
2852  tor_assert(or_circ->rend_splice != or_circ);
2853  } else {
2854  tor_assert(!or_circ || !or_circ->rend_splice);
2855  }
2856 }
#define CIRCUIT_PURPOSE_C_INTRODUCING
Definition: circuitlist.h:74
Header file for circuitstats.c.
#define CIRCLAUNCH_ONEHOP_TUNNEL
Definition: circuituse.h:39
static circuit_t * circuit_get_by_circid_channel_impl(circid_t circ_id, channel_t *chan, int *found_entry_out)
Definition: circuitlist.c:1443
Header file for rendcommon.c.
void circuit_get_all_pending_on_channel(smartlist_t *out, channel_t *chan)
Definition: circuitlist.c:573
#define CIRCLAUNCH_IS_INTERNAL
Definition: circuituse.h:46
rend_data_t * rend_data
circuit_t * circuit_get_by_circid_channel_even_if_marked(circid_t circ_id, channel_t *chan)
Definition: circuitlist.c:1526
struct circuit_guard_state_t * guard_state
const char * channel_get_canonical_remote_descr(channel_t *chan)
Definition: channel.c:2847
#define CIRCUIT_PURPOSE_IS_ORIGIN(p)
Definition: circuitlist.h:138
Header file for channeltls.c.
static int conns_compare_by_buffer_age_(const void **a_, const void **b_)
Definition: circuitlist.c:2643
#define CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT
Definition: circuitlist.h:94
int routerset_contains_extendinfo(const routerset_t *set, const extend_info_t *ei)
Definition: routerset.c:293
static void circuit_about_to_free(circuit_t *circ)
Definition: circuitlist.c:2305
#define CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED
Definition: circuitlist.h:87
int package_window
Definition: circuit_st.h:105
Header file for circuitbuild.c.
Common functions for using (pseudo-)random number generators.
int rend_client_report_intro_point_failure(extend_info_t *failed_intro, rend_data_t *rend_data, unsigned int failure_type)
Definition: rendclient.c:794
int marked_for_close_orig_reason
Definition: circuit_st.h:190
Definition: node_st.h:28
Headers for crypto_dh.c.
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define TO_CONN(c)
Definition: or.h:735
void entry_guard_cancel(circuit_guard_state_t **guard_state_p)
Definition: entrynodes.c:2459
crypt_path_t * circuit_get_cpath_hop(origin_circuit_t *circ, int hopnum)
Definition: circuitlist.c:2071
void circuits_handle_oom(size_t current_allocation)
Definition: circuitlist.c:2664
struct crypt_path_t * next
Definition: crypt_path_st.h:67
uint16_t marked_for_close
Definition: circuit_st.h:178
Header file for connection.c.
crypt_path_reference_t * service_pending_final_cpath_ref
void rep_hist_buffer_stats_add_circ(circuit_t *circ, time_t end_of_interval)
Definition: rephist.c:1857
struct or_circuit_t * rend_splice
Definition: or_circuit_st.h:50
#define LD_GENERAL
Definition: log.h:60
static int chan_circid_entries_eq_(chan_circid_circuit_map_t *a, chan_circid_circuit_map_t *b)
Definition: circuitlist.c:190
crypt_path_t * pending_final_cpath
uint32_t age_tmp
Definition: circuit_st.h:139
int route_len_for_purpose(uint8_t purpose, extend_info_t *exit_ei)
#define CIRCUIT_IS_ORIGIN(c)
Definition: circuitlist.h:145
#define CIRCLAUNCH_NEED_UPTIME
Definition: circuituse.h:41
int rend_cmp_service_ids(const char *one, const char *two)
Definition: rendcommon.c:48
static size_t marked_circuit_free_stream_bytes(circuit_t *c)
Definition: circuitlist.c:2486
#define DOWNCAST(to, ptr)
Definition: or.h:110
int predicted_ports_prediction_time_remaining(time_t now)
Definition: predict_ports.c:54
void circuit_reset_sendme_randomness(circuit_t *circ)
Definition: relay.c:2060
#define END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED
Definition: or.h:279
static void init_circuit_base(circuit_t *circ)
Definition: circuitlist.c:984
#define CIRCUIT_PURPOSE_REND_POINT_WAITING
Definition: circuitlist.h:44
Headers for compress.c.
const char * circuit_purpose_to_string(uint8_t purpose)
Definition: circuitlist.c:898
#define DEFAULT_ROUTE_LEN
Definition: or.h:1007
Header file for nodelist.c.
#define CIRCWINDOW_START
Definition: or.h:501
HT_PROTOTYPE(HT_GENERATE2(strmap_impl, HT_GENERATE2(strmap_entry_t, HT_GENERATE2(node, HT_GENERATE2(strmap_entry_hash, HT_GENERATE2(strmap_entries_eq)
Definition: map.c:87
crypt_path_t * cpath
void tor_log(int severity, log_domain_mask_t domain, const char *format,...)
Definition: log.c:633
Header file for directory.c.
void smartlist_add(smartlist_t *sl, void *element)
static HT_HEAD(HT_PROTOTYPE(chan_circid_map, HT_PROTOTYPE(chan_circid_circuit_map_t)
Definition: circuitlist.c:213
static unsigned int chan_circid_entry_hash_(chan_circid_circuit_map_t *a)
Definition: circuitlist.c:199
const char * circuit_purpose_to_controller_hs_state_string(uint8_t purpose)
Definition: circuitlist.c:838
int circuit_id_in_use_on_channel(circid_t circ_id, channel_t *chan)
Definition: circuitlist.c:1540
void circuit_clear_testing_cell_stats(circuit_t *circ)
Definition: circuitlist.c:1106
void cell_queue_clear(cell_queue_t *queue)
Definition: relay.c:2583
int connection_edge_destroy(circid_t circ_id, edge_connection_t *conn)
int smartlist_contains(const smartlist_t *sl, const void *element)
#define TO_CIRCUIT(x)
Definition: or.h:951
int circuit_count_pending_on_channel(channel_t *chan)
Definition: circuitlist.c:604
#define CIRCUIT_PURPOSE_C_REND_READY
Definition: circuitlist.h:84
Header file for config.c.
origin_circuit_t * circuit_get_next_service_rp_circ(origin_circuit_t *start)
Definition: circuitlist.c:1770
struct tor_compress_state_t * compress_state
struct connection_t * linked_conn
guard_selection_t * get_guard_selection_info(void)
Definition: entrynodes.c:303
STATIC size_t n_cells_in_circ_queues(const circuit_t *c)
Definition: circuitlist.c:2497
origin_circuit_t * circuit_get_by_global_id(uint32_t id)
Definition: circuitlist.c:1419
#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
Definition: circuitlist.h:102
void circuit_clear_cell_queue(circuit_t *circ, channel_t *chan)
Definition: relay.c:3230
static int circuits_compare_by_oldest_queued_item_(const void **a_, const void **b_)
Definition: circuitlist.c:2623
void circuit_set_state(circuit_t *circ, uint8_t state)
Definition: circuitlist.c:540
int circuit_event_status(origin_circuit_t *circ, circuit_status_event_t tp, int reason_code)
Definition: circuitlist.c:496
static smartlist_t * global_circuitlist
Definition: circuitlist.c:119
unsigned int num_n_circuits
Definition: channel.h:416
void mainloop_schedule_postloop_cleanup(void)
Definition: mainloop.c:1616
#define tor_free(p)
Definition: malloc.h:52
#define tor_fragile_assert()
Definition: util_bug.h:241
#define SMARTLIST_DEL_CURRENT(sl, var)
Header file for mainloop.c.
#define CIRCUIT_PURPOSE_REND_ESTABLISHED
Definition: circuitlist.h:46
Integer definitions used throughout Tor.
circuitmux_t * cmux
Definition: channel.h:403
int circuit_get_cpath_len(origin_circuit_t *circ)
Definition: circuitlist.c:2035
uint8_t purpose
Definition: circuit_st.h:100
Header for compress_lzma.c.
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:57
size_t packed_cell_mem_cost(void)
Definition: relay.c:2676
smartlist_t * sendme_last_digests
Definition: circuit_st.h:136
void onion_pending_remove(or_circuit_t *circ)
Definition: onion_queue.c:308
void circuit_clear_cpath(origin_circuit_t *circ)
Definition: circuitlist.c:1267
void cpath_assert_ok(const crypt_path_t *cp)
Definition: crypt_path.c:83
Definition: or.h:923
void * tor_reallocarray_(void *ptr, size_t sz1, size_t sz2)
Definition: malloc.c:146
void smartlist_sort_pointers(smartlist_t *sl)
Definition: smartlist.c:594
unsigned int n_delete_pending
Definition: circuit_st.h:90
unsigned int remaining_relay_early_cells
#define END_CIRC_REASON_FLAG_REMOTE
Definition: or.h:328
int entry_guards_upgrade_waiting_circuits(guard_selection_t *gs, const smartlist_t *all_circuits_in, smartlist_t *newly_complete_out)
Definition: entrynodes.c:2584
cell_queue_t n_chan_cells
Definition: circuit_st.h:70
size_t outbuf_flushlen
Definition: connection_st.h:96
#define CIRCUIT_PURPOSE_C_HSDIR_GET
Definition: circuitlist.h:91
#define CIRCLAUNCH_IS_V3_RP
Definition: circuituse.h:49
extend_info_t * n_hop
Definition: circuit_st.h:76
void circpad_circuit_free_all_machineinfos(circuit_t *circ)
struct create_cell_t * n_chan_create_cell
Definition: circuit_st.h:142
int circuit_should_use_vanguards(uint8_t purpose)
Definition: circuituse.c:1997
smartlist_t * circuit_get_global_origin_circuit_list(void)
Definition: circuitlist.c:698
#define MAX_RELAY_EARLY_CELLS_PER_CIRCUIT
Definition: or.h:940
static smartlist_t * circuits_pending_chans
Definition: circuitlist.c:126
static int any_opened_circs_cached_val
Definition: circuitlist.c:146
Header file for policies.c.
channel_t * p_chan
Definition: or_circuit_st.h:37
#define CIRCUIT_STATE_ONIONSKIN_PENDING
Definition: circuitlist.h:22
void channel_note_destroy_pending(channel_t *chan, circid_t id)
Definition: circuitlist.c:406
#define CIRCUIT_PURPOSE_CONTROLLER
Definition: circuitlist.h:119
int circuit_build_times_needs_circuits(const circuit_build_times_t *cbt)
static void marked_circuit_free_cells(circuit_t *circ)
Definition: circuitlist.c:2430
struct buf_t * inbuf
Definition: connection_st.h:93
size_t tor_zlib_get_total_allocation(void)
int32_t circuit_initial_package_window(void)
Definition: circuitlist.c:970
Common functions for cryptographic routines.
Header file for channel.c.
tor_assert(buffer)
edge_connection_t * n_streams
Definition: or_circuit_st.h:39
origin_circuit_t * circuit_get_ready_rend_circ_by_rend_data(const rend_data_t *rend_data)
Definition: circuitlist.c:1681
origin_circuit_t * circuit_find_to_cannibalize(uint8_t purpose_to_produce, extend_info_t *info, int flags)
Definition: circuitlist.c:1897
STATIC uint32_t circuit_max_queued_item_age(const circuit_t *c, uint32_t now)
Definition: circuitlist.c:2610
time_t timestamp_dirty
Definition: circuit_st.h:176
#define LD_CIRC
Definition: log.h:80
uint8_t state
Definition: circuit_st.h:99
circuit_t * circuit_get_by_circid_channel(circid_t circ_id, channel_t *chan)
Definition: circuitlist.c:1511
int tor_memeq(const void *a, const void *b, size_t sz)
Definition: di_ops.c:107
struct workqueue_entry_s * workqueue_entry
Definition: or_circuit_st.h:30
uint32_t inserted_timestamp
Definition: cell_queue_st.h:17
origin_circuit_t * circuit_get_next_intro_circ(const origin_circuit_t *start, bool want_client_circ)
Definition: circuitlist.c:1718
routerset_t * ExcludeNodes
Definition: or_options_st.h:85
circid_t n_circ_id
Definition: circuit_st.h:67
dir_connection_t * TO_DIR_CONN(connection_t *c)
Definition: directory.c:85
time_t circuit_id_when_marked_unusable_on_channel(circid_t circ_id, channel_t *chan)
Definition: circuitlist.c:1553
Header file for circuitpadding.c.
int conn_array_index
Definition: connection_st.h:89
#define DIGEST_LEN
Definition: digest_sizes.h:20
void circuit_synchronize_written_or_bandwidth(const circuit_t *c, circuit_channel_direction_t dir)
Definition: circuitlist.c:2134
#define CIRCUIT_PURPOSE_C_INTRODUCE_ACKED
Definition: circuitlist.h:80
#define CIRCUIT_PURPOSE_TESTING
Definition: circuitlist.h:117
static int circuit_can_be_cannibalized_for_v3_rp(const origin_circuit_t *circ)
Definition: circuitlist.c:1841
#define END_CIRC_AT_ORIGIN
Definition: or.h:305
Master header file for Tor-specific functionality.
#define CIRCUIT_STATE_OPEN
Definition: circuitlist.h:31
MOCK_IMPL(void, channel_note_destroy_not_pending,(channel_t *chan, circid_t id))
Definition: circuitlist.c:425
Header file for onion_queue.c.
Header file for circuitbuild.c.
int crypto_rand_int(unsigned int max)
uint16_t marked_for_close
void circuit_mark_all_unused_circs(void)
Definition: circuitlist.c:2087
Header file for onion_fast.c.
void cpath_free(crypt_path_t *victim)
Definition: crypt_path.c:162
void channel_mark_circid_usable(channel_t *chan, circid_t id)
Definition: circuitlist.c:383
Header file for rephist.c.
static void circuit_about_to_free_atexit(circuit_t *circ)
Definition: circuitlist.c:2280
void smartlist_remove(smartlist_t *sl, const void *element)
Header file containing circuit and connection identifier data for the whole HS subsytem.
STATIC uint32_t circuit_max_queued_data_age(const circuit_t *c, uint32_t now)
Definition: circuitlist.c:2595
int marked_for_close_reason
Definition: circuit_st.h:186
#define LOG_WARN
Definition: log.h:51
unsigned int type
Definition: connection_st.h:45
unsigned int edge_has_sent_end
static smartlist_t * global_origin_circuit_list
Definition: circuitlist.c:123
Header file for circuituse.c.
void cell_queue_init(cell_queue_t *queue)
Definition: relay.c:2575
#define CIRCUIT_PURPOSE_C_ESTABLISH_REND
Definition: circuitlist.h:82
void tor_free_(void *mem)
Definition: malloc.c:227
smartlist_t * testing_cell_stats
Definition: circuit_st.h:201
#define CELL_MAX_NETWORK_SIZE
Definition: or.h:579
smartlist_t * half_streams
time_t timestamp_last_had_circuits
Definition: channel.h:454
void smartlist_del(smartlist_t *sl, int idx)
static smartlist_t * circuits_pending_other_guards
Definition: circuitlist.c:130
circid_t p_circ_id
Definition: or_circuit_st.h:33
Header file for hs_circuitmap.c.
#define CIRCUIT_PURPOSE_S_CONNECT_REND
Definition: circuitlist.h:108
#define LD_REND
Definition: log.h:82
Header file for circuitlist.c.
#define CIRCUIT_PURPOSE_PATH_BIAS_TESTING
Definition: circuitlist.h:121
int circuit_any_opened_circuits_cached(void)
Definition: circuitlist.c:750
static uint32_t conn_get_buffer_age(const connection_t *conn, uint32_t now_ts)
Definition: circuitlist.c:2554
void circuit_log_path(int severity, unsigned int domain, origin_circuit_t *circ)
Definition: circuitbuild.c:357
size_t tor_compress_get_total_allocation(void)
Definition: compress.c:458
int channel_matches_extend_info(channel_t *chan, extend_info_t *extend_info)
Definition: channel.c:3313
int tor_digest_is_zero(const char *digest)
Definition: util_string.c:96
STATIC void circuit_free_(circuit_t *circ)
Definition: circuitlist.c:1119
void circuit_dump_by_conn(connection_t *conn, int severity)
Definition: circuitlist.c:1378
void circuit_close_all_marked(void)
Definition: circuitlist.c:657
#define CIRCLAUNCH_NEED_CAPACITY
Definition: circuituse.h:43
int pathbias_check_close(origin_circuit_t *ocirc, int reason)
Header for compress_zstd.c.
#define CIRCUIT_PURPOSE_S_INTRO
Definition: circuitlist.h:105
static void cpath_ref_decref(crypt_path_reference_t *cpath_ref)
Definition: circuitlist.c:1343
int circpad_marked_circuit_for_padding(circuit_t *circ, int reason)
struct buf_t * outbuf
Definition: connection_st.h:94
#define CIRCUIT_PURPOSE_HS_VANGUARDS
Definition: circuitlist.h:129
void circuit_cache_opened_circuit_state(int circuits_are_opened)
Definition: circuitlist.c:739
Header file containing circuit data for the whole HS subsytem.
cpath_build_state_t * build_state
struct chan_circid_circuit_map_t chan_circid_circuit_map_t
Header file for connection_edge.c.
STATIC uint32_t circuit_max_queued_cell_age(const circuit_t *c, uint32_t now)
Definition: circuitlist.c:2530
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:163
static void circuit_remove_from_origin_circuit_list(origin_circuit_t *origin_circ)
Definition: circuitlist.c:624
Header file for crypt_path.c.
size_t tor_compress_state_size(const tor_compress_state_t *state)
Definition: compress.c:639
#define DFLT_IDLE_TIMEOUT_WHILE_LEARNING
Definition: circuitlist.c:1005
cell_queue_t p_chan_cells
Definition: or_circuit_st.h:35
const char * circuit_state_to_string(int state)
Definition: circuitlist.c:757
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition: printf.c:27
size_t buf_allocation(const buf_t *buf)
Definition: buffers.c:399
struct hs_ident_circuit_t * hs_ident
char rend_cookie[REND_COOKIE_LEN]
Definition: or.h:427
void circuit_mark_all_dirty_circs_as_unusable(void)
Definition: circuitlist.c:2106
int node_supports_v3_rendezvous_point(const node_t *node)
Definition: nodelist.c:1183
streamid_t next_stream_id
#define CIRCUIT_PURPOSE_INTRO_POINT
Definition: circuitlist.h:41
Header file for relay.c.
edge_connection_t * p_streams
char identity_digest[DIGEST_LEN]
#define SMARTLIST_FOREACH(sl, type, var, cmd)
STATIC smartlist_t * connection_array
Definition: mainloop.c:164
enum channel_s::@9 reason_for_closing
#define CIRCUIT_PURPOSE_S_HSDIR_POST
Definition: circuitlist.h:113
Header for compress_zlib.c.
origin_circuit_t * origin_circuit_new(void)
Definition: circuitlist.c:1013
edge_connection_t * resolving_streams
Definition: or_circuit_st.h:42
static uint8_t get_circuit_purpose_needed_to_cannibalize(uint8_t purpose)
Definition: circuitlist.c:1866
#define CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT
Definition: circuitlist.h:77
int circuit_get_cpath_opened_len(const origin_circuit_t *circ)
Definition: circuitlist.c:2051
uint32_t buf_get_oldest_chunk_timestamp(const buf_t *buf, uint32_t now)
Definition: buffers.c:504
#define CIRCUIT_PURPOSE_C_REND_JOINED
Definition: circuitlist.h:89
void rep_hist_note_bytes_written(uint64_t num_bytes, time_t when)
Definition: rephist.c:1149
uint8_t state
Definition: crypt_path_st.h:63
void circuit_build_failed(origin_circuit_t *circ)
Definition: circuituse.c:1776
circuit_build_times_t * get_circuit_build_times_mutable(void)
Definition: circuitstats.c:89
uint32_t circid_t
Definition: or.h:608
#define CIRCUIT_PURPOSE_OR
Definition: circuitlist.h:38
struct timeval timestamp_began
Definition: circuit_st.h:154
#define log_fn(severity, domain, args,...)
Definition: log.h:274
#define CIRCUIT_STATE_GUARD_WAIT
Definition: circuitlist.h:29
unsigned int isolation_values_set
#define CIRCUIT_STATE_BUILDING
Definition: circuitlist.h:20
#define CONN_TYPE_EXIT
Definition: connection.h:26
void mark_circuit_unusable_for_new_conns(origin_circuit_t *circ)
Definition: circuituse.c:3105
or_circuit_t * or_circuit_new(circid_t p_circ_id, channel_t *p_chan)
Definition: circuitlist.c:1085
or_circuit_t * TO_OR_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:151
#define CIRCUIT_IS_ORCIRC(c)
Definition: circuitlist.h:152
void circuit_free_all(void)
Definition: circuitlist.c:1291
int deliver_window
Definition: circuit_st.h:110
const circuit_build_times_t * get_circuit_build_times(void)
Definition: circuitstats.c:82
#define CIRCUIT_PURPOSE_C_GENERAL
Definition: circuitlist.h:71
time_t approx_time(void)
Definition: approx_time.c:32
static size_t circuit_alloc_in_half_streams(const circuit_t *c)
Definition: circuitlist.c:2509
smartlist_t * prepend_policy
unsigned int p_delete_pending
Definition: circuit_st.h:87
const char * circuit_purpose_to_controller_string(uint8_t purpose)
Definition: circuitlist.c:777
size_t tor_lzma_get_total_allocation(void)
extend_info_t * extend_info
Definition: crypt_path_st.h:56
#define CIRCUIT_STATE_CHAN_WAIT
Definition: circuitlist.h:25
uint32_t magic
Definition: circuit_st.h:54
static uint32_t circuit_get_streams_max_data_age(const edge_connection_t *stream, uint32_t now)
Definition: circuitlist.c:2574
void circuit_set_n_circid_chan(circuit_t *circ, circid_t id, channel_t *chan)
Definition: circuitlist.c:471
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:1357
static smartlist_t * circuits_pending_close
Definition: circuitlist.c:134
Header file for buffers.c.
struct timeval timestamp_created
Definition: circuit_st.h:157
#define CONN_TYPE_DIR
Definition: connection.h:35
Header file for ocirc_event.c.
circuit_t * circuit_get_by_edge_conn(edge_connection_t *conn)
Definition: circuitlist.c:1572
Header file for connection_or.c.
struct circuit_t * on_circuit
void channel_mark_circid_unusable(channel_t *chan, circid_t id)
Definition: circuitlist.c:350
void circuit_unlink_all_from_channel(channel_t *chan, int reason)
Definition: circuitlist.c:1589
int entry_guard_could_succeed(const circuit_guard_state_t *guard_state)
Definition: entrynodes.c:3457
#define REND_COOKIE_LEN
Definition: or.h:399
extend_info_t * chosen_exit
static void circuit_add_to_origin_circuit_list(origin_circuit_t *origin_circ)
Definition: circuitlist.c:645
unsigned int remaining_relay_early_cells
Definition: or_circuit_st.h:57
char identity_digest[DIGEST_LEN]
Definition: channel.h:384
static void circuit_state_publish(const circuit_t *circ)
Definition: circuitlist.c:520
int control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, int reason_code)
relay_crypto_t crypto
Definition: or_circuit_st.h:46
struct edge_connection_t * next_stream
int global_circuitlist_idx
Definition: circuit_st.h:196
circuit_channel_direction_t
Definition: or.h:494
origin_circuit_t * circuit_get_next_by_pk_and_purpose(origin_circuit_t *start, const uint8_t *digest, uint8_t purpose)
Definition: circuitlist.c:1804
#define CIRCUIT_PURPOSE_S_REND_JOINED
Definition: circuitlist.h:111
Header file for rendclient.c.
void buf_clear(buf_t *buf)
Definition: buffers.c:379
int circuit_any_opened_circuits(void)
Definition: circuitlist.c:713
Header file for control_events.c.
void smartlist_clear(smartlist_t *sl)
void circuit_set_p_circid_chan(or_circuit_t *or_circ, circid_t id, channel_t *chan)
Definition: circuitlist.c:448
void smartlist_sort(smartlist_t *sl, int(*compare)(const void **a, const void **b))
Definition: smartlist.c:334
smartlist_t * circuit_find_circuits_to_upgrade_from_guard_wait(void)
Definition: circuitlist.c:2007
int nodes_in_same_family(const node_t *node1, const node_t *node2)
Definition: nodelist.c:2062
const char * build_state_get_exit_nickname(cpath_build_state_t *state)
const char * marked_for_close_file
Definition: circuit_st.h:181
size_t tor_zstd_get_total_allocation(void)
static size_t marked_circuit_streams_free_bytes(edge_connection_t *stream)
Definition: circuitlist.c:2470
void channel_unlink_all_circuits(channel_t *chan, smartlist_t *circuits_out)
Definition: relay.c:2799
int channel_send_destroy(circid_t circ_id, channel_t *chan, int reason)
Definition: channel.c:2028
Header file for networkstatus.c.
#define LD_BUG
Definition: log.h:84
uint32_t monotime_coarse_get_stamp(void)
Definition: compat_time.c:844
Header file for routerlist.c.
int circuit_build_times_disabled(const or_options_t *options)
Definition: circuitstats.c:121
channel_t * n_chan
Definition: circuit_st.h:58
#define CIRCUIT_PURPOSE_C_CIRCUIT_PADDING
Definition: circuitlist.h:96
circuit_status_event_t
Definition: ocirc_event.h:19
uint64_t global_identifier
Definition: channel.h:197
Header file for onion_crypto.c.